Files
yggdrasil/userspace/lib/cross/src/process.rs
T

65 lines
1.9 KiB
Rust

use std::io;
#[derive(Debug)]
pub enum TraceEvent {
SyscallEntry(u64, [u64; 6]),
SyscallExit(i64),
Exited,
}
pub trait ChildTrace {
fn next_event(&mut self) -> io::Result<TraceEvent>;
fn resume(&mut self) -> io::Result<()>;
fn kill(&mut self) -> io::Result<()>;
unsafe fn peek_u8(&mut self, address: usize) -> io::Result<u8> {
let aligned = address & !7;
let shift = (address & 7) << 3;
let word = self.peek_u64(aligned)?;
Ok((word >> shift) as u8)
}
unsafe fn peek_u32(&mut self, address: usize) -> io::Result<u32> {
eprintln!("PEEK U32 @ {address:#x}");
assert_eq!(address & 3, 0);
let aligned = address & !7;
let shift = (address & 7) << 3;
let word = self.peek_u64(aligned)?;
Ok((word >> shift) as u32)
}
unsafe fn peek_u64(&mut self, address: usize) -> io::Result<u64>;
unsafe fn peek_bytes(&mut self, address: usize, buffer: &mut [u8]) -> io::Result<()> {
for i in 0..buffer.len() {
buffer[i] = self.peek_u8(address + i)?;
}
Ok(())
}
unsafe fn peek_cstr(&mut self, address: usize, buffer: &mut [u8]) -> io::Result<usize> {
let mut len = 0;
while len < buffer.len() - 1 {
let byte = self.peek_u8(address + len)?;
buffer[len] = byte;
if byte == 0 {
break;
}
len += 1;
}
Ok(len)
}
unsafe fn peek_usize(&mut self, address: usize) -> io::Result<usize> {
// FIXME I only support 64-bit archs
Ok(self.peek_u64(address)? as _)
}
}
pub trait CommandSpawnExt {
type ChildTrace: ChildTrace;
fn create_session(&mut self) -> io::Result<&mut Self>;
fn create_process_group(&mut self) -> io::Result<&mut Self>;
// TODO options for tracing across subchildren, etc
fn spawn_with_trace(&mut self) -> io::Result<Self::ChildTrace>;
}