summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorMason Reed <35282038+emesare@users.noreply.github.com>2025-12-15 19:41:38 -0500
committerGitHub <noreply@github.com>2025-12-15 19:41:38 -0500
commit2e5b893b79e053dbacd8a72cc900d1af1d825041 (patch)
tree4f44f4332f2453492fd747725a4ce8546e116754 /rust/src
parent8e409a0854292eb7e61420b7bfc904a1156b4a68 (diff)
[Rust] Return Array in more debug info functions (#7744)
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/debuginfo.rs104
-rw-r--r--rust/src/variable.rs30
2 files changed, 44 insertions, 90 deletions
diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs
index a4d0b139..02bf1ebb 100644
--- a/rust/src/debuginfo.rs
+++ b/rust/src/debuginfo.rs
@@ -78,6 +78,7 @@ use binaryninjacore_sys::*;
use std::ffi::c_void;
use crate::progress::{NoProgressCallback, ProgressCallback};
+use crate::string::strings_to_string_list;
use crate::variable::{NamedDataVariableWithType, NamedVariableWithType};
use crate::{
binary_view::BinaryView,
@@ -417,36 +418,19 @@ impl DebugInfo {
}
/// Returns all types within the parser
- pub fn types_by_name(&self, parser_name: &str) -> Vec<NameAndType> {
+ pub fn types_by_name(&self, parser_name: &str) -> Array<NameAndType> {
let parser_name = parser_name.to_cstr();
-
let mut count: usize = 0;
let debug_types_ptr =
unsafe { BNGetDebugTypes(self.handle, parser_name.as_ptr(), &mut count) };
- let result: Vec<_> = unsafe {
- std::slice::from_raw_parts_mut(debug_types_ptr, count)
- .iter()
- .map(NameAndType::from_raw)
- .collect()
- };
-
- unsafe { BNFreeDebugTypes(debug_types_ptr, count) };
- result
+ unsafe { Array::new(debug_types_ptr, count, ()) }
}
- pub fn types(&self) -> Vec<NameAndType> {
+ pub fn types(&self) -> Array<NameAndType> {
let mut count: usize = 0;
let debug_types_ptr =
unsafe { BNGetDebugTypes(self.handle, std::ptr::null_mut(), &mut count) };
- let result: Vec<_> = unsafe {
- std::slice::from_raw_parts_mut(debug_types_ptr, count)
- .iter()
- .map(NameAndType::from_raw)
- .collect()
- };
-
- unsafe { BNFreeDebugTypes(debug_types_ptr, count) };
- result
+ unsafe { Array::new(debug_types_ptr, count, ()) }
}
/// Returns all functions within the parser
@@ -485,38 +469,19 @@ impl DebugInfo {
}
/// Returns all data variables within the parser
- pub fn data_variables_by_name(&self, parser_name: &str) -> Vec<NamedDataVariableWithType> {
+ pub fn data_variables_by_name(&self, parser_name: &str) -> Array<NamedDataVariableWithType> {
let parser_name = parser_name.to_cstr();
-
let mut count: usize = 0;
let data_variables_ptr =
unsafe { BNGetDebugDataVariables(self.handle, parser_name.as_ptr(), &mut count) };
-
- let result: Vec<NamedDataVariableWithType> = unsafe {
- std::slice::from_raw_parts_mut(data_variables_ptr, count)
- .iter()
- .map(NamedDataVariableWithType::from_raw)
- .collect()
- };
-
- unsafe { BNFreeDataVariablesAndName(data_variables_ptr, count) };
- result
+ unsafe { Array::new(data_variables_ptr, count, ()) }
}
- pub fn data_variables(&self) -> Vec<NamedDataVariableWithType> {
+ pub fn data_variables(&self) -> Array<NamedDataVariableWithType> {
let mut count: usize = 0;
let data_variables_ptr =
unsafe { BNGetDebugDataVariables(self.handle, std::ptr::null_mut(), &mut count) };
-
- let result: Vec<NamedDataVariableWithType> = unsafe {
- std::slice::from_raw_parts_mut(data_variables_ptr, count)
- .iter()
- .map(NamedDataVariableWithType::from_raw)
- .collect()
- };
-
- unsafe { BNFreeDataVariablesAndName(data_variables_ptr, count) };
- result
+ unsafe { Array::new(data_variables_ptr, count, ()) }
}
pub fn type_by_name(&self, parser_name: &str, name: &str) -> Option<Ref<Type>> {
@@ -572,49 +537,21 @@ impl DebugInfo {
}
/// Returns a list of [`NameAndType`] where the `name` is the parser the type originates from.
- pub fn get_types_by_name(&self, name: &str) -> Vec<NameAndType> {
- let mut count: usize = 0;
+ pub fn get_types_by_name(&self, name: &str) -> Array<NameAndType> {
let name = name.to_cstr();
+ let mut count: usize = 0;
let raw_names_and_types_ptr =
unsafe { BNGetDebugTypesByName(self.handle, name.as_ptr(), &mut count) };
-
- let raw_names_and_types: &[BNNameAndType] =
- unsafe { std::slice::from_raw_parts(raw_names_and_types_ptr, count) };
-
- let names_and_types = raw_names_and_types
- .iter()
- .map(NameAndType::from_raw)
- .collect();
-
- unsafe { BNFreeNameAndTypeList(raw_names_and_types_ptr, count) };
- names_and_types
+ unsafe { Array::new(raw_names_and_types_ptr, count, ()) }
}
// The tuple is (DebugInfoParserName, address, type)
- pub fn get_data_variables_by_name(&self, name: &str) -> Vec<(String, u64, Ref<Type>)> {
+ pub fn get_data_variables_by_name(&self, name: &str) -> Array<NamedDataVariableWithType> {
let name = name.to_cstr();
-
let mut count: usize = 0;
let raw_variables_and_names =
unsafe { BNGetDebugDataVariablesByName(self.handle, name.as_ptr(), &mut count) };
-
- let variables_and_names: &[*mut BNDataVariableAndName] =
- unsafe { std::slice::from_raw_parts(raw_variables_and_names as *mut _, count) };
-
- let result = variables_and_names
- .iter()
- .take(count)
- .map(|&variable_and_name| unsafe {
- (
- raw_to_string((*variable_and_name).name).unwrap(),
- (*variable_and_name).address,
- Type::from_raw((*variable_and_name).type_).to_owned(),
- )
- })
- .collect();
-
- unsafe { BNFreeDataVariablesAndName(raw_variables_and_names, count) };
- result
+ unsafe { Array::new(raw_variables_and_names, count, ()) }
}
/// The tuple is (DebugInfoParserName, TypeName, type)
@@ -687,19 +624,20 @@ impl DebugInfo {
/// Adds a type scoped under the current parser's name to the debug info
pub fn add_type(&self, name: &str, new_type: &Type, components: &[&str]) -> bool {
- // SAFETY: Lifetime of `components` will live long enough, so passing as_ptr is safe.
- let raw_components: Vec<_> = components.iter().map(|&c| c.as_ptr()).collect();
-
+ // NOTE: Must be freed after call to BNAddDebugType is over.
+ let raw_components_ptr = strings_to_string_list(components);
let name = name.to_cstr();
- unsafe {
+ let result = unsafe {
BNAddDebugType(
self.handle,
name.as_ptr(),
new_type.handle,
- raw_components.as_ptr() as *mut _,
+ raw_components_ptr as *mut _,
components.len(),
)
- }
+ };
+ unsafe { BNFreeStringList(raw_components_ptr, components.len()) };
+ result
}
/// Adds a function scoped under the current parser's name to the debug info
diff --git a/rust/src/variable.rs b/rust/src/variable.rs
index d224a45b..fe833f97 100644
--- a/rust/src/variable.rs
+++ b/rust/src/variable.rs
@@ -8,13 +8,13 @@ use crate::string::{raw_to_string, BnString};
use crate::types::Type;
use binaryninjacore_sys::{
BNDataVariable, BNDataVariableAndName, BNFreeDataVariableAndName, BNFreeDataVariables,
- BNFreeILInstructionList, BNFreeIndirectBranchList, BNFreeMergedVariableList,
- BNFreePossibleValueSet, BNFreeStackVariableReferenceList, BNFreeUserVariableValues,
- BNFreeVariableList, BNFreeVariableNameAndTypeList, BNFromVariableIdentifier,
- BNIndirectBranchInfo, BNLookupTableEntry, BNMergedVariable, BNPossibleValueSet,
- BNRegisterValue, BNRegisterValueType, BNStackVariableReference, BNToVariableIdentifier,
- BNTypeWithConfidence, BNUserVariableValue, BNValueRange, BNVariable, BNVariableNameAndType,
- BNVariableSourceType,
+ BNFreeDataVariablesAndName, BNFreeILInstructionList, BNFreeIndirectBranchList,
+ BNFreeMergedVariableList, BNFreePossibleValueSet, BNFreeStackVariableReferenceList,
+ BNFreeUserVariableValues, BNFreeVariableList, BNFreeVariableNameAndTypeList,
+ BNFromVariableIdentifier, BNIndirectBranchInfo, BNLookupTableEntry, BNMergedVariable,
+ BNPossibleValueSet, BNRegisterValue, BNRegisterValueType, BNStackVariableReference,
+ BNToVariableIdentifier, BNTypeWithConfidence, BNUserVariableValue, BNValueRange, BNVariable,
+ BNVariableNameAndType, BNVariableSourceType,
};
use std::collections::HashSet;
@@ -147,6 +147,22 @@ impl NamedDataVariableWithType {
}
}
+impl CoreArrayProvider for NamedDataVariableWithType {
+ type Raw = BNDataVariableAndName;
+ type Context = ();
+ type Wrapped<'a> = NamedDataVariableWithType;
+}
+
+unsafe impl CoreArrayProviderInner for NamedDataVariableWithType {
+ unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
+ BNFreeDataVariablesAndName(raw, count)
+ }
+
+ unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
+ Self::from_raw(raw)
+ }
+}
+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct NamedVariableWithType {
pub variable: Variable,