Skip to content

Rust bindings are not exaustive and do not exploit rust typing #2194

Open
@amaelFr

Description

@amaelFr

Hello

I'm a regular user of your fantastic project.

A few month ago I start used it more often and mainly in rust.
Where I find out the binding is not exploiting the full capabilities of it (mainly typing).
Ex:
Registers enum are pass to read/ write function under Into<i32>
Moreover the reg_read wrapper don't let us read CP_REG (for exemple under arm64)

if I may suggest you a little work around using
a trait

Trait Register {
    fn id(&self) -> i32;

    fn get_val_ptr(&self) -> *mut core::ffi::c_void {
        let val:alloc::boxed::Box<u64> = alloc::boxed::Box::new(0u64);
        alloc::boxed::Box::into_raw(val) as *mut core::ffi::c_void
    }

    fn get_val(&self, val_ptr: *const core::ffi::c_void) -> u64 {
        unsafe{ *(val_ptr as *const u64) }
    }
}

#[macro_export]
macro_rules! register_impl {
    ($name:ident) => {
        impl crate::Register for $name {
            fn id(&self) -> i32 {
                (*self).into()
            }
        }
    }
}

the trait will be used in reg_read/ write

and will be implement for a CPRegisterARM64 struct

Such impl using return a ref to the heap is not a proper way

An other more beautifull path i think is the used of a traint combined with any trait

use std::any::Any;
trait Register {
    fn id(&self) -> i32;
}

trait AnyRegister: Any+Register {}
impl<T: Any + Register> AnyRegister for T {}

#[macro_export]
macro_rules! register_impl {
    ($name:ident) => {
        impl crate::Register for $name {
            fn id(&self) -> i32 {
                (*self).into()
            }
        }
    }
}

In such way which will let us develop fucntion in a more regular way

    pub fn reg_read(&self, reg: &(dyn AnyRegister)) -> Result<u64, uc_error> // reg_no_ref
    {
        Ok(match reg.type_id() {
            #[cfg(feature="aarch64")]
            TypeId::of::<CPRegisterARM64> => { 
                let cp_reg:_CPRegisterARM64 = reg.downcast_ref_unchecked::<CPRegisterARM64>().clone().into();
                unsafe { ffi::uc_reg_read(self.get_handle(), RegisterARM64::CP_REG as i32, &mut cp_reg_id as *mut _ as *mut core::ffi::c_void) };
                    cp_reg_id
            }

            _ => {
                let mut value: u64 = 0;
                unsafe { ffi::uc_reg_read(self.get_handle(), reg.id(), &mut value as *mut u64 as _) };
                    value
            }
        })
    }

Let me know if you are interested in a way or another in such code

Have a good day

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions