[Lldb-commits] [lldb] 583f67c - [lldb] [ABI/AArch64] Add pseudo-regs if missing

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 11 08:03:29 PDT 2021


Author: Michał Górny
Date: 2021-10-11T17:02:27+02:00
New Revision: 583f67cb4eef6171326d72da8bbb3001c846bbfb

URL: https://github.com/llvm/llvm-project/commit/583f67cb4eef6171326d72da8bbb3001c846bbfb
DIFF: https://github.com/llvm/llvm-project/commit/583f67cb4eef6171326d72da8bbb3001c846bbfb.diff

LOG: [lldb] [ABI/AArch64] Add pseudo-regs if missing

Create pseudo-registers on the AArch64 target if they are not provided
by the remote server. This is the case for gdbserver. The created
registers are:

- 32-bit wN partials for 64-bit xN registers
- double precision floating-point dN registers (overlapping with vN)
- single precision floating-point sN registers (overlapping with vN)

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

Added: 
    

Modified: 
    lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
    lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
index f3165999f7e5f..da5de9bfa736d 100644
--- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
@@ -13,6 +13,8 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Target/Process.h"
 
+#include <bitset>
+
 LLDB_PLUGIN_DEFINE(ABIAArch64)
 
 void ABIAArch64::Initialize() {
@@ -71,14 +73,81 @@ uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) {
       .Default(LLDB_INVALID_REGNUM);
 }
 
+static void addPartialRegisters(
+    std::vector<lldb_private::DynamicRegisterInfo::Register> &regs,
+    llvm::ArrayRef<llvm::Optional<uint32_t>> full_reg_indices,
+    uint32_t full_reg_size, const char *partial_reg_format,
+    uint32_t partial_reg_size, lldb::Encoding encoding, lldb::Format format) {
+  for (auto it : llvm::enumerate(full_reg_indices)) {
+    llvm::Optional<uint32_t> full_reg_index = it.value();
+    if (!full_reg_index ||
+        regs[full_reg_index.getValue()].byte_size != full_reg_size)
+      return;
+
+    lldb_private::DynamicRegisterInfo::Register partial_reg{
+        lldb_private::ConstString(
+            llvm::formatv(partial_reg_format, it.index()).str()),
+        lldb_private::ConstString(),
+        lldb_private::ConstString("supplementary registers"),
+        partial_reg_size,
+        LLDB_INVALID_INDEX32,
+        encoding,
+        format,
+        LLDB_INVALID_REGNUM,
+        LLDB_INVALID_REGNUM,
+        LLDB_INVALID_REGNUM,
+        LLDB_INVALID_REGNUM,
+        {full_reg_index.getValue()},
+        {}};
+    addSupplementaryRegister(regs, partial_reg);
+  }
+}
+
 void ABIAArch64::AugmentRegisterInfo(
     std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) {
   lldb_private::MCBasedABI::AugmentRegisterInfo(regs);
 
   lldb_private::ConstString sp_string{"sp"};
-  for (lldb_private::DynamicRegisterInfo::Register &info : regs) {
+
+  std::array<llvm::Optional<uint32_t>, 32> x_regs;
+  std::array<llvm::Optional<uint32_t>, 32> v_regs;
+  std::bitset<32> have_w_regs;
+  std::bitset<32> have_s_regs;
+  std::bitset<32> have_d_regs;
+
+  for (auto it : llvm::enumerate(regs)) {
+    lldb_private::DynamicRegisterInfo::Register &info = it.value();
     // GDB sends x31 as "sp".  Add the "x31" alt_name for convenience.
     if (info.name == sp_string && !info.alt_name)
       info.alt_name.SetCString("x31");
+
+    unsigned int reg_num;
+    auto get_reg = [&info, &reg_num](const char *prefix) {
+      llvm::StringRef reg_name = info.name.GetStringRef();
+      llvm::StringRef alt_name = info.alt_name.GetStringRef();
+      return (reg_name.consume_front(prefix) &&
+              llvm::to_integer(reg_name, reg_num, 10) && reg_num < 32) ||
+             (alt_name.consume_front(prefix) &&
+              llvm::to_integer(alt_name, reg_num, 10) && reg_num < 32);
+    };
+
+    if (get_reg("x"))
+      x_regs[reg_num] = it.index();
+    if (get_reg("v"))
+      v_regs[reg_num] = it.index();
+    if (get_reg("w"))
+      have_w_regs[reg_num] = true;
+    if (get_reg("s"))
+      have_s_regs[reg_num] = true;
+    if (get_reg("d"))
+      have_d_regs[reg_num] = true;
   }
+
+  // Create aliases for partial registers: wN for xN, and sN/dN for vN.
+  addPartialRegisters(regs, x_regs, 8, "w{0}", 4, lldb::eEncodingUint,
+                      lldb::eFormatHex);
+  addPartialRegisters(regs, v_regs, 16, "s{0}", 4, lldb::eEncodingIEEE754,
+                      lldb::eFormatFloat);
+  addPartialRegisters(regs, v_regs, 16, "d{0}", 8, lldb::eEncodingIEEE754,
+                      lldb::eFormatFloat);
 }

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
index 225b16d8946e1..1a83b673cac0f 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
@@ -270,27 +270,27 @@ def haltReason(self):
     @skipIfLLVMTargetMissing("AArch64")
     def test_aarch64_regs(self):
         """Test grabbing various aarch64 registers from gdbserver."""
-        reg_data = [
-            "0102030405060708",  # x0
-            "1112131415161718",  # x1
-        ] + 27 * [
-            "2122232425262728",  # x2..x28
-        ] + [
-            "3132333435363738",  # x29 (fp)
-            "4142434445464748",  # x30 (lr)
-            "5152535455565758",  # x31 (sp)
-            "6162636465666768",  # pc
-            "71727374",  # cpsr
-            "8182838485868788898a8b8c8d8e8f90",  # v0
-            "9192939495969798999a9b9c9d9e9fa0",  # v1
-        ] + 30 * [
-            "a1a2a3a4a5a6a7a8a9aaabacadaeafb0",  # v2..v31
-        ] + [
-            "00000000",  # fpsr
-            "00000000",  # fpcr
-        ]
-
         class MyResponder(MockGDBServerResponder):
+            reg_data = (
+                "0102030405060708"  # x0
+                "1112131415161718"  # x1
+            ) + 27 * (
+                "2122232425262728"  # x2..x28
+            ) + (
+                "3132333435363738"  # x29 (fp)
+                "4142434445464748"  # x30 (lr)
+                "5152535455565758"  # x31 (sp)
+                "6162636465666768"  # pc
+                "71727374"  # cpsr
+                "8182838485868788898a8b8c8d8e8f90"  # v0
+                "9192939495969798999a9b9c9d9e9fa0"  # v1
+            ) + 30 * (
+                "a1a2a3a4a5a6a7a8a9aaabacadaeafb0"  # v2..v31
+            ) + (
+                "00000000"  # fpsr
+                "00000000"  # fpcr
+            )
+
             def qXferRead(self, obj, annex, offset, length):
                 if annex == "target.xml":
                     return """<?xml version="1.0"?>
@@ -377,9 +377,10 @@ def readRegister(self, regnum):
                 return ""
 
             def readRegisters(self):
-                return "".join(reg_data)
+                return self.reg_data
 
             def writeRegisters(self, reg_hex):
+                self.reg_data = reg_hex
                 return "OK"
 
             def haltReason(self):
@@ -429,3 +430,43 @@ def haltReason(self):
                    ["v0 = {0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"])
         self.match("register read v31",
                    ["v31 = {0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0}"])
+
+        # test partial registers
+        self.match("register read w0",
+                   ["w0 = 0x04030201"])
+        self.runCmd("register write w0 0xfffefdfc")
+        self.match("register read x0",
+                   ["x0 = 0x08070605fffefdfc"])
+
+        self.match("register read w1",
+                   ["w1 = 0x14131211"])
+        self.runCmd("register write w1 0xefeeedec")
+        self.match("register read x1",
+                   ["x1 = 0x18171615efeeedec"])
+
+        self.match("register read w30",
+                   ["w30 = 0x44434241"])
+        self.runCmd("register write w30 0xdfdedddc")
+        self.match("register read x30",
+                   ["x30 = 0x48474645dfdedddc"])
+
+        self.match("register read w31",
+                   ["w31 = 0x54535251"])
+        self.runCmd("register write w31 0xcfcecdcc")
+        self.match("register read x31",
+                   ["sp = 0x58575655cfcecdcc"])
+
+        # test FPU registers (overlapping with vector registers)
+        self.runCmd("register write d0 16")
+        self.match("register read v0",
+                   ["v0 = {0x00 0x00 0x00 0x00 0x00 0x00 0x30 0x40 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"])
+        self.runCmd("register write v31 '{0x00 0x00 0x00 0x00 0x00 0x00 0x50 0x40 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff}'")
+        self.match("register read d31",
+                   ["d31 = 64"])
+
+        self.runCmd("register write s0 32")
+        self.match("register read v0",
+                   ["v0 = {0x00 0x00 0x00 0x42 0x00 0x00 0x30 0x40 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"])
+        self.runCmd("register write v31 '{0x00 0x00 0x00 0x43 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff}'")
+        self.match("register read s31",
+                   ["s31 = 128"])


        


More information about the lldb-commits mailing list