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