1 //===-- DynamicRegisterInfo.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/DynamicRegisterInfo.h"
10 #include "lldb/DataFormatters/FormatManager.h"
11 #include "lldb/Host/StreamFile.h"
12 #include "lldb/Interpreter/OptionArgParser.h"
13 #include "lldb/Utility/ArchSpec.h"
14 #include "lldb/Utility/LLDBLog.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/RegularExpression.h"
17 #include "lldb/Utility/StringExtractor.h"
18 #include "lldb/Utility/StructuredData.h"
21 using namespace lldb_private
;
23 std::unique_ptr
<DynamicRegisterInfo
>
24 DynamicRegisterInfo::Create(const StructuredData::Dictionary
&dict
,
25 const ArchSpec
&arch
) {
26 auto dyn_reg_info
= std::make_unique
<DynamicRegisterInfo
>();
30 if (dyn_reg_info
->SetRegisterInfo(dict
, arch
) == 0)
36 DynamicRegisterInfo::DynamicRegisterInfo(DynamicRegisterInfo
&&info
) {
37 MoveFrom(std::move(info
));
41 DynamicRegisterInfo::operator=(DynamicRegisterInfo
&&info
) {
42 MoveFrom(std::move(info
));
46 void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo
&&info
) {
47 m_regs
= std::move(info
.m_regs
);
48 m_sets
= std::move(info
.m_sets
);
49 m_set_reg_nums
= std::move(info
.m_set_reg_nums
);
50 m_set_names
= std::move(info
.m_set_names
);
51 m_value_regs_map
= std::move(info
.m_value_regs_map
);
52 m_invalidate_regs_map
= std::move(info
.m_invalidate_regs_map
);
54 m_reg_data_byte_size
= info
.m_reg_data_byte_size
;
55 m_finalized
= info
.m_finalized
;
58 const size_t num_sets
= m_sets
.size();
59 for (size_t set
= 0; set
< num_sets
; ++set
)
60 m_sets
[set
].registers
= m_set_reg_nums
[set
].data();
66 llvm::Expected
<uint32_t> DynamicRegisterInfo::ByteOffsetFromSlice(
67 uint32_t index
, llvm::StringRef slice_str
, lldb::ByteOrder byte_order
) {
68 // Slices use the following format:
69 // REGNAME[MSBIT:LSBIT]
70 // REGNAME - name of the register to grab a slice of
71 // MSBIT - the most significant bit at which the current register value
73 // LSBIT - the least significant bit at which the current register value
75 static llvm::Regex
g_bitfield_regex(
76 "([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
77 llvm::SmallVector
<llvm::StringRef
, 4> matches
;
78 if (!g_bitfield_regex
.match(slice_str
, &matches
))
79 return llvm::createStringError(
80 llvm::inconvertibleErrorCode(),
81 "failed to match against register bitfield regex (slice: %s)",
82 slice_str
.str().c_str());
84 llvm::StringRef reg_name_str
= matches
[1];
85 llvm::StringRef msbit_str
= matches
[2];
86 llvm::StringRef lsbit_str
= matches
[3];
89 if (!llvm::to_integer(msbit_str
, msbit
) ||
90 !llvm::to_integer(lsbit_str
, lsbit
))
91 return llvm::createStringError(
92 llvm::inconvertibleErrorCode(), "msbit (%s) or lsbit (%s) are invalid",
93 msbit_str
.str().c_str(), lsbit_str
.str().c_str());
96 return llvm::createStringError(llvm::inconvertibleErrorCode(),
97 "msbit (%u) must be greater than lsbit (%u)",
100 const uint32_t msbyte
= msbit
/ 8;
101 const uint32_t lsbyte
= lsbit
/ 8;
103 const RegisterInfo
*containing_reg_info
= GetRegisterInfo(reg_name_str
);
104 if (!containing_reg_info
)
105 return llvm::createStringError(llvm::inconvertibleErrorCode(),
106 "invalid concrete register \"%s\"",
107 reg_name_str
.str().c_str());
109 const uint32_t max_bit
= containing_reg_info
->byte_size
* 8;
112 return llvm::createStringError(
113 llvm::inconvertibleErrorCode(),
114 "msbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
115 msbit
, reg_name_str
.str().c_str(), max_bit
);
117 return llvm::createStringError(
118 llvm::inconvertibleErrorCode(),
119 "lsbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
120 lsbit
, reg_name_str
.str().c_str(), max_bit
);
122 m_invalidate_regs_map
[containing_reg_info
->kinds
[eRegisterKindLLDB
]]
124 m_value_regs_map
[index
].push_back(
125 containing_reg_info
->kinds
[eRegisterKindLLDB
]);
126 m_invalidate_regs_map
[index
].push_back(
127 containing_reg_info
->kinds
[eRegisterKindLLDB
]);
129 if (byte_order
== eByteOrderLittle
)
130 return containing_reg_info
->byte_offset
+ lsbyte
;
131 if (byte_order
== eByteOrderBig
)
132 return containing_reg_info
->byte_offset
+ msbyte
;
133 llvm_unreachable("Invalid byte order");
136 llvm::Expected
<uint32_t> DynamicRegisterInfo::ByteOffsetFromComposite(
137 uint32_t index
, StructuredData::Array
&composite_reg_list
,
138 lldb::ByteOrder byte_order
) {
139 const size_t num_composite_regs
= composite_reg_list
.GetSize();
140 if (num_composite_regs
== 0)
141 return llvm::createStringError(llvm::inconvertibleErrorCode(),
142 "\"composite\" list is empty");
144 uint32_t composite_offset
= UINT32_MAX
;
145 for (uint32_t composite_idx
= 0; composite_idx
< num_composite_regs
;
147 llvm::StringRef composite_reg_name
;
148 if (!composite_reg_list
.GetItemAtIndexAsString(composite_idx
, composite_reg_name
))
149 return llvm::createStringError(
150 llvm::inconvertibleErrorCode(),
151 "\"composite\" list value is not a Python string at index %d",
154 const RegisterInfo
*composite_reg_info
=
155 GetRegisterInfo(composite_reg_name
);
156 if (!composite_reg_info
)
157 return llvm::createStringError(
158 llvm::inconvertibleErrorCode(),
159 "failed to find composite register by name: \"%s\"",
160 composite_reg_name
.str().c_str());
163 std::min(composite_offset
, composite_reg_info
->byte_offset
);
164 m_value_regs_map
[index
].push_back(
165 composite_reg_info
->kinds
[eRegisterKindLLDB
]);
166 m_invalidate_regs_map
[composite_reg_info
->kinds
[eRegisterKindLLDB
]]
168 m_invalidate_regs_map
[index
].push_back(
169 composite_reg_info
->kinds
[eRegisterKindLLDB
]);
172 return composite_offset
;
175 llvm::Expected
<uint32_t> DynamicRegisterInfo::ByteOffsetFromRegInfoDict(
176 uint32_t index
, StructuredData::Dictionary
®_info_dict
,
177 lldb::ByteOrder byte_order
) {
178 uint32_t byte_offset
;
179 if (reg_info_dict
.GetValueForKeyAsInteger("offset", byte_offset
))
182 // No offset for this register, see if the register has a value
183 // expression which indicates this register is part of another register.
184 // Value expressions are things like "rax[31:0]" which state that the
185 // current register's value is in a concrete register "rax" in bits 31:0.
186 // If there is a value expression we can calculate the offset
187 llvm::StringRef slice_str
;
188 if (reg_info_dict
.GetValueForKeyAsString("slice", slice_str
, nullptr))
189 return ByteOffsetFromSlice(index
, slice_str
, byte_order
);
191 StructuredData::Array
*composite_reg_list
;
192 if (reg_info_dict
.GetValueForKeyAsArray("composite", composite_reg_list
))
193 return ByteOffsetFromComposite(index
, *composite_reg_list
, byte_order
);
195 return llvm::createStringError(llvm::inconvertibleErrorCode(),
196 "insufficient data to calculate byte offset");
200 DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary
&dict
,
201 const ArchSpec
&arch
) {
202 Log
*log
= GetLog(LLDBLog::Object
);
203 assert(!m_finalized
);
204 StructuredData::Array
*sets
= nullptr;
205 if (dict
.GetValueForKeyAsArray("sets", sets
)) {
206 const uint32_t num_sets
= sets
->GetSize();
207 for (uint32_t i
= 0; i
< num_sets
; ++i
) {
208 llvm::StringRef set_name
;
209 if (sets
->GetItemAtIndexAsString(i
, set_name
) && !set_name
.empty()) {
211 {ConstString(set_name
).AsCString(), nullptr, 0, nullptr});
214 printf("error: register sets must have valid names\n");
218 m_set_reg_nums
.resize(m_sets
.size());
221 StructuredData::Array
*regs
= nullptr;
222 if (!dict
.GetValueForKeyAsArray("registers", regs
))
225 const ByteOrder byte_order
= arch
.GetByteOrder();
227 const uint32_t num_regs
= regs
->GetSize();
228 // typedef std::map<std::string, std::vector<std::string> >
229 // InvalidateNameMap;
230 // InvalidateNameMap invalidate_map;
231 for (uint32_t i
= 0; i
< num_regs
; ++i
) {
232 StructuredData::Dictionary
*reg_info_dict
= nullptr;
233 if (!regs
->GetItemAtIndexAsDictionary(i
, reg_info_dict
)) {
235 printf("error: items in the 'registers' array must be dictionaries\n");
236 regs
->DumpToStdout();
240 // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16,
241 // 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,
242 // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
243 RegisterInfo reg_info
;
244 std::vector
<uint32_t> value_regs
;
245 std::vector
<uint32_t> invalidate_regs
;
246 memset(®_info
, 0, sizeof(reg_info
));
248 llvm::StringRef name_val
;
249 if (!reg_info_dict
->GetValueForKeyAsString("name", name_val
)) {
251 printf("error: registers must have valid names and offsets\n");
252 reg_info_dict
->DumpToStdout();
255 reg_info
.name
= ConstString(name_val
).GetCString();
257 llvm::StringRef alt_name_val
;
258 if (reg_info_dict
->GetValueForKeyAsString("alt-name", alt_name_val
))
259 reg_info
.alt_name
= ConstString(alt_name_val
).GetCString();
261 reg_info
.alt_name
= nullptr;
263 llvm::Expected
<uint32_t> byte_offset
=
264 ByteOffsetFromRegInfoDict(i
, *reg_info_dict
, byte_order
);
266 reg_info
.byte_offset
= byte_offset
.get();
268 LLDB_LOG_ERROR(log
, byte_offset
.takeError(),
269 "error while parsing register {1}: {0}", reg_info
.name
);
271 reg_info_dict
->DumpToStdout();
275 uint64_t bitsize
= 0;
276 if (!reg_info_dict
->GetValueForKeyAsInteger("bitsize", bitsize
)) {
278 printf("error: invalid or missing 'bitsize' key/value pair in register "
280 reg_info_dict
->DumpToStdout();
284 reg_info
.byte_size
= bitsize
/ 8;
286 llvm::StringRef format_str
;
287 if (reg_info_dict
->GetValueForKeyAsString("format", format_str
, nullptr)) {
288 if (OptionArgParser::ToFormat(format_str
.str().c_str(), reg_info
.format
,
292 printf("error: invalid 'format' value in register dictionary\n");
293 reg_info_dict
->DumpToStdout();
297 reg_info_dict
->GetValueForKeyAsInteger("format", reg_info
.format
,
301 llvm::StringRef encoding_str
;
302 if (reg_info_dict
->GetValueForKeyAsString("encoding", encoding_str
))
303 reg_info
.encoding
= Args::StringToEncoding(encoding_str
, eEncodingUint
);
305 reg_info_dict
->GetValueForKeyAsInteger("encoding", reg_info
.encoding
,
309 if (!reg_info_dict
->GetValueForKeyAsInteger("set", set
) ||
310 set
>= m_sets
.size()) {
312 printf("error: invalid 'set' value in register dictionary, valid values "
315 reg_info_dict
->DumpToStdout();
319 // Fill in the register numbers
320 reg_info
.kinds
[lldb::eRegisterKindLLDB
] = i
;
321 reg_info
.kinds
[lldb::eRegisterKindProcessPlugin
] = i
;
322 uint32_t eh_frame_regno
= LLDB_INVALID_REGNUM
;
323 reg_info_dict
->GetValueForKeyAsInteger("gcc", eh_frame_regno
,
324 LLDB_INVALID_REGNUM
);
325 if (eh_frame_regno
== LLDB_INVALID_REGNUM
)
326 reg_info_dict
->GetValueForKeyAsInteger("ehframe", eh_frame_regno
,
327 LLDB_INVALID_REGNUM
);
328 reg_info
.kinds
[lldb::eRegisterKindEHFrame
] = eh_frame_regno
;
329 reg_info_dict
->GetValueForKeyAsInteger(
330 "dwarf", reg_info
.kinds
[lldb::eRegisterKindDWARF
], LLDB_INVALID_REGNUM
);
331 llvm::StringRef generic_str
;
332 if (reg_info_dict
->GetValueForKeyAsString("generic", generic_str
))
333 reg_info
.kinds
[lldb::eRegisterKindGeneric
] =
334 Args::StringToGenericRegister(generic_str
);
336 reg_info_dict
->GetValueForKeyAsInteger(
337 "generic", reg_info
.kinds
[lldb::eRegisterKindGeneric
],
338 LLDB_INVALID_REGNUM
);
340 // Check if this register invalidates any other register values when it is
342 StructuredData::Array
*invalidate_reg_list
= nullptr;
343 if (reg_info_dict
->GetValueForKeyAsArray("invalidate-regs",
344 invalidate_reg_list
)) {
345 const size_t num_regs
= invalidate_reg_list
->GetSize();
347 for (uint32_t idx
= 0; idx
< num_regs
; ++idx
) {
348 llvm::StringRef invalidate_reg_name
;
349 uint64_t invalidate_reg_num
;
350 if (invalidate_reg_list
->GetItemAtIndexAsString(
351 idx
, invalidate_reg_name
)) {
352 const RegisterInfo
*invalidate_reg_info
=
353 GetRegisterInfo(invalidate_reg_name
);
354 if (invalidate_reg_info
) {
355 m_invalidate_regs_map
[i
].push_back(
356 invalidate_reg_info
->kinds
[eRegisterKindLLDB
]);
358 // TODO: print error invalid slice string that doesn't follow the
360 printf("error: failed to find a 'invalidate-regs' register for "
361 "\"%s\" while parsing register \"%s\"\n",
362 invalidate_reg_name
.str().c_str(), reg_info
.name
);
364 } else if (invalidate_reg_list
->GetItemAtIndexAsInteger(
365 idx
, invalidate_reg_num
)) {
366 if (invalidate_reg_num
!= UINT64_MAX
)
367 m_invalidate_regs_map
[i
].push_back(invalidate_reg_num
);
369 printf("error: 'invalidate-regs' list value wasn't a valid "
372 printf("error: 'invalidate-regs' list value wasn't a python string "
377 printf("error: 'invalidate-regs' contained an empty list\n");
381 // Calculate the register offset
382 const size_t end_reg_offset
= reg_info
.byte_offset
+ reg_info
.byte_size
;
383 if (m_reg_data_byte_size
< end_reg_offset
)
384 m_reg_data_byte_size
= end_reg_offset
;
386 m_regs
.push_back(reg_info
);
387 m_set_reg_nums
[set
].push_back(i
);
390 return m_regs
.size();
393 size_t DynamicRegisterInfo::SetRegisterInfo(
394 std::vector
<DynamicRegisterInfo::Register
> &®s
,
395 const ArchSpec
&arch
) {
396 assert(!m_finalized
);
398 for (auto it
: llvm::enumerate(regs
)) {
399 uint32_t local_regnum
= it
.index();
400 const DynamicRegisterInfo::Register
®
= it
.value();
403 assert(reg
.set_name
);
405 if (!reg
.value_regs
.empty())
406 m_value_regs_map
[local_regnum
] = std::move(reg
.value_regs
);
407 if (!reg
.invalidate_regs
.empty())
408 m_invalidate_regs_map
[local_regnum
] = std::move(reg
.invalidate_regs
);
409 if (reg
.value_reg_offset
!= 0) {
410 assert(reg
.value_regs
.size() == 1);
411 m_value_reg_offset_map
[local_regnum
] = reg
.value_reg_offset
;
414 struct RegisterInfo reg_info
{
415 reg
.name
.AsCString(), reg
.alt_name
.AsCString(), reg
.byte_size
,
416 reg
.byte_offset
, reg
.encoding
, reg
.format
,
417 {reg
.regnum_ehframe
, reg
.regnum_dwarf
, reg
.regnum_generic
,
418 reg
.regnum_remote
, local_regnum
},
419 // value_regs and invalidate_regs are filled by Finalize()
420 nullptr, nullptr, reg
.flags_type
423 m_regs
.push_back(reg_info
);
425 uint32_t set
= GetRegisterSetIndexByName(reg
.set_name
, true);
426 assert(set
< m_sets
.size());
427 assert(set
< m_set_reg_nums
.size());
428 assert(set
< m_set_names
.size());
429 m_set_reg_nums
[set
].push_back(local_regnum
);
433 return m_regs
.size();
436 void DynamicRegisterInfo::Finalize(const ArchSpec
&arch
) {
441 const size_t num_sets
= m_sets
.size();
442 for (size_t set
= 0; set
< num_sets
; ++set
) {
443 assert(m_sets
.size() == m_set_reg_nums
.size());
444 m_sets
[set
].num_registers
= m_set_reg_nums
[set
].size();
445 m_sets
[set
].registers
= m_set_reg_nums
[set
].data();
448 // make sure value_regs are terminated with LLDB_INVALID_REGNUM
450 for (reg_to_regs_map::iterator pos
= m_value_regs_map
.begin(),
451 end
= m_value_regs_map
.end();
453 if (pos
->second
.back() != LLDB_INVALID_REGNUM
)
454 pos
->second
.push_back(LLDB_INVALID_REGNUM
);
457 // Now update all value_regs with each register info as needed
458 const size_t num_regs
= m_regs
.size();
459 for (size_t i
= 0; i
< num_regs
; ++i
) {
460 if (m_value_regs_map
.find(i
) != m_value_regs_map
.end())
461 m_regs
[i
].value_regs
= m_value_regs_map
[i
].data();
463 m_regs
[i
].value_regs
= nullptr;
466 // Expand all invalidation dependencies
467 for (reg_to_regs_map::iterator pos
= m_invalidate_regs_map
.begin(),
468 end
= m_invalidate_regs_map
.end();
470 const uint32_t reg_num
= pos
->first
;
472 if (m_regs
[reg_num
].value_regs
) {
473 reg_num_collection extra_invalid_regs
;
474 for (const uint32_t invalidate_reg_num
: pos
->second
) {
475 reg_to_regs_map::iterator invalidate_pos
=
476 m_invalidate_regs_map
.find(invalidate_reg_num
);
477 if (invalidate_pos
!= m_invalidate_regs_map
.end()) {
478 for (const uint32_t concrete_invalidate_reg_num
:
479 invalidate_pos
->second
) {
480 if (concrete_invalidate_reg_num
!= reg_num
)
481 extra_invalid_regs
.push_back(concrete_invalidate_reg_num
);
485 pos
->second
.insert(pos
->second
.end(), extra_invalid_regs
.begin(),
486 extra_invalid_regs
.end());
490 // sort and unique all invalidate registers and make sure each is terminated
491 // with LLDB_INVALID_REGNUM
492 for (reg_to_regs_map::iterator pos
= m_invalidate_regs_map
.begin(),
493 end
= m_invalidate_regs_map
.end();
495 if (pos
->second
.size() > 1) {
496 llvm::sort(pos
->second
);
497 reg_num_collection::iterator unique_end
=
498 std::unique(pos
->second
.begin(), pos
->second
.end());
499 if (unique_end
!= pos
->second
.end())
500 pos
->second
.erase(unique_end
, pos
->second
.end());
502 assert(!pos
->second
.empty());
503 if (pos
->second
.back() != LLDB_INVALID_REGNUM
)
504 pos
->second
.push_back(LLDB_INVALID_REGNUM
);
507 // Now update all invalidate_regs with each register info as needed
508 for (size_t i
= 0; i
< num_regs
; ++i
) {
509 if (m_invalidate_regs_map
.find(i
) != m_invalidate_regs_map
.end())
510 m_regs
[i
].invalidate_regs
= m_invalidate_regs_map
[i
].data();
512 m_regs
[i
].invalidate_regs
= nullptr;
515 // Check if we need to automatically set the generic registers in case they
517 bool generic_regs_specified
= false;
518 for (const auto ®
: m_regs
) {
519 if (reg
.kinds
[eRegisterKindGeneric
] != LLDB_INVALID_REGNUM
) {
520 generic_regs_specified
= true;
525 if (!generic_regs_specified
) {
526 switch (arch
.GetMachine()) {
527 case llvm::Triple::aarch64
:
528 case llvm::Triple::aarch64_32
:
529 case llvm::Triple::aarch64_be
:
530 for (auto ®
: m_regs
) {
531 if (strcmp(reg
.name
, "pc") == 0)
532 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_PC
;
533 else if ((strcmp(reg
.name
, "fp") == 0) ||
534 (strcmp(reg
.name
, "x29") == 0))
535 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
536 else if ((strcmp(reg
.name
, "lr") == 0) ||
537 (strcmp(reg
.name
, "x30") == 0))
538 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_RA
;
539 else if ((strcmp(reg
.name
, "sp") == 0) ||
540 (strcmp(reg
.name
, "x31") == 0))
541 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_SP
;
542 else if (strcmp(reg
.name
, "cpsr") == 0)
543 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FLAGS
;
547 case llvm::Triple::arm
:
548 case llvm::Triple::armeb
:
549 case llvm::Triple::thumb
:
550 case llvm::Triple::thumbeb
:
551 for (auto ®
: m_regs
) {
552 if ((strcmp(reg
.name
, "pc") == 0) || (strcmp(reg
.name
, "r15") == 0))
553 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_PC
;
554 else if ((strcmp(reg
.name
, "sp") == 0) ||
555 (strcmp(reg
.name
, "r13") == 0))
556 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_SP
;
557 else if ((strcmp(reg
.name
, "lr") == 0) ||
558 (strcmp(reg
.name
, "r14") == 0))
559 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_RA
;
560 else if ((strcmp(reg
.name
, "r7") == 0) &&
561 arch
.GetTriple().getVendor() == llvm::Triple::Apple
)
562 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
563 else if ((strcmp(reg
.name
, "r11") == 0) &&
564 arch
.GetTriple().getVendor() != llvm::Triple::Apple
)
565 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
566 else if (strcmp(reg
.name
, "fp") == 0)
567 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
568 else if (strcmp(reg
.name
, "cpsr") == 0)
569 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FLAGS
;
573 case llvm::Triple::x86
:
574 for (auto ®
: m_regs
) {
575 if ((strcmp(reg
.name
, "eip") == 0) || (strcmp(reg
.name
, "pc") == 0))
576 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_PC
;
577 else if ((strcmp(reg
.name
, "esp") == 0) ||
578 (strcmp(reg
.name
, "sp") == 0))
579 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_SP
;
580 else if ((strcmp(reg
.name
, "ebp") == 0) ||
581 (strcmp(reg
.name
, "fp") == 0))
582 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
583 else if ((strcmp(reg
.name
, "eflags") == 0) ||
584 (strcmp(reg
.name
, "flags") == 0))
585 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FLAGS
;
589 case llvm::Triple::x86_64
:
590 for (auto ®
: m_regs
) {
591 if ((strcmp(reg
.name
, "rip") == 0) || (strcmp(reg
.name
, "pc") == 0))
592 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_PC
;
593 else if ((strcmp(reg
.name
, "rsp") == 0) ||
594 (strcmp(reg
.name
, "sp") == 0))
595 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_SP
;
596 else if ((strcmp(reg
.name
, "rbp") == 0) ||
597 (strcmp(reg
.name
, "fp") == 0))
598 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FP
;
599 else if ((strcmp(reg
.name
, "rflags") == 0) ||
600 (strcmp(reg
.name
, "eflags") == 0) ||
601 (strcmp(reg
.name
, "flags") == 0))
602 reg
.kinds
[eRegisterKindGeneric
] = LLDB_REGNUM_GENERIC_FLAGS
;
611 // At this stage call ConfigureOffsets to calculate register offsets for
612 // targets supporting dynamic offset calculation. It also calculates
613 // total byte size of register data.
616 // Check if register info is reconfigurable
617 // AArch64 SVE register set has configurable register sizes, as does the ZA
618 // register that SME added (the streaming state of SME reuses the SVE state).
619 if (arch
.GetTriple().isAArch64()) {
620 for (const auto ®
: m_regs
) {
621 if ((strcmp(reg
.name
, "vg") == 0) || (strcmp(reg
.name
, "svg") == 0)) {
622 m_is_reconfigurable
= true;
629 void DynamicRegisterInfo::ConfigureOffsets() {
630 // We are going to create a map between remote (eRegisterKindProcessPlugin)
631 // and local (eRegisterKindLLDB) register numbers. This map will give us
632 // remote register numbers in increasing order for offset calculation.
633 std::map
<uint32_t, uint32_t> remote_to_local_regnum_map
;
634 for (const auto ®
: m_regs
)
635 remote_to_local_regnum_map
[reg
.kinds
[eRegisterKindProcessPlugin
]] =
636 reg
.kinds
[eRegisterKindLLDB
];
638 // At this stage we manually calculate g/G packet offsets of all primary
639 // registers, only if target XML or qRegisterInfo packet did not send
640 // an offset explicitly.
641 uint32_t reg_offset
= 0;
642 for (auto const ®num_pair
: remote_to_local_regnum_map
) {
643 if (m_regs
[regnum_pair
.second
].byte_offset
== LLDB_INVALID_INDEX32
&&
644 m_regs
[regnum_pair
.second
].value_regs
== nullptr) {
645 m_regs
[regnum_pair
.second
].byte_offset
= reg_offset
;
647 reg_offset
= m_regs
[regnum_pair
.second
].byte_offset
+
648 m_regs
[regnum_pair
.second
].byte_size
;
652 // Now update all value_regs with each register info as needed
653 for (auto ®
: m_regs
) {
654 if (reg
.value_regs
!= nullptr) {
655 // Assign a valid offset to all pseudo registers that have only a single
656 // parent register in value_regs list, if not assigned by stub. Pseudo
657 // registers with value_regs list populated will share same offset as
658 // that of their corresponding parent register.
659 if (reg
.byte_offset
== LLDB_INVALID_INDEX32
) {
660 uint32_t value_regnum
= reg
.value_regs
[0];
661 if (value_regnum
!= LLDB_INVALID_INDEX32
&&
662 reg
.value_regs
[1] == LLDB_INVALID_INDEX32
) {
664 GetRegisterInfoAtIndex(value_regnum
)->byte_offset
;
665 auto it
= m_value_reg_offset_map
.find(reg
.kinds
[eRegisterKindLLDB
]);
666 if (it
!= m_value_reg_offset_map
.end())
667 reg
.byte_offset
+= it
->second
;
672 reg_offset
= reg
.byte_offset
+ reg
.byte_size
;
673 if (m_reg_data_byte_size
< reg_offset
)
674 m_reg_data_byte_size
= reg_offset
;
678 bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable
; }
680 size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs
.size(); }
682 size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets
.size(); }
684 size_t DynamicRegisterInfo::GetRegisterDataByteSize() const {
685 return m_reg_data_byte_size
;
689 DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i
) const {
690 if (i
< m_regs
.size())
695 const RegisterInfo
*DynamicRegisterInfo::GetRegisterInfo(uint32_t kind
,
696 uint32_t num
) const {
697 uint32_t reg_index
= ConvertRegisterKindToRegisterNumber(kind
, num
);
698 if (reg_index
!= LLDB_INVALID_REGNUM
)
699 return &m_regs
[reg_index
];
703 const RegisterSet
*DynamicRegisterInfo::GetRegisterSet(uint32_t i
) const {
704 if (i
< m_sets
.size())
710 DynamicRegisterInfo::GetRegisterSetIndexByName(const ConstString
&set_name
,
712 name_collection::iterator pos
, end
= m_set_names
.end();
713 for (pos
= m_set_names
.begin(); pos
!= end
; ++pos
) {
714 if (*pos
== set_name
)
715 return std::distance(m_set_names
.begin(), pos
);
718 m_set_names
.push_back(set_name
);
719 m_set_reg_nums
.resize(m_set_reg_nums
.size() + 1);
720 RegisterSet new_set
= {set_name
.AsCString(), nullptr, 0, nullptr};
721 m_sets
.push_back(new_set
);
722 return m_sets
.size() - 1;
726 DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber(uint32_t kind
,
727 uint32_t num
) const {
728 reg_collection::const_iterator pos
, end
= m_regs
.end();
729 for (pos
= m_regs
.begin(); pos
!= end
; ++pos
) {
730 if (pos
->kinds
[kind
] == num
)
731 return std::distance(m_regs
.begin(), pos
);
734 return LLDB_INVALID_REGNUM
;
737 void DynamicRegisterInfo::Clear() {
740 m_set_reg_nums
.clear();
742 m_value_regs_map
.clear();
743 m_invalidate_regs_map
.clear();
744 m_reg_data_byte_size
= 0;
748 void DynamicRegisterInfo::Dump() const {
749 StreamFile
s(stdout
, false);
750 const size_t num_regs
= m_regs
.size();
751 s
.Printf("%p: DynamicRegisterInfo contains %" PRIu64
" registers:\n",
752 static_cast<const void *>(this), static_cast<uint64_t>(num_regs
));
753 for (size_t i
= 0; i
< num_regs
; ++i
) {
754 s
.Printf("[%3" PRIu64
"] name = %-10s", (uint64_t)i
, m_regs
[i
].name
);
755 s
.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
756 m_regs
[i
].byte_size
, m_regs
[i
].byte_offset
, m_regs
[i
].encoding
,
757 FormatManager::GetFormatAsCString(m_regs
[i
].format
));
758 if (m_regs
[i
].kinds
[eRegisterKindProcessPlugin
] != LLDB_INVALID_REGNUM
)
759 s
.Printf(", process plugin = %3u",
760 m_regs
[i
].kinds
[eRegisterKindProcessPlugin
]);
761 if (m_regs
[i
].kinds
[eRegisterKindDWARF
] != LLDB_INVALID_REGNUM
)
762 s
.Printf(", dwarf = %3u", m_regs
[i
].kinds
[eRegisterKindDWARF
]);
763 if (m_regs
[i
].kinds
[eRegisterKindEHFrame
] != LLDB_INVALID_REGNUM
)
764 s
.Printf(", ehframe = %3u", m_regs
[i
].kinds
[eRegisterKindEHFrame
]);
765 if (m_regs
[i
].kinds
[eRegisterKindGeneric
] != LLDB_INVALID_REGNUM
)
766 s
.Printf(", generic = %3u", m_regs
[i
].kinds
[eRegisterKindGeneric
]);
767 if (m_regs
[i
].alt_name
)
768 s
.Printf(", alt-name = %s", m_regs
[i
].alt_name
);
769 if (m_regs
[i
].value_regs
) {
770 s
.Printf(", value_regs = [ ");
771 for (size_t j
= 0; m_regs
[i
].value_regs
[j
] != LLDB_INVALID_REGNUM
; ++j
) {
772 s
.Printf("%s ", m_regs
[m_regs
[i
].value_regs
[j
]].name
);
776 if (m_regs
[i
].invalidate_regs
) {
777 s
.Printf(", invalidate_regs = [ ");
778 for (size_t j
= 0; m_regs
[i
].invalidate_regs
[j
] != LLDB_INVALID_REGNUM
;
780 s
.Printf("%s ", m_regs
[m_regs
[i
].invalidate_regs
[j
]].name
);
787 const size_t num_sets
= m_sets
.size();
788 s
.Printf("%p: DynamicRegisterInfo contains %" PRIu64
" register sets:\n",
789 static_cast<const void *>(this), static_cast<uint64_t>(num_sets
));
790 for (size_t i
= 0; i
< num_sets
; ++i
) {
791 s
.Printf("set[%" PRIu64
"] name = %s, regs = [", (uint64_t)i
,
793 for (size_t idx
= 0; idx
< m_sets
[i
].num_registers
; ++idx
) {
794 s
.Printf("%s ", m_regs
[m_sets
[i
].registers
[idx
]].name
);
800 const lldb_private::RegisterInfo
*
801 DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name
) const {
802 for (auto ®_info
: m_regs
)
803 if (reg_info
.name
== reg_name
)
808 void lldb_private::addSupplementaryRegister(
809 std::vector
<DynamicRegisterInfo::Register
> ®s
,
810 DynamicRegisterInfo::Register new_reg_info
) {
811 assert(!new_reg_info
.value_regs
.empty());
812 const uint32_t reg_num
= regs
.size();
813 regs
.push_back(new_reg_info
);
815 std::map
<uint32_t, std::vector
<uint32_t>> new_invalidates
;
816 for (uint32_t value_reg
: new_reg_info
.value_regs
) {
817 // copy value_regs to invalidate_regs
818 new_invalidates
[reg_num
].push_back(value_reg
);
820 // copy invalidate_regs from the parent register
821 llvm::append_range(new_invalidates
[reg_num
],
822 regs
[value_reg
].invalidate_regs
);
824 // add reverse invalidate entries
825 for (uint32_t x
: new_invalidates
[reg_num
])
826 new_invalidates
[x
].push_back(reg_num
);
829 for (const auto &x
: new_invalidates
)
830 llvm::append_range(regs
[x
.first
].invalidate_regs
, x
.second
);