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
8class TestJLink6Armv7RegisterDefinition(GDBRemoteTestBase):
9    @skipIfXmlSupportMissing
10    @skipIfRemote
11    def test(self):
12        """
13        Test lldb's parsing of SEGGER J-Link v6.54 register
14        definition for a Cortex M-4 dev board, and the fact
15        that the J-Link only supports g/G for reading/writing
16        register AND the J-Link v6.54 doesn't provide anything
17        but the general purpose registers."""
18
19        class MyResponder(MockGDBServerResponder):
20            def qXferRead(self, obj, annex, offset, length):
21                if annex == "target.xml":
22                    return (
23                        """<?xml version="1.0"?>
24<!-- Copyright (C) 2008 Free Software Foundation, Inc.
25
26     Copying and distribution of this file, with or without modification,
27     are permitted in any medium without royalty provided the copyright
28     notice and this notice are preserved.  -->
29
30<!DOCTYPE feature SYSTEM "gdb-target.dtd">
31<target version="1.0">
32  <architecture>arm</architecture>
33  <feature name="org.gnu.gdb.arm.m-profile">
34    <reg name="r0" bitsize="32" regnum="0" type="uint32" group="general"/>
35    <reg name="r1" bitsize="32" regnum="1" type="uint32" group="general"/>
36    <reg name="r2" bitsize="32" regnum="2" type="uint32" group="general"/>
37    <reg name="r3" bitsize="32" regnum="3" type="uint32" group="general"/>
38    <reg name="r4" bitsize="32" regnum="4" type="uint32" group="general"/>
39    <reg name="r5" bitsize="32" regnum="5" type="uint32" group="general"/>
40    <reg name="r6" bitsize="32" regnum="6" type="uint32" group="general"/>
41    <reg name="r7" bitsize="32" regnum="7" type="uint32" group="general"/>
42    <reg name="r8" bitsize="32" regnum="8" type="uint32" group="general"/>
43    <reg name="r9" bitsize="32" regnum="9" type="uint32" group="general"/>
44    <reg name="r10" bitsize="32" regnum="10" type="uint32" group="general"/>
45    <reg name="r11" bitsize="32" regnum="11" type="uint32" group="general"/>
46    <reg name="r12" bitsize="32" regnum="12" type="uint32" group="general"/>
47    <reg name="sp" bitsize="32" regnum="13" type="data_ptr" group="general"/>
48    <reg name="lr" bitsize="32" regnum="14" type="uint32" group="general"/>
49    <reg name="pc" bitsize="32" regnum="15" type="code_ptr" group="general"/>
50    <reg name="xpsr" bitsize="32" regnum="25" type="uint32" group="general"/>
51  </feature>
52  <feature name="org.gnu.gdb.arm.m-system">
53    <reg name="msp" bitsize="32" regnum="26" type="uint32" group="general"/>
54    <reg name="psp" bitsize="32" regnum="27" type="uint32" group="general"/>
55    <reg name="primask" bitsize="32" regnum="28" type="uint32" group="general"/>
56    <reg name="basepri" bitsize="32" regnum="29" type="uint32" group="general"/>
57    <reg name="faultmask" bitsize="32" regnum="30" type="uint32" group="general"/>
58    <reg name="control" bitsize="32" regnum="31" type="uint32" group="general"/>
59  </feature>
60  <feature name="org.gnu.gdb.arm.m-float">
61    <reg name="fpscr" bitsize="32" regnum="32" type="uint32" group="float"/>
62    <reg name="s0" bitsize="32" regnum="33" type="float" group="float"/>
63    <reg name="s1" bitsize="32" regnum="34" type="float" group="float"/>
64    <reg name="s2" bitsize="32" regnum="35" type="float" group="float"/>
65    <reg name="s3" bitsize="32" regnum="36" type="float" group="float"/>
66    <reg name="s4" bitsize="32" regnum="37" type="float" group="float"/>
67    <reg name="s5" bitsize="32" regnum="38" type="float" group="float"/>
68    <reg name="s6" bitsize="32" regnum="39" type="float" group="float"/>
69    <reg name="s7" bitsize="32" regnum="40" type="float" group="float"/>
70    <reg name="s8" bitsize="32" regnum="41" type="float" group="float"/>
71    <reg name="s9" bitsize="32" regnum="42" type="float" group="float"/>
72    <reg name="s10" bitsize="32" regnum="43" type="float" group="float"/>
73    <reg name="s11" bitsize="32" regnum="44" type="float" group="float"/>
74    <reg name="s12" bitsize="32" regnum="45" type="float" group="float"/>
75    <reg name="s13" bitsize="32" regnum="46" type="float" group="float"/>
76    <reg name="s14" bitsize="32" regnum="47" type="float" group="float"/>
77    <reg name="s15" bitsize="32" regnum="48" type="float" group="float"/>
78    <reg name="s16" bitsize="32" regnum="49" type="float" group="float"/>
79    <reg name="s17" bitsize="32" regnum="50" type="float" group="float"/>
80    <reg name="s18" bitsize="32" regnum="51" type="float" group="float"/>
81    <reg name="s19" bitsize="32" regnum="52" type="float" group="float"/>
82    <reg name="s20" bitsize="32" regnum="53" type="float" group="float"/>
83    <reg name="s21" bitsize="32" regnum="54" type="float" group="float"/>
84    <reg name="s22" bitsize="32" regnum="55" type="float" group="float"/>
85    <reg name="s23" bitsize="32" regnum="56" type="float" group="float"/>
86    <reg name="s24" bitsize="32" regnum="57" type="float" group="float"/>
87    <reg name="s25" bitsize="32" regnum="58" type="float" group="float"/>
88    <reg name="s26" bitsize="32" regnum="59" type="float" group="float"/>
89    <reg name="s27" bitsize="32" regnum="60" type="float" group="float"/>
90    <reg name="s28" bitsize="32" regnum="61" type="float" group="float"/>
91    <reg name="s29" bitsize="32" regnum="62" type="float" group="float"/>
92    <reg name="s30" bitsize="32" regnum="63" type="float" group="float"/>
93    <reg name="s31" bitsize="32" regnum="64" type="float" group="float"/>
94    <reg name="d0" bitsize="64" regnum="65" type="ieee_double" group="float"/>
95    <reg name="d1" bitsize="64" regnum="66" type="ieee_double" group="float"/>
96    <reg name="d2" bitsize="64" regnum="67" type="ieee_double" group="float"/>
97    <reg name="d3" bitsize="64" regnum="68" type="ieee_double" group="float"/>
98    <reg name="d4" bitsize="64" regnum="69" type="ieee_double" group="float"/>
99    <reg name="d5" bitsize="64" regnum="70" type="ieee_double" group="float"/>
100    <reg name="d6" bitsize="64" regnum="71" type="ieee_double" group="float"/>
101    <reg name="d7" bitsize="64" regnum="72" type="ieee_double" group="float"/>
102    <reg name="d8" bitsize="64" regnum="73" type="ieee_double" group="float"/>
103    <reg name="d9" bitsize="64" regnum="74" type="ieee_double" group="float"/>
104    <reg name="d10" bitsize="64" regnum="75" type="ieee_double" group="float"/>
105    <reg name="d11" bitsize="64" regnum="76" type="ieee_double" group="float"/>
106    <reg name="d12" bitsize="64" regnum="77" type="ieee_double" group="float"/>
107    <reg name="d13" bitsize="64" regnum="78" type="ieee_double" group="float"/>
108    <reg name="d14" bitsize="64" regnum="79" type="ieee_double" group="float"/>
109    <reg name="d15" bitsize="64" regnum="80" type="ieee_double" group="float"/>
110  </feature>
111</target>""",
112                        False,
113                    )
114                else:
115                    return None, False
116
117            def readRegister(self, regnum):
118                return "E01"
119
120            # Initial r1 bytes, in little-endian order
121            r1_bytes = "01000000"
122
123            ## readRegisters only provides reg values up through xpsr (0x61000000)
124            ## it doesn't send up any of the exception registers or floating point
125            ## registers that the above register xml describes.
126            def readRegisters(self):
127                return (
128                    "00000000"
129                    + self.r1_bytes
130                    + "010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"
131                )
132
133            ## the J-Link accepts a register write packet with just the GPRs
134            ## defined.
135            def writeRegisters(self, registers_hex):
136                # Check that lldb returns the full 704 hex-byte register context,
137                # or the 136 hex-byte general purpose register reg ctx.
138                if len(registers_hex) != 704 and len(register_hex) != 136:
139                    return "E06"
140                if registers_hex.startswith(
141                    "0000000044332211010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"
142                ):
143                    self.r1_bytes = "44332211"
144                    return "OK"
145                else:
146                    return "E07"
147
148            def haltReason(self):
149                return "S05"
150
151            def qfThreadInfo(self):
152                return "mdead"
153
154            def qC(self):
155                return ""
156
157            def qSupported(self, client_supported):
158                return "PacketSize=4000;qXfer:memory-map:read-;QStartNoAckMode+;hwbreak+;qXfer:features:read+"
159
160            def QThreadSuffixSupported(self):
161                return "OK"
162
163            def QListThreadsInStopReply(self):
164                return "OK"
165
166        self.server.responder = MyResponder()
167        if self.TraceOn():
168            self.runCmd("log enable gdb-remote packets")
169            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))
170
171        self.dbg.SetDefaultArchitecture("armv7em")
172        target = self.dbg.CreateTargetWithFileAndArch(None, None)
173
174        process = self.connect(target)
175
176        if self.TraceOn():
177            interp = self.dbg.GetCommandInterpreter()
178            result = lldb.SBCommandReturnObject()
179            interp.HandleCommand("target list", result)
180            print(result.GetOutput())
181
182        r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r1")
183        self.assertEqual(r1_valobj.GetValueAsUnsigned(), 1)
184
185        pc_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("pc")
186        self.assertEqual(pc_valobj.GetValueAsUnsigned(), 0x0800269E)
187
188        xpsr_valobj = (
189            process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("xpsr")
190        )
191        self.assertEqual(xpsr_valobj.GetValueAsUnsigned(), 0x61000000)
192
193        msp_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("msp")
194        err = msp_valobj.GetError()
195        self.assertTrue(err.Fail(), "lldb should not be able to fetch the msp register")
196
197        val = b"\x11\x22\x33\x44"
198        error = lldb.SBError()
199        data = lldb.SBData()
200        data.SetData(error, val, lldb.eByteOrderBig, 4)
201        self.assertTrue(r1_valobj.SetData(data, error))
202        self.assertSuccess(error)
203
204        r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r1")
205        self.assertEqual(r1_valobj.GetValueAsUnsigned(), 0x11223344)
206