xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
1import lldb
2from lldbsuite.test.lldbtest import *
3from lldbsuite.test.decorators import *
4from lldbsuite.test.gdbclientutils import *
5from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
6
7# This test ensures that LLDB correctly handles packets sent by MSPDebug.
8# https://github.com/dlbeer/mspdebug
9
10
11class MyResponder(MockGDBServerResponder):
12    def qSupported(self, client_supported):
13        return "PacketSize=4000"
14
15    def setBreakpoint(self, packet):
16        return "OK"
17
18    def stopPackets():
19        # Registers 3 to 15 are empty
20        regs3to15 = "".join("%02x:%s;" % (i, "00000000") for i in range(3, 16))
21        yield "T0500:00050000;01:00000000;02:00000000;" + regs3to15
22        yield "T0500:10050000;01:baff0000;02:05000000;" + regs3to15
23        yield "T0500:16050000;01:baff0000;02:05000000;" + regs3to15
24
25    stopPacket = stopPackets()
26
27    def haltReason(self):
28        return next(self.stopPacket)
29
30    def cont(self):
31        return self.haltReason()
32
33    # Memory dump
34    def readMemory(self, addr, length):
35        # Program memory
36        if addr == 0x0400:
37            return (
38                ("ff" * 256)
39                + "3140c0ff0c43b0121c05b01281010000b240d2043c051c423c0530413180020081430000b01210053150020030411c4330413c402a0030410c433041"
40                + ("ff" * 196)
41            )
42        # Stack contents
43        if addr == 0xFE00:
44            return ("ff" * 442) + "280500000a05" + ("ff" * 62) + "0005"
45
46
47class TestMSP430MSPDebug(GDBRemoteTestBase):
48    @skipIfLLVMTargetMissing("MSP430")
49    def test(self):
50        """
51        Test LLDB's MSP430 functionality.
52        """
53        target = self.createTarget("msp430.yaml")
54        self.server.responder = MyResponder()
55
56        if self.TraceOn():
57            self.runCmd("log enable gdb-remote packets")
58            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))
59
60        process = self.connect(target)
61        lldbutil.expect_state_changes(
62            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
63        )
64        num_threads = len(process.threads)
65        self.assertEqual(num_threads, 1, "Only one thread")
66        thread = process.GetThreadAtIndex(0)
67
68        # Test if a breakpoint can be set
69        bp = target.BreakpointCreateByName("func")
70        self.assertTrue(bp.IsValid())
71        bp.SetEnabled(True)
72        self.assertTrue(bp.IsEnabled())
73
74        # Test if the breakpoint address is resolved correctly
75        self.assertEqual(bp.GetNumLocations(), 1, "Only one location")
76        bp_loc = bp.GetLocationAtIndex(0)
77        self.assertEqual(
78            bp_loc.GetAddress().GetLoadAddress(target), 0x510, "Address of main"
79        )
80
81        # Test if the process stops at the breakpoint
82        process.Continue()
83        self.assertStopReason(
84            thread.GetStopReason(), lldb.eStopReasonBreakpoint, "Hit a breakpoint"
85        )
86
87        # Check if disassembler works and the current function is "func"
88        func = thread.GetFrameAtIndex(0).GetFunction()
89        insts = func.GetInstructions(target)
90        inst = insts.GetInstructionAtIndex(0)
91        self.assertEqual(inst.GetMnemonic(target), "mov")
92        self.assertEqual(inst.GetOperands(target), "#1234, &1340")
93
94        # Test if thread can step a single instruction
95        thread.StepInstruction(False)
96        self.assertEqual(
97            thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(target),
98            0x516,
99            "Address of the next instruction",
100        )
101
102        # Test if registers are being set correctly
103        registerSet = thread.GetFrameAtIndex(0).GetRegisters().GetValueAtIndex(0)
104        reg_val_dict = {
105            "pc": 0x0516,
106            "sp": 0xFFBA,
107            "r2": 0x0005,
108            "r3": 0x0000,
109            "fp": 0x0000,
110            "r5": 0x0000,
111            "r6": 0x0000,
112            "r7": 0x0000,
113            "r8": 0x0000,
114            "r9": 0x0000,
115            "r10": 0x0000,
116            "r11": 0x0000,
117            "r12": 0x0000,
118            "r13": 0x0000,
119            "r14": 0x0000,
120            "r15": 0x0000,
121        }
122        for reg in registerSet:
123            self.assertEqual(reg.GetValueAsUnsigned(), reg_val_dict[reg.GetName()])
124
125        # Check if backtracing works:
126        self.assertGreaterEqual(len(thread.frames), 3)
127        crt0_addr = thread.GetFrameAtIndex(2).GetPCAddress().GetLoadAddress(target)
128        self.assertEqual(crt0_addr, 0x50A)
129