This uses [teyit](https://pypi.org/project/teyit/) to modernize asserts, as recommended by the [unittest release notes](https://docs.python.org/3.12/whatsnew/3.12.html#id3). For example, `assertTrue(a == b)` is replaced with `assertEqual(a, b)`. This produces better error messages, e.g. `error: unexpectedly found 1 and 2 to be different` instead of `error: False`.
129 lines
4.3 KiB
Python
129 lines
4.3 KiB
Python
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 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)
|