Skip to content

Commit 2e5b893

Browse files
authored
[Rust] Return Array in more debug info functions (#7744)
1 parent 8e409a0 commit 2e5b893

File tree

2 files changed

+44
-90
lines changed

2 files changed

+44
-90
lines changed

rust/src/debuginfo.rs

Lines changed: 21 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ use binaryninjacore_sys::*;
7878
use std::ffi::c_void;
7979

8080
use crate::progress::{NoProgressCallback, ProgressCallback};
81+
use crate::string::strings_to_string_list;
8182
use crate::variable::{NamedDataVariableWithType, NamedVariableWithType};
8283
use crate::{
8384
binary_view::BinaryView,
@@ -417,36 +418,19 @@ impl DebugInfo {
417418
}
418419

419420
/// Returns all types within the parser
420-
pub fn types_by_name(&self, parser_name: &str) -> Vec<NameAndType> {
421+
pub fn types_by_name(&self, parser_name: &str) -> Array<NameAndType> {
421422
let parser_name = parser_name.to_cstr();
422-
423423
let mut count: usize = 0;
424424
let debug_types_ptr =
425425
unsafe { BNGetDebugTypes(self.handle, parser_name.as_ptr(), &mut count) };
426-
let result: Vec<_> = unsafe {
427-
std::slice::from_raw_parts_mut(debug_types_ptr, count)
428-
.iter()
429-
.map(NameAndType::from_raw)
430-
.collect()
431-
};
432-
433-
unsafe { BNFreeDebugTypes(debug_types_ptr, count) };
434-
result
426+
unsafe { Array::new(debug_types_ptr, count, ()) }
435427
}
436428

437-
pub fn types(&self) -> Vec<NameAndType> {
429+
pub fn types(&self) -> Array<NameAndType> {
438430
let mut count: usize = 0;
439431
let debug_types_ptr =
440432
unsafe { BNGetDebugTypes(self.handle, std::ptr::null_mut(), &mut count) };
441-
let result: Vec<_> = unsafe {
442-
std::slice::from_raw_parts_mut(debug_types_ptr, count)
443-
.iter()
444-
.map(NameAndType::from_raw)
445-
.collect()
446-
};
447-
448-
unsafe { BNFreeDebugTypes(debug_types_ptr, count) };
449-
result
433+
unsafe { Array::new(debug_types_ptr, count, ()) }
450434
}
451435

452436
/// Returns all functions within the parser
@@ -485,38 +469,19 @@ impl DebugInfo {
485469
}
486470

487471
/// Returns all data variables within the parser
488-
pub fn data_variables_by_name(&self, parser_name: &str) -> Vec<NamedDataVariableWithType> {
472+
pub fn data_variables_by_name(&self, parser_name: &str) -> Array<NamedDataVariableWithType> {
489473
let parser_name = parser_name.to_cstr();
490-
491474
let mut count: usize = 0;
492475
let data_variables_ptr =
493476
unsafe { BNGetDebugDataVariables(self.handle, parser_name.as_ptr(), &mut count) };
494-
495-
let result: Vec<NamedDataVariableWithType> = unsafe {
496-
std::slice::from_raw_parts_mut(data_variables_ptr, count)
497-
.iter()
498-
.map(NamedDataVariableWithType::from_raw)
499-
.collect()
500-
};
501-
502-
unsafe { BNFreeDataVariablesAndName(data_variables_ptr, count) };
503-
result
477+
unsafe { Array::new(data_variables_ptr, count, ()) }
504478
}
505479

506-
pub fn data_variables(&self) -> Vec<NamedDataVariableWithType> {
480+
pub fn data_variables(&self) -> Array<NamedDataVariableWithType> {
507481
let mut count: usize = 0;
508482
let data_variables_ptr =
509483
unsafe { BNGetDebugDataVariables(self.handle, std::ptr::null_mut(), &mut count) };
510-
511-
let result: Vec<NamedDataVariableWithType> = unsafe {
512-
std::slice::from_raw_parts_mut(data_variables_ptr, count)
513-
.iter()
514-
.map(NamedDataVariableWithType::from_raw)
515-
.collect()
516-
};
517-
518-
unsafe { BNFreeDataVariablesAndName(data_variables_ptr, count) };
519-
result
484+
unsafe { Array::new(data_variables_ptr, count, ()) }
520485
}
521486

522487
pub fn type_by_name(&self, parser_name: &str, name: &str) -> Option<Ref<Type>> {
@@ -572,49 +537,21 @@ impl DebugInfo {
572537
}
573538

574539
/// Returns a list of [`NameAndType`] where the `name` is the parser the type originates from.
575-
pub fn get_types_by_name(&self, name: &str) -> Vec<NameAndType> {
576-
let mut count: usize = 0;
540+
pub fn get_types_by_name(&self, name: &str) -> Array<NameAndType> {
577541
let name = name.to_cstr();
542+
let mut count: usize = 0;
578543
let raw_names_and_types_ptr =
579544
unsafe { BNGetDebugTypesByName(self.handle, name.as_ptr(), &mut count) };
580-
581-
let raw_names_and_types: &[BNNameAndType] =
582-
unsafe { std::slice::from_raw_parts(raw_names_and_types_ptr, count) };
583-
584-
let names_and_types = raw_names_and_types
585-
.iter()
586-
.map(NameAndType::from_raw)
587-
.collect();
588-
589-
unsafe { BNFreeNameAndTypeList(raw_names_and_types_ptr, count) };
590-
names_and_types
545+
unsafe { Array::new(raw_names_and_types_ptr, count, ()) }
591546
}
592547

593548
// The tuple is (DebugInfoParserName, address, type)
594-
pub fn get_data_variables_by_name(&self, name: &str) -> Vec<(String, u64, Ref<Type>)> {
549+
pub fn get_data_variables_by_name(&self, name: &str) -> Array<NamedDataVariableWithType> {
595550
let name = name.to_cstr();
596-
597551
let mut count: usize = 0;
598552
let raw_variables_and_names =
599553
unsafe { BNGetDebugDataVariablesByName(self.handle, name.as_ptr(), &mut count) };
600-
601-
let variables_and_names: &[*mut BNDataVariableAndName] =
602-
unsafe { std::slice::from_raw_parts(raw_variables_and_names as *mut _, count) };
603-
604-
let result = variables_and_names
605-
.iter()
606-
.take(count)
607-
.map(|&variable_and_name| unsafe {
608-
(
609-
raw_to_string((*variable_and_name).name).unwrap(),
610-
(*variable_and_name).address,
611-
Type::from_raw((*variable_and_name).type_).to_owned(),
612-
)
613-
})
614-
.collect();
615-
616-
unsafe { BNFreeDataVariablesAndName(raw_variables_and_names, count) };
617-
result
554+
unsafe { Array::new(raw_variables_and_names, count, ()) }
618555
}
619556

620557
/// The tuple is (DebugInfoParserName, TypeName, type)
@@ -687,19 +624,20 @@ impl DebugInfo {
687624

688625
/// Adds a type scoped under the current parser's name to the debug info
689626
pub fn add_type(&self, name: &str, new_type: &Type, components: &[&str]) -> bool {
690-
// SAFETY: Lifetime of `components` will live long enough, so passing as_ptr is safe.
691-
let raw_components: Vec<_> = components.iter().map(|&c| c.as_ptr()).collect();
692-
627+
// NOTE: Must be freed after call to BNAddDebugType is over.
628+
let raw_components_ptr = strings_to_string_list(components);
693629
let name = name.to_cstr();
694-
unsafe {
630+
let result = unsafe {
695631
BNAddDebugType(
696632
self.handle,
697633
name.as_ptr(),
698634
new_type.handle,
699-
raw_components.as_ptr() as *mut _,
635+
raw_components_ptr as *mut _,
700636
components.len(),
701637
)
702-
}
638+
};
639+
unsafe { BNFreeStringList(raw_components_ptr, components.len()) };
640+
result
703641
}
704642

705643
/// Adds a function scoped under the current parser's name to the debug info

rust/src/variable.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ use crate::string::{raw_to_string, BnString};
88
use crate::types::Type;
99
use binaryninjacore_sys::{
1010
BNDataVariable, BNDataVariableAndName, BNFreeDataVariableAndName, BNFreeDataVariables,
11-
BNFreeILInstructionList, BNFreeIndirectBranchList, BNFreeMergedVariableList,
12-
BNFreePossibleValueSet, BNFreeStackVariableReferenceList, BNFreeUserVariableValues,
13-
BNFreeVariableList, BNFreeVariableNameAndTypeList, BNFromVariableIdentifier,
14-
BNIndirectBranchInfo, BNLookupTableEntry, BNMergedVariable, BNPossibleValueSet,
15-
BNRegisterValue, BNRegisterValueType, BNStackVariableReference, BNToVariableIdentifier,
16-
BNTypeWithConfidence, BNUserVariableValue, BNValueRange, BNVariable, BNVariableNameAndType,
17-
BNVariableSourceType,
11+
BNFreeDataVariablesAndName, BNFreeILInstructionList, BNFreeIndirectBranchList,
12+
BNFreeMergedVariableList, BNFreePossibleValueSet, BNFreeStackVariableReferenceList,
13+
BNFreeUserVariableValues, BNFreeVariableList, BNFreeVariableNameAndTypeList,
14+
BNFromVariableIdentifier, BNIndirectBranchInfo, BNLookupTableEntry, BNMergedVariable,
15+
BNPossibleValueSet, BNRegisterValue, BNRegisterValueType, BNStackVariableReference,
16+
BNToVariableIdentifier, BNTypeWithConfidence, BNUserVariableValue, BNValueRange, BNVariable,
17+
BNVariableNameAndType, BNVariableSourceType,
1818
};
1919
use std::collections::HashSet;
2020

@@ -147,6 +147,22 @@ impl NamedDataVariableWithType {
147147
}
148148
}
149149

150+
impl CoreArrayProvider for NamedDataVariableWithType {
151+
type Raw = BNDataVariableAndName;
152+
type Context = ();
153+
type Wrapped<'a> = NamedDataVariableWithType;
154+
}
155+
156+
unsafe impl CoreArrayProviderInner for NamedDataVariableWithType {
157+
unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
158+
BNFreeDataVariablesAndName(raw, count)
159+
}
160+
161+
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
162+
Self::from_raw(raw)
163+
}
164+
}
165+
150166
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
151167
pub struct NamedVariableWithType {
152168
pub variable: Variable,

0 commit comments

Comments
 (0)