diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h --- a/lldb/include/lldb/Target/ABI.h +++ b/lldb/include/lldb/Target/ABI.h @@ -11,6 +11,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" @@ -127,7 +128,8 @@ llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } - virtual void AugmentRegisterInfo(RegisterInfo &info) = 0; + virtual void + AugmentRegisterInfo(std::vector ®s) = 0; virtual bool GetPointerReturnRegister(const char *&name) { return false; } @@ -159,7 +161,8 @@ class RegInfoBasedABI : public ABI { public: - void AugmentRegisterInfo(RegisterInfo &info) override; + void AugmentRegisterInfo( + std::vector ®s) override; protected: using ABI::ABI; @@ -171,12 +174,14 @@ class MCBasedABI : public ABI { public: - void AugmentRegisterInfo(RegisterInfo &info) override; + void AugmentRegisterInfo( + std::vector ®s) override; /// If the register name is of the form "[]" then change /// the name to "[]". Otherwise, leave the name unchanged. static void MapRegisterName(std::string ®, llvm::StringRef from_prefix, - llvm::StringRef to_prefix); + llvm::StringRef to_prefix); + protected: using ABI::ABI; diff --git a/lldb/include/lldb/Target/DynamicRegisterInfo.h b/lldb/include/lldb/Target/DynamicRegisterInfo.h --- a/lldb/include/lldb/Target/DynamicRegisterInfo.h +++ b/lldb/include/lldb/Target/DynamicRegisterInfo.h @@ -24,6 +24,22 @@ DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default; public: + struct Register { + ConstString name; + ConstString alt_name; + ConstString set_name; + uint32_t byte_size = LLDB_INVALID_INDEX32; + uint32_t byte_offset = LLDB_INVALID_INDEX32; + lldb::Encoding encoding = lldb::eEncodingUint; + lldb::Format format = lldb::eFormatHex; + uint32_t regnum_dwarf = LLDB_INVALID_REGNUM; + uint32_t regnum_ehframe = LLDB_INVALID_REGNUM; + uint32_t regnum_generic = LLDB_INVALID_REGNUM; + uint32_t regnum_remote = LLDB_INVALID_REGNUM; + std::vector value_regs; + std::vector invalidate_regs; + }; + DynamicRegisterInfo() = default; DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, diff --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h --- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h +++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h @@ -11,7 +11,7 @@ #include "lldb/Target/ABI.h" -class ABIAArch64: public lldb_private::MCBasedABI { +class ABIAArch64 : public lldb_private::MCBasedABI { public: static void Initialize(); static void Terminate(); @@ -31,7 +31,8 @@ uint32_t GetGenericNum(llvm::StringRef name) override; - void AugmentRegisterInfo(lldb_private::RegisterInfo &info) override; + void AugmentRegisterInfo( + std::vector ®s) override; using lldb_private::MCBasedABI::MCBasedABI; }; diff --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp --- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -71,10 +71,14 @@ .Default(LLDB_INVALID_REGNUM); } -void ABIAArch64::AugmentRegisterInfo(lldb_private::RegisterInfo &info) { - lldb_private::MCBasedABI::AugmentRegisterInfo(info); +void ABIAArch64::AugmentRegisterInfo( + std::vector ®s) { + lldb_private::MCBasedABI::AugmentRegisterInfo(regs); - // GDB sends x31 as "sp". Add the "x31" alt_name for convenience. - if (!strcmp(info.name, "sp") && !info.alt_name) - info.alt_name = "x31"; + lldb_private::ConstString sp_string{"sp"}; + for (lldb_private::DynamicRegisterInfo::Register &info : regs) { + // GDB sends x31 as "sp". Add the "x31" alt_name for convenience. + if (info.name == sp_string && !info.alt_name) + info.alt_name.SetCString("x31"); + } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -19,6 +19,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ArchSpec.h" @@ -44,22 +45,6 @@ } namespace process_gdb_remote { -struct RemoteRegisterInfo { - ConstString name; - ConstString alt_name; - ConstString set_name; - uint32_t byte_size = LLDB_INVALID_INDEX32; - uint32_t byte_offset = LLDB_INVALID_INDEX32; - lldb::Encoding encoding = lldb::eEncodingUint; - lldb::Format format = lldb::eFormatHex; - uint32_t regnum_dwarf = LLDB_INVALID_REGNUM; - uint32_t regnum_ehframe = LLDB_INVALID_REGNUM; - uint32_t regnum_generic = LLDB_INVALID_REGNUM; - uint32_t regnum_remote = LLDB_INVALID_REGNUM; - std::vector value_regs; - std::vector invalidate_regs; -}; - class ThreadGDBRemote; class ProcessGDBRemote : public Process, @@ -411,11 +396,11 @@ bool GetGDBServerRegisterInfoXMLAndProcess( ArchSpec &arch_to_use, std::string xml_filename, - std::vector ®isters); + std::vector ®isters); - // Convert RemoteRegisterInfos into RegisterInfos and add to the dynamic - // register list. - void AddRemoteRegisters(std::vector ®isters, + // Convert DynamicRegisterInfo::Registers into RegisterInfos and add + // to the dynamic register list. + void AddRemoteRegisters(std::vector ®isters, const ArchSpec &arch_to_use); // Query remote GDBServer for register information bool GetGDBServerRegisterInfo(ArchSpec &arch); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -442,7 +442,7 @@ return; char packet[128]; - std::vector registers; + std::vector registers; uint32_t reg_num = 0; for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse; @@ -458,7 +458,7 @@ if (response_type == StringExtractorGDBRemote::eResponse) { llvm::StringRef name; llvm::StringRef value; - RemoteRegisterInfo reg_info; + DynamicRegisterInfo::Register reg_info; while (response.GetNameColonValue(name, value)) { if (name.equals("name")) { @@ -4223,7 +4223,7 @@ }; bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, - std::vector ®isters) { + std::vector ®isters) { if (!feature_node) return false; @@ -4231,7 +4231,7 @@ "reg", [&target_info, ®isters](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; - RemoteRegisterInfo reg_info; + DynamicRegisterInfo::Register reg_info; bool encoding_set = false; bool format_set = false; @@ -4356,7 +4356,8 @@ // for nested register definition files. It returns true if it was able // to fetch and parse an xml file. bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( - ArchSpec &arch_to_use, std::string xml_filename, std::vector ®isters) { + ArchSpec &arch_to_use, std::string xml_filename, + std::vector ®isters) { // request the target xml file llvm::Expected raw = m_gdb_comm.ReadExtFeature("features", xml_filename); if (errorToBool(raw.takeError())) @@ -4466,16 +4467,12 @@ } void ProcessGDBRemote::AddRemoteRegisters( - std::vector ®isters, const ArchSpec &arch_to_use) { - // Don't use Process::GetABI, this code gets called from DidAttach, and - // in that context we haven't set the Target's architecture yet, so the - // ABI is also potentially incorrect. - ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); - + std::vector ®isters, + const ArchSpec &arch_to_use) { std::map remote_to_local_map; uint32_t remote_regnum = 0; for (auto it : llvm::enumerate(registers)) { - RemoteRegisterInfo &remote_reg_info = it.value(); + DynamicRegisterInfo::Register &remote_reg_info = it.value(); // Assign successive remote regnums if missing. if (remote_reg_info.regnum_remote == LLDB_INVALID_REGNUM) @@ -4487,10 +4484,7 @@ remote_regnum = remote_reg_info.regnum_remote + 1; } - for (auto it : llvm::enumerate(registers)) { - uint32_t local_regnum = it.index(); - RemoteRegisterInfo &remote_reg_info = it.value(); - + for (DynamicRegisterInfo::Register &remote_reg_info : registers) { auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) { auto lldb_regit = remote_to_local_map.find(process_regnum); return lldb_regit != remote_to_local_map.end() ? lldb_regit->second @@ -4501,6 +4495,17 @@ remote_reg_info.value_regs.begin(), proc_to_lldb); llvm::transform(remote_reg_info.invalidate_regs, remote_reg_info.invalidate_regs.begin(), proc_to_lldb); + } + + // Don't use Process::GetABI, this code gets called from DidAttach, and + // in that context we haven't set the Target's architecture yet, so the + // ABI is also potentially incorrect. + if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use)) + abi_sp->AugmentRegisterInfo(registers); + + for (auto it : llvm::enumerate(registers)) { + uint32_t local_regnum = it.index(); + DynamicRegisterInfo::Register &remote_reg_info = it.value(); auto regs_with_sentinel = [](std::vector &vec) -> uint32_t * { if (!vec.empty()) { @@ -4520,9 +4525,6 @@ regs_with_sentinel(remote_reg_info.value_regs), regs_with_sentinel(remote_reg_info.invalidate_regs), }; - - if (abi_sp) - abi_sp->AugmentRegisterInfo(reg_info); m_register_info_sp->AddRegister(reg_info, remote_reg_info.set_name); }; @@ -4540,7 +4542,7 @@ if (!m_gdb_comm.GetQXferFeaturesReadSupported()) return false; - std::vector registers; + std::vector registers; if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml", registers)) AddRemoteRegisters(registers, arch_to_use); @@ -4590,14 +4592,12 @@ root_element.ForEachChildElementWithName( "library", [log, &list](const XMLNode &library) -> bool { - LoadedModuleInfoList::LoadedModuleInfo module; // FIXME: we're silently ignoring invalid data here library.ForEachAttribute( [&module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - uint64_t uint_value = LLDB_INVALID_ADDRESS; if (name == "name") module.set_name(value.str()); diff --git a/lldb/source/Target/ABI.cpp b/lldb/source/Target/ABI.cpp --- a/lldb/source/Target/ABI.cpp +++ b/lldb/source/Target/ABI.cpp @@ -214,33 +214,39 @@ return info_up; } -void RegInfoBasedABI::AugmentRegisterInfo(RegisterInfo &info) { - if (info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM && - info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) - return; - - RegisterInfo abi_info; - if (!GetRegisterInfoByName(info.name, abi_info)) - return; - - if (info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindEHFrame] = abi_info.kinds[eRegisterKindEHFrame]; - if (info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindDWARF] = abi_info.kinds[eRegisterKindDWARF]; - if (info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindGeneric] = abi_info.kinds[eRegisterKindGeneric]; +void RegInfoBasedABI::AugmentRegisterInfo( + std::vector ®s) { + for (DynamicRegisterInfo::Register &info : regs) { + if (info.regnum_ehframe != LLDB_INVALID_REGNUM && + info.regnum_dwarf != LLDB_INVALID_REGNUM) + continue; + + RegisterInfo abi_info; + if (!GetRegisterInfoByName(info.name.GetStringRef(), abi_info)) + continue; + + if (info.regnum_ehframe == LLDB_INVALID_REGNUM) + info.regnum_ehframe = abi_info.kinds[eRegisterKindEHFrame]; + if (info.regnum_dwarf == LLDB_INVALID_REGNUM) + info.regnum_dwarf = abi_info.kinds[eRegisterKindDWARF]; + if (info.regnum_generic == LLDB_INVALID_REGNUM) + info.regnum_generic = abi_info.kinds[eRegisterKindGeneric]; + } } -void MCBasedABI::AugmentRegisterInfo(RegisterInfo &info) { - uint32_t eh, dwarf; - std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name); - - if (info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindEHFrame] = eh; - if (info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindDWARF] = dwarf; - if (info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindGeneric] = GetGenericNum(info.name); +void MCBasedABI::AugmentRegisterInfo( + std::vector ®s) { + for (DynamicRegisterInfo::Register &info : regs) { + uint32_t eh, dwarf; + std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name.GetStringRef()); + + if (info.regnum_ehframe == LLDB_INVALID_REGNUM) + info.regnum_ehframe = eh; + if (info.regnum_dwarf == LLDB_INVALID_REGNUM) + info.regnum_dwarf = dwarf; + if (info.regnum_generic == LLDB_INVALID_REGNUM) + info.regnum_generic = GetGenericNum(info.name.GetStringRef()); + } } std::pair