summaryrefslogtreecommitdiff
path: root/rust/src/debuginfo.rs
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2024-01-16 15:07:23 -0500
committerKyleMiles <krm504@nyu.edu>2024-01-19 15:45:24 -0500
commitfb0fcd199680032932784b07b074738999779d58 (patch)
tree55a1d53541c0ec99bb486ff9863d14540602ad9c /rust/src/debuginfo.rs
parent60d69dba06adb8ea442ee5e28c1bfda5290818e1 (diff)
Add support for components in debug info
Diffstat (limited to 'rust/src/debuginfo.rs')
-rw-r--r--rust/src/debuginfo.rs88
1 files changed, 67 insertions, 21 deletions
diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs
index 640819dd..ab4f8f6b 100644
--- a/rust/src/debuginfo.rs
+++ b/rust/src/debuginfo.rs
@@ -285,17 +285,23 @@ unsafe impl CoreOwnedArrayProvider for DebugInfoParser {
/// When contributing function info, provide only what you know - BinaryNinja will figure out everything else that it can, as it usually does.
///
/// Functions will not be created if an address is not provided, but will be able to be queried from debug info for later user analysis.
-pub struct DebugFunctionInfo<S: BnStrCompatible> {
- short_name: Option<S>,
- full_name: Option<S>,
- raw_name: Option<S>,
+pub struct DebugFunctionInfo {
+ short_name: Option<String>,
+ full_name: Option<String>,
+ raw_name: Option<String>,
type_: Option<Ref<Type>>,
address: u64,
platform: Option<Ref<Platform>>,
+ components: Vec<String>,
}
-impl From<&BNDebugFunctionInfo> for DebugFunctionInfo<String> {
+impl From<&BNDebugFunctionInfo> for DebugFunctionInfo {
fn from(raw: &BNDebugFunctionInfo) -> Self {
+ let components = unsafe { slice::from_raw_parts(raw.components, raw.componentN) }
+ .iter()
+ .map(|component| raw_to_string(*component as *const _).unwrap())
+ .collect();
+
Self {
short_name: raw_to_string(raw.shortName),
full_name: raw_to_string(raw.fullName),
@@ -311,18 +317,20 @@ impl From<&BNDebugFunctionInfo> for DebugFunctionInfo<String> {
} else {
Some(unsafe { Platform::ref_from_raw(raw.platform) })
},
+ components,
}
}
}
-impl<S: BnStrCompatible> DebugFunctionInfo<S> {
+impl DebugFunctionInfo {
pub fn new(
- short_name: Option<S>,
- full_name: Option<S>,
- raw_name: Option<S>,
+ short_name: Option<String>,
+ full_name: Option<String>,
+ raw_name: Option<String>,
type_: Option<Ref<Type>>,
address: Option<u64>,
platform: Option<Ref<Platform>>,
+ components: Vec<String>,
) -> Self {
Self {
short_name,
@@ -334,6 +342,7 @@ impl<S: BnStrCompatible> DebugFunctionInfo<S> {
_ => 0,
},
platform,
+ components,
}
}
}
@@ -408,7 +417,7 @@ impl DebugInfo {
pub fn functions_by_name<S: BnStrCompatible>(
&self,
parser_name: S,
- ) -> Vec<DebugFunctionInfo<String>> {
+ ) -> Vec<DebugFunctionInfo> {
let parser_name = parser_name.into_bytes_with_nul();
let mut count: usize = 0;
@@ -420,10 +429,10 @@ impl DebugInfo {
)
};
- let result: Vec<DebugFunctionInfo<String>> = unsafe {
+ let result: Vec<DebugFunctionInfo> = unsafe {
slice::from_raw_parts_mut(functions_ptr, count)
.iter()
- .map(DebugFunctionInfo::<String>::from)
+ .map(DebugFunctionInfo::from)
.collect()
};
@@ -432,15 +441,15 @@ impl DebugInfo {
}
/// A generator of all functions provided by DebugInfoParsers
- pub fn functions(&self) -> Vec<DebugFunctionInfo<String>> {
+ pub fn functions(&self) -> Vec<DebugFunctionInfo> {
let mut count: usize = 0;
let functions_ptr =
unsafe { BNGetDebugFunctions(self.handle, ptr::null_mut(), &mut count) };
- let result: Vec<DebugFunctionInfo<String>> = unsafe {
+ let result: Vec<DebugFunctionInfo> = unsafe {
slice::from_raw_parts_mut(functions_ptr, count)
.iter()
- .map(DebugFunctionInfo::<String>::from)
+ .map(DebugFunctionInfo::from)
.collect()
};
@@ -720,38 +729,57 @@ impl DebugInfo {
}
/// Adds a type scoped under the current parser's name to the debug info
- pub fn add_type<S: BnStrCompatible>(&self, name: S, new_type: &Type) -> bool {
+ pub fn add_type<S: BnStrCompatible>(
+ &self,
+ name: S,
+ new_type: &Type,
+ components: &[&str],
+ ) -> bool {
+ let mut components_array: Vec<*const ::std::os::raw::c_char> =
+ Vec::with_capacity(components.len());
+ for component in components {
+ components_array.push(component.as_ptr() as _);
+ }
+
let name = name.into_bytes_with_nul();
unsafe {
BNAddDebugType(
self.handle,
name.as_ref().as_ptr() as *mut _,
new_type.handle,
+ components_array.as_ptr() as _,
+ components.len(),
)
}
}
/// Adds a function scoped under the current parser's name to the debug info
- pub fn add_function<S: BnStrCompatible>(&self, new_func: DebugFunctionInfo<S>) -> bool {
+ pub fn add_function(&self, new_func: DebugFunctionInfo) -> bool {
let short_name_bytes = new_func.short_name.map(|name| name.into_bytes_with_nul());
let short_name = short_name_bytes
.as_ref()
.map_or(ptr::null_mut() as *mut _, |name| {
- name.as_ref().as_ptr() as *mut _
+ name.as_ptr() as _
});
let full_name_bytes = new_func.full_name.map(|name| name.into_bytes_with_nul());
let full_name = full_name_bytes
.as_ref()
.map_or(ptr::null_mut() as *mut _, |name| {
- name.as_ref().as_ptr() as *mut _
+ name.as_ptr() as _
});
let raw_name_bytes = new_func.raw_name.map(|name| name.into_bytes_with_nul());
let raw_name = raw_name_bytes
.as_ref()
.map_or(ptr::null_mut() as *mut _, |name| {
- name.as_ref().as_ptr() as *mut _
+ name.as_ptr() as _
});
+ let mut components_array: Vec<*const ::std::os::raw::c_char> =
+ Vec::with_capacity(new_func.components.len());
+ for component in &new_func.components {
+ components_array.push(component.as_ptr() as _);
+ }
+
unsafe {
BNAddDebugFunction(
self.handle,
@@ -768,6 +796,8 @@ impl DebugInfo {
Some(platform) => platform.handle,
_ => ptr::null_mut(),
},
+ components: components_array.as_ptr() as _,
+ componentN: new_func.components.len(),
},
)
}
@@ -779,7 +809,14 @@ impl DebugInfo {
address: u64,
t: &Type,
name: Option<S>,
+ components: &[&str],
) -> bool {
+ let mut components_array: Vec<*const ::std::os::raw::c_char> =
+ Vec::with_capacity(components.len());
+ for component in components {
+ components_array.push(component.as_ptr() as _);
+ }
+
match name {
Some(name) => {
let name = name.into_bytes_with_nul();
@@ -789,11 +826,20 @@ impl DebugInfo {
address,
t.handle,
name.as_ref().as_ptr() as *mut _,
+ components.as_ptr() as _,
+ components.len(),
)
}
}
None => unsafe {
- BNAddDebugDataVariable(self.handle, address, t.handle, ptr::null_mut())
+ BNAddDebugDataVariable(
+ self.handle,
+ address,
+ t.handle,
+ ptr::null_mut(),
+ components.as_ptr() as _,
+ components.len(),
+ )
},
}
}