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 @skipIfXmlSupportMissing 21 def test(self): 22 class MyResponder(MockGDBServerResponder): 23 def haltReason(self): 24 return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:00bc010001000000;09:c04825ebfe7f0000;" 25 26 def threadStopInfo(self, threadnum): 27 return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:00bc010001000000;09:c04825ebfe7f0000;" 28 29 def writeRegisters(self): 30 return "E02" 31 32 def readRegisters(self): 33 return "E01" 34 35 rax_regnum2_val = "7882773ce0ffffff" 36 rbx_regnum4_val = "1122334455667788" 37 38 def readRegister(self, regnum): 39 # lldb will try sending "p0" to see if the p packet is supported, 40 # give a bogus value; in theory lldb could use this value in the 41 # register context and that would be valid behavior. 42 43 # notably, don't give values for registers 1 & 3 -- lldb should 44 # get those from the ? stop packet ("T11") and it is a pref regression 45 # if lldb is asking for these register values. 46 if regnum == 0: 47 return "5555555555555555" 48 if regnum == 2: 49 return self.rax_regnum2_val 50 if regnum == 4: 51 return self.rbx_regnum4_val 52 53 return "E03" 54 55 def writeRegister(self, regnum, value_hex): 56 if regnum == 2: 57 self.rax_regnum2_val = value_hex 58 if regnum == 4: 59 self.rbx_regnum4_val = value_hex 60 61 return "OK" 62 63 def qXferRead(self, obj, annex, offset, length): 64 if annex == "target.xml": 65 return """<?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>""", False 77 else: 78 return None, False 79 80 self.server.responder = MyResponder() 81 target = self.dbg.CreateTarget('') 82 if self.TraceOn(): 83 self.runCmd("log enable gdb-remote packets") 84 self.addTearDownHook( 85 lambda: self.runCmd("log disable gdb-remote packets")) 86 process = self.connect(target) 87 88 thread = process.GetThreadAtIndex(0) 89 frame = thread.GetFrameAtIndex(0) 90 rax = frame.FindRegister("rax").GetValueAsUnsigned() 91 eax = frame.FindRegister("eax").GetValueAsUnsigned() 92 rbx = frame.FindRegister("rbx").GetValueAsUnsigned() 93 ebx = frame.FindRegister("ebx").GetValueAsUnsigned() 94 rsi = frame.FindRegister("rsi").GetValueAsUnsigned() 95 pc = frame.GetPC() 96 rip = frame.FindRegister("rip").GetValueAsUnsigned() 97 98 if self.TraceOn(): 99 print("Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" % ( 100 rax, rbx, rsi, pc, rip)) 101 102 self.assertEqual(rax, 0xffffffe03c778278) 103 self.assertEqual(rbx, 0x8877665544332211) 104 self.assertEqual(eax, 0x3c778278) 105 self.assertEqual(ebx, 0x44332211) 106 self.assertEqual(rsi, 0x00007ffeeb2548c0) 107 self.assertEqual(pc, 0x10001bc00) 108 self.assertEqual(rip, 0x10001bc00) 109 110 frame.FindRegister("eax").SetValueFromCString("1") 111 frame.FindRegister("ebx").SetValueFromCString("0") 112 eax = frame.FindRegister("eax").GetValueAsUnsigned() 113 ebx = frame.FindRegister("ebx").GetValueAsUnsigned() 114 rax = frame.FindRegister("rax").GetValueAsUnsigned() 115 rbx = frame.FindRegister("rbx").GetValueAsUnsigned() 116 117 if self.TraceOn(): 118 print("Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" % ( 119 rax, rbx, rsi, pc, rip)) 120 121 self.assertEqual(rax, 0xffffffe000000001) 122 self.assertEqual(rbx, 0x8877665500000000) 123 self.assertEqual(eax, 0x00000001) 124 self.assertEqual(ebx, 0x00000000) 125 self.assertEqual(rsi, 0x00007ffeeb2548c0) 126 self.assertEqual(pc, 0x10001bc00) 127 self.assertEqual(rip, 0x10001bc00) 128