1import lldb 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test.decorators import * 4from lldbsuite.test.gdbclientutils import * 5from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 6 7 8# This test case checks for register number mismatch between lldb and gdb stub. 9# LLDB client assigns register numbers to target xml registers in increasing 10# order starting with regnum = 0, while gdb-remote may specify different regnum 11# which is stored as eRegisterKindProcessPlugin. Remote side will use its 12# register number in expedited register list, value_regs and invalidate_regnums. 13# 14# This test creates a ficticious target xml with non-sequential regnums to test 15# that correct registers are accessed in all of above mentioned cases. 16 17 18class TestRemoteRegNums(GDBRemoteTestBase): 19 @skipIfXmlSupportMissing 20 def test(self): 21 class MyResponder(MockGDBServerResponder): 22 def haltReason(self): 23 return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:00bc010001000000;09:c04825ebfe7f0000;" 24 25 def threadStopInfo(self, threadnum): 26 return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:00bc010001000000;09:c04825ebfe7f0000;" 27 28 def writeRegisters(self): 29 return "E02" 30 31 def readRegisters(self): 32 return "E01" 33 34 rax_regnum2_val = "7882773ce0ffffff" 35 rbx_regnum4_val = "1122334455667788" 36 37 def readRegister(self, regnum): 38 # lldb will try sending "p0" to see if the p packet is supported, 39 # give a bogus value; in theory lldb could use this value in the 40 # register context and that would be valid behavior. 41 42 # notably, don't give values for registers 1 & 3 -- lldb should 43 # get those from the ? stop packet ("T11") and it is a pref regression 44 # if lldb is asking for these register values. 45 if regnum == 0: 46 return "5555555555555555" 47 if regnum == 2: 48 return self.rax_regnum2_val 49 if regnum == 4: 50 return self.rbx_regnum4_val 51 52 return "E03" 53 54 def writeRegister(self, regnum, value_hex): 55 if regnum == 2: 56 self.rax_regnum2_val = value_hex 57 if regnum == 4: 58 self.rbx_regnum4_val = value_hex 59 60 return "OK" 61 62 def qXferRead(self, obj, annex, offset, length): 63 if annex == "target.xml": 64 return ( 65 """<?xml version="1.0"?> 66 <target version="1.0"> 67 <architecture>i386:x86-64</architecture> 68 <feature name="org.gnu.gdb.i386.core"> 69 <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general" altname="pc" generic="pc"/> 70 <reg name="rax" bitsize="64" regnum="2" type="code_ptr" group="general"/> 71 <reg name="rbx" bitsize="64" regnum="4" type="code_ptr" group="general"/> 72 <reg name="eax" bitsize="32" regnum="5" value_regnums="2" invalidate_regnums="2" type="code_ptr" group="general"/> 73 <reg name="ebx" bitsize="32" regnum="7" value_regnums="4" invalidate_regnums="4" type="code_ptr" group="general"/> 74 <reg name="rsi" bitsize="64" regnum="9" type="code_ptr" group="general"/> 75 </feature> 76 </target>""", 77 False, 78 ) 79 else: 80 return None, False 81 82 self.server.responder = MyResponder() 83 target = self.dbg.CreateTarget("") 84 if self.TraceOn(): 85 self.runCmd("log enable gdb-remote packets") 86 self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets")) 87 process = self.connect(target) 88 89 thread = process.GetThreadAtIndex(0) 90 frame = thread.GetFrameAtIndex(0) 91 rax = frame.FindRegister("rax").GetValueAsUnsigned() 92 eax = frame.FindRegister("eax").GetValueAsUnsigned() 93 rbx = frame.FindRegister("rbx").GetValueAsUnsigned() 94 ebx = frame.FindRegister("ebx").GetValueAsUnsigned() 95 rsi = frame.FindRegister("rsi").GetValueAsUnsigned() 96 pc = frame.GetPC() 97 rip = frame.FindRegister("rip").GetValueAsUnsigned() 98 99 if self.TraceOn(): 100 print( 101 "Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" 102 % (rax, rbx, rsi, pc, rip) 103 ) 104 105 self.assertEqual(rax, 0xFFFFFFE03C778278) 106 self.assertEqual(rbx, 0x8877665544332211) 107 self.assertEqual(eax, 0x3C778278) 108 self.assertEqual(ebx, 0x44332211) 109 self.assertEqual(rsi, 0x00007FFEEB2548C0) 110 self.assertEqual(pc, 0x10001BC00) 111 self.assertEqual(rip, 0x10001BC00) 112 113 frame.FindRegister("eax").SetValueFromCString("1") 114 frame.FindRegister("ebx").SetValueFromCString("0") 115 eax = frame.FindRegister("eax").GetValueAsUnsigned() 116 ebx = frame.FindRegister("ebx").GetValueAsUnsigned() 117 rax = frame.FindRegister("rax").GetValueAsUnsigned() 118 rbx = frame.FindRegister("rbx").GetValueAsUnsigned() 119 120 if self.TraceOn(): 121 print( 122 "Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" 123 % (rax, rbx, rsi, pc, rip) 124 ) 125 126 self.assertEqual(rax, 0xFFFFFFE000000001) 127 self.assertEqual(rbx, 0x8877665500000000) 128 self.assertEqual(eax, 0x00000001) 129 self.assertEqual(ebx, 0x00000000) 130 self.assertEqual(rsi, 0x00007FFEEB2548C0) 131 self.assertEqual(pc, 0x10001BC00) 132 self.assertEqual(rip, 0x10001BC00) 133