1 use super::prelude::*; 2 use crate::protocol::commands::ext::TargetXml; 3 4 use crate::arch::Arch; 5 6 impl<T: Target, C: Connection> GdbStubImpl<T, C> { handle_target_xml( &mut self, res: &mut ResponseWriter<'_, C>, target: &mut T, command: TargetXml<'_>, ) -> Result<HandlerStatus, Error<T::Error, C::Error>>7 pub(crate) fn handle_target_xml( 8 &mut self, 9 res: &mut ResponseWriter<'_, C>, 10 target: &mut T, 11 command: TargetXml<'_>, 12 ) -> Result<HandlerStatus, Error<T::Error, C::Error>> { 13 if !target.use_target_description_xml() { 14 return Ok(HandlerStatus::Handled); 15 } 16 17 let handler_status = match command { 18 TargetXml::qXferFeaturesRead(cmd) => { 19 let ret = if let Some(ops) = target.support_target_description_xml_override() { 20 ops.target_description_xml(cmd.annex.name, cmd.offset, cmd.length, cmd.buf) 21 .handle_error()? 22 } else if let Some(xml) = T::Arch::target_description_xml() { 23 if cmd.annex.name != b"target.xml" { 24 // TODO: not the best error... should probably report to the user the 25 // <xi:include> isn't supported at the Arch level (yet) 26 return Err(Error::PacketUnexpected); 27 } 28 29 let xml = xml.trim().as_bytes(); 30 let xml_len = xml.len(); 31 32 let start = xml_len.min(cmd.offset as usize); 33 let end = xml_len.min((cmd.offset as usize).saturating_add(cmd.length)); 34 35 // LLVM isn't smart enough to realize that `start <= end`, and fails to elide a 36 // `slice_end_index_len_fail` check unless we include this seemingly useless 37 // call to `min`. 38 let data = &xml[start.min(end)..end]; 39 40 let n = data.len().min(cmd.buf.len()); 41 cmd.buf[..n].copy_from_slice(&data[..n]); 42 n 43 } else { 44 // If the target hasn't provided their own XML, then the initial response to 45 // "qSupported" wouldn't have included "qXfer:features:read", and gdb wouldn't 46 // send this packet unless it was explicitly marked as supported. 47 return Err(Error::PacketUnexpected); 48 }; 49 50 if ret == 0 { 51 res.write_str("l")?; 52 } else { 53 res.write_str("m")?; 54 // TODO: add more specific error variant? 55 res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?; 56 } 57 HandlerStatus::Handled 58 } 59 }; 60 61 Ok(handler_status) 62 } 63 } 64