1from __future__ import print_function
2import lldb
3import time
4from lldbsuite.test.lldbtest import *
5from lldbsuite.test.decorators import *
6from gdbclientutils import *
7
8class TestRegDefinitionInParts(GDBRemoteTestBase):
9
10    @skipIfXmlSupportMissing
11    @skipIfRemote
12    def test(self):
13        """
14        Test that lldb correctly fetches the target definition file
15        in multiple chunks if the remote server only provides the
16        content in small parts, and the small parts it provides is
17        smaller than the maximum packet size that it declared at
18        the start of the debug session.  qemu does this.
19        """
20        class MyResponder(MockGDBServerResponder):
21
22            def qXferRead(self, obj, annex, offset, length):
23                if annex == "target.xml":
24                    return """<?xml version="1.0"?>
25                              <!DOCTYPE feature SYSTEM "gdb-target.dtd">
26                              <target version="1.0">
27                              <architecture>i386:x86-64</architecture>
28                              <xi:include href="i386-64bit-core.xml"/>
29                              </target>""", False
30
31                if annex == "i386-64bit-core.xml" and offset == 0:
32                    return """<?xml version="1.0"?>
33<!-- Copyright (C) 2010-2015 Free Software Foundation, Inc.
34
35     Copying and distribution of this file, with or without modification,
36     are permitted in any medium without royalty provided the copyright
37     notice and this notice are preserved.  -->
38
39<!DOCTYPE feature SYSTEM "gdb-target.dtd">
40<feature name="org.gnu.gdb.i386.core">
41  <flags id="i386_eflags" size="4">
42    <field name="CF" start="0" end="0"/>
43    <field name="" start="1" end="1"/>
44    <field name="PF" start="2" end="2"/>
45    <field name="AF" start="4" end="4"/>
46    <field name="ZF" start="6" end="6"/>
47    <field name="SF" start="7" end="7"/>
48    <field name="TF" start="8" end="8"/>
49    <field name="IF" start="9" end="9"/>
50    <field name="DF" start="10" end="10"/>
51    <field name="OF" start="11" end="11"/>
52    <field name="NT" start="14" end="14"/>
53    <field name="RF" start="16" end="16"/>
54    <field name="VM" start="17" end="17"/>
55    <field name="AC" start="18" end="18"/>
56    <field name="VIF" start="19" end="19"/>
57    <field name="VIP" start="20" end="20"/>
58    <field name="ID" start="21" end="21"/>
59  </flags>
60
61  <reg name="rax" bitsize="64" type="int64"/>
62  <reg name="rbx" bitsize="64" type="int64"/>
63  <reg name="rcx" bitsize="64" type="int64"/>
64  <reg name="rdx" bitsize="64" type="int64"/>
65  <reg name="rsi" bitsize="64" type="int64"/>
66  <reg name="rdi" bitsize="64" type="int64"/>
67  <reg name="rbp" bitsize="64" type="data_ptr"/>
68  <reg name="rsp" bitsize="64" type="data_ptr"/>
69  <reg name="r8" bitsize="64" type="int64"/>
70  <reg name="r9" bitsize="64" type="int64"/>
71  <reg name="r10" bitsize="64" type="int64"/>
72  <reg name="r11" bitsize="64" type="int64"/>
73  <reg name="r12" bitsize="64" type="int64"/>
74  <reg name="r13" bitsize="64" type="int64"/>
75  <reg name="r14" bitsize="64" type="int64"/>
76  <reg name="r15" bitsize="64" type="int64"/>
77
78  <reg name="rip" bitsize="64" type="code_ptr"/>
79  <reg name="eflags" bitsize="32" type="i386_eflags"/>
80  <reg name="cs" bitsize="32" type="int32"/>
81  <reg name="ss" bitsize="32" ty""", True
82
83                if annex == "i386-64bit-core.xml" and offset == 2045:
84                    return """pe="int32"/>
85  <reg name="ds" bitsize="32" type="int32"/>
86  <reg name="es" bitsize="32" type="int32"/>
87  <reg name="fs" bitsize="32" type="int32"/>
88  <reg name="gs" bitsize="32" type="int32"/>
89
90  <reg name="st0" bitsize="80" type="i387_ext"/>
91  <reg name="st1" bitsize="80" type="i387_ext"/>
92  <reg name="st2" bitsize="80" type="i387_ext"/>
93  <reg name="st3" bitsize="80" type="i387_ext"/>
94  <reg name="st4" bitsize="80" type="i387_ext"/>
95  <reg name="st5" bitsize="80" type="i387_ext"/>
96  <reg name="st6" bitsize="80" type="i387_ext"/>
97  <reg name="st7" bitsize="80" type="i387_ext"/>
98
99  <reg name="fctrl" bitsize="32" type="int" group="float"/>
100  <reg name="fstat" bitsize="32" type="int" group="float"/>
101  <reg name="ftag" bitsize="32" type="int" group="float"/>
102  <reg name="fiseg" bitsize="32" type="int" group="float"/>
103  <reg name="fioff" bitsize="32" type="int" group="float"/>
104  <reg name="foseg" bitsize="32" type="int" group="float"/>
105  <reg name="fooff" bitsize="32" type="int" group="float"/>
106  <reg name="fop" bitsize="32" type="int" group="float"/>
107</feature>""", False
108
109                return None, False
110
111            def readRegister(self, regnum):
112                return ""
113
114            def readRegisters(self):
115                return "0600000000000000c0b7c00080fffffff021c60080ffffff1a00000000000000020000000000000078b7c00080ffffff203f8ca090ffffff103f8ca090ffffff3025990a80ffffff809698000000000070009f0a80ffffff020000000000000000eae10080ffffff00000000000000001822d74f1a00000078b7c00080ffffff0e12410080ffff004602000011111111222222223333333300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000"
116
117            def haltReason(self):
118                return "T02thread:dead;threads:dead;"
119
120            def qfThreadInfo(self):
121                return "mdead"
122
123            def qC(self):
124                return ""
125
126            def qSupported(self, client_supported):
127                return "PacketSize=1000;qXfer:features:read+"
128
129            def QThreadSuffixSupported(self):
130                return "OK"
131
132            def QListThreadsInStopReply(self):
133                return "OK"
134
135        self.server.responder = MyResponder()
136        if self.TraceOn():
137            self.runCmd("log enable gdb-remote packets")
138            time.sleep(10)
139            self.addTearDownHook(
140                    lambda: self.runCmd("log disable gdb-remote packets"))
141
142        target = self.dbg.CreateTargetWithFileAndArch(None, None)
143
144        process = self.connect(target)
145
146        if self.TraceOn():
147            interp = self.dbg.GetCommandInterpreter()
148            result = lldb.SBCommandReturnObject()
149            interp.HandleCommand("target list", result)
150            print(result.GetOutput())
151
152        rip_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("rip")
153        self.assertEqual(rip_valobj.GetValueAsUnsigned(), 0x00ffff800041120e)
154
155        ss_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("ss")
156        self.assertEqual(ss_valobj.GetValueAsUnsigned(), 0x22222222)
157
158        if self.TraceOn():
159            print("rip is 0x%x" % rip_valobj.GetValueAsUnsigned())
160            print("ss is 0x%x" % ss_valobj.GetValueAsUnsigned())
161