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
15#include "lldb/Utility/Log.h"
19
20using namespace lldb;
21using 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
47 m_reg_data_byte_size = info.m_reg_data_byte_size;
48 m_finalized = info.m_finalized;
49
50 if (m_finalized) {
51 const size_t num_sets = m_sets.size();
52 for (size_t set = 0; set < num_sets; ++set)
53 m_sets[set].registers = m_set_reg_nums[set].data();
54 }
55
56 info.Clear();
57}
58
60 uint32_t index, llvm::StringRef slice_str, lldb::ByteOrder byte_order) {
61 // Slices use the following format:
62 // REGNAME[MSBIT:LSBIT]
63 // REGNAME - name of the register to grab a slice of
64 // MSBIT - the most significant bit at which the current register value
65 // starts at
66 // LSBIT - the least significant bit at which the current register value
67 // ends at
68 static llvm::Regex g_bitfield_regex(
69 "([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
70 llvm::SmallVector<llvm::StringRef, 4> matches;
71 if (!g_bitfield_regex.match(slice_str, &matches))
72 return llvm::createStringError(
73 llvm::inconvertibleErrorCode(),
74 "failed to match against register bitfield regex (slice: %s)",
75 slice_str.str().c_str());
76
77 llvm::StringRef reg_name_str = matches[1];
78 llvm::StringRef msbit_str = matches[2];
79 llvm::StringRef lsbit_str = matches[3];
80 uint32_t msbit;
81 uint32_t lsbit;
82 if (!llvm::to_integer(msbit_str, msbit) ||
83 !llvm::to_integer(lsbit_str, lsbit))
84 return llvm::createStringError(
85 llvm::inconvertibleErrorCode(), "msbit (%s) or lsbit (%s) are invalid",
86 msbit_str.str().c_str(), lsbit_str.str().c_str());
87
88 if (msbit <= lsbit)
89 return llvm::createStringError(llvm::inconvertibleErrorCode(),
90 "msbit (%u) must be greater than lsbit (%u)",
91 msbit, lsbit);
92
93 const uint32_t msbyte = msbit / 8;
94 const uint32_t lsbyte = lsbit / 8;
95
96 const RegisterInfo *containing_reg_info = GetRegisterInfo(reg_name_str);
97 if (!containing_reg_info)
98 return llvm::createStringError(llvm::inconvertibleErrorCode(),
99 "invalid concrete register \"%s\"",
100 reg_name_str.str().c_str());
101
102 const uint32_t max_bit = containing_reg_info->byte_size * 8;
103
104 if (msbit > max_bit)
105 return llvm::createStringError(
106 llvm::inconvertibleErrorCode(),
107 "msbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
108 msbit, reg_name_str.str().c_str(), max_bit);
109 if (lsbit > max_bit)
110 return llvm::createStringError(
111 llvm::inconvertibleErrorCode(),
112 "lsbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
113 lsbit, reg_name_str.str().c_str(), max_bit);
114
115 m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]]
116 .push_back(index);
117 m_value_regs_map[index].push_back(
118 containing_reg_info->kinds[eRegisterKindLLDB]);
119 m_invalidate_regs_map[index].push_back(
120 containing_reg_info->kinds[eRegisterKindLLDB]);
121
122 if (byte_order == eByteOrderLittle)
123 return containing_reg_info->byte_offset + lsbyte;
124 if (byte_order == eByteOrderBig)
125 return containing_reg_info->byte_offset + msbyte;
126 llvm_unreachable("Invalid byte order");
127}
128
130 uint32_t index, StructuredData::Array &composite_reg_list,
131 lldb::ByteOrder byte_order) {
132 const size_t num_composite_regs = composite_reg_list.GetSize();
133 if (num_composite_regs == 0)
134 return llvm::createStringError(llvm::inconvertibleErrorCode(),
135 "\"composite\" list is empty");
136
137 uint32_t composite_offset = UINT32_MAX;
138 for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
139 ++composite_idx) {
140 ConstString composite_reg_name;
141 if (!composite_reg_list.GetItemAtIndexAsString(composite_idx,
142 composite_reg_name, nullptr))
143 return llvm::createStringError(
144 llvm::inconvertibleErrorCode(),
145 "\"composite\" list value is not a Python string at index %d",
146 composite_idx);
147
148 const RegisterInfo *composite_reg_info =
149 GetRegisterInfo(composite_reg_name.GetStringRef());
150 if (!composite_reg_info)
151 return llvm::createStringError(
152 llvm::inconvertibleErrorCode(),
153 "failed to find composite register by name: \"%s\"",
154 composite_reg_name.GetCString());
155
156 composite_offset =
157 std::min(composite_offset, composite_reg_info->byte_offset);
158 m_value_regs_map[index].push_back(
159 composite_reg_info->kinds[eRegisterKindLLDB]);
160 m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]]
161 .push_back(index);
162 m_invalidate_regs_map[index].push_back(
163 composite_reg_info->kinds[eRegisterKindLLDB]);
164 }
165
166 return composite_offset;
167}
168
170 uint32_t index, StructuredData::Dictionary &reg_info_dict,
171 lldb::ByteOrder byte_order) {
172 uint32_t byte_offset;
173 if (reg_info_dict.GetValueForKeyAsInteger("offset", byte_offset))
174 return byte_offset;
175
176 // No offset for this register, see if the register has a value
177 // expression which indicates this register is part of another register.
178 // Value expressions are things like "rax[31:0]" which state that the
179 // current register's value is in a concrete register "rax" in bits 31:0.
180 // If there is a value expression we can calculate the offset
181 llvm::StringRef slice_str;
182 if (reg_info_dict.GetValueForKeyAsString("slice", slice_str, nullptr))
183 return ByteOffsetFromSlice(index, slice_str, byte_order);
184
185 StructuredData::Array *composite_reg_list;
186 if (reg_info_dict.GetValueForKeyAsArray("composite", composite_reg_list))
187 return ByteOffsetFromComposite(index, *composite_reg_list, byte_order);
188
189 return llvm::createStringError(llvm::inconvertibleErrorCode(),
190 "insufficient data to calculate byte offset");
191}
192
193size_t
195 const ArchSpec &arch) {
196 Log *log = GetLog(LLDBLog::Object);
197 assert(!m_finalized);
198 StructuredData::Array *sets = nullptr;
199 if (dict.GetValueForKeyAsArray("sets", sets)) {
200 const uint32_t num_sets = sets->GetSize();
201 for (uint32_t i = 0; i < num_sets; ++i) {
202 ConstString set_name;
203 if (sets->GetItemAtIndexAsString(i, set_name) && !set_name.IsEmpty()) {
204 m_sets.push_back({set_name.AsCString(), nullptr, 0, nullptr});
205 } else {
206 Clear();
207 printf("error: register sets must have valid names\n");
208 return 0;
209 }
210 }
211 m_set_reg_nums.resize(m_sets.size());
212 }
213
214 StructuredData::Array *regs = nullptr;
215 if (!dict.GetValueForKeyAsArray("registers", regs))
216 return 0;
217
218 const ByteOrder byte_order = arch.GetByteOrder();
219
220 const uint32_t num_regs = regs->GetSize();
221 // typedef std::map<std::string, std::vector<std::string> >
222 // InvalidateNameMap;
223 // InvalidateNameMap invalidate_map;
224 for (uint32_t i = 0; i < num_regs; ++i) {
225 StructuredData::Dictionary *reg_info_dict = nullptr;
226 if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) {
227 Clear();
228 printf("error: items in the 'registers' array must be dictionaries\n");
229 regs->DumpToStdout();
230 return 0;
231 }
232
233 // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16,
234 // 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,
235 // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
236 RegisterInfo reg_info;
237 std::vector<uint32_t> value_regs;
238 std::vector<uint32_t> invalidate_regs;
239 memset(&reg_info, 0, sizeof(reg_info));
240
241 ConstString name_val;
242 ConstString alt_name_val;
243 if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) {
244 Clear();
245 printf("error: registers must have valid names and offsets\n");
246 reg_info_dict->DumpToStdout();
247 return 0;
248 }
249 reg_info.name = name_val.GetCString();
250 reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
251 reg_info.alt_name = alt_name_val.GetCString();
252
253 llvm::Expected<uint32_t> byte_offset =
254 ByteOffsetFromRegInfoDict(i, *reg_info_dict, byte_order);
255 if (byte_offset)
256 reg_info.byte_offset = byte_offset.get();
257 else {
258 LLDB_LOG_ERROR(log, byte_offset.takeError(),
259 "error while parsing register {1}: {0}", reg_info.name);
260 Clear();
261 reg_info_dict->DumpToStdout();
262 return 0;
263 }
264
265 int64_t bitsize = 0;
266 if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
267 Clear();
268 printf("error: invalid or missing 'bitsize' key/value pair in register "
269 "dictionary\n");
270 reg_info_dict->DumpToStdout();
271 return 0;
272 }
273
274 reg_info.byte_size = bitsize / 8;
275
276 llvm::StringRef format_str;
277 if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
278 if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format,
279 nullptr)
280 .Fail()) {
281 Clear();
282 printf("error: invalid 'format' value in register dictionary\n");
283 reg_info_dict->DumpToStdout();
284 return 0;
285 }
286 } else {
287 reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,
288 eFormatHex);
289 }
290
291 llvm::StringRef encoding_str;
292 if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
293 reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);
294 else
295 reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,
297
298 size_t set = 0;
299 if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) ||
300 set >= m_sets.size()) {
301 Clear();
302 printf("error: invalid 'set' value in register dictionary, valid values "
303 "are 0 - %i\n",
304 (int)set);
305 reg_info_dict->DumpToStdout();
306 return 0;
307 }
308
309 // Fill in the register numbers
310 reg_info.kinds[lldb::eRegisterKindLLDB] = i;
311 reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
312 uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
313 reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,
315 if (eh_frame_regno == LLDB_INVALID_REGNUM)
316 reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,
318 reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
319 reg_info_dict->GetValueForKeyAsInteger(
320 "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
321 llvm::StringRef generic_str;
322 if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
323 reg_info.kinds[lldb::eRegisterKindGeneric] =
325 else
326 reg_info_dict->GetValueForKeyAsInteger(
327 "generic", reg_info.kinds[lldb::eRegisterKindGeneric],
329
330 // Check if this register invalidates any other register values when it is
331 // modified
332 StructuredData::Array *invalidate_reg_list = nullptr;
333 if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",
334 invalidate_reg_list)) {
335 const size_t num_regs = invalidate_reg_list->GetSize();
336 if (num_regs > 0) {
337 for (uint32_t idx = 0; idx < num_regs; ++idx) {
338 ConstString invalidate_reg_name;
339 uint64_t invalidate_reg_num;
340 if (invalidate_reg_list->GetItemAtIndexAsString(
341 idx, invalidate_reg_name)) {
342 const RegisterInfo *invalidate_reg_info =
343 GetRegisterInfo(invalidate_reg_name.GetStringRef());
344 if (invalidate_reg_info) {
345 m_invalidate_regs_map[i].push_back(
346 invalidate_reg_info->kinds[eRegisterKindLLDB]);
347 } else {
348 // TODO: print error invalid slice string that doesn't follow the
349 // format
350 printf("error: failed to find a 'invalidate-regs' register for "
351 "\"%s\" while parsing register \"%s\"\n",
352 invalidate_reg_name.GetCString(), reg_info.name);
353 }
354 } else if (invalidate_reg_list->GetItemAtIndexAsInteger(
355 idx, invalidate_reg_num)) {
356 if (invalidate_reg_num != UINT64_MAX)
357 m_invalidate_regs_map[i].push_back(invalidate_reg_num);
358 else
359 printf("error: 'invalidate-regs' list value wasn't a valid "
360 "integer\n");
361 } else {
362 printf("error: 'invalidate-regs' list value wasn't a python string "
363 "or integer\n");
364 }
365 }
366 } else {
367 printf("error: 'invalidate-regs' contained an empty list\n");
368 }
369 }
370
371 // Calculate the register offset
372 const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
373 if (m_reg_data_byte_size < end_reg_offset)
374 m_reg_data_byte_size = end_reg_offset;
375
376 m_regs.push_back(reg_info);
377 m_set_reg_nums[set].push_back(i);
378 }
379 Finalize(arch);
380 return m_regs.size();
381}
382
384 std::vector<DynamicRegisterInfo::Register> &&regs,
385 const ArchSpec &arch) {
386 assert(!m_finalized);
387
388 for (auto it : llvm::enumerate(regs)) {
389 uint32_t local_regnum = it.index();
390 const DynamicRegisterInfo::Register &reg = it.value();
391
392 assert(reg.name);
393 assert(reg.set_name);
394
395 if (!reg.value_regs.empty())
396 m_value_regs_map[local_regnum] = std::move(reg.value_regs);
397 if (!reg.invalidate_regs.empty())
398 m_invalidate_regs_map[local_regnum] = std::move(reg.invalidate_regs);
399 if (reg.value_reg_offset != 0) {
400 assert(reg.value_regs.size() == 1);
401 m_value_reg_offset_map[local_regnum] = reg.value_reg_offset;
402 }
403
404 struct RegisterInfo reg_info {
405 reg.name.AsCString(), reg.alt_name.AsCString(), reg.byte_size,
406 reg.byte_offset, reg.encoding, reg.format,
408 reg.regnum_remote, local_regnum},
409 // value_regs and invalidate_regs are filled by Finalize()
410 nullptr, nullptr
411 };
412
413 m_regs.push_back(reg_info);
414
416 assert(set < m_sets.size());
417 assert(set < m_set_reg_nums.size());
418 assert(set < m_set_names.size());
419 m_set_reg_nums[set].push_back(local_regnum);
420 };
421
422 Finalize(arch);
423 return m_regs.size();
424}
425
427 if (m_finalized)
428 return;
429
430 m_finalized = true;
431 const size_t num_sets = m_sets.size();
432 for (size_t set = 0; set < num_sets; ++set) {
433 assert(m_sets.size() == m_set_reg_nums.size());
434 m_sets[set].num_registers = m_set_reg_nums[set].size();
435 m_sets[set].registers = m_set_reg_nums[set].data();
436 }
437
438 // make sure value_regs are terminated with LLDB_INVALID_REGNUM
439
440 for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),
441 end = m_value_regs_map.end();
442 pos != end; ++pos) {
443 if (pos->second.back() != LLDB_INVALID_REGNUM)
444 pos->second.push_back(LLDB_INVALID_REGNUM);
445 }
446
447 // Now update all value_regs with each register info as needed
448 const size_t num_regs = m_regs.size();
449 for (size_t i = 0; i < num_regs; ++i) {
450 if (m_value_regs_map.find(i) != m_value_regs_map.end())
451 m_regs[i].value_regs = m_value_regs_map[i].data();
452 else
453 m_regs[i].value_regs = nullptr;
454 }
455
456 // Expand all invalidation dependencies
457 for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
458 end = m_invalidate_regs_map.end();
459 pos != end; ++pos) {
460 const uint32_t reg_num = pos->first;
461
462 if (m_regs[reg_num].value_regs) {
463 reg_num_collection extra_invalid_regs;
464 for (const uint32_t invalidate_reg_num : pos->second) {
465 reg_to_regs_map::iterator invalidate_pos =
466 m_invalidate_regs_map.find(invalidate_reg_num);
467 if (invalidate_pos != m_invalidate_regs_map.end()) {
468 for (const uint32_t concrete_invalidate_reg_num :
469 invalidate_pos->second) {
470 if (concrete_invalidate_reg_num != reg_num)
471 extra_invalid_regs.push_back(concrete_invalidate_reg_num);
472 }
473 }
474 }
475 pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
476 extra_invalid_regs.end());
477 }
478 }
479
480 // sort and unique all invalidate registers and make sure each is terminated
481 // with LLDB_INVALID_REGNUM
482 for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
483 end = m_invalidate_regs_map.end();
484 pos != end; ++pos) {
485 if (pos->second.size() > 1) {
486 llvm::sort(pos->second);
487 reg_num_collection::iterator unique_end =
488 std::unique(pos->second.begin(), pos->second.end());
489 if (unique_end != pos->second.end())
490 pos->second.erase(unique_end, pos->second.end());
491 }
492 assert(!pos->second.empty());
493 if (pos->second.back() != LLDB_INVALID_REGNUM)
494 pos->second.push_back(LLDB_INVALID_REGNUM);
495 }
496
497 // Now update all invalidate_regs with each register info as needed
498 for (size_t i = 0; i < num_regs; ++i) {
499 if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
500 m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
501 else
502 m_regs[i].invalidate_regs = nullptr;
503 }
504
505 // Check if we need to automatically set the generic registers in case they
506 // weren't set
507 bool generic_regs_specified = false;
508 for (const auto &reg : m_regs) {
509 if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
510 generic_regs_specified = true;
511 break;
512 }
513 }
514
515 if (!generic_regs_specified) {
516 switch (arch.GetMachine()) {
517 case llvm::Triple::aarch64:
518 case llvm::Triple::aarch64_32:
519 case llvm::Triple::aarch64_be:
520 for (auto &reg : m_regs) {
521 if (strcmp(reg.name, "pc") == 0)
523 else if ((strcmp(reg.name, "fp") == 0) ||
524 (strcmp(reg.name, "x29") == 0))
526 else if ((strcmp(reg.name, "lr") == 0) ||
527 (strcmp(reg.name, "x30") == 0))
529 else if ((strcmp(reg.name, "sp") == 0) ||
530 (strcmp(reg.name, "x31") == 0))
532 else if (strcmp(reg.name, "cpsr") == 0)
534 }
535 break;
536
537 case llvm::Triple::arm:
538 case llvm::Triple::armeb:
539 case llvm::Triple::thumb:
540 case llvm::Triple::thumbeb:
541 for (auto &reg : m_regs) {
542 if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
544 else if ((strcmp(reg.name, "sp") == 0) ||
545 (strcmp(reg.name, "r13") == 0))
547 else if ((strcmp(reg.name, "lr") == 0) ||
548 (strcmp(reg.name, "r14") == 0))
550 else if ((strcmp(reg.name, "r7") == 0) &&
551 arch.GetTriple().getVendor() == llvm::Triple::Apple)
553 else if ((strcmp(reg.name, "r11") == 0) &&
554 arch.GetTriple().getVendor() != llvm::Triple::Apple)
556 else if (strcmp(reg.name, "fp") == 0)
558 else if (strcmp(reg.name, "cpsr") == 0)
560 }
561 break;
562
563 case llvm::Triple::x86:
564 for (auto &reg : m_regs) {
565 if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
567 else if ((strcmp(reg.name, "esp") == 0) ||
568 (strcmp(reg.name, "sp") == 0))
570 else if ((strcmp(reg.name, "ebp") == 0) ||
571 (strcmp(reg.name, "fp") == 0))
573 else if ((strcmp(reg.name, "eflags") == 0) ||
574 (strcmp(reg.name, "flags") == 0))
576 }
577 break;
578
579 case llvm::Triple::x86_64:
580 for (auto &reg : m_regs) {
581 if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
583 else if ((strcmp(reg.name, "rsp") == 0) ||
584 (strcmp(reg.name, "sp") == 0))
586 else if ((strcmp(reg.name, "rbp") == 0) ||
587 (strcmp(reg.name, "fp") == 0))
589 else if ((strcmp(reg.name, "rflags") == 0) ||
590 (strcmp(reg.name, "eflags") == 0) ||
591 (strcmp(reg.name, "flags") == 0))
593 }
594 break;
595
596 default:
597 break;
598 }
599 }
600
601 // At this stage call ConfigureOffsets to calculate register offsets for
602 // targets supporting dynamic offset calculation. It also calculates
603 // total byte size of register data.
605
606 // Check if register info is reconfigurable
607 // AArch64 SVE register set has configurable register sizes
608 if (arch.GetTriple().isAArch64()) {
609 for (const auto &reg : m_regs) {
610 if (strcmp(reg.name, "vg") == 0) {
611 m_is_reconfigurable = true;
612 break;
613 }
614 }
615 }
616}
617
619 // We are going to create a map between remote (eRegisterKindProcessPlugin)
620 // and local (eRegisterKindLLDB) register numbers. This map will give us
621 // remote register numbers in increasing order for offset calculation.
622 std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
623 for (const auto &reg : m_regs)
624 remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =
625 reg.kinds[eRegisterKindLLDB];
626
627 // At this stage we manually calculate g/G packet offsets of all primary
628 // registers, only if target XML or qRegisterInfo packet did not send
629 // an offset explicitly.
630 uint32_t reg_offset = 0;
631 for (auto const &regnum_pair : remote_to_local_regnum_map) {
632 if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&
633 m_regs[regnum_pair.second].value_regs == nullptr) {
634 m_regs[regnum_pair.second].byte_offset = reg_offset;
635
636 reg_offset = m_regs[regnum_pair.second].byte_offset +
637 m_regs[regnum_pair.second].byte_size;
638 }
639 }
640
641 // Now update all value_regs with each register info as needed
642 for (auto &reg : m_regs) {
643 if (reg.value_regs != nullptr) {
644 // Assign a valid offset to all pseudo registers that have only a single
645 // parent register in value_regs list, if not assigned by stub. Pseudo
646 // registers with value_regs list populated will share same offset as
647 // that of their corresponding parent register.
648 if (reg.byte_offset == LLDB_INVALID_INDEX32) {
649 uint32_t value_regnum = reg.value_regs[0];
650 if (value_regnum != LLDB_INVALID_INDEX32 &&
651 reg.value_regs[1] == LLDB_INVALID_INDEX32) {
652 reg.byte_offset =
653 GetRegisterInfoAtIndex(value_regnum)->byte_offset;
654 auto it = m_value_reg_offset_map.find(reg.kinds[eRegisterKindLLDB]);
655 if (it != m_value_reg_offset_map.end())
656 reg.byte_offset += it->second;
657 }
658 }
659 }
660
661 reg_offset = reg.byte_offset + reg.byte_size;
662 if (m_reg_data_byte_size < reg_offset)
663 m_reg_data_byte_size = reg_offset;
664 }
665}
666
668
669size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }
670
671size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }
672
675}
676
677const RegisterInfo *
679 if (i < m_regs.size())
680 return &m_regs[i];
681 return nullptr;
682}
683
685 uint32_t num) const {
686 uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num);
687 if (reg_index != LLDB_INVALID_REGNUM)
688 return &m_regs[reg_index];
689 return nullptr;
690}
691
693 if (i < m_sets.size())
694 return &m_sets[i];
695 return nullptr;
696}
697
700 bool can_create) {
701 name_collection::iterator pos, end = m_set_names.end();
702 for (pos = m_set_names.begin(); pos != end; ++pos) {
703 if (*pos == set_name)
704 return std::distance(m_set_names.begin(), pos);
705 }
706
707 m_set_names.push_back(set_name);
708 m_set_reg_nums.resize(m_set_reg_nums.size() + 1);
709 RegisterSet new_set = {set_name.AsCString(), nullptr, 0, nullptr};
710 m_sets.push_back(new_set);
711 return m_sets.size() - 1;
712}
713
716 uint32_t num) const {
717 reg_collection::const_iterator pos, end = m_regs.end();
718 for (pos = m_regs.begin(); pos != end; ++pos) {
719 if (pos->kinds[kind] == num)
720 return std::distance(m_regs.begin(), pos);
721 }
722
723 return LLDB_INVALID_REGNUM;
724}
725
727 m_regs.clear();
728 m_sets.clear();
729 m_set_reg_nums.clear();
730 m_set_names.clear();
731 m_value_regs_map.clear();
732 m_invalidate_regs_map.clear();
734 m_finalized = false;
735}
736
738 StreamFile s(stdout, false);
739 const size_t num_regs = m_regs.size();
740 s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
741 static_cast<const void *>(this), static_cast<uint64_t>(num_regs));
742 for (size_t i = 0; i < num_regs; ++i) {
743 s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
744 s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
745 m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding,
748 s.Printf(", process plugin = %3u",
751 s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
753 s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
755 s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
756 if (m_regs[i].alt_name)
757 s.Printf(", alt-name = %s", m_regs[i].alt_name);
758 if (m_regs[i].value_regs) {
759 s.Printf(", value_regs = [ ");
760 for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) {
761 s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
762 }
763 s.Printf("]");
764 }
765 if (m_regs[i].invalidate_regs) {
766 s.Printf(", invalidate_regs = [ ");
767 for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM;
768 ++j) {
769 s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
770 }
771 s.Printf("]");
772 }
773 s.EOL();
774 }
775
776 const size_t num_sets = m_sets.size();
777 s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
778 static_cast<const void *>(this), static_cast<uint64_t>(num_sets));
779 for (size_t i = 0; i < num_sets; ++i) {
780 s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i,
781 m_sets[i].name);
782 for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) {
783 s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
784 }
785 s.Printf("]\n");
786 }
787}
788
789const lldb_private::RegisterInfo *
790DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const {
791 for (auto &reg_info : m_regs)
792 if (reg_info.name == reg_name)
793 return &reg_info;
794 return nullptr;
795}
796
798 std::vector<DynamicRegisterInfo::Register> &regs,
799 DynamicRegisterInfo::Register new_reg_info) {
800 assert(!new_reg_info.value_regs.empty());
801 const uint32_t reg_num = regs.size();
802 regs.push_back(new_reg_info);
803
804 std::map<uint32_t, std::vector<uint32_t>> new_invalidates;
805 for (uint32_t value_reg : new_reg_info.value_regs) {
806 // copy value_regs to invalidate_regs
807 new_invalidates[reg_num].push_back(value_reg);
808
809 // copy invalidate_regs from the parent register
810 llvm::append_range(new_invalidates[reg_num],
811 regs[value_reg].invalidate_regs);
812
813 // add reverse invalidate entries
814 for (uint32_t x : new_invalidates[reg_num])
815 new_invalidates[x].push_back(reg_num);
816 }
817
818 for (const auto &x : new_invalidates)
819 llvm::append_range(regs[x.first].invalidate_regs, x.second);
820}
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:360
An architecture specification class.
Definition: ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:463
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:741
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:678
static lldb::Encoding StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value=lldb::eEncodingInvalid)
Definition: Args.cpp:421
static uint32_t StringToGenericRegister(llvm::StringRef s)
Definition: Args.cpp:431
A uniqued constant string class.
Definition: ConstString.h:39
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:192
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:303
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:201
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:215
size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, const lldb_private::ArchSpec &arch)
std::vector< uint32_t > reg_num_collection
const lldb_private::RegisterSet * GetRegisterSet(uint32_t i) const
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(uint32_t i) const
uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num) const
llvm::Expected< uint32_t > ByteOffsetFromComposite(uint32_t index, lldb_private::StructuredData::Array &composite_reg_list, lldb::ByteOrder byte_order)
void Finalize(const lldb_private::ArchSpec &arch)
void MoveFrom(DynamicRegisterInfo &&info)
llvm::Expected< uint32_t > ByteOffsetFromSlice(uint32_t index, llvm::StringRef slice_str, lldb::ByteOrder byte_order)
uint32_t GetRegisterSetIndexByName(const lldb_private::ConstString &set_name, bool can_create)
const lldb_private::RegisterInfo * GetRegisterInfo(uint32_t kind, uint32_t num) const
DynamicRegisterInfo & operator=(DynamicRegisterInfo &)=default
llvm::iterator_range< reg_collection::const_iterator > registers() const
llvm::Expected< uint32_t > ByteOffsetFromRegInfoDict(uint32_t index, lldb_private::StructuredData::Dictionary &reg_info_dict, lldb::ByteOrder byte_order)
static const char * GetFormatAsCString(lldb::Format format)
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const
bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const
bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void DumpToStdout(bool pretty_print=true) const
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:54
#define UINT64_MAX
Definition: lldb-defines.h:23
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:75
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:52
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:55
#define UINT32_MAX
Definition: lldb-defines.h:19
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:51
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:53
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:309
void addSupplementaryRegister(std::vector< DynamicRegisterInfo::Register > &regs, DynamicRegisterInfo::Register new_reg_info)
Definition: SBAddress.h:15
@ eEncodingUint
unsigned integer
ByteOrder
Byte ordering definitions.
@ eByteOrderLittle
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF
@ eRegisterKindEHFrame
the register numbers seen in eh_frame
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
static Status ToFormat(const char *s, lldb::Format &format, size_t *byte_size_ptr)