xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestNoGPacketSupported.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
199451b44SJordan Rupprechtimport lldb
299451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
399451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
433c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
533c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
699451b44SJordan Rupprecht
799451b44SJordan Rupprecht
899451b44SJordan Rupprecht# This test case is testing three things:
999451b44SJordan Rupprecht#
1099451b44SJordan Rupprecht#  1. three register values will be provided in the ? stop packet (T11) -
1199451b44SJordan Rupprecht#     registers 0 ("rax"), 1 ("rbx"), and 3 ("rip")
1299451b44SJordan Rupprecht#  2. ReadRegister packet will provide the value of register 2 ("rsi")
1399451b44SJordan Rupprecht#  3. The "g" read-all-registers packet is not supported; p must be used
1499451b44SJordan Rupprecht#     to get the value of register 2 ("rsi")
1599451b44SJordan Rupprecht#
1699451b44SJordan Rupprecht# Forcing lldb to use the expedited registers in the stop packet and
1799451b44SJordan Rupprecht# marking it an error to request that register value is to prevent
1899451b44SJordan Rupprecht# performance regressions.
1999451b44SJordan Rupprecht#
2099451b44SJordan Rupprecht# Some gdb RSP stubs only implement p/P, they do not support g/G.
2199451b44SJordan Rupprecht# lldb must be able to work with either.
2299451b44SJordan Rupprecht
2399451b44SJordan Rupprecht
24*2238dcc3SJonas Devlieghereclass TestNoGPacketSupported(GDBRemoteTestBase):
2599451b44SJordan Rupprecht    @skipIfXmlSupportMissing
2699451b44SJordan Rupprecht    def test(self):
2799451b44SJordan Rupprecht        class MyResponder(MockGDBServerResponder):
2899451b44SJordan Rupprecht            def haltReason(self):
2999451b44SJordan Rupprecht                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:7882773ce0ffffff;01:1122334455667788;03:00bc010001000000;"
3099451b44SJordan Rupprecht
3199451b44SJordan Rupprecht            def threadStopInfo(self, threadnum):
3299451b44SJordan Rupprecht                return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;00:7882773ce0ffffff;01:1122334455667788;03:00bc010001000000;"
3399451b44SJordan Rupprecht
3499451b44SJordan Rupprecht            def writeRegisters(self):
3599451b44SJordan Rupprecht                return "E02"
3699451b44SJordan Rupprecht
3799451b44SJordan Rupprecht            def readRegisters(self):
3899451b44SJordan Rupprecht                return "E01"
3999451b44SJordan Rupprecht
4099451b44SJordan Rupprecht            def readRegister(self, regnum):
4199451b44SJordan Rupprecht                # lldb will try sending "p0" to see if the p packet is supported,
4299451b44SJordan Rupprecht                # give a bogus value; in theory lldb could use this value in the
4399451b44SJordan Rupprecht                # register context and that would be valid behavior.
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht                # notably, don't give values for registers 1 & 3 -- lldb should
4699451b44SJordan Rupprecht                # get those from the ? stop packet ("T11") and it is a pref regression
4799451b44SJordan Rupprecht                # if lldb is asking for these register values.
4899451b44SJordan Rupprecht                if regnum == 0:
4999451b44SJordan Rupprecht                    return "5555555555555555"
5099451b44SJordan Rupprecht                if regnum == 2:
5199451b44SJordan Rupprecht                    return "c04825ebfe7f0000"  # 0x00007ffeeb2548c0
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht                return "E03"
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht            def writeRegister(self, regnum):
5699451b44SJordan Rupprecht                return "OK"
5799451b44SJordan Rupprecht
5899451b44SJordan Rupprecht            def qXferRead(self, obj, annex, offset, length):
5999451b44SJordan Rupprecht                if annex == "target.xml":
60*2238dcc3SJonas Devlieghere                    return (
61*2238dcc3SJonas Devlieghere                        """<?xml version="1.0"?>
6299451b44SJordan Rupprecht                        <target version="1.0">
6399451b44SJordan Rupprecht                          <architecture>i386:x86-64</architecture>
6499451b44SJordan Rupprecht                          <feature name="org.gnu.gdb.i386.core">
6599451b44SJordan Rupprecht                            <reg name="rax" bitsize="64" regnum="0" type="code_ptr" group="general"/>
6699451b44SJordan Rupprecht                            <reg name="rbx" bitsize="64" regnum="1" type="code_ptr" group="general"/>
6799451b44SJordan Rupprecht                            <reg name="rsi" bitsize="64" regnum="2" type="code_ptr" group="general"/>
6899451b44SJordan Rupprecht                            <reg name="rip" bitsize="64" regnum="3" type="code_ptr" group="general" altname="pc" generic="pc"/>
6999451b44SJordan Rupprecht                          </feature>
70*2238dcc3SJonas Devlieghere                        </target>""",
71*2238dcc3SJonas Devlieghere                        False,
72*2238dcc3SJonas Devlieghere                    )
7399451b44SJordan Rupprecht                else:
7499451b44SJordan Rupprecht                    return None, False
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        self.server.responder = MyResponder()
77*2238dcc3SJonas Devlieghere        target = self.dbg.CreateTarget("")
7899451b44SJordan Rupprecht        if self.TraceOn():
7999451b44SJordan Rupprecht            self.runCmd("log enable gdb-remote packets")
80*2238dcc3SJonas Devlieghere            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))
8199451b44SJordan Rupprecht        process = self.connect(target)
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht        thread = process.GetThreadAtIndex(0)
8499451b44SJordan Rupprecht        frame = thread.GetFrameAtIndex(0)
8599451b44SJordan Rupprecht        rax = frame.FindRegister("rax").GetValueAsUnsigned()
8699451b44SJordan Rupprecht        rbx = frame.FindRegister("rbx").GetValueAsUnsigned()
8799451b44SJordan Rupprecht        rsi = frame.FindRegister("rsi").GetValueAsUnsigned()
8899451b44SJordan Rupprecht        pc = frame.GetPC()
8999451b44SJordan Rupprecht        rip = frame.FindRegister("rip").GetValueAsUnsigned()
9099451b44SJordan Rupprecht
9199451b44SJordan Rupprecht        if self.TraceOn():
92*2238dcc3SJonas Devlieghere            print(
93*2238dcc3SJonas Devlieghere                "Register values: rax == 0x%x, rbx == 0x%x, rsi == 0x%x, pc == 0x%x, rip == 0x%x"
94*2238dcc3SJonas Devlieghere                % (rax, rbx, rsi, pc, rip)
95*2238dcc3SJonas Devlieghere            )
9699451b44SJordan Rupprecht
97*2238dcc3SJonas Devlieghere        self.assertEqual(rax, 0xFFFFFFE03C778278)
9899451b44SJordan Rupprecht        self.assertEqual(rbx, 0x8877665544332211)
99*2238dcc3SJonas Devlieghere        self.assertEqual(rsi, 0x00007FFEEB2548C0)
100*2238dcc3SJonas Devlieghere        self.assertEqual(pc, 0x10001BC00)
101*2238dcc3SJonas Devlieghere        self.assertEqual(rip, 0x10001BC00)
102