• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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