diff options
| author | Josh Ferrell <josh@vector35.com> | 2024-06-13 14:13:11 -0400 |
|---|---|---|
| committer | Josh Ferrell <josh@vector35.com> | 2024-06-13 14:13:11 -0400 |
| commit | d75066545afdc9b5d0a52bd2518e43f683c671a5 (patch) | |
| tree | bed26d348a726fc02c1d44cbdc36a8056b44baaf /rust/src | |
| parent | f3a440248cda4d0c850cd32e3aa127ab29e0bb3e (diff) | |
Apply stack variables from DWARF
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/debuginfo.rs | 55 | ||||
| -rw-r--r-- | rust/src/types.rs | 61 |
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) } } } |
