40 m_regs = std::move(info.m_regs);
41 m_sets = std::move(info.m_sets);
51 const size_t num_sets =
m_sets.size();
52 for (
size_t set = 0; set < num_sets; ++set)
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());
77 llvm::StringRef reg_name_str = matches[1];
78 llvm::StringRef msbit_str = matches[2];
79 llvm::StringRef lsbit_str = matches[3];
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());
89 return llvm::createStringError(llvm::inconvertibleErrorCode(),
90 "msbit (%u) must be greater than lsbit (%u)",
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());
102 const uint32_t max_bit = containing_reg_info->byte_size * 8;
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);
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);
123 return containing_reg_info->byte_offset + lsbyte;
125 return containing_reg_info->byte_offset + msbyte;
126 llvm_unreachable(
"Invalid 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");
138 for (
uint32_t composite_idx = 0; composite_idx < num_composite_regs;
142 composite_reg_name,
nullptr))
143 return llvm::createStringError(
144 llvm::inconvertibleErrorCode(),
145 "\"composite\" list value is not a Python string at index %d",
148 const RegisterInfo *composite_reg_info =
150 if (!composite_reg_info)
151 return llvm::createStringError(
152 llvm::inconvertibleErrorCode(),
153 "failed to find composite register by name: \"%s\"",
157 std::min(composite_offset, composite_reg_info->byte_offset);
166 return composite_offset;
181 llvm::StringRef slice_str;
189 return llvm::createStringError(llvm::inconvertibleErrorCode(),
190 "insufficient data to calculate byte offset");
201 for (
uint32_t i = 0; i < num_sets; ++i) {
207 printf(
"error: register sets must have valid names\n");
224 for (
uint32_t i = 0; i < num_regs; ++i) {
228 printf(
"error: items in the 'registers' array must be dictionaries\n");
236 RegisterInfo reg_info;
237 std::vector<uint32_t> value_regs;
238 std::vector<uint32_t> invalidate_regs;
239 memset(®_info, 0,
sizeof(reg_info));
245 printf(
"error: registers must have valid names and offsets\n");
251 reg_info.alt_name = alt_name_val.
GetCString();
253 llvm::Expected<uint32_t> byte_offset =
256 reg_info.byte_offset = byte_offset.get();
259 "error while parsing register {1}: {0}", reg_info.name);
265 uint64_t bitsize = 0;
268 printf(
"error: invalid or missing 'bitsize' key/value pair in register "
274 reg_info.byte_size = bitsize / 8;
276 llvm::StringRef format_str;
282 printf(
"error: invalid 'format' value in register dictionary\n");
291 llvm::StringRef encoding_str;
302 printf(
"error: invalid 'set' value in register dictionary, valid values "
321 llvm::StringRef generic_str;
334 invalidate_reg_list)) {
335 const size_t num_regs = invalidate_reg_list->
GetSize();
337 for (
uint32_t idx = 0; idx < num_regs; ++idx) {
339 uint64_t invalidate_reg_num;
341 idx, invalidate_reg_name)) {
342 const RegisterInfo *invalidate_reg_info =
344 if (invalidate_reg_info) {
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);
355 idx, invalidate_reg_num)) {
359 printf(
"error: 'invalidate-regs' list value wasn't a valid "
362 printf(
"error: 'invalidate-regs' list value wasn't a python string "
367 printf(
"error: 'invalidate-regs' contained an empty list\n");
372 const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
376 m_regs.push_back(reg_info);
384 std::vector<DynamicRegisterInfo::Register> &®s,
388 for (
auto it : llvm::enumerate(regs)) {
404 struct RegisterInfo reg_info {
413 m_regs.push_back(reg_info);
416 assert(set <
m_sets.size());
431 const size_t num_sets =
m_sets.size();
432 for (
size_t set = 0; set < num_sets; ++set) {
448 const size_t num_regs =
m_regs.size();
449 for (
size_t i = 0; i < num_regs; ++i) {
453 m_regs[i].value_regs =
nullptr;
460 const uint32_t reg_num = pos->first;
462 if (
m_regs[reg_num].value_regs) {
464 for (
const uint32_t invalidate_reg_num : pos->second) {
465 reg_to_regs_map::iterator invalidate_pos =
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);
475 pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
476 extra_invalid_regs.end());
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());
492 assert(!pos->second.empty());
498 for (
size_t i = 0; i < num_regs; ++i) {
502 m_regs[i].invalidate_regs =
nullptr;
507 bool generic_regs_specified =
false;
508 for (
const auto ® :
m_regs) {
510 generic_regs_specified =
true;
515 if (!generic_regs_specified) {
517 case llvm::Triple::aarch64:
518 case llvm::Triple::aarch64_32:
519 case llvm::Triple::aarch64_be:
520 for (
auto ® :
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)
537 case llvm::Triple::arm:
538 case llvm::Triple::armeb:
539 case llvm::Triple::thumb:
540 case llvm::Triple::thumbeb:
541 for (
auto ® :
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)
563 case llvm::Triple::x86:
564 for (
auto ® :
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))
579 case llvm::Triple::x86_64:
580 for (
auto ® :
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))
609 for (
const auto ® :
m_regs) {
610 if (strcmp(reg.name,
"vg") == 0) {
622 std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
623 for (
const auto ® :
m_regs)
631 for (
auto const ®num_pair : remote_to_local_regnum_map) {
633 m_regs[regnum_pair.second].value_regs ==
nullptr) {
634 m_regs[regnum_pair.second].byte_offset = reg_offset;
636 reg_offset =
m_regs[regnum_pair.second].byte_offset +
637 m_regs[regnum_pair.second].byte_size;
642 for (
auto ® :
m_regs) {
643 if (reg.value_regs !=
nullptr) {
649 uint32_t value_regnum = reg.value_regs[0];
656 reg.byte_offset += it->second;
661 reg_offset = reg.byte_offset + reg.byte_size;
688 return &
m_regs[reg_index];
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)
709 RegisterSet new_set = {set_name.
AsCString(),
nullptr, 0,
nullptr};
710 m_sets.push_back(new_set);
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);
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",
748 s.
Printf(
", process plugin = %3u",
758 if (
m_regs[i].value_regs) {
759 s.
Printf(
", value_regs = [ ");
765 if (
m_regs[i].invalidate_regs) {
766 s.
Printf(
", invalidate_regs = [ ");
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,
782 for (
size_t idx = 0; idx <
m_sets[i].num_registers; ++idx) {
789const lldb_private::RegisterInfo *
791 for (
auto ®_info :
m_regs)
792 if (reg_info.name == reg_name)
798 std::vector<DynamicRegisterInfo::Register> ®s,
801 const uint32_t reg_num = regs.size();
802 regs.push_back(new_reg_info);
804 std::map<uint32_t, std::vector<uint32_t>> new_invalidates;
807 new_invalidates[reg_num].push_back(value_reg);
810 llvm::append_range(new_invalidates[reg_num],
811 regs[value_reg].invalidate_regs);
814 for (
uint32_t x : new_invalidates[reg_num])
815 new_invalidates[x].push_back(reg_num);
818 for (
const auto &x : new_invalidates)
819 llvm::append_range(regs[x.first].invalidate_regs, x.second);
#define LLDB_LOG_ERROR(log, error,...)
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
static lldb::Encoding StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value=lldb::eEncodingInvalid)
static uint32_t StringToGenericRegister(llvm::StringRef s)
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, const lldb_private::ArchSpec &arch)
set_reg_num_collection m_set_reg_nums
reg_to_regs_map m_value_regs_map
std::vector< uint32_t > reg_num_collection
name_collection m_set_names
DynamicRegisterInfo()=default
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
size_t GetNumRegisters() 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)
size_t GetRegisterDataByteSize() const
size_t m_reg_data_byte_size
reg_offset_map m_value_reg_offset_map
reg_to_regs_map m_invalidate_regs_map
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
size_t GetNumRegisterSets() const
llvm::iterator_range< reg_collection::const_iterator > registers() const
llvm::Expected< uint32_t > ByteOffsetFromRegInfoDict(uint32_t index, lldb_private::StructuredData::Dictionary ®_info_dict, lldb::ByteOrder byte_order)
bool Fail() const
Test for error condition.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t EOL()
Output and End of Line character to the stream.
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
#define LLDB_INVALID_INDEX32
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
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.
void addSupplementaryRegister(std::vector< DynamicRegisterInfo::Register > ®s, DynamicRegisterInfo::Register new_reg_info)
@ eEncodingUint
unsigned integer
ByteOrder
Byte ordering definitions.
@ 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.
uint32_t value_reg_offset
const RegisterFlags * flags_type
std::vector< uint32_t > value_regs
std::vector< uint32_t > invalidate_regs
static Status ToFormat(const char *s, lldb::Format &format, size_t *byte_size_ptr)