[Lldb-commits] [lldb] 78cb456 - Make offset field optional in RegisterInfo packet for Arm64

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Tue Dec 1 14:20:08 PST 2020


Author: Muhammad Omair Javaid
Date: 2020-12-02T03:19:43+05:00
New Revision: 78cb4562faa7315fff030593bc6bca4dc033f803

URL: https://github.com/llvm/llvm-project/commit/78cb4562faa7315fff030593bc6bca4dc033f803
DIFF: https://github.com/llvm/llvm-project/commit/78cb4562faa7315fff030593bc6bca4dc033f803.diff

LOG: Make offset field optional in RegisterInfo packet for Arm64

This patch carries forward our aim to remove offset field from qRegisterInfo
packets and XML register description. I have created a new function which
returns if offset fields are dynamic meaning client can calculate offset on
its own based on register number sequence and register size. For now this
function only returns true for NativeRegisterContextLinux_arm64 but we can
test this for other architectures and make it standard later.

As a consequence we do not send offset field from lldb-server (arm64 for now)
while other stubs dont have an offset field so it wont effect them for now.
On the client side we have replaced previous offset calculation algorithm
with a new scheme, where we sort all primary registers in increasing
order of remote regnum and then calculate offset incrementally.

This committ also includes a test to verify all of above functionality
on Arm64.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D91241

Added: 
    lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py

Modified: 
    lldb/include/lldb/Host/common/NativeRegisterContext.h
    lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
    lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
    lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
    lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
    lldb/unittests/tools/lldb-server/tests/TestClient.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Host/common/NativeRegisterContext.h b/lldb/include/lldb/Host/common/NativeRegisterContext.h
index a8c74358c718..f7568fe31b80 100644
--- a/lldb/include/lldb/Host/common/NativeRegisterContext.h
+++ b/lldb/include/lldb/Host/common/NativeRegisterContext.h
@@ -121,6 +121,8 @@ class NativeRegisterContext
   virtual std::vector<uint32_t>
   GetExpeditedRegisters(ExpeditedRegs expType) const;
 
+  virtual bool RegisterOffsetIsDynamic() const { return false; }
+
   const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name,
                                             uint32_t start_idx = 0);
 

diff  --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
index a1c420d1fa03..2f278289988c 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
@@ -664,7 +664,10 @@ def assert_valid_reg_info(self, reg_info):
         # Check the bare-minimum expected set of register info keys.
         self.assertTrue("name" in reg_info)
         self.assertTrue("bitsize" in reg_info)
-        self.assertTrue("offset" in reg_info)
+
+        if not self.getArchitecture() == 'aarch64':
+            self.assertTrue("offset" in reg_info)
+
         self.assertTrue("encoding" in reg_info)
         self.assertTrue("format" in reg_info)
 

diff  --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 9ba8c7699a56..344eae247e91 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -47,6 +47,8 @@ class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
   std::vector<uint32_t>
   GetExpeditedRegisters(ExpeditedRegs expType) const override;
 
+  bool RegisterOffsetIsDynamic() const override { return true; }
+
   // Hardware breakpoints/watchpoint management functions
 
   uint32_t NumSupportedHardwareBreakpoints() override;

diff  --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index fd9e1923104d..71e9b5ea4b2a 100644
--- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -428,9 +428,6 @@ void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
   assert(set < m_set_reg_nums.size());
   assert(set < m_set_names.size());
   m_set_reg_nums[set].push_back(reg_num);
-  size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
-  if (m_reg_data_byte_size < end_reg_offset)
-    m_reg_data_byte_size = end_reg_offset;
 }
 
 void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
@@ -445,6 +442,28 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
     m_sets[set].registers = m_set_reg_nums[set].data();
   }
 
+  // We are going to create a map between remote (eRegisterKindProcessPlugin)
+  // and local (eRegisterKindLLDB) register numbers. This map will give us
+  // remote register numbers in increasing order for offset calculation.
+  std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
+  for (const auto &reg : m_regs)
+    remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =
+        reg.kinds[eRegisterKindLLDB];
+
+  // At this stage we manually calculate g/G packet offsets of all primary
+  // registers, only if target XML or qRegisterInfo packet did not send
+  // an offset explicitly.
+  uint32_t reg_offset = 0;
+  for (auto const &regnum_pair : remote_to_local_regnum_map) {
+    if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&
+        m_regs[regnum_pair.second].value_regs == nullptr) {
+      m_regs[regnum_pair.second].byte_offset = reg_offset;
+
+      reg_offset = m_regs[regnum_pair.second].byte_offset +
+                   m_regs[regnum_pair.second].byte_size;
+    }
+  }
+
   // sort and unique all value registers and make sure each is terminated with
   // LLDB_INVALID_REGNUM
 
@@ -466,10 +485,24 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
   // Now update all value_regs with each register info as needed
   const size_t num_regs = m_regs.size();
   for (size_t i = 0; i < num_regs; ++i) {
-    if (m_value_regs_map.find(i) != m_value_regs_map.end())
+    if (m_value_regs_map.find(i) != m_value_regs_map.end()) {
       m_regs[i].value_regs = m_value_regs_map[i].data();
-    else
+      // Assign a valid offset to all pseudo registers if not assigned by stub.
+      // Pseudo registers with value_regs list populated will share same offset
+      // as that of their corresponding primary register in value_regs list.
+      if (m_regs[i].byte_offset == LLDB_INVALID_INDEX32) {
+        uint32_t value_regnum = m_regs[i].value_regs[0];
+        if (value_regnum != LLDB_INVALID_INDEX32)
+          m_regs[i].byte_offset =
+              GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum])
+                  ->byte_offset;
+      }
+    } else
       m_regs[i].value_regs = nullptr;
+
+    reg_offset = m_regs[i].byte_offset + m_regs[i].byte_size;
+    if (m_reg_data_byte_size < reg_offset)
+      m_reg_data_byte_size = reg_offset;
   }
 
   // Expand all invalidation dependencies

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 694c88c49eba..c202fc9d339f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1788,8 +1788,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
     response.PutChar(';');
   }
 
-  response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
-                  reg_info->byte_size * 8, reg_info->byte_offset);
+  response.Printf("bitsize:%" PRIu32 ";", reg_info->byte_size * 8);
+
+  if (!reg_context.RegisterOffsetIsDynamic())
+    response.Printf("offset:%" PRIu32 ";", reg_info->byte_offset);
 
   llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info);
   if (!encoding.empty())
@@ -2861,10 +2863,11 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() {
       continue;
     }
 
-    response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" offset=\"%" PRIu32
-                    "\" regnum=\"%d\" ",
-                    reg_info->name, reg_info->byte_size * 8,
-                    reg_info->byte_offset, reg_index);
+    response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" regnum=\"%d\" ",
+                    reg_info->name, reg_info->byte_size * 8, reg_index);
+
+    if (!reg_context.RegisterOffsetIsDynamic())
+      response.Printf("offset=\"%" PRIu32 "\" ", reg_info->byte_offset);
 
     if (reg_info->alt_name && reg_info->alt_name[0])
       response.Printf("altname=\"%s\" ", reg_info->alt_name);

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 4c00e9a4c673..0d02acf1b12a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -451,7 +451,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
     return;
 
   char packet[128];
-  uint32_t reg_offset = 0;
+  uint32_t reg_offset = LLDB_INVALID_INDEX32;
   uint32_t reg_num = 0;
   for (StringExtractorGDBRemote::ResponseType response_type =
            StringExtractorGDBRemote::eResponse;
@@ -564,7 +564,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
 
         reg_info.byte_offset = reg_offset;
         assert(reg_info.byte_size != 0);
-        reg_offset += reg_info.byte_size;
+        reg_offset = LLDB_INVALID_INDEX32;
         if (!value_regs.empty()) {
           value_regs.push_back(LLDB_INVALID_REGNUM);
           reg_info.value_regs = value_regs.data();
@@ -4276,14 +4276,14 @@ struct GdbServerTargetInfo {
 
 bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
                     GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp,
-                    uint32_t &cur_reg_num, uint32_t &reg_offset) {
+                    uint32_t &reg_num_remote, uint32_t &reg_num_local) {
   if (!feature_node)
     return false;
 
+  uint32_t reg_offset = LLDB_INVALID_INDEX32;
   feature_node.ForEachChildElementWithName(
-      "reg",
-      [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset,
-       &abi_sp](const XMLNode &reg_node) -> bool {
+      "reg", [&target_info, &dyn_reg_info, &reg_num_remote, &reg_num_local,
+              &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
         std::string gdb_group;
         std::string gdb_type;
         ConstString reg_name;
@@ -4305,8 +4305,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
                 LLDB_INVALID_REGNUM, // eh_frame reg num
                 LLDB_INVALID_REGNUM, // DWARF reg num
                 LLDB_INVALID_REGNUM, // generic reg num
-                cur_reg_num,         // process plugin reg num
-                cur_reg_num          // native register number
+                reg_num_remote,      // process plugin reg num
+                reg_num_local        // native register number
             },
             nullptr,
             nullptr,
@@ -4433,7 +4433,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
 
         reg_info.byte_offset = reg_offset;
         assert(reg_info.byte_size != 0);
-        reg_offset += reg_info.byte_size;
+        reg_offset = LLDB_INVALID_INDEX32;
         if (!value_regs.empty()) {
           value_regs.push_back(LLDB_INVALID_REGNUM);
           reg_info.value_regs = value_regs.data();
@@ -4443,7 +4443,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
           reg_info.invalidate_regs = invalidate_regs.data();
         }
 
-        ++cur_reg_num;
+        reg_num_remote = reg_info.kinds[eRegisterKindProcessPlugin] + 1;
+        ++reg_num_local;
         reg_info.name = reg_name.AsCString();
         if (abi_sp)
           abi_sp->AugmentRegisterInfo(reg_info);
@@ -4462,8 +4463,8 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
 // 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, uint32_t &cur_reg_num,
-    uint32_t &reg_offset) {
+    ArchSpec &arch_to_use, std::string xml_filename, uint32_t &reg_num_remote,
+    uint32_t &reg_num_local) {
   // request the target xml file
   std::string raw;
   lldb_private::Status lldberr;
@@ -4567,12 +4568,12 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess(
       ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use);
       for (auto &feature_node : feature_nodes) {
         ParseRegisters(feature_node, target_info, this->m_register_info,
-                       abi_to_use_sp, cur_reg_num, reg_offset);
+                       abi_to_use_sp, reg_num_remote, reg_num_local);
       }
 
       for (const auto &include : target_info.includes) {
-        GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, cur_reg_num,
-                                              reg_offset);
+        GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include,
+                                              reg_num_remote, reg_num_local);
       }
     }
   } else {
@@ -4592,9 +4593,10 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
   if (!m_gdb_comm.GetQXferFeaturesReadSupported())
     return false;
 
-  uint32_t cur_reg_num = 0;
-  uint32_t reg_offset = 0;
-  if (GetGDBServerRegisterInfoXMLAndProcess (arch_to_use, "target.xml", cur_reg_num, reg_offset))
+  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))
     this->m_register_info.Finalize(arch_to_use);
 
   return m_register_info.GetNumRegisters() > 0;

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 5efe8b757af8..8e0a04f04eb0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -391,8 +391,8 @@ class ProcessGDBRemote : public Process,
 
   bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use,
                                              std::string xml_filename,
-                                             uint32_t &cur_reg_num,
-                                             uint32_t &reg_offset);
+                                             uint32_t &cur_reg_remote,
+                                             uint32_t &cur_reg_local);
 
   // Query remote GDBServer for register information
   bool GetGDBServerRegisterInfo(ArchSpec &arch);

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py b/lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py
new file mode 100644
index 000000000000..8026abc7fc18
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py
@@ -0,0 +1,151 @@
+from __future__ import print_function
+from textwrap import dedent
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+
+class MyResponder(MockGDBServerResponder):
+    def qXferRead(self, obj, annex, offset, length):
+        if annex == "target.xml":
+            return dedent("""\
+                <?xml version="1.0"?>
+                  <target version="1.0">
+                    <architecture>aarch64</architecture>
+                    <feature name="org.gnu.gdb.aarch64.core">
+                      <reg name="cpsr" regnum="33" bitsize="32"/>
+                      <reg name="x0" regnum="0" bitsize="64"/>
+                      <reg name="x1" bitsize="64"/>
+                      <reg name="x2" bitsize="64"/>
+                      <reg name="x3" bitsize="64"/>
+                      <reg name="x4" bitsize="64"/>
+                      <reg name="x5" bitsize="64"/>
+                      <reg name="x6" bitsize="64"/>
+                      <reg name="x7" bitsize="64"/>
+                      <reg name="x8" bitsize="64"/>
+                      <reg name="x9" bitsize="64"/>
+                      <reg name="x10" bitsize="64"/>
+                      <reg name="x11" bitsize="64"/>
+                      <reg name="x12" bitsize="64"/>
+                      <reg name="x13" bitsize="64"/>
+                      <reg name="x14" bitsize="64"/>
+                      <reg name="x15" bitsize="64"/>
+                      <reg name="x16" bitsize="64"/>
+                      <reg name="x17" bitsize="64"/>
+                      <reg name="x18" bitsize="64"/>
+                      <reg name="x19" bitsize="64"/>
+                      <reg name="x20" bitsize="64"/>
+                      <reg name="x21" bitsize="64"/>
+                      <reg name="x22" bitsize="64"/>
+                      <reg name="x23" bitsize="64"/>
+                      <reg name="x24" bitsize="64"/>
+                      <reg name="x25" bitsize="64"/>
+                      <reg name="x26" bitsize="64"/>
+                      <reg name="x27" bitsize="64"/>
+                      <reg name="x28" bitsize="64"/>
+                      <reg name="x29" bitsize="64"/>
+                      <reg name="x30" bitsize="64"/>
+                      <reg name="sp" bitsize="64"/>
+                      <reg name="pc" bitsize="64"/>
+                      <reg name="w0" bitsize="32" value_regnums="0" invalidate_regnums="0" regnum="34"/>
+                      <reg name="w1" bitsize="32" value_regnums="1" invalidate_regnums="1"/>
+                      <reg name="w2" bitsize="32" value_regnums="2" invalidate_regnums="2"/>
+                      <reg name="w3" bitsize="32" value_regnums="3" invalidate_regnums="3"/>
+                      <reg name="w4" bitsize="32" value_regnums="4" invalidate_regnums="4"/>
+                      <reg name="w5" bitsize="32" value_regnums="5" invalidate_regnums="5"/>
+                      <reg name="w6" bitsize="32" value_regnums="6" invalidate_regnums="6"/>
+                      <reg name="w7" bitsize="32" value_regnums="7" invalidate_regnums="7"/>
+                      <reg name="w8" bitsize="32" value_regnums="8" invalidate_regnums="8"/>
+                      <reg name="w9" bitsize="32" value_regnums="9" invalidate_regnums="9"/>
+                      <reg name="w10" bitsize="32" value_regnums="10" invalidate_regnums="10"/>
+                      <reg name="w11" bitsize="32" value_regnums="11" invalidate_regnums="11"/>
+                      <reg name="w12" bitsize="32" value_regnums="12" invalidate_regnums="12"/>
+                      <reg name="w13" bitsize="32" value_regnums="13" invalidate_regnums="13"/>
+                      <reg name="w14" bitsize="32" value_regnums="14" invalidate_regnums="14"/>
+                      <reg name="w15" bitsize="32" value_regnums="15" invalidate_regnums="15"/>
+                      <reg name="w16" bitsize="32" value_regnums="16" invalidate_regnums="16"/>
+                      <reg name="w17" bitsize="32" value_regnums="17" invalidate_regnums="17"/>
+                      <reg name="w18" bitsize="32" value_regnums="18" invalidate_regnums="18"/>
+                      <reg name="w19" bitsize="32" value_regnums="19" invalidate_regnums="19"/>
+                      <reg name="w20" bitsize="32" value_regnums="20" invalidate_regnums="20"/>
+                      <reg name="w21" bitsize="32" value_regnums="21" invalidate_regnums="21"/>
+                      <reg name="w22" bitsize="32" value_regnums="22" invalidate_regnums="22"/>
+                      <reg name="w23" bitsize="32" value_regnums="23" invalidate_regnums="23"/>
+                      <reg name="w24" bitsize="32" value_regnums="24" invalidate_regnums="24"/>
+                      <reg name="w25" bitsize="32" value_regnums="25" invalidate_regnums="25"/>
+                      <reg name="w26" bitsize="32" value_regnums="26" invalidate_regnums="26"/>
+                      <reg name="w27" bitsize="32" value_regnums="27" invalidate_regnums="27"/>
+                      <reg name="w28" bitsize="32" value_regnums="28" invalidate_regnums="28"/>
+                    </feature>
+                  </target>
+                """), False
+        else:
+            return None,
+
+    def readRegister(self, regnum):
+        return "E01"
+
+    def readRegisters(self):
+        return "20000000000000002000000000000000f0c154bfffff00005daa985a8fea0b48f0b954bfffff0000ad13cce570150b48380000000000000070456abfffff0000a700000000000000000000000000000001010101010101010000000000000000f0c154bfffff00000f2700000000000008e355bfffff0000080e55bfffff0000281041000000000010de61bfffff00005c05000000000000f0c154bfffff000090fcffffffff00008efcffffffff00008ffcffffffff00000000000000000000001000000000000090fcffffffff000000d06cbfffff0000f0c154bfffff00000100000000000000d0b954bfffff0000e407400000000000d0b954bfffff0000e40740000000000000100000"
+
+
+class TestAArch64XMLRegOffsets(GDBRemoteTestBase):
+
+    @skipIfXmlSupportMissing
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_register_gpacket_offsets(self):
+        """
+        Test that we correctly associate the register info with the eh_frame
+        register numbers.
+        """
+
+        target = self.createTarget("basic_eh_frame-aarch64.yaml")
+        self.server.responder = MyResponder()
+
+        if self.TraceOn():
+            self.runCmd("log enable gdb-remote packets")
+            self.addTearDownHook(
+                lambda: self.runCmd("log disable gdb-remote packets"))
+
+        process = self.connect(target)
+        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process,
+                                      [lldb.eStateStopped])
+
+        registerSet = process.GetThreadAtIndex(
+            0).GetFrameAtIndex(0).GetRegisters().GetValueAtIndex(0)
+
+        reg_val_dict = {
+            "x0": 0x0000000000000020, "x1": 0x0000000000000020,
+            "x2": 0x0000ffffbf54c1f0, "x3": 0x480bea8f5a98aa5d,
+            "x4": 0x0000ffffbf54b9f0, "x5": 0x480b1570e5cc13ad,
+            "x6": 0x0000000000000038, "x7": 0x0000ffffbf6a4570,
+            "x8": 0x00000000000000a7, "x9": 0x0000000000000000,
+            "x10": 0x0101010101010101, "x11": 0x0000000000000000,
+            "x12": 0x0000ffffbf54c1f0, "x13": 0x000000000000270f,
+            "x14": 0x0000ffffbf55e308, "x15": 0x0000ffffbf550e08,
+            "x16": 0x0000000000411028, "x17": 0x0000ffffbf61de10,
+            "x18": 0x000000000000055c, "x19": 0x0000ffffbf54c1f0,
+            "x20": 0x0000fffffffffc90, "x21": 0x0000fffffffffc8e,
+            "x22": 0x0000fffffffffc8f, "x23": 0x0000000000000000,
+            "x24": 0x0000000000001000, "x25": 0x0000fffffffffc90,
+            "x26": 0x0000ffffbf6cd000, "x27": 0x0000ffffbf54c1f0,
+            "x28": 0x0000000000000001, "x29": 0x0000ffffbf54b9d0,
+            "x30": 0x00000000004007e4, "sp": 0x0000ffffbf54b9d0,
+            "pc": 0x00000000004007e4, "cpsr": 0x00001000, "w0": 0x00000020,
+            "w1": 0x00000020, "w2": 0xbf54c1f0, "w3": 0x5a98aa5d,
+            "w4": 0xbf54b9f0, "w5": 0xe5cc13ad, "w6": 0x00000038,
+            "w7": 0xbf6a4570, "w8": 0x000000a7, "w9": 0x00000000,
+            "w10": 0x01010101, "w11": 0x00000000, "w12": 0xbf54c1f0,
+            "w13": 0x0000270f, "w14": 0xbf55e308, "w15": 0xbf550e08,
+            "w16": 0x00411028, "w17": 0xbf61de10, "w18": 0x0000055c,
+            "w19": 0xbf54c1f0, "w20": 0xfffffc90, "w21": 0xfffffc8e,
+            "w22": 0xfffffc8f, "w23": 0x00000000, "w24": 0x00001000,
+            "w25": 0xfffffc90, "w26": 0xbf6cd000, "w27": 0xbf54c1f0,
+            "w28": 0x00000001
+        }
+
+        for reg in registerSet:
+            self.assertEqual(reg.GetValueAsUnsigned(),
+                             reg_val_dict[reg.GetName()])

diff  --git a/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py b/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
index 5ef074c1802c..cd14fcf8125c 100644
--- a/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
+++ b/lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
@@ -65,5 +65,8 @@ def test_g_target_xml_returns_correct_data(self):
             self.assertEqual(q_info_reg["set"], xml_info_reg.get("group"))
             self.assertEqual(q_info_reg["format"], xml_info_reg.get("format"))
             self.assertEqual(q_info_reg["bitsize"], xml_info_reg.get("bitsize"))
-            self.assertEqual(q_info_reg["offset"], xml_info_reg.get("offset"))
+
+            if not self.getArchitecture() == 'aarch64':
+                self.assertEqual(q_info_reg["offset"], xml_info_reg.get("offset"))
+
             self.assertEqual(q_info_reg["encoding"], xml_info_reg.get("encoding"))

diff  --git a/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp b/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
index 3d1a153d2894..77bc3a5e6eef 100644
--- a/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
+++ b/lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
@@ -171,7 +171,7 @@ Expected<RegisterInfo> RegisterInfoParser::create(StringRef Response) {
   Info.byte_size /= CHAR_BIT;
 
   if (!to_integer(Elements["offset"], Info.byte_offset, 10))
-    return make_parsing_error("qRegisterInfo: offset");
+    Info.byte_offset = LLDB_INVALID_INDEX32;
 
   Info.encoding = Args::StringToEncoding(Elements["encoding"]);
   if (Info.encoding == eEncodingInvalid)

diff  --git a/lldb/unittests/tools/lldb-server/tests/TestClient.cpp b/lldb/unittests/tools/lldb-server/tests/TestClient.cpp
index 52428e4afc8a..752b0bb2600b 100644
--- a/lldb/unittests/tools/lldb-server/tests/TestClient.cpp
+++ b/lldb/unittests/tools/lldb-server/tests/TestClient.cpp
@@ -219,6 +219,7 @@ Error TestClient::qProcessInfo() {
 }
 
 Error TestClient::qRegisterInfos() {
+  uint32_t reg_offset = 0;
   for (unsigned int Reg = 0;; ++Reg) {
     std::string Message = formatv("qRegisterInfo{0:x-}", Reg).str();
     Expected<RegisterInfo> InfoOr = SendMessage<RegisterInfoParser>(Message);
@@ -227,6 +228,12 @@ Error TestClient::qRegisterInfos() {
       break;
     }
     m_register_infos.emplace_back(std::move(*InfoOr));
+
+    if (m_register_infos[Reg].byte_offset == LLDB_INVALID_INDEX32)
+      m_register_infos[Reg].byte_offset = reg_offset;
+
+    reg_offset =
+        m_register_infos[Reg].byte_offset + m_register_infos[Reg].byte_size;
     if (m_register_infos[Reg].kinds[eRegisterKindGeneric] ==
         LLDB_REGNUM_GENERIC_PC)
       m_pc_register = Reg;


        


More information about the lldb-commits mailing list