diff --git a/rust/src/function.rs b/rust/src/function.rs index 15cab7b69..638554fef 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -19,6 +19,7 @@ use crate::disassembly::InstructionTextToken; use crate::rc::*; use crate::string::*; use crate::tags::{Tag, TagType}; +use crate::types::IndirectBranchInfo; use crate::types::{ConstantReference, QualifiedName, RegisterValueType, Variable}; use crate::{ architecture::CoreArchitecture, @@ -713,6 +714,29 @@ impl Function { unsafe { Array::new(tags, count, ()) } } + + /// List of indirect branches + pub fn indirect_branches( + &self, + ) -> Array { + let mut count = 0; + let branches = unsafe { BNGetIndirectBranches(self.handle, &mut count) }; + assert!(!branches.is_null()); + unsafe { Array::new(branches, count, ()) } + } + + /// List of indirect branches at this address + pub fn indirect_branches_at( + &self, + addr: u64, + arch: Option, + ) -> Array { + let arch = arch.unwrap_or_else(|| self.arch()); + let mut count = 0; + let branches = unsafe { BNGetIndirectBranchesAt(self.handle, arch.0, addr, &mut count) }; + assert!(!branches.is_null()); + unsafe { Array::new(branches, count, ()) } + } } impl fmt::Debug for Function { diff --git a/rust/src/types.rs b/rust/src/types.rs index e3ecc47d0..728dfdba8 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -3203,15 +3203,15 @@ impl ConstantReference { value: value.value, size: value.size, pointer: value.pointer, - intermediate: value.intermediate + intermediate: value.intermediate, } } - pub fn into_raw(self) -> BNConstantReference{ + pub fn into_raw(self) -> BNConstantReference { BNConstantReference { value: self.value, size: self.size, pointer: self.pointer, - intermediate: self.intermediate + intermediate: self.intermediate, } } } @@ -3233,3 +3233,53 @@ unsafe impl CoreArrayWrapper for ConstantReference { Self::from_raw(*raw) } } + +///////////////////////// +// IndirectBranchInfo + +pub struct IndirectBranchInfo { + pub source_arch: CoreArchitecture, + pub source_addr: u64, + pub dest_arch: CoreArchitecture, + pub dest_addr: u64, + pub auto_defined: bool, +} + +impl IndirectBranchInfo { + pub fn from_raw(value: BNIndirectBranchInfo) -> Self { + Self { + source_arch: unsafe { CoreArchitecture::from_raw(value.sourceArch) }, + source_addr: value.sourceAddr, + dest_arch: unsafe { CoreArchitecture::from_raw(value.destArch) }, + dest_addr: value.destAddr, + auto_defined: value.autoDefined, + } + } + pub fn into_raw(self) -> BNIndirectBranchInfo { + BNIndirectBranchInfo { + sourceArch: self.source_arch.0, + sourceAddr: self.source_addr, + destArch: self.dest_arch.0, + destAddr: self.dest_addr, + autoDefined: self.auto_defined, + } + } +} + +impl CoreArrayProvider for IndirectBranchInfo { + type Raw = BNIndirectBranchInfo; + type Context = (); +} + +unsafe impl CoreOwnedArrayProvider for IndirectBranchInfo { + unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) { + BNFreeIndirectBranchList(raw) + } +} + +unsafe impl CoreArrayWrapper for IndirectBranchInfo { + type Wrapped<'a> = Self; + unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> { + Self::from_raw(*raw) + } +}