Index: lldb/include/lldb/Target/ABI.h =================================================================== --- lldb/include/lldb/Target/ABI.h +++ lldb/include/lldb/Target/ABI.h @@ -21,6 +21,9 @@ class Type; } +// TODO +class DynamicRegisterInfo; + namespace lldb_private { class ABI : public PluginInterface { @@ -128,6 +131,8 @@ llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } virtual void AugmentRegisterInfo(RegisterInfo &info) = 0; + // Routine called before DynamicRegisterInfo::Finalize(). + virtual void PreFinalizeDynamicRegisterInfo(DynamicRegisterInfo &info) {} virtual bool GetPointerReturnRegister(const char *&name) { return false; } Index: lldb/source/Plugins/ABI/AArch64/ABIAArch64.h =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABIAArch64.h +++ lldb/source/Plugins/ABI/AArch64/ABIAArch64.h @@ -32,6 +32,7 @@ uint32_t GetGenericNum(llvm::StringRef name) override; void AugmentRegisterInfo(lldb_private::RegisterInfo &info) override; + void PreFinalizeDynamicRegisterInfo(DynamicRegisterInfo &info) override; using lldb_private::MCBasedABI::MCBasedABI; }; Index: lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp =================================================================== --- lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -13,6 +13,8 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Target/Process.h" +#include "Plugins/Process/Utility/DynamicRegisterInfo.h" + LLDB_PLUGIN_DEFINE(ABIAArch64) void ABIAArch64::Initialize() { @@ -78,3 +80,45 @@ if (!strcmp(info.name, "sp") && !info.alt_name) info.alt_name = "x31"; } + +static uint32_t tmp_value_regs[32][2]; + +void ABIAArch64::PreFinalizeDynamicRegisterInfo(DynamicRegisterInfo &info) { + uint32_t next_regnum_process = 0; + // TODO: use public API + uint32_t next_regnum_lldb = info.m_regs.size(); + for (const lldb_private::RegisterInfo ® : info.m_regs) + next_regnum_process = std::max(next_regnum_process, + reg.kinds[lldb::eRegisterKindProcessPlugin]); + next_regnum_process++; + + lldb_private::ConstString group{"partial registers"}; + + // Create wN aliases for xN registers if missing. + for (int i = 0; i < 32; i++) { + std::string r64_name = llvm::formatv("x{0}", i); + std::string r32_name = llvm::formatv("w{0}", i); + const lldb_private::RegisterInfo* r64 = info.GetRegisterInfo(r64_name); + const lldb_private::RegisterInfo* r32 = info.GetRegisterInfo(r32_name); + if (r64 && !r32 && r64->byte_size == 8) { + lldb_private::ConstString r32_name_const{r32_name}; + // TODO + tmp_value_regs[i][0] = r64->kinds[lldb::eRegisterKindProcessPlugin]; + tmp_value_regs[i][1] = LLDB_INVALID_REGNUM; + + struct lldb_private::RegisterInfo new_reg { + r32_name_const.AsCString(), nullptr, 4, + LLDB_INVALID_INDEX32, r64->encoding, r64->format, + { + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, next_regnum_process++, + next_regnum_lldb++, + }, + tmp_value_regs[i], nullptr, + nullptr, 0 + }; + + info.AddRegister(new_reg, group); + } + } +} Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -70,7 +70,8 @@ const lldb_private::RegisterInfo * GetRegisterInfo(llvm::StringRef reg_name) const; -protected: +// TODO +//protected: // Classes that inherit from DynamicRegisterInfo can see and modify these typedef std::vector reg_collection; typedef std::vector set_collection; Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -453,6 +453,7 @@ if (GetGDBServerRegisterInfo(arch_to_use)) return; + ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); char packet[128]; uint32_t reg_offset = LLDB_INVALID_INDEX32; uint32_t reg_num = 0; @@ -582,7 +583,7 @@ // We have to make a temporary ABI here, and not use the GetABI because // this code gets called in DidAttach, when the target architecture // (and consequently the ABI we'll get from the process) may be wrong. - if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use)) + if (abi_sp) abi_sp->AugmentRegisterInfo(reg_info); m_register_info_sp->AddRegister(reg_info, set_name); @@ -595,6 +596,8 @@ } if (m_register_info_sp->GetNumRegisters() > 0) { + if (abi_sp) + abi_sp->PreFinalizeDynamicRegisterInfo(*m_register_info_sp); m_register_info_sp->Finalize(GetTarget().GetArchitecture()); return; } @@ -618,6 +621,8 @@ } // At this point, we can finalize our register info. + if (abi_sp) + abi_sp->PreFinalizeDynamicRegisterInfo(*m_register_info_sp); m_register_info_sp->Finalize(GetTarget().GetArchitecture()); } @@ -4704,8 +4709,12 @@ uint32_t reg_num_remote = 0; uint32_t reg_num_local = 0; if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml", - reg_num_remote, reg_num_local)) + reg_num_remote, reg_num_local)) { + ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); + if (abi_sp) + abi_sp->PreFinalizeDynamicRegisterInfo(*m_register_info_sp); this->m_register_info_sp->Finalize(arch_to_use); + } return m_register_info_sp->GetNumRegisters() > 0; } Index: lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py =================================================================== --- lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py +++ lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py @@ -423,3 +423,7 @@ ["x30 = 0x4847464544434241"]) self.match("register read flags", ["cpsr = 0x74737271"]) + + # test partial registers + self.match("register read w0", + ["w0 = 0x04030201"])