[Lldb-commits] [lldb] r247121 - When lldb gets the register definitions from the response of a

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 8 20:36:25 PDT 2015

Author: jmolenda
Date: Tue Sep  8 22:36:24 2015
New Revision: 247121

URL: http://llvm.org/viewvc/llvm-project?rev=247121&view=rev
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

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

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.



Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=247121&r1=247120&r2=247121&view=diff
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Sep  8 22:36:24 2015
@@ -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::ParsePythonTargetDefin
     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 &reg_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<uint32_t> &regnums, int base)
@@ -715,6 +745,8 @@ ProcessGDBRemote::BuildDynamicRegisterIn
                     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);
@@ -4273,7 +4305,7 @@ struct GdbServerTargetInfo
-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, Gd
     uint32_t prev_reg_num = 0;
     uint32_t reg_offset = 0;
-    feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &prev_reg_num, &reg_offset](const XMLNode &reg_node) -> bool {
+    feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &prev_reg_num, &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
         std::string gdb_group;
         std::string gdb_type;
         ConstString reg_name;
@@ -4444,6 +4476,7 @@ ParseRegisters (XMLNode feature_node, Gd
+        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::GetGDBServerRegisterIn
             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::GetGDBServerRegisterIn
                 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());

More information about the lldb-commits mailing list