LLDB  mainline
DynamicRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- DynamicRegisterInfo.cpp -------------------------------------------===//
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(), nullptr, 0, nullptr});
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  llvm::SmallVector<llvm::StringRef, 4> matches;
141  if (g_bitfield_regex.Execute(slice_str, &matches)) {
142  std::string reg_name_str = matches[1].str();
143  std::string msbit_str = matches[2].str();
144  std::string lsbit_str = matches[3].str();
145  const uint32_t msbit =
146  StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
147  const uint32_t lsbit =
148  StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
149  if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
150  if (msbit > lsbit) {
151  const uint32_t msbyte = msbit / 8;
152  const uint32_t lsbyte = lsbit / 8;
153 
154  const RegisterInfo *containing_reg_info =
155  GetRegisterInfo(reg_name_str);
156  if (containing_reg_info) {
157  const uint32_t max_bit = containing_reg_info->byte_size * 8;
158  if (msbit < max_bit && lsbit < max_bit) {
159  m_invalidate_regs_map[containing_reg_info
160  ->kinds[eRegisterKindLLDB]]
161  .push_back(i);
162  m_value_regs_map[i].push_back(
163  containing_reg_info->kinds[eRegisterKindLLDB]);
164  m_invalidate_regs_map[i].push_back(
165  containing_reg_info->kinds[eRegisterKindLLDB]);
166 
167  if (byte_order == eByteOrderLittle) {
168  success = true;
169  reg_info.byte_offset =
170  containing_reg_info->byte_offset + lsbyte;
171  } else if (byte_order == eByteOrderBig) {
172  success = true;
173  reg_info.byte_offset =
174  containing_reg_info->byte_offset + msbyte;
175  } else {
176  llvm_unreachable("Invalid byte order");
177  }
178  } else {
179  if (msbit > max_bit)
180  printf("error: msbit (%u) must be less than the bitsize "
181  "of the register (%u)\n",
182  msbit, max_bit);
183  else
184  printf("error: lsbit (%u) must be less than the bitsize "
185  "of the register (%u)\n",
186  lsbit, max_bit);
187  }
188  } else {
189  printf("error: invalid concrete register \"%s\"\n",
190  reg_name_str.c_str());
191  }
192  } else {
193  printf("error: msbit (%u) must be greater than lsbit (%u)\n",
194  msbit, lsbit);
195  }
196  } else {
197  printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
198  lsbit);
199  }
200  } else {
201  // TODO: print error invalid slice string that doesn't follow the
202  // format
203  printf("error: failed to match against register bitfield regex\n");
204  }
205  } else {
206  StructuredData::Array *composite_reg_list = nullptr;
207  if (reg_info_dict->GetValueForKeyAsArray("composite",
208  composite_reg_list)) {
209  const size_t num_composite_regs = composite_reg_list->GetSize();
210  if (num_composite_regs > 0) {
211  uint32_t composite_offset = UINT32_MAX;
212  for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
213  ++composite_idx) {
214  ConstString composite_reg_name;
215  if (composite_reg_list->GetItemAtIndexAsString(
216  composite_idx, composite_reg_name, nullptr)) {
217  const RegisterInfo *composite_reg_info =
218  GetRegisterInfo(composite_reg_name.GetStringRef());
219  if (composite_reg_info) {
220  composite_offset = std::min(composite_offset,
221  composite_reg_info->byte_offset);
222  m_value_regs_map[i].push_back(
223  composite_reg_info->kinds[eRegisterKindLLDB]);
224  m_invalidate_regs_map[composite_reg_info
225  ->kinds[eRegisterKindLLDB]]
226  .push_back(i);
227  m_invalidate_regs_map[i].push_back(
228  composite_reg_info->kinds[eRegisterKindLLDB]);
229  } else {
230  // TODO: print error invalid slice string that doesn't follow
231  // the format
232  printf("error: failed to find composite register by name: "
233  "\"%s\"\n",
234  composite_reg_name.GetCString());
235  }
236  } else {
237  printf(
238  "error: 'composite' list value wasn't a python string\n");
239  }
240  }
241  if (composite_offset != UINT32_MAX) {
242  reg_info.byte_offset = composite_offset;
243  success = m_value_regs_map.find(i) != m_value_regs_map.end();
244  } else {
245  printf("error: 'composite' registers must specify at least one "
246  "real register\n");
247  }
248  } else {
249  printf("error: 'composite' list was empty\n");
250  }
251  }
252  }
253 
254  if (!success) {
255  Clear();
256  reg_info_dict->DumpToStdout();
257  return 0;
258  }
259  }
260 
261  int64_t bitsize = 0;
262  if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
263  Clear();
264  printf("error: invalid or missing 'bitsize' key/value pair in register "
265  "dictionary\n");
266  reg_info_dict->DumpToStdout();
267  return 0;
268  }
269 
270  reg_info.byte_size = bitsize / 8;
271 
272  llvm::StringRef dwarf_opcode_string;
273  if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes",
274  dwarf_opcode_string)) {
275  reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.size() / 2;
276  assert(reg_info.dynamic_size_dwarf_len > 0);
277 
278  std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
279  uint32_t j;
280  StringExtractor opcode_extractor(dwarf_opcode_string);
281  uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
282  UNUSED_IF_ASSERT_DISABLED(ret_val);
283  assert(ret_val == reg_info.dynamic_size_dwarf_len);
284 
285  for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
286  m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);
287 
288  reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data();
289  }
290 
291  llvm::StringRef format_str;
292  if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
293  if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format,
294  nullptr)
295  .Fail()) {
296  Clear();
297  printf("error: invalid 'format' value in register dictionary\n");
298  reg_info_dict->DumpToStdout();
299  return 0;
300  }
301  } else {
302  reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,
303  eFormatHex);
304  }
305 
306  llvm::StringRef encoding_str;
307  if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
308  reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);
309  else
310  reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,
311  eEncodingUint);
312 
313  size_t set = 0;
314  if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
315  set >= m_sets.size()) {
316  Clear();
317  printf("error: invalid 'set' value in register dictionary, valid values "
318  "are 0 - %i\n",
319  (int)set);
320  reg_info_dict->DumpToStdout();
321  return 0;
322  }
323 
324  // Fill in the register numbers
325  reg_info.kinds[lldb::eRegisterKindLLDB] = i;
326  reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
327  uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
328  reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,
330  if (eh_frame_regno == LLDB_INVALID_REGNUM)
331  reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,
333  reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
334  reg_info_dict->GetValueForKeyAsInteger(
335  "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
336  llvm::StringRef generic_str;
337  if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
338  reg_info.kinds[lldb::eRegisterKindGeneric] =
339  Args::StringToGenericRegister(generic_str);
340  else
341  reg_info_dict->GetValueForKeyAsInteger(
342  "generic", reg_info.kinds[lldb::eRegisterKindGeneric],
344 
345  // Check if this register invalidates any other register values when it is
346  // modified
347  StructuredData::Array *invalidate_reg_list = nullptr;
348  if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",
349  invalidate_reg_list)) {
350  const size_t num_regs = invalidate_reg_list->GetSize();
351  if (num_regs > 0) {
352  for (uint32_t idx = 0; idx < num_regs; ++idx) {
353  ConstString invalidate_reg_name;
354  uint64_t invalidate_reg_num;
355  if (invalidate_reg_list->GetItemAtIndexAsString(
356  idx, invalidate_reg_name)) {
357  const RegisterInfo *invalidate_reg_info =
358  GetRegisterInfo(invalidate_reg_name.GetStringRef());
359  if (invalidate_reg_info) {
360  m_invalidate_regs_map[i].push_back(
361  invalidate_reg_info->kinds[eRegisterKindLLDB]);
362  } else {
363  // TODO: print error invalid slice string that doesn't follow the
364  // format
365  printf("error: failed to find a 'invalidate-regs' register for "
366  "\"%s\" while parsing register \"%s\"\n",
367  invalidate_reg_name.GetCString(), reg_info.name);
368  }
369  } else if (invalidate_reg_list->GetItemAtIndexAsInteger(
370  idx, invalidate_reg_num)) {
371  if (invalidate_reg_num != UINT64_MAX)
372  m_invalidate_regs_map[i].push_back(invalidate_reg_num);
373  else
374  printf("error: 'invalidate-regs' list value wasn't a valid "
375  "integer\n");
376  } else {
377  printf("error: 'invalidate-regs' list value wasn't a python string "
378  "or integer\n");
379  }
380  }
381  } else {
382  printf("error: 'invalidate-regs' contained an empty list\n");
383  }
384  }
385 
386  // Calculate the register offset
387  const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
388  if (m_reg_data_byte_size < end_reg_offset)
389  m_reg_data_byte_size = end_reg_offset;
390 
391  m_regs.push_back(reg_info);
392  m_set_reg_nums[set].push_back(i);
393  }
394  Finalize(arch);
395  return m_regs.size();
396 }
397 
398 void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
399  ConstString &reg_name,
400  ConstString &reg_alt_name,
401  ConstString &set_name) {
402  assert(!m_finalized);
403  const uint32_t reg_num = m_regs.size();
404  reg_info.name = reg_name.AsCString();
405  assert(reg_info.name);
406  reg_info.alt_name = reg_alt_name.AsCString(nullptr);
407  uint32_t i;
408  if (reg_info.value_regs) {
409  for (i = 0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
410  m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
411  }
412  if (reg_info.invalidate_regs) {
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  if (reg_info.dynamic_size_dwarf_expr_bytes) {
417  for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i)
418  m_dynamic_reg_size_map[reg_num].push_back(
419  reg_info.dynamic_size_dwarf_expr_bytes[i]);
420 
421  reg_info.dynamic_size_dwarf_expr_bytes =
422  m_dynamic_reg_size_map[reg_num].data();
423  }
424 
425  m_regs.push_back(reg_info);
426  uint32_t set = GetRegisterSetIndexByName(set_name, true);
427  assert(set < m_sets.size());
428  assert(set < m_set_reg_nums.size());
429  assert(set < m_set_names.size());
430  m_set_reg_nums[set].push_back(reg_num);
431 }
432 
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  assert(m_sets.size() == m_set_reg_nums.size());
441  m_sets[set].num_registers = m_set_reg_nums[set].size();
442  m_sets[set].registers = m_set_reg_nums[set].data();
443  }
444 
445  // sort and unique all value registers and make sure each is terminated with
446  // LLDB_INVALID_REGNUM
447 
448  for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),
449  end = m_value_regs_map.end();
450  pos != end; ++pos) {
451  if (pos->second.size() > 1) {
452  llvm::sort(pos->second.begin(), pos->second.end());
453  reg_num_collection::iterator unique_end =
454  std::unique(pos->second.begin(), pos->second.end());
455  if (unique_end != pos->second.end())
456  pos->second.erase(unique_end, pos->second.end());
457  }
458  assert(!pos->second.empty());
459  if (pos->second.back() != LLDB_INVALID_REGNUM)
460  pos->second.push_back(LLDB_INVALID_REGNUM);
461  }
462 
463  // Now update all value_regs with each register info as needed
464  const size_t num_regs = m_regs.size();
465  for (size_t i = 0; i < num_regs; ++i) {
466  if (m_value_regs_map.find(i) != m_value_regs_map.end())
467  m_regs[i].value_regs = m_value_regs_map[i].data();
468  else
469  m_regs[i].value_regs = nullptr;
470  }
471 
472  // Expand all invalidation dependencies
473  for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
474  end = m_invalidate_regs_map.end();
475  pos != end; ++pos) {
476  const uint32_t reg_num = pos->first;
477 
478  if (m_regs[reg_num].value_regs) {
479  reg_num_collection extra_invalid_regs;
480  for (const uint32_t invalidate_reg_num : pos->second) {
481  reg_to_regs_map::iterator invalidate_pos =
482  m_invalidate_regs_map.find(invalidate_reg_num);
483  if (invalidate_pos != m_invalidate_regs_map.end()) {
484  for (const uint32_t concrete_invalidate_reg_num :
485  invalidate_pos->second) {
486  if (concrete_invalidate_reg_num != reg_num)
487  extra_invalid_regs.push_back(concrete_invalidate_reg_num);
488  }
489  }
490  }
491  pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
492  extra_invalid_regs.end());
493  }
494  }
495 
496  // sort and unique all invalidate registers and make sure each is terminated
497  // with LLDB_INVALID_REGNUM
498  for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
499  end = m_invalidate_regs_map.end();
500  pos != end; ++pos) {
501  if (pos->second.size() > 1) {
502  llvm::sort(pos->second.begin(), pos->second.end());
503  reg_num_collection::iterator unique_end =
504  std::unique(pos->second.begin(), pos->second.end());
505  if (unique_end != pos->second.end())
506  pos->second.erase(unique_end, pos->second.end());
507  }
508  assert(!pos->second.empty());
509  if (pos->second.back() != LLDB_INVALID_REGNUM)
510  pos->second.push_back(LLDB_INVALID_REGNUM);
511  }
512 
513  // Now update all invalidate_regs with each register info as needed
514  for (size_t i = 0; i < num_regs; ++i) {
515  if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
516  m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
517  else
518  m_regs[i].invalidate_regs = nullptr;
519  }
520 
521  // Check if we need to automatically set the generic registers in case they
522  // weren't set
523  bool generic_regs_specified = false;
524  for (const auto &reg : m_regs) {
525  if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
526  generic_regs_specified = true;
527  break;
528  }
529  }
530 
531  if (!generic_regs_specified) {
532  switch (arch.GetMachine()) {
533  case llvm::Triple::aarch64:
534  case llvm::Triple::aarch64_32:
535  case llvm::Triple::aarch64_be:
536  for (auto &reg : m_regs) {
537  if (strcmp(reg.name, "pc") == 0)
539  else if ((strcmp(reg.name, "fp") == 0) ||
540  (strcmp(reg.name, "x29") == 0))
542  else if ((strcmp(reg.name, "lr") == 0) ||
543  (strcmp(reg.name, "x30") == 0))
545  else if ((strcmp(reg.name, "sp") == 0) ||
546  (strcmp(reg.name, "x31") == 0))
548  else if (strcmp(reg.name, "cpsr") == 0)
550  }
551  break;
552 
553  case llvm::Triple::arm:
554  case llvm::Triple::armeb:
555  case llvm::Triple::thumb:
556  case llvm::Triple::thumbeb:
557  for (auto &reg : m_regs) {
558  if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
560  else if ((strcmp(reg.name, "sp") == 0) ||
561  (strcmp(reg.name, "r13") == 0))
563  else if ((strcmp(reg.name, "lr") == 0) ||
564  (strcmp(reg.name, "r14") == 0))
566  else if ((strcmp(reg.name, "r7") == 0) &&
567  arch.GetTriple().getVendor() == llvm::Triple::Apple)
569  else if ((strcmp(reg.name, "r11") == 0) &&
570  arch.GetTriple().getVendor() != llvm::Triple::Apple)
572  else if (strcmp(reg.name, "fp") == 0)
574  else if (strcmp(reg.name, "cpsr") == 0)
576  }
577  break;
578 
579  case llvm::Triple::x86:
580  for (auto &reg : m_regs) {
581  if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
583  else if ((strcmp(reg.name, "esp") == 0) ||
584  (strcmp(reg.name, "sp") == 0))
586  else if ((strcmp(reg.name, "ebp") == 0) ||
587  (strcmp(reg.name, "fp") == 0))
589  else if ((strcmp(reg.name, "eflags") == 0) ||
590  (strcmp(reg.name, "flags") == 0))
592  }
593  break;
594 
595  case llvm::Triple::x86_64:
596  for (auto &reg : m_regs) {
597  if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
599  else if ((strcmp(reg.name, "rsp") == 0) ||
600  (strcmp(reg.name, "sp") == 0))
602  else if ((strcmp(reg.name, "rbp") == 0) ||
603  (strcmp(reg.name, "fp") == 0))
605  else if ((strcmp(reg.name, "rflags") == 0) ||
606  (strcmp(reg.name, "flags") == 0))
608  }
609  break;
610 
611  default:
612  break;
613  }
614  }
615 
616  // At this stage call ConfigureOffsets to calculate register offsets for
617  // targets supporting dynamic offset calculation. It also calculates
618  // total byte size of register data.
619  ConfigureOffsets();
620 
621  // Check if register info is reconfigurable
622  // AArch64 SVE register set has configurable register sizes
623  if (arch.GetTriple().isAArch64()) {
624  for (const auto &reg : m_regs) {
625  if (strcmp(reg.name, "vg") == 0) {
626  m_is_reconfigurable = true;
627  break;
628  }
629  }
630  }
631 }
632 
634  // We are going to create a map between remote (eRegisterKindProcessPlugin)
635  // and local (eRegisterKindLLDB) register numbers. This map will give us
636  // remote register numbers in increasing order for offset calculation.
637  std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
638  for (const auto &reg : m_regs)
639  remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =
640  reg.kinds[eRegisterKindLLDB];
641 
642  // At this stage we manually calculate g/G packet offsets of all primary
643  // registers, only if target XML or qRegisterInfo packet did not send
644  // an offset explicitly.
645  uint32_t reg_offset = 0;
646  for (auto const &regnum_pair : remote_to_local_regnum_map) {
647  if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&
648  m_regs[regnum_pair.second].value_regs == nullptr) {
649  m_regs[regnum_pair.second].byte_offset = reg_offset;
650 
651  reg_offset = m_regs[regnum_pair.second].byte_offset +
652  m_regs[regnum_pair.second].byte_size;
653  }
654  }
655 
656  // Now update all value_regs with each register info as needed
657  for (auto &reg : m_regs) {
658  if (reg.value_regs != nullptr) {
659  // Assign a valid offset to all pseudo registers if not assigned by stub.
660  // Pseudo registers with value_regs list populated will share same offset
661  // as that of their corresponding primary register in value_regs list.
662  if (reg.byte_offset == LLDB_INVALID_INDEX32) {
663  uint32_t value_regnum = reg.value_regs[0];
664  if (value_regnum != LLDB_INVALID_INDEX32)
665  reg.byte_offset =
666  GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum])
667  ->byte_offset;
668  }
669  }
670 
671  reg_offset = reg.byte_offset + reg.byte_size;
672  if (m_reg_data_byte_size < reg_offset)
673  m_reg_data_byte_size = reg_offset;
674  }
675 }
676 
677 bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; }
678 
679 size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
680 
681 size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }
682 
684  return m_reg_data_byte_size;
685 }
686 
687 const RegisterInfo *
689  if (i < m_regs.size())
690  return &m_regs[i];
691  return nullptr;
692 }
693 
695  if (i < m_regs.size())
696  return &m_regs[i];
697  return nullptr;
698 }
699 
701  uint32_t num) const {
702  uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num);
703  if (reg_index != LLDB_INVALID_REGNUM)
704  return &m_regs[reg_index];
705  return nullptr;
706 }
707 
708 const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {
709  if (i < m_sets.size())
710  return &m_sets[i];
711  return nullptr;
712 }
713 
715  bool can_create) {
716  name_collection::iterator pos, end = m_set_names.end();
717  for (pos = m_set_names.begin(); pos != end; ++pos) {
718  if (*pos == set_name)
719  return std::distance(m_set_names.begin(), pos);
720  }
721 
722  m_set_names.push_back(set_name);
723  m_set_reg_nums.resize(m_set_reg_nums.size() + 1);
724  RegisterSet new_set = {set_name.AsCString(), nullptr, 0, nullptr};
725  m_sets.push_back(new_set);
726  return m_sets.size() - 1;
727 }
728 
729 uint32_t
731  uint32_t num) const {
732  reg_collection::const_iterator pos, end = m_regs.end();
733  for (pos = m_regs.begin(); pos != end; ++pos) {
734  if (pos->kinds[kind] == num)
735  return std::distance(m_regs.begin(), pos);
736  }
737 
738  return LLDB_INVALID_REGNUM;
739 }
740 
742  m_regs.clear();
743  m_sets.clear();
744  m_set_reg_nums.clear();
745  m_set_names.clear();
746  m_value_regs_map.clear();
747  m_invalidate_regs_map.clear();
748  m_dynamic_reg_size_map.clear();
749  m_reg_data_byte_size = 0;
750  m_finalized = false;
751 }
752 
754  StreamFile s(stdout, false);
755  const size_t num_regs = m_regs.size();
756  s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
757  static_cast<const void *>(this), static_cast<uint64_t>(num_regs));
758  for (size_t i = 0; i < num_regs; ++i) {
759  s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
760  s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
761  m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding,
762  FormatManager::GetFormatAsCString(m_regs[i].format));
763  if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
764  s.Printf(", process plugin = %3u",
765  m_regs[i].kinds[eRegisterKindProcessPlugin]);
766  if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
767  s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
768  if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
769  s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
770  if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
771  s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
772  if (m_regs[i].alt_name)
773  s.Printf(", alt-name = %s", m_regs[i].alt_name);
774  if (m_regs[i].value_regs) {
775  s.Printf(", value_regs = [ ");
776  for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) {
777  s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
778  }
779  s.Printf("]");
780  }
781  if (m_regs[i].invalidate_regs) {
782  s.Printf(", invalidate_regs = [ ");
783  for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM;
784  ++j) {
785  s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
786  }
787  s.Printf("]");
788  }
789  s.EOL();
790  }
791 
792  const size_t num_sets = m_sets.size();
793  s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
794  static_cast<const void *>(this), static_cast<uint64_t>(num_sets));
795  for (size_t i = 0; i < num_sets; ++i) {
796  s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i,
797  m_sets[i].name);
798  for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) {
799  s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
800  }
801  s.Printf("]\n");
802  }
803 }
804 
805 const lldb_private::RegisterInfo *
806 DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const {
807  for (auto &reg_info : m_regs)
808  if (reg_info.name == reg_name)
809  return &reg_info;
810  return nullptr;
811 }
RegularExpression.h
lldb_private::ArchSpec::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:730
lldb_private::StructuredData::Dictionary
Definition: StructuredData.h:352
DynamicRegisterInfo::GetRegisterInfoAtIndex
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(uint32_t i) const
Definition: DynamicRegisterInfo.cpp:688
lldb_private::ArchSpec
Definition: ArchSpec.h:33
lldb_private::RegularExpression
Definition: RegularExpression.h:18
DynamicRegisterInfo::Clear
void Clear()
Definition: DynamicRegisterInfo.cpp:741
UNUSED_IF_ASSERT_DISABLED
#define UNUSED_IF_ASSERT_DISABLED(x)
Definition: lldb-defines.h:137
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:91
lldb_private::ArchSpec::GetMachine
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:667
lldb_private::StructuredData::Array
Definition: StructuredData.h:165
lldb::eRegisterKindDWARF
@ eRegisterKindDWARF
the register numbers seen DWARF
Definition: lldb-enumerations.h:229
StructuredData.h
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
FormatManager.h
lldb_private::StructuredData::Array::GetItemAtIndexAsDictionary
bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const
Definition: StructuredData.h:254
lldb_private::StructuredData::Object::DumpToStdout
void DumpToStdout(bool pretty_print=true) const
Definition: StructuredData.cpp:129
DynamicRegisterInfo::GetNumRegisters
size_t GetNumRegisters() const
Definition: DynamicRegisterInfo.cpp:679
DynamicRegisterInfo.h
DynamicRegisterInfo::GetRegisterDataByteSize
size_t GetRegisterDataByteSize() const
Definition: DynamicRegisterInfo.cpp:683
OptionArgParser.h
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
DynamicRegisterInfo::GetNumRegisterSets
size_t GetNumRegisterSets() const
Definition: DynamicRegisterInfo.cpp:681
DynamicRegisterInfo::DynamicRegisterInfo
DynamicRegisterInfo()=default
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
StringExtractor
Definition: StringExtractor.h:19
lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
Definition: StructuredData.h:403
lldb::eRegisterKindEHFrame
@ eRegisterKindEHFrame
the register numbers seen in eh_frame
Definition: lldb-enumerations.h:228
LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
DynamicRegisterInfo::ConfigureOffsets
void ConfigureOffsets()
Definition: DynamicRegisterInfo.cpp:633
StringConvert.h
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:234
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
lldb::eRegisterKindProcessPlugin
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
Definition: lldb-enumerations.h:232
lldb_private::repro::Finalize
llvm::Error Finalize(Loader *loader)
Definition: Reproducer.cpp:365
DynamicRegisterInfo::AddRegister
void AddRegister(lldb_private::RegisterInfo &reg_info, lldb_private::ConstString &reg_name, lldb_private::ConstString &reg_alt_name, lldb_private::ConstString &set_name)
Definition: DynamicRegisterInfo.cpp:398
lldb::eEncodingUint
@ eEncodingUint
unsigned integer
Definition: lldb-enumerations.h:148
lldb_private::ConstString
Definition: ConstString.h:40
DynamicRegisterInfo::IsReconfigurable
bool IsReconfigurable()
Definition: DynamicRegisterInfo.cpp:677
DynamicRegisterInfo::reg_num_collection
std::vector< uint32_t > reg_num_collection
Definition: DynamicRegisterInfo.h:79
StringExtractor::GetHexBytesAvail
size_t GetHexBytesAvail(llvm::MutableArrayRef< uint8_t > dest)
Definition: StringExtractor.cpp:287
DynamicRegisterInfo::Dump
void Dump() const
Definition: DynamicRegisterInfo.cpp:753
set
set(option_framework FRAMEWORK) endif() if(LLDB_ENABLE_PYTHON) get_target_property(python_bindings_dir swig_wrapper_python BINARY_DIR) set(lldb_python_wrapper $
Definition: API/CMakeLists.txt:9
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:39
DynamicRegisterInfo::operator=
DynamicRegisterInfo & operator=(DynamicRegisterInfo &)=default
DynamicRegisterInfo::GetRegisterInfo
const lldb_private::RegisterInfo * GetRegisterInfo(uint32_t kind, uint32_t num) const
Definition: DynamicRegisterInfo.cpp:700
DynamicRegisterInfo::GetRegisterSetIndexByName
uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name, bool can_create)
Definition: DynamicRegisterInfo.cpp:714
StreamFile.h
uint32_t
LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
DynamicRegisterInfo
Definition: DynamicRegisterInfo.h:19
DynamicRegisterInfo::GetRegisterSet
const lldb_private::RegisterSet * GetRegisterSet(uint32_t i) const
Definition: DynamicRegisterInfo.cpp:708
lldb_private::Stream::EOL
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
StringExtractor.h
lldb_private::StructuredData::Array::GetItemAtIndexAsInteger
bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const
Definition: StructuredData.h:196
ArchSpec.h
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
DynamicRegisterInfo::SetRegisterInfo
size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, const lldb_private::ArchSpec &arch)
Definition: DynamicRegisterInfo.cpp:61
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
DynamicRegisterInfo::MoveFrom
void MoveFrom(DynamicRegisterInfo &&info)
Definition: DynamicRegisterInfo.cpp:39
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb::eFormatHex
@ eFormatHex
Definition: lldb-enumerations.h:169
LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
lldb_private::RegularExpression::Execute
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
Definition: RegularExpression.cpp:23
lldb::eByteOrderBig
@ eByteOrderBig
Definition: lldb-enumerations.h:140
LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
lldb_private::StringConvert::ToUInt32
uint32_t ToUInt32(const char *s, uint32_t fail_value=0, int base=0, bool *success_ptr=nullptr)
Definition: StringConvert.cpp:32
lldb_private::StreamFile
Definition: StreamFile.h:22
LLDB_INVALID_INDEX32
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:87
DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber
uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num) const
Definition: DynamicRegisterInfo.cpp:730
lldb_private::StructuredData::Array::GetItemAtIndexAsString
bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const
Definition: StructuredData.h:216
lldb_private::StructuredData::Dictionary::GetValueForKeyAsString
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
Definition: StructuredData.h:423
lldb_private::StructuredData::Dictionary::GetValueForKeyAsArray
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
Definition: StructuredData.h:478
lldb_private::StructuredData::Array::GetSize
size_t GetSize() const
Definition: StructuredData.h:180
DynamicRegisterInfo::Finalize
void Finalize(const lldb_private::ArchSpec &arch)
Definition: DynamicRegisterInfo.cpp:433
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
lldb
Definition: SBAddress.h:15
UINT64_MAX
#define UINT64_MAX
Definition: lldb-defines.h:35
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138
LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:66