Path: blob/main/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp
96333 views
//===-- DynamicRegisterInfo.cpp -------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Target/DynamicRegisterInfo.h"9#include "lldb/DataFormatters/FormatManager.h"10#include "lldb/Host/StreamFile.h"11#include "lldb/Interpreter/OptionArgParser.h"12#include "lldb/Utility/ArchSpec.h"13#include "lldb/Utility/LLDBLog.h"14#include "lldb/Utility/Log.h"15#include "lldb/Utility/RegularExpression.h"16#include "lldb/Utility/StringExtractor.h"17#include "lldb/Utility/StructuredData.h"1819using namespace lldb;20using namespace lldb_private;2122std::unique_ptr<DynamicRegisterInfo>23DynamicRegisterInfo::Create(const StructuredData::Dictionary &dict,24const ArchSpec &arch) {25auto dyn_reg_info = std::make_unique<DynamicRegisterInfo>();26if (!dyn_reg_info)27return nullptr;2829if (dyn_reg_info->SetRegisterInfo(dict, arch) == 0)30return nullptr;3132return dyn_reg_info;33}3435DynamicRegisterInfo::DynamicRegisterInfo(DynamicRegisterInfo &&info) {36MoveFrom(std::move(info));37}3839DynamicRegisterInfo &40DynamicRegisterInfo::operator=(DynamicRegisterInfo &&info) {41MoveFrom(std::move(info));42return *this;43}4445void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) {46m_regs = std::move(info.m_regs);47m_sets = std::move(info.m_sets);48m_set_reg_nums = std::move(info.m_set_reg_nums);49m_set_names = std::move(info.m_set_names);50m_value_regs_map = std::move(info.m_value_regs_map);51m_invalidate_regs_map = std::move(info.m_invalidate_regs_map);5253m_reg_data_byte_size = info.m_reg_data_byte_size;54m_finalized = info.m_finalized;5556if (m_finalized) {57const size_t num_sets = m_sets.size();58for (size_t set = 0; set < num_sets; ++set)59m_sets[set].registers = m_set_reg_nums[set].data();60}6162info.Clear();63}6465llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromSlice(66uint32_t index, llvm::StringRef slice_str, lldb::ByteOrder byte_order) {67// Slices use the following format:68// REGNAME[MSBIT:LSBIT]69// REGNAME - name of the register to grab a slice of70// MSBIT - the most significant bit at which the current register value71// starts at72// LSBIT - the least significant bit at which the current register value73// ends at74static llvm::Regex g_bitfield_regex(75"([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");76llvm::SmallVector<llvm::StringRef, 4> matches;77if (!g_bitfield_regex.match(slice_str, &matches))78return llvm::createStringError(79llvm::inconvertibleErrorCode(),80"failed to match against register bitfield regex (slice: %s)",81slice_str.str().c_str());8283llvm::StringRef reg_name_str = matches[1];84llvm::StringRef msbit_str = matches[2];85llvm::StringRef lsbit_str = matches[3];86uint32_t msbit;87uint32_t lsbit;88if (!llvm::to_integer(msbit_str, msbit) ||89!llvm::to_integer(lsbit_str, lsbit))90return llvm::createStringError(91llvm::inconvertibleErrorCode(), "msbit (%s) or lsbit (%s) are invalid",92msbit_str.str().c_str(), lsbit_str.str().c_str());9394if (msbit <= lsbit)95return llvm::createStringError(llvm::inconvertibleErrorCode(),96"msbit (%u) must be greater than lsbit (%u)",97msbit, lsbit);9899const uint32_t msbyte = msbit / 8;100const uint32_t lsbyte = lsbit / 8;101102const RegisterInfo *containing_reg_info = GetRegisterInfo(reg_name_str);103if (!containing_reg_info)104return llvm::createStringError(llvm::inconvertibleErrorCode(),105"invalid concrete register \"%s\"",106reg_name_str.str().c_str());107108const uint32_t max_bit = containing_reg_info->byte_size * 8;109110if (msbit > max_bit)111return llvm::createStringError(112llvm::inconvertibleErrorCode(),113"msbit (%u) must be less than the bitsize of the register \"%s\" (%u)",114msbit, reg_name_str.str().c_str(), max_bit);115if (lsbit > max_bit)116return llvm::createStringError(117llvm::inconvertibleErrorCode(),118"lsbit (%u) must be less than the bitsize of the register \"%s\" (%u)",119lsbit, reg_name_str.str().c_str(), max_bit);120121m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]]122.push_back(index);123m_value_regs_map[index].push_back(124containing_reg_info->kinds[eRegisterKindLLDB]);125m_invalidate_regs_map[index].push_back(126containing_reg_info->kinds[eRegisterKindLLDB]);127128if (byte_order == eByteOrderLittle)129return containing_reg_info->byte_offset + lsbyte;130if (byte_order == eByteOrderBig)131return containing_reg_info->byte_offset + msbyte;132llvm_unreachable("Invalid byte order");133}134135llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromComposite(136uint32_t index, StructuredData::Array &composite_reg_list,137lldb::ByteOrder byte_order) {138const size_t num_composite_regs = composite_reg_list.GetSize();139if (num_composite_regs == 0)140return llvm::createStringError(llvm::inconvertibleErrorCode(),141"\"composite\" list is empty");142143uint32_t composite_offset = UINT32_MAX;144for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;145++composite_idx) {146std::optional<llvm::StringRef> maybe_composite_reg_name =147composite_reg_list.GetItemAtIndexAsString(composite_idx);148if (!maybe_composite_reg_name)149return llvm::createStringError(150llvm::inconvertibleErrorCode(),151"\"composite\" list value is not a Python string at index %d",152composite_idx);153154const RegisterInfo *composite_reg_info =155GetRegisterInfo(*maybe_composite_reg_name);156if (!composite_reg_info)157return llvm::createStringError(158llvm::inconvertibleErrorCode(),159"failed to find composite register by name: \"%s\"",160maybe_composite_reg_name->str().c_str());161162composite_offset =163std::min(composite_offset, composite_reg_info->byte_offset);164m_value_regs_map[index].push_back(165composite_reg_info->kinds[eRegisterKindLLDB]);166m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]]167.push_back(index);168m_invalidate_regs_map[index].push_back(169composite_reg_info->kinds[eRegisterKindLLDB]);170}171172return composite_offset;173}174175llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromRegInfoDict(176uint32_t index, StructuredData::Dictionary ®_info_dict,177lldb::ByteOrder byte_order) {178uint32_t byte_offset;179if (reg_info_dict.GetValueForKeyAsInteger("offset", byte_offset))180return byte_offset;181182// No offset for this register, see if the register has a value183// expression which indicates this register is part of another register.184// Value expressions are things like "rax[31:0]" which state that the185// 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 offset187llvm::StringRef slice_str;188if (reg_info_dict.GetValueForKeyAsString("slice", slice_str, nullptr))189return ByteOffsetFromSlice(index, slice_str, byte_order);190191StructuredData::Array *composite_reg_list;192if (reg_info_dict.GetValueForKeyAsArray("composite", composite_reg_list))193return ByteOffsetFromComposite(index, *composite_reg_list, byte_order);194195return llvm::createStringError(llvm::inconvertibleErrorCode(),196"insufficient data to calculate byte offset");197}198199size_t200DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,201const ArchSpec &arch) {202Log *log = GetLog(LLDBLog::Object);203assert(!m_finalized);204StructuredData::Array *sets = nullptr;205if (dict.GetValueForKeyAsArray("sets", sets)) {206const uint32_t num_sets = sets->GetSize();207for (uint32_t i = 0; i < num_sets; ++i) {208std::optional<llvm::StringRef> maybe_set_name =209sets->GetItemAtIndexAsString(i);210if (maybe_set_name && !maybe_set_name->empty()) {211m_sets.push_back(212{ConstString(*maybe_set_name).AsCString(), nullptr, 0, nullptr});213} else {214Clear();215printf("error: register sets must have valid names\n");216return 0;217}218}219m_set_reg_nums.resize(m_sets.size());220}221222StructuredData::Array *regs = nullptr;223if (!dict.GetValueForKeyAsArray("registers", regs))224return 0;225226const ByteOrder byte_order = arch.GetByteOrder();227228const uint32_t num_regs = regs->GetSize();229// typedef std::map<std::string, std::vector<std::string> >230// InvalidateNameMap;231// InvalidateNameMap invalidate_map;232for (uint32_t i = 0; i < num_regs; ++i) {233std::optional<StructuredData::Dictionary *> maybe_reg_info_dict =234regs->GetItemAtIndexAsDictionary(i);235if (!maybe_reg_info_dict) {236Clear();237printf("error: items in the 'registers' array must be dictionaries\n");238regs->DumpToStdout();239return 0;240}241StructuredData::Dictionary *reg_info_dict = *maybe_reg_info_dict;242243// { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16,244// 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,245// 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },246RegisterInfo reg_info;247std::vector<uint32_t> value_regs;248std::vector<uint32_t> invalidate_regs;249memset(®_info, 0, sizeof(reg_info));250251llvm::StringRef name_val;252if (!reg_info_dict->GetValueForKeyAsString("name", name_val)) {253Clear();254printf("error: registers must have valid names and offsets\n");255reg_info_dict->DumpToStdout();256return 0;257}258reg_info.name = ConstString(name_val).GetCString();259260llvm::StringRef alt_name_val;261if (reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val))262reg_info.alt_name = ConstString(alt_name_val).GetCString();263else264reg_info.alt_name = nullptr;265266llvm::Expected<uint32_t> byte_offset =267ByteOffsetFromRegInfoDict(i, *reg_info_dict, byte_order);268if (byte_offset)269reg_info.byte_offset = byte_offset.get();270else {271LLDB_LOG_ERROR(log, byte_offset.takeError(),272"error while parsing register {1}: {0}", reg_info.name);273Clear();274reg_info_dict->DumpToStdout();275return 0;276}277278uint64_t bitsize = 0;279if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {280Clear();281printf("error: invalid or missing 'bitsize' key/value pair in register "282"dictionary\n");283reg_info_dict->DumpToStdout();284return 0;285}286287reg_info.byte_size = bitsize / 8;288289llvm::StringRef format_str;290if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {291if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format,292nullptr)293.Fail()) {294Clear();295printf("error: invalid 'format' value in register dictionary\n");296reg_info_dict->DumpToStdout();297return 0;298}299} else {300reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,301eFormatHex);302}303304llvm::StringRef encoding_str;305if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))306reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);307else308reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,309eEncodingUint);310311size_t set = 0;312if (!reg_info_dict->GetValueForKeyAsInteger("set", set) ||313set >= m_sets.size()) {314Clear();315printf("error: invalid 'set' value in register dictionary, valid values "316"are 0 - %i\n",317(int)set);318reg_info_dict->DumpToStdout();319return 0;320}321322// Fill in the register numbers323reg_info.kinds[lldb::eRegisterKindLLDB] = i;324reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;325uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;326reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,327LLDB_INVALID_REGNUM);328if (eh_frame_regno == LLDB_INVALID_REGNUM)329reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,330LLDB_INVALID_REGNUM);331reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;332reg_info_dict->GetValueForKeyAsInteger(333"dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);334llvm::StringRef generic_str;335if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))336reg_info.kinds[lldb::eRegisterKindGeneric] =337Args::StringToGenericRegister(generic_str);338else339reg_info_dict->GetValueForKeyAsInteger(340"generic", reg_info.kinds[lldb::eRegisterKindGeneric],341LLDB_INVALID_REGNUM);342343// Check if this register invalidates any other register values when it is344// modified345StructuredData::Array *invalidate_reg_list = nullptr;346if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",347invalidate_reg_list)) {348const size_t num_regs = invalidate_reg_list->GetSize();349if (num_regs > 0) {350for (uint32_t idx = 0; idx < num_regs; ++idx) {351if (auto maybe_invalidate_reg_name =352invalidate_reg_list->GetItemAtIndexAsString(idx)) {353const RegisterInfo *invalidate_reg_info =354GetRegisterInfo(*maybe_invalidate_reg_name);355if (invalidate_reg_info) {356m_invalidate_regs_map[i].push_back(357invalidate_reg_info->kinds[eRegisterKindLLDB]);358} else {359// TODO: print error invalid slice string that doesn't follow the360// format361printf("error: failed to find a 'invalidate-regs' register for "362"\"%s\" while parsing register \"%s\"\n",363maybe_invalidate_reg_name->str().c_str(), reg_info.name);364}365} else if (auto maybe_invalidate_reg_num =366invalidate_reg_list->GetItemAtIndexAsInteger<uint64_t>(367idx)) {368if (*maybe_invalidate_reg_num != UINT64_MAX)369m_invalidate_regs_map[i].push_back(*maybe_invalidate_reg_num);370else371printf("error: 'invalidate-regs' list value wasn't a valid "372"integer\n");373} else {374printf("error: 'invalidate-regs' list value wasn't a python string "375"or integer\n");376}377}378} else {379printf("error: 'invalidate-regs' contained an empty list\n");380}381}382383// Calculate the register offset384const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;385if (m_reg_data_byte_size < end_reg_offset)386m_reg_data_byte_size = end_reg_offset;387388m_regs.push_back(reg_info);389m_set_reg_nums[set].push_back(i);390}391Finalize(arch);392return m_regs.size();393}394395size_t DynamicRegisterInfo::SetRegisterInfo(396std::vector<DynamicRegisterInfo::Register> &®s,397const ArchSpec &arch) {398assert(!m_finalized);399400for (auto it : llvm::enumerate(regs)) {401uint32_t local_regnum = it.index();402const DynamicRegisterInfo::Register ® = it.value();403404assert(reg.name);405assert(reg.set_name);406407if (!reg.value_regs.empty())408m_value_regs_map[local_regnum] = std::move(reg.value_regs);409if (!reg.invalidate_regs.empty())410m_invalidate_regs_map[local_regnum] = std::move(reg.invalidate_regs);411if (reg.value_reg_offset != 0) {412assert(reg.value_regs.size() == 1);413m_value_reg_offset_map[local_regnum] = reg.value_reg_offset;414}415416struct RegisterInfo reg_info {417reg.name.AsCString(), reg.alt_name.AsCString(), reg.byte_size,418reg.byte_offset, reg.encoding, reg.format,419{reg.regnum_ehframe, reg.regnum_dwarf, reg.regnum_generic,420reg.regnum_remote, local_regnum},421// value_regs and invalidate_regs are filled by Finalize()422nullptr, nullptr, reg.flags_type423};424425m_regs.push_back(reg_info);426427uint32_t set = GetRegisterSetIndexByName(reg.set_name, true);428assert(set < m_sets.size());429assert(set < m_set_reg_nums.size());430assert(set < m_set_names.size());431m_set_reg_nums[set].push_back(local_regnum);432};433434Finalize(arch);435return m_regs.size();436}437438void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {439if (m_finalized)440return;441442m_finalized = true;443const size_t num_sets = m_sets.size();444for (size_t set = 0; set < num_sets; ++set) {445assert(m_sets.size() == m_set_reg_nums.size());446m_sets[set].num_registers = m_set_reg_nums[set].size();447m_sets[set].registers = m_set_reg_nums[set].data();448}449450// make sure value_regs are terminated with LLDB_INVALID_REGNUM451452for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),453end = m_value_regs_map.end();454pos != end; ++pos) {455if (pos->second.back() != LLDB_INVALID_REGNUM)456pos->second.push_back(LLDB_INVALID_REGNUM);457}458459// Now update all value_regs with each register info as needed460const size_t num_regs = m_regs.size();461for (size_t i = 0; i < num_regs; ++i) {462if (m_value_regs_map.find(i) != m_value_regs_map.end())463m_regs[i].value_regs = m_value_regs_map[i].data();464else465m_regs[i].value_regs = nullptr;466}467468// Expand all invalidation dependencies469for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),470end = m_invalidate_regs_map.end();471pos != end; ++pos) {472const uint32_t reg_num = pos->first;473474if (m_regs[reg_num].value_regs) {475reg_num_collection extra_invalid_regs;476for (const uint32_t invalidate_reg_num : pos->second) {477reg_to_regs_map::iterator invalidate_pos =478m_invalidate_regs_map.find(invalidate_reg_num);479if (invalidate_pos != m_invalidate_regs_map.end()) {480for (const uint32_t concrete_invalidate_reg_num :481invalidate_pos->second) {482if (concrete_invalidate_reg_num != reg_num)483extra_invalid_regs.push_back(concrete_invalidate_reg_num);484}485}486}487pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),488extra_invalid_regs.end());489}490}491492// sort and unique all invalidate registers and make sure each is terminated493// with LLDB_INVALID_REGNUM494for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),495end = m_invalidate_regs_map.end();496pos != end; ++pos) {497if (pos->second.size() > 1) {498llvm::sort(pos->second);499reg_num_collection::iterator unique_end =500std::unique(pos->second.begin(), pos->second.end());501if (unique_end != pos->second.end())502pos->second.erase(unique_end, pos->second.end());503}504assert(!pos->second.empty());505if (pos->second.back() != LLDB_INVALID_REGNUM)506pos->second.push_back(LLDB_INVALID_REGNUM);507}508509// Now update all invalidate_regs with each register info as needed510for (size_t i = 0; i < num_regs; ++i) {511if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())512m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();513else514m_regs[i].invalidate_regs = nullptr;515}516517// Check if we need to automatically set the generic registers in case they518// weren't set519bool generic_regs_specified = false;520for (const auto ® : m_regs) {521if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {522generic_regs_specified = true;523break;524}525}526527if (!generic_regs_specified) {528switch (arch.GetMachine()) {529case llvm::Triple::aarch64:530case llvm::Triple::aarch64_32:531case llvm::Triple::aarch64_be:532for (auto ® : m_regs) {533if (strcmp(reg.name, "pc") == 0)534reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;535else if ((strcmp(reg.name, "fp") == 0) ||536(strcmp(reg.name, "x29") == 0))537reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;538else if ((strcmp(reg.name, "lr") == 0) ||539(strcmp(reg.name, "x30") == 0))540reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;541else if ((strcmp(reg.name, "sp") == 0) ||542(strcmp(reg.name, "x31") == 0))543reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;544else if (strcmp(reg.name, "cpsr") == 0)545reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;546}547break;548549case llvm::Triple::arm:550case llvm::Triple::armeb:551case llvm::Triple::thumb:552case llvm::Triple::thumbeb:553for (auto ® : m_regs) {554if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))555reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;556else if ((strcmp(reg.name, "sp") == 0) ||557(strcmp(reg.name, "r13") == 0))558reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;559else if ((strcmp(reg.name, "lr") == 0) ||560(strcmp(reg.name, "r14") == 0))561reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;562else if ((strcmp(reg.name, "r7") == 0) &&563arch.GetTriple().getVendor() == llvm::Triple::Apple)564reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;565else if ((strcmp(reg.name, "r11") == 0) &&566arch.GetTriple().getVendor() != llvm::Triple::Apple)567reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;568else if (strcmp(reg.name, "fp") == 0)569reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;570else if (strcmp(reg.name, "cpsr") == 0)571reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;572}573break;574575case llvm::Triple::x86:576for (auto ® : m_regs) {577if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))578reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;579else if ((strcmp(reg.name, "esp") == 0) ||580(strcmp(reg.name, "sp") == 0))581reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;582else if ((strcmp(reg.name, "ebp") == 0) ||583(strcmp(reg.name, "fp") == 0))584reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;585else if ((strcmp(reg.name, "eflags") == 0) ||586(strcmp(reg.name, "flags") == 0))587reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;588}589break;590591case llvm::Triple::x86_64:592for (auto ® : m_regs) {593if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))594reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;595else if ((strcmp(reg.name, "rsp") == 0) ||596(strcmp(reg.name, "sp") == 0))597reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;598else if ((strcmp(reg.name, "rbp") == 0) ||599(strcmp(reg.name, "fp") == 0))600reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;601else if ((strcmp(reg.name, "rflags") == 0) ||602(strcmp(reg.name, "eflags") == 0) ||603(strcmp(reg.name, "flags") == 0))604reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;605}606break;607608default:609break;610}611}612613// At this stage call ConfigureOffsets to calculate register offsets for614// targets supporting dynamic offset calculation. It also calculates615// total byte size of register data.616ConfigureOffsets();617618// Check if register info is reconfigurable619// AArch64 SVE register set has configurable register sizes, as does the ZA620// register that SME added (the streaming state of SME reuses the SVE state).621if (arch.GetTriple().isAArch64()) {622for (const auto ® : m_regs) {623if ((strcmp(reg.name, "vg") == 0) || (strcmp(reg.name, "svg") == 0)) {624m_is_reconfigurable = true;625break;626}627}628}629}630631void DynamicRegisterInfo::ConfigureOffsets() {632// We are going to create a map between remote (eRegisterKindProcessPlugin)633// and local (eRegisterKindLLDB) register numbers. This map will give us634// remote register numbers in increasing order for offset calculation.635std::map<uint32_t, uint32_t> remote_to_local_regnum_map;636for (const auto ® : m_regs)637remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =638reg.kinds[eRegisterKindLLDB];639640// At this stage we manually calculate g/G packet offsets of all primary641// registers, only if target XML or qRegisterInfo packet did not send642// an offset explicitly.643uint32_t reg_offset = 0;644for (auto const ®num_pair : remote_to_local_regnum_map) {645if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&646m_regs[regnum_pair.second].value_regs == nullptr) {647m_regs[regnum_pair.second].byte_offset = reg_offset;648649reg_offset = m_regs[regnum_pair.second].byte_offset +650m_regs[regnum_pair.second].byte_size;651}652}653654// Now update all value_regs with each register info as needed655for (auto ® : m_regs) {656if (reg.value_regs != nullptr) {657// Assign a valid offset to all pseudo registers that have only a single658// parent register in value_regs list, if not assigned by stub. Pseudo659// registers with value_regs list populated will share same offset as660// that of their corresponding parent register.661if (reg.byte_offset == LLDB_INVALID_INDEX32) {662uint32_t value_regnum = reg.value_regs[0];663if (value_regnum != LLDB_INVALID_INDEX32 &&664reg.value_regs[1] == LLDB_INVALID_INDEX32) {665reg.byte_offset =666GetRegisterInfoAtIndex(value_regnum)->byte_offset;667auto it = m_value_reg_offset_map.find(reg.kinds[eRegisterKindLLDB]);668if (it != m_value_reg_offset_map.end())669reg.byte_offset += it->second;670}671}672}673674reg_offset = reg.byte_offset + reg.byte_size;675if (m_reg_data_byte_size < reg_offset)676m_reg_data_byte_size = reg_offset;677}678}679680bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; }681682size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }683684size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }685686size_t DynamicRegisterInfo::GetRegisterDataByteSize() const {687return m_reg_data_byte_size;688}689690const RegisterInfo *691DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) const {692if (i < m_regs.size())693return &m_regs[i];694return nullptr;695}696697const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind,698uint32_t num) const {699uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num);700if (reg_index != LLDB_INVALID_REGNUM)701return &m_regs[reg_index];702return nullptr;703}704705const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {706if (i < m_sets.size())707return &m_sets[i];708return nullptr;709}710711uint32_t712DynamicRegisterInfo::GetRegisterSetIndexByName(const ConstString &set_name,713bool can_create) {714name_collection::iterator pos, end = m_set_names.end();715for (pos = m_set_names.begin(); pos != end; ++pos) {716if (*pos == set_name)717return std::distance(m_set_names.begin(), pos);718}719720m_set_names.push_back(set_name);721m_set_reg_nums.resize(m_set_reg_nums.size() + 1);722RegisterSet new_set = {set_name.AsCString(), nullptr, 0, nullptr};723m_sets.push_back(new_set);724return m_sets.size() - 1;725}726727uint32_t728DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber(uint32_t kind,729uint32_t num) const {730reg_collection::const_iterator pos, end = m_regs.end();731for (pos = m_regs.begin(); pos != end; ++pos) {732if (pos->kinds[kind] == num)733return std::distance(m_regs.begin(), pos);734}735736return LLDB_INVALID_REGNUM;737}738739void DynamicRegisterInfo::Clear() {740m_regs.clear();741m_sets.clear();742m_set_reg_nums.clear();743m_set_names.clear();744m_value_regs_map.clear();745m_invalidate_regs_map.clear();746m_reg_data_byte_size = 0;747m_finalized = false;748}749750void DynamicRegisterInfo::Dump() const {751StreamFile s(stdout, false);752const size_t num_regs = m_regs.size();753s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",754static_cast<const void *>(this), static_cast<uint64_t>(num_regs));755for (size_t i = 0; i < num_regs; ++i) {756s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);757s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",758m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding,759FormatManager::GetFormatAsCString(m_regs[i].format));760if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)761s.Printf(", process plugin = %3u",762m_regs[i].kinds[eRegisterKindProcessPlugin]);763if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)764s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);765if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)766s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);767if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)768s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);769if (m_regs[i].alt_name)770s.Printf(", alt-name = %s", m_regs[i].alt_name);771if (m_regs[i].value_regs) {772s.Printf(", value_regs = [ ");773for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) {774s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);775}776s.Printf("]");777}778if (m_regs[i].invalidate_regs) {779s.Printf(", invalidate_regs = [ ");780for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM;781++j) {782s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);783}784s.Printf("]");785}786s.EOL();787}788789const size_t num_sets = m_sets.size();790s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",791static_cast<const void *>(this), static_cast<uint64_t>(num_sets));792for (size_t i = 0; i < num_sets; ++i) {793s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i,794m_sets[i].name);795for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) {796s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);797}798s.Printf("]\n");799}800}801802const lldb_private::RegisterInfo *803DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const {804for (auto ®_info : m_regs)805if (reg_info.name == reg_name)806return ®_info;807return nullptr;808}809810void lldb_private::addSupplementaryRegister(811std::vector<DynamicRegisterInfo::Register> ®s,812DynamicRegisterInfo::Register new_reg_info) {813assert(!new_reg_info.value_regs.empty());814const uint32_t reg_num = regs.size();815regs.push_back(new_reg_info);816817std::map<uint32_t, std::vector<uint32_t>> new_invalidates;818for (uint32_t value_reg : new_reg_info.value_regs) {819// copy value_regs to invalidate_regs820new_invalidates[reg_num].push_back(value_reg);821822// copy invalidate_regs from the parent register823llvm::append_range(new_invalidates[reg_num],824regs[value_reg].invalidate_regs);825826// add reverse invalidate entries827for (uint32_t x : new_invalidates[reg_num])828new_invalidates[x].push_back(reg_num);829}830831for (const auto &x : new_invalidates)832llvm::append_range(regs[x.first].invalidate_regs, x.second);833}834835836