]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
Vendor import of stripped lldb trunk r256633:
[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, 'ehframe' : 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::eRegisterKindProcessPlugin] = i;
329         uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
330         reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno, LLDB_INVALID_REGNUM);
331         if (eh_frame_regno == LLDB_INVALID_REGNUM)
332             reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno, LLDB_INVALID_REGNUM);
333         reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
334         reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
335         std::string generic_str;
336         if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
337             reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str());
338         else
339             reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM);
340
341         // Check if this register invalidates any other register values when it is modified
342         StructuredData::Array *invalidate_reg_list = nullptr;
343         if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list))
344         {
345             const size_t num_regs = invalidate_reg_list->GetSize();
346             if (num_regs > 0)
347             {
348                 for (uint32_t idx = 0; idx < num_regs; ++idx)
349                 {
350                     ConstString invalidate_reg_name;
351                     uint64_t invalidate_reg_num;
352                     if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name))
353                     {
354                         RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name);
355                         if (invalidate_reg_info)
356                         {
357                             m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]);
358                         }
359                         else
360                         {
361                             // TODO: print error invalid slice string that doesn't follow the format
362                             printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n",
363                                    invalidate_reg_name.GetCString(), reg_info.name);
364                         }
365                     }
366                     else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num))
367                     {
368                         if (invalidate_reg_num != UINT64_MAX)
369                             m_invalidate_regs_map[i].push_back(invalidate_reg_num);
370                         else
371                             printf("error: 'invalidate-regs' list value wasn't a valid integer\n");
372                     }
373                     else
374                     {
375                         printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
376                     }
377                 }
378             }
379             else
380             {
381                 printf("error: 'invalidate-regs' contained an empty list\n");
382             }
383         }
384
385         // Calculate the register offset
386         const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
387         if (m_reg_data_byte_size < end_reg_offset)
388             m_reg_data_byte_size = end_reg_offset;
389
390         m_regs.push_back(reg_info);
391         m_set_reg_nums[set].push_back(i);
392     }
393     Finalize(arch);
394     return m_regs.size();
395 }
396
397
398 void
399 DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
400                                   ConstString &reg_name, 
401                                   ConstString &reg_alt_name, 
402                                   ConstString &set_name)
403 {
404     assert(!m_finalized);
405     const uint32_t reg_num = m_regs.size();
406     reg_info.name = reg_name.AsCString();
407     assert (reg_info.name);
408     reg_info.alt_name = reg_alt_name.AsCString(NULL);
409     uint32_t i;
410     if (reg_info.value_regs)
411     {
412         for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
413             m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
414     }
415     if (reg_info.invalidate_regs)
416     {
417         for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
418             m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
419     }
420     m_regs.push_back (reg_info);
421     uint32_t set = GetRegisterSetIndexByName (set_name, true);
422     assert (set < m_sets.size());
423     assert (set < m_set_reg_nums.size());
424     assert (set < m_set_names.size());
425     m_set_reg_nums[set].push_back(reg_num);
426     size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
427     if (m_reg_data_byte_size < end_reg_offset)
428         m_reg_data_byte_size = end_reg_offset;
429 }
430
431 void
432 DynamicRegisterInfo::Finalize (const ArchSpec &arch)
433 {
434     if (m_finalized)
435         return;
436     
437     m_finalized = true;
438     const size_t num_sets = m_sets.size();
439     for (size_t set = 0; set < num_sets; ++set)
440     {
441         assert (m_sets.size() == m_set_reg_nums.size());
442         m_sets[set].num_registers = m_set_reg_nums[set].size();
443         m_sets[set].registers = &m_set_reg_nums[set][0];
444     }
445     
446     // sort and unique all value registers and make sure each is terminated with
447     // LLDB_INVALID_REGNUM
448     
449     for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end();
450          pos != end;
451          ++pos)
452     {
453         if (pos->second.size() > 1)
454         {
455             std::sort (pos->second.begin(), pos->second.end());
456             reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
457             if (unique_end != pos->second.end())
458                 pos->second.erase(unique_end, pos->second.end());
459         }
460         assert (!pos->second.empty());
461         if (pos->second.back() != LLDB_INVALID_REGNUM)
462             pos->second.push_back(LLDB_INVALID_REGNUM);
463     }
464     
465     // Now update all value_regs with each register info as needed
466     const size_t num_regs = m_regs.size();
467     for (size_t i=0; i<num_regs; ++i)
468     {
469         if (m_value_regs_map.find(i) != m_value_regs_map.end())
470             m_regs[i].value_regs = m_value_regs_map[i].data();
471         else
472             m_regs[i].value_regs = NULL;
473     }
474
475     // Expand all invalidation dependencies
476     for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
477          pos != end;
478          ++pos)
479     {
480         const uint32_t reg_num = pos->first;
481         
482         if (m_regs[reg_num].value_regs)
483         {
484             reg_num_collection extra_invalid_regs;
485             for (const uint32_t invalidate_reg_num : pos->second)
486             {
487                 reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num);
488                 if (invalidate_pos != m_invalidate_regs_map.end())
489                 {
490                     for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second)
491                     {
492                         if (concrete_invalidate_reg_num != reg_num)
493                             extra_invalid_regs.push_back(concrete_invalidate_reg_num);
494                     }
495                 }
496             }
497             pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end());
498         }
499     }
500
501     // sort and unique all invalidate registers and make sure each is terminated with
502     // LLDB_INVALID_REGNUM
503     for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
504          pos != end;
505          ++pos)
506     {
507         if (pos->second.size() > 1)
508         {
509             std::sort (pos->second.begin(), pos->second.end());
510             reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
511             if (unique_end != pos->second.end())
512                 pos->second.erase(unique_end, pos->second.end());
513         }
514         assert (!pos->second.empty());
515         if (pos->second.back() != LLDB_INVALID_REGNUM)
516             pos->second.push_back(LLDB_INVALID_REGNUM);
517     }
518
519     // Now update all invalidate_regs with each register info as needed
520     for (size_t i=0; i<num_regs; ++i)
521     {
522         if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
523             m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
524         else
525             m_regs[i].invalidate_regs = NULL;
526     }
527     
528     // Check if we need to automatically set the generic registers in case
529     // they weren't set
530     bool generic_regs_specified = false;
531     for (const auto &reg: m_regs)
532     {
533         if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
534         {
535             generic_regs_specified = true;
536             break;
537         }
538     }
539
540     if (!generic_regs_specified)
541     {
542         switch (arch.GetMachine())
543         {
544         case llvm::Triple::aarch64:
545         case llvm::Triple::aarch64_be:
546             for (auto &reg: m_regs)
547             {
548                 if (strcmp(reg.name, "pc") == 0)
549                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
550                 else if ((strcmp(reg.name, "fp") == 0) || (strcmp(reg.name, "x29") == 0))
551                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
552                 else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "x30") == 0))
553                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
554                 else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "x31") == 0))
555                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
556                 else if (strcmp(reg.name, "cpsr") == 0)
557                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
558             }
559             break;
560             
561         case llvm::Triple::arm:
562         case llvm::Triple::armeb:
563         case llvm::Triple::thumb:
564         case llvm::Triple::thumbeb:
565             for (auto &reg: m_regs)
566             {
567                 if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
568                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
569                 else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "r13") == 0))
570                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
571                 else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "r14") == 0))
572                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
573                 else if ((strcmp(reg.name, "r7") == 0) && arch.GetTriple().getVendor() == llvm::Triple::Apple)
574                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
575                 else if ((strcmp(reg.name, "r11") == 0) && arch.GetTriple().getVendor() != llvm::Triple::Apple)
576                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
577                 else if (strcmp(reg.name, "fp") == 0)
578                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
579                 else if (strcmp(reg.name, "cpsr") == 0)
580                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
581             }
582             break;
583             
584         case llvm::Triple::x86:
585             for (auto &reg: m_regs)
586             {
587                 if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
588                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
589                 else if ((strcmp(reg.name, "esp") == 0) || (strcmp(reg.name, "sp") == 0))
590                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
591                 else if ((strcmp(reg.name, "ebp") == 0) || (strcmp(reg.name, "fp") == 0))
592                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
593                 else if ((strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0))
594                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
595             }
596             break;
597
598         case llvm::Triple::x86_64:
599             for (auto &reg: m_regs)
600             {
601                 if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
602                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
603                 else if ((strcmp(reg.name, "rsp") == 0) || (strcmp(reg.name, "sp") == 0))
604                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
605                 else if ((strcmp(reg.name, "rbp") == 0) || (strcmp(reg.name, "fp") == 0))
606                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
607                 else if ((strcmp(reg.name, "rflags") == 0) || (strcmp(reg.name, "flags") == 0))
608                     reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
609             }
610             break;
611
612         default:
613             break;
614         }
615     }
616 }
617
618 size_t
619 DynamicRegisterInfo::GetNumRegisters() const
620 {
621     return m_regs.size();
622 }
623
624 size_t
625 DynamicRegisterInfo::GetNumRegisterSets() const
626 {
627     return m_sets.size();
628 }
629
630 size_t
631 DynamicRegisterInfo::GetRegisterDataByteSize() const
632 {
633     return m_reg_data_byte_size;
634 }
635
636 const RegisterInfo *
637 DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
638 {
639     if (i < m_regs.size())
640         return &m_regs[i];
641     return NULL;
642 }
643
644 const RegisterSet *
645 DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
646 {
647     if (i < m_sets.size())
648         return &m_sets[i];
649     return NULL;
650 }
651
652 uint32_t
653 DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
654 {
655     name_collection::iterator pos, end = m_set_names.end();
656     for (pos = m_set_names.begin(); pos != end; ++pos)
657     {
658         if (*pos == set_name)
659             return std::distance (m_set_names.begin(), pos);
660     }
661     
662     m_set_names.push_back(set_name);
663     m_set_reg_nums.resize(m_set_reg_nums.size()+1);
664     RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
665     m_sets.push_back (new_set);
666     return m_sets.size() - 1;
667 }
668
669 uint32_t
670 DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
671 {
672     reg_collection::const_iterator pos, end = m_regs.end();
673     for (pos = m_regs.begin(); pos != end; ++pos)
674     {
675         if (pos->kinds[kind] == num)
676             return std::distance (m_regs.begin(), pos);
677     }
678     
679     return LLDB_INVALID_REGNUM;
680 }
681
682 void
683 DynamicRegisterInfo::Clear()
684 {
685     m_regs.clear();
686     m_sets.clear();
687     m_set_reg_nums.clear();
688     m_set_names.clear();
689     m_value_regs_map.clear();
690     m_invalidate_regs_map.clear();
691     m_reg_data_byte_size = 0;
692     m_finalized = false;
693 }
694
695 void
696 DynamicRegisterInfo::Dump () const
697 {
698     StreamFile s(stdout, false);
699     const size_t num_regs = m_regs.size();
700     s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
701              static_cast<const void*>(this), static_cast<uint64_t>(num_regs));
702     for (size_t i=0; i<num_regs; ++i)
703     {
704         s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
705         s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
706                  m_regs[i].byte_size,
707                  m_regs[i].byte_offset,
708                  m_regs[i].encoding,
709                  FormatManager::GetFormatAsCString (m_regs[i].format));
710         if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
711             s.Printf(", process plugin = %3u", m_regs[i].kinds[eRegisterKindProcessPlugin]);
712         if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
713             s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
714         if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
715             s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
716         if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
717             s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
718         if (m_regs[i].alt_name)
719             s.Printf(", alt-name = %s", m_regs[i].alt_name);
720         if (m_regs[i].value_regs)
721         {
722             s.Printf(", value_regs = [ ");
723             for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j)
724             {
725                 s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
726             }
727             s.Printf("]");
728         }
729         if (m_regs[i].invalidate_regs)
730         {
731             s.Printf(", invalidate_regs = [ ");
732             for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j)
733             {
734                 s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
735             }
736             s.Printf("]");
737         }
738         s.EOL();
739     }
740
741     const size_t num_sets = m_sets.size();
742     s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
743              static_cast<const void*>(this), static_cast<uint64_t>(num_sets));
744     for (size_t i=0; i<num_sets; ++i)
745     {
746         s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name);
747         for (size_t idx=0; idx<m_sets[i].num_registers; ++idx)
748         {
749             s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
750         }
751         s.Printf("]\n");
752     }
753 }
754
755
756
757 lldb_private::RegisterInfo *
758 DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString &reg_name)
759 {
760     for (auto &reg_info : m_regs)
761     {
762         // We can use pointer comparison since we used a ConstString to set
763         // the "name" member in AddRegister()
764         if (reg_info.name == reg_name.GetCString())
765         {
766             return &reg_info;
767         }
768     }
769     return NULL;
770 }