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
347 lines
11 KiB
Python
347 lines
11 KiB
Python
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"])
|