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    @skipIfXmlSupportMissing
11    @skipIfRemote
12    def test(self):
13        """
14        Test lldb's parsing of SEGGER J-Link v6.54 register
15        definition for a Cortex M-4 dev board, and the fact
16        that the J-Link only supports g/G for reading/writing
17        register AND the J-Link v6.54 doesn't provide anything
18        but the general purpose registers."""
19        class MyResponder(MockGDBServerResponder):
20
21            def qXferRead(self, obj, annex, offset, length):
22                if annex == "target.xml":
23                    return """<?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>""", False
112                else:
113                    return None, False
114
115            def readRegister(self, regnum):
116                return "E01"
117
118            # Initial r1 bytes, in little-endian order
119            r1_bytes = "01000000"
120
121            ## readRegisters only provides reg values up through xpsr (0x61000000)
122            ## it doesn't send up any of the exception registers or floating point
123            ## registers that the above register xml describes.
124            def readRegisters(self):
125                return "00000000" + self.r1_bytes + "010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"
126
127            ## the J-Link accepts a register write packet with just the GPRs
128            ## defined.
129            def writeRegisters(self, registers_hex):
130                # Check that lldb returns the full 704 hex-byte register context,
131                # or the 136 hex-byte general purpose register reg ctx.
132                if len(registers_hex) != 704 and len(register_hex) != 136:
133                    return "E06"
134                if registers_hex.startswith("0000000044332211010000000100000001000000000000008c080020a872012000000000a0790120000000008065012041ad0008a0720120692a00089e26000800000061"):
135                    self.r1_bytes = "44332211"
136                    return "OK"
137                else:
138                    return "E07"
139
140            def haltReason(self):
141                return "S05"
142
143            def qfThreadInfo(self):
144                return "mdead"
145
146            def qC(self):
147                return ""
148
149            def qSupported(self, client_supported):
150                return "PacketSize=4000;qXfer:memory-map:read-;QStartNoAckMode+;hwbreak+;qXfer:features:read+"
151
152            def QThreadSuffixSupported(self):
153                return "OK"
154
155            def QListThreadsInStopReply(self):
156                return "OK"
157
158        self.server.responder = MyResponder()
159        if self.TraceOn():
160            self.runCmd("log enable gdb-remote packets")
161            self.addTearDownHook(
162                    lambda: self.runCmd("log disable gdb-remote packets"))
163
164        self.dbg.SetDefaultArchitecture("armv7em")
165        target = self.dbg.CreateTargetWithFileAndArch(None, None)
166
167        process = self.connect(target)
168
169        if self.TraceOn():
170            interp = self.dbg.GetCommandInterpreter()
171            result = lldb.SBCommandReturnObject()
172            interp.HandleCommand("target list", result)
173            print(result.GetOutput())
174
175        r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r1")
176        self.assertEqual(r1_valobj.GetValueAsUnsigned(), 1)
177
178        pc_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("pc")
179        self.assertEqual(pc_valobj.GetValueAsUnsigned(), 0x0800269e)
180
181        xpsr_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("xpsr")
182        self.assertEqual(xpsr_valobj.GetValueAsUnsigned(), 0x61000000)
183
184        msp_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("msp")
185        err = msp_valobj.GetError()
186        self.assertTrue(err.Fail(), "lldb should not be able to fetch the msp register")
187
188        val = b'\x11\x22\x33\x44'
189        error = lldb.SBError()
190        data = lldb.SBData()
191        data.SetData(error, val, lldb.eByteOrderBig, 4)
192        self.assertEqual(r1_valobj.SetData(data, error), True)
193        self.assertSuccess(error)
194
195        r1_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r1")
196        self.assertEqual(r1_valobj.GetValueAsUnsigned(), 0x11223344)
197
198