xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestMSP430MSPDebug.py (revision 9c2468821ec51defd09c246fea4a47886fff8c01)
181beb15dSIlya Kuklinimport lldb
281beb15dSIlya Kuklinfrom lldbsuite.test.lldbtest import *
381beb15dSIlya Kuklinfrom lldbsuite.test.decorators import *
481beb15dSIlya Kuklinfrom lldbsuite.test.gdbclientutils import *
581beb15dSIlya Kuklinfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
681beb15dSIlya Kuklin
781beb15dSIlya Kuklin# This test ensures that LLDB correctly handles packets sent by MSPDebug.
881beb15dSIlya Kuklin# https://github.com/dlbeer/mspdebug
981beb15dSIlya Kuklin
102238dcc3SJonas Devlieghere
1181beb15dSIlya Kuklinclass MyResponder(MockGDBServerResponder):
1281beb15dSIlya Kuklin    def qSupported(self, client_supported):
1381beb15dSIlya Kuklin        return "PacketSize=4000"
1481beb15dSIlya Kuklin
1581beb15dSIlya Kuklin    def setBreakpoint(self, packet):
1681beb15dSIlya Kuklin        return "OK"
1781beb15dSIlya Kuklin
1881beb15dSIlya Kuklin    def stopPackets():
1981beb15dSIlya Kuklin        # Registers 3 to 15 are empty
202238dcc3SJonas Devlieghere        regs3to15 = "".join("%02x:%s;" % (i, "00000000") for i in range(3, 16))
2181beb15dSIlya Kuklin        yield "T0500:00050000;01:00000000;02:00000000;" + regs3to15
2281beb15dSIlya Kuklin        yield "T0500:10050000;01:baff0000;02:05000000;" + regs3to15
2381beb15dSIlya Kuklin        yield "T0500:16050000;01:baff0000;02:05000000;" + regs3to15
2481beb15dSIlya Kuklin
2581beb15dSIlya Kuklin    stopPacket = stopPackets()
262238dcc3SJonas Devlieghere
2781beb15dSIlya Kuklin    def haltReason(self):
2881beb15dSIlya Kuklin        return next(self.stopPacket)
2981beb15dSIlya Kuklin
3081beb15dSIlya Kuklin    def cont(self):
3181beb15dSIlya Kuklin        return self.haltReason()
3281beb15dSIlya Kuklin
3381beb15dSIlya Kuklin    # Memory dump
3481beb15dSIlya Kuklin    def readMemory(self, addr, length):
3581beb15dSIlya Kuklin        # Program memory
362238dcc3SJonas Devlieghere        if addr == 0x0400:
372238dcc3SJonas Devlieghere            return (
382238dcc3SJonas Devlieghere                ("ff" * 256)
392238dcc3SJonas Devlieghere                + "3140c0ff0c43b0121c05b01281010000b240d2043c051c423c0530413180020081430000b01210053150020030411c4330413c402a0030410c433041"
402238dcc3SJonas Devlieghere                + ("ff" * 196)
412238dcc3SJonas Devlieghere            )
4281beb15dSIlya Kuklin        # Stack contents
432238dcc3SJonas Devlieghere        if addr == 0xFE00:
4481beb15dSIlya Kuklin            return ("ff" * 442) + "280500000a05" + ("ff" * 62) + "0005"
4581beb15dSIlya Kuklin
4681beb15dSIlya Kuklin
472238dcc3SJonas Devlieghereclass TestMSP430MSPDebug(GDBRemoteTestBase):
4881beb15dSIlya Kuklin    @skipIfLLVMTargetMissing("MSP430")
4981beb15dSIlya Kuklin    def test(self):
5081beb15dSIlya Kuklin        """
5181beb15dSIlya Kuklin        Test LLDB's MSP430 functionality.
5281beb15dSIlya Kuklin        """
5381beb15dSIlya Kuklin        target = self.createTarget("msp430.yaml")
5481beb15dSIlya Kuklin        self.server.responder = MyResponder()
5581beb15dSIlya Kuklin
5681beb15dSIlya Kuklin        if self.TraceOn():
5781beb15dSIlya Kuklin            self.runCmd("log enable gdb-remote packets")
582238dcc3SJonas Devlieghere            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))
5981beb15dSIlya Kuklin
6081beb15dSIlya Kuklin        process = self.connect(target)
612238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(
622238dcc3SJonas Devlieghere            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
632238dcc3SJonas Devlieghere        )
6481beb15dSIlya Kuklin        num_threads = len(process.threads)
6581beb15dSIlya Kuklin        self.assertEqual(num_threads, 1, "Only one thread")
6681beb15dSIlya Kuklin        thread = process.GetThreadAtIndex(0)
6781beb15dSIlya Kuklin
6881beb15dSIlya Kuklin        # Test if a breakpoint can be set
6981beb15dSIlya Kuklin        bp = target.BreakpointCreateByName("func")
7081beb15dSIlya Kuklin        self.assertTrue(bp.IsValid())
7181beb15dSIlya Kuklin        bp.SetEnabled(True)
7281beb15dSIlya Kuklin        self.assertTrue(bp.IsEnabled())
7381beb15dSIlya Kuklin
7481beb15dSIlya Kuklin        # Test if the breakpoint address is resolved correctly
7581beb15dSIlya Kuklin        self.assertEqual(bp.GetNumLocations(), 1, "Only one location")
762238dcc3SJonas Devlieghere        bp_loc = bp.GetLocationAtIndex(0)
77*9c246882SJordan Rupprecht        self.assertEqual(
78*9c246882SJordan Rupprecht            bp_loc.GetAddress().GetLoadAddress(target), 0x510, "Address of main"
792238dcc3SJonas Devlieghere        )
8081beb15dSIlya Kuklin
8181beb15dSIlya Kuklin        # Test if the process stops at the breakpoint
8281beb15dSIlya Kuklin        process.Continue()
832238dcc3SJonas Devlieghere        self.assertStopReason(
842238dcc3SJonas Devlieghere            thread.GetStopReason(), lldb.eStopReasonBreakpoint, "Hit a breakpoint"
852238dcc3SJonas Devlieghere        )
8681beb15dSIlya Kuklin
8781beb15dSIlya Kuklin        # Check if disassembler works and the current function is "func"
8881beb15dSIlya Kuklin        func = thread.GetFrameAtIndex(0).GetFunction()
8981beb15dSIlya Kuklin        insts = func.GetInstructions(target)
9081beb15dSIlya Kuklin        inst = insts.GetInstructionAtIndex(0)
9181beb15dSIlya Kuklin        self.assertEqual(inst.GetMnemonic(target), "mov")
9281beb15dSIlya Kuklin        self.assertEqual(inst.GetOperands(target), "#1234, &1340")
9381beb15dSIlya Kuklin
9481beb15dSIlya Kuklin        # Test if thread can step a single instruction
9581beb15dSIlya Kuklin        thread.StepInstruction(False)
96*9c246882SJordan Rupprecht        self.assertEqual(
97*9c246882SJordan Rupprecht            thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(target),
98*9c246882SJordan Rupprecht            0x516,
992238dcc3SJonas Devlieghere            "Address of the next instruction",
1002238dcc3SJonas Devlieghere        )
10181beb15dSIlya Kuklin
10281beb15dSIlya Kuklin        # Test if registers are being set correctly
10381beb15dSIlya Kuklin        registerSet = thread.GetFrameAtIndex(0).GetRegisters().GetValueAtIndex(0)
10481beb15dSIlya Kuklin        reg_val_dict = {
1052238dcc3SJonas Devlieghere            "pc": 0x0516,
1062238dcc3SJonas Devlieghere            "sp": 0xFFBA,
1072238dcc3SJonas Devlieghere            "r2": 0x0005,
1082238dcc3SJonas Devlieghere            "r3": 0x0000,
1092238dcc3SJonas Devlieghere            "fp": 0x0000,
1102238dcc3SJonas Devlieghere            "r5": 0x0000,
1112238dcc3SJonas Devlieghere            "r6": 0x0000,
1122238dcc3SJonas Devlieghere            "r7": 0x0000,
1132238dcc3SJonas Devlieghere            "r8": 0x0000,
1142238dcc3SJonas Devlieghere            "r9": 0x0000,
1152238dcc3SJonas Devlieghere            "r10": 0x0000,
1162238dcc3SJonas Devlieghere            "r11": 0x0000,
1172238dcc3SJonas Devlieghere            "r12": 0x0000,
1182238dcc3SJonas Devlieghere            "r13": 0x0000,
1192238dcc3SJonas Devlieghere            "r14": 0x0000,
1202238dcc3SJonas Devlieghere            "r15": 0x0000,
12181beb15dSIlya Kuklin        }
12281beb15dSIlya Kuklin        for reg in registerSet:
1232238dcc3SJonas Devlieghere            self.assertEqual(reg.GetValueAsUnsigned(), reg_val_dict[reg.GetName()])
12481beb15dSIlya Kuklin
12581beb15dSIlya Kuklin        # Check if backtracing works:
126*9c246882SJordan Rupprecht        self.assertGreaterEqual(len(thread.frames), 3)
12781beb15dSIlya Kuklin        crt0_addr = thread.GetFrameAtIndex(2).GetPCAddress().GetLoadAddress(target)
1282238dcc3SJonas Devlieghere        self.assertEqual(crt0_addr, 0x50A)
129