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