rust add tlb callback

This commit is contained in:
Philipp Takacs
2023-04-05 11:26:02 +02:00
committed by Kevin Schneider
parent 0729dc0312
commit a9f0dabc64
4 changed files with 103 additions and 2 deletions

View File

@@ -3,7 +3,7 @@
use crate::{Unicorn, UnicornInner};
use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query};
use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query, TlbEntry};
use alloc::rc::Weak;
use core::{cell::UnsafeCell, ffi::c_void};
use libc::{c_char, c_int};
@@ -252,3 +252,25 @@ where
debug_assert_eq!(uc, user_data_uc.get_handle());
(user_data.callback)(&mut user_data_uc);
}
pub extern "C" fn tlb_lookup_hook_proxy<D, F>(uc: uc_handle, vaddr: u64, mem_type: MemType, result: *mut TlbEntry, user_data: *mut UcHook<D, F>) -> bool
where
F: FnMut(&mut crate::Unicorn<D>, u64, MemType) -> Option<TlbEntry>,
{
let user_data = unsafe { &mut *user_data };
let mut user_data_uc = Unicorn {
inner: user_data.uc.upgrade().unwrap(),
};
debug_assert_eq!(uc, user_data_uc.get_handle());
let r = (user_data.callback)(&mut user_data_uc, vaddr, mem_type);
match r {
Some(ref e) => {
unsafe {
let ref_result: &mut TlbEntry = &mut *result;
*ref_result = *e;
}
},
None => {},
};
return r.is_some();
}

View File

@@ -885,6 +885,33 @@ impl<'a, D> Unicorn<'a, D> {
}
}
pub fn add_tlb_hook<F>(&mut self, begin: u64, end: u64, callback: F) -> Result<ffi::uc_hook, uc_error>
where
F: FnMut(&mut crate::Unicorn<D>, u64, MemType) -> Option<TlbEntry> + 'a,
{
let mut hook_ptr = core::ptr::null_mut();
let mut user_data = Box::new(ffi::UcHook {
callback,
uc: Rc::downgrade(&self.inner),
});
let err = unsafe {
ffi::uc_hook_add(self.get_handle(),
&mut hook_ptr,
HookType::TLB,
ffi::tlb_lookup_hook_proxy::<D, F> as _,
user_data.as_mut() as *mut _ as _,
begin,
end,
)
};
if err == uc_error::OK {
self.inner_mut().hooks.push((hook_ptr, user_data));
Ok(hook_ptr)
} else {
Err(err)
}
}
/// Remove a hook.
///
/// `hook` is the value returned by `add_*_hook` functions.

View File

@@ -93,6 +93,8 @@ bitflags! {
const MEM_INVALID = Self::MEM_READ_INVALID.bits | Self::MEM_WRITE_INVALID.bits | Self::MEM_FETCH_INVALID.bits;
const MEM_ALL = Self::MEM_VALID.bits | Self::MEM_INVALID.bits;
const TLB = (1 << 17);
}
}
@@ -239,3 +241,10 @@ pub enum ControlType {
UC_CTL_IO_READ = 1<<31,
UC_CTL_IO_WRITE = 1<<30,
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct TlbEntry {
pub paddr: u64,
pub perms: Permission,
}