1 use super::copy_range_to_buf;
2 use crate::emu::Emu;
3 use gdbstub::target;
4 use gdbstub::target::TargetError;
5 use gdbstub::target::TargetResult;
6 
7 impl target::ext::target_description_xml_override::TargetDescriptionXmlOverride for Emu {
target_description_xml( &self, annex: &[u8], offset: u64, length: usize, buf: &mut [u8], ) -> TargetResult<usize, Self>8     fn target_description_xml(
9         &self,
10         annex: &[u8],
11         offset: u64,
12         length: usize,
13         buf: &mut [u8],
14     ) -> TargetResult<usize, Self> {
15         let xml = match annex {
16             b"target.xml" => TARGET_XML.trim(),
17             b"extra.xml" => EXTRA_XML.trim(),
18             _ => return Err(TargetError::NonFatal),
19         };
20 
21         Ok(copy_range_to_buf(
22             xml.trim().as_bytes(),
23             offset,
24             length,
25             buf,
26         ))
27     }
28 }
29 
30 const TARGET_XML: &str = r#"
31 <?xml version="1.0"?>
32 <!DOCTYPE target SYSTEM "gdb-target.dtd">
33 <target version="1.0">
34     <architecture>armv4t</architecture>
35     <feature name="org.gnu.gdb.arm.core">
36         <vector id="padding" type="uint32" count="25"/>
37 
38         <reg name="r0" bitsize="32" type="uint32"/>
39         <reg name="r1" bitsize="32" type="uint32"/>
40         <reg name="r2" bitsize="32" type="uint32"/>
41         <reg name="r3" bitsize="32" type="uint32"/>
42         <reg name="r4" bitsize="32" type="uint32"/>
43         <reg name="r5" bitsize="32" type="uint32"/>
44         <reg name="r6" bitsize="32" type="uint32"/>
45         <reg name="r7" bitsize="32" type="uint32"/>
46         <reg name="r8" bitsize="32" type="uint32"/>
47         <reg name="r9" bitsize="32" type="uint32"/>
48         <reg name="r10" bitsize="32" type="uint32"/>
49         <reg name="r11" bitsize="32" type="uint32"/>
50         <reg name="r12" bitsize="32" type="uint32"/>
51         <reg name="sp" bitsize="32" type="data_ptr"/>
52         <reg name="lr" bitsize="32"/>
53         <reg name="pc" bitsize="32" type="code_ptr"/>
54 
55         <!--
56             For some reason, my version of `gdb-multiarch` doesn't seem to
57             respect "regnum", and will not parse this custom target.xml unless I
58             manually include the padding bytes in the target description.
59 
60             On the bright side, AFAIK, there aren't all that many architectures
61             that use padding bytes. Heck, the only reason armv4t uses padding is
62             for historical reasons (see comment below).
63 
64             Odds are if you're defining your own custom arch, you won't run into
65             this issue, since you can just lay out all the registers in the
66             correct order.
67         -->
68         <reg name="padding" type="padding" bitsize="32"/>
69 
70         <!-- The CPSR is register 25, rather than register 16, because
71         the FPA registers historically were placed between the PC
72         and the CPSR in the "g" packet. -->
73         <reg name="cpsr" bitsize="32" regnum="25"/>
74     </feature>
75     <xi:include href="extra.xml"/>
76 </target>
77 "#;
78 
79 const EXTRA_XML: &str = r#"
80 <?xml version="1.0"?>
81 <!DOCTYPE target SYSTEM "gdb-target.dtd">
82 <feature name="custom-armv4t-extension">
83     <!--
84         maps to a simple scratch register within the emulator. the GDB
85         client can read the register using `p $custom` and set it using
86         `set $custom=1337`
87     -->
88     <reg name="custom" bitsize="32" type="uint32"/>
89 
90     <!--
91         pseudo-register that return the current time when read.
92 
93         notably, i've set up the target to NOT send this register as part of
94         the regular register list, which means that GDB will fetch/update
95         this register via the 'p' and 'P' packets respectively
96     -->
97     <reg name="time" bitsize="32" type="uint32"/>
98 
99     <!--
100         pseudo-register that is always unavailable.
101 
102         it is supposed to be reported as 'x'-ed bytes in replies to 'p' packets
103         and shown by the GDB client as "<unavailable>".
104     -->
105     <reg name="unavailable" bitsize="32" type="uint32"/>
106 </feature>
107 "#;
108