diff options
author | Devin Moore <devinmoore@google.com> | 2022-05-02 22:30:09 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-05-02 22:30:09 +0000 |
commit | d30c9f199d2206759fb802ec2452713d37529d77 (patch) | |
tree | b72b4d23393f62226a2d5d9ca0d5b7038b20b605 | |
parent | f7a97fbc0c1eb721f39af3354c422bb114bb2b31 (diff) | |
parent | c4d8f27720a6f64d5b6cbe4ebd0a8a41f0eab8a5 (diff) | |
download | gdbstub_arch-d30c9f199d2206759fb802ec2452713d37529d77.tar.gz |
Update gdbstub_arch crate to version 0.2.2 am: 7a64a43e82 am: e70e588e77 am: 01f70252f7 am: c4d8f27720
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/gdbstub_arch/+/2068150
Change-Id: I72c61c3e0f92b4656b3568ccebb8564c5419eef8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 28 | ||||
-rw-r--r-- | Cargo.toml | 15 | ||||
-rw-r--r-- | Cargo.toml.orig | 6 | ||||
-rw-r--r-- | LICENSE | 23 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | src/arm/mod.rs | 7 | ||||
-rw-r--r-- | src/arm/reg/arm_core.rs | 2 | ||||
-rw-r--r-- | src/arm/reg/id.rs | 6 | ||||
-rw-r--r-- | src/mips/mod.rs | 89 | ||||
-rw-r--r-- | src/mips/reg/id.rs | 16 | ||||
-rw-r--r-- | src/mips/reg/mips.rs | 12 | ||||
-rw-r--r-- | src/msp430/mod.rs | 41 | ||||
-rw-r--r-- | src/msp430/reg/id.rs | 51 | ||||
-rw-r--r-- | src/msp430/reg/msp430.rs | 60 | ||||
-rw-r--r-- | src/ppc/mod.rs | 8 | ||||
-rw-r--r-- | src/ppc/reg/common.rs | 8 | ||||
-rw-r--r-- | src/riscv/mod.rs | 16 | ||||
-rw-r--r-- | src/riscv/reg/id.rs | 9 | ||||
-rw-r--r-- | src/x86/mod.rs | 37 | ||||
-rw-r--r-- | src/x86/reg/core32.rs | 4 | ||||
-rw-r--r-- | src/x86/reg/core64.rs | 4 | ||||
-rw-r--r-- | src/x86/reg/id.rs | 30 | ||||
-rw-r--r-- | src/x86/reg/mod.rs | 2 |
26 files changed, 307 insertions, 191 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 66f2471..77ccc2c 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "4e14680234812020427385521d7d6cad585c4905" - } -} + "sha1": "534aff1e9ae8ce2af72f08921b8e3edf88295d59" + }, + "path_in_vcs": "gdbstub_arch" +}
\ No newline at end of file @@ -23,7 +23,7 @@ rust_test { host_supported: true, crate_name: "gdbstub_arch", cargo_env_compat: true, - cargo_pkg_version: "0.1.1", + cargo_pkg_version: "0.2.2", srcs: ["src/lib.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -42,7 +42,7 @@ rust_library { host_supported: true, crate_name: "gdbstub_arch", cargo_env_compat: true, - cargo_pkg_version: "0.1.1", + cargo_pkg_version: "0.2.2", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9ed4353 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,28 @@ +All notable changes to this project will be documented in this file. + +This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +# 0.2.1 + +- Removed all remaining instances of `SingleStepGdbBehavior::Unknown` [\#62](https://github.com/daniel5151/gdbstub/pull/95) ([bet4it](https://github.com/bet4it)) + +# 0.2.0 + +**Bumps required `gdbstub` version to 0.6.0**. + +#### Breaking Arch Changes + +- Improved support + fixes for `Msp430` [\#62](https://github.com/daniel5151/gdbstub/pull/62) ([mchesser](https://github.com/mchesser)) +- `X86_64CoreRegId`: Change rip size to 8 [\#87](https://github.com/daniel5151/gdbstub/pull/87) ([gz](https://github.com/gz)) +- Removed `RegId` template parameters from the following `Arch` implementations: + - x86/x64 + - MIPS + - MSP-430 + +# 0.1.0 + +**Bumps required `gdbstub` version to 0.5.0**. + +- **`gdbstub::arch` has been moved into a separate `gdbstub_arch` crate** + - _See [\#45](https://github.com/daniel5151/gdbstub/issues/45) for details on why this was done._ +- (x86) Break GPRs & SRs into individual fields/variants [\#34](https://github.com/daniel5151/gdbstub/issues/34) @@ -3,17 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "gdbstub_arch" -version = "0.1.1" +version = "0.2.2" authors = ["Daniel Prilik <danielprilik@gmail.com>"] description = "Implementations of `gdbstub::arch::Arch` for various architectures." homepage = "https://github.com/daniel5151/gdbstub" @@ -21,10 +20,10 @@ documentation = "https://docs.rs/gdbstub_arch" readme = "README.md" keywords = ["gdb", "emulation", "no_std", "debugging"] categories = ["development-tools::debugging", "embedded", "emulators", "no-std"] -license = "MIT" +license = "MIT OR Apache-2.0" repository = "https://github.com/daniel5151/gdbstub" [dependencies.gdbstub] -version = "0.5" +version = "0.6" default-features = false [dependencies.num-traits] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index b518f6c..0c3d68d 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -2,8 +2,8 @@ name = "gdbstub_arch" description = "Implementations of `gdbstub::arch::Arch` for various architectures." authors = ["Daniel Prilik <danielprilik@gmail.com>"] -version = "0.1.1" -license = "MIT" +version = "0.2.2" +license = "MIT OR Apache-2.0" edition = "2018" readme = "README.md" documentation = "https://docs.rs/gdbstub_arch" @@ -13,6 +13,6 @@ keywords = ["gdb", "emulation", "no_std", "debugging"] categories = ["development-tools::debugging", "embedded", "emulators", "no-std"] [dependencies] -gdbstub = { path = "../", version = "0.5", default-features = false } +gdbstub = { path = "../", version = "0.6", default-features = false } num-traits = { version = "0.2", default-features = false } @@ -1,21 +1,6 @@ -MIT License +gdbstub_arch is dual-licensed under either -Copyright (c) 2021 Daniel Prilik +* MIT License (../docs/LICENSE-MIT or http://opensource.org/licenses/MIT) +* Apache License, Version 2.0 (../docs/LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +at your option. @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/gdbstub_arch/gdbstub_arch-0.1.1.crate" + value: "https://static.crates.io/crates/gdbstub_arch/gdbstub_arch-0.2.2.crate" } - version: "0.1.1" + version: "0.2.2" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 9 - day: 22 + year: 2022 + month: 4 + day: 19 } } @@ -1,7 +1,8 @@ # gdbstub_arch -[![](http://meritbadge.herokuapp.com/gdbstub_arch)](https://crates.io/crates/gdbstub_arch) +[![](https://img.shields.io/crates/v/gdbstub_arch.svg)](https://crates.io/crates/gdbstub_arch) [![](https://docs.rs/gdbstub_arch/badge.svg)](https://docs.rs/gdbstub_arch) +[![](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](./LICENSE) Community-contributed implementations of `gdbstub::arch::Arch` for various architectures. diff --git a/src/arm/mod.rs b/src/arm/mod.rs index 96fc404..efb410c 100644 --- a/src/arm/mod.rs +++ b/src/arm/mod.rs @@ -1,6 +1,6 @@ //! Implementations for various ARM architectures. -use gdbstub::arch::Arch; +use gdbstub::arch::{Arch, SingleStepGdbBehavior}; pub mod reg; @@ -42,4 +42,9 @@ impl Arch for Armv4t { fn target_description_xml() -> Option<&'static str> { Some(r#"<target version="1.0"><architecture>armv4t</architecture></target>"#) } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Optional + } } diff --git a/src/arm/reg/arm_core.rs b/src/arm/reg/arm_core.rs index 179d590..b07d6a0 100644 --- a/src/arm/reg/arm_core.rs +++ b/src/arm/reg/arm_core.rs @@ -2,7 +2,7 @@ use gdbstub::arch::Registers; /// 32-bit ARM core registers. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml> #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct ArmCoreRegs { /// General purpose registers (R0-R12) diff --git a/src/arm/reg/id.rs b/src/arm/reg/id.rs index c7e11a2..5b79c89 100644 --- a/src/arm/reg/id.rs +++ b/src/arm/reg/id.rs @@ -1,3 +1,5 @@ +use core::num::NonZeroUsize; + use gdbstub::arch::RegId; /// 32-bit ARM core register identifier. @@ -21,7 +23,7 @@ pub enum ArmCoreRegId { } impl RegId for ArmCoreRegId { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { let reg = match id { 0..=12 => Self::Gpr(id as u8), 13 => Self::Sp, @@ -31,6 +33,6 @@ impl RegId for ArmCoreRegId { 25 => Self::Cpsr, _ => return None, }; - Some((reg, 4)) + Some((reg, Some(NonZeroUsize::new(4)?))) } } diff --git a/src/mips/mod.rs b/src/mips/mod.rs index 7784fe8..7e39cc5 100644 --- a/src/mips/mod.rs +++ b/src/mips/mod.rs @@ -1,7 +1,6 @@ //! Implementations for the MIPS architecture. -use gdbstub::arch::Arch; -use gdbstub::arch::RegId; +use gdbstub::arch::{Arch, SingleStepGdbBehavior}; pub mod reg; @@ -38,48 +37,46 @@ impl gdbstub::arch::BreakpointKind for MipsBreakpointKind { } /// Implements `Arch` for 32-bit MIPS. -/// -/// Check out the [module level docs](gdbstub::arch#whats-with-regidimpl) for -/// more info about the `RegIdImpl` type parameter. -pub enum Mips<RegIdImpl: RegId = reg::id::MipsRegId<u32>> { - #[doc(hidden)] - _Marker(core::marker::PhantomData<RegIdImpl>), -} +pub enum Mips {} + +/// Implements `Arch` for 32-bit MIPS, with the DSP feature enabled. +pub enum MipsWithDsp {} /// Implements `Arch` for 64-bit MIPS. /// -/// Check out the [module level docs](gdbstub::arch#whats-with-regidimpl) for -/// more info about the `RegIdImpl` type parameter. -pub enum Mips64<RegIdImpl: RegId = reg::id::MipsRegId<u64>> { - #[doc(hidden)] - _Marker(core::marker::PhantomData<RegIdImpl>), -} - -/// Implements `Arch` for 32-bit MIPS with the DSP feature enabled. -pub enum MipsWithDsp {} +/// **NOTE:** Due to GDB client behavior, this arch does _not_ include a +/// built-in `target.xml` implementation. Consider manually implementing +/// [`TargetDescriptionXmlOverride`]. +/// +/// See [daniel5151/gdbstub#97](https://github.com/daniel5151/gdbstub/issues/97). +/// +/// [`TargetDescriptionXmlOverride`]: gdbstub::target::ext::target_description_xml_override::TargetDescriptionXmlOverride +pub enum Mips64 {} -/// Implements `Arch` for 64-bit MIPS with the DSP feature enabled. +/// Implements `Arch` for 64-bit MIPS, with the DSP feature enabled. +/// +/// **NOTE:** Due to GDB client behavior, this arch does _not_ include a +/// built-in `target.xml` implementation. Consider manually implementing +/// [`TargetDescriptionXmlOverride`]. +/// +/// See [daniel5151/gdbstub#97](https://github.com/daniel5151/gdbstub/issues/97). +/// +/// [`TargetDescriptionXmlOverride`]: gdbstub::target::ext::target_description_xml_override::TargetDescriptionXmlOverride pub enum Mips64WithDsp {} -impl<RegIdImpl: RegId> Arch for Mips<RegIdImpl> { +impl Arch for Mips { type Usize = u32; type Registers = reg::MipsCoreRegs<u32>; - type RegId = RegIdImpl; + type RegId = reg::id::MipsRegId<u32>; type BreakpointKind = MipsBreakpointKind; fn target_description_xml() -> Option<&'static str> { Some(r#"<target version="1.0"><architecture>mips</architecture></target>"#) } -} - -impl<RegIdImpl: RegId> Arch for Mips64<RegIdImpl> { - type Usize = u64; - type Registers = reg::MipsCoreRegs<u64>; - type RegId = RegIdImpl; - type BreakpointKind = MipsBreakpointKind; - fn target_description_xml() -> Option<&'static str> { - Some(r#"<target version="1.0"><architecture>mips64</architecture></target>"#) + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Ignored } } @@ -94,8 +91,31 @@ impl Arch for MipsWithDsp { r#"<target version="1.0"><architecture>mips</architecture><feature name="org.gnu.gdb.mips.dsp"></feature></target>"#, ) } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Ignored + } +} + +#[allow(deprecated)] +impl Arch for Mips64 { + type Usize = u64; + type Registers = reg::MipsCoreRegs<u64>; + type RegId = reg::id::MipsRegId<u64>; + type BreakpointKind = MipsBreakpointKind; + + fn target_description_xml() -> Option<&'static str> { + None + } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Ignored + } } +#[allow(deprecated)] impl Arch for Mips64WithDsp { type Usize = u64; type Registers = reg::MipsCoreRegsWithDsp<u64>; @@ -103,8 +123,11 @@ impl Arch for Mips64WithDsp { type BreakpointKind = MipsBreakpointKind; fn target_description_xml() -> Option<&'static str> { - Some( - r#"<target version="1.0"><architecture>mips64</architecture><feature name="org.gnu.gdb.mips.dsp"></feature></target>"#, - ) + None + } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Ignored } } diff --git a/src/mips/reg/id.rs b/src/mips/reg/id.rs index 57665c6..99afb3f 100644 --- a/src/mips/reg/id.rs +++ b/src/mips/reg/id.rs @@ -1,3 +1,5 @@ +use core::num::NonZeroUsize; + use gdbstub::arch::RegId; /// MIPS register identifier. @@ -41,10 +43,10 @@ pub enum MipsRegId<U> { /// Restart register Restart, #[doc(hidden)] - _Size(U), + _Size(core::marker::PhantomData<U>), } -fn from_raw_id<U>(id: usize) -> Option<(MipsRegId<U>, usize)> { +fn from_raw_id<U>(id: usize) -> Option<(MipsRegId<U>, Option<NonZeroUsize>)> { let reg = match id { 0..=31 => MipsRegId::Gpr(id as u8), 32 => MipsRegId::Status, @@ -63,23 +65,23 @@ fn from_raw_id<U>(id: usize) -> Option<(MipsRegId<U>, usize)> { 76 => MipsRegId::Hi3, 77 => MipsRegId::Lo3, // `MipsRegId::Dspctl` is the only register that will always be 4 bytes wide - 78 => return Some((MipsRegId::Dspctl, 4)), + 78 => return Some((MipsRegId::Dspctl, Some(NonZeroUsize::new(4)?))), 79 => MipsRegId::Restart, _ => return None, }; let ptrsize = core::mem::size_of::<U>(); - Some((reg, ptrsize)) + Some((reg, Some(NonZeroUsize::new(ptrsize)?))) } impl RegId for MipsRegId<u32> { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { from_raw_id::<u32>(id) } } impl RegId for MipsRegId<u64> { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { from_raw_id::<u64>(id) } } @@ -104,7 +106,7 @@ mod tests { let mut i = 0; let mut sum_reg_sizes = 0; while let Some((_, size)) = RId::from_raw_id(i) { - sum_reg_sizes += size; + sum_reg_sizes += size.unwrap().get(); i += 1; } diff --git a/src/mips/reg/mips.rs b/src/mips/reg/mips.rs index be14e33..d40aead 100644 --- a/src/mips/reg/mips.rs +++ b/src/mips/reg/mips.rs @@ -9,7 +9,7 @@ use gdbstub::internal::LeBytes; /// /// The register width is set to `u32` or `u64` based on the `<U>` type. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-cpu.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-cpu.xml> #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct MipsCoreRegs<U> { /// General purpose registers (R0-R31) @@ -28,7 +28,7 @@ pub struct MipsCoreRegs<U> { /// MIPS CP0 (coprocessor 0) registers. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-cp0.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-cp0.xml> #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct MipsCp0Regs<U> { /// Status register (regnum 32) @@ -41,7 +41,7 @@ pub struct MipsCp0Regs<U> { /// MIPS FPU registers. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-fpu.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-fpu.xml> #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct MipsFpuRegs<U> { /// FP registers (F0-F31) starting at regnum 38 @@ -54,7 +54,7 @@ pub struct MipsFpuRegs<U> { /// MIPS DSP registers. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-dsp.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-dsp.xml> #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct MipsDspRegs<U> { /// High 1 register (regnum 72) @@ -71,7 +71,7 @@ pub struct MipsDspRegs<U> { pub lo3: U, /// DSP Control register (regnum 78) /// Note: This register will always be 32-bit regardless of the target - /// https://sourceware.org/gdb/current/onlinedocs/gdb/MIPS-Features.html#MIPS-Features + /// <https://sourceware.org/gdb/current/onlinedocs/gdb/MIPS-Features.html#MIPS-Features> pub dspctl: u32, /// Restart register (regnum 79) pub restart: U, @@ -79,7 +79,7 @@ pub struct MipsDspRegs<U> { /// MIPS core and DSP registers. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-dsp-linux.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/mips-dsp-linux.xml> #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct MipsCoreRegsWithDsp<U> { /// Core registers diff --git a/src/msp430/mod.rs b/src/msp430/mod.rs index 456ce18..dd90c6a 100644 --- a/src/msp430/mod.rs +++ b/src/msp430/mod.rs @@ -1,26 +1,43 @@ //! Implementations for the TI-MSP430 family of MCUs. -use gdbstub::arch::Arch; -use gdbstub::arch::RegId; +use gdbstub::arch::{Arch, SingleStepGdbBehavior}; pub mod reg; /// Implements `Arch` for standard 16-bit TI-MSP430 MCUs. -/// -/// Check out the [module level docs](gdbstub::arch#whats-with-regidimpl) for -/// more info about the `RegIdImpl` type parameter. -pub enum Msp430<RegIdImpl: RegId = reg::id::Msp430RegId> { - #[doc(hidden)] - _Marker(core::marker::PhantomData<RegIdImpl>), -} +pub struct Msp430 {} -impl<RegIdImpl: RegId> Arch for Msp430<RegIdImpl> { +impl Arch for Msp430 { type Usize = u16; - type Registers = reg::Msp430Regs; - type RegId = RegIdImpl; + type Registers = reg::Msp430Regs<u16>; + type RegId = reg::id::Msp430RegId<u16>; type BreakpointKind = usize; fn target_description_xml() -> Option<&'static str> { Some(r#"<target version="1.0"><architecture>msp430</architecture></target>"#) } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Required + } +} + +/// Implements `Arch` for 20-bit TI-MSP430 MCUs (CPUX). +pub struct Msp430X {} + +impl Arch for Msp430X { + type Usize = u32; + type Registers = reg::Msp430Regs<u32>; + type RegId = reg::id::Msp430RegId<u32>; + type BreakpointKind = usize; + + fn target_description_xml() -> Option<&'static str> { + Some(r#"<target version="1.0"><architecture>msp430x</architecture></target>"#) + } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Required + } } diff --git a/src/msp430/reg/id.rs b/src/msp430/reg/id.rs index 1c38763..679c1cc 100644 --- a/src/msp430/reg/id.rs +++ b/src/msp430/reg/id.rs @@ -1,3 +1,5 @@ +use core::num::NonZeroUsize; + use gdbstub::arch::RegId; /// TI-MSP430 register identifier. @@ -6,7 +8,7 @@ use gdbstub::arch::RegId; /// The best file to reference is [msp430-tdep.c](https://github.com/bminor/binutils-gdb/blob/master/gdb/msp430-tdep.c). #[derive(Debug, Clone, Copy)] #[non_exhaustive] -pub enum Msp430RegId { +pub enum Msp430RegId<U> { /// Program Counter (R0) Pc, /// Stack Pointer (R1) @@ -17,19 +19,33 @@ pub enum Msp430RegId { Cg, /// General Purpose Registers (R4-R15) Gpr(u8), + #[doc(hidden)] + _Size(core::marker::PhantomData<U>), } -impl RegId for Msp430RegId { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { - let reg = match id { - 0 => Self::Pc, - 1 => Self::Sp, - 2 => Self::Sr, - 3 => Self::Cg, - 4..=15 => Self::Gpr((id as u8) - 4), - _ => return None, - }; - Some((reg, 2)) +fn from_raw_id<U>(id: usize) -> Option<(Msp430RegId<U>, Option<NonZeroUsize>)> { + let reg = match id { + 0 => Msp430RegId::Pc, + 1 => Msp430RegId::Sp, + 2 => Msp430RegId::Sr, + 3 => Msp430RegId::Cg, + 4..=15 => Msp430RegId::Gpr((id as u8) - 4), + _ => return None, + }; + + let ptrsize = core::mem::size_of::<U>(); + Some((reg, Some(NonZeroUsize::new(ptrsize)?))) +} + +impl RegId for Msp430RegId<u16> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { + from_raw_id::<u16>(id) + } +} + +impl RegId for Msp430RegId<u32> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { + from_raw_id::<u32>(id) } } @@ -51,13 +67,13 @@ mod tests { // The `Msp430Regs` implementation does not increment the size for // the CG register since it will always be the constant zero. - serialized_data_len += 4; + serialized_data_len += RId::from_raw_id(3).unwrap().1.unwrap().get(); // Accumulate register sizes returned by `from_raw_id`. let mut i = 0; let mut sum_reg_sizes = 0; while let Some((_, size)) = RId::from_raw_id(i) { - sum_reg_sizes += size; + sum_reg_sizes += size.unwrap().get(); i += 1; } @@ -66,6 +82,11 @@ mod tests { #[test] fn test_msp430() { - test::<crate::msp430::reg::Msp430Regs, crate::msp430::reg::id::Msp430RegId>() + test::<crate::msp430::reg::Msp430Regs<u16>, crate::msp430::reg::id::Msp430RegId<u16>>() + } + + #[test] + fn test_msp430x() { + test::<crate::msp430::reg::Msp430Regs<u32>, crate::msp430::reg::id::Msp430RegId<u32>>() } } diff --git a/src/msp430/reg/msp430.rs b/src/msp430/reg/msp430.rs index 652fc1b..d063d6d 100644 --- a/src/msp430/reg/msp430.rs +++ b/src/msp430/reg/msp430.rs @@ -1,60 +1,74 @@ +use num_traits::PrimInt; + use gdbstub::arch::Registers; +use gdbstub::internal::LeBytes; -/// 16-bit TI-MSP430 registers. +/// TI-MSP430 registers. +/// +/// The register width is set based on the `<U>` type. For 16-bit MSP430 CPUs +/// this should be `u16` and for 20-bit MSP430 CPUs (CPUX) this should be `u32`. #[derive(Debug, Default, Clone, Eq, PartialEq)] -pub struct Msp430Regs { +pub struct Msp430Regs<U> { /// Program Counter (R0) - pub pc: u16, + pub pc: U, /// Stack Pointer (R1) - pub sp: u16, + pub sp: U, /// Status Register (R2) - pub sr: u16, + pub sr: U, /// General Purpose Registers (R4-R15) - pub r: [u16; 11], + pub r: [U; 12], } -impl Registers for Msp430Regs { - type ProgramCounter = u16; +impl<U> Registers for Msp430Regs<U> +where + U: PrimInt + LeBytes + Default + core::fmt::Debug, +{ + type ProgramCounter = U; fn pc(&self) -> Self::ProgramCounter { self.pc } fn gdb_serialize(&self, mut write_byte: impl FnMut(Option<u8>)) { - macro_rules! write_bytes { - ($bytes:expr) => { - for b in $bytes { - write_byte(Some(*b)) + macro_rules! write_le_bytes { + ($value:expr) => { + let mut buf = [0; 4]; + // infallible (register size a maximum of 32-bits) + let len = $value.to_le_bytes(&mut buf).unwrap(); + let buf = &buf[..len]; + for b in buf { + write_byte(Some(*b)); } }; } - write_bytes!(&self.pc.to_le_bytes()); - write_bytes!(&self.sp.to_le_bytes()); - write_bytes!(&self.sr.to_le_bytes()); - (0..4).for_each(|_| write_byte(None)); // Constant Generator (CG/R3) + write_le_bytes!(&self.pc); + write_le_bytes!(&self.sp); + write_le_bytes!(&self.sr); + (0..core::mem::size_of::<U>()).for_each(|_| write_byte(None)); // Constant Generator (CG/R3) for reg in self.r.iter() { - write_bytes!(®.to_le_bytes()); + write_le_bytes!(®); } } fn gdb_deserialize(&mut self, bytes: &[u8]) -> Result<(), ()> { - // ensure bytes.chunks_exact(2) won't panic - if bytes.len() % 2 != 0 { + let ptrsize = core::mem::size_of::<U>(); + + // Ensure bytes contains enough data for all 16 registers + if bytes.len() < ptrsize * 16 { return Err(()); } - use core::convert::TryInto; let mut regs = bytes - .chunks_exact(2) - .map(|c| u16::from_le_bytes(c.try_into().unwrap())); + .chunks_exact(ptrsize) + .map(|c| U::from_le_bytes(c).unwrap()); self.pc = regs.next().ok_or(())?; self.sp = regs.next().ok_or(())?; self.sr = regs.next().ok_or(())?; // Constant Generator (CG/R3) should always be 0 - if regs.next().ok_or(())? != 0 { + if regs.next().ok_or(())? != U::zero() { return Err(()); } diff --git a/src/ppc/mod.rs b/src/ppc/mod.rs index 60beed3..5351ef4 100644 --- a/src/ppc/mod.rs +++ b/src/ppc/mod.rs @@ -1,7 +1,6 @@ //! Implementations for various PowerPC architectures. -use gdbstub::arch::Arch; -use gdbstub::arch::RegId; +use gdbstub::arch::{Arch, RegId, SingleStepGdbBehavior}; pub mod reg; @@ -25,4 +24,9 @@ impl<RegIdImpl: RegId> Arch for PowerPcAltivec32<RegIdImpl> { r#"<target version="1.0"><architecture>powerpc:common</architecture><feature name="org.gnu.gdb.power.core"></feature><feature name="org.gnu.gdb.power.fpu"></feature><feature name="org.gnu.gdb.power.altivec"></feature></target>"#, ) } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Required + } } diff --git a/src/ppc/reg/common.rs b/src/ppc/reg/common.rs index 45bdb1c..c84a87b 100644 --- a/src/ppc/reg/common.rs +++ b/src/ppc/reg/common.rs @@ -7,10 +7,10 @@ use core::convert::TryInto; /// 32-bit PowerPC core registers, FPU registers, and AltiVec SIMD registers. /// /// Sources: -/// * https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/powerpc-altivec32.xml -/// * https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-core.xml -/// * https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-fpu.xml -/// * https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-altivec.xml +/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/powerpc-altivec32.xml> +/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-core.xml> +/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-fpu.xml> +/// * <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/rs6000/power-altivec.xml> #[derive(Debug, Default, Clone, PartialEq)] pub struct PowerPcCommonRegs { /// General purpose registers diff --git a/src/riscv/mod.rs b/src/riscv/mod.rs index 62ce98e..d5c6c67 100644 --- a/src/riscv/mod.rs +++ b/src/riscv/mod.rs @@ -2,7 +2,7 @@ //! //! *Note*: currently only supports integer versions of the ISA. -use gdbstub::arch::Arch; +use gdbstub::arch::{Arch, SingleStepGdbBehavior}; pub mod reg; @@ -19,7 +19,12 @@ impl Arch for Riscv32 { type BreakpointKind = usize; fn target_description_xml() -> Option<&'static str> { - Some(r#"<target version="1.0"><architecture>riscv</architecture></target>"#) + Some(r#"<target version="1.0"><architecture>riscv:rv32</architecture></target>"#) + } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Ignored } } @@ -30,6 +35,11 @@ impl Arch for Riscv64 { type BreakpointKind = usize; fn target_description_xml() -> Option<&'static str> { - Some(r#"<target version="1.0"><architecture>riscv64</architecture></target>"#) + Some(r#"<target version="1.0"><architecture>riscv:rv64</architecture></target>"#) + } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Ignored } } diff --git a/src/riscv/reg/id.rs b/src/riscv/reg/id.rs index b6e589d..621231e 100644 --- a/src/riscv/reg/id.rs +++ b/src/riscv/reg/id.rs @@ -1,3 +1,5 @@ +use core::num::NonZeroUsize; + use gdbstub::arch::RegId; /// RISC-V Register identifier. @@ -22,10 +24,10 @@ pub enum RiscvRegId<U> { macro_rules! impl_riscv_reg_id { ($usize:ty) => { impl RegId for RiscvRegId<$usize> { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { const USIZE: usize = core::mem::size_of::<$usize>(); - let reg_size = match id { + let (id, size) = match id { 0..=31 => (Self::Gpr(id as u8), USIZE), 32 => (Self::Pc, USIZE), 33..=64 => (Self::Fpr((id - 33) as u8), USIZE), @@ -33,7 +35,8 @@ macro_rules! impl_riscv_reg_id { 4161 => (Self::Priv, 1), _ => return None, }; - Some(reg_size) + + Some((id, Some(NonZeroUsize::new(size)?))) } } }; diff --git a/src/x86/mod.rs b/src/x86/mod.rs index e7fec5c..d1c7a61 100644 --- a/src/x86/mod.rs +++ b/src/x86/mod.rs @@ -1,24 +1,17 @@ //! Implementations for various x86 architectures. -use gdbstub::arch::Arch; -use gdbstub::arch::RegId; +use gdbstub::arch::{Arch, SingleStepGdbBehavior}; pub mod reg; /// Implements `Arch` for 64-bit x86 + SSE Extensions. -/// -/// Check out the [module level docs](gdbstub::arch#whats-with-regidimpl) for -/// more info about the `RegIdImpl` type parameter. #[allow(non_camel_case_types, clippy::upper_case_acronyms)] -pub enum X86_64_SSE<RegIdImpl: RegId = reg::id::X86_64CoreRegId> { - #[doc(hidden)] - _Marker(core::marker::PhantomData<RegIdImpl>), -} +pub enum X86_64_SSE {} -impl<RegIdImpl: RegId> Arch for X86_64_SSE<RegIdImpl> { +impl Arch for X86_64_SSE { type Usize = u64; type Registers = reg::X86_64CoreRegs; - type RegId = RegIdImpl; + type RegId = reg::id::X86_64CoreRegId; type BreakpointKind = usize; fn target_description_xml() -> Option<&'static str> { @@ -26,22 +19,21 @@ impl<RegIdImpl: RegId> Arch for X86_64_SSE<RegIdImpl> { r#"<target version="1.0"><architecture>i386:x86-64</architecture><feature name="org.gnu.gdb.i386.sse"></feature></target>"#, ) } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Required + } } /// Implements `Arch` for 32-bit x86 + SSE Extensions. -/// -/// Check out the [module level docs](gdbstub::arch#whats-with-regidimpl) for -/// more info about the `RegIdImpl` type parameter. #[allow(non_camel_case_types, clippy::upper_case_acronyms)] -pub enum X86_SSE<RegIdImpl: RegId = reg::id::X86CoreRegId> { - #[doc(hidden)] - _Marker(core::marker::PhantomData<RegIdImpl>), -} +pub enum X86_SSE {} -impl<RegIdImpl: RegId> Arch for X86_SSE<RegIdImpl> { +impl Arch for X86_SSE { type Usize = u32; type Registers = reg::X86CoreRegs; - type RegId = RegIdImpl; + type RegId = reg::id::X86CoreRegId; type BreakpointKind = usize; fn target_description_xml() -> Option<&'static str> { @@ -49,4 +41,9 @@ impl<RegIdImpl: RegId> Arch for X86_SSE<RegIdImpl> { r#"<target version="1.0"><architecture>i386:intel</architecture><feature name="org.gnu.gdb.i386.sse"></feature></target>"#, ) } + + #[inline(always)] + fn single_step_gdb_behavior() -> SingleStepGdbBehavior { + SingleStepGdbBehavior::Required + } } diff --git a/src/x86/reg/core32.rs b/src/x86/reg/core32.rs index d91e707..91c94c2 100644 --- a/src/x86/reg/core32.rs +++ b/src/x86/reg/core32.rs @@ -6,8 +6,8 @@ use super::{X86SegmentRegs, X87FpuInternalRegs, F80}; /// 32-bit x86 core registers (+ SSE extensions). /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-core.xml -/// Additionally: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-sse.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-core.xml> +/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-sse.xml> #[derive(Debug, Default, Clone, PartialEq)] pub struct X86CoreRegs { /// Accumulator diff --git a/src/x86/reg/core64.rs b/src/x86/reg/core64.rs index e0fc5af..b6ae323 100644 --- a/src/x86/reg/core64.rs +++ b/src/x86/reg/core64.rs @@ -6,8 +6,8 @@ use super::{X86SegmentRegs, X87FpuInternalRegs, F80}; /// 64-bit x86 core registers (+ SSE extensions). /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml -/// Additionally: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-sse.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml> +/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-sse.xml> #[derive(Debug, Default, Clone, PartialEq)] pub struct X86_64CoreRegs { /// RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, r8-r15 diff --git a/src/x86/reg/id.rs b/src/x86/reg/id.rs index 03de64b..d1f5462 100644 --- a/src/x86/reg/id.rs +++ b/src/x86/reg/id.rs @@ -1,3 +1,5 @@ +use core::num::NonZeroUsize; + use gdbstub::arch::RegId; /// FPU register identifier. @@ -77,8 +79,8 @@ impl X86SegmentRegId { /// 32-bit x86 core + SSE register identifier. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-core.xml -/// Additionally: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-sse.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-core.xml> +/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/32bit-sse.xml> #[derive(Debug, Clone, Copy)] #[non_exhaustive] pub enum X86CoreRegId { @@ -115,10 +117,10 @@ pub enum X86CoreRegId { } impl RegId for X86CoreRegId { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { use self::X86CoreRegId::*; - let r = match id { + let (r, sz): (X86CoreRegId, usize) = match id { 0 => (Eax, 4), 1 => (Ecx, 4), 2 => (Edx, 4), @@ -136,14 +138,15 @@ impl RegId for X86CoreRegId { 40 => (Mxcsr, 4), _ => return None, }; - Some(r) + + Some((r, Some(NonZeroUsize::new(sz)?))) } } /// 64-bit x86 core + SSE register identifier. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml -/// Additionally: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-sse.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml> +/// Additionally: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-sse.xml> #[derive(Debug, Clone, Copy)] #[non_exhaustive] pub enum X86_64CoreRegId { @@ -167,13 +170,13 @@ pub enum X86_64CoreRegId { } impl RegId for X86_64CoreRegId { - fn from_raw_id(id: usize) -> Option<(Self, usize)> { + fn from_raw_id(id: usize) -> Option<(Self, Option<NonZeroUsize>)> { use self::X86_64CoreRegId::*; - let r = match id { + let (r, sz): (X86_64CoreRegId, usize) = match id { 0..=15 => (Gpr(id as u8), 8), - 16 => (Rip, 4), - 17 => (Eflags, 8), + 16 => (Rip, 8), + 17 => (Eflags, 4), 18..=23 => (Segment(X86SegmentRegId::from_u8(id as u8 - 18)?), 4), 24..=31 => (St(id as u8 - 24), 10), 32..=39 => (Fpu(X87FpuInternalRegId::from_u8(id as u8 - 32)?), 4), @@ -181,7 +184,8 @@ impl RegId for X86_64CoreRegId { 56 => (Mxcsr, 4), _ => return None, }; - Some(r) + + Some((r, Some(NonZeroUsize::new(sz)?))) } } @@ -208,7 +212,7 @@ mod tests { let mut i = 0; let mut sum_reg_sizes = 0; while let Some((_, size)) = RId::from_raw_id(i) { - sum_reg_sizes += size; + sum_reg_sizes += size.unwrap().get(); i += 1; } diff --git a/src/x86/reg/mod.rs b/src/x86/reg/mod.rs index bac64cd..64d0afa 100644 --- a/src/x86/reg/mod.rs +++ b/src/x86/reg/mod.rs @@ -91,7 +91,7 @@ impl Registers for X87FpuInternalRegs { /// x86 segment registers. /// -/// Source: https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml +/// Source: <https://github.com/bminor/binutils-gdb/blob/master/gdb/features/i386/64bit-core.xml> #[derive(Debug, Default, Clone, PartialEq)] pub struct X86SegmentRegs { /// Code Segment |