from __future__ import print_function import lldb from lldbsuite.test.lldbtest import * from lldbsuite.test.decorators import * from gdbclientutils import * class TestJLink6Armv7RegisterDefinition(GDBRemoteTestBase): @skipIfXmlSupportMissing @skipIfRemote def test(self): """ Test lldb's parsing of SEGGER J-Link v6.54 register definition for a Cortex M-4 dev board, and the fact that the J-Link only supports g/G for reading/writing register AND the J-Link v6.54 doesn't provide anything but the general purpose registers.""" class MyResponder(MockGDBServerResponder): def qXferRead(self, obj, annex, offset, length): if annex == "target.xml": return """ arm """, False else: return None, False def readRegister(self, regnum): return "E01" # Initial r1 bytes, in little-endian order r1_bytes = "01000000" ## readRegisters only provides reg values up through xpsr (0x61000000) ## it doesn't send up any of the exception registers or floating point ## registers that the above register xml describes. def readRegisters(self): return "00000000" + self.r1_bytes + "010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061" ## the J-Link accepts a register write packet with just the GPRs ## defined. def writeRegisters(self, registers_hex): # Check that lldb returns the full 704 hex-byte register context, # or the 136 hex-byte general purpose register reg ctx. if len(registers_hex) != 704 and len(register_hex) != 136: return "E06" if registers_hex.startswith("0000000044332211010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"): self.r1_bytes = "44332211" return "OK" else: return "E07" def haltReason(self): return "S05" def qfThreadInfo(self): return "mdead" def qC(self): return "" def qSupported(self, client_supported): return "PacketSize=4000;qXfer:memory-map:read-;QStartNoAckMode+;hwbreak+;qXfer:features:read+" def QThreadSuffixSupported(self): return "OK" def QListThreadsInStopReply(self): return "OK" self.server.responder = MyResponder() if self.TraceOn(): self.runCmd("log enable gdb-remote packets") self.addTearDownHook( lambda: self.runCmd("log disable gdb-remote packets")) self.dbg.SetDefaultArchitecture("armv7em") target = self.dbg.CreateTargetWithFileAndArch(None, None) process = self.connect(target) if self.TraceOn(): interp = self.dbg.GetCommandInterpreter() result = lldb.SBCommandReturnObject() interp.HandleCommand("target list", result) print(result.GetOutput()) r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r1") self.assertEqual(r1_valobj.GetValueAsUnsigned(), 1) pc_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("pc") self.assertEqual(pc_valobj.GetValueAsUnsigned(), 0x0800269e) xpsr_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("xpsr") self.assertEqual(xpsr_valobj.GetValueAsUnsigned(), 0x61000000) msp_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("msp") err = msp_valobj.GetError() self.assertTrue(err.Fail(), "lldb should not be able to fetch the msp register") val = b'\x11\x22\x33\x44' error = lldb.SBError() data = lldb.SBData() data.SetData(error, val, lldb.eByteOrderBig, 4) self.assertEqual(r1_valobj.SetData(data, error), True) self.assertTrue(error.Success()) r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r1") self.assertEqual(r1_valobj.GetValueAsUnsigned(), 0x11223344)