gdbstub 0.6.3

An implementation of the GDB Remote Serial Protocol in Rust
Documentation
//! Support for single-register read/write access.

use crate::arch::Arch;
use crate::target::{Target, TargetResult};

/// Target Extension - Support for single-register access.
///
/// While this is an optional feature, it is **highly recommended** to
/// implement it when possible, as it can significantly improve performance
/// on certain architectures.
///
/// If this extension is not implemented, the GDB client will fall-back to
/// accessing _all_ registers, even in cases where it only requires knowing a
/// single register's value.
///
/// Moreover, certain architectures have registers that are not accessible as
/// part of the default default register file used by the `read/write_registers`
/// methods, and can only be accessed via this extension (e.g: the RISC-V
/// Control and Status registers).
pub trait SingleRegisterAccess<Tid>: Target
where
    Tid: crate::is_valid_tid::IsValidTid,
{
    /// Read to a single register on the target.
    ///
    /// The `tid` field identifies which thread the value should be read from.
    /// On single threaded targets, `tid` is set to `()` and can be ignored.
    ///
    /// Implementations should write the value of the register using target's
    /// native byte order in the buffer `buf`.
    ///
    /// Return the number of bytes written into `buf` or `0` if the register is
    /// valid but unavailable.
    ///
    /// If the requested register could not be accessed, an appropriate
    /// non-fatal error should be returned.
    fn read_register(
        &mut self,
        tid: Tid,
        reg_id: <Self::Arch as Arch>::RegId,
        buf: &mut [u8],
    ) -> TargetResult<usize, Self>;

    /// Write from a single register on the target.
    ///
    /// The `tid` field identifies which thread the value should be written to.
    /// On single threaded targets, `tid` is set to `()` and can be ignored.
    ///
    /// The `val` buffer contains the new value of the register in the target's
    /// native byte order. It is guaranteed to be the exact length as the target
    /// register.
    ///
    /// If the requested register could not be accessed, an appropriate
    /// non-fatal error should be returned.
    fn write_register(
        &mut self,
        tid: Tid,
        reg_id: <Self::Arch as Arch>::RegId,
        val: &[u8],
    ) -> TargetResult<(), Self>;
}

/// See [`SingleRegisterAccess`]
pub type SingleRegisterAccessOps<'a, Tid, T> =
    &'a mut dyn SingleRegisterAccess<Tid, Arch = <T as Target>::Arch, Error = <T as Target>::Error>;