Support to pass unicorn handle to rust through FFI
This commit is contained in:
@ -128,6 +128,7 @@ impl<'a> MmioCallbackScope<'a> {
|
|||||||
|
|
||||||
pub struct UnicornInner<'a, D> {
|
pub struct UnicornInner<'a, D> {
|
||||||
pub uc: uc_handle,
|
pub uc: uc_handle,
|
||||||
|
pub ffi: bool,
|
||||||
pub arch: Arch,
|
pub arch: Arch,
|
||||||
/// to keep ownership over the hook for this uc instance's lifetime
|
/// to keep ownership over the hook for this uc instance's lifetime
|
||||||
pub hooks: Vec<(ffi::uc_hook, Box<dyn ffi::IsUcHook<'a> + 'a>)>,
|
pub hooks: Vec<(ffi::uc_hook, Box<dyn ffi::IsUcHook<'a> + 'a>)>,
|
||||||
@ -139,7 +140,7 @@ pub struct UnicornInner<'a, D> {
|
|||||||
/// Drop UC
|
/// Drop UC
|
||||||
impl<'a, D> Drop for UnicornInner<'a, D> {
|
impl<'a, D> Drop for UnicornInner<'a, D> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if !self.uc.is_null() {
|
if !self.ffi && !self.uc.is_null() {
|
||||||
unsafe { ffi::uc_close(self.uc) };
|
unsafe { ffi::uc_close(self.uc) };
|
||||||
}
|
}
|
||||||
self.uc = ptr::null_mut();
|
self.uc = ptr::null_mut();
|
||||||
@ -157,6 +158,27 @@ impl<'a> Unicorn<'a, ()> {
|
|||||||
pub fn new(arch: Arch, mode: Mode) -> Result<Unicorn<'a, ()>, uc_error> {
|
pub fn new(arch: Arch, mode: Mode) -> Result<Unicorn<'a, ()>, uc_error> {
|
||||||
Self::new_with_data(arch, mode, ())
|
Self::new_with_data(arch, mode, ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_with_handle(handle: uc_handle) -> Result<Unicorn<'a, ()>, uc_error> {
|
||||||
|
if handle == ptr::null_mut() {
|
||||||
|
return Err(uc_error::HANDLE);
|
||||||
|
}
|
||||||
|
let mut arch: libc::size_t = Default::default();
|
||||||
|
let err = unsafe { ffi::uc_query(handle, Query::ARCH, &mut arch) };
|
||||||
|
if err != uc_error::OK {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
Ok(Unicorn {
|
||||||
|
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
||||||
|
uc: handle,
|
||||||
|
ffi: true,
|
||||||
|
arch: arch.try_into()?,
|
||||||
|
data: (),
|
||||||
|
hooks: vec![],
|
||||||
|
mmio_callbacks: vec![],
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D> Unicorn<'a, D>
|
impl<'a, D> Unicorn<'a, D>
|
||||||
@ -172,6 +194,7 @@ where
|
|||||||
Ok(Unicorn {
|
Ok(Unicorn {
|
||||||
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
inner: Rc::new(UnsafeCell::from(UnicornInner {
|
||||||
uc: handle,
|
uc: handle,
|
||||||
|
ffi: false,
|
||||||
arch,
|
arch,
|
||||||
data,
|
data,
|
||||||
hooks: vec![],
|
hooks: vec![],
|
||||||
|
@ -131,6 +131,25 @@ pub enum Arch {
|
|||||||
MAX = 9,
|
MAX = 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<usize> for Arch {
|
||||||
|
type Error = uc_error;
|
||||||
|
|
||||||
|
fn try_from(v: usize) -> Result<Self, Self::Error> {
|
||||||
|
match v {
|
||||||
|
x if x == Self::ARM as usize => Ok(Self::ARM),
|
||||||
|
x if x == Self::ARM64 as usize => Ok(Self::ARM64),
|
||||||
|
x if x == Self::MIPS as usize => Ok(Self::MIPS),
|
||||||
|
x if x == Self::X86 as usize => Ok(Self::X86),
|
||||||
|
x if x == Self::PPC as usize => Ok(Self::PPC),
|
||||||
|
x if x == Self::SPARC as usize => Ok(Self::SPARC),
|
||||||
|
x if x == Self::M68K as usize => Ok(Self::M68K),
|
||||||
|
x if x == Self::RISCV as usize => Ok(Self::RISCV),
|
||||||
|
x if x == Self::MAX as usize => Ok(Self::MAX),
|
||||||
|
_ => Err(uc_error::ARCH),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Mode: i32 {
|
pub struct Mode: i32 {
|
||||||
|
Reference in New Issue
Block a user