in reverie-ptrace/src/task.rs [1916:1944]
fn read_inferior_memory(&self, addr: u64, mut size: usize) -> Result<Vec<u8>, TraceError> {
let task = self.assume_stopped();
// NB: dont' trust size to be sane blindly.
if size > 0x8000 {
size = 0x8000;
}
let mut res = vec![0; size];
if let Some(addr) = Addr::from_raw(addr as usize) {
let nb = task.read(addr, &mut res)?;
res.resize(nb, 0);
}
// There could be a software breakpoint within the address requested,
// we should return the orignal contents without the breakpoint insn.
// This is *not* documented in gdb remote protocol, however, both
// gdbserver and rr does this. see:
// rr: https://github.com/rr-debugger/rr/blob/master/src/GdbServer.cc#L561
// gdbserver: https://github.com/bminor/binutils-gdb/blob/master/gdbserver/mem-break.cc#L1914
for (bkpt, saved_insn) in self.breakpoints.iter() {
if (addr..addr + res.len() as u64).contains(bkpt) {
// This abuses bkpt insn 0xcc is single byte.
res[*bkpt as usize - addr as usize] = *saved_insn as u8;
}
}
Ok(res)
}