| import lldb | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.gdbclientutils import * | |
| from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase | |
| # This test ensures that LLDB correctly handles packets sent by MSPDebug. | |
| # https://github.com/dlbeer/mspdebug | |
| class MyResponder(MockGDBServerResponder): | |
| def qSupported(self, client_supported): | |
| return "PacketSize=4000" | |
| def setBreakpoint(self, packet): | |
| return "OK" | |
| def clearBreakpoint(self, packet): | |
| return "OK" | |
| def stopPackets(): | |
| # Registers 3 to 15 are empty | |
| regs3to15 = "".join("%02x:%s;" % (i, "00000000") for i in range(3, 16)) | |
| yield "T0500:00050000;01:00000000;02:00000000;" + regs3to15 | |
| yield "T0500:10050000;01:baff0000;02:05000000;" + regs3to15 | |
| yield "T0500:16050000;01:baff0000;02:05000000;" + regs3to15 | |
| stopPacket = stopPackets() | |
| def haltReason(self): | |
| return next(self.stopPacket) | |
| def cont(self): | |
| return self.haltReason() | |
| # Memory dump | |
| def readMemory(self, addr, length): | |
| # Program memory | |
| if addr == 0x0400: | |
| return ( | |
| ("ff" * 256) | |
| + "3140c0ff0c43b0121c05b01281010000b240d2043c051c423c0530413180020081430000b01210053150020030411c4330413c402a0030410c433041" | |
| + ("ff" * 196) | |
| ) | |
| # Stack contents | |
| if addr == 0xFE00: | |
| return ("ff" * 442) + "280500000a05" + ("ff" * 62) + "0005" | |
| class TestMSP430MSPDebug(GDBRemoteTestBase): | |
| @skipIfLLVMTargetMissing("MSP430") | |
| def test(self): | |
| """ | |
| Test LLDB's MSP430 functionality. | |
| """ | |
| target = self.createTarget("msp430.yaml") | |
| self.server.responder = MyResponder() | |
| if self.TraceOn(): | |
| self.runCmd("log enable gdb-remote packets") | |
| self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets")) | |
| process = self.connect(target) | |
| lldbutil.expect_state_changes( | |
| self, self.dbg.GetListener(), process, [lldb.eStateStopped] | |
| ) | |
| num_threads = len(process.threads) | |
| self.assertEqual(num_threads, 1, "Only one thread") | |
| thread = process.GetThreadAtIndex(0) | |
| # Test if a breakpoint can be set | |
| bp = target.BreakpointCreateByName("func") | |
| self.assertTrue(bp.IsValid()) | |
| bp.SetEnabled(True) | |
| self.assertTrue(bp.IsEnabled()) | |
| # Test if the breakpoint address is resolved correctly | |
| self.assertEqual(bp.GetNumLocations(), 1, "Only one location") | |
| bp_loc = bp.GetLocationAtIndex(0) | |
| self.assertEqual( | |
| bp_loc.GetAddress().GetLoadAddress(target), 0x510, "Address of main" | |
| ) | |
| # Test if the process stops at the breakpoint | |
| process.Continue() | |
| self.assertStopReason( | |
| thread.GetStopReason(), lldb.eStopReasonBreakpoint, "Hit a breakpoint" | |
| ) | |
| # Check if disassembler works and the current function is "func" | |
| func = thread.GetFrameAtIndex(0).GetFunction() | |
| insts = func.GetInstructions(target) | |
| inst = insts.GetInstructionAtIndex(0) | |
| self.assertEqual(inst.GetMnemonic(target), "mov") | |
| self.assertEqual(inst.GetOperands(target), "#1234, &1340") | |
| # Test if thread can step a single instruction | |
| thread.StepInstruction(False) | |
| self.assertEqual( | |
| thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(target), | |
| 0x516, | |
| "Address of the next instruction", | |
| ) | |
| # Test if registers are being set correctly | |
| registerSet = thread.GetFrameAtIndex(0).GetRegisters().GetValueAtIndex(0) | |
| reg_val_dict = { | |
| "pc": 0x0516, | |
| "sp": 0xFFBA, | |
| "r2": 0x0005, | |
| "r3": 0x0000, | |
| "fp": 0x0000, | |
| "r5": 0x0000, | |
| "r6": 0x0000, | |
| "r7": 0x0000, | |
| "r8": 0x0000, | |
| "r9": 0x0000, | |
| "r10": 0x0000, | |
| "r11": 0x0000, | |
| "r12": 0x0000, | |
| "r13": 0x0000, | |
| "r14": 0x0000, | |
| "r15": 0x0000, | |
| } | |
| for reg in registerSet: | |
| self.assertEqual(reg.GetValueAsUnsigned(), reg_val_dict[reg.GetName()]) | |
| # Check if backtracing works: | |
| self.assertGreaterEqual(len(thread.frames), 3) | |
| crt0_addr = thread.GetFrameAtIndex(2).GetPCAddress().GetLoadAddress(target) | |
| self.assertEqual(crt0_addr, 0x50A) |