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