summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2024-06-13 14:13:11 -0400
committerJosh Ferrell <josh@vector35.com>2024-06-13 14:13:11 -0400
commitd75066545afdc9b5d0a52bd2518e43f683c671a5 (patch)
treebed26d348a726fc02c1d44cbdc36a8056b44baaf /rust/src
parentf3a440248cda4d0c850cd32e3aa127ab29e0bb3e (diff)
Apply stack variables from DWARF
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/debuginfo.rs55
-rw-r--r--rust/src/types.rs61
2 files changed, 92 insertions, 24 deletions
diff --git a/rust/src/debuginfo.rs b/rust/src/debuginfo.rs
index f29f8ac2..68c666e8 100644
--- a/rust/src/debuginfo.rs
+++ b/rust/src/debuginfo.rs
@@ -75,7 +75,7 @@ use crate::{
platform::Platform,
rc::*,
string::{raw_to_string, BnStrCompatible, BnString},
- types::{DataVariableAndName, NameAndType, Type},
+ types::{DataVariableAndName, NameAndType, NamedTypedVariable, Type},
};
use std::{hash::Hash, os::raw::c_void, ptr, slice};
@@ -301,6 +301,7 @@ pub struct DebugFunctionInfo {
address: u64,
platform: Option<Ref<Platform>>,
components: Vec<String>,
+ local_variables: Vec<NamedTypedVariable>,
}
impl From<&BNDebugFunctionInfo> for DebugFunctionInfo {
@@ -310,6 +311,15 @@ impl From<&BNDebugFunctionInfo> for DebugFunctionInfo {
.map(|component| raw_to_string(*component as *const _).unwrap())
.collect();
+ let local_variables: Vec<NamedTypedVariable> = unsafe { slice::from_raw_parts(raw.localVariables, raw.localVariableN) }
+ .iter()
+ .map(|local_variable| {
+ unsafe {
+ NamedTypedVariable::from_raw(local_variable)
+ }
+ })
+ .collect();
+
Self {
short_name: raw_to_string(raw.shortName),
full_name: raw_to_string(raw.fullName),
@@ -326,6 +336,7 @@ impl From<&BNDebugFunctionInfo> for DebugFunctionInfo {
Some(unsafe { Platform::ref_from_raw(raw.platform) })
},
components,
+ local_variables,
}
}
}
@@ -339,6 +350,7 @@ impl DebugFunctionInfo {
address: Option<u64>,
platform: Option<Ref<Platform>>,
components: Vec<String>,
+ local_variables: Vec<NamedTypedVariable>,
) -> Self {
Self {
short_name,
@@ -351,6 +363,7 @@ impl DebugFunctionInfo {
},
platform,
components,
+ local_variables,
}
}
}
@@ -776,14 +789,31 @@ impl DebugInfo {
.as_ref()
.map_or(ptr::null_mut() as *mut _, |name| name.as_ptr() as _);
- let mut components_array: Vec<*const ::std::os::raw::c_char> =
+ let mut components_array: Vec<*mut ::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 _);
- }
+
+
+ let mut local_variables_array: Vec<BNVariableNameAndType> =
+ Vec::with_capacity(new_func.local_variables.len());
unsafe {
- BNAddDebugFunction(
+ for component in &new_func.components {
+ components_array.push(BNAllocString(component.clone().into_bytes_with_nul().as_ptr() as _));
+ }
+
+ for local_variable in &new_func.local_variables {
+ local_variables_array.push(
+ BNVariableNameAndType {
+ var: local_variable.var.raw(),
+ autoDefined: local_variable.auto_defined,
+ typeConfidence: local_variable.ty.confidence,
+ name: BNAllocString(local_variable.name.clone().into_bytes_with_nul().as_ptr() as _),
+ type_: local_variable.ty.contents.handle,
+ }
+ );
+ }
+
+ let result = BNAddDebugFunction(
self.handle,
&mut BNDebugFunctionInfo {
shortName: short_name,
@@ -800,8 +830,19 @@ impl DebugInfo {
},
components: components_array.as_ptr() as _,
componentN: new_func.components.len(),
+ localVariables: local_variables_array.as_ptr() as _,
+ localVariableN: local_variables_array.len(),
},
- )
+ );
+
+ for i in components_array {
+ BNFreeString(i);
+ }
+
+ for i in &local_variables_array {
+ BNFreeString(i.name);
+ }
+ result
}
}
diff --git a/rust/src/types.rs b/rust/src/types.rs
index b42c7039..9b2271d5 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -181,6 +181,20 @@ impl<T: Display> Display for Conf<T> {
}
}
+impl<T: PartialEq> PartialEq for Conf<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.contents.eq(&other.contents)
+ }
+}
+
+impl<T: Eq> Eq for Conf<T> {}
+
+impl<T: Hash> Hash for Conf<T> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.contents.hash(state);
+ }
+}
+
impl<'a, T> From<&'a Conf<T>> for Conf<&'a T> {
fn from(c: &'a Conf<T>) -> Self {
Conf::new(&c.contents, c.confidence)
@@ -1500,21 +1514,40 @@ unsafe impl CoreArrayProviderInner for Array<SSAVariable> {
///////////////
// NamedVariable
+#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct NamedTypedVariable {
- var: BNVariable,
- auto_defined: bool,
- type_confidence: u8,
- name: *mut c_char,
- ty: *mut BNType,
+ pub name: String,
+ pub ty: Conf<Ref<Type>>,
+ pub var: Variable,
+ pub auto_defined: bool,
}
impl NamedTypedVariable {
+
+ pub fn new(var: Variable, name: String, ty: Conf<Ref<Type>>, auto_defined: bool) -> Self {
+ Self {
+ name,
+ ty,
+ var,
+ auto_defined,
+ }
+ }
+
+ pub(crate) unsafe fn from_raw(var: &BNVariableNameAndType) -> Self {
+ Self {
+ var: Variable::from_raw(var.var),
+ auto_defined: var.autoDefined,
+ name: CStr::from_ptr(var.name).to_str().unwrap().to_string(),
+ ty: Conf::new(Type::ref_from_raw(var.type_), var.typeConfidence)
+ }
+ }
+
pub fn name(&self) -> &str {
- unsafe { CStr::from_ptr(self.name).to_str().unwrap() }
+ &self.name
}
pub fn var(&self) -> Variable {
- unsafe { Variable::from_raw(self.var) }
+ self.var
}
pub fn auto_defined(&self) -> bool {
@@ -1522,18 +1555,18 @@ impl NamedTypedVariable {
}
pub fn type_confidence(&self) -> u8 {
- self.type_confidence
+ self.ty.confidence
}
pub fn var_type(&self) -> Ref<Type> {
- unsafe { Ref::new(Type::from_raw(self.ty)) }
+ self.ty.contents.clone()
}
}
impl CoreArrayProvider for NamedTypedVariable {
type Raw = BNVariableNameAndType;
type Context = ();
- type Wrapped<'a> = ManuallyDrop<NamedTypedVariable>;
+ type Wrapped<'a> = Guard<'a, NamedTypedVariable>;
}
unsafe impl CoreArrayProviderInner for NamedTypedVariable {
@@ -1541,13 +1574,7 @@ unsafe impl CoreArrayProviderInner for NamedTypedVariable {
BNFreeVariableNameAndTypeList(raw, count)
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
- ManuallyDrop::new(NamedTypedVariable {
- var: raw.var,
- ty: raw.type_,
- name: raw.name,
- auto_defined: raw.autoDefined,
- type_confidence: raw.typeConfidence,
- })
+ unsafe { Guard::new(NamedTypedVariable::from_raw(raw), raw) }
}
}