omjavaid updated this revision to Diff 305680.
omjavaid added a comment.

This update tries to fix concerns raised by removing AArch64 specific code and 
makes offset assignment more generic.

We now have a new flag which is set to true if offset field was present and on 
basis of that we assign offsets to Primary and Pseudo registers.

If offset is not specified for a primary register then its offset is equal to 
last_register_offset + last_register_size. This is what LLDB was doing already 
we just restrict this scheme to primary registers only.

If offset is not specified for a pseudo register then fall-back offset is same 
as the offset of its first value_reg in value_regs list.

For assigning offsets to pseudo registers all primary registers should have 
valid offsets. Primary registers  are assigned offsets in ParseRegisters and 
ProcessGDBRemote::BuildDynamicRegisterInfo while pseudo register offsets are 
update once their value_regs are known in DynamicRegisterInfo::Finalize


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91241/new/

https://reviews.llvm.org/D91241

Files:
  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/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

Index: lldb/unittests/tools/lldb-server/tests/TestClient.cpp
===================================================================
--- lldb/unittests/tools/lldb-server/tests/TestClient.cpp
+++ lldb/unittests/tools/lldb-server/tests/TestClient.cpp
@@ -219,6 +219,7 @@
 }
 
 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 @@
       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;
Index: lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
===================================================================
--- lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
+++ lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp
@@ -171,7 +171,7 @@
   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)
Index: lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
===================================================================
--- lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
+++ lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
@@ -65,5 +65,8 @@
             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"))
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
@@ -472,6 +472,7 @@
         std::vector<uint32_t> value_regs;
         std::vector<uint32_t> invalidate_regs;
         std::vector<uint8_t> dwarf_opcode_bytes;
+        bool offset_field_set = false;
         RegisterInfo reg_info = {
             nullptr,       // Name
             nullptr,       // Alt name
@@ -501,6 +502,7 @@
             value.getAsInteger(0, reg_info.byte_size);
             reg_info.byte_size /= CHAR_BIT;
           } else if (name.equals("offset")) {
+            offset_field_set = true;
             if (value.getAsInteger(0, reg_offset))
               reg_offset = UINT32_MAX;
           } else if (name.equals("encoding")) {
@@ -561,12 +563,17 @@
           }
         }
 
-        reg_info.byte_offset = reg_offset;
         assert(reg_info.byte_size != 0);
-        reg_offset += reg_info.byte_size;
         if (!value_regs.empty()) {
           value_regs.push_back(LLDB_INVALID_REGNUM);
           reg_info.value_regs = value_regs.data();
+          if (offset_field_set)
+            reg_info.byte_offset = reg_offset;
+          else
+            reg_info.byte_offset = LLDB_INVALID_INDEX32;
+        } else {
+          reg_info.byte_offset = reg_offset;
+          reg_offset += reg_info.byte_size;
         }
         if (!invalidate_regs.empty()) {
           invalidate_regs.push_back(LLDB_INVALID_REGNUM);
@@ -4293,6 +4300,7 @@
         std::vector<uint8_t> dwarf_opcode_bytes;
         bool encoding_set = false;
         bool format_set = false;
+        bool offset_field_set = false;
         RegisterInfo reg_info = {
             nullptr,       // Name
             nullptr,       // Alt name
@@ -4316,7 +4324,8 @@
         reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type,
                                    &reg_name, &alt_name, &set_name, &value_regs,
                                    &invalidate_regs, &encoding_set, &format_set,
-                                   &reg_info, &reg_offset, &dwarf_opcode_bytes](
+                                   &reg_info, &reg_offset, &offset_field_set,
+                                   &dwarf_opcode_bytes](
                                       const llvm::StringRef &name,
                                       const llvm::StringRef &value) -> bool {
           if (name == "name") {
@@ -4335,6 +4344,7 @@
               reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
             }
           } else if (name == "offset") {
+            offset_field_set = true;
             reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
           } else if (name == "altname") {
             alt_name.SetString(value);
@@ -4430,12 +4440,17 @@
           }
         }
 
-        reg_info.byte_offset = reg_offset;
         assert(reg_info.byte_size != 0);
-        reg_offset += reg_info.byte_size;
         if (!value_regs.empty()) {
           value_regs.push_back(LLDB_INVALID_REGNUM);
           reg_info.value_regs = value_regs.data();
+          if (offset_field_set)
+            reg_info.byte_offset = reg_offset;
+          else
+            reg_info.byte_offset = LLDB_INVALID_INDEX32;
+        } else {
+          reg_info.byte_offset = reg_offset;
+          reg_offset += reg_info.byte_size;
         }
         if (!invalidate_regs.empty()) {
           invalidate_regs.push_back(LLDB_INVALID_REGNUM);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1825,8 +1825,10 @@
     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())
@@ -2887,10 +2889,11 @@
       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);
Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -466,9 +466,15 @@
   // 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)
+        m_regs[i].byte_offset =
+            GetRegisterInfoAtIndex(m_regs[i].value_regs[0])->byte_offset;
+    } else
       m_regs[i].value_regs = nullptr;
   }
 
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -44,6 +44,8 @@
 
   void InvalidateAllRegisters() override;
 
+  bool RegisterOffsetIsDynamic() const override { return true; }
+
   // Hardware breakpoints/watchpoint management functions
 
   uint32_t NumSupportedHardwareBreakpoints() override;
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
@@ -664,7 +664,10 @@
         # 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)
 
Index: lldb/include/lldb/Host/common/NativeRegisterContext.h
===================================================================
--- lldb/include/lldb/Host/common/NativeRegisterContext.h
+++ lldb/include/lldb/Host/common/NativeRegisterContext.h
@@ -116,6 +116,8 @@
 
   virtual NativeThreadProtocol &GetThread() { return m_thread; }
 
+  virtual bool RegisterOffsetIsDynamic() const { return false; }
+
   const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name,
                                             uint32_t start_idx = 0);
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to