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