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

Add TargetDescriptionXmlOverride extension #43

Merged
merged 3 commits into from Mar 19, 2021
Merged
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
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