Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Target to override Arch's target description #42

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 17 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,17 @@ 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 +343,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