From 21586c83856cb54e82e25c9acd00a5f4d0e1ac8a Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Wed, 9 Sep 2015 03:36:24 +0000 Subject: [PATCH] When lldb gets the register definitions from the response of a qXfer:features:read:target.xml packet, or via the plugin.process.gdb-remote.target-definition-file setting, if the register definition doesn't give us eh_frame or DWARF register numbers for that register, try to get that information from the ABI plugin. The DWARF/eh_frame register numbers are defined in the ABI standardization documents - so getting this from the ABI plugin is reasonable. There's little value in having the remote stub inform us of this generic information, as long as we can all agree on the names of the registers. There's some additional information we could get from the ABI. For instance, on ABIs where function arguments are passed in registers, lldb defines alternate names like "arg1", "arg2", "arg3" for these registers so they can be referred to that way by the user. We could get this from the ABI if the remote stub doesn't provide that. That may be something worth doing in the future - but for now, I'm keeping this a little more minimal. Thinking about this, what we want/need from the remote stub at a minimum are: 1. The names of the register 2. The number that the stub will use to refer to the register with the p/P packets and in the ? response packets (T/S) where expedited register values are provided 3. The size of the register in bytes (nice to have, to remove any doubt) 4. The offset of the register in the g/G packet if we're going to use that for reading/writing registers. debugserver traditionally provides a lot more information in addition to this via the qRegisterInfo packet, and debugserver augments its response to the qXfer:features:read:target.xml query to include this information. Including: DWARF regnum, eh_frame regnum, stabs regnum, encoding (ieee754, Uint, Vector, Sint), format (hex, unsigned, pointer, vectorof*, float), registers that should be marked as invalid if this register is modified, and registers that contain this register. We might want to get all of this from the ABI - I'm not convinced that it makes sense for the remote stub to provide any of these details, as long as the ABI and remote stub can agree on register names. Anyway, start with eh_frame and DWARF coming from the ABI if they're not provided by the remote stub. We can look at doing more in the future. llvm-svn: 247121 --- .../Process/gdb-remote/ProcessGDBRemote.cpp | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 4a60d68dd238..e37e23f25a4c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -56,6 +56,7 @@ #include "lldb/Interpreter/OptionGroupUInt64.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" @@ -513,6 +514,35 @@ ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_ return false; } +// If the remote stub didn't give us eh_frame or DWARF register numbers for a register, +// see if the ABI can provide them. +// DWARF and eh_frame register numbers are defined as a part of the ABI. +static void +AugmentRegisterInfoViaABI (RegisterInfo ®_info, ConstString reg_name, ABISP abi_sp) +{ + if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM + || reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) + { + if (abi_sp) + { + RegisterInfo abi_reg_info; + if (abi_sp->GetRegisterInfoByName (reg_name, abi_reg_info)) + { + if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM + && abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) + { + reg_info.kinds[eRegisterKindEHFrame] = abi_reg_info.kinds[eRegisterKindEHFrame]; + } + if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM + && abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) + { + reg_info.kinds[eRegisterKindDWARF] = abi_reg_info.kinds[eRegisterKindDWARF]; + } + } + } + } +} + static size_t SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_regiter_numbers, std::vector ®nums, int base) { @@ -715,6 +745,8 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) reg_info.invalidate_regs = invalidate_regs.data(); } + AugmentRegisterInfoViaABI (reg_info, reg_name, GetABI ()); + m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name); } else @@ -4273,7 +4305,7 @@ struct GdbServerTargetInfo }; bool -ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info) +ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp) { if (!feature_node) return false; @@ -4281,7 +4313,7 @@ ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemot uint32_t prev_reg_num = 0; uint32_t reg_offset = 0; - feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &prev_reg_num, ®_offset](const XMLNode ®_node) -> bool { + feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &prev_reg_num, ®_offset, &abi_sp](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; ConstString reg_name; @@ -4444,6 +4476,7 @@ ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemot } ++prev_reg_num; + AugmentRegisterInfoViaABI (reg_info, reg_name, abi_sp); dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name); return true; // Keep iterating through all "reg" elements @@ -4539,7 +4572,7 @@ ProcessGDBRemote::GetGDBServerRegisterInfo () if (feature_node) { - ParseRegisters(feature_node, target_info, this->m_register_info); + ParseRegisters(feature_node, target_info, this->m_register_info, GetABI()); } for (const auto &include : target_info.includes) @@ -4557,7 +4590,7 @@ ProcessGDBRemote::GetGDBServerRegisterInfo () XMLNode include_feature_node = include_xml_document.GetRootElement("feature"); if (include_feature_node) { - ParseRegisters(include_feature_node, target_info, this->m_register_info); + ParseRegisters(include_feature_node, target_info, this->m_register_info, GetABI()); } } this->m_register_info.Finalize(GetTarget().GetArchitecture());