diff --git a/src/arch/arm/reg/arm_core.rs b/src/arch/arm/reg/arm_core.rs index dba5f1df..632ca748 100644 --- a/src/arch/arm/reg/arm_core.rs +++ b/src/arch/arm/reg/arm_core.rs @@ -18,6 +18,12 @@ pub struct ArmCoreRegs { } impl Registers for ArmCoreRegs { + type ProgramCounter = u32; + + fn pc(&self) -> Self::ProgramCounter { + self.pc + } + fn gdb_serialize(&self, mut write_byte: impl FnMut(Option)) { macro_rules! write_bytes { ($bytes:expr) => { diff --git a/src/arch/mips/reg/mips.rs b/src/arch/mips/reg/mips.rs index 5b328b06..1e3e5f72 100644 --- a/src/arch/mips/reg/mips.rs +++ b/src/arch/mips/reg/mips.rs @@ -54,6 +54,12 @@ impl Registers for MipsCoreRegs 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)) { macro_rules! write_le_bytes { ($value:expr) => { diff --git a/src/arch/msp430/mod.rs b/src/arch/msp430/mod.rs index 5abbce35..5da5586f 100644 --- a/src/arch/msp430/mod.rs +++ b/src/arch/msp430/mod.rs @@ -15,7 +15,7 @@ pub enum Msp430 { } impl Arch for Msp430 { - type Usize = u32; + type Usize = u16; type Registers = reg::Msp430Regs; type RegId = RegIdImpl; type BreakpointKind = usize; diff --git a/src/arch/msp430/reg/msp430.rs b/src/arch/msp430/reg/msp430.rs index 456fb963..f3569791 100644 --- a/src/arch/msp430/reg/msp430.rs +++ b/src/arch/msp430/reg/msp430.rs @@ -14,6 +14,12 @@ pub struct Msp430Regs { } impl Registers for Msp430Regs { + type ProgramCounter = u16; + + fn pc(&self) -> Self::ProgramCounter { + self.pc + } + fn gdb_serialize(&self, mut write_byte: impl FnMut(Option)) { macro_rules! write_bytes { ($bytes:expr) => { diff --git a/src/arch/ppc/reg/common.rs b/src/arch/ppc/reg/common.rs index 8936e3ab..16c22c8d 100644 --- a/src/arch/ppc/reg/common.rs +++ b/src/arch/ppc/reg/common.rs @@ -39,6 +39,12 @@ pub struct PowerPcCommonRegs { } impl Registers for PowerPcCommonRegs { + type ProgramCounter = u32; + + fn pc(&self) -> Self::ProgramCounter { + self.pc + } + fn gdb_serialize(&self, mut write_byte: impl FnMut(Option)) { macro_rules! write_bytes { ($bytes:expr) => { diff --git a/src/arch/riscv/reg/riscv.rs b/src/arch/riscv/reg/riscv.rs index 1dfb4655..d4951fbd 100644 --- a/src/arch/riscv/reg/riscv.rs +++ b/src/arch/riscv/reg/riscv.rs @@ -22,6 +22,12 @@ impl Registers for RiscvCoreRegs 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)) { macro_rules! write_le_bytes { ($value:expr) => { diff --git a/src/arch/traits.rs b/src/arch/traits.rs index b11c9e6d..ea29d377 100644 --- a/src/arch/traits.rs +++ b/src/arch/traits.rs @@ -30,6 +30,13 @@ impl RegId for () { /// github.com/bminor/binutils-gdb/blob/master/gdb/features/arm/arm-core.xml // TODO: add way to de/serialize arbitrary "missing"/"uncollected" registers. pub trait Registers: Default + Debug + Clone + PartialEq { + /// The type of the architecture's program counter / instruction pointer. + /// Must match with the corresponding `Arch::Usize`. + type ProgramCounter: Copy; + + /// Return the value of the program counter / instruction pointer. + fn pc(&self) -> Self::ProgramCounter; + /// Serialize `self` into a GDB register bytestream. /// /// Missing registers are serialized by passing `None` to write_byte. @@ -88,7 +95,7 @@ pub trait Arch { type Usize: PrimInt + Unsigned + BeBytes + LeBytes; /// The architecture's register file. - type Registers: Registers; + type Registers: Registers; /// The architecture's breakpoint kind, used to determine the "size" /// of breakpoint to set. See [`BreakpointKind`] for more details. diff --git a/src/arch/x86/reg/core32.rs b/src/arch/x86/reg/core32.rs index a49ee9a8..149d58cd 100644 --- a/src/arch/x86/reg/core32.rs +++ b/src/arch/x86/reg/core32.rs @@ -42,6 +42,12 @@ pub struct X86CoreRegs { } impl Registers for X86CoreRegs { + type ProgramCounter = u32; + + fn pc(&self) -> Self::ProgramCounter { + self.eip + } + fn gdb_serialize(&self, mut write_byte: impl FnMut(Option)) { macro_rules! write_bytes { ($bytes:expr) => { diff --git a/src/arch/x86/reg/core64.rs b/src/arch/x86/reg/core64.rs index 6f54581d..a70f47f5 100644 --- a/src/arch/x86/reg/core64.rs +++ b/src/arch/x86/reg/core64.rs @@ -28,6 +28,12 @@ pub struct X86_64CoreRegs { } impl Registers for X86_64CoreRegs { + type ProgramCounter = u64; + + fn pc(&self) -> Self::ProgramCounter { + self.rip + } + fn gdb_serialize(&self, mut write_byte: impl FnMut(Option)) { macro_rules! write_bytes { ($bytes:expr) => { diff --git a/src/arch/x86/reg/mod.rs b/src/arch/x86/reg/mod.rs index 46c85088..47a193ca 100644 --- a/src/arch/x86/reg/mod.rs +++ b/src/arch/x86/reg/mod.rs @@ -38,6 +38,14 @@ pub struct X87FpuInternalRegs { } impl Registers for X87FpuInternalRegs { + type ProgramCounter = u32; + + // HACK: this struct is never used as an architecture's main register file, so + // using a dummy value here is fine. + fn pc(&self) -> Self::ProgramCounter { + 0 + } + fn gdb_serialize(&self, mut write_byte: impl FnMut(Option)) { macro_rules! write_bytes { ($bytes:expr) => {