summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorRyan Snyder <ryan@vector35.com>2024-05-01 08:58:39 -0400
committerRyan Snyder <ryan@vector35.com>2024-05-01 08:58:39 -0400
commit6b268f83d6b496b2314501d5e3d03c03857573b1 (patch)
treeabd56bb55c0516abb0770c6b50bb43c1eb3d0258 /rust/src
parente0fb8752878a5edecf5d2d768d4f9571ca9e74d7 (diff)
parent562fbfae8aa17a2f3758710b23ec25e828d16cd6 (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.rs8
-rw-r--r--rust/src/binaryview.rs16
-rw-r--r--rust/src/debuginfo.rs12
-rw-r--r--rust/src/types.rs138
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_) }
}
}