1""" 2Check that lldb falls back to default register layouts when the remote provides 3no target XML or does not include registers in the target XML. 4 5GPRS are passed to the responder to create register data to send back to lldb. 6Registers in SUPPL are virtual registers based on those general ones. The tests 7pass __file__ to FileCheck so any prefixes in this Python file will be checked. 8""" 9 10import lldb 11from lldbsuite.test.lldbtest import * 12from lldbsuite.test.decorators import * 13from lldbsuite.test.gdbclientutils import * 14from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 15 16import binascii 17from textwrap import dedent 18 19 20class MyResponder(MockGDBServerResponder): 21 @staticmethod 22 def filecheck_to_blob(fc): 23 for l in fc.strip().splitlines(): 24 val = l.split("0x")[1] 25 yield binascii.b2a_hex(bytes(reversed(binascii.a2b_hex(val)))).decode() 26 27 def __init__(self, architecture, has_target_xml, reg_data, halt_reason): 28 super().__init__() 29 self.architecture = architecture 30 self.has_target_xml = has_target_xml 31 self.reg_data = "".join(self.filecheck_to_blob(reg_data)) 32 self.halt_reason = halt_reason 33 34 def readRegister(self, regnum): 35 return "" 36 37 def readRegisters(self): 38 return self.reg_data 39 40 def haltReason(self): 41 return self.halt_reason 42 43 def qXferRead(self, obj, annex, offset, length): 44 if self.has_target_xml and annex == "target.xml": 45 return ( 46 dedent( 47 f"""\ 48 <?xml version="1.0"?> 49 <target version="1.0"> 50 <architecture>{self.architecture}</architecture> 51 </target>""" 52 ), 53 False, 54 ) 55 56 return None, False 57 58 59class TestGDBServerTargetXML(GDBRemoteTestBase): 60 def check_x86_64_regs(self, has_target_xml): 61 GPRS = """ 62CHECK-AMD64-DAG: rax = 0x0807060504030201 63CHECK-AMD64-DAG: rbx = 0x1817161514131211 64CHECK-AMD64-DAG: rcx = 0x2827262524232221 65CHECK-AMD64-DAG: rdx = 0x3837363534333231 66CHECK-AMD64-DAG: rsi = 0x4847464544434241 67CHECK-AMD64-DAG: rdi = 0x5857565554535251 68CHECK-AMD64-DAG: rbp = 0x6867666564636261 69CHECK-AMD64-DAG: rsp = 0x7877767574737271 70CHECK-AMD64-DAG: r8 = 0x8887868584838281 71CHECK-AMD64-DAG: r9 = 0x9897969594939291 72CHECK-AMD64-DAG: r10 = 0xa8a7a6a5a4a3a2a1 73CHECK-AMD64-DAG: r11 = 0xb8b7b6b5b4b3b2b1 74CHECK-AMD64-DAG: r12 = 0xc8c7c6c5c4c3c2c1 75CHECK-AMD64-DAG: r13 = 0xd8d7d6d5d4d3d2d1 76CHECK-AMD64-DAG: r14 = 0xe8e7e6e5e4e3e2e1 77CHECK-AMD64-DAG: r15 = 0xf8f7f6f5f4f3f2f1 78CHECK-AMD64-DAG: rip = 0x100f0e0d0c0b0a09 79CHECK-AMD64-DAG: eflags = 0x1c1b1a19 80CHECK-AMD64-DAG: cs = 0x2c2b2a29 81CHECK-AMD64-DAG: ss = 0x3c3b3a39 82""" 83 84 SUPPL = """ 85CHECK-AMD64-DAG: eax = 0x04030201 86CHECK-AMD64-DAG: ebx = 0x14131211 87CHECK-AMD64-DAG: ecx = 0x24232221 88CHECK-AMD64-DAG: edx = 0x34333231 89CHECK-AMD64-DAG: esi = 0x44434241 90CHECK-AMD64-DAG: edi = 0x54535251 91CHECK-AMD64-DAG: ebp = 0x64636261 92CHECK-AMD64-DAG: esp = 0x74737271 93CHECK-AMD64-DAG: r8d = 0x84838281 94CHECK-AMD64-DAG: r9d = 0x94939291 95CHECK-AMD64-DAG: r10d = 0xa4a3a2a1 96CHECK-AMD64-DAG: r11d = 0xb4b3b2b1 97CHECK-AMD64-DAG: r12d = 0xc4c3c2c1 98CHECK-AMD64-DAG: r13d = 0xd4d3d2d1 99CHECK-AMD64-DAG: r14d = 0xe4e3e2e1 100CHECK-AMD64-DAG: r15d = 0xf4f3f2f1 101 102CHECK-AMD64-DAG: ax = 0x0201 103CHECK-AMD64-DAG: bx = 0x1211 104CHECK-AMD64-DAG: cx = 0x2221 105CHECK-AMD64-DAG: dx = 0x3231 106CHECK-AMD64-DAG: si = 0x4241 107CHECK-AMD64-DAG: di = 0x5251 108CHECK-AMD64-DAG: bp = 0x6261 109CHECK-AMD64-DAG: sp = 0x7271 110CHECK-AMD64-DAG: r8w = 0x8281 111CHECK-AMD64-DAG: r9w = 0x9291 112CHECK-AMD64-DAG: r10w = 0xa2a1 113CHECK-AMD64-DAG: r11w = 0xb2b1 114CHECK-AMD64-DAG: r12w = 0xc2c1 115CHECK-AMD64-DAG: r13w = 0xd2d1 116CHECK-AMD64-DAG: r14w = 0xe2e1 117CHECK-AMD64-DAG: r15w = 0xf2f1 118 119CHECK-AMD64-DAG: ah = 0x02 120CHECK-AMD64-DAG: bh = 0x12 121CHECK-AMD64-DAG: ch = 0x22 122CHECK-AMD64-DAG: dh = 0x32 123 124CHECK-AMD64-DAG: al = 0x01 125CHECK-AMD64-DAG: bl = 0x11 126CHECK-AMD64-DAG: cl = 0x21 127CHECK-AMD64-DAG: dl = 0x31 128CHECK-AMD64-DAG: sil = 0x41 129CHECK-AMD64-DAG: dil = 0x51 130CHECK-AMD64-DAG: bpl = 0x61 131CHECK-AMD64-DAG: spl = 0x71 132CHECK-AMD64-DAG: r8l = 0x81 133CHECK-AMD64-DAG: r9l = 0x91 134CHECK-AMD64-DAG: r10l = 0xa1 135CHECK-AMD64-DAG: r11l = 0xb1 136CHECK-AMD64-DAG: r12l = 0xc1 137CHECK-AMD64-DAG: r13l = 0xd1 138CHECK-AMD64-DAG: r14l = 0xe1 139CHECK-AMD64-DAG: r15l = 0xf1 140""" 141 142 self.server.responder = MyResponder( 143 "x86-64", 144 has_target_xml, 145 GPRS, 146 "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;", 147 ) 148 149 target = self.createTarget("basic_eh_frame.yaml") 150 process = self.connect(target) 151 lldbutil.expect_state_changes( 152 self, self.dbg.GetListener(), process, [lldb.eStateStopped] 153 ) 154 155 # test all registers 156 self.filecheck( 157 "register read --all", 158 __file__, 159 filecheck_options="--check-prefix=CHECK-AMD64", 160 ) 161 162 # test generic aliases 163 self.match("register read arg4", ["rcx = 0x2827262524232221"]) 164 self.match("register read arg3", ["rdx = 0x3837363534333231"]) 165 self.match("register read arg2", ["rsi = 0x4847464544434241"]) 166 self.match("register read arg1", ["rdi = 0x5857565554535251"]) 167 self.match("register read fp", ["rbp = 0x6867666564636261"]) 168 self.match("register read sp", ["rsp = 0x7877767574737271"]) 169 self.match("register read arg5", ["r8 = 0x8887868584838281"]) 170 self.match("register read arg6", ["r9 = 0x9897969594939291"]) 171 self.match("register read pc", ["rip = 0x100f0e0d0c0b0a09"]) 172 self.match("register read flags", ["eflags = 0x1c1b1a19"]) 173 174 @skipIfRemote 175 @skipIfLLVMTargetMissing("X86") 176 def test_x86_64_regs_no_target_xml(self): 177 """Test grabbing various x86_64 registers from gdbserver when there 178 is no target XML.""" 179 self.check_x86_64_regs(False) 180 181 @skipIfXmlSupportMissing 182 @skipIfRemote 183 @skipIfLLVMTargetMissing("X86") 184 def test_x86_64_regs_no_register_info(self): 185 """Test grabbing various x86_64 registers from gdbserver when there 186 is target XML but it does not include register info.""" 187 self.check_x86_64_regs(True) 188 189 def check_aarch64_regs(self, has_target_xml): 190 GPRS = """ 191CHECK-AARCH64-DAG: x0 = 0x0001020304050607 192CHECK-AARCH64-DAG: x1 = 0x0102030405060708 193CHECK-AARCH64-DAG: x2 = 0x0203040506070809 194CHECK-AARCH64-DAG: x3 = 0x030405060708090a 195CHECK-AARCH64-DAG: x4 = 0x0405060708090a0b 196CHECK-AARCH64-DAG: x5 = 0x05060708090a0b0c 197CHECK-AARCH64-DAG: x6 = 0x060708090a0b0c0d 198CHECK-AARCH64-DAG: x7 = 0x0708090a0b0c0d0e 199CHECK-AARCH64-DAG: x8 = 0x08090a0b0c0d0e0f 200CHECK-AARCH64-DAG: x9 = 0x090a0b0c0d0e0f10 201CHECK-AARCH64-DAG: x10 = 0x0a0b0c0d0e0f1011 202CHECK-AARCH64-DAG: x11 = 0x0b0c0d0e0f101112 203CHECK-AARCH64-DAG: x12 = 0x0c0d0e0f10111213 204CHECK-AARCH64-DAG: x13 = 0x0d0e0f1011121314 205CHECK-AARCH64-DAG: x14 = 0x0e0f101112131415 206CHECK-AARCH64-DAG: x15 = 0x0f10111213141516 207CHECK-AARCH64-DAG: x16 = 0x1011121314151617 208CHECK-AARCH64-DAG: x17 = 0x1112131415161718 209CHECK-AARCH64-DAG: x18 = 0x1213141516171819 210CHECK-AARCH64-DAG: x19 = 0x131415161718191a 211CHECK-AARCH64-DAG: x20 = 0x1415161718191a1b 212CHECK-AARCH64-DAG: x21 = 0x15161718191a1b1c 213CHECK-AARCH64-DAG: x22 = 0x161718191a1b1c1d 214CHECK-AARCH64-DAG: x23 = 0x1718191a1b1c1d1e 215CHECK-AARCH64-DAG: x24 = 0x18191a1b1c1d1e1f 216CHECK-AARCH64-DAG: x25 = 0x191a1b1c1d1e1f20 217CHECK-AARCH64-DAG: x26 = 0x1a1b1c1d1e1f2021 218CHECK-AARCH64-DAG: x27 = 0x1b1c1d1e1f202122 219CHECK-AARCH64-DAG: x28 = 0x1c1d1e1f20212223 220CHECK-AARCH64-DAG: x29 = 0x1d1e1f2021222324 221CHECK-AARCH64-DAG: x30 = 0x1e1f202122232425 222CHECK-AARCH64-DAG: sp = 0x1f20212223242526 223CHECK-AARCH64-DAG: pc = 0x2021222324252627 224CHECK-AARCH64-DAG: cpsr = 0x21222324 225""" 226 227 SUPPL = """ 228CHECK-AARCH64-DAG: w0 = 0x04050607 229CHECK-AARCH64-DAG: w1 = 0x05060708 230CHECK-AARCH64-DAG: w2 = 0x06070809 231CHECK-AARCH64-DAG: w3 = 0x0708090a 232CHECK-AARCH64-DAG: w4 = 0x08090a0b 233CHECK-AARCH64-DAG: w5 = 0x090a0b0c 234CHECK-AARCH64-DAG: w6 = 0x0a0b0c0d 235CHECK-AARCH64-DAG: w7 = 0x0b0c0d0e 236CHECK-AARCH64-DAG: w8 = 0x0c0d0e0f 237CHECK-AARCH64-DAG: w9 = 0x0d0e0f10 238CHECK-AARCH64-DAG: w10 = 0x0e0f1011 239CHECK-AARCH64-DAG: w11 = 0x0f101112 240CHECK-AARCH64-DAG: w12 = 0x10111213 241CHECK-AARCH64-DAG: w13 = 0x11121314 242CHECK-AARCH64-DAG: w14 = 0x12131415 243CHECK-AARCH64-DAG: w15 = 0x13141516 244CHECK-AARCH64-DAG: w16 = 0x14151617 245CHECK-AARCH64-DAG: w17 = 0x15161718 246CHECK-AARCH64-DAG: w18 = 0x16171819 247CHECK-AARCH64-DAG: w19 = 0x1718191a 248CHECK-AARCH64-DAG: w20 = 0x18191a1b 249CHECK-AARCH64-DAG: w21 = 0x191a1b1c 250CHECK-AARCH64-DAG: w22 = 0x1a1b1c1d 251CHECK-AARCH64-DAG: w23 = 0x1b1c1d1e 252CHECK-AARCH64-DAG: w24 = 0x1c1d1e1f 253CHECK-AARCH64-DAG: w25 = 0x1d1e1f20 254CHECK-AARCH64-DAG: w26 = 0x1e1f2021 255CHECK-AARCH64-DAG: w27 = 0x1f202122 256CHECK-AARCH64-DAG: w28 = 0x20212223 257CHECK-AARCH64-DAG: w29 = 0x21222324 258CHECK-AARCH64-DAG: w30 = 0x22232425 259CHECK-AARCH64-DAG: w31 = 0x23242526 260""" 261 262 self.server.responder = MyResponder( 263 "aarch64", 264 has_target_xml, 265 GPRS, 266 "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;", 267 ) 268 269 target = self.createTarget("basic_eh_frame-aarch64.yaml") 270 process = self.connect(target) 271 lldbutil.expect_state_changes( 272 self, self.dbg.GetListener(), process, [lldb.eStateStopped] 273 ) 274 275 # test all registers 276 self.filecheck( 277 "register read --all", 278 __file__, 279 filecheck_options="--check-prefix=CHECK-AARCH64", 280 ) 281 282 # test generic aliases 283 self.match("register read arg1", ["x0 = 0x0001020304050607"]) 284 self.match("register read arg2", ["x1 = 0x0102030405060708"]) 285 self.match("register read fp", ["x29 = 0x1d1e1f2021222324"]) 286 self.match("register read lr", ["x30 = 0x1e1f202122232425"]) 287 self.match("register read ra", ["x30 = 0x1e1f202122232425"]) 288 self.match("register read flags", ["cpsr = 0x21222324"]) 289 290 @skipIfRemote 291 @skipIfLLVMTargetMissing("AArch64") 292 def test_aarch64_regs_no_target_xml(self): 293 """Test grabbing various aarch64 registers from gdbserver when there 294 is no target XML.""" 295 self.check_aarch64_regs(False) 296 297 @skipIfXmlSupportMissing 298 @skipIfRemote 299 @skipIfLLVMTargetMissing("AArch64") 300 def test_aarch64_regs_no_register_info(self): 301 """Test grabbing various aarch64 registers from gdbserver when there 302 is target XML but it does not include register info.""" 303 self.check_aarch64_regs(True) 304 305 def check_i386_regs(self, has_target_xml): 306 GPRS = """ 307CHECK-I386-DAG: eax = 0x04030201 308CHECK-I386-DAG: ecx = 0x14131211 309CHECK-I386-DAG: edx = 0x24232221 310CHECK-I386-DAG: ebx = 0x34333231 311CHECK-I386-DAG: esp = 0x44434241 312CHECK-I386-DAG: ebp = 0x54535251 313CHECK-I386-DAG: esi = 0x64636261 314CHECK-I386-DAG: edi = 0x74737271 315CHECK-I386-DAG: eip = 0x84838281 316CHECK-I386-DAG: eflags = 0x94939291 317CHECK-I386-DAG: cs = 0xa4a3a2a1 318CHECK-I386-DAG: ss = 0xb4b3b2b1 319CHECK-I386-DAG: ds = 0xc4c3c2c1 320CHECK-I386-DAG: es = 0xd4d3d2d1 321CHECK-I386-DAG: fs = 0xe4e3e2e1 322CHECK-I386-DAG: gs = 0xf4f3f2f1 323""" 324 325 SUPPL = """ 326CHECK-I386-DAG: ax = 0x0201 327CHECK-I386-DAG: cx = 0x1211 328CHECK-I386-DAG: dx = 0x2221 329CHECK-I386-DAG: bx = 0x3231 330CHECK-I386-DAG: sp = 0x4241 331CHECK-I386-DAG: bp = 0x5251 332CHECK-I386-DAG: si = 0x6261 333CHECK-I386-DAG: di = 0x7271 334 335CHECK-I386-DAG: ah = 0x02 336CHECK-I386-DAG: ch = 0x12 337CHECK-I386-DAG: dh = 0x22 338CHECK-I386-DAG: bh = 0x32 339 340CHECK-I386-DAG: al = 0x01 341CHECK-I386-DAG: cl = 0x11 342CHECK-I386-DAG: dl = 0x21 343CHECK-I386-DAG: bl = 0x31 344CHECK-I386-DAG: spl = 0x41 345CHECK-I386-DAG: bpl = 0x51 346CHECK-I386-DAG: sil = 0x61 347CHECK-I386-DAG: dil = 0x71 348""" 349 350 self.server.responder = MyResponder( 351 "i386", 352 has_target_xml, 353 GPRS, 354 "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;", 355 ) 356 357 target = self.createTarget("basic_eh_frame-i386.yaml") 358 process = self.connect(target) 359 lldbutil.expect_state_changes( 360 self, self.dbg.GetListener(), process, [lldb.eStateStopped] 361 ) 362 363 # test all registers 364 self.filecheck( 365 "register read --all", 366 __file__, 367 filecheck_options="--check-prefix=CHECK-I386", 368 ) 369 370 # test generic aliases 371 self.match("register read fp", ["ebp = 0x54535251"]) 372 self.match("register read sp", ["esp = 0x44434241"]) 373 self.match("register read pc", ["eip = 0x84838281"]) 374 self.match("register read flags", ["eflags = 0x94939291"]) 375 376 @skipIfRemote 377 @skipIfLLVMTargetMissing("X86") 378 def test_i386_regs_no_target_xml(self): 379 """Test grabbing various i386 registers from gdbserver when there is 380 no target XML.""" 381 self.check_i386_regs(False) 382 383 @skipIfXmlSupportMissing 384 @skipIfRemote 385 @skipIfLLVMTargetMissing("X86") 386 def test_i386_regs_no_register_info(self): 387 """Test grabbing various i386 registers from gdbserver when there is 388 target XML but it does not include register info.""" 389 self.check_i386_regs(True)