Skip to content

Commit

Permalink
add 'write register' command of the RSP protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
thomashk0 committed Sep 5, 2020
1 parent fbdd3d4 commit e33d4b6
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/gdbstub_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
target.read_register(reg_id, dst).maybe_missing_impl()?;
res.write_hex_buf(dst)?;
}
Command::P(p) => {
let reg = <<T::Arch as Arch>::Registers as Registers>::RegId::from_raw_id(p.reg_id);
let (reg_id, _) = match reg {
Some(v) => v,
None => return Ok(None),
};
target.write_register(reg_id, p.val).maybe_missing_impl()?;
res.write_str("OK")?;
}
Command::vCont(cmd) => {
use crate::protocol::_vCont::VContKind;

Expand Down Expand Up @@ -454,14 +463,14 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
res,
target,
&mut core::iter::once((self.current_tid.tid, ResumeAction::Continue)),
)
);
}
Command::s(_) => {
return self.do_vcont(
res,
target,
&mut core::iter::once((self.current_tid.tid, ResumeAction::Step)),
)
);
}

// ------------------- Multi-threading Support ------------------ //
Expand Down
1 change: 1 addition & 0 deletions src/protocol/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ commands! {
"z" => _z::z,
"Z" => _z_upcase::Z,
"p" => _p::p,
"P" => _p_upcase::P<'a>,
// Order Matters (because of prefix matching)
"vCont?" => vCont_question_mark::vContQuestionMark,
"vCont" => _vCont::vCont<'a>,
Expand Down
17 changes: 17 additions & 0 deletions src/protocol/commands/_p_upcase.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use super::prelude::*;

#[derive(PartialEq, Eq, Debug)]
pub struct P<'a> {
pub reg_id: usize,
pub val: &'a [u8]
}

impl<'a> ParseCommand<'a> for P<'a> {
fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
let body = buf.into_body();
let mut body = body.split_mut(|&b| b == b'=');
let reg_id = decode_hex(body.next()?).ok()?;
let val = decode_hex_buf(body.next()?).ok()?;
Some(P { reg_id, val })
}
}
21 changes: 21 additions & 0 deletions src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,19 @@ pub trait Target {
regs: &<Self::Arch as Arch>::Registers,
) -> Result<(), Self::Error>;

/// Write a single register on the target.
///
/// On multi-threaded systems, this method **must** respect the currently
/// selected thread (set via the `set_current_thread` method).
fn write_register(
&mut self,
reg_id: <<Self::Arch as Arch>::Registers as Registers>::RegId,
val: &[u8],
) -> OptResult<(), Self::Error> {
let _ = (reg_id, val);
Err(MaybeUnimpl::no_impl())
}

/// Read bytes from the specified address range.
///
/// ### Handling non-fatal invalid memory reads
Expand Down Expand Up @@ -414,6 +427,14 @@ macro_rules! impl_dyn_target {
(**self).write_registers(regs)
}

fn write_register(
&mut self,
reg_number: <<Self::Arch as Arch>::Registers as Registers>::RegId,
val: &[u8],
) -> OptResult<(), Self::Error> {
(**self).write_register(reg_number, val)
}

fn read_addrs(
&mut self,
start_addr: <Self::Arch as Arch>::Usize,
Expand Down

0 comments on commit e33d4b6

Please sign in to comment.