diff options
| author | Ryan Snyder <ryan@vector35.com> | 2024-05-01 08:58:39 -0400 |
|---|---|---|
| committer | Ryan Snyder <ryan@vector35.com> | 2024-05-01 08:58:39 -0400 |
| commit | 6b268f83d6b496b2314501d5e3d03c03857573b1 (patch) | |
| tree | abd56bb55c0516abb0770c6b50bb43c1eb3d0258 /rust/src | |
| parent | e0fb8752878a5edecf5d2d768d4f9571ca9e74d7 (diff) | |
| parent | 562fbfae8aa17a2f3758710b23ec25e828d16cd6 (diff) | |
Merge branch 'name-and-type-transparent' of github.com:rbran/binaryninja-api into dev
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/architecture.rs | 8 | ||||
| -rw-r--r-- | rust/src/binaryview.rs | 16 | ||||
| -rw-r--r-- | rust/src/debuginfo.rs | 12 | ||||
| -rw-r--r-- | rust/src/types.rs | 138 |
4 files changed, 122 insertions, 52 deletions
diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index a03f28d0..b2413d39 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -313,7 +313,7 @@ pub trait Intrinsic: Sized + Clone + Copy { fn id(&self) -> u32; /// Reeturns the list of the input names and types for this intrinsic. - fn inputs(&self) -> Vec<NameAndType<String>>; + fn inputs(&self) -> Vec<Ref<NameAndType>>; /// Returns the list of the output types for this intrinsic. fn outputs(&self) -> Vec<Conf<Ref<Type>>>; @@ -650,7 +650,7 @@ impl Intrinsic for UnusedIntrinsic { fn id(&self) -> u32 { unreachable!() } - fn inputs(&self) -> Vec<NameAndType<String>> { + fn inputs(&self) -> Vec<Ref<NameAndType>> { unreachable!() } fn outputs(&self) -> Vec<Conf<Ref<Type>>> { @@ -992,7 +992,7 @@ impl Intrinsic for crate::architecture::CoreIntrinsic { self.1 } - fn inputs(&self) -> Vec<NameAndType<String>> { + fn inputs(&self) -> Vec<Ref<NameAndType>> { let mut count: usize = 0; unsafe { @@ -2423,7 +2423,7 @@ where let inputs = intrinsic.inputs(); let mut res = Vec::with_capacity(inputs.len()); for input in inputs { - res.push(input.into_raw()); + res.push(unsafe { Ref::into_raw(input) }.into_raw()); } unsafe { diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index 52d688b8..33fd9881 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -574,16 +574,24 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn define_auto_data_var(&self, dv: DataVariable) { + fn define_auto_data_var(&self, dv: &DataVariable) { unsafe { - BNDefineDataVariable(self.as_ref().handle, dv.address, &mut dv.t.into()); + BNDefineDataVariable( + self.as_ref().handle, + dv.address(), + &mut dv.type_with_confidence().into(), + ); } } /// You likely would also like to call [`Self::define_user_symbol`] to bind this data variable with a name - fn define_user_data_var(&self, dv: DataVariable) { + fn define_user_data_var(&self, dv: &DataVariable) { unsafe { - BNDefineUserDataVariable(self.as_ref().handle, dv.address, &mut dv.t.into()); + BNDefineUserDataVariable( + self.as_ref().handle, + dv.address(), + &mut dv.type_with_confidence().into(), + ); } } diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs index 08ba2517..ac398334 100644 --- a/rust/src/debuginfo.rs +++ b/rust/src/debuginfo.rs @@ -376,7 +376,7 @@ impl DebugInfo { } /// Returns a generator of all types provided by a named DebugInfoParser - pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<NameAndType<String>> { + pub fn types_by_name<S: BnStrCompatible>(&self, parser_name: S) -> Vec<Ref<NameAndType>> { let parser_name = parser_name.into_bytes_with_nul(); let mut count: usize = 0; @@ -387,10 +387,10 @@ impl DebugInfo { &mut count, ) }; - let result: Vec<NameAndType<String>> = unsafe { + let result: Vec<Ref<NameAndType>> = unsafe { slice::from_raw_parts_mut(debug_types_ptr, count) .iter() - .map(NameAndType::<String>::from_raw) + .map(NameAndType::from_raw) .collect() }; @@ -399,13 +399,13 @@ impl DebugInfo { } /// A generator of all types provided by DebugInfoParsers - pub fn types(&self) -> Vec<NameAndType<String>> { + pub fn types(&self) -> Vec<Ref<NameAndType>> { let mut count: usize = 0; let debug_types_ptr = unsafe { BNGetDebugTypes(self.handle, ptr::null_mut(), &mut count) }; - let result: Vec<NameAndType<String>> = unsafe { + let result: Vec<Ref<NameAndType>> = unsafe { slice::from_raw_parts_mut(debug_types_ptr, count) .iter() - .map(NameAndType::<String>::from_raw) + .map(NameAndType::from_raw) .collect() }; diff --git a/rust/src/types.rs b/rust/src/types.rs index 85405b5e..f886228e 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -56,6 +56,7 @@ pub type MemberScope = BNMemberScope; //////////////// // Confidence +/// Compatible with the `BNType*WithConfidence` types pub struct Conf<T> { pub contents: T, pub confidence: u8, @@ -698,6 +699,7 @@ impl Drop for TypeBuilder { ////////// // Type +#[repr(transparent)] pub struct Type { pub(crate) handle: *mut BNType, } @@ -2447,13 +2449,11 @@ unsafe impl CoreArrayWrapper for QualifiedNameTypeAndId { ////////////////////////// // NameAndType -pub struct NameAndType<S: BnStrCompatible> { - pub name: S, - pub t: Conf<Ref<Type>>, -} +#[repr(transparent)] +pub struct NameAndType(pub(crate) BNNameAndType); -impl NameAndType<String> { - pub(crate) fn from_raw(raw: &BNNameAndType) -> Self { +impl NameAndType { + pub(crate) fn from_raw(raw: &BNNameAndType) -> Ref<Self> { Self::new( raw_to_string(raw.name).unwrap(), unsafe { &Type::ref_from_raw(raw.type_) }, @@ -2462,43 +2462,73 @@ impl NameAndType<String> { } } -impl<S: BnStrCompatible> NameAndType<S> { - pub fn new(name: S, t: &Ref<Type>, confidence: u8) -> Self { - Self { - name, - t: Conf::new(t.clone(), confidence), +impl NameAndType { + pub fn new<S: BnStrCompatible>(name: S, t: &Type, confidence: u8) -> Ref<Self> { + unsafe { + Ref::new(Self(BNNameAndType { + name: BNAllocString(name.into_bytes_with_nul().as_ref().as_ptr() as *mut _), + type_: Ref::into_raw(t.to_owned()).handle, + typeConfidence: confidence, + })) } } pub(crate) fn into_raw(self) -> BNNameAndType { - let t = self.t.clone(); - let res = BNNameAndType { - name: BnString::new(self.name).into_raw(), - type_: t.contents.handle, - typeConfidence: self.t.confidence, - }; - mem::forget(t); - res + self.0 } - pub fn type_with_confidence(&self) -> Conf<Ref<Type>> { - self.t.clone() + pub fn name(&self) -> &str { + let c_str = unsafe { CStr::from_ptr(self.0.name) }; + c_str.to_str().unwrap() + } + + pub fn t(&self) -> &Type { + unsafe { mem::transmute::<_, &Type>(&self.0.type_) } + } + + pub fn type_with_confidence(&self) -> Conf<&Type> { + Conf::new(self.t(), self.0.typeConfidence) + } +} + +impl ToOwned for NameAndType { + type Owned = Ref<Self>; + + fn to_owned(&self) -> Self::Owned { + unsafe { RefCountable::inc_ref(self) } + } +} + +unsafe impl RefCountable for NameAndType { + unsafe fn inc_ref(handle: &Self) -> Ref<Self> { + Self::new( + CStr::from_ptr(handle.0.name), + handle.t(), + handle.type_with_confidence().confidence, + ) + } + + unsafe fn dec_ref(handle: &Self) { + unsafe { + BNFreeString(handle.0.name); + RefCountable::dec_ref(handle.t()); + } } } -impl<S: BnStrCompatible> CoreArrayProvider for NameAndType<S> { +impl CoreArrayProvider for NameAndType { type Raw = BNNameAndType; type Context = (); } -unsafe impl<S: BnStrCompatible> CoreOwnedArrayProvider for NameAndType<S> { +unsafe impl CoreOwnedArrayProvider for NameAndType { unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) { BNFreeNameAndTypeList(raw, count); } } -unsafe impl<S: BnStrCompatible> CoreArrayWrapper for NameAndType<S> { - type Wrapped<'a> = &'a NameAndType<S> where S: 'a; +unsafe impl CoreArrayWrapper for NameAndType { + type Wrapped<'a> = &'a NameAndType; unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { mem::transmute(raw) @@ -2508,29 +2538,61 @@ unsafe impl<S: BnStrCompatible> CoreArrayWrapper for NameAndType<S> { ////////////////// // DataVariable -pub struct DataVariable { - pub address: u64, - pub t: Conf<Ref<Type>>, - pub auto_discovered: bool, -} +#[repr(transparent)] +pub struct DataVariable(pub(crate) BNDataVariable); // impl DataVariable { // pub(crate) fn from_raw(var: &BNDataVariable) -> Self { -// Self { -// address: var.address, -// t: Conf::new(unsafe { Type::ref_from_raw(var.type_) }, var.typeConfidence), -// auto_discovered: var.autoDiscovered, -// } +// let var = DataVariable(*var); +// Self(BNDataVariable { +// type_: unsafe { Ref::into_raw(var.t().to_owned()).handle }, +// ..var.0 +// }) // } // } impl DataVariable { - pub fn type_with_confidence(&self) -> Conf<Ref<Type>> { - Conf::new(self.t.contents.clone(), self.t.confidence) + pub fn address(&self) -> u64 { + self.0.address + } + + pub fn auto_discovered(&self) -> bool { + self.0.autoDiscovered + } + + pub fn t(&self) -> &Type { + unsafe { mem::transmute(&self.0.type_) } + } + + pub fn type_with_confidence(&self) -> Conf<&Type> { + Conf::new(self.t(), self.0.typeConfidence) } pub fn symbol(&self, bv: &BinaryView) -> Option<Ref<Symbol>> { - bv.symbol_by_address(self.address).ok() + bv.symbol_by_address(self.0.address).ok() + } +} + +impl ToOwned for DataVariable { + type Owned = Ref<Self>; + + fn to_owned(&self) -> Self::Owned { + unsafe { RefCountable::inc_ref(self) } + } +} + +unsafe impl RefCountable for DataVariable { + unsafe fn inc_ref(handle: &Self) -> Ref<Self> { + unsafe { + Ref::new(Self(BNDataVariable { + type_: Ref::into_raw(handle.t().to_owned()).handle, + ..handle.0 + })) + } + } + + unsafe fn dec_ref(handle: &Self) { + unsafe { BNFreeType(handle.0.type_) } } } |
