mirror of
https://github.com/obhq/obliteration.git
synced 2024-11-26 20:50:22 +00:00
Implements read_addrs (#1060)
Co-authored-by: tompro <tomas.prochazka@apertia.cz>
This commit is contained in:
parent
01693fa90d
commit
6643a4db22
@ -35,12 +35,21 @@ impl Debuggee {
|
||||
pub fn get_regs(&mut self) -> Option<GdbRegs> {
|
||||
self.sender.send(DebugReq::GetRegs).ok()?;
|
||||
self.locked = true;
|
||||
self.receiver
|
||||
.recv()
|
||||
.map(|v| match v {
|
||||
DebugRes::Regs(v) => v,
|
||||
})
|
||||
.ok()
|
||||
self.receiver.recv().ok().map(|v| match v {
|
||||
DebugRes::Regs(v) => v,
|
||||
_ => panic!("unexpected response when getting registers {v:?}"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn translate_address(&mut self, addr: usize) -> Option<usize> {
|
||||
self.sender.send(DebugReq::TranslateAddress(addr)).ok()?;
|
||||
|
||||
self.locked = true;
|
||||
|
||||
self.receiver.recv().ok().map(|v| match v {
|
||||
DebugRes::TranslatedAddress(v) => v,
|
||||
_ => panic!("unexpected response when translating address {v:?}"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn lock(&mut self) {
|
||||
@ -67,18 +76,22 @@ impl Debugger {
|
||||
}
|
||||
|
||||
pub fn send(&self, r: DebugRes) {
|
||||
self.sender.send(r).ok();
|
||||
let _ = self.sender.send(r);
|
||||
}
|
||||
}
|
||||
|
||||
/// Debug request from a debugger to a debuggee.
|
||||
#[derive(Debug)]
|
||||
pub enum DebugReq {
|
||||
GetRegs,
|
||||
Lock,
|
||||
Release,
|
||||
TranslateAddress(usize),
|
||||
}
|
||||
|
||||
/// Debug response from a debuggee to a debugger.
|
||||
#[derive(Debug)]
|
||||
pub enum DebugRes {
|
||||
Regs(GdbRegs),
|
||||
TranslatedAddress(usize),
|
||||
}
|
||||
|
@ -256,16 +256,6 @@ impl<H: Hypervisor, S: Screen> CpuManager<H, S> {
|
||||
cpu: &mut impl Cpu,
|
||||
stop: Option<MultiThreadStopReason<u64>>,
|
||||
) -> bool {
|
||||
// Get states.
|
||||
let mut states = match cpu.states() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
let e = RustError::with_source("couldn't get CPU states", e);
|
||||
unsafe { args.event.invoke(VmmEvent::Error { reason: &e }) };
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Convert stop reason.
|
||||
let stop = match stop {
|
||||
Some(_) => todo!(),
|
||||
@ -285,10 +275,34 @@ impl<H: Hypervisor, S: Screen> CpuManager<H, S> {
|
||||
};
|
||||
|
||||
match req {
|
||||
DebugReq::GetRegs => match Self::get_debug_regs(&mut states) {
|
||||
Ok(v) => debug.send(DebugRes::Regs(v)),
|
||||
DebugReq::GetRegs => {
|
||||
// Get states.
|
||||
let mut states = match cpu.states() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
let e = RustError::with_source("couldn't get CPU states", e);
|
||||
unsafe { args.event.invoke(VmmEvent::Error { reason: &e }) };
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
match Self::get_debug_regs(&mut states) {
|
||||
Ok(v) => debug.send(DebugRes::Regs(v)),
|
||||
Err(e) => {
|
||||
unsafe { args.event.invoke(VmmEvent::Error { reason: &e }) };
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
DebugReq::TranslateAddress(addr) => match cpu.translate(addr) {
|
||||
Ok(v) => debug.send(DebugRes::TranslatedAddress(v)),
|
||||
Err(e) => {
|
||||
unsafe { args.event.invoke(VmmEvent::Error { reason: &e }) };
|
||||
let err = RustError::with_source(
|
||||
format! {"couldn't translate address {addr}"},
|
||||
e,
|
||||
);
|
||||
|
||||
unsafe { args.event.invoke(VmmEvent::Error { reason: &err }) };
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
@ -17,6 +17,7 @@ use std::num::NonZero;
|
||||
use thiserror::Error;
|
||||
|
||||
const ENOENT: u8 = 2;
|
||||
const EFAULT: u8 = 14;
|
||||
|
||||
pub type GdbRegs = gdbstub_arch::x86::reg::X86_64CoreRegs;
|
||||
|
||||
@ -66,11 +67,31 @@ impl<H: Hypervisor, S: Screen> MultiThreadBase for CpuManager<H, S> {
|
||||
data: &mut [u8],
|
||||
tid: Tid,
|
||||
) -> TargetResult<usize, Self> {
|
||||
let mut _cpu = self.get_cpu(tid)?;
|
||||
let Some(len) = NonZero::new(data.len()) else {
|
||||
return Ok(0);
|
||||
};
|
||||
|
||||
let cpu = self.get_cpu(tid)?;
|
||||
|
||||
let translated = cpu
|
||||
.debug_mut()
|
||||
.unwrap()
|
||||
.translate_address(start_addr.try_into().unwrap())
|
||||
.ok_or(GdbTargetError::Errno(ENOENT))?;
|
||||
|
||||
drop(cpu);
|
||||
|
||||
let ram = self.hv.ram();
|
||||
|
||||
todo!()
|
||||
let locked_addr = ram
|
||||
.lock(translated, len)
|
||||
.ok_or(GdbTargetError::Errno(EFAULT))?;
|
||||
|
||||
data.copy_from_slice(unsafe {
|
||||
std::slice::from_raw_parts(locked_addr.as_ptr(), len.get())
|
||||
});
|
||||
|
||||
Ok(len.get())
|
||||
}
|
||||
|
||||
fn write_addrs(&mut self, start_addr: u64, data: &[u8], tid: Tid) -> TargetResult<(), Self> {
|
||||
|
@ -35,7 +35,7 @@ impl<'a> RamBuilder<'a> {
|
||||
assert!(self.kern.is_none());
|
||||
|
||||
let addr = self.next;
|
||||
let mem = unsafe { self.ram.alloc(addr, len)? };
|
||||
let mem = self.ram.alloc(addr, len)?;
|
||||
|
||||
self.kern = Some(addr..(addr + len.get()));
|
||||
self.next += len.get();
|
||||
@ -51,7 +51,7 @@ impl<'a> RamBuilder<'a> {
|
||||
|
||||
let addr = self.next;
|
||||
|
||||
unsafe { self.ram.alloc(addr, len) }?;
|
||||
self.ram.alloc(addr, len)?;
|
||||
|
||||
self.stack = Some(addr..(addr + len.get()));
|
||||
self.next += len.get();
|
||||
@ -73,7 +73,8 @@ impl<'a> RamBuilder<'a> {
|
||||
.and_then(|len| len.checked_next_multiple_of(self.ram.block_size.get()))
|
||||
.and_then(NonZero::new)
|
||||
.unwrap();
|
||||
let args = unsafe { self.ram.alloc(addr, len)? };
|
||||
|
||||
let args = self.ram.alloc(addr, len)?;
|
||||
let mut w = ArgsWriter { mem: args, next: 0 };
|
||||
|
||||
// Write arguments.
|
||||
@ -345,7 +346,7 @@ impl<'a> RamBuilder<'a> {
|
||||
assert_eq!(addr % 4096, 0);
|
||||
|
||||
// Allocate.
|
||||
let tab = unsafe { self.ram.alloc(addr, len).map(|v| v.as_mut_ptr().cast())? };
|
||||
let tab = self.ram.alloc(addr, len).map(|v| v.as_mut_ptr().cast())?;
|
||||
|
||||
self.next += len.get();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user