1from __future__ import print_function 2import lldb 3from lldbsuite.test.lldbtest import * 4from lldbsuite.test.decorators import * 5from gdbclientutils import * 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 17class TestRemoteRegNums(GDBRemoteTestBase): 18 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 """<?xml version="1.0"?> 65 <target version="1.0"> 66 <architecture>i386:x86-64</architecture> 67 <feature name="org.gnu.gdb.i386.core"> 68 <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general" altname="pc" generic="pc"/> 69 <reg name="rax" bitsize="64" regnum="2" type="code_ptr" group="general"/> 70 <reg name="rbx" bitsize="64" regnum="4" type="code_ptr" group="general"/> 71 <reg name="eax" bitsize="32" regnum="5" value_regnums="2" invalidate_regnums="2" type="code_ptr" group="general"/> 72 <reg name="ebx" bitsize="32" regnum="7" value_regnums="4" invalidate_regnums="4" type="code_ptr" group="general"/> 73 <reg name="rsi" bitsize="64" regnum="9" type="code_ptr" group="general"/> 74 </feature> 75 </target>""", False 76 else: 77 return None, False 78 79 self.server.responder = MyResponder() 80 target = self.dbg.CreateTarget('') 81 if self.TraceOn(): 82 self.runCmd("log enable gdb-remote packets") 83 self.addTearDownHook( 84 lambda: self.runCmd("log disable gdb-remote packets")) 85 process = self.connect(target) 86 87 thread = process.GetThreadAtIndex(0) 88 frame = thread.GetFrameAtIndex(0) 89 rax = frame.FindRegister("rax").GetValueAsUnsigned() 90 eax = frame.FindRegister("eax").GetValueAsUnsigned() 91 rbx = frame.FindRegister("rbx").GetValueAsUnsigned() 92 ebx = frame.FindRegister("ebx").GetValueAsUnsigned() 93 rsi = frame.FindRegister("rsi").GetValueAsUnsigned() 94 pc = frame.GetPC() 95 rip = frame.FindRegister("rip").GetValueAsUnsigned() 96 97 if self.TraceOn(): 98 print("Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" % ( 99 rax, rbx, rsi, pc, rip)) 100 101 self.assertEqual(rax, 0xffffffe03c778278) 102 self.assertEqual(rbx, 0x8877665544332211) 103 self.assertEqual(eax, 0x3c778278) 104 self.assertEqual(ebx, 0x44332211) 105 self.assertEqual(rsi, 0x00007ffeeb2548c0) 106 self.assertEqual(pc, 0x10001bc00) 107 self.assertEqual(rip, 0x10001bc00) 108 109 frame.FindRegister("eax").SetValueFromCString("1") 110 frame.FindRegister("ebx").SetValueFromCString("0") 111 eax = frame.FindRegister("eax").GetValueAsUnsigned() 112 ebx = frame.FindRegister("ebx").GetValueAsUnsigned() 113 rax = frame.FindRegister("rax").GetValueAsUnsigned() 114 rbx = frame.FindRegister("rbx").GetValueAsUnsigned() 115 116 if self.TraceOn(): 117 print("Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" % ( 118 rax, rbx, rsi, pc, rip)) 119 120 self.assertEqual(rax, 0xffffffe000000001) 121 self.assertEqual(rbx, 0x8877665500000000) 122 self.assertEqual(eax, 0x00000001) 123 self.assertEqual(ebx, 0x00000000) 124 self.assertEqual(rsi, 0x00007ffeeb2548c0) 125 self.assertEqual(pc, 0x10001bc00) 126 self.assertEqual(rip, 0x10001bc00) 127