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