omjavaid created this revision.
omjavaid added reviewers: labath, jankratochvil.
Herald added subscribers: danielkiss, kristof.beyls.
Herald added a reviewer: rengolin.

Native register descriptions in LLDB specify lldb register numbers in 
value_regs and invalidate_regs lists. These register numbers may not match with 
Process gdb-remote register numbers which are generated through native process 
by counting all registers in its register sets.

It was coincidentally not causing any problems as we never came across a native 
target with dynamically changing register sets and register numbers generated 
by counter matched with LLDB native register numbers. This came up while 
testing target AArch64 SVE which can choose register sets based on underlying 
hardware.

This patch fixes this behavior and tries to send lldb register number as extra 
information in registerinfo and targetxml packets. This patch also updates 
Read/Write RegisterBytes function of process gdb-remote to look for LLDB 
register numbers if they are available.

I have tested this on arm, aarch64, x86_64.


https://reviews.llvm.org/D77043

Files:
  lldb/docs/lldb-gdb-remote.txt
  lldb/include/lldb/Host/common/NativeRegisterContext.h
  lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
  lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
  lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

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
@@ -553,6 +553,10 @@
           } else if (name.equals("generic")) {
             reg_info.kinds[eRegisterKindGeneric] =
                 Args::StringToGenericRegister(value);
+          } else if (name.equals("regnum")) {
+            if (value.getAsInteger(0,
+                                   reg_info.kinds[eRegisterKindProcessPlugin]))
+              reg_info.kinds[eRegisterKindProcessPlugin] = reg_num;
           } else if (name.equals("container-regs")) {
             SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
           } else if (name.equals("invalidate-regs")) {
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -242,11 +242,15 @@
       // Index of the primordial register.
       bool success = true;
       for (uint32_t idx = 0; success; ++idx) {
-        const uint32_t prim_reg = reg_info->value_regs[idx];
+        uint32_t prim_reg = reg_info->value_regs[idx];
         if (prim_reg == LLDB_INVALID_REGNUM)
           break;
         // We have a valid primordial register as our constituent. Grab the
         // corresponding register info.
+        uint32_t regnum = ConvertRegisterKindToRegisterNumber(
+            eRegisterKindProcessPlugin, prim_reg);
+        if (regnum != LLDB_INVALID_REGNUM)
+          prim_reg = regnum;
         const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
         if (prim_reg_info == nullptr)
           success = false;
@@ -375,11 +379,15 @@
           // Invalidate this composite register first.
 
           for (uint32_t idx = 0; success; ++idx) {
-            const uint32_t reg = reg_info->value_regs[idx];
+            uint32_t reg = reg_info->value_regs[idx];
             if (reg == LLDB_INVALID_REGNUM)
               break;
             // We have a valid primordial register as our constituent. Grab the
             // corresponding register info.
+            uint32_t lldb_regnum = ConvertRegisterKindToRegisterNumber(
+                eRegisterKindProcessPlugin, reg);
+            if (lldb_regnum != LLDB_INVALID_REGNUM)
+              reg = lldb_regnum;
             const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
             if (value_reg_info == nullptr)
               success = false;
@@ -397,6 +405,10 @@
           for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
                reg != LLDB_INVALID_REGNUM;
                reg = reg_info->invalidate_regs[++idx]) {
+            uint32_t lldb_regnum = ConvertRegisterKindToRegisterNumber(
+                eRegisterKindProcessPlugin, reg);
+            if (lldb_regnum != LLDB_INVALID_REGNUM)
+              reg = lldb_regnum;
             SetRegisterIsValid(reg, false);
           }
         }
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
@@ -1772,7 +1772,9 @@
   if (reg_index >= reg_context.GetUserRegisterCount())
     return SendErrorResponse(69);
 
-  const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
+  uint32_t native_reg_index = reg_context.GetNativeRegisterIndex(reg_index);
+  const RegisterInfo *reg_info =
+      reg_context.GetRegisterInfoAtIndex(native_reg_index);
   if (!reg_info)
     return SendErrorResponse(69);
 
@@ -1801,7 +1803,7 @@
     response << "format:" << format << ';';
 
   const char *const register_set_name =
-      reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
+      reg_context.GetRegisterSetNameForRegisterAtIndex(native_reg_index);
   if (register_set_name)
     response << "set:" << register_set_name << ';';
 
@@ -1818,6 +1820,10 @@
   if (!kind_generic.empty())
     response << "generic:" << kind_generic << ';';
 
+  if (reg_info->kinds[RegisterKind::eRegisterKindLLDB] != LLDB_INVALID_REGNUM)
+    response.Printf("regnum:%" PRIu32 ";",
+                    reg_info->kinds[RegisterKind::eRegisterKindLLDB]);
+
   if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
     response.PutCString("container-regs:");
     CollectRegNums(reg_info->value_regs, response, true);
@@ -1903,7 +1909,9 @@
   std::vector<uint8_t> regs_buffer;
   for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount();
        ++reg_num) {
-    const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num);
+    uint32_t native_reg_num = reg_ctx.GetNativeRegisterIndex(reg_num);
+    const RegisterInfo *reg_info =
+        reg_ctx.GetRegisterInfoAtIndex(native_reg_num);
 
     if (reg_info == nullptr) {
       LLDB_LOG(log, "failed to get register info for register index {0}",
@@ -1966,11 +1974,11 @@
 
   // Return the end of registers response if we've iterated one past the end of
   // the register set.
-  if (reg_index >= reg_context.GetUserRegisterCount()) {
+  if (reg_index >= reg_context.GetRegisterCount()) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s failed, requested "
               "register %" PRIu32 " beyond register count %" PRIu32,
-              __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
+              __FUNCTION__, reg_index, reg_context.GetRegisterCount());
     return SendErrorResponse(0x15);
   }
 
@@ -2066,11 +2074,11 @@
 
   // Return the end of registers response if we've iterated one past the end of
   // the register set.
-  if (reg_index >= reg_context.GetUserRegisterCount()) {
+  if (reg_index >= reg_context.GetRegisterCount()) {
     LLDB_LOGF(log,
               "GDBRemoteCommunicationServerLLGS::%s failed, requested "
               "register %" PRIu32 " beyond register count %" PRIu32,
-              __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
+              __FUNCTION__, reg_index, reg_context.GetRegisterCount());
     return SendErrorResponse(0x47);
   }
 
@@ -2763,8 +2771,9 @@
 
   const int registers_count = reg_context.GetUserRegisterCount();
   for (int reg_index = 0; reg_index < registers_count; reg_index++) {
+    uint32_t native_reg_index = reg_context.GetNativeRegisterIndex(reg_index);
     const RegisterInfo *reg_info =
-        reg_context.GetRegisterInfoAtIndex(reg_index);
+        reg_context.GetRegisterInfoAtIndex(native_reg_index);
 
     if (!reg_info) {
       LLDB_LOGF(log,
@@ -2773,10 +2782,14 @@
       continue;
     }
 
+    uint32_t regnum = native_reg_index;
+    if (reg_info->kinds[RegisterKind::eRegisterKindLLDB] != LLDB_INVALID_REGNUM)
+      regnum = reg_info->kinds[RegisterKind::eRegisterKindLLDB];
+
     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);
+                    reg_info->byte_offset, regnum);
 
     if (reg_info->alt_name && reg_info->alt_name[0])
       response.Printf("altname=\"%s\" ", reg_info->alt_name);
@@ -2790,7 +2803,7 @@
       response << "format=\"" << format << "\" ";
 
     const char *const register_set_name =
-        reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
+        reg_context.GetRegisterSetNameForRegisterAtIndex(native_reg_index);
     if (register_set_name)
       response << "group=\"" << register_set_name << "\" ";
 
Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
===================================================================
--- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
+++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
@@ -29,6 +29,8 @@
 
   uint32_t GetUserRegisterCount() const override;
 
+  uint32_t GetNativeRegisterIndex(uint32_t reg_index) const override;
+
   const RegisterInfo *GetRegisterInfoAtIndex(uint32_t reg_index) const override;
 
   const RegisterInfoInterface &GetRegisterInfoInterface() const;
Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
+++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
@@ -28,6 +28,11 @@
   return m_register_info_interface_up->GetUserRegisterCount();
 }
 
+uint32_t NativeRegisterContextRegisterInfo::GetNativeRegisterIndex(
+    uint32_t reg_index) const {
+  return reg_index;
+}
+
 const RegisterInfo *NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex(
     uint32_t reg_index) const {
   if (reg_index <= GetRegisterCount())
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
@@ -752,6 +752,7 @@
         "ehframe",
         "dwarf",
         "generic",
+        "regnum",
         "container-regs",
         "invalidate-regs",
         "dynamic_size_dwarf_expr_bytes",
Index: lldb/include/lldb/Host/common/NativeRegisterContext.h
===================================================================
--- lldb/include/lldb/Host/common/NativeRegisterContext.h
+++ lldb/include/lldb/Host/common/NativeRegisterContext.h
@@ -35,6 +35,8 @@
 
   virtual uint32_t GetUserRegisterCount() const = 0;
 
+  virtual uint32_t GetNativeRegisterIndex(uint32_t reg_index) const = 0;
+
   virtual const RegisterInfo *GetRegisterInfoAtIndex(uint32_t reg) const = 0;
 
   const char *GetRegisterSetNameForRegisterAtIndex(uint32_t reg_index) const;
Index: lldb/docs/lldb-gdb-remote.txt
===================================================================
--- lldb/docs/lldb-gdb-remote.txt
+++ lldb/docs/lldb-gdb-remote.txt
@@ -597,6 +597,8 @@
                 vector-float32
                 vector-uint128
 
+regnum      Optional register number assigned by native process or remote stub.
+
 set         The register set name as a string that this register belongs to.
 
 gcc         The GCC compiler registers number for this register (used for
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to