Skip to content

Commit

Permalink
add Registers::pc method
Browse files Browse the repository at this point in the history
If #29 is ever resolved, a similar method could be added to `RegId`,
enabling more efficient `pc` queries. Note that the less efficient
approach would still need to be supported, as the ability to query
individual registers is not a required feature implemented by all
targets.
  • Loading branch information
daniel5151 committed Jan 4, 2021
1 parent 131f059 commit cca6bd2
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/arch/arm/reg/arm_core.rs
Expand Up @@ -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<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
Expand Down
6 changes: 6 additions & 0 deletions src/arch/mips/reg/mips.rs
Expand Up @@ -54,6 +54,12 @@ impl<U> Registers for MipsCoreRegs<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_le_bytes {
($value:expr) => {
Expand Down
2 changes: 1 addition & 1 deletion src/arch/msp430/mod.rs
Expand Up @@ -15,7 +15,7 @@ pub enum Msp430<RegIdImpl: RegId> {
}

impl<RegIdImpl: RegId> Arch for Msp430<RegIdImpl> {
type Usize = u32;
type Usize = u16;
type Registers = reg::Msp430Regs;
type RegId = RegIdImpl;
type BreakpointKind = usize;
Expand Down
6 changes: 6 additions & 0 deletions src/arch/msp430/reg/msp430.rs
Expand Up @@ -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<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
Expand Down
6 changes: 6 additions & 0 deletions src/arch/ppc/reg/common.rs
Expand Up @@ -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<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
Expand Down
6 changes: 6 additions & 0 deletions src/arch/riscv/reg/riscv.rs
Expand Up @@ -22,6 +22,12 @@ impl<U> Registers for RiscvCoreRegs<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_le_bytes {
($value:expr) => {
Expand Down
9 changes: 8 additions & 1 deletion src/arch/traits.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -88,7 +95,7 @@ pub trait Arch {
type Usize: PrimInt + Unsigned + BeBytes + LeBytes;

/// The architecture's register file.
type Registers: Registers;
type Registers: Registers<ProgramCounter = Self::Usize>;

/// The architecture's breakpoint kind, used to determine the "size"
/// of breakpoint to set. See [`BreakpointKind`] for more details.
Expand Down
6 changes: 6 additions & 0 deletions src/arch/x86/reg/core32.rs
Expand Up @@ -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<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
Expand Down
6 changes: 6 additions & 0 deletions src/arch/x86/reg/core64.rs
Expand Up @@ -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<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
Expand Down
8 changes: 8 additions & 0 deletions src/arch/x86/reg/mod.rs
Expand Up @@ -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<u8>)) {
macro_rules! write_bytes {
($bytes:expr) => {
Expand Down

0 comments on commit cca6bd2

Please sign in to comment.