| 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 |
| |
| |
| class TestGDBServerTargetXML(GDBRemoteTestBase): |
| |
| mydir = TestBase.compute_mydir(__file__) |
| |
| @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 """<?xml version="1.0"?> |
| <!DOCTYPE feature SYSTEM "gdb-target.dtd"> |
| <target> |
| <architecture>i386:x86-64</architecture> |
| <osabi>GNU/Linux</osabi> |
| <feature name="org.gnu.gdb.i386.core"> |
| <reg name="rcx" bitsize="64" type="int64" regnum="2"/> |
| <reg name="rdx" bitsize="64" type="int64" regnum="3"/> |
| <reg name="rsi" bitsize="64" type="int64" regnum="4"/> |
| <reg name="rdi" bitsize="64" type="int64" regnum="5"/> |
| <reg name="rbp" bitsize="64" type="data_ptr" regnum="6"/> |
| <reg name="rsp" bitsize="64" type="data_ptr" regnum="7"/> |
| <reg name="r8" bitsize="64" type="int64" regnum="8"/> |
| <reg name="r9" bitsize="64" type="int64" regnum="9"/> |
| <reg name="rip" bitsize="64" type="code_ptr" regnum="16"/> |
| <reg name="eflags" bitsize="32" type="i386_eflags" regnum="17"/> |
| <reg name="st0" bitsize="80" type="i387_ext" regnum="24"/> |
| <reg name="st1" bitsize="80" type="i387_ext" regnum="25"/> |
| <reg name="st2" bitsize="80" type="i387_ext" regnum="26"/> |
| <reg name="st3" bitsize="80" type="i387_ext" regnum="27"/> |
| <reg name="st4" bitsize="80" type="i387_ext" regnum="28"/> |
| <reg name="st5" bitsize="80" type="i387_ext" regnum="29"/> |
| <reg name="st6" bitsize="80" type="i387_ext" regnum="30"/> |
| <reg name="st7" bitsize="80" type="i387_ext" regnum="31"/> |
| </feature> |
| <feature name="org.gnu.gdb.i386.sse"> |
| <reg name="xmm0" bitsize="128" type="vec128" regnum="40"/> |
| <reg name="xmm1" bitsize="128" type="vec128" regnum="41"/> |
| <reg name="xmm2" bitsize="128" type="vec128" regnum="42"/> |
| <reg name="xmm3" bitsize="128" type="vec128" regnum="43"/> |
| <reg name="xmm4" bitsize="128" type="vec128" regnum="44"/> |
| <reg name="xmm5" bitsize="128" type="vec128" regnum="45"/> |
| <reg name="xmm6" bitsize="128" type="vec128" regnum="46"/> |
| <reg name="xmm7" bitsize="128" type="vec128" regnum="47"/> |
| <reg name="xmm8" bitsize="128" type="vec128" regnum="48"/> |
| <reg name="xmm9" bitsize="128" type="vec128" regnum="49"/> |
| <reg name="xmm10" bitsize="128" type="vec128" regnum="50"/> |
| <reg name="xmm11" bitsize="128" type="vec128" regnum="51"/> |
| <reg name="xmm12" bitsize="128" type="vec128" regnum="52"/> |
| <reg name="xmm13" bitsize="128" type="vec128" regnum="53"/> |
| <reg name="xmm14" bitsize="128" type="vec128" regnum="54"/> |
| <reg name="xmm15" bitsize="128" type="vec128" regnum="55"/> |
| <reg name="mxcsr" bitsize="32" type="i386_mxcsr" regnum="56" group="vector"/> |
| </feature> |
| <feature name="org.gnu.gdb.i386.avx"> |
| <reg name="ymm0h" bitsize="128" type="uint128" regnum="60"/> |
| <reg name="ymm1h" bitsize="128" type="uint128" regnum="61"/> |
| <reg name="ymm2h" bitsize="128" type="uint128" regnum="62"/> |
| <reg name="ymm3h" bitsize="128" type="uint128" regnum="63"/> |
| <reg name="ymm4h" bitsize="128" type="uint128" regnum="64"/> |
| <reg name="ymm5h" bitsize="128" type="uint128" regnum="65"/> |
| <reg name="ymm6h" bitsize="128" type="uint128" regnum="66"/> |
| <reg name="ymm7h" bitsize="128" type="uint128" regnum="67"/> |
| <reg name="ymm8h" bitsize="128" type="uint128" regnum="68"/> |
| <reg name="ymm9h" bitsize="128" type="uint128" regnum="69"/> |
| <reg name="ymm10h" bitsize="128" type="uint128" regnum="70"/> |
| <reg name="ymm11h" bitsize="128" type="uint128" regnum="71"/> |
| <reg name="ymm12h" bitsize="128" type="uint128" regnum="72"/> |
| <reg name="ymm13h" bitsize="128" type="uint128" regnum="73"/> |
| <reg name="ymm14h" bitsize="128" type="uint128" regnum="74"/> |
| <reg name="ymm15h" bitsize="128" type="uint128" regnum="75"/> |
| </feature> |
| </target>""", 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 """<?xml version="1.0"?> |
| <!DOCTYPE feature SYSTEM "gdb-target.dtd"> |
| <target> |
| <architecture>i386</architecture> |
| <osabi>GNU/Linux</osabi> |
| <feature name="org.gnu.gdb.i386.core"> |
| <reg name="eax" bitsize="32" type="int32" regnum="0"/> |
| <reg name="ecx" bitsize="32" type="int32" regnum="1"/> |
| <reg name="edx" bitsize="32" type="int32" regnum="2"/> |
| <reg name="ebx" bitsize="32" type="int32" regnum="3"/> |
| <reg name="esp" bitsize="32" type="data_ptr" regnum="4"/> |
| <reg name="ebp" bitsize="32" type="data_ptr" regnum="5"/> |
| <reg name="esi" bitsize="32" type="int32" regnum="6"/> |
| <reg name="edi" bitsize="32" type="int32" regnum="7"/> |
| <reg name="eip" bitsize="32" type="code_ptr" regnum="8"/> |
| <reg name="eflags" bitsize="32" type="i386_eflags" regnum="9"/> |
| <reg name="st0" bitsize="80" type="i387_ext" regnum="16"/> |
| <reg name="st1" bitsize="80" type="i387_ext" regnum="17"/> |
| <reg name="st2" bitsize="80" type="i387_ext" regnum="18"/> |
| <reg name="st3" bitsize="80" type="i387_ext" regnum="19"/> |
| <reg name="st4" bitsize="80" type="i387_ext" regnum="20"/> |
| <reg name="st5" bitsize="80" type="i387_ext" regnum="21"/> |
| <reg name="st6" bitsize="80" type="i387_ext" regnum="22"/> |
| <reg name="st7" bitsize="80" type="i387_ext" regnum="23"/> |
| </feature> |
| <feature name="org.gnu.gdb.i386.sse"> |
| <reg name="xmm0" bitsize="128" type="vec128" regnum="32"/> |
| <reg name="xmm1" bitsize="128" type="vec128" regnum="33"/> |
| <reg name="xmm2" bitsize="128" type="vec128" regnum="34"/> |
| <reg name="xmm3" bitsize="128" type="vec128" regnum="35"/> |
| <reg name="xmm4" bitsize="128" type="vec128" regnum="36"/> |
| <reg name="xmm5" bitsize="128" type="vec128" regnum="37"/> |
| <reg name="xmm6" bitsize="128" type="vec128" regnum="38"/> |
| <reg name="xmm7" bitsize="128" type="vec128" regnum="39"/> |
| <reg name="mxcsr" bitsize="32" type="i386_mxcsr" regnum="40" group="vector"/> |
| </feature> |
| <feature name="org.gnu.gdb.i386.avx"> |
| <reg name="ymm0h" bitsize="128" type="uint128" regnum="42"/> |
| <reg name="ymm1h" bitsize="128" type="uint128" regnum="43"/> |
| <reg name="ymm2h" bitsize="128" type="uint128" regnum="44"/> |
| <reg name="ymm3h" bitsize="128" type="uint128" regnum="45"/> |
| <reg name="ymm4h" bitsize="128" type="uint128" regnum="46"/> |
| <reg name="ymm5h" bitsize="128" type="uint128" regnum="47"/> |
| <reg name="ymm6h" bitsize="128" type="uint128" regnum="48"/> |
| <reg name="ymm7h" bitsize="128" type="uint128" regnum="49"/> |
| </feature> |
| </target>""", 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 """<?xml version="1.0"?> |
| <!DOCTYPE feature SYSTEM "gdb-target.dtd"> |
| <target> |
| <architecture>aarch64</architecture> |
| <feature name="org.gnu.gdb.aarch64.core"> |
| <reg name="x0" bitsize="64" type="int" regnum="0"/> |
| <reg name="x1" bitsize="64" type="int" regnum="1"/> |
| <reg name="x2" bitsize="64" type="int" regnum="2"/> |
| <reg name="x3" bitsize="64" type="int" regnum="3"/> |
| <reg name="x4" bitsize="64" type="int" regnum="4"/> |
| <reg name="x5" bitsize="64" type="int" regnum="5"/> |
| <reg name="x6" bitsize="64" type="int" regnum="6"/> |
| <reg name="x7" bitsize="64" type="int" regnum="7"/> |
| <reg name="x8" bitsize="64" type="int" regnum="8"/> |
| <reg name="x9" bitsize="64" type="int" regnum="9"/> |
| <reg name="x10" bitsize="64" type="int" regnum="10"/> |
| <reg name="x11" bitsize="64" type="int" regnum="11"/> |
| <reg name="x12" bitsize="64" type="int" regnum="12"/> |
| <reg name="x13" bitsize="64" type="int" regnum="13"/> |
| <reg name="x14" bitsize="64" type="int" regnum="14"/> |
| <reg name="x15" bitsize="64" type="int" regnum="15"/> |
| <reg name="x16" bitsize="64" type="int" regnum="16"/> |
| <reg name="x17" bitsize="64" type="int" regnum="17"/> |
| <reg name="x18" bitsize="64" type="int" regnum="18"/> |
| <reg name="x19" bitsize="64" type="int" regnum="19"/> |
| <reg name="x20" bitsize="64" type="int" regnum="20"/> |
| <reg name="x21" bitsize="64" type="int" regnum="21"/> |
| <reg name="x22" bitsize="64" type="int" regnum="22"/> |
| <reg name="x23" bitsize="64" type="int" regnum="23"/> |
| <reg name="x24" bitsize="64" type="int" regnum="24"/> |
| <reg name="x25" bitsize="64" type="int" regnum="25"/> |
| <reg name="x26" bitsize="64" type="int" regnum="26"/> |
| <reg name="x27" bitsize="64" type="int" regnum="27"/> |
| <reg name="x28" bitsize="64" type="int" regnum="28"/> |
| <reg name="x29" bitsize="64" type="int" regnum="29"/> |
| <reg name="x30" bitsize="64" type="int" regnum="30"/> |
| <reg name="sp" bitsize="64" type="data_ptr" regnum="31"/> |
| <reg name="pc" bitsize="64" type="code_ptr" regnum="32"/> |
| <reg name="cpsr" bitsize="32" type="cpsr_flags" regnum="33"/> |
| </feature> |
| <feature name="org.gnu.gdb.aarch64.fpu"> |
| <reg name="v0" bitsize="128" type="aarch64v" regnum="34"/> |
| <reg name="v1" bitsize="128" type="aarch64v" regnum="35"/> |
| <reg name="v2" bitsize="128" type="aarch64v" regnum="36"/> |
| <reg name="v3" bitsize="128" type="aarch64v" regnum="37"/> |
| <reg name="v4" bitsize="128" type="aarch64v" regnum="38"/> |
| <reg name="v5" bitsize="128" type="aarch64v" regnum="39"/> |
| <reg name="v6" bitsize="128" type="aarch64v" regnum="40"/> |
| <reg name="v7" bitsize="128" type="aarch64v" regnum="41"/> |
| <reg name="v8" bitsize="128" type="aarch64v" regnum="42"/> |
| <reg name="v9" bitsize="128" type="aarch64v" regnum="43"/> |
| <reg name="v10" bitsize="128" type="aarch64v" regnum="44"/> |
| <reg name="v11" bitsize="128" type="aarch64v" regnum="45"/> |
| <reg name="v12" bitsize="128" type="aarch64v" regnum="46"/> |
| <reg name="v13" bitsize="128" type="aarch64v" regnum="47"/> |
| <reg name="v14" bitsize="128" type="aarch64v" regnum="48"/> |
| <reg name="v15" bitsize="128" type="aarch64v" regnum="49"/> |
| <reg name="v16" bitsize="128" type="aarch64v" regnum="50"/> |
| <reg name="v17" bitsize="128" type="aarch64v" regnum="51"/> |
| <reg name="v18" bitsize="128" type="aarch64v" regnum="52"/> |
| <reg name="v19" bitsize="128" type="aarch64v" regnum="53"/> |
| <reg name="v20" bitsize="128" type="aarch64v" regnum="54"/> |
| <reg name="v21" bitsize="128" type="aarch64v" regnum="55"/> |
| <reg name="v22" bitsize="128" type="aarch64v" regnum="56"/> |
| <reg name="v23" bitsize="128" type="aarch64v" regnum="57"/> |
| <reg name="v24" bitsize="128" type="aarch64v" regnum="58"/> |
| <reg name="v25" bitsize="128" type="aarch64v" regnum="59"/> |
| <reg name="v26" bitsize="128" type="aarch64v" regnum="60"/> |
| <reg name="v27" bitsize="128" type="aarch64v" regnum="61"/> |
| <reg name="v28" bitsize="128" type="aarch64v" regnum="62"/> |
| <reg name="v29" bitsize="128" type="aarch64v" regnum="63"/> |
| <reg name="v30" bitsize="128" type="aarch64v" regnum="64"/> |
| <reg name="v31" bitsize="128" type="aarch64v" regnum="65"/> |
| <reg name="fpsr" bitsize="32" type="int" regnum="66"/> |
| <reg name="fpcr" bitsize="32" type="int" regnum="67"/> |
| </feature> |
| </target>""", 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 """<?xml version="1.0"?> |
| <!DOCTYPE feature SYSTEM "gdb-target.dtd"> |
| <target> |
| <architecture>i386:x86-64</architecture> |
| <osabi>GNU/Linux</osabi> |
| <feature name="org.gnu.gdb.i386.core"> |
| <reg name="rcx" bitsize="64" type="int64" regnum="2"/> |
| <reg name="rdx" bitsize="64" type="int64" regnum="3"/> |
| <reg name="rsi" bitsize="64" type="int64" regnum="4"/> |
| <reg name="rdi" bitsize="64" type="int64" regnum="5"/> |
| <reg name="rbp" bitsize="64" type="data_ptr" regnum="6"/> |
| <reg name="rsp" bitsize="64" type="data_ptr" regnum="7"/> |
| <reg name="r8" bitsize="64" type="int64" regnum="8"/> |
| <reg name="r9" bitsize="64" type="int64" regnum="9"/> |
| <reg name="rip" bitsize="64" type="code_ptr" regnum="16"/> |
| <reg name="eflags" bitsize="32" type="i386_eflags" regnum="17"/> |
| <reg name="ecx" bitsize="32" type="int" regnum="18" value_regnums="2"/> |
| </feature> |
| </target>""", 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 """<?xml version="1.0"?> |
| <!DOCTYPE feature SYSTEM "gdb-target.dtd"> |
| <target> |
| <architecture>i386</architecture> |
| <osabi>GNU/Linux</osabi> |
| <feature name="org.gnu.gdb.i386.core"> |
| <reg name="eax" bitsize="32" type="int32" regnum="0"/> |
| <reg name="ecx" bitsize="32" type="int32" regnum="1"/> |
| <reg name="edx" bitsize="32" type="int32" regnum="2"/> |
| <reg name="ebx" bitsize="32" type="int32" regnum="3"/> |
| <reg name="esp" bitsize="32" type="data_ptr" regnum="4"/> |
| <reg name="ebp" bitsize="32" type="data_ptr" regnum="5"/> |
| <reg name="esi" bitsize="32" type="int32" regnum="6"/> |
| <reg name="edi" bitsize="32" type="int32" regnum="7"/> |
| <reg name="eip" bitsize="32" type="code_ptr" regnum="8"/> |
| <reg name="eflags" bitsize="32" type="i386_eflags" regnum="9"/> |
| <reg name="ax" bitsize="16" type="int" regnum="10" value_regnums="0"/> |
| </feature> |
| </target>""", 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 """<?xml version="1.0"?> |
| <!DOCTYPE feature SYSTEM "gdb-target.dtd"> |
| <target> |
| <architecture>aarch64</architecture> |
| <feature name="org.gnu.gdb.aarch64.core"> |
| <reg name="x0" bitsize="64" type="int" regnum="0"/> |
| <reg name="x1" bitsize="64" type="int" regnum="1"/> |
| <reg name="x2" bitsize="64" type="int" regnum="2"/> |
| <reg name="x3" bitsize="64" type="int" regnum="3"/> |
| <reg name="x4" bitsize="64" type="int" regnum="4"/> |
| <reg name="x5" bitsize="64" type="int" regnum="5"/> |
| <reg name="x6" bitsize="64" type="int" regnum="6"/> |
| <reg name="x7" bitsize="64" type="int" regnum="7"/> |
| <reg name="x8" bitsize="64" type="int" regnum="8"/> |
| <reg name="x9" bitsize="64" type="int" regnum="9"/> |
| <reg name="x10" bitsize="64" type="int" regnum="10"/> |
| <reg name="x11" bitsize="64" type="int" regnum="11"/> |
| <reg name="x12" bitsize="64" type="int" regnum="12"/> |
| <reg name="x13" bitsize="64" type="int" regnum="13"/> |
| <reg name="x14" bitsize="64" type="int" regnum="14"/> |
| <reg name="x15" bitsize="64" type="int" regnum="15"/> |
| <reg name="x16" bitsize="64" type="int" regnum="16"/> |
| <reg name="x17" bitsize="64" type="int" regnum="17"/> |
| <reg name="x18" bitsize="64" type="int" regnum="18"/> |
| <reg name="x19" bitsize="64" type="int" regnum="19"/> |
| <reg name="x20" bitsize="64" type="int" regnum="20"/> |
| <reg name="x21" bitsize="64" type="int" regnum="21"/> |
| <reg name="x22" bitsize="64" type="int" regnum="22"/> |
| <reg name="x23" bitsize="64" type="int" regnum="23"/> |
| <reg name="x24" bitsize="64" type="int" regnum="24"/> |
| <reg name="x25" bitsize="64" type="int" regnum="25"/> |
| <reg name="x26" bitsize="64" type="int" regnum="26"/> |
| <reg name="x27" bitsize="64" type="int" regnum="27"/> |
| <reg name="x28" bitsize="64" type="int" regnum="28"/> |
| <reg name="x29" bitsize="64" type="int" regnum="29"/> |
| <reg name="x30" bitsize="64" type="int" regnum="30"/> |
| <reg name="sp" bitsize="64" type="data_ptr" regnum="31"/> |
| <reg name="pc" bitsize="64" type="code_ptr" regnum="32"/> |
| <reg name="cpsr" bitsize="32" type="cpsr_flags" regnum="33"/> |
| <reg name="w0" bitsize="32" type="int" regnum="34" value_regnums="0"/> |
| </feature> |
| </target>""", 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) |