Skip to content

Commit

Permalink
Allow Target to override Arch's target description
Browse files Browse the repository at this point in the history
  • Loading branch information
DrChat committed Mar 18, 2021
1 parent cd5d04b commit f5892a1
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/gdbstub_impl/mod.rs
Expand Up @@ -303,7 +303,9 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
// TODO: implement conditional breakpoint support (since that's kool).
// res.write_str("ConditionalBreakpoints+;")?;

if T::Arch::target_description_xml().is_some() {
if target.target_description().is_some()
|| <T::Arch as Arch>::target_description_xml().is_some()
{
res.write_str(";qXfer:features:read+")?;
}

Expand All @@ -314,7 +316,16 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
HandlerStatus::NeedsOK
}
ext::Base::qXferFeaturesRead(cmd) => {
match T::Arch::target_description_xml() {
// Query the target description ops for the target's description.
let xml = {
// Target gets the first chance to override the XML description.
target.target_description().map_or(
<T::Arch as Arch>::target_description_xml(),
|v| Some(v.target_description_xml()),
)
};

match xml {
Some(xml) => {
let xml = xml.trim();
if cmd.offset >= xml.len() {
Expand All @@ -331,10 +342,11 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
}
}
// If the target hasn't provided their own XML, then the initial response to
// "qSupported" wouldn't have included "qXfer:features:read", and gdb wouldn't
// send this packet unless it was explicitly marked as supported.
// "qSupported" wouldn't have included "qXfer:features:read", and gdb
// wouldn't send this packet unless it was explicitly marked as supported.
None => return Err(Error::PacketUnexpected),
}

HandlerStatus::Handled
}

Expand Down
15 changes: 15 additions & 0 deletions src/target/ext/base/description.rs
@@ -0,0 +1,15 @@
use crate::arch::Arch;
use crate::target::Target;

/// Basic operation to return an XML-formatted target description string
/// to the GDB client.
pub trait TargetDescription: Target {
/// Returns an optional XML description for the target to GDB.
fn target_description_xml(&self) -> &'static str {
<Self::Arch as Arch>::target_description_xml().unwrap()
}
}

/// See [`TargetDescription`]
pub type TargetDescriptionOps<'a, T> =
&'a mut dyn TargetDescription<Arch = <T as Target>::Arch, Error = <T as Target>::Error>;
5 changes: 5 additions & 0 deletions src/target/ext/base/mod.rs
Expand Up @@ -7,6 +7,11 @@
pub mod multithread;
pub mod singlethread;

mod description;

pub use description::TargetDescription;
pub use description::TargetDescriptionOps;

/// Base operations for single/multi threaded targets.
pub enum BaseOps<'a, A, E> {
/// Single-threaded target
Expand Down
5 changes: 5 additions & 0 deletions src/target/mod.rs
Expand Up @@ -239,6 +239,11 @@ pub trait Target {
fn section_offsets(&mut self) -> Option<ext::section_offsets::SectionOffsetsOps<Self>> {
None
}

/// Handle requests for the target's XML description for GDB.
fn target_description(&mut self) -> Option<ext::base::TargetDescriptionOps<Self>> {
None
}
}

macro_rules! impl_dyn_target {
Expand Down

0 comments on commit f5892a1

Please sign in to comment.