Implements read_addrs (#1060)

Co-authored-by: tompro <tomas.prochazka@apertia.cz>
This commit is contained in:
SuchAFuriousDeath 2024-10-22 23:18:16 +02:00 committed by GitHub
parent 01693fa90d
commit 6643a4db22
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 75 additions and 26 deletions

View File

@ -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),
}

View File

@ -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;
}
},

View File

@ -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> {

View File

@ -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();