Support saving and restoring registers

This commit is contained in:
momo5502
2025-04-01 18:23:24 +02:00
parent 7222c0fc1d
commit fd018c46b4
3 changed files with 56 additions and 7 deletions

View File

@@ -251,6 +251,26 @@ impl IcicleEmulator {
return res.is_ok();
}
pub fn save_registers(&self) -> Vec<u8> {
const REG_SIZE: usize = std::mem::size_of::<icicle_cpu::Regs>();
unsafe {
let data: [u8; REG_SIZE] = self.vm.cpu.regs.read_at(0);
return data.to_vec();
}
}
pub fn restore_registers(&mut self, data: &[u8]) {
const REG_SIZE: usize = std::mem::size_of::<icicle_cpu::Regs>();
let mut buffer: [u8; REG_SIZE] = [0; REG_SIZE];
let size = std::cmp::min(REG_SIZE, data.len());
buffer.copy_from_slice(&data[..size]);
unsafe {
self.vm.cpu.regs.write_at(0, buffer);
};
}
pub fn read_register(&mut self, reg: X64Register, buffer: &mut [u8]) -> usize {
let reg_node = self.reg.get_node(reg);

View File

@@ -25,6 +25,8 @@ pub fn icicle_start(ptr: *mut c_void) {
}
}
type RawFunction = extern "C" fn(*mut c_void);
type DataFunction = extern "C" fn(*mut c_void, *const c_void, usize);
type MmioReadFunction = extern "C" fn(*mut c_void, u64, usize, *mut c_void);
type MmioWriteFunction = extern "C" fn(*mut c_void, u64, usize, *const c_void);
@@ -98,6 +100,24 @@ pub fn icicle_write_memory(
}
}
#[unsafe(no_mangle)]
pub fn icicle_save_registers(ptr: *mut c_void, accessor: DataFunction, accessor_data: *mut c_void) {
unsafe {
let emulator = &mut *(ptr as *mut IcicleEmulator);
let registers = emulator.save_registers();
accessor(accessor_data, registers.as_ptr() as *const c_void, registers.len());
}
}
#[unsafe(no_mangle)]
pub fn icicle_restore_registers(ptr: *mut c_void, data: *const c_void, size: usize) {
unsafe {
let emulator = &mut *(ptr as *mut IcicleEmulator);
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
emulator.restore_registers(u8_slice);
}
}
#[unsafe(no_mangle)]
pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, size: usize) -> i32 {
unsafe {
@@ -108,10 +128,8 @@ pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, siz
}
}
type CFunctionPointer = extern "C" fn(*mut c_void);
#[unsafe(no_mangle)]
pub fn icicle_add_syscall_hook(ptr: *mut c_void, callback: CFunctionPointer, data: *mut c_void) {
pub fn icicle_add_syscall_hook(ptr: *mut c_void, callback: RawFunction, data: *mut c_void) {
unsafe {
let emulator = &mut *(ptr as *mut IcicleEmulator);
emulator.add_syscall_hook(Box::new(move || callback(data)));