Skip to content

Commit

Permalink
Add TargetDescriptionXmlOverride extension (#43)
Browse files Browse the repository at this point in the history
* add target description XML override extension

* more consistent naming

* doc tweaks
  • Loading branch information
daniel5151 committed Mar 19, 2021
1 parent cd5d04b commit 1593da2
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 7 deletions.
8 changes: 8 additions & 0 deletions examples/armv4t/gdb/mod.rs
Expand Up @@ -15,6 +15,7 @@ use crate::emu::{Emu, Event};
mod extended_mode;
mod monitor_cmd;
mod section_offsets;
mod target_description_xml_override;

/// Turn a `ArmCoreRegId` into an internal register number of `armv4t_emu`.
fn cpu_reg_id(id: ArmCoreRegId) -> Option<u8> {
Expand Down Expand Up @@ -55,6 +56,13 @@ impl Target for Emu {
fn section_offsets(&mut self) -> Option<target::ext::section_offsets::SectionOffsetsOps<Self>> {
Some(self)
}

fn target_description_xml_override(
&mut self,
) -> Option<target::ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<Self>>
{
Some(self)
}
}

impl SingleThreadOps for Emu {
Expand Down
9 changes: 9 additions & 0 deletions examples/armv4t/gdb/target_description_xml_override.rs
@@ -0,0 +1,9 @@
use gdbstub::target;

use crate::emu::Emu;

impl target::ext::target_description_xml_override::TargetDescriptionXmlOverride for Emu {
fn target_description_xml(&self) -> &str {
r#"<target version="1.0"><!-- custom override string --><architecture>armv4t</architecture></target>"#
}
}
9 changes: 4 additions & 5 deletions src/arch/traits.rs
Expand Up @@ -63,18 +63,17 @@ pub trait Arch {
/// separate from the main `Registers` structure.
type RegId: RegId;

/// (optional) Return the platform's `features.xml` file.
/// (optional) Return the target's description XML file (`target.xml`).
///
/// Implementing this method enables `gdb` to automatically detect the
/// Implementing this method enables GDB to automatically detect the
/// target's architecture, saving the hassle of having to run `set
/// architecture <arch>` when starting a debugging session.
///
/// These descriptions can be quite succinct. For example, the target
/// description for an `armv4t` platform can be as simple as:
/// description for an `armv4t` target can be as simple as:
///
/// ```
/// r#"<target version="1.0"><architecture>armv4t</architecture></target>"#
/// # ;
/// r#"<target version="1.0"><architecture>armv4t</architecture></target>"#;
/// ```
///
/// See the [GDB docs](https://sourceware.org/gdb/current/onlinedocs/gdb/Target-Description-Format.html)
Expand Down
12 changes: 10 additions & 2 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 T::Arch::target_description_xml().is_some()
|| target.target_description_xml_override().is_some()
{
res.write_str(";qXfer:features:read+")?;
}

Expand All @@ -314,7 +316,13 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
HandlerStatus::NeedsOK
}
ext::Base::qXferFeaturesRead(cmd) => {
match T::Arch::target_description_xml() {
#[allow(clippy::redundant_closure)]
let xml = target
.target_description_xml_override()
.map(|ops| ops.target_description_xml())
.or_else(|| T::Arch::target_description_xml());

match xml {
Some(xml) => {
let xml = xml.trim();
if cmd.offset >= xml.len() {
Expand Down
1 change: 1 addition & 0 deletions src/target/ext/mod.rs
Expand Up @@ -250,3 +250,4 @@ pub mod breakpoints;
pub mod extended_mode;
pub mod monitor_cmd;
pub mod section_offsets;
pub mod target_description_xml_override;
22 changes: 22 additions & 0 deletions src/target/ext/target_description_xml_override.rs
@@ -0,0 +1,22 @@
//! Override the target description XML specified by `Target::Arch`.
use crate::target::Target;

/// Target Extension - Override the target description XML specified by
/// `Target::Arch`.
///
/// _Note:_ Unless you're working with a particularly dynamic,
/// runtime-configurable target, it's unlikely that you'll need to implement
/// this extension.
pub trait TargetDescriptionXmlOverride: Target {
/// Return the target's description XML file (`target.xml`).
///
/// Refer to the
/// [target_description_xml](crate::arch::Arch::target_description_xml)
/// docs for more info.
fn target_description_xml(&self) -> &str;
}

define_ext!(
TargetDescriptionXmlOverrideOps,
TargetDescriptionXmlOverride
);
14 changes: 14 additions & 0 deletions src/target/mod.rs
Expand Up @@ -239,6 +239,13 @@ pub trait Target {
fn section_offsets(&mut self) -> Option<ext::section_offsets::SectionOffsetsOps<Self>> {
None
}

/// Override the target description XML specified by `Target::Arch`.
fn target_description_xml_override(
&mut self,
) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<Self>> {
None
}
}

macro_rules! impl_dyn_target {
Expand Down Expand Up @@ -278,6 +285,13 @@ macro_rules! impl_dyn_target {
fn section_offsets(&mut self) -> Option<ext::section_offsets::SectionOffsetsOps<Self>> {
(**self).section_offsets()
}

fn target_description_xml_override(
&mut self,
) -> Option<ext::target_description_xml_override::TargetDescriptionXmlOverrideOps<Self>>
{
(**self).target_description_xml_override()
}
}
};
}
Expand Down

0 comments on commit 1593da2

Please sign in to comment.