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