[Lldb-commits] [lldb] e69a3d1 - [lldb] [gdb-remote] Support client fallback for servers without reg defs

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Mon Jan 17 13:31:54 PST 2022


Author: Michał Górny
Date: 2022-01-17T22:31:49+01:00
New Revision: e69a3d18f48bc0d81b5dd12e735a2ec898ce64d4

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

LOG: [lldb] [gdb-remote] Support client fallback for servers without reg defs

Provide minimal register definition defaults for working with servers
that implement neither target.xml nor qRegisterInfo packets.  This is
useful e.g. when interacting with FreeBSD's kernel minimal gdbserver
that does not send target.xml but uses the same layout for its supported
register subset as GDB.

The prerequisite for this is the ability to determine the correct
architecture, e.g. from the target executable.

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

Added: 
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h
    lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py

Modified: 
    lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
    lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt b/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
index d578033e1c414..3a1a0e435ad25 100644
--- a/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -25,6 +25,7 @@ add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
   GDBRemoteCommunicationServerLLGS.cpp
   GDBRemoteCommunicationServerPlatform.cpp
   GDBRemoteRegisterContext.cpp
+  GDBRemoteRegisterFallback.cpp
   ProcessGDBRemote.cpp
   ProcessGDBRemoteLog.cpp
   ThreadGDBRemote.cpp

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
new file mode 100644
index 0000000000000..b391edced695f
--- /dev/null
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp
@@ -0,0 +1,86 @@
+//===-- GDBRemoteRegisterFallback.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GDBRemoteRegisterFallback.h"
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+#define REG(name, size)                                                        \
+  DynamicRegisterInfo::Register {                                              \
+    ConstString(#name), empty_alt_name, reg_set, size, LLDB_INVALID_INDEX32,   \
+        lldb::eEncodingUint, lldb::eFormatHex, LLDB_INVALID_REGNUM,            \
+        LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, {}, {}  \
+  }
+#define R64(name) REG(name, 8)
+#define R32(name) REG(name, 4)
+
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() {
+  ConstString empty_alt_name;
+  ConstString reg_set{"general purpose registers"};
+
+  std::vector<DynamicRegisterInfo::Register> registers{
+      R64(x0),  R64(x1),  R64(x2),  R64(x3),  R64(x4),  R64(x5),   R64(x6),
+      R64(x7),  R64(x8),  R64(x9),  R64(x10), R64(x11), R64(x12),  R64(x13),
+      R64(x14), R64(x15), R64(x16), R64(x17), R64(x18), R64(x19),  R64(x20),
+      R64(x21), R64(x22), R64(x23), R64(x24), R64(x25), R64(x26),  R64(x27),
+      R64(x28), R64(x29), R64(x30), R64(sp),  R64(pc),  R32(cpsr),
+  };
+
+  return registers;
+}
+
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86() {
+  ConstString empty_alt_name;
+  ConstString reg_set{"general purpose registers"};
+
+  std::vector<DynamicRegisterInfo::Register> registers{
+      R32(eax), R32(ecx), R32(edx), R32(ebx),    R32(esp), R32(ebp),
+      R32(esi), R32(edi), R32(eip), R32(eflags), R32(cs),  R32(ss),
+      R32(ds),  R32(es),  R32(fs),  R32(gs),
+  };
+
+  return registers;
+}
+
+static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86_64() {
+  ConstString empty_alt_name;
+  ConstString reg_set{"general purpose registers"};
+
+  std::vector<DynamicRegisterInfo::Register> registers{
+      R64(rax), R64(rbx), R64(rcx), R64(rdx), R64(rsi), R64(rdi),
+      R64(rbp), R64(rsp), R64(r8),  R64(r9),  R64(r10), R64(r11),
+      R64(r12), R64(r13), R64(r14), R64(r15), R64(rip), R32(eflags),
+      R32(cs),  R32(ss),  R32(ds),  R32(es),  R32(fs),  R32(gs),
+  };
+
+  return registers;
+}
+
+#undef R32
+#undef R64
+#undef REG
+
+std::vector<DynamicRegisterInfo::Register>
+GetFallbackRegisters(const ArchSpec &arch_to_use) {
+  switch (arch_to_use.GetMachine()) {
+  case llvm::Triple::aarch64:
+    return GetRegisters_aarch64();
+  case llvm::Triple::x86:
+    return GetRegisters_x86();
+  case llvm::Triple::x86_64:
+    return GetRegisters_x86_64();
+  default:
+    break;
+  }
+
+  return {};
+}
+
+} // namespace process_gdb_remote
+} // namespace lldb_private

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h
new file mode 100644
index 0000000000000..82e03c6b9b1cc
--- /dev/null
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.h
@@ -0,0 +1,26 @@
+//===-- GDBRemoteRegisterFallback.h -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
+
+#include <vector>
+
+#include "lldb/Target/DynamicRegisterInfo.h"
+#include "lldb/Utility/ArchSpec.h"
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+std::vector<DynamicRegisterInfo::Register>
+GetFallbackRegisters(const ArchSpec &arch_to_use);
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index dfc1c4a200689..1946520d5d6cb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -72,6 +72,7 @@
 #include <thread>
 
 #include "GDBRemoteRegisterContext.h"
+#include "GDBRemoteRegisterFallback.h"
 #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
@@ -394,6 +395,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
   //     2 - If the target definition doesn't have any of the info from the
   //     target.xml (registers) then proceed to read the target.xml.
   //     3 - Fall back on the qRegisterInfo packets.
+  //     4 - Use hardcoded defaults if available.
 
   FileSpec target_definition_fspec =
       GetGlobalPluginProperties().GetTargetDefinitionFile();
@@ -507,6 +509,9 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
     }
   }
 
+  if (registers.empty())
+    registers = GetFallbackRegisters(arch_to_use);
+
   AddRemoteRegisters(registers, arch_to_use);
 }
 

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py
new file mode 100644
index 0000000000000..3fa750c6f6c1e
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerNoTargetXML.py
@@ -0,0 +1,346 @@
+from __future__ import print_function
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.gdbclientutils import *
+from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
+
+import binascii
+
+
+class TestGDBServerTargetXML(GDBRemoteTestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @staticmethod
+    def filecheck_to_blob(fc):
+        for l in fc.strip().splitlines():
+            val = l.split('0x')[1]
+            yield binascii.b2a_hex(bytes(reversed(binascii.a2b_hex(val)))).decode()
+
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("X86")
+    def test_x86_64_regs(self):
+        """Test grabbing various x86_64 registers from gdbserver."""
+
+        GPRS = '''
+CHECK-AMD64-DAG: rax = 0x0807060504030201
+CHECK-AMD64-DAG: rbx = 0x1817161514131211
+CHECK-AMD64-DAG: rcx = 0x2827262524232221
+CHECK-AMD64-DAG: rdx = 0x3837363534333231
+CHECK-AMD64-DAG: rsi = 0x4847464544434241
+CHECK-AMD64-DAG: rdi = 0x5857565554535251
+CHECK-AMD64-DAG: rbp = 0x6867666564636261
+CHECK-AMD64-DAG: rsp = 0x7877767574737271
+CHECK-AMD64-DAG: r8 = 0x8887868584838281
+CHECK-AMD64-DAG: r9 = 0x9897969594939291
+CHECK-AMD64-DAG: r10 = 0xa8a7a6a5a4a3a2a1
+CHECK-AMD64-DAG: r11 = 0xb8b7b6b5b4b3b2b1
+CHECK-AMD64-DAG: r12 = 0xc8c7c6c5c4c3c2c1
+CHECK-AMD64-DAG: r13 = 0xd8d7d6d5d4d3d2d1
+CHECK-AMD64-DAG: r14 = 0xe8e7e6e5e4e3e2e1
+CHECK-AMD64-DAG: r15 = 0xf8f7f6f5f4f3f2f1
+CHECK-AMD64-DAG: rip = 0x100f0e0d0c0b0a09
+CHECK-AMD64-DAG: eflags = 0x1c1b1a19
+CHECK-AMD64-DAG: cs = 0x2c2b2a29
+CHECK-AMD64-DAG: ss = 0x3c3b3a39
+'''
+
+        SUPPL = '''
+CHECK-AMD64-DAG: eax = 0x04030201
+CHECK-AMD64-DAG: ebx = 0x14131211
+CHECK-AMD64-DAG: ecx = 0x24232221
+CHECK-AMD64-DAG: edx = 0x34333231
+CHECK-AMD64-DAG: esi = 0x44434241
+CHECK-AMD64-DAG: edi = 0x54535251
+CHECK-AMD64-DAG: ebp = 0x64636261
+CHECK-AMD64-DAG: esp = 0x74737271
+CHECK-AMD64-DAG: r8d = 0x84838281
+CHECK-AMD64-DAG: r9d = 0x94939291
+CHECK-AMD64-DAG: r10d = 0xa4a3a2a1
+CHECK-AMD64-DAG: r11d = 0xb4b3b2b1
+CHECK-AMD64-DAG: r12d = 0xc4c3c2c1
+CHECK-AMD64-DAG: r13d = 0xd4d3d2d1
+CHECK-AMD64-DAG: r14d = 0xe4e3e2e1
+CHECK-AMD64-DAG: r15d = 0xf4f3f2f1
+
+CHECK-AMD64-DAG: ax = 0x0201
+CHECK-AMD64-DAG: bx = 0x1211
+CHECK-AMD64-DAG: cx = 0x2221
+CHECK-AMD64-DAG: dx = 0x3231
+CHECK-AMD64-DAG: si = 0x4241
+CHECK-AMD64-DAG: di = 0x5251
+CHECK-AMD64-DAG: bp = 0x6261
+CHECK-AMD64-DAG: sp = 0x7271
+CHECK-AMD64-DAG: r8w = 0x8281
+CHECK-AMD64-DAG: r9w = 0x9291
+CHECK-AMD64-DAG: r10w = 0xa2a1
+CHECK-AMD64-DAG: r11w = 0xb2b1
+CHECK-AMD64-DAG: r12w = 0xc2c1
+CHECK-AMD64-DAG: r13w = 0xd2d1
+CHECK-AMD64-DAG: r14w = 0xe2e1
+CHECK-AMD64-DAG: r15w = 0xf2f1
+
+CHECK-AMD64-DAG: ah = 0x02
+CHECK-AMD64-DAG: bh = 0x12
+CHECK-AMD64-DAG: ch = 0x22
+CHECK-AMD64-DAG: dh = 0x32
+
+CHECK-AMD64-DAG: al = 0x01
+CHECK-AMD64-DAG: bl = 0x11
+CHECK-AMD64-DAG: cl = 0x21
+CHECK-AMD64-DAG: dl = 0x31
+CHECK-AMD64-DAG: sil = 0x41
+CHECK-AMD64-DAG: dil = 0x51
+CHECK-AMD64-DAG: bpl = 0x61
+CHECK-AMD64-DAG: spl = 0x71
+CHECK-AMD64-DAG: r8l = 0x81
+CHECK-AMD64-DAG: r9l = 0x91
+CHECK-AMD64-DAG: r10l = 0xa1
+CHECK-AMD64-DAG: r11l = 0xb1
+CHECK-AMD64-DAG: r12l = 0xc1
+CHECK-AMD64-DAG: r13l = 0xd1
+CHECK-AMD64-DAG: r14l = 0xe1
+CHECK-AMD64-DAG: r15l = 0xf1
+'''
+
+        class MyResponder(MockGDBServerResponder):
+            reg_data = ''.join(self.filecheck_to_blob(GPRS))
+
+            def readRegister(self, regnum):
+                return ""
+
+            def readRegisters(self):
+                return self.reg_data
+
+            def haltReason(self):
+                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;"
+
+        self.server.responder = MyResponder()
+
+        target = self.createTarget("basic_eh_frame.yaml")
+        process = self.connect(target)
+        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process,
+                                      [lldb.eStateStopped])
+
+        # test all registers
+        self.filecheck("register read --all", __file__,
+                       filecheck_options='--check-prefix=CHECK-AMD64')
+
+        # test generic aliases
+        self.match("register read arg4",
+                   ["rcx = 0x2827262524232221"])
+        self.match("register read arg3",
+                   ["rdx = 0x3837363534333231"])
+        self.match("register read arg2",
+                   ["rsi = 0x4847464544434241"])
+        self.match("register read arg1",
+                   ["rdi = 0x5857565554535251"])
+        self.match("register read fp",
+                   ["rbp = 0x6867666564636261"])
+        self.match("register read sp",
+                   ["rsp = 0x7877767574737271"])
+        self.match("register read arg5",
+                   ["r8 = 0x8887868584838281"])
+        self.match("register read arg6",
+                   ["r9 = 0x9897969594939291"])
+        self.match("register read pc",
+                   ["rip = 0x100f0e0d0c0b0a09"])
+        self.match("register read flags",
+                   ["eflags = 0x1c1b1a19"])
+
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64_regs(self):
+        """Test grabbing various aarch64 registers from gdbserver."""
+
+        GPRS = '''
+CHECK-AARCH64-DAG: x0 = 0x0001020304050607
+CHECK-AARCH64-DAG: x1 = 0x0102030405060708
+CHECK-AARCH64-DAG: x2 = 0x0203040506070809
+CHECK-AARCH64-DAG: x3 = 0x030405060708090a
+CHECK-AARCH64-DAG: x4 = 0x0405060708090a0b
+CHECK-AARCH64-DAG: x5 = 0x05060708090a0b0c
+CHECK-AARCH64-DAG: x6 = 0x060708090a0b0c0d
+CHECK-AARCH64-DAG: x7 = 0x0708090a0b0c0d0e
+CHECK-AARCH64-DAG: x8 = 0x08090a0b0c0d0e0f
+CHECK-AARCH64-DAG: x9 = 0x090a0b0c0d0e0f10
+CHECK-AARCH64-DAG: x10 = 0x0a0b0c0d0e0f1011
+CHECK-AARCH64-DAG: x11 = 0x0b0c0d0e0f101112
+CHECK-AARCH64-DAG: x12 = 0x0c0d0e0f10111213
+CHECK-AARCH64-DAG: x13 = 0x0d0e0f1011121314
+CHECK-AARCH64-DAG: x14 = 0x0e0f101112131415
+CHECK-AARCH64-DAG: x15 = 0x0f10111213141516
+CHECK-AARCH64-DAG: x16 = 0x1011121314151617
+CHECK-AARCH64-DAG: x17 = 0x1112131415161718
+CHECK-AARCH64-DAG: x18 = 0x1213141516171819
+CHECK-AARCH64-DAG: x19 = 0x131415161718191a
+CHECK-AARCH64-DAG: x20 = 0x1415161718191a1b
+CHECK-AARCH64-DAG: x21 = 0x15161718191a1b1c
+CHECK-AARCH64-DAG: x22 = 0x161718191a1b1c1d
+CHECK-AARCH64-DAG: x23 = 0x1718191a1b1c1d1e
+CHECK-AARCH64-DAG: x24 = 0x18191a1b1c1d1e1f
+CHECK-AARCH64-DAG: x25 = 0x191a1b1c1d1e1f20
+CHECK-AARCH64-DAG: x26 = 0x1a1b1c1d1e1f2021
+CHECK-AARCH64-DAG: x27 = 0x1b1c1d1e1f202122
+CHECK-AARCH64-DAG: x28 = 0x1c1d1e1f20212223
+CHECK-AARCH64-DAG: x29 = 0x1d1e1f2021222324
+CHECK-AARCH64-DAG: x30 = 0x1e1f202122232425
+CHECK-AARCH64-DAG: sp = 0x1f20212223242526
+CHECK-AARCH64-DAG: pc = 0x2021222324252627
+CHECK-AARCH64-DAG: cpsr = 0x21222324
+'''
+
+        SUPPL = '''
+CHECK-AARCH64-DAG: w0 = 0x04050607
+CHECK-AARCH64-DAG: w1 = 0x05060708
+CHECK-AARCH64-DAG: w2 = 0x06070809
+CHECK-AARCH64-DAG: w3 = 0x0708090a
+CHECK-AARCH64-DAG: w4 = 0x08090a0b
+CHECK-AARCH64-DAG: w5 = 0x090a0b0c
+CHECK-AARCH64-DAG: w6 = 0x0a0b0c0d
+CHECK-AARCH64-DAG: w7 = 0x0b0c0d0e
+CHECK-AARCH64-DAG: w8 = 0x0c0d0e0f
+CHECK-AARCH64-DAG: w9 = 0x0d0e0f10
+CHECK-AARCH64-DAG: w10 = 0x0e0f1011
+CHECK-AARCH64-DAG: w11 = 0x0f101112
+CHECK-AARCH64-DAG: w12 = 0x10111213
+CHECK-AARCH64-DAG: w13 = 0x11121314
+CHECK-AARCH64-DAG: w14 = 0x12131415
+CHECK-AARCH64-DAG: w15 = 0x13141516
+CHECK-AARCH64-DAG: w16 = 0x14151617
+CHECK-AARCH64-DAG: w17 = 0x15161718
+CHECK-AARCH64-DAG: w18 = 0x16171819
+CHECK-AARCH64-DAG: w19 = 0x1718191a
+CHECK-AARCH64-DAG: w20 = 0x18191a1b
+CHECK-AARCH64-DAG: w21 = 0x191a1b1c
+CHECK-AARCH64-DAG: w22 = 0x1a1b1c1d
+CHECK-AARCH64-DAG: w23 = 0x1b1c1d1e
+CHECK-AARCH64-DAG: w24 = 0x1c1d1e1f
+CHECK-AARCH64-DAG: w25 = 0x1d1e1f20
+CHECK-AARCH64-DAG: w26 = 0x1e1f2021
+CHECK-AARCH64-DAG: w27 = 0x1f202122
+CHECK-AARCH64-DAG: w28 = 0x20212223
+CHECK-AARCH64-DAG: w29 = 0x21222324
+CHECK-AARCH64-DAG: w30 = 0x22232425
+CHECK-AARCH64-DAG: w31 = 0x23242526
+'''
+
+        class MyResponder(MockGDBServerResponder):
+            reg_data = ''.join(self.filecheck_to_blob(GPRS))
+
+            def readRegister(self, regnum):
+                return ""
+
+            def readRegisters(self):
+                return self.reg_data
+
+            def haltReason(self):
+                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;"
+
+        self.server.responder = MyResponder()
+
+        target = self.createTarget("basic_eh_frame-aarch64.yaml")
+        process = self.connect(target)
+        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process,
+                                      [lldb.eStateStopped])
+
+        # test all registers
+        self.filecheck("register read --all", __file__,
+                       filecheck_options='--check-prefix=CHECK-AARCH64')
+
+        # test generic aliases
+        self.match("register read arg1",
+                   ["x0 = 0x0001020304050607"])
+        self.match("register read arg2",
+                   ["x1 = 0x0102030405060708"])
+        self.match("register read fp",
+                   ["x29 = 0x1d1e1f2021222324"])
+        self.match("register read lr",
+                   ["x30 = 0x1e1f202122232425"])
+        self.match("register read ra",
+                   ["x30 = 0x1e1f202122232425"])
+        self.match("register read flags",
+                   ["cpsr = 0x21222324"])
+
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("X86")
+    def test_i386_regs(self):
+        """Test grabbing various i386 registers from gdbserver."""
+
+        GPRS = '''
+CHECK-I386-DAG: eax = 0x04030201
+CHECK-I386-DAG: ecx = 0x14131211
+CHECK-I386-DAG: edx = 0x24232221
+CHECK-I386-DAG: ebx = 0x34333231
+CHECK-I386-DAG: esp = 0x44434241
+CHECK-I386-DAG: ebp = 0x54535251
+CHECK-I386-DAG: esi = 0x64636261
+CHECK-I386-DAG: edi = 0x74737271
+CHECK-I386-DAG: eip = 0x84838281
+CHECK-I386-DAG: eflags = 0x94939291
+CHECK-I386-DAG: cs = 0xa4a3a2a1
+CHECK-I386-DAG: ss = 0xb4b3b2b1
+CHECK-I386-DAG: ds = 0xc4c3c2c1
+CHECK-I386-DAG: es = 0xd4d3d2d1
+CHECK-I386-DAG: fs = 0xe4e3e2e1
+CHECK-I386-DAG: gs = 0xf4f3f2f1
+'''
+
+        SUPPL = '''
+CHECK-I386-DAG: ax = 0x0201
+CHECK-I386-DAG: cx = 0x1211
+CHECK-I386-DAG: dx = 0x2221
+CHECK-I386-DAG: bx = 0x3231
+CHECK-I386-DAG: sp = 0x4241
+CHECK-I386-DAG: bp = 0x5251
+CHECK-I386-DAG: si = 0x6261
+CHECK-I386-DAG: di = 0x7271
+
+CHECK-I386-DAG: ah = 0x02
+CHECK-I386-DAG: ch = 0x12
+CHECK-I386-DAG: dh = 0x22
+CHECK-I386-DAG: bh = 0x32
+
+CHECK-I386-DAG: al = 0x01
+CHECK-I386-DAG: cl = 0x11
+CHECK-I386-DAG: dl = 0x21
+CHECK-I386-DAG: bl = 0x31
+CHECK-I386-DAG: spl = 0x41
+CHECK-I386-DAG: bpl = 0x51
+CHECK-I386-DAG: sil = 0x61
+CHECK-I386-DAG: dil = 0x71
+'''
+
+        class MyResponder(MockGDBServerResponder):
+            reg_data = ''.join(self.filecheck_to_blob(GPRS))
+
+            def readRegister(self, regnum):
+                return ""
+
+            def readRegisters(self):
+                return self.reg_data
+
+            def haltReason(self):
+                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;"
+
+        self.server.responder = MyResponder()
+
+        target = self.createTarget("basic_eh_frame-i386.yaml")
+        process = self.connect(target)
+        lldbutil.expect_state_changes(self, self.dbg.GetListener(), process,
+                                      [lldb.eStateStopped])
+
+        # test all registers
+        self.filecheck("register read --all", __file__,
+                       filecheck_options='--check-prefix=CHECK-I386')
+
+        # test generic aliases
+        self.match("register read fp",
+                   ["ebp = 0x54535251"])
+        self.match("register read sp",
+                   ["esp = 0x44434241"])
+        self.match("register read pc",
+                   ["eip = 0x84838281"])
+        self.match("register read flags",
+                   ["eflags = 0x94939291"])


        


More information about the lldb-commits mailing list