from __future__ import print_function import lldb from lldbsuite.test.lldbtest import * from lldbsuite.test.decorators import * from gdbclientutils import * class TestGDBServerTargetXML(GDBRemoteTestBase): @skipIfXmlSupportMissing @skipIfRemote @skipIfLLVMTargetMissing("X86") def test_x86_64_regs(self): """Test grabbing various x86_64 registers from gdbserver.""" class MyResponder(MockGDBServerResponder): reg_data = ( "0102030405060708" # rcx "1112131415161718" # rdx "2122232425262728" # rsi "3132333435363738" # rdi "4142434445464748" # rbp "5152535455565758" # rsp "6162636465666768" # r8 "7172737475767778" # r9 "8182838485868788" # rip "91929394" # eflags "0102030405060708090a" # st0 "1112131415161718191a" # st1 ) + 6 * ( "2122232425262728292a" # st2..st7 ) + ( "8182838485868788898a8b8c8d8e8f90" # xmm0 "9192939495969798999a9b9c9d9e9fa0" # xmm1 ) + 14 * ( "a1a2a3a4a5a6a7a8a9aaabacadaeafb0" # xmm2..xmm15 ) + ( "00000000" # mxcsr ) + ( "b1b2b3b4b5b6b7b8b9babbbcbdbebfc0" # ymm0h "c1c2c3c4c5c6c7c8c9cacbcccdcecfd0" # ymm1h ) + 14 * ( "d1d2d3d4d5d6d7d8d9dadbdcdddedfe0" # ymm2h..ymm15h ) def qXferRead(self, obj, annex, offset, length): if annex == "target.xml": return """ i386:x86-64 GNU/Linux """, False else: return None, False def readRegister(self, regnum): return "" def readRegisters(self): return self.reg_data def writeRegisters(self, reg_hex): self.reg_data = reg_hex return "OK" 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 generic aliases self.match("register read arg4", ["rcx = 0x0807060504030201"]) self.match("register read arg3", ["rdx = 0x1817161514131211"]) self.match("register read arg2", ["rsi = 0x2827262524232221"]) self.match("register read arg1", ["rdi = 0x3837363534333231"]) self.match("register read fp", ["rbp = 0x4847464544434241"]) self.match("register read sp", ["rsp = 0x5857565554535251"]) self.match("register read arg5", ["r8 = 0x6867666564636261"]) self.match("register read arg6", ["r9 = 0x7877767574737271"]) self.match("register read pc", ["rip = 0x8887868584838281"]) self.match("register read flags", ["eflags = 0x94939291"]) # both stX and xmmX should be displayed as vectors self.match("register read st0", ["st0 = {0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a}"]) self.match("register read st1", ["st1 = {0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a}"]) self.match("register read xmm0", ["xmm0 = {0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 " "0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"]) self.match("register read xmm1", ["xmm1 = {0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 " "0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0}"]) # test pseudo-registers self.filecheck("register read --all", os.path.join(os.path.dirname(__file__), "amd64-partial-regs.FileCheck")) # test writing into pseudo-registers self.runCmd("register write ecx 0xfffefdfc") self.match("register read rcx", ["rcx = 0x08070605fffefdfc"]) self.runCmd("register write cx 0xfbfa") self.match("register read ecx", ["ecx = 0xfffefbfa"]) self.match("register read rcx", ["rcx = 0x08070605fffefbfa"]) self.runCmd("register write ch 0xf9") self.match("register read cx", ["cx = 0xf9fa"]) self.match("register read ecx", ["ecx = 0xfffef9fa"]) self.match("register read rcx", ["rcx = 0x08070605fffef9fa"]) self.runCmd("register write cl 0xf8") self.match("register read cx", ["cx = 0xf9f8"]) self.match("register read ecx", ["ecx = 0xfffef9f8"]) self.match("register read rcx", ["rcx = 0x08070605fffef9f8"]) self.runCmd("register write mm0 0xfffefdfcfbfaf9f8") self.match("register read st0", ["st0 = {0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x09 0x0a}"]) self.runCmd("register write xmm0 \"{0xff 0xfe 0xfd 0xfc 0xfb 0xfa 0xf9 " "0xf8 0xf7 0xf6 0xf5 0xf4 0xf3 0xf2 0xf1 0xf0}\"") self.match("register read ymm0", ["ymm0 = {0xff 0xfe 0xfd 0xfc 0xfb 0xfa 0xf9 0xf8 0xf7 0xf6 " "0xf5 0xf4 0xf3 0xf2 0xf1 0xf0 0xb1 0xb2 0xb3 0xb4 0xb5 " "0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0}"]) self.runCmd("register write ymm0h \"{0xef 0xee 0xed 0xec 0xeb 0xea 0xe9 " "0xe8 0xe7 0xe6 0xe5 0xe4 0xe3 0xe2 0xe1 0xe0}\"") self.match("register read ymm0", ["ymm0 = {0xff 0xfe 0xfd 0xfc 0xfb 0xfa 0xf9 0xf8 0xf7 0xf6 " "0xf5 0xf4 0xf3 0xf2 0xf1 0xf0 0xef 0xee 0xed 0xec 0xeb " "0xea 0xe9 0xe8 0xe7 0xe6 0xe5 0xe4 0xe3 0xe2 0xe1 0xe0}"]) self.runCmd("register write ymm0 \"{0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 " "0xd7 0xd8 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 " "0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec " "0xed 0xee 0xef}\"") self.match("register read ymm0", ["ymm0 = {0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 " "0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 0xe4 " "0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef}"]) @skipIfXmlSupportMissing @skipIfRemote @skipIfLLVMTargetMissing("X86") def test_i386_regs(self): """Test grabbing various i386 registers from gdbserver.""" class MyResponder(MockGDBServerResponder): reg_data = ( "01020304" # eax "11121314" # ecx "21222324" # edx "31323334" # ebx "41424344" # esp "51525354" # ebp "61626364" # esi "71727374" # edi "81828384" # eip "91929394" # eflags "0102030405060708090a" # st0 "1112131415161718191a" # st1 ) + 6 * ( "2122232425262728292a" # st2..st7 ) + ( "8182838485868788898a8b8c8d8e8f90" # xmm0 "9192939495969798999a9b9c9d9e9fa0" # xmm1 ) + 6 * ( "a1a2a3a4a5a6a7a8a9aaabacadaeafb0" # xmm2..xmm7 ) + ( "00000000" # mxcsr ) + ( "b1b2b3b4b5b6b7b8b9babbbcbdbebfc0" # ymm0h "c1c2c3c4c5c6c7c8c9cacbcccdcecfd0" # ymm1h ) + 6 * ( "d1d2d3d4d5d6d7d8d9dadbdcdddedfe0" # ymm2h..ymm7h ) def qXferRead(self, obj, annex, offset, length): if annex == "target.xml": return """ i386 GNU/Linux """, False else: return None, False def readRegister(self, regnum): return "" def readRegisters(self): return self.reg_data def writeRegisters(self, reg_hex): self.reg_data = reg_hex return "OK" 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 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"]) # test pseudo-registers self.match("register read cx", ["cx = 0x1211"]) self.match("register read ch", ["ch = 0x12"]) self.match("register read cl", ["cl = 0x11"]) self.match("register read mm0", ["mm0 = 0x0807060504030201"]) self.match("register read mm1", ["mm1 = 0x1817161514131211"]) # both stX and xmmX should be displayed as vectors self.match("register read st0", ["st0 = {0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a}"]) self.match("register read st1", ["st1 = {0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a}"]) self.match("register read xmm0", ["xmm0 = {0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 " "0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"]) self.match("register read xmm1", ["xmm1 = {0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 " "0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0}"]) # test writing into pseudo-registers self.runCmd("register write cx 0xfbfa") self.match("register read ecx", ["ecx = 0x1413fbfa"]) self.runCmd("register write ch 0xf9") self.match("register read cx", ["cx = 0xf9fa"]) self.match("register read ecx", ["ecx = 0x1413f9fa"]) self.runCmd("register write cl 0xf8") self.match("register read cx", ["cx = 0xf9f8"]) self.match("register read ecx", ["ecx = 0x1413f9f8"]) self.runCmd("register write mm0 0xfffefdfcfbfaf9f8") self.match("register read st0", ["st0 = {0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x09 0x0a}"]) self.runCmd("register write xmm0 \"{0xff 0xfe 0xfd 0xfc 0xfb 0xfa 0xf9 " "0xf8 0xf7 0xf6 0xf5 0xf4 0xf3 0xf2 0xf1 0xf0}\"") self.match("register read ymm0", ["ymm0 = {0xff 0xfe 0xfd 0xfc 0xfb 0xfa 0xf9 0xf8 0xf7 0xf6 " "0xf5 0xf4 0xf3 0xf2 0xf1 0xf0 0xb1 0xb2 0xb3 0xb4 0xb5 " "0xb6 0xb7 0xb8 0xb9 0xba 0xbb 0xbc 0xbd 0xbe 0xbf 0xc0}"]) self.runCmd("register write ymm0h \"{0xef 0xee 0xed 0xec 0xeb 0xea 0xe9 " "0xe8 0xe7 0xe6 0xe5 0xe4 0xe3 0xe2 0xe1 0xe0}\"") self.match("register read ymm0", ["ymm0 = {0xff 0xfe 0xfd 0xfc 0xfb 0xfa 0xf9 0xf8 0xf7 0xf6 " "0xf5 0xf4 0xf3 0xf2 0xf1 0xf0 0xef 0xee 0xed 0xec 0xeb " "0xea 0xe9 0xe8 0xe7 0xe6 0xe5 0xe4 0xe3 0xe2 0xe1 0xe0}"]) self.runCmd("register write ymm0 \"{0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 " "0xd7 0xd8 0xd9 0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 " "0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec " "0xed 0xee 0xef}\"") self.match("register read ymm0", ["ymm0 = {0xd0 0xd1 0xd2 0xd3 0xd4 0xd5 0xd6 0xd7 0xd8 0xd9 " "0xda 0xdb 0xdc 0xdd 0xde 0xdf 0xe0 0xe1 0xe2 0xe3 0xe4 " "0xe5 0xe6 0xe7 0xe8 0xe9 0xea 0xeb 0xec 0xed 0xee 0xef}"]) @skipIfXmlSupportMissing @skipIfRemote @skipIfLLVMTargetMissing("AArch64") def test_aarch64_regs(self): """Test grabbing various aarch64 registers from gdbserver.""" 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 """ aarch64 """, False else: return None, False def readRegister(self, regnum): return "" def readRegisters(self): return self.reg_data def writeRegisters(self, reg_hex): self.reg_data = reg_hex return "OK" 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 GPRs self.match("register read x0", ["x0 = 0x0807060504030201"]) self.match("register read x1", ["x1 = 0x1817161514131211"]) self.match("register read x29", ["x29 = 0x3837363534333231"]) self.match("register read x30", ["x30 = 0x4847464544434241"]) self.match("register read x31", ["sp = 0x5857565554535251"]) self.match("register read sp", ["sp = 0x5857565554535251"]) self.match("register read pc", ["pc = 0x6867666564636261"]) self.match("register read cpsr", ["cpsr = 0x74737271"]) # test generic aliases self.match("register read arg1", ["x0 = 0x0807060504030201"]) self.match("register read arg2", ["x1 = 0x1817161514131211"]) self.match("register read fp", ["x29 = 0x3837363534333231"]) self.match("register read lr", ["x30 = 0x4847464544434241"]) self.match("register read ra", ["x30 = 0x4847464544434241"]) self.match("register read flags", ["cpsr = 0x74737271"]) # test vector registers self.match("register read v0", ["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"]) @skipIfXmlSupportMissing @skipIfRemote @skipIfLLVMTargetMissing("X86") def test_x86_64_no_duplicate_subregs(self): """Test that duplicate subregisters are not added (on x86_64).""" class MyResponder(MockGDBServerResponder): reg_data = ( "0102030405060708" # rcx "1112131415161718" # rdx "2122232425262728" # rsi "3132333435363738" # rdi "4142434445464748" # rbp "5152535455565758" # rsp "6162636465666768" # r8 "7172737475767778" # r9 "8182838485868788" # rip "91929394" # eflags ) def qXferRead(self, obj, annex, offset, length): if annex == "target.xml": return """ i386:x86-64 GNU/Linux """, False else: return None, False 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]) self.match("register read rcx", ["rcx = 0x0807060504030201"]) # ecx is supplied via target.xml self.match("register read ecx", ["ecx = 0x04030201"]) self.match("register read rdx", ["rdx = 0x1817161514131211"]) # edx should not be added self.match("register read edx", ["error: Invalid register name 'edx'."], error=True) @skipIfXmlSupportMissing @skipIfRemote @skipIfLLVMTargetMissing("X86") def test_i386_no_duplicate_subregs(self): """Test that duplicate subregisters are not added (on i386).""" class MyResponder(MockGDBServerResponder): reg_data = ( "01020304" # eax "11121314" # ecx "21222324" # edx "31323334" # ebx "41424344" # esp "51525354" # ebp "61626364" # esi "71727374" # edi "81828384" # eip "91929394" # eflags ) def qXferRead(self, obj, annex, offset, length): if annex == "target.xml": return """ i386 GNU/Linux """, False else: return None, False 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]) self.match("register read eax", ["eax = 0x04030201"]) # cx is supplied via target.xml self.match("register read ax", ["ax = 0x0201"]) self.match("register read ecx", ["ecx = 0x14131211"]) # dx should not be added self.match("register read cx", ["error: Invalid register name 'cx'."], error=True) @skipIfXmlSupportMissing @skipIfRemote @skipIfLLVMTargetMissing("AArch64") def test_aarch64_no_duplicate_subregs(self): """Test that duplicate subregisters are not added.""" 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 ) def qXferRead(self, obj, annex, offset, length): if annex == "target.xml": return """ aarch64 """, False else: return None, False 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]) self.match("register read x0", ["x0 = 0x0807060504030201"]) # w0 comes from target.xml self.match("register read w0", ["w0 = 0x04030201"]) self.match("register read x1", ["x1 = 0x1817161514131211"]) # w1 should not be added self.match("register read w1", ["error: Invalid register name 'w1'."], error=True)