18561ad92SMuhammad Omair Javaidfrom __future__ import print_function
28561ad92SMuhammad Omair Javaidimport lldb
38561ad92SMuhammad Omair Javaidfrom lldbsuite.test.lldbtest import *
48561ad92SMuhammad Omair Javaidfrom lldbsuite.test.decorators import *
5*33c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
6*33c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
78561ad92SMuhammad Omair Javaid
88561ad92SMuhammad Omair Javaid
98561ad92SMuhammad Omair Javaid# This test case checks for register number mismatch between lldb and gdb stub.
108561ad92SMuhammad Omair Javaid# LLDB client assigns register numbers to target xml registers in increasing
118561ad92SMuhammad Omair Javaid# order starting with regnum = 0, while gdb-remote may specify different regnum
128561ad92SMuhammad Omair Javaid# which is stored as eRegisterKindProcessPlugin. Remote side will use its
138561ad92SMuhammad Omair Javaid# register number in expedited register list, value_regs and invalidate_regnums.
148561ad92SMuhammad Omair Javaid#
158561ad92SMuhammad Omair Javaid# This test creates a ficticious target xml with non-sequential regnums to test
168561ad92SMuhammad Omair Javaid# that correct registers are accessed in all of above mentioned cases.
178561ad92SMuhammad Omair Javaid
188561ad92SMuhammad Omair Javaidclass TestRemoteRegNums(GDBRemoteTestBase):
198561ad92SMuhammad Omair Javaid
208561ad92SMuhammad Omair Javaid    @skipIfXmlSupportMissing
218561ad92SMuhammad Omair Javaid    def test(self):
228561ad92SMuhammad Omair Javaid        class MyResponder(MockGDBServerResponder):
238561ad92SMuhammad Omair Javaid            def haltReason(self):
248561ad92SMuhammad Omair Javaid                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:00bc010001000000;09:c04825ebfe7f0000;"
258561ad92SMuhammad Omair Javaid
268561ad92SMuhammad Omair Javaid            def threadStopInfo(self, threadnum):
278561ad92SMuhammad Omair Javaid                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:00bc010001000000;09:c04825ebfe7f0000;"
288561ad92SMuhammad Omair Javaid
298561ad92SMuhammad Omair Javaid            def writeRegisters(self):
308561ad92SMuhammad Omair Javaid                return "E02"
318561ad92SMuhammad Omair Javaid
328561ad92SMuhammad Omair Javaid            def readRegisters(self):
338561ad92SMuhammad Omair Javaid                return "E01"
348561ad92SMuhammad Omair Javaid
358561ad92SMuhammad Omair Javaid            rax_regnum2_val = "7882773ce0ffffff"
368561ad92SMuhammad Omair Javaid            rbx_regnum4_val = "1122334455667788"
378561ad92SMuhammad Omair Javaid
388561ad92SMuhammad Omair Javaid            def readRegister(self, regnum):
398561ad92SMuhammad Omair Javaid                # lldb will try sending "p0" to see if the p packet is supported,
408561ad92SMuhammad Omair Javaid                # give a bogus value; in theory lldb could use this value in the
418561ad92SMuhammad Omair Javaid                # register context and that would be valid behavior.
428561ad92SMuhammad Omair Javaid
438561ad92SMuhammad Omair Javaid                # notably, don't give values for registers 1 & 3 -- lldb should
448561ad92SMuhammad Omair Javaid                # get those from the ? stop packet ("T11") and it is a pref regression
458561ad92SMuhammad Omair Javaid                # if lldb is asking for these register values.
468561ad92SMuhammad Omair Javaid                if regnum == 0:
478561ad92SMuhammad Omair Javaid                    return "5555555555555555"
488561ad92SMuhammad Omair Javaid                if regnum == 2:
498561ad92SMuhammad Omair Javaid                    return self.rax_regnum2_val
508561ad92SMuhammad Omair Javaid                if regnum == 4:
518561ad92SMuhammad Omair Javaid                    return self.rbx_regnum4_val
528561ad92SMuhammad Omair Javaid
538561ad92SMuhammad Omair Javaid                return "E03"
548561ad92SMuhammad Omair Javaid
558561ad92SMuhammad Omair Javaid            def writeRegister(self, regnum, value_hex):
568561ad92SMuhammad Omair Javaid                if regnum == 2:
578561ad92SMuhammad Omair Javaid                    self.rax_regnum2_val = value_hex
588561ad92SMuhammad Omair Javaid                if regnum == 4:
598561ad92SMuhammad Omair Javaid                    self.rbx_regnum4_val = value_hex
608561ad92SMuhammad Omair Javaid
618561ad92SMuhammad Omair Javaid                return "OK"
628561ad92SMuhammad Omair Javaid
638561ad92SMuhammad Omair Javaid            def qXferRead(self, obj, annex, offset, length):
648561ad92SMuhammad Omair Javaid                if annex == "target.xml":
658561ad92SMuhammad Omair Javaid                    return """<?xml version="1.0"?>
668561ad92SMuhammad Omair Javaid                        <target version="1.0">
678561ad92SMuhammad Omair Javaid                          <architecture>i386:x86-64</architecture>
688561ad92SMuhammad Omair Javaid                          <feature name="org.gnu.gdb.i386.core">
698561ad92SMuhammad Omair Javaid                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general" altname="pc" generic="pc"/>
708561ad92SMuhammad Omair Javaid                            <reg name="rax" bitsize="64" regnum="2" type="code_ptr" group="general"/>
718561ad92SMuhammad Omair Javaid                            <reg name="rbx" bitsize="64" regnum="4" type="code_ptr" group="general"/>
728561ad92SMuhammad Omair Javaid                            <reg name="eax" bitsize="32" regnum="5" value_regnums="2" invalidate_regnums="2" type="code_ptr" group="general"/>
738561ad92SMuhammad Omair Javaid                            <reg name="ebx" bitsize="32" regnum="7" value_regnums="4" invalidate_regnums="4" type="code_ptr" group="general"/>
748561ad92SMuhammad Omair Javaid                            <reg name="rsi" bitsize="64" regnum="9" type="code_ptr" group="general"/>
758561ad92SMuhammad Omair Javaid                          </feature>
768561ad92SMuhammad Omair Javaid                        </target>""", False
778561ad92SMuhammad Omair Javaid                else:
788561ad92SMuhammad Omair Javaid                    return None, False
798561ad92SMuhammad Omair Javaid
808561ad92SMuhammad Omair Javaid        self.server.responder = MyResponder()
818561ad92SMuhammad Omair Javaid        target = self.dbg.CreateTarget('')
828561ad92SMuhammad Omair Javaid        if self.TraceOn():
838561ad92SMuhammad Omair Javaid            self.runCmd("log enable gdb-remote packets")
848561ad92SMuhammad Omair Javaid            self.addTearDownHook(
858561ad92SMuhammad Omair Javaid                lambda: self.runCmd("log disable gdb-remote packets"))
868561ad92SMuhammad Omair Javaid        process = self.connect(target)
878561ad92SMuhammad Omair Javaid
888561ad92SMuhammad Omair Javaid        thread = process.GetThreadAtIndex(0)
898561ad92SMuhammad Omair Javaid        frame = thread.GetFrameAtIndex(0)
908561ad92SMuhammad Omair Javaid        rax = frame.FindRegister("rax").GetValueAsUnsigned()
918561ad92SMuhammad Omair Javaid        eax = frame.FindRegister("eax").GetValueAsUnsigned()
928561ad92SMuhammad Omair Javaid        rbx = frame.FindRegister("rbx").GetValueAsUnsigned()
938561ad92SMuhammad Omair Javaid        ebx = frame.FindRegister("ebx").GetValueAsUnsigned()
948561ad92SMuhammad Omair Javaid        rsi = frame.FindRegister("rsi").GetValueAsUnsigned()
958561ad92SMuhammad Omair Javaid        pc = frame.GetPC()
968561ad92SMuhammad Omair Javaid        rip = frame.FindRegister("rip").GetValueAsUnsigned()
978561ad92SMuhammad Omair Javaid
988561ad92SMuhammad Omair Javaid        if self.TraceOn():
998561ad92SMuhammad Omair Javaid            print("Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" % (
1008561ad92SMuhammad Omair Javaid                rax, rbx, rsi, pc, rip))
1018561ad92SMuhammad Omair Javaid
1028561ad92SMuhammad Omair Javaid        self.assertEqual(rax, 0xffffffe03c778278)
1038561ad92SMuhammad Omair Javaid        self.assertEqual(rbx, 0x8877665544332211)
1048561ad92SMuhammad Omair Javaid        self.assertEqual(eax, 0x3c778278)
1058561ad92SMuhammad Omair Javaid        self.assertEqual(ebx, 0x44332211)
1068561ad92SMuhammad Omair Javaid        self.assertEqual(rsi, 0x00007ffeeb2548c0)
1078561ad92SMuhammad Omair Javaid        self.assertEqual(pc, 0x10001bc00)
1088561ad92SMuhammad Omair Javaid        self.assertEqual(rip, 0x10001bc00)
1098561ad92SMuhammad Omair Javaid
1108561ad92SMuhammad Omair Javaid        frame.FindRegister("eax").SetValueFromCString("1")
1118561ad92SMuhammad Omair Javaid        frame.FindRegister("ebx").SetValueFromCString("0")
1128561ad92SMuhammad Omair Javaid        eax = frame.FindRegister("eax").GetValueAsUnsigned()
1138561ad92SMuhammad Omair Javaid        ebx = frame.FindRegister("ebx").GetValueAsUnsigned()
1148561ad92SMuhammad Omair Javaid        rax = frame.FindRegister("rax").GetValueAsUnsigned()
1158561ad92SMuhammad Omair Javaid        rbx = frame.FindRegister("rbx").GetValueAsUnsigned()
1168561ad92SMuhammad Omair Javaid
1178561ad92SMuhammad Omair Javaid        if self.TraceOn():
1188561ad92SMuhammad Omair Javaid            print("Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x" % (
1198561ad92SMuhammad Omair Javaid                rax, rbx, rsi, pc, rip))
1208561ad92SMuhammad Omair Javaid
1218561ad92SMuhammad Omair Javaid        self.assertEqual(rax, 0xffffffe000000001)
1228561ad92SMuhammad Omair Javaid        self.assertEqual(rbx, 0x8877665500000000)
1238561ad92SMuhammad Omair Javaid        self.assertEqual(eax, 0x00000001)
1248561ad92SMuhammad Omair Javaid        self.assertEqual(ebx, 0x00000000)
1258561ad92SMuhammad Omair Javaid        self.assertEqual(rsi, 0x00007ffeeb2548c0)
1268561ad92SMuhammad Omair Javaid        self.assertEqual(pc, 0x10001bc00)
1278561ad92SMuhammad Omair Javaid        self.assertEqual(rip, 0x10001bc00)
128