]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
Import LLDB as of upstream SVN 241361 (git 612c075f)
[FreeBSD/FreeBSD.git] / source / Plugins / Process / Utility / DynamicRegisterInfo.cpp
1 //===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "DynamicRegisterInfo.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/ArchSpec.h"
17 #include "lldb/Core/RegularExpression.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Core/StructuredData.h"
20 #include "lldb/DataFormatters/FormatManager.h"
21 #include "lldb/Host/StringConvert.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 DynamicRegisterInfo::DynamicRegisterInfo () :
27     m_regs (),
28     m_sets (),
29     m_set_reg_nums (),
30     m_set_names (),
31     m_value_regs_map (),
32     m_invalidate_regs_map (),
33     m_reg_data_byte_size (0),
34     m_finalized (false)
35 {
36 }
37
38 DynamicRegisterInfo::DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
39                                          const lldb_private::ArchSpec &arch) :
40     m_regs (),
41     m_sets (),
42     m_set_reg_nums (),
43     m_set_names (),
44     m_value_regs_map (),
45     m_invalidate_regs_map (),
46     m_reg_data_byte_size (0),
47     m_finalized (false)
48 {
49     SetRegisterInfo (dict, arch);
50 }
51
52 DynamicRegisterInfo::~DynamicRegisterInfo ()
53 {
54 }
55
56 size_t
57 DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch)
58 {
59     assert(!m_finalized);
60     StructuredData::Array *sets = nullptr;
61     if (dict.GetValueForKeyAsArray("sets", sets))
62     {
63         const uint32_t num_sets = sets->GetSize();
64         for (uint32_t i=0; i<num_sets; ++i)
65         {
66             std::string set_name_str;
67             ConstString set_name;
68             if (sets->GetItemAtIndexAsString(i, set_name_str))
69                 set_name.SetCString(set_name_str.c_str());
70             if (set_name)
71             {
72                 RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
73                 m_sets.push_back (new_set);
74             }
75             else
76             {
77                 Clear();
78                 printf("error: register sets must have valid names\n");
79                 return 0;
80             }
81         }
82         m_set_reg_nums.resize(m_sets.size());
83     }
84     StructuredData::Array *regs = nullptr;
85     if (!dict.GetValueForKeyAsArray("registers", regs))
86         return 0;
87
88     const uint32_t num_regs = regs->GetSize();
89 //        typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
90 //        InvalidateNameMap invalidate_map;
91     for (uint32_t i = 0; i < num_regs; ++i)
92     {
93         StructuredData::Dictionary *reg_info_dict = nullptr;
94         if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict))
95         {
96             Clear();
97             printf("error: items in the 'registers' array must be dictionaries\n");
98             regs->DumpToStdout();
99             return 0;
100         }
101
102         // { 'name':'rcx'       , 'bitsize' :  64, 'offset' :  16, 'encoding':'uint'  , 'format':'hex'         , 'set': 0, 'gcc' : 2,
103         // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
104         RegisterInfo reg_info;
105         std::vector<uint32_t> value_regs;
106         std::vector<uint32_t> invalidate_regs;
107         memset(&reg_info, 0, sizeof(reg_info));
108
109         ConstString name_val;
110         ConstString alt_name_val;
111         if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr))
112         {
113             Clear();
114             printf("error: registers must have valid names and offsets\n");
115             reg_info_dict->DumpToStdout();
116             return 0;
117         }
118         reg_info.name = name_val.GetCString();
119         reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
120         reg_info.alt_name = alt_name_val.GetCString();
121
122         reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX);
123
124         const ByteOrder byte_order = arch.GetByteOrder();
125         
126         if (reg_info.byte_offset == UINT32_MAX)
127         {
128             // No offset for this register, see if the register has a value expression
129             // which indicates this register is part of another register. Value expressions
130             // are things like "rax[31:0]" which state that the current register's value
131             // is in a concrete register "rax" in bits 31:0. If there is a value expression
132             // we can calculate the offset
133             bool success = false;
134             std::string slice_str;
135             if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr))
136             {
137                 // Slices use the following format:
138                 //  REGNAME[MSBIT:LSBIT]
139                 // REGNAME - name of the register to grab a slice of
140                 // MSBIT - the most significant bit at which the current register value starts at
141                 // LSBIT - the least significant bit at which the current register value ends at
142                 static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
143                 RegularExpression::Match regex_match(3);
144                 if (g_bitfield_regex.Execute(slice_str.c_str(), &regex_match))
145                 {
146                     llvm::StringRef reg_name_str;
147                     std::string msbit_str;
148                     std::string lsbit_str;
149                     if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
150                         regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
151                         regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str))
152                     {
153                         const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
154                         const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
155                         if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
156                         {
157                             if (msbit > lsbit)
158                             {
159                                 const uint32_t msbyte = msbit / 8;
160                                 const uint32_t lsbyte = lsbit / 8;
161
162                                 ConstString containing_reg_name(reg_name_str);
163
164                                 RegisterInfo *containing_reg_info = GetRegisterInfo(containing_reg_name);
165                                 if (containing_reg_info)
166                                 {
167                                     const uint32_t max_bit = containing_reg_info->byte_size * 8;
168                                     if (msbit < max_bit && lsbit < max_bit)
169                                     {
170                                         m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
171                                         m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
172                                         m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
173
174                                         if (byte_order == eByteOrderLittle)
175                                         {
176                                             success = true;
177                                             reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte;
178                                         }
179                                         else if (byte_order == eByteOrderBig)
180                                         {
181                                             success = true;
182                                             reg_info.byte_offset = containing_reg_info->byte_offset + msbyte;
183                                         }
184                                         else
185                                         {
186                                             assert(!"Invalid byte order");
187                                         }
188                                     }
189                                     else
190                                     {
191                                         if (msbit > max_bit)
192                                             printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit,
193                                                    max_bit);
194                                         else
195                                             printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit,
196                                                    max_bit);
197                                     }
198                                 }
199                                 else
200                                 {
201                                     printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString());
202                                 }
203                             }
204                             else
205                             {
206                                 printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit);
207                             }
208                         }
209                         else
210                         {
211                             printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit);
212                         }
213                     }
214                     else
215                     {
216                         // TODO: print error invalid slice string that doesn't follow the format
217                         printf("error: failed to extract regex matches for parsing the register bitfield regex\n");
218                     }
219                 }
220                 else
221                 {
222                     // TODO: print error invalid slice string that doesn't follow the format
223                     printf("error: failed to match against register bitfield regex\n");
224                 }
225             }
226             else
227             {
228                 StructuredData::Array *composite_reg_list = nullptr;
229                 if (reg_info_dict->GetValueForKeyAsArray("composite", composite_reg_list))
230                 {
231                     const size_t num_composite_regs = composite_reg_list->GetSize();
232                     if (num_composite_regs > 0)
233                     {
234                         uint32_t composite_offset = UINT32_MAX;
235                         for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; ++composite_idx)
236                         {
237                             ConstString composite_reg_name;
238                             if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr))
239                             {
240                                 RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name);
241                                 if (composite_reg_info)
242                                 {
243                                     composite_offset = std::min(composite_offset, composite_reg_info->byte_offset);
244                                     m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
245                                     m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
246                                     m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
247                                 }
248                                 else
249                                 {
250                                     // TODO: print error invalid slice string that doesn't follow the format
251                                     printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString());
252                                 }
253                             }
254                             else
255                             {
256                                 printf("error: 'composite' list value wasn't a python string\n");
257                             }
258                         }
259                         if (composite_offset != UINT32_MAX)
260                         {
261                             reg_info.byte_offset = composite_offset;
262                             success = m_value_regs_map.find(i) != m_value_regs_map.end();
263                         }
264                         else
265                         {
266                             printf("error: 'composite' registers must specify at least one real register\n");
267                         }
268                     }
269                     else
270                     {
271                         printf("error: 'composite' list was empty\n");
272                     }
273                 }
274             }
275
276             if (!success)
277             {
278                 Clear();
279                 reg_info_dict->DumpToStdout();
280                 return 0;
281             }
282         }
283
284         int64_t bitsize = 0;
285         if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize))
286         {
287             Clear();
288             printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n");
289             reg_info_dict->DumpToStdout();
290             return 0;
291         }
292
293         reg_info.byte_size = bitsize / 8;
294
295         std::string format_str;
296         if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr))
297         {
298             if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL).Fail())
299             {
300                 Clear();
301                 printf("error: invalid 'format' value in register dictionary\n");
302                 reg_info_dict->DumpToStdout();
303                 return 0;
304             }
305         }
306         else
307         {
308             reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, eFormatHex);
309         }
310
311         std::string encoding_str;
312         if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
313             reg_info.encoding = Args::StringToEncoding(encoding_str.c_str(), eEncodingUint);
314         else
315             reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, eEncodingUint);
316
317         size_t set = 0;
318         if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) || set >= m_sets.size())
319         {
320             Clear();
321             printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set);
322             reg_info_dict->DumpToStdout();
323             return 0;
324         }
325
326         // Fill in the register numbers
327         reg_info.kinds[lldb::eRegisterKindLLDB] = i;
328         reg_info.kinds[lldb::eRegisterKindGDB] = i;
329         reg_info_dict->GetValueForKeyAsInteger("gcc", reg_info.kinds[lldb::eRegisterKindGCC], LLDB_INVALID_REGNUM);
330         reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
331         std::string generic_str;
332         if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
333             reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str());
334         else
335             reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM);
336
337         // Check if this register invalidates any other register values when it is modified
338         StructuredData::Array *invalidate_reg_list = nullptr;
339         if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list))
340         {
341             const size_t num_regs = invalidate_reg_list->GetSize();
342             if (num_regs > 0)
343             {
344                 for (uint32_t idx = 0; idx < num_regs; ++idx)
345                 {
346                     ConstString invalidate_reg_name;
347                     uint64_t invalidate_reg_num;
348                     if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name))
349                     {
350                         RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name);
351                         if (invalidate_reg_info)
352                         {
353                             m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]);
354                         }
355                         else
356                         {
357                             // TODO: print error invalid slice string that doesn't follow the format
358                             printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n",
359                                    invalidate_reg_name.GetCString(), reg_info.name);
360                         }
361                     }
362                     else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num))
363                     {
364                         if (invalidate_reg_num != UINT64_MAX)
365                             m_invalidate_regs_map[i].push_back(invalidate_reg_num);
366                         else
367                             printf("error: 'invalidate-regs' list value wasn't a valid integer\n");
368                     }
369                     else
370                     {
371                         printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
372                     }
373                 }
374             }
375             else
376             {
377                 printf("error: 'invalidate-regs' contained an empty list\n");
378             }
379         }
380
381         // Calculate the register offset
382         const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
383         if (m_reg_data_byte_size < end_reg_offset)
384             m_reg_data_byte_size = end_reg_offset;
385
386         m_regs.push_back(reg_info);
387         m_set_reg_nums[set].push_back(i);
388     }
389     Finalize(arch);
390     return m_regs.size();
391 }
392
393
394 void
395 DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
396                                   ConstString &reg_name, 
397                                   ConstString &reg_alt_name, 
398                                   ConstString &set_name)
399 {
400     assert(!m_finalized);
401     const uint32_t reg_num = m_regs.size();
402     reg_info.name = reg_name.AsCString();
403     assert (reg_info.name);
404     reg_info.alt_name = reg_alt_name.AsCString(NULL);
405     uint32_t i;
406     if (reg_info.value_regs)
407     {
408         for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
409             m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
410     }
411     if (reg_info.invalidate_regs)
412     {
413         for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
414             m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
415     }
416     m_regs.push_back (reg_info);
417     uint32_t set = GetRegisterSetIndexByName (set_name, true);
418     assert (set < m_sets.size());
419     assert (set < m_set_reg_nums.size());
420     assert (set < m_set_names.size());
421     m_set_reg_nums[set].push_back(reg_num);
422     size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
423     if (m_reg_data_byte_size < end_reg_offset)
424         m_reg_data_byte_size = end_reg_offset;
425 }
426
427 void
428 DynamicRegisterInfo::Finalize (const ArchSpec &arch)
429 {
430     if (m_finalized)
431         return;
432     
433     m_finalized = true;
434     const size_t num_sets = m_sets.size();
435     for (size_t set = 0; set < num_sets; ++set)
436     {
437         assert (m_sets.size() == m_set_reg_nums.size());
438         m_sets[set].num_registers = m_set_reg_nums[set].size();
439         m_sets[set].registers = &m_set_reg_nums[set][0];
440     }
441     
442     // sort and unique all value registers and make sure each is terminated with
443     // LLDB_INVALID_REGNUM
444     
445     for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end();
446          pos != end;
447          ++pos)
448     {
449         if (pos->second.size() > 1)
450         {
451             std::sort (pos->second.begin(), pos->second.end());
452             reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
453             if (unique_end != pos->second.end())
454                 pos->second.erase(unique_end, pos->second.end());
455         }
456         assert (!pos->second.empty());
457         if (pos->second.back() != LLDB_INVALID_REGNUM)
458             pos->second.push_back(LLDB_INVALID_REGNUM);
459     }
460     
461     // Now update all value_regs with each register info as needed
462     const size_t num_regs = m_regs.size();
463     for (size_t i=0; i<num_regs; ++i)
464     {
465         if (m_value_regs_map.find(i) != m_value_regs_map.end())
466             m_regs[i].value_regs = m_value_regs_map[i].data();
467         else
468             m_regs[i].value_regs = NULL;
469     }
470
471     // Expand all invalidation dependencies
472     for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
473          pos != end;
474          ++pos)
475     {
476         const uint32_t reg_num = pos->first;
477         
478         if (m_regs[reg_num].value_regs)
479         {
480             reg_num_collection extra_invalid_regs;
481             for (const uint32_t invalidate_reg_num : pos->second)
482             {
483                 reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num);
484                 if (invalidate_pos != m_invalidate_regs_map.end())
485                 {
486                     for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second)
487                     {
488                         if (concrete_invalidate_reg_num != reg_num)
489                             extra_invalid_regs.push_back(concrete_invalidate_reg_num);
490                     }
491                 }
492             }
493             pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end());
494         }
495     }
496
497     // sort and unique all invalidate registers and make sure each is terminated with
498     // LLDB_INVALID_REGNUM
499     for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
500          pos != end;
501          ++pos)
502     {
503         if (pos->second.size() > 1)
504         {
505             std::sort (pos->second.begin(), pos->second.end());
506             reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
507             if (unique_end != pos->second.end())
508                 pos->second.erase(unique_end, pos->second.end());
509         }
510         assert (!pos->second.empty());
511         if (pos->second.back() != LLDB_INVALID_REGNUM)
512             pos->second.push_back(LLDB_INVALID_REGNUM);
513     }
514
515     // Now update all invalidate_regs with each register info as needed
516     for (size_t i=0; i<num_regs; ++i)
517     {
518         if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
519             m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
520         else
521             m_regs[i].invalidate_regs = NULL;
522     }
523     
524     // Check if we need to automatically set the generic registers in case
525     // they weren't set
526     bool generic_regs_specified = false;
527     for (const auto &reg: m_regs)
528     {
529         if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
530         {
531             generic_regs_specified = true;
532             break;
533         }
534     }
535
536     if (!generic_regs_specified)
537     {
538         switch (arch.GetMachine())
539         {
540         case llvm::Triple::aarch64:
541         case llvm::Triple::aarch64_be:
542             for (auto &reg: m_regs)
543             {
544                 if (strcmp(reg.name, "pc") == 0)
545                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
546                 else if ((strcmp(reg.name, "fp") == 0) || (strcmp(reg.name, "x29") == 0))
547                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
548                 else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "x30") == 0))
549                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
550                 else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "x31") == 0))
551                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
552                 else if (strcmp(reg.name, "cpsr") == 0)
553                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
554             }
555             break;
556             
557         case llvm::Triple::arm:
558         case llvm::Triple::armeb:
559         case llvm::Triple::thumb:
560         case llvm::Triple::thumbeb:
561             for (auto &reg: m_regs)
562             {
563                 if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
564                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
565                 else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "r13") == 0))
566                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
567                 else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "r14") == 0))
568                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
569                 else if ((strcmp(reg.name, "r7") == 0) && arch.GetTriple().getVendor() == llvm::Triple::Apple)
570                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
571                 else if ((strcmp(reg.name, "r11") == 0) && arch.GetTriple().getVendor() != llvm::Triple::Apple)
572                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
573                 else if (strcmp(reg.name, "fp") == 0)
574                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
575                 else if (strcmp(reg.name, "cpsr") == 0)
576                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
577             }
578             break;
579             
580         case llvm::Triple::x86:
581             for (auto &reg: m_regs)
582             {
583                 if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
584                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
585                 else if ((strcmp(reg.name, "esp") == 0) || (strcmp(reg.name, "sp") == 0))
586                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
587                 else if ((strcmp(reg.name, "ebp") == 0) || (strcmp(reg.name, "fp") == 0))
588                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
589                 else if ((strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0))
590                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
591             }
592             break;
593
594         case llvm::Triple::x86_64:
595             for (auto &reg: m_regs)
596             {
597                 if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
598                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
599                 else if ((strcmp(reg.name, "rsp") == 0) || (strcmp(reg.name, "sp") == 0))
600                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
601                 else if ((strcmp(reg.name, "rbp") == 0) || (strcmp(reg.name, "fp") == 0))
602                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
603                 else if ((strcmp(reg.name, "rflags") == 0) || (strcmp(reg.name, "flags") == 0))
604                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
605             }
606             break;
607
608         default:
609             break;
610         }
611     }
612 }
613
614 size_t
615 DynamicRegisterInfo::GetNumRegisters() const
616 {
617     return m_regs.size();
618 }
619
620 size_t
621 DynamicRegisterInfo::GetNumRegisterSets() const
622 {
623     return m_sets.size();
624 }
625
626 size_t
627 DynamicRegisterInfo::GetRegisterDataByteSize() const
628 {
629     return m_reg_data_byte_size;
630 }
631
632 const RegisterInfo *
633 DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
634 {
635     if (i < m_regs.size())
636         return &m_regs[i];
637     return NULL;
638 }
639
640 const RegisterSet *
641 DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
642 {
643     if (i < m_sets.size())
644         return &m_sets[i];
645     return NULL;
646 }
647
648 uint32_t
649 DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
650 {
651     name_collection::iterator pos, end = m_set_names.end();
652     for (pos = m_set_names.begin(); pos != end; ++pos)
653     {
654         if (*pos == set_name)
655             return std::distance (m_set_names.begin(), pos);
656     }
657     
658     m_set_names.push_back(set_name);
659     m_set_reg_nums.resize(m_set_reg_nums.size()+1);
660     RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
661     m_sets.push_back (new_set);
662     return m_sets.size() - 1;
663 }
664
665 uint32_t
666 DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
667 {
668     reg_collection::const_iterator pos, end = m_regs.end();
669     for (pos = m_regs.begin(); pos != end; ++pos)
670     {
671         if (pos->kinds[kind] == num)
672             return std::distance (m_regs.begin(), pos);
673     }
674     
675     return LLDB_INVALID_REGNUM;
676 }
677
678 void
679 DynamicRegisterInfo::Clear()
680 {
681     m_regs.clear();
682     m_sets.clear();
683     m_set_reg_nums.clear();
684     m_set_names.clear();
685     m_value_regs_map.clear();
686     m_invalidate_regs_map.clear();
687     m_reg_data_byte_size = 0;
688     m_finalized = false;
689 }
690
691 void
692 DynamicRegisterInfo::Dump () const
693 {
694     StreamFile s(stdout, false);
695     const size_t num_regs = m_regs.size();
696     s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
697              static_cast<const void*>(this), static_cast<uint64_t>(num_regs));
698     for (size_t i=0; i<num_regs; ++i)
699     {
700         s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
701         s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
702                  m_regs[i].byte_size,
703                  m_regs[i].byte_offset,
704                  m_regs[i].encoding,
705                  FormatManager::GetFormatAsCString (m_regs[i].format));
706         if (m_regs[i].kinds[eRegisterKindGDB] != LLDB_INVALID_REGNUM)
707             s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]);
708         if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
709             s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
710         if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM)
711             s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]);
712         if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
713             s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
714         if (m_regs[i].alt_name)
715             s.Printf(", alt-name = %s", m_regs[i].alt_name);
716         if (m_regs[i].value_regs)
717         {
718             s.Printf(", value_regs = [ ");
719             for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j)
720             {
721                 s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
722             }
723             s.Printf("]");
724         }
725         if (m_regs[i].invalidate_regs)
726         {
727             s.Printf(", invalidate_regs = [ ");
728             for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j)
729             {
730                 s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
731             }
732             s.Printf("]");
733         }
734         s.EOL();
735     }
736
737     const size_t num_sets = m_sets.size();
738     s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
739              static_cast<const void*>(this), static_cast<uint64_t>(num_sets));
740     for (size_t i=0; i<num_sets; ++i)
741     {
742         s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name);
743         for (size_t idx=0; idx<m_sets[i].num_registers; ++idx)
744         {
745             s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
746         }
747         s.Printf("]\n");
748     }
749 }
750
751
752
753 lldb_private::RegisterInfo *
754 DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString &reg_name)
755 {
756     for (auto &reg_info : m_regs)
757     {
758         // We can use pointer comparison since we used a ConstString to set
759         // the "name" member in AddRegister()
760         if (reg_info.name == reg_name.GetCString())
761         {
762             return &reg_info;
763         }
764     }
765     return NULL;
766 }