From ba95ecc66d27786e98167ae52756397b21d05c85 Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Wed, 24 Apr 2024 09:58:18 -0300 Subject: [PATCH] remove the Architecture Handle --- arch/riscv/src/lib.rs | 39 +- rust/examples/pdb-ng/src/parser.rs | 2 +- rust/examples/pdb-ng/src/type_parser.rs | 24 +- rust/src/architecture.rs | 464 +++++++++++++----------- rust/src/basicblock.rs | 2 +- rust/src/binaryview.rs | 6 +- rust/src/callingconvention.rs | 65 ++-- rust/src/custombinaryview.rs | 9 +- rust/src/demangle.rs | 4 +- rust/src/function.rs | 234 ++++++------ rust/src/functionrecognizer.rs | 6 +- rust/src/hlil/instruction.rs | 4 +- rust/src/llil/function.rs | 26 +- rust/src/llil/lifting.rs | 14 +- rust/src/mlil/function.rs | 32 +- rust/src/mlil/instruction.rs | 6 +- rust/src/platform.rs | 12 +- rust/src/references.rs | 4 +- rust/src/relocation.rs | 13 +- rust/src/tags.rs | 4 +- rust/src/types.rs | 62 +++- 21 files changed, 539 insertions(+), 493 deletions(-) diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs index bc67e4655..a720c5867 100644 --- a/arch/riscv/src/lib.rs +++ b/arch/riscv/src/lib.rs @@ -624,14 +624,11 @@ impl architecture::Intrinsic for RiscVIntrinsic { } struct RiscVArch { - handle: CoreArchitecture, - custom_handle: CustomArchitectureHandle>, + handle: &'static CoreArchitecture, _dis: PhantomData, } impl architecture::Architecture for RiscVArch { - type Handle = CustomArchitectureHandle; - type RegisterInfo = Register; type Register = Register; type RegisterStackInfo = UnusedRegisterStackInfo; @@ -674,7 +671,7 @@ impl architecture::Architecture fo self.max_instr_len() } - fn associated_arch_by_addr(&self, _addr: &mut u64) -> CoreArchitecture { + fn associated_arch_by_addr(&self, _addr: &mut u64) -> &'static CoreArchitecture { self.handle } @@ -2140,8 +2137,8 @@ impl architecture::Architecture fo true } - fn handle(&self) -> CustomArchitectureHandle { - self.custom_handle + fn core(&self) -> &'static CoreArchitecture { + self.handle } } @@ -2868,22 +2865,18 @@ pub extern "C" fn CorePluginInit() -> bool { binaryninja::logger::init(log::LevelFilter::Trace).expect("Failed to set up logging"); use riscv_dis::{RiscVIMACDisassembler, Rv32GRegs, Rv64GRegs}; - let arch32 = - architecture::register_architecture("rv32gc", |custom_handle, core_arch| RiscVArch::< - RiscVIMACDisassembler, - > { - handle: core_arch, - custom_handle, - _dis: PhantomData, - }); - let arch64 = - architecture::register_architecture("rv64gc", |custom_handle, core_arch| RiscVArch::< - RiscVIMACDisassembler, - > { - handle: core_arch, - custom_handle, - _dis: PhantomData, - }); + let arch32 = architecture::register_architecture("rv32gc", |core_arch| RiscVArch::< + RiscVIMACDisassembler, + > { + handle: core_arch, + _dis: PhantomData, + }); + let arch64 = architecture::register_architecture("rv64gc", |core_arch| RiscVArch::< + RiscVIMACDisassembler, + > { + handle: core_arch, + _dis: PhantomData, + }); arch32.register_relocation_handler("ELF", |custom_handle, core_handler| { RiscVELFRelocationHandler::> { diff --git a/rust/examples/pdb-ng/src/parser.rs b/rust/examples/pdb-ng/src/parser.rs index 9e0bf0257..027228302 100644 --- a/rust/examples/pdb-ng/src/parser.rs +++ b/rust/examples/pdb-ng/src/parser.rs @@ -44,7 +44,7 @@ pub struct PDBParserInstance<'a, S: Source<'a> + 'a> { /// Parent binary view (usually during BinaryView::Finalize) pub(crate) bv: &'a BinaryView, /// Default arch of self.bv - pub(crate) arch: CoreArchitecture, + pub(crate) arch: &'static CoreArchitecture, /// Default calling convention for self.arch pub(crate) default_cc: Ref>, /// Thiscall calling convention for self.bv, or default_cc if we can't find one diff --git a/rust/examples/pdb-ng/src/type_parser.rs b/rust/examples/pdb-ng/src/type_parser.rs index f21a04fad..cce5e519b 100644 --- a/rust/examples/pdb-ng/src/type_parser.rs +++ b/rust/examples/pdb-ng/src/type_parser.rs @@ -700,31 +700,31 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { // TODO: Pointer suffix is not exposed match data.indirection { Some(Indirection::Near16) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), Some(Indirection::Far16) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), Some(Indirection::Huge16) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), Some(Indirection::Near32) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), Some(Indirection::Far32) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), Some(Indirection::Near64) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), Some(Indirection::Near128) => Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))), None => Ok(Some(Box::new(ParsedType::Bare(base)))), @@ -1102,7 +1102,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { for (offset, (name, method)) in virt_methods { vt.insert( &Conf::new( - Type::pointer(&self.arch, &Conf::new(method.method_type, max_confidence())), + Type::pointer(self.arch, &Conf::new(method.method_type, max_confidence())), max_confidence(), ), &name, @@ -1127,7 +1127,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { self.named_types.insert(vt_name.clone(), vt_type.clone()); let vt_pointer = Type::pointer( - &self.arch, + self.arch, &Conf::new( Type::named_type_from_type(&QualifiedName::from(vt_name), vt_type.as_ref()), max_confidence(), @@ -1245,7 +1245,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { // Return UDT?? // This probably means the return value got pushed to the stack fancy_return_type = Type::pointer( - &self.arch, + self.arch, &Conf::new(return_type.clone(), max_confidence()), ); fancy_arguments.insert( @@ -1528,7 +1528,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { if return_stacky { // Stack return via a pointer in the first parameter fancy_return_type = - Conf::new(Type::pointer(&self.arch, &return_type), max_confidence()); + Conf::new(Type::pointer(self.arch, &return_type), max_confidence()); fancy_arguments.insert( 0, FunctionParameter::new(fancy_return_type.clone(), "__return".to_string(), None), @@ -1583,7 +1583,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { if let Some(base) = base { Ok(Some(Box::new(ParsedType::Bare(Type::pointer( - &self.arch, + self.arch, base.as_ref(), ))))) } else { diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index cf5d32d64..3c48a3a1b 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -59,7 +59,7 @@ pub enum BranchInfo { pub struct BranchIter<'a>(&'a InstructionInfo, ops::Range); impl<'a> Iterator for BranchIter<'a> { - type Item = (BranchInfo, Option); + type Item = (BranchInfo, Option<&'static CoreArchitecture>); fn next(&mut self) -> Option { use crate::BranchType::*; @@ -71,7 +71,7 @@ impl<'a> Iterator for BranchIter<'a> { let arch = if arch.is_null() { None } else { - Some(CoreArchitecture(arch)) + Some(unsafe { CoreArchitecture::from_raw(arch) }) }; let res = match (self.0).0.branchType[i] { @@ -164,7 +164,7 @@ impl InstructionInfo { self.0.branchType[idx] = ty; self.0.branchArch[idx] = match arch { - Some(a) => a.0, + Some(a) => a.core().as_ptr(), _ => ptr::null_mut(), }; @@ -319,9 +319,7 @@ pub trait Intrinsic: Sized + Clone + Copy { fn outputs(&self) -> Vec>>; } -pub trait Architecture: 'static + Sized + AsRef { - type Handle: Borrow + Clone; - +pub trait Architecture: 'static + Sized { type RegisterInfo: RegisterInfo; type Register: Register; type RegisterStackInfo: RegisterStackInfo< @@ -349,7 +347,7 @@ pub trait Architecture: 'static + Sized + AsRef { fn max_instr_len(&self) -> usize; fn opcode_display_len(&self) -> usize; - fn associated_arch_by_addr(&self, addr: &mut u64) -> CoreArchitecture; + fn associated_arch_by_addr(&self, addr: &mut u64) -> &'static CoreArchitecture; fn instruction_info(&self, data: &[u8], addr: u64) -> Option; fn instruction_text( @@ -533,7 +531,7 @@ pub trait Architecture: 'static + Sized + AsRef { false } - fn handle(&self) -> Self::Handle; + fn core(&self) -> &'static CoreArchitecture; } /// Type for architrectures that do not use register stacks. Will panic if accessed as a register stack. @@ -658,7 +656,7 @@ impl Intrinsic for UnusedIntrinsic { } } -pub struct CoreRegisterInfo(*mut BNArchitecture, u32, BNRegisterInfo); +pub struct CoreRegisterInfo(&'static CoreArchitecture, u32, BNRegisterInfo); impl RegisterInfo for CoreRegisterInfo { type RegType = CoreRegister; @@ -684,13 +682,13 @@ impl RegisterInfo for CoreRegisterInfo { } #[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct CoreRegister(*mut BNArchitecture, u32); +pub struct CoreRegister(&'static CoreArchitecture, u32); impl Register for CoreRegister { type InfoType = CoreRegisterInfo; fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureRegisterName(self.0, self.1); + let name = BNGetArchitectureRegisterName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -706,7 +704,7 @@ impl Register for CoreRegister { fn info(&self) -> CoreRegisterInfo { CoreRegisterInfo(self.0, self.1, unsafe { - BNGetArchitectureRegisterInfo(self.0, self.1) + BNGetArchitectureRegisterInfo(self.0.as_ptr(), self.1) }) } @@ -717,7 +715,7 @@ impl Register for CoreRegister { impl CoreArrayProvider for CoreRegister { type Raw = u32; - type Context = CoreArchitecture; + type Context = &'static CoreArchitecture; type Wrapped<'a> = Self; } @@ -726,11 +724,11 @@ unsafe impl CoreArrayProviderInner for CoreRegister { BNFreeRegisterList(raw) } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> { - Self(context.0, *raw) + Self(context, *raw) } } -pub struct CoreRegisterStackInfo(*mut BNArchitecture, BNRegisterStackInfo); +pub struct CoreRegisterStackInfo(&'static CoreArchitecture, BNRegisterStackInfo); impl RegisterStackInfo for CoreRegisterStackInfo { type RegStackType = CoreRegisterStack; @@ -761,7 +759,7 @@ impl RegisterStackInfo for CoreRegisterStackInfo { } #[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct CoreRegisterStack(*mut BNArchitecture, u32); +pub struct CoreRegisterStack(&'static CoreArchitecture, u32); impl RegisterStack for CoreRegisterStack { type InfoType = CoreRegisterStackInfo; @@ -770,7 +768,7 @@ impl RegisterStack for CoreRegisterStack { fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureRegisterStackName(self.0, self.1); + let name = BNGetArchitectureRegisterStackName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -786,7 +784,7 @@ impl RegisterStack for CoreRegisterStack { fn info(&self) -> CoreRegisterStackInfo { CoreRegisterStackInfo(self.0, unsafe { - BNGetArchitectureRegisterStackInfo(self.0, self.1) + BNGetArchitectureRegisterStackInfo(self.0.as_ptr(), self.1) }) } @@ -796,13 +794,13 @@ impl RegisterStack for CoreRegisterStack { } #[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct CoreFlag(*mut BNArchitecture, u32); +pub struct CoreFlag(&'static CoreArchitecture, u32); impl Flag for CoreFlag { type FlagClass = CoreFlagClass; fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureFlagName(self.0, self.1); + let name = BNGetArchitectureFlagName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -822,7 +820,7 @@ impl Flag for CoreFlag { _ => 0, }; - unsafe { BNGetArchitectureFlagRole(self.0, self.1, class_id) } + unsafe { BNGetArchitectureFlagRole(self.0.as_ptr(), self.1, class_id) } } fn id(&self) -> u32 { @@ -831,14 +829,14 @@ impl Flag for CoreFlag { } #[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct CoreFlagWrite(*mut BNArchitecture, u32); +pub struct CoreFlagWrite(&'static CoreArchitecture, u32); impl FlagWrite for CoreFlagWrite { type FlagType = CoreFlag; type FlagClass = CoreFlagClass; fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureFlagWriteTypeName(self.0, self.1); + let name = BNGetArchitectureFlagWriteTypeName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -859,7 +857,7 @@ impl FlagWrite for CoreFlagWrite { fn flags_written(&self) -> Vec { let mut count: usize = 0; let regs: *mut u32 = unsafe { - BNGetArchitectureFlagsWrittenByFlagWriteType(self.0, self.1, &mut count as *mut _) + BNGetArchitectureFlagsWrittenByFlagWriteType(self.0.as_ptr(), self.1, &mut count as *mut _) }; let ret = unsafe { @@ -877,7 +875,7 @@ impl FlagWrite for CoreFlagWrite { } fn class(&self) -> Option { - let class = unsafe { BNGetArchitectureSemanticClassForFlagWriteType(self.0, self.1) }; + let class = unsafe { BNGetArchitectureSemanticClassForFlagWriteType(self.0.as_ptr(), self.1) }; match class { 0 => None, @@ -887,11 +885,11 @@ impl FlagWrite for CoreFlagWrite { } #[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct CoreFlagClass(*mut BNArchitecture, u32); +pub struct CoreFlagClass(&'static CoreArchitecture, u32); impl FlagClass for CoreFlagClass { fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureSemanticFlagClassName(self.0, self.1); + let name = BNGetArchitectureSemanticFlagClassName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -911,14 +909,14 @@ impl FlagClass for CoreFlagClass { } #[derive(Copy, Clone, Eq, PartialEq)] -pub struct CoreFlagGroup(*mut BNArchitecture, u32); +pub struct CoreFlagGroup(&'static CoreArchitecture, u32); impl FlagGroup for CoreFlagGroup { type FlagType = CoreFlag; type FlagClass = CoreFlagClass; fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureSemanticFlagGroupName(self.0, self.1); + let name = BNGetArchitectureSemanticFlagGroupName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -939,7 +937,7 @@ impl FlagGroup for CoreFlagGroup { fn flags_required(&self) -> Vec { let mut count: usize = 0; let regs: *mut u32 = unsafe { - BNGetArchitectureFlagsRequiredForSemanticFlagGroup(self.0, self.1, &mut count as *mut _) + BNGetArchitectureFlagsRequiredForSemanticFlagGroup(self.0.as_ptr(), self.1, &mut count as *mut _) }; let ret = unsafe { @@ -961,7 +959,7 @@ impl FlagGroup for CoreFlagGroup { unsafe { let flag_conds = BNGetArchitectureFlagConditionsForSemanticFlagGroup( - self.0, + self.0.as_ptr(), self.1, &mut count as *mut _, ); @@ -984,12 +982,12 @@ impl FlagGroup for CoreFlagGroup { } #[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub struct CoreIntrinsic(pub(crate) *mut BNArchitecture, pub(crate) u32); +pub struct CoreIntrinsic(pub(crate) &'static CoreArchitecture, pub(crate) u32); impl Intrinsic for crate::architecture::CoreIntrinsic { fn name(&self) -> Cow { unsafe { - let name = BNGetArchitectureIntrinsicName(self.0, self.1); + let name = BNGetArchitectureIntrinsicName(self.0.as_ptr(), self.1); // We need to guarantee ownership, as if we're still // a Borrowed variant we're about to free the underlying @@ -1011,7 +1009,7 @@ impl Intrinsic for crate::architecture::CoreIntrinsic { let mut count: usize = 0; unsafe { - let inputs = BNGetArchitectureIntrinsicInputs(self.0, self.1, &mut count as *mut _); + let inputs = BNGetArchitectureIntrinsicInputs(self.0.as_ptr(), self.1, &mut count as *mut _); let ret = slice::from_raw_parts_mut(inputs, count) .iter() @@ -1028,7 +1026,7 @@ impl Intrinsic for crate::architecture::CoreIntrinsic { let mut count: usize = 0; unsafe { - let inputs = BNGetArchitectureIntrinsicOutputs(self.0, self.1, &mut count as *mut _); + let inputs = BNGetArchitectureIntrinsicOutputs(self.0.as_ptr(), self.1, &mut count as *mut _); let ret = slice::from_raw_parts_mut(inputs, count) .iter() @@ -1059,15 +1057,29 @@ impl Drop for CoreArchitectureList { } } -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub struct CoreArchitecture(pub(crate) *mut BNArchitecture); +#[repr(transparent)] +#[derive(Copy, Clone, Debug)] +pub struct CoreArchitecture(pub(crate) BNArchitecture); + +impl PartialEq for CoreArchitecture { + fn eq(&self, other: &Self) -> bool { + self as *const _ as usize == other as *const _ as usize + } +} + +impl Eq for CoreArchitecture {} +impl std::hash::Hash for CoreArchitecture { + fn hash(&self, state: &mut H) { + state.write_usize(self as *const _ as usize); + } +} unsafe impl Send for CoreArchitecture {} unsafe impl Sync for CoreArchitecture {} impl CoreArchitecture { - pub(crate) unsafe fn from_raw(raw: *mut BNArchitecture) -> Self { - CoreArchitecture(raw) + pub(crate) unsafe fn from_raw(raw: *mut BNArchitecture) -> &'static Self { + core::mem::transmute(raw) } pub fn list_all() -> CoreArchitectureList { @@ -1077,17 +1089,21 @@ impl CoreArchitecture { CoreArchitectureList(archs, count) } - pub fn by_name(name: &str) -> Option { + pub fn by_name(name: &str) -> Option<&'static Self> { let res = unsafe { BNGetArchitectureByName(name.into_bytes_with_nul().as_ptr() as *mut _) }; match res.is_null() { - false => Some(CoreArchitecture(res)), + false => Some(unsafe { CoreArchitecture::from_raw(res) }), true => None, } } pub fn name(&self) -> BnString { - unsafe { BnString::from_raw(BNGetArchitectureName(self.0)) } + unsafe { BnString::from_raw(BNGetArchitectureName(self.core().as_ptr())) } + } + + pub(crate) fn as_ptr(&self) -> *mut BNArchitecture { + &self.0 as *const _ as *mut _ } } @@ -1098,8 +1114,6 @@ impl AsRef for CoreArchitecture { } impl Architecture for CoreArchitecture { - type Handle = Self; - type RegisterInfo = CoreRegisterInfo; type Register = CoreRegister; type RegisterStackInfo = CoreRegisterStackInfo; @@ -1111,40 +1125,41 @@ impl Architecture for CoreArchitecture { type Intrinsic = CoreIntrinsic; fn endianness(&self) -> Endianness { - unsafe { BNGetArchitectureEndianness(self.0) } + unsafe { BNGetArchitectureEndianness(self.core().as_ptr()) } } fn address_size(&self) -> usize { - unsafe { BNGetArchitectureAddressSize(self.0) } + unsafe { BNGetArchitectureAddressSize(self.core().as_ptr()) } } fn default_integer_size(&self) -> usize { - unsafe { BNGetArchitectureDefaultIntegerSize(self.0) } + unsafe { BNGetArchitectureDefaultIntegerSize(self.core().as_ptr()) } } fn instruction_alignment(&self) -> usize { - unsafe { BNGetArchitectureInstructionAlignment(self.0) } + unsafe { BNGetArchitectureInstructionAlignment(self.core().as_ptr()) } } fn max_instr_len(&self) -> usize { - unsafe { BNGetArchitectureMaxInstructionLength(self.0) } + unsafe { BNGetArchitectureMaxInstructionLength(self.core().as_ptr()) } } fn opcode_display_len(&self) -> usize { - unsafe { BNGetArchitectureOpcodeDisplayLength(self.0) } + unsafe { BNGetArchitectureOpcodeDisplayLength(self.core().as_ptr()) } } - fn associated_arch_by_addr(&self, addr: &mut u64) -> CoreArchitecture { - let arch = unsafe { BNGetAssociatedArchitectureByAddress(self.0, addr as *mut _) }; + fn associated_arch_by_addr(&self, addr: &mut u64) -> &'static CoreArchitecture { + let arch = + unsafe { BNGetAssociatedArchitectureByAddress(self.core().as_ptr(), addr as *mut _) }; - CoreArchitecture(arch) + unsafe { CoreArchitecture::from_raw(arch) } } fn instruction_info(&self, data: &[u8], addr: u64) -> Option { let mut info = unsafe { zeroed::() }; let success = unsafe { BNGetInstructionInfo( - self.0, + self.core().as_ptr(), data.as_ptr(), addr, data.len(), @@ -1170,7 +1185,7 @@ impl Architecture for CoreArchitecture { unsafe { if BNGetInstructionText( - self.0, + self.core().as_ptr(), data.as_ptr(), addr, &mut consumed as *mut _, @@ -1197,7 +1212,13 @@ impl Architecture for CoreArchitecture { ) -> Option<(usize, bool)> { let mut size = data.len(); let success = unsafe { - BNGetInstructionLowLevelIL(self.0, data.as_ptr(), addr, &mut size as *mut _, il.handle) + BNGetInstructionLowLevelIL( + self.core().as_ptr(), + data.as_ptr(), + addr, + &mut size as *mut _, + il.handle, + ) }; if !success { @@ -1237,11 +1258,11 @@ impl Architecture for CoreArchitecture { fn registers_all(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetAllArchitectureRegisters(self.0, &mut count as *mut _); + let regs = BNGetAllArchitectureRegisters(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreRegister(self.0, *reg)) + .map(|reg| CoreRegister(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1253,11 +1274,12 @@ impl Architecture for CoreArchitecture { fn registers_full_width(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetFullWidthArchitectureRegisters(self.0, &mut count as *mut _); + let regs = + BNGetFullWidthArchitectureRegisters(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreRegister(self.0, *reg)) + .map(|reg| CoreRegister(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1269,11 +1291,11 @@ impl Architecture for CoreArchitecture { fn registers_global(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetArchitectureGlobalRegisters(self.0, &mut count as *mut _); + let regs = BNGetArchitectureGlobalRegisters(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreRegister(self.0, *reg)) + .map(|reg| CoreRegister(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1285,11 +1307,11 @@ impl Architecture for CoreArchitecture { fn registers_system(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetArchitectureSystemRegisters(self.0, &mut count as *mut _); + let regs = BNGetArchitectureSystemRegisters(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreRegister(self.0, *reg)) + .map(|reg| CoreRegister(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1301,11 +1323,12 @@ impl Architecture for CoreArchitecture { fn register_stacks(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetAllArchitectureRegisterStacks(self.0, &mut count as *mut _); + let regs = + BNGetAllArchitectureRegisterStacks(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreRegisterStack(self.0, *reg)) + .map(|reg| CoreRegisterStack(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1317,11 +1340,11 @@ impl Architecture for CoreArchitecture { fn flags(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetAllArchitectureFlags(self.0, &mut count as *mut _); + let regs = BNGetAllArchitectureFlags(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreFlag(self.0, *reg)) + .map(|reg| CoreFlag(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1333,11 +1356,12 @@ impl Architecture for CoreArchitecture { fn flag_write_types(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetAllArchitectureFlagWriteTypes(self.0, &mut count as *mut _); + let regs = + BNGetAllArchitectureFlagWriteTypes(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreFlagWrite(self.0, *reg)) + .map(|reg| CoreFlagWrite(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1349,11 +1373,12 @@ impl Architecture for CoreArchitecture { fn flag_classes(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetAllArchitectureSemanticFlagClasses(self.0, &mut count as *mut _); + let regs = + BNGetAllArchitectureSemanticFlagClasses(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreFlagClass(self.0, *reg)) + .map(|reg| CoreFlagClass(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1365,11 +1390,12 @@ impl Architecture for CoreArchitecture { fn flag_groups(&self) -> Vec { unsafe { let mut count: usize = 0; - let regs = BNGetAllArchitectureSemanticFlagGroups(self.0, &mut count as *mut _); + let regs = + BNGetAllArchitectureSemanticFlagGroups(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(regs, count) .iter() - .map(|reg| CoreFlagGroup(self.0, *reg)) + .map(|reg| CoreFlagGroup(self.core(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1388,7 +1414,7 @@ impl Architecture for CoreArchitecture { unsafe { let mut count: usize = 0; let flags = BNGetArchitectureFlagsRequiredForFlagCondition( - self.0, + self.core().as_ptr(), condition, class_id, &mut count as *mut _, @@ -1396,7 +1422,7 @@ impl Architecture for CoreArchitecture { let ret = slice::from_raw_parts_mut(flags, count) .iter() - .map(|flag| CoreFlag(self.0, *flag)) + .map(|flag| CoreFlag(self.core(), *flag)) .collect(); BNFreeRegisterList(flags); @@ -1406,57 +1432,58 @@ impl Architecture for CoreArchitecture { } fn stack_pointer_reg(&self) -> Option { - match unsafe { BNGetArchitectureStackPointerRegister(self.0) } { + match unsafe { BNGetArchitectureStackPointerRegister(self.core().as_ptr()) } { 0xffff_ffff => None, - reg => Some(CoreRegister(self.0, reg)), + reg => Some(CoreRegister(self.core(), reg)), } } fn link_reg(&self) -> Option { - match unsafe { BNGetArchitectureLinkRegister(self.0) } { + match unsafe { BNGetArchitectureLinkRegister(self.core().as_ptr()) } { 0xffff_ffff => None, - reg => Some(CoreRegister(self.0, reg)), + reg => Some(CoreRegister(self.core(), reg)), } } fn register_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreRegister(self.0, id)) + Some(CoreRegister(self.core(), id)) } fn register_stack_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreRegisterStack(self.0, id)) + Some(CoreRegisterStack(self.core(), id)) } fn flag_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlag(self.0, id)) + Some(CoreFlag(self.core(), id)) } fn flag_write_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlagWrite(self.0, id)) + Some(CoreFlagWrite(self.core(), id)) } fn flag_class_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlagClass(self.0, id)) + Some(CoreFlagClass(self.core(), id)) } fn flag_group_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlagGroup(self.0, id)) + Some(CoreFlagGroup(self.core(), id)) } fn intrinsics(&self) -> Vec { unsafe { let mut count: usize = 0; - let intrinsics = BNGetAllArchitectureIntrinsics(self.0, &mut count as *mut _); + let intrinsics = + BNGetAllArchitectureIntrinsics(self.core().as_ptr(), &mut count as *mut _); let ret = slice::from_raw_parts_mut(intrinsics, count) .iter() - .map(|reg| CoreIntrinsic(self.0, *reg)) + .map(|reg| CoreIntrinsic(self.core(), *reg)) .collect(); BNFreeRegisterList(intrinsics); @@ -1466,16 +1493,16 @@ impl Architecture for CoreArchitecture { } fn intrinsic_class(&self, id: u32) -> binaryninjacore_sys::BNIntrinsicClass { - unsafe { BNGetArchitectureIntrinsicClass(self.0, id) } + unsafe { BNGetArchitectureIntrinsicClass(self.core().as_ptr(), id) } } fn intrinsic_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreIntrinsic(self.0, id)) + Some(CoreIntrinsic(self.core(), id)) } fn can_assemble(&self) -> bool { - unsafe { BNCanArchitectureAssemble(self.0) } + unsafe { BNCanArchitectureAssemble(self.core().as_ptr()) } } fn assemble(&self, code: &str, addr: u64) -> Result, String> { @@ -1488,7 +1515,7 @@ impl Architecture for CoreArchitecture { let mut error_raw: *mut c_char = ptr::null_mut(); let res = unsafe { BNAssemble( - self.0, + self.core().as_ptr(), code.as_ptr(), addr, result.as_raw(), @@ -1510,32 +1537,52 @@ impl Architecture for CoreArchitecture { fn is_never_branch_patch_available(&self, data: &[u8], addr: u64) -> bool { unsafe { - BNIsArchitectureNeverBranchPatchAvailable(self.0, data.as_ptr(), addr, data.len()) + BNIsArchitectureNeverBranchPatchAvailable( + self.core().as_ptr(), + data.as_ptr(), + addr, + data.len(), + ) } } fn is_always_branch_patch_available(&self, data: &[u8], addr: u64) -> bool { unsafe { - BNIsArchitectureAlwaysBranchPatchAvailable(self.0, data.as_ptr(), addr, data.len()) + BNIsArchitectureAlwaysBranchPatchAvailable( + self.core().as_ptr(), + data.as_ptr(), + addr, + data.len(), + ) } } fn is_invert_branch_patch_available(&self, data: &[u8], addr: u64) -> bool { unsafe { - BNIsArchitectureInvertBranchPatchAvailable(self.0, data.as_ptr(), addr, data.len()) + BNIsArchitectureInvertBranchPatchAvailable( + self.core().as_ptr(), + data.as_ptr(), + addr, + data.len(), + ) } } fn is_skip_and_return_zero_patch_available(&self, data: &[u8], addr: u64) -> bool { unsafe { - BNIsArchitectureSkipAndReturnZeroPatchAvailable(self.0, data.as_ptr(), addr, data.len()) + BNIsArchitectureSkipAndReturnZeroPatchAvailable( + self.core().as_ptr(), + data.as_ptr(), + addr, + data.len(), + ) } } fn is_skip_and_return_value_patch_available(&self, data: &[u8], addr: u64) -> bool { unsafe { BNIsArchitectureSkipAndReturnValuePatchAvailable( - self.0, + self.core().as_ptr(), data.as_ptr(), addr, data.len(), @@ -1544,54 +1591,62 @@ impl Architecture for CoreArchitecture { } fn convert_to_nop(&self, data: &mut [u8], addr: u64) -> bool { - unsafe { BNArchitectureConvertToNop(self.0, data.as_mut_ptr(), addr, data.len()) } + unsafe { + BNArchitectureConvertToNop(self.core().as_ptr(), data.as_mut_ptr(), addr, data.len()) + } } fn always_branch(&self, data: &mut [u8], addr: u64) -> bool { - unsafe { BNArchitectureAlwaysBranch(self.0, data.as_mut_ptr(), addr, data.len()) } + unsafe { + BNArchitectureAlwaysBranch(self.core().as_ptr(), data.as_mut_ptr(), addr, data.len()) + } } fn invert_branch(&self, data: &mut [u8], addr: u64) -> bool { - unsafe { BNArchitectureInvertBranch(self.0, data.as_mut_ptr(), addr, data.len()) } + unsafe { + BNArchitectureInvertBranch(self.core().as_ptr(), data.as_mut_ptr(), addr, data.len()) + } } fn skip_and_return_value(&self, data: &mut [u8], addr: u64, value: u64) -> bool { unsafe { - BNArchitectureSkipAndReturnValue(self.0, data.as_mut_ptr(), addr, data.len(), value) + BNArchitectureSkipAndReturnValue( + self.core().as_ptr(), + data.as_mut_ptr(), + addr, + data.len(), + value, + ) } } - fn handle(&self) -> CoreArchitecture { - *self + fn core(&self) -> &'static CoreArchitecture { + unsafe { core::mem::transmute(&self) } } } macro_rules! cc_func { ($get_name:ident, $get_api:ident, $set_name:ident, $set_api:ident) => { fn $get_name(&self) -> Option>> { - let handle = self.as_ref(); - unsafe { - let cc = $get_api(handle.0); + let cc = $get_api(self.core().as_ptr()); if cc.is_null() { None } else { - Some(CallingConvention::ref_from_raw(cc, self.handle())) + Some(CallingConvention::ref_from_raw(cc, core::mem::transmute(self))) } } } fn $set_name(&self, cc: &CallingConvention) { - let handle = self.as_ref(); - assert!( - cc.arch_handle.borrow().as_ref().0 == handle.0, + cc.arch_handle.core().as_ptr() as usize == self.core().as_ptr() as usize, "use of calling convention with non-matching architecture!" ); unsafe { - $set_api(handle.0, cc.handle); + $set_api(self.core().as_ptr(), cc.handle); } } }; @@ -1603,7 +1658,7 @@ pub trait ArchitectureExt: Architecture { let name = name.into_bytes_with_nul(); match unsafe { - BNGetArchitectureRegisterByName(self.as_ref().0, name.as_ref().as_ptr() as *mut _) + BNGetArchitectureRegisterByName(self.core().as_ptr(), name.as_ref().as_ptr() as *mut _) } { 0xffff_ffff => None, reg => self.register_from_id(reg), @@ -1640,7 +1695,7 @@ pub trait ArchitectureExt: Architecture { fn standalone_platform(&self) -> Option> { unsafe { - let handle = BNGetArchitectureStandalonePlatform(self.as_ref().0); + let handle = BNGetArchitectureStandalonePlatform(self.core().as_ptr()); if handle.is_null() { return None; @@ -1657,7 +1712,8 @@ pub trait ArchitectureExt: Architecture { }; unsafe { - let handle = BNArchitectureGetRelocationHandler(self.as_ref().0, view_name.as_ptr()); + let handle = + BNArchitectureGetRelocationHandler(self.core().as_ptr(), view_name.as_ptr()); if handle.is_null() { return None; @@ -1677,14 +1733,14 @@ pub trait ArchitectureExt: Architecture { + Sized, F: FnOnce(CustomRelocationHandlerHandle, CoreRelocationHandler) -> R, { - crate::relocation::register_relocation_handler(self.as_ref(), name, func); + crate::relocation::register_relocation_handler(self.core(), name, func); } fn register_function_recognizer(&self, recognizer: R) where R: 'static + FunctionRecognizer + Send + Sync + Sized, { - crate::functionrecognizer::register_arch_function_recognizer(self.as_ref(), recognizer); + crate::functionrecognizer::register_arch_function_recognizer(self.core(), recognizer); } } @@ -1693,8 +1749,8 @@ impl ArchitectureExt for T {} pub fn register_architecture(name: S, func: F) -> &'static A where S: BnStrCompatible, - A: 'static + Architecture> + Send + Sync + Sized, - F: FnOnce(CustomArchitectureHandle, CoreArchitecture) -> A, + A: 'static + Architecture + Send + Sync + Sized, + F: FnOnce(&'static CoreArchitecture) -> A, { use std::mem; use std::os::raw::{c_char, c_void}; @@ -1702,8 +1758,8 @@ where #[repr(C)] struct ArchitectureBuilder where - A: 'static + Architecture> + Send + Sync, - F: FnOnce(CustomArchitectureHandle, CoreArchitecture) -> A, + A: 'static + Architecture + Send + Sync, + F: FnOnce(&'static CoreArchitecture) -> A, { arch: MaybeUninit, func: Option, @@ -1711,25 +1767,22 @@ where extern "C" fn cb_init(ctxt: *mut c_void, obj: *mut BNArchitecture) where - A: 'static + Architecture> + Send + Sync, - F: FnOnce(CustomArchitectureHandle, CoreArchitecture) -> A, + A: 'static + Architecture + Send + Sync, + F: FnOnce(&'static CoreArchitecture) -> A, { unsafe { let custom_arch = &mut *(ctxt as *mut ArchitectureBuilder); - let custom_arch_handle = CustomArchitectureHandle { - handle: ctxt as *mut A, - }; let create = custom_arch.func.take().unwrap(); custom_arch .arch - .write(create(custom_arch_handle, CoreArchitecture(obj))); + .write(create(CoreArchitecture::from_raw(obj))); } } extern "C" fn cb_endianness(ctxt: *mut c_void) -> BNEndianness where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.endianness() @@ -1737,7 +1790,7 @@ where extern "C" fn cb_address_size(ctxt: *mut c_void) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.address_size() @@ -1745,7 +1798,7 @@ where extern "C" fn cb_default_integer_size(ctxt: *mut c_void) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.default_integer_size() @@ -1753,7 +1806,7 @@ where extern "C" fn cb_instruction_alignment(ctxt: *mut c_void) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.instruction_alignment() @@ -1761,7 +1814,7 @@ where extern "C" fn cb_max_instr_len(ctxt: *mut c_void) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.max_instr_len() @@ -1769,7 +1822,7 @@ where extern "C" fn cb_opcode_display_len(ctxt: *mut c_void) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.opcode_display_len() @@ -1780,12 +1833,12 @@ where addr: *mut u64, ) -> *mut BNArchitecture where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let addr = unsafe { &mut *(addr) }; - custom_arch.associated_arch_by_addr(addr).0 + custom_arch.associated_arch_by_addr(addr).core().as_ptr() } extern "C" fn cb_instruction_info( @@ -1796,7 +1849,7 @@ where result: *mut BNInstructionInfo, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, len) }; @@ -1820,7 +1873,7 @@ where count: *mut usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, *len) }; @@ -1855,15 +1908,12 @@ where il: *mut BNLowLevelILFunction, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let custom_arch_handle = CustomArchitectureHandle { - handle: ctxt as *mut A, - }; let data = unsafe { slice::from_raw_parts(data, *len) }; - let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; + let mut lifter = unsafe { Lifter::from_raw(custom_arch, il) }; match custom_arch.instruction_llil(data, addr, &mut lifter) { Some((res_len, res_value)) => { @@ -1876,7 +1926,7 @@ where extern "C" fn cb_reg_name(ctxt: *mut c_void, reg: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -1888,7 +1938,7 @@ where extern "C" fn cb_flag_name(ctxt: *mut c_void, flag: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -1900,7 +1950,7 @@ where extern "C" fn cb_flag_write_name(ctxt: *mut c_void, flag_write: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -1912,7 +1962,7 @@ where extern "C" fn cb_semantic_flag_class_name(ctxt: *mut c_void, class: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -1924,7 +1974,7 @@ where extern "C" fn cb_semantic_flag_group_name(ctxt: *mut c_void, group: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -1955,7 +2005,7 @@ where extern "C" fn cb_registers_full_width(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_full_width(); @@ -1965,7 +2015,7 @@ where extern "C" fn cb_registers_all(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_all(); @@ -1975,7 +2025,7 @@ where extern "C" fn cb_registers_global(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_global(); @@ -1985,7 +2035,7 @@ where extern "C" fn cb_registers_system(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.registers_system(); @@ -1995,7 +2045,7 @@ where extern "C" fn cb_flags(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let flags = custom_arch.flags(); @@ -2005,7 +2055,7 @@ where extern "C" fn cb_flag_write_types(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let flag_writes = custom_arch.flag_write_types(); @@ -2015,7 +2065,7 @@ where extern "C" fn cb_semantic_flag_classes(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let flag_classes = custom_arch.flag_classes(); @@ -2025,7 +2075,7 @@ where extern "C" fn cb_semantic_flag_groups(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let flag_groups = custom_arch.flag_groups(); @@ -2035,7 +2085,7 @@ where extern "C" fn cb_flag_role(ctxt: *mut c_void, flag: u32, class: u32) -> BNFlagRole where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2056,7 +2106,7 @@ where count: *mut usize, ) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let class = custom_arch.flag_class_from_id(class); @@ -2071,7 +2121,7 @@ where count: *mut usize, ) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2092,7 +2142,7 @@ where count: *mut usize, ) -> *mut BNFlagConditionForSemanticClass where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2127,7 +2177,7 @@ where _ctxt: *mut c_void, conds: *mut BNFlagConditionForSemanticClass, ) where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { unsafe { libc::free(conds as *mut _); @@ -2140,7 +2190,7 @@ where count: *mut usize, ) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2160,7 +2210,7 @@ where write_type: u32, ) -> u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch @@ -2181,17 +2231,14 @@ where il: *mut BNLowLevelILFunction, ) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let custom_arch_handle = CustomArchitectureHandle { - handle: ctxt as *mut A, - }; let flag_write = custom_arch.flag_write_from_id(flag_write); let flag = custom_arch.flag_from_id(flag); let operands = unsafe { slice::from_raw_parts(operands_raw, operand_count) }; - let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; + let mut lifter = unsafe { Lifter::from_raw(custom_arch, il) }; if let (Some(flag_write), Some(flag)) = (flag_write, flag) { if let Some(op) = FlagWriteOp::from_op(custom_arch, size, op, operands) { @@ -2211,7 +2258,7 @@ where unsafe { BNGetDefaultArchitectureFlagWriteLowLevelIL( - custom_arch.as_ref().0, + custom_arch.core().as_ptr(), op, size, role, @@ -2234,16 +2281,13 @@ where il: *mut BNLowLevelILFunction, ) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let custom_arch_handle = CustomArchitectureHandle { - handle: ctxt as *mut A, - }; let class = custom_arch.flag_class_from_id(class); - let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; + let mut lifter = unsafe { Lifter::from_raw(custom_arch, il) }; if let Some(expr) = custom_arch.flag_cond_llil(cond, class, &mut lifter) { // TODO verify that returned expr is a bool value return expr.expr_idx; @@ -2258,14 +2302,11 @@ where il: *mut BNLowLevelILFunction, ) -> usize where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let custom_arch_handle = CustomArchitectureHandle { - handle: ctxt as *mut A, - }; - let mut lifter = unsafe { Lifter::from_raw(custom_arch_handle, il) }; + let mut lifter = unsafe { Lifter::from_raw(custom_arch, il) }; if let Some(group) = custom_arch.flag_group_from_id(group) { if let Some(expr) = custom_arch.flag_group_llil(group, &mut lifter) { @@ -2292,7 +2333,7 @@ where extern "C" fn cb_register_info(ctxt: *mut c_void, reg: u32, result: *mut BNRegisterInfo) where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let result = unsafe { &mut *result }; @@ -2313,7 +2354,7 @@ where extern "C" fn cb_stack_pointer(ctxt: *mut c_void) -> u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2326,7 +2367,7 @@ where extern "C" fn cb_link_reg(ctxt: *mut c_void) -> u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2339,7 +2380,7 @@ where extern "C" fn cb_reg_stack_name(ctxt: *mut c_void, stack: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2351,7 +2392,7 @@ where extern "C" fn cb_reg_stacks(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let regs = custom_arch.register_stacks(); @@ -2364,7 +2405,7 @@ where stack: u32, result: *mut BNRegisterStackInfo, ) where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let result = unsafe { &mut *result }; @@ -2390,7 +2431,7 @@ where extern "C" fn cb_intrinsic_class(ctxt: *mut c_void, intrinsic: u32) -> BNIntrinsicClass where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.intrinsic_class(intrinsic) @@ -2398,7 +2439,7 @@ where extern "C" fn cb_intrinsic_name(ctxt: *mut c_void, intrinsic: u32) -> *mut c_char where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; match custom_arch.intrinsic_from_id(intrinsic) { @@ -2409,7 +2450,7 @@ where extern "C" fn cb_intrinsics(ctxt: *mut c_void, count: *mut usize) -> *mut u32 where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let intrinsics = custom_arch.intrinsics(); @@ -2422,7 +2463,7 @@ where count: *mut usize, ) -> *mut BNNameAndType where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2453,7 +2494,7 @@ where extern "C" fn cb_free_name_and_types(ctxt: *mut c_void, nt: *mut BNNameAndType, count: usize) where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let _custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2473,7 +2514,7 @@ where count: *mut usize, ) -> *mut BNTypeWithConfidence where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; @@ -2504,7 +2545,7 @@ where tl: *mut BNTypeWithConfidence, count: usize, ) where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let _custom_arch = unsafe { &*(ctxt as *mut A) }; if !tl.is_null() { @@ -2514,7 +2555,7 @@ where extern "C" fn cb_can_assemble(ctxt: *mut c_void) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; custom_arch.can_assemble() @@ -2528,7 +2569,7 @@ where errors: *mut *mut c_char, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let code = raw_to_string(code).unwrap_or("".into()); @@ -2563,7 +2604,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, len) }; @@ -2577,7 +2618,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, len) }; @@ -2591,7 +2632,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, len) }; @@ -2605,7 +2646,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, len) }; @@ -2619,7 +2660,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts(data, len) }; @@ -2633,7 +2674,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts_mut(data, len) }; @@ -2647,7 +2688,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts_mut(data, len) }; @@ -2661,7 +2702,7 @@ where len: usize, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts_mut(data, len) }; @@ -2676,7 +2717,7 @@ where val: u64, ) -> bool where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { slice::from_raw_parts_mut(data, len) }; @@ -2783,38 +2824,29 @@ where pub struct CustomArchitectureHandle where - A: 'static + Architecture> + Send + Sync, + A: 'static + Architecture + Send + Sync, { handle: *mut A, } -unsafe impl Send for CustomArchitectureHandle where - A: 'static + Architecture> + Send + Sync -{ -} +unsafe impl Send for CustomArchitectureHandle where A: 'static + Architecture + Send + Sync {} -unsafe impl Sync for CustomArchitectureHandle where - A: 'static + Architecture> + Send + Sync -{ -} +unsafe impl Sync for CustomArchitectureHandle where A: 'static + Architecture + Send + Sync {} impl Clone for CustomArchitectureHandle where - A: 'static + Architecture + Send + Sync, + A: 'static + Architecture + Send + Sync, { fn clone(&self) -> Self { *self } } -impl Copy for CustomArchitectureHandle where - A: 'static + Architecture + Send + Sync -{ -} +impl Copy for CustomArchitectureHandle where A: 'static + Architecture + Send + Sync {} impl Borrow for CustomArchitectureHandle where - A: 'static + Architecture + Send + Sync, + A: 'static + Architecture + Send + Sync, { fn borrow(&self) -> &A { unsafe { &*self.handle } diff --git a/rust/src/basicblock.rs b/rust/src/basicblock.rs index a6ac8f745..59d40a3ee 100644 --- a/rust/src/basicblock.rs +++ b/rust/src/basicblock.rs @@ -132,7 +132,7 @@ impl BasicBlock { } } - pub fn arch(&self) -> CoreArchitecture { + pub fn arch(&self) -> &'static CoreArchitecture { unsafe { let arch = BNGetBasicBlockArchitecture(self.handle); CoreArchitecture::from_raw(arch) diff --git a/rust/src/binaryview.rs b/rust/src/binaryview.rs index 25b3fbb2f..b73a0ae33 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -345,7 +345,7 @@ pub trait BinaryViewExt: BinaryViewBase { } } - fn default_arch(&self) -> Option { + fn default_arch(&self) -> Option<&'static CoreArchitecture> { unsafe { let raw = BNGetDefaultArchitecture(self.as_ref().handle); @@ -359,7 +359,7 @@ pub trait BinaryViewExt: BinaryViewBase { fn set_default_arch(&self, arch: &A) { unsafe { - BNSetDefaultArchitecture(self.as_ref().handle, arch.as_ref().0); + BNSetDefaultArchitecture(self.as_ref().handle, arch.core().as_ptr()); } } @@ -383,7 +383,7 @@ pub trait BinaryViewExt: BinaryViewBase { fn instruction_len(&self, arch: &A, addr: u64) -> Option { unsafe { - let size = BNGetInstructionLength(self.as_ref().handle, arch.as_ref().0, addr); + let size = BNGetInstructionLength(self.as_ref().handle, arch.core().as_ptr(), addr); if size > 0 { Some(size) diff --git a/rust/src/callingconvention.rs b/rust/src/callingconvention.rs index e7888131b..f1900a8c4 100644 --- a/rust/src/callingconvention.rs +++ b/rust/src/callingconvention.rs @@ -14,9 +14,7 @@ //! Contains and provides information about different systems' calling conventions to analysis. -use std::borrow::Borrow; use std::fmt::{Debug, Formatter}; -use std::marker::PhantomData; use std::mem; use std::os::raw::c_void; use std::ptr; @@ -58,7 +56,11 @@ pub trait CallingConventionBase: Sync { fn are_argument_registers_used_for_var_args(&self) -> bool; } -pub fn register_calling_convention(arch: &A, name: N, cc: C) -> Ref> +pub fn register_calling_convention( + arch: &'static A, + name: N, + cc: C, +) -> Ref> where A: Architecture, N: BnStrCompatible, @@ -399,26 +401,24 @@ where unsafe { let cc_name = name.as_ref().as_ptr() as *mut _; - let result = BNCreateCallingConvention(arch.as_ref().0, cc_name, &mut cc); + let result = BNCreateCallingConvention(arch.core().as_ptr(), cc_name, &mut cc); assert!(!result.is_null()); (*raw).raw_handle = result; - BNRegisterCallingConvention(arch.as_ref().0, result); + BNRegisterCallingConvention(arch.core().as_ptr(), result); Ref::new(CallingConvention { handle: result, - arch_handle: arch.handle(), - _arch: PhantomData, + arch_handle: arch, }) } } pub struct CallingConvention { pub(crate) handle: *mut BNCallingConvention, - pub(crate) arch_handle: A::Handle, - _arch: PhantomData<*mut A>, + pub(crate) arch_handle: &'static A, } unsafe impl Send for CallingConvention {} @@ -427,12 +427,11 @@ unsafe impl Sync for CallingConvention {} impl CallingConvention { pub(crate) unsafe fn ref_from_raw( handle: *mut BNCallingConvention, - arch: A::Handle, + arch: &'static A, ) -> Ref { Ref::new(CallingConvention { handle, arch_handle: arch, - _arch: PhantomData, }) } @@ -524,7 +523,7 @@ impl CallingConventionBase for CallingConvention { unsafe { let mut count = 0; let regs = BNGetCallerSavedRegisters(self.handle, &mut count); - let arch = self.arch_handle.borrow(); + let arch = self.arch_handle; let res = slice::from_raw_parts(regs, count) .iter() @@ -544,7 +543,7 @@ impl CallingConventionBase for CallingConvention { unsafe { let mut count = 0; let regs = BNGetCalleeSavedRegisters(self.handle, &mut count); - let arch = self.arch_handle.borrow(); + let arch = self.arch_handle; let res = slice::from_raw_parts(regs, count) .iter() @@ -564,12 +563,10 @@ impl CallingConventionBase for CallingConvention { unsafe { let mut count = 0; let regs = BNGetIntegerArgumentRegisters(self.handle, &mut count); - let arch = self.arch_handle.borrow(); - let res = slice::from_raw_parts(regs, count) .iter() .map(|&r| { - arch.register_from_id(r) + self.arch_handle.register_from_id(r) .expect("bad reg id from CallingConvention") }) .collect(); @@ -584,12 +581,10 @@ impl CallingConventionBase for CallingConvention { unsafe { let mut count = 0; let regs = BNGetFloatArgumentRegisters(self.handle, &mut count); - let arch = self.arch_handle.borrow(); - let res = slice::from_raw_parts(regs, count) .iter() .map(|&r| { - arch.register_from_id(r) + self.arch_handle.register_from_id(r) .expect("bad reg id from CallingConvention") }) .collect(); @@ -618,28 +613,28 @@ impl CallingConventionBase for CallingConvention { fn return_int_reg(&self) -> Option { match unsafe { BNGetIntegerReturnValueRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.register_from_id(id), _ => None, } } fn return_hi_int_reg(&self) -> Option { match unsafe { BNGetHighIntegerReturnValueRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.register_from_id(id), _ => None, } } fn return_float_reg(&self) -> Option { match unsafe { BNGetFloatReturnValueRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.register_from_id(id), _ => None, } } fn global_pointer_reg(&self) -> Option { match unsafe { BNGetGlobalPointerRegister(self.handle) } { - id if id < 0x8000_0000 => self.arch_handle.borrow().register_from_id(id), + id if id < 0x8000_0000 => self.arch_handle.register_from_id(id), _ => None, } } @@ -665,8 +660,7 @@ unsafe impl RefCountable for CallingConvention { unsafe fn inc_ref(handle: &Self) -> Ref { Ref::new(Self { handle: BNNewCallingConventionReference(handle.handle), - arch_handle: handle.arch_handle.clone(), - _arch: PhantomData, + arch_handle: handle.arch_handle, }) } @@ -677,7 +671,7 @@ unsafe impl RefCountable for CallingConvention { impl CoreArrayProvider for CallingConvention { type Raw = *mut BNCallingConvention; - type Context = A::Handle; + type Context = &'static A; type Wrapped<'a> = Guard<'a, CallingConvention>; } @@ -689,8 +683,7 @@ unsafe impl CoreArrayProviderInner for CallingConvention { Guard::new( CallingConvention { handle: *raw, - arch_handle: context.clone(), - _arch: Default::default(), + arch_handle: context, }, context, ) @@ -724,8 +717,7 @@ pub struct ConventionBuilder { are_argument_registers_used_for_var_args: bool, - arch_handle: A::Handle, - _arch: PhantomData<*const A>, + arch_handle: &'static A, } unsafe impl Send for ConventionBuilder {} @@ -745,7 +737,7 @@ macro_rules! reg_list { pub fn $name(mut self, regs: &[&str]) -> Self { { // FIXME NLL - let arch = self.arch_handle.borrow(); + let arch = self.arch_handle; let arch_regs = regs.iter().filter_map(|&r| arch.register_by_name(r)); self.$name = arch_regs.collect(); @@ -761,7 +753,7 @@ macro_rules! reg { pub fn $name(mut self, reg: &str) -> Self { { // FIXME NLL - let arch = self.arch_handle.borrow(); + let arch = self.arch_handle; self.$name = arch.register_by_name(reg); } @@ -771,7 +763,7 @@ macro_rules! reg { } impl ConventionBuilder { - pub fn new(arch: &A) -> Self { + pub fn new(arch: &'static A) -> Self { Self { caller_saved_registers: Vec::new(), _callee_saved_registers: Vec::new(), @@ -793,8 +785,7 @@ impl ConventionBuilder { are_argument_registers_used_for_var_args: false, - arch_handle: arch.handle(), - _arch: PhantomData, + arch_handle: arch, } } @@ -819,9 +810,7 @@ impl ConventionBuilder { bool_arg!(are_argument_registers_used_for_var_args); pub fn register(self, name: &str) -> Ref> { - let arch = self.arch_handle.clone(); - - register_calling_convention(arch.borrow(), name, self) + register_calling_convention(self.arch_handle, name, self) } } diff --git a/rust/src/custombinaryview.rs b/rust/src/custombinaryview.rs index 05f1acb8d..5b500f14e 100644 --- a/rust/src/custombinaryview.rs +++ b/rust/src/custombinaryview.rs @@ -192,7 +192,12 @@ pub trait BinaryViewTypeExt: BinaryViewTypeBase { fn register_arch(&self, id: u32, endianness: Endianness, arch: &A) { unsafe { - BNRegisterArchitectureForViewType(self.as_ref().0, id, endianness, arch.as_ref().0); + BNRegisterArchitectureForViewType( + self.as_ref().0, + id, + endianness, + arch.core().as_ptr(), + ); } } @@ -200,7 +205,7 @@ pub trait BinaryViewTypeExt: BinaryViewTypeBase { let arch = plat.arch(); unsafe { - BNRegisterPlatformForViewType(self.as_ref().0, id, arch.0, plat.handle); + BNRegisterPlatformForViewType(self.as_ref().0, id, arch.core().as_ptr(), plat.handle); } } diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs index 1b940ff91..25b233017 100644 --- a/rust/src/demangle.rs +++ b/rust/src/demangle.rs @@ -81,7 +81,7 @@ pub fn demangle_gnu3( let mut out_size: usize = 0; let res = unsafe { BNDemangleGNU3( - arch.0, + arch.as_ptr(), mangled_name_ptr.as_ptr() as *const c_char, &mut out_type, &mut out_name, @@ -137,7 +137,7 @@ pub fn demangle_ms( let mut out_size: usize = 0; let res = unsafe { BNDemangleMS( - arch.0, + arch.as_ptr(), mangled_name_ptr.as_ptr() as *const c_char, &mut out_type, &mut out_name, diff --git a/rust/src/function.rs b/rust/src/function.rs index 48f02205b..689b118b9 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -43,7 +43,7 @@ use std::{fmt, mem}; use std::{ffi::c_char, hash::Hash, ops::Range}; pub struct Location { - pub arch: Option, + pub arch: Option<&'static CoreArchitecture>, pub addr: u64, } @@ -53,8 +53,8 @@ impl From for Location { } } -impl From<(CoreArchitecture, u64)> for Location { - fn from(loc: (CoreArchitecture, u64)) -> Self { +impl From<(&'static CoreArchitecture, u64)> for Location { + fn from(loc: (&'static CoreArchitecture, u64)) -> Self { Location { arch: Some(loc.0), addr: loc.1, @@ -63,7 +63,7 @@ impl From<(CoreArchitecture, u64)> for Location { } pub struct NativeBlockIter { - arch: CoreArchitecture, + arch: &'static CoreArchitecture, bv: Ref, cur: u64, end: u64, @@ -79,7 +79,7 @@ impl Iterator for NativeBlockIter { None } else { self.bv - .instruction_len(&self.arch, res) + .instruction_len(self.arch, res) .map(|x| { self.cur += x as u64; res @@ -134,7 +134,7 @@ impl Function { Ref::new(Self { handle }) } - pub fn arch(&self) -> CoreArchitecture { + pub fn arch(&self) -> &'static CoreArchitecture { unsafe { let arch = BNGetFunctionArchitecture(self.handle); CoreArchitecture::from_raw(arch) @@ -248,11 +248,11 @@ impl Function { pub fn basic_block_containing( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Option>> { let arch = arch.unwrap_or_else(|| self.arch()); unsafe { - let block = BNGetFunctionBasicBlockAtAddress(self.handle, arch.0, addr); + let block = BNGetFunctionBasicBlockAtAddress(self.handle, arch.as_ptr(), addr); let context = NativeBlock { _priv: () }; if block.is_null() { @@ -266,11 +266,11 @@ impl Function { pub fn block_annotations( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array> { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; - let lines = unsafe { BNGetFunctionBlockAnnotations(self.handle, arch.0, addr, &mut count) }; + let lines = unsafe { BNGetFunctionBlockAnnotations(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!lines.is_null()); unsafe { Array::new(lines, count, ()) } } @@ -462,9 +462,9 @@ impl Function { unsafe { BNSetAutoFunctionStackAdjustment(self.handle, &mut value_raw) } } - pub fn call_stack_adjustment(&self, addr: u64, arch: Option) -> Conf { + pub fn call_stack_adjustment(&self, addr: u64, arch: Option<&'static CoreArchitecture>) -> Conf { let arch = arch.unwrap_or_else(|| self.arch()); - let result = unsafe { BNGetCallStackAdjustment(self.handle, arch.0, addr) }; + let result = unsafe { BNGetCallStackAdjustment(self.handle, arch.as_ptr(), addr) }; result.into() } @@ -472,7 +472,7 @@ impl Function { &self, addr: u64, adjust: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: Into>, { @@ -481,7 +481,7 @@ impl Function { unsafe { BNSetUserCallStackAdjustment( self.handle, - arch.0, + arch.as_ptr(), addr, adjust.contents, adjust.confidence, @@ -493,7 +493,7 @@ impl Function { &self, addr: u64, adjust: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: Into>, { @@ -502,7 +502,7 @@ impl Function { unsafe { BNSetAutoCallStackAdjustment( self.handle, - arch.0, + arch.as_ptr(), addr, adjust.contents, adjust.confidence, @@ -513,10 +513,10 @@ impl Function { pub fn call_type_adjustment( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Option>> { let arch = arch.unwrap_or_else(|| self.arch()); - let result = unsafe { BNGetCallTypeAdjustment(self.handle, arch.0, addr) }; + let result = unsafe { BNGetCallTypeAdjustment(self.handle, arch.as_ptr(), addr) }; (!result.type_.is_null()) .then(|| unsafe { Conf::new(Type::ref_from_raw(result.type_), result.confidence) }) } @@ -530,7 +530,7 @@ impl Function { &self, addr: u64, adjust_type: Option, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: Into>, { @@ -546,14 +546,14 @@ impl Function { .as_mut() .map(|x| x as *mut _) .unwrap_or(core::ptr::null_mut()); - unsafe { BNSetUserCallTypeAdjustment(self.handle, arch.0, addr, adjust_ptr) } + unsafe { BNSetUserCallTypeAdjustment(self.handle, arch.as_ptr(), addr, adjust_ptr) } } pub fn set_auto_call_type_adjustment<'a, I>( &self, addr: u64, adjust_type: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: Into>, { @@ -562,7 +562,7 @@ impl Function { unsafe { BNSetAutoCallTypeAdjustment( self.handle, - arch.0, + arch.as_ptr(), addr, &mut BNTypeWithConfidence { type_: adjust_type.contents.handle, @@ -575,21 +575,21 @@ impl Function { pub fn call_reg_stack_adjustment( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array> { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let adjust = - unsafe { BNGetCallRegisterStackAdjustment(self.handle, arch.0, addr, &mut count) }; + unsafe { BNGetCallRegisterStackAdjustment(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!adjust.is_null()); - unsafe { Array::new(adjust, count, arch.handle()) } + unsafe { Array::new(adjust, count, arch) } } pub fn set_user_call_reg_stack_adjustment( self, addr: u64, adjust: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: IntoIterator>, { @@ -599,7 +599,7 @@ impl Function { unsafe { BNSetUserCallRegisterStackAdjustment( self.handle, - arch.0, + arch.as_ptr(), addr, adjust_buf.as_mut_ptr(), adjust_buf.len(), @@ -611,7 +611,7 @@ impl Function { &self, addr: u64, adjust: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: IntoIterator>, { @@ -622,7 +622,7 @@ impl Function { unsafe { BNSetAutoCallRegisterStackAdjustment( self.handle, - arch.0, + arch.as_ptr(), addr, adjust_buf.as_mut_ptr(), adjust_buf.len(), @@ -634,13 +634,13 @@ impl Function { &self, addr: u64, reg_stack_id: u32, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> RegisterStackAdjustment { let arch = arch.unwrap_or_else(|| self.arch()); let adjust = unsafe { BNGetCallRegisterStackAdjustmentForRegisterStack( self.handle, - arch.0, + arch.as_ptr(), addr, reg_stack_id, ) @@ -653,7 +653,7 @@ impl Function { addr: u64, reg_stack_id: u32, adjust: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: Into>, { @@ -662,7 +662,7 @@ impl Function { unsafe { BNSetUserCallRegisterStackAdjustmentForRegisterStack( self.handle, - arch.0, + arch.as_ptr(), addr, reg_stack_id, adjust.contents, @@ -676,7 +676,7 @@ impl Function { addr: u64, reg_stack_id: u32, adjust: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: Into>, { @@ -685,7 +685,7 @@ impl Function { unsafe { BNSetAutoCallRegisterStackAdjustmentForRegisterStack( self.handle, - arch.0, + arch.as_ptr(), addr, reg_stack_id, adjust.contents, @@ -698,7 +698,7 @@ impl Function { let mut count = 0; let adjust = unsafe { BNGetFunctionRegisterStackAdjustments(self.handle, &mut count) }; assert!(!adjust.is_null()); - unsafe { Array::new(adjust, count, self.arch().handle()) } + unsafe { Array::new(adjust, count, self.arch()) } } pub fn set_user_reg_stack_adjustments(&self, values: I) @@ -803,12 +803,12 @@ impl Function { addr: u64, func_type: Option<&Type>, i: usize, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> RegisterValue { let arch = arch.unwrap_or_else(|| self.arch()); let func_type = func_type.map(|f| f.handle).unwrap_or(core::ptr::null_mut()); let value = - unsafe { BNGetParameterValueAtInstruction(self.handle, arch.0, addr, func_type, i) }; + unsafe { BNGetParameterValueAtInstruction(self.handle, arch.as_ptr(), addr, func_type, i) }; value.into() } @@ -956,7 +956,7 @@ impl Function { data: S, addr: Option, user: bool, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); @@ -968,9 +968,9 @@ impl Function { unsafe { match (user, addr) { (false, None) => BNAddAutoFunctionTag(self.handle, tag.handle), - (false, Some(addr)) => BNAddAutoAddressTag(self.handle, arch.0, addr, tag.handle), + (false, Some(addr)) => BNAddAutoAddressTag(self.handle, arch.as_ptr(), addr, tag.handle), (true, None) => BNAddUserFunctionTag(self.handle, tag.handle), - (true, Some(addr)) => BNAddUserAddressTag(self.handle, arch.0, addr, tag.handle), + (true, Some(addr)) => BNAddUserAddressTag(self.handle, arch.as_ptr(), addr, tag.handle), } } } @@ -985,17 +985,17 @@ impl Function { tag: &Tag, addr: Option, user: bool, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); unsafe { match (user, addr) { (false, None) => BNRemoveAutoFunctionTag(self.handle, tag.handle), (false, Some(addr)) => { - BNRemoveAutoAddressTag(self.handle, arch.0, addr, tag.handle) + BNRemoveAutoAddressTag(self.handle, arch.as_ptr(), addr, tag.handle) } (true, None) => BNRemoveUserFunctionTag(self.handle, tag.handle), - (true, Some(addr)) => BNRemoveUserAddressTag(self.handle, arch.0, addr, tag.handle), + (true, Some(addr)) => BNRemoveUserAddressTag(self.handle, arch.as_ptr(), addr, tag.handle), } } } @@ -1011,18 +1011,18 @@ impl Function { tag_type: &TagType, addr: Option, user: bool, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); unsafe { match (user, addr) { (false, None) => BNRemoveAutoFunctionTagsOfType(self.handle, tag_type.handle), (false, Some(addr)) => { - BNRemoveAutoAddressTagsOfType(self.handle, arch.0, addr, tag_type.handle) + BNRemoveAutoAddressTagsOfType(self.handle, arch.as_ptr(), addr, tag_type.handle) } (true, None) => BNRemoveUserFunctionTagsOfType(self.handle, tag_type.handle), (true, Some(addr)) => { - BNRemoveUserAddressTagsOfType(self.handle, arch.0, addr, tag_type.handle) + BNRemoveUserAddressTagsOfType(self.handle, arch.as_ptr(), addr, tag_type.handle) } } } @@ -1044,9 +1044,9 @@ impl Function { /// # let fun: Function = todo!(); /// fun.add_user_code_ref(0x1337, 0x400000, None); /// ``` - pub fn add_user_code_ref(&self, from_addr: u64, to_addr: u64, arch: Option) { + pub fn add_user_code_ref(&self, from_addr: u64, to_addr: u64, arch: Option<&'static CoreArchitecture>) { let arch = arch.unwrap_or_else(|| self.arch()); - unsafe { BNAddUserCodeReference(self.handle, arch.0, from_addr, to_addr) } + unsafe { BNAddUserCodeReference(self.handle, arch.as_ptr(), from_addr, to_addr) } } /// Removes a user-defined cross-reference. @@ -1068,10 +1068,10 @@ impl Function { self, from_addr: u64, to_addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); - unsafe { BNRemoveUserCodeReference(self.handle, arch.0, from_addr, to_addr) } + unsafe { BNRemoveUserCodeReference(self.handle, arch.as_ptr(), from_addr, to_addr) } } /// Places a user-defined type cross-reference from the instruction at @@ -1093,11 +1093,11 @@ impl Function { &self, from_addr: u64, name: &QualifiedName, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); let name_ptr = &name.0 as *const BNQualifiedName as *mut _; - unsafe { BNAddUserTypeReference(self.handle, arch.0, from_addr, name_ptr) } + unsafe { BNAddUserTypeReference(self.handle, arch.as_ptr(), from_addr, name_ptr) } } /// Removes a user-defined type cross-reference. @@ -1118,11 +1118,11 @@ impl Function { &self, from_addr: u64, name: &QualifiedName, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); let name_ptr = &name.0 as *const BNQualifiedName as *mut _; - unsafe { BNRemoveUserTypeReference(self.handle, arch.0, from_addr, name_ptr) } + unsafe { BNRemoveUserTypeReference(self.handle, arch.as_ptr(), from_addr, name_ptr) } } /// Places a user-defined type field cross-reference from the @@ -1147,14 +1147,14 @@ impl Function { from_addr: u64, name: &QualifiedName, offset: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, size: Option, ) { let size = size.unwrap_or(0); let arch = arch.unwrap_or_else(|| self.arch()); let name_ptr = &name.0 as *const _ as *mut _; unsafe { - BNAddUserTypeFieldReference(self.handle, arch.0, from_addr, name_ptr, offset, size) + BNAddUserTypeFieldReference(self.handle, arch.as_ptr(), from_addr, name_ptr, offset, size) } } @@ -1179,14 +1179,14 @@ impl Function { from_addr: u64, name: &QualifiedName, offset: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, size: Option, ) { let size = size.unwrap_or(0); let arch = arch.unwrap_or_else(|| self.arch()); let name_ptr = &name.0 as *const _ as *mut _; unsafe { - BNRemoveUserTypeFieldReference(self.handle, arch.0, from_addr, name_ptr, offset, size) + BNRemoveUserTypeFieldReference(self.handle, arch.as_ptr(), from_addr, name_ptr, offset, size) } } @@ -1204,12 +1204,12 @@ impl Function { pub fn constants_referenced_by( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let refs = - unsafe { BNGetConstantsReferencedByInstruction(self.handle, arch.0, addr, &mut count) }; + unsafe { BNGetConstantsReferencedByInstruction(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!refs.is_null()); unsafe { Array::new(refs, count, ()) } } @@ -1217,12 +1217,12 @@ impl Function { pub fn constants_referenced_by_address_if_available( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let refs = unsafe { - BNGetConstantsReferencedByInstructionIfAvailable(self.handle, arch.0, addr, &mut count) + BNGetConstantsReferencedByInstructionIfAvailable(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!refs.is_null()); unsafe { Array::new(refs, count, ()) } @@ -1277,15 +1277,15 @@ impl Function { &self, addr: u64, auto: Option, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let tags = match auto { - None => unsafe { BNGetAddressTags(self.handle, arch.0, addr, &mut count) }, - Some(true) => unsafe { BNGetAutoAddressTags(self.handle, arch.0, addr, &mut count) }, - Some(false) => unsafe { BNGetUserAddressTags(self.handle, arch.0, addr, &mut count) }, + None => unsafe { BNGetAddressTags(self.handle, arch.as_ptr(), addr, &mut count) }, + Some(true) => unsafe { BNGetAutoAddressTags(self.handle, arch.as_ptr(), addr, &mut count) }, + Some(false) => unsafe { BNGetUserAddressTags(self.handle, arch.as_ptr(), addr, &mut count) }, }; assert!(!tags.is_null()); unsafe { Array::new(tags, count, ()) } @@ -1299,20 +1299,20 @@ impl Function { &self, range: Range, auto: Option, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let tags = match auto { None => unsafe { - BNGetAddressTagsInRange(self.handle, arch.0, range.start, range.end, &mut count) + BNGetAddressTagsInRange(self.handle, arch.as_ptr(), range.start, range.end, &mut count) }, Some(true) => unsafe { - BNGetAutoAddressTagsInRange(self.handle, arch.0, range.start, range.end, &mut count) + BNGetAutoAddressTagsInRange(self.handle, arch.as_ptr(), range.start, range.end, &mut count) }, Some(false) => unsafe { - BNGetUserAddressTagsInRange(self.handle, arch.0, range.start, range.end, &mut count) + BNGetUserAddressTagsInRange(self.handle, arch.as_ptr(), range.start, range.end, &mut count) }, }; assert!(!tags.is_null()); @@ -1331,7 +1331,7 @@ impl Function { &self, source: u64, branches: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: IntoIterator, { @@ -1340,13 +1340,13 @@ impl Function { .into_iter() .map(|address| BNArchitectureAndAddress { address, - arch: arch.0, + arch: arch.as_ptr(), }) .collect(); unsafe { BNSetUserIndirectBranches( self.handle, - arch.0, + arch.as_ptr(), source, branches.as_mut_ptr(), branches.len(), @@ -1358,7 +1358,7 @@ impl Function { &self, source: u64, branches: I, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) where I: IntoIterator, { @@ -1367,13 +1367,13 @@ impl Function { .into_iter() .map(|address| BNArchitectureAndAddress { address, - arch: arch.0, + arch: arch.as_ptr(), }) .collect(); unsafe { BNSetAutoIndirectBranches( self.handle, - arch.0, + arch.as_ptr(), source, branches.as_mut_ptr(), branches.len(), @@ -1385,11 +1385,11 @@ impl Function { pub fn indirect_branches_at( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; - let branches = unsafe { BNGetIndirectBranchesAt(self.handle, arch.0, addr, &mut count) }; + let branches = unsafe { BNGetIndirectBranchesAt(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!branches.is_null()); unsafe { Array::new(branches, count, ()) } } @@ -1399,9 +1399,9 @@ impl Function { /// # let fun: binaryninja::function::Function = todo!(); /// let color = fun.instr_highlight(0x1337, None); /// ``` - pub fn instr_highlight(&self, addr: u64, arch: Option) -> HighlightColor { + pub fn instr_highlight(&self, addr: u64, arch: Option<&'static CoreArchitecture>) -> HighlightColor { let arch = arch.unwrap_or_else(|| self.arch()); - let color = unsafe { BNGetInstructionHighlight(self.handle, arch.0, addr) }; + let color = unsafe { BNGetInstructionHighlight(self.handle, arch.as_ptr(), addr) }; HighlightColor::from_raw(color) } @@ -1416,11 +1416,11 @@ impl Function { &self, addr: u64, color: HighlightColor, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); let color_raw = color.into_raw(); - unsafe { BNSetAutoInstructionHighlight(self.handle, arch.0, addr, color_raw) } + unsafe { BNSetAutoInstructionHighlight(self.handle, arch.as_ptr(), addr, color_raw) } } /// Sets the highlights the instruction at the specified address with the supplied color @@ -1440,11 +1440,11 @@ impl Function { &self, addr: u64, color: HighlightColor, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) { let arch = arch.unwrap_or_else(|| self.arch()); let color_raw = color.into_raw(); - unsafe { BNSetUserInstructionHighlight(self.handle, arch.0, addr, color_raw) } + unsafe { BNSetUserInstructionHighlight(self.handle, arch.as_ptr(), addr, color_raw) } } /// return the address, if any, of the instruction that contains the @@ -1452,11 +1452,11 @@ impl Function { pub fn instruction_containing_address( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Option { let arch = arch.unwrap_or_else(|| self.arch()); let mut start = 0; - unsafe { BNGetInstructionContainingAddress(self.handle, arch.0, addr, &mut start) } + unsafe { BNGetInstructionContainingAddress(self.handle, arch.as_ptr(), addr, &mut start) } .then_some(start) } @@ -1473,10 +1473,10 @@ impl Function { instr_addr: u64, value: u64, operand: usize, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> IntegerDisplayType { let arch = arch.unwrap_or_else(|| self.arch()); - unsafe { BNGetIntegerConstantDisplayType(self.handle, arch.0, instr_addr, value, operand) } + unsafe { BNGetIntegerConstantDisplayType(self.handle, arch.as_ptr(), instr_addr, value, operand) } } /// Change the text display type for an integer token in the disassembly or IL views @@ -1493,7 +1493,7 @@ impl Function { value: u64, operand: usize, display_type: IntegerDisplayType, - arch: Option, + arch: Option<&'static CoreArchitecture>, enum_display_typeid: Option, ) { let arch = arch.unwrap_or_else(|| self.arch()); @@ -1504,7 +1504,7 @@ impl Function { unsafe { BNSetIntegerConstantDisplayType( self.handle, - arch.0, + arch.as_ptr(), instr_addr, value, operand, @@ -1527,13 +1527,13 @@ impl Function { instr_addr: u64, value: u64, operand: usize, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> BnString { let arch = arch.unwrap_or_else(|| self.arch()); unsafe { BnString::from_raw(BNGetIntegerConstantDisplayTypeEnumerationType( self.handle, - arch.0, + arch.as_ptr(), instr_addr, value, operand, @@ -1552,7 +1552,7 @@ impl Function { instr_addr: u64, value: u64, operand: usize, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> (IntegerDisplayType, BnString) { let arch = arch.unwrap_or_else(|| self.arch()); let name = self.int_enum_display_typeid(instr_addr, value, operand, Some(arch)); @@ -1577,10 +1577,10 @@ impl Function { &self, addr: u64, reg: u32, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> RegisterValue { let arch = arch.unwrap_or_else(|| self.arch()); - let register = unsafe { BNGetRegisterValueAtInstruction(self.handle, arch.0, addr, reg) }; + let register = unsafe { BNGetRegisterValueAtInstruction(self.handle, arch.as_ptr(), addr, reg) }; register.into() } @@ -1601,11 +1601,11 @@ impl Function { &self, addr: u64, reg: u32, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> RegisterValue { let arch = arch.unwrap_or_else(|| self.arch()); let register = - unsafe { BNGetRegisterValueAfterInstruction(self.handle, arch.0, addr, reg) }; + unsafe { BNGetRegisterValueAfterInstruction(self.handle, arch.as_ptr(), addr, reg) }; register.into() } @@ -1617,12 +1617,12 @@ impl Function { pub fn registers_read_by( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let regs = - unsafe { BNGetRegistersReadByInstruction(self.handle, arch.0, addr, &mut count) }; + unsafe { BNGetRegistersReadByInstruction(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!regs.is_null()); unsafe { Array::new(regs, count, arch) } } @@ -1630,12 +1630,12 @@ impl Function { pub fn registers_written_by( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let regs = - unsafe { BNGetRegistersWrittenByInstruction(self.handle, arch.0, addr, &mut count) }; + unsafe { BNGetRegistersWrittenByInstruction(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!regs.is_null()); unsafe { Array::new(regs, count, arch) } } @@ -1644,7 +1644,7 @@ impl Function { pub fn clobbered_registers(&self) -> Conf> { let result = unsafe { BNGetFunctionClobberedRegisters(self.handle) }; - let reg_set = unsafe { Array::new(result.regs, result.count, self.arch().handle()) }; + let reg_set = unsafe { Array::new(result.regs, result.count, self.arch()) }; Conf::new(reg_set, result.confidence) } @@ -1679,11 +1679,11 @@ impl Function { addr: u64, offset: i64, size: usize, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> RegisterValue { let arch = arch.unwrap_or_else(|| self.arch()); let value = - unsafe { BNGetStackContentsAtInstruction(self.handle, arch.0, addr, offset, size) }; + unsafe { BNGetStackContentsAtInstruction(self.handle, arch.as_ptr(), addr, offset, size) }; value.into() } @@ -1692,11 +1692,11 @@ impl Function { addr: u64, offset: i64, size: usize, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> RegisterValue { let arch = arch.unwrap_or_else(|| self.arch()); let value = - unsafe { BNGetStackContentsAfterInstruction(self.handle, arch.0, addr, offset, size) }; + unsafe { BNGetStackContentsAfterInstruction(self.handle, arch.as_ptr(), addr, offset, size) }; value.into() } @@ -1704,12 +1704,12 @@ impl Function { &self, addr: u64, offset: i64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Option<(Variable, BnString, Conf>)> { let arch = arch.unwrap_or_else(|| self.arch()); let mut found_value: BNVariableNameAndType = unsafe { mem::zeroed() }; let found = unsafe { - BNGetStackVariableAtFrameOffset(self.handle, arch.0, addr, offset, &mut found_value) + BNGetStackVariableAtFrameOffset(self.handle, arch.as_ptr(), addr, offset, &mut found_value) }; if !found { return None; @@ -1726,12 +1726,12 @@ impl Function { pub fn stack_variables_referenced_by( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let refs = unsafe { - BNGetStackVariablesReferencedByInstruction(self.handle, arch.0, addr, &mut count) + BNGetStackVariablesReferencedByInstruction(self.handle, arch.as_ptr(), addr, &mut count) }; assert!(!refs.is_null()); unsafe { Array::new(refs, count, ()) } @@ -1740,14 +1740,14 @@ impl Function { pub fn stack_variables_referenced_by_address_if_available( &self, addr: u64, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let arch = arch.unwrap_or_else(|| self.arch()); let mut count = 0; let refs = unsafe { BNGetStackVariablesReferencedByInstructionIfAvailable( self.handle, - arch.0, + arch.as_ptr(), addr, &mut count, ) @@ -1773,9 +1773,9 @@ impl Function { unsafe { Array::new(lines, count, ()) } } - pub fn is_call_instruction(&self, addr: u64, arch: Option) -> bool { + pub fn is_call_instruction(&self, addr: u64, arch: Option<&'static CoreArchitecture>) -> bool { let arch = arch.unwrap_or_else(|| self.arch()); - unsafe { BNIsCallInstruction(self.handle, arch.0, addr) } + unsafe { BNIsCallInstruction(self.handle, arch.as_ptr(), addr) } } pub fn is_variable_user_defined(&self, var: &Variable) -> bool { @@ -2093,7 +2093,7 @@ impl Function { /// Get registers that are used for the return value pub fn return_registers(&self) -> Conf> { let result = unsafe { BNGetFunctionReturnRegisters(self.handle) }; - let regs = unsafe { Array::new(result.regs, result.count, self.arch().handle()) }; + let regs = unsafe { Array::new(result.regs, result.count, self.arch()) }; Conf::new(regs, result.confidence) } @@ -2202,7 +2202,7 @@ impl PartialEq for Function { return true; } self.start() == other.start() - && self.arch() == other.arch() + && self.arch().as_ptr() as usize == other.arch().as_ptr() as usize && self.platform() == other.platform() } } diff --git a/rust/src/functionrecognizer.rs b/rust/src/functionrecognizer.rs index c63edcab0..90f86d2df 100644 --- a/rust/src/functionrecognizer.rs +++ b/rust/src/functionrecognizer.rs @@ -1,4 +1,3 @@ -use crate::architecture::Architecture; use crate::{ architecture::CoreArchitecture, binaryview::BinaryView, function::Function, llil, mlil, }; @@ -99,9 +98,6 @@ where { let mut recognizer = create_function_recognizer_registration::(recognizer); unsafe { - BNRegisterArchitectureFunctionRecognizer( - arch.handle().as_ref().0, - &mut recognizer as *mut _, - ); + BNRegisterArchitectureFunctionRecognizer(arch.as_ptr(), &mut recognizer as *mut _); } } diff --git a/rust/src/hlil/instruction.rs b/rust/src/hlil/instruction.rs index 6b27284d4..1ec30a8a6 100644 --- a/rust/src/hlil/instruction.rs +++ b/rust/src/hlil/instruction.rs @@ -811,11 +811,11 @@ impl HighLevelILInstruction { cond_false: self.lift_operand(op.cond_false), }), Intrinsic(op) => Lifted::Intrinsic(LiftedIntrinsic { - intrinsic: CoreIntrinsic(self.function.get_function().arch().0, op.intrinsic), + intrinsic: CoreIntrinsic(self.function.get_function().arch(), op.intrinsic), params: self.lift_instruction_list(op.first_param, op.num_params), }), IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa { - intrinsic: CoreIntrinsic(self.function.get_function().arch().0, op.intrinsic), + intrinsic: CoreIntrinsic(self.function.get_function().arch(), op.intrinsic), params: self.lift_instruction_list(op.first_param, op.num_params), dest_memory: op.dest_memory, src_memory: op.src_memory, diff --git a/rust/src/llil/function.rs b/rust/src/llil/function.rs index 8f1eac62d..33e1588aa 100644 --- a/rust/src/llil/function.rs +++ b/rust/src/llil/function.rs @@ -17,7 +17,6 @@ use binaryninjacore_sys::BNGetLowLevelILOwnerFunction; use binaryninjacore_sys::BNLowLevelILFunction; use binaryninjacore_sys::BNNewLowLevelILFunctionReference; -use std::borrow::Borrow; use std::marker::PhantomData; use crate::architecture::CoreArchitecture; @@ -54,9 +53,8 @@ impl FunctionForm for SSA {} impl FunctionForm for NonSSA {} pub struct Function { - pub(crate) borrower: A::Handle, + pub(crate) borrower: &'static A, pub(crate) handle: *mut BNLowLevelILFunction, - _arch: PhantomData<*mut A>, _mutability: PhantomData, _form: PhantomData, } @@ -85,7 +83,7 @@ where F: FunctionForm, { pub(crate) unsafe fn from_raw( - borrower: A::Handle, + borrower: &'static A, handle: *mut BNLowLevelILFunction, ) -> Ref { debug_assert!(!handle.is_null()); @@ -93,15 +91,14 @@ where Self { borrower, handle, - _arch: PhantomData, _mutability: PhantomData, _form: PhantomData, } .to_owned() } - pub(crate) fn arch(&self) -> &A { - self.borrower.borrow() + pub(crate) fn arch(&self) -> &'static A { + self.borrower } pub fn instruction_at>(&self, loc: L) -> Option> { @@ -109,10 +106,11 @@ where use binaryninjacore_sys::BNLowLevelILGetInstructionStart; let loc: Location = loc.into(); - let arch_handle = loc.arch.unwrap_or_else(|| *self.arch().as_ref()); + let arch_handle = loc.arch.unwrap_or_else(|| self.arch().core()); unsafe { - let instr_idx = BNLowLevelILGetInstructionStart(self.handle, arch_handle.0, loc.addr); + let instr_idx = + BNLowLevelILGetInstructionStart(self.handle, arch_handle.as_ptr(), loc.addr); if instr_idx >= BNGetLowLevelILInstructionCount(self.handle) { None @@ -178,7 +176,7 @@ where // Allow instantiating Lifted IL functions for querying Lifted IL from Architectures impl Function> { pub fn new( - arch: CoreArchitecture, + arch: &'static CoreArchitecture, source_func: Option, ) -> Result, ()> { use binaryninjacore_sys::BNCreateLowLevelILFunction; @@ -186,8 +184,8 @@ impl Function> { let handle = unsafe { match source_func { - Some(func) => BNCreateLowLevelILFunction(arch.0, func.handle), - None => BNCreateLowLevelILFunction(arch.0, null_mut()), + Some(func) => BNCreateLowLevelILFunction(arch.core().as_ptr(), func.handle), + None => BNCreateLowLevelILFunction(arch.core().as_ptr(), null_mut()), } }; if handle.is_null() { @@ -198,7 +196,6 @@ impl Function> { Ref::new(Self { borrower: arch, handle, - _arch: PhantomData, _mutability: PhantomData, _form: PhantomData, }) @@ -227,9 +224,8 @@ where { unsafe fn inc_ref(handle: &Self) -> Ref { Ref::new(Self { - borrower: handle.borrower.clone(), + borrower: handle.borrower, handle: BNNewLowLevelILFunctionReference(handle.handle), - _arch: PhantomData, _mutability: PhantomData, _form: PhantomData, }) diff --git a/rust/src/llil/lifting.rs b/rust/src/llil/lifting.rs index daf95ac3f..30160e23f 100644 --- a/rust/src/llil/lifting.rs +++ b/rust/src/llil/lifting.rs @@ -375,7 +375,7 @@ where let expr_idx = unsafe { use binaryninjacore_sys::BNGetDefaultArchitectureFlagWriteLowLevelIL; BNGetDefaultArchitectureFlagWriteLowLevelIL( - arch.as_ref().0, + arch.core().as_ptr(), operation, size, role, @@ -399,12 +399,12 @@ where { use binaryninjacore_sys::BNGetDefaultArchitectureFlagConditionLowLevelIL; - let handle = arch.as_ref(); + let handle = arch.core().as_ptr(); let class_id = class.map(|c| c.id()).unwrap_or(0); unsafe { let expr_idx = - BNGetDefaultArchitectureFlagConditionLowLevelIL(handle.0, cond, class_id, il.handle); + BNGetDefaultArchitectureFlagConditionLowLevelIL(handle, cond, class_id, il.handle); Expression::new(il, expr_idx) } @@ -1380,10 +1380,10 @@ where use binaryninjacore_sys::BNLowLevelILSetCurrentAddress; let loc: Location = loc.into(); - let arch = loc.arch.unwrap_or_else(|| *self.arch().as_ref()); + let arch = loc.arch.unwrap_or_else(|| self.arch().core()); unsafe { - BNLowLevelILSetCurrentAddress(self.handle, arch.0, loc.addr); + BNLowLevelILSetCurrentAddress(self.handle, arch.as_ptr(), loc.addr); } } @@ -1391,9 +1391,9 @@ where use binaryninjacore_sys::BNGetLowLevelILLabelForAddress; let loc: Location = loc.into(); - let arch = loc.arch.unwrap_or_else(|| *self.arch().as_ref()); + let arch = loc.arch.unwrap_or_else(|| self.arch().core()); - let res = unsafe { BNGetLowLevelILLabelForAddress(self.handle, arch.0, loc.addr) }; + let res = unsafe { BNGetLowLevelILLabelForAddress(self.handle, arch.as_ptr(), loc.addr) }; if res.is_null() { None diff --git a/rust/src/mlil/function.rs b/rust/src/mlil/function.rs index 928f1b6aa..84f314e25 100644 --- a/rust/src/mlil/function.rs +++ b/rust/src/mlil/function.rs @@ -3,7 +3,7 @@ use std::ffi::c_char; use binaryninjacore_sys::*; -use crate::architecture::CoreArchitecture; +use crate::architecture::{Architecture, CoreArchitecture}; use crate::basicblock::BasicBlock; use crate::disassembly::DisassemblySettings; use crate::flowgraph::FlowGraph; @@ -47,8 +47,9 @@ impl MediumLevelILFunction { let loc: Location = loc.into(); let arch_handle = loc.arch.unwrap(); - let expr_idx = - unsafe { BNMediumLevelILGetInstructionStart(self.handle, arch_handle.0, loc.addr) }; + let expr_idx = unsafe { + BNMediumLevelILGetInstructionStart(self.handle, arch_handle.core().as_ptr(), loc.addr) + }; if expr_idx >= self.instruction_count() { None @@ -208,7 +209,7 @@ impl MediumLevelILFunction { }; let function = self.get_function(); let def_site = BNArchitectureAndAddress { - arch: function.arch().0, + arch: function.arch().as_ptr(), address: addr, }; let value = value.into_raw(); @@ -232,7 +233,7 @@ impl MediumLevelILFunction { let function = self.get_function(); let def_site = BNArchitectureAndAddress { - arch: function.arch().0, + arch: function.arch().as_ptr(), address: addr, }; @@ -351,7 +352,7 @@ impl MediumLevelILFunction { &self, addr: u64, length: Option, - arch: Option, + arch: Option<&'static CoreArchitecture>, ) -> Array { let function = self.get_function(); let arch = arch.unwrap_or_else(|| function.arch()); @@ -361,7 +362,7 @@ impl MediumLevelILFunction { unsafe { BNGetMediumLevelILVariableReferencesInRange( function.handle, - arch.0, + arch.as_ptr(), addr, length, &mut count, @@ -369,7 +370,12 @@ impl MediumLevelILFunction { } } else { unsafe { - BNGetMediumLevelILVariableReferencesFrom(function.handle, arch.0, addr, &mut count) + BNGetMediumLevelILVariableReferencesFrom( + function.handle, + arch.as_ptr(), + addr, + &mut count, + ) } }; assert!(!refs.is_null()); @@ -382,11 +388,9 @@ impl MediumLevelILFunction { } /// Set the current IL Address - pub fn set_current_address(&self, value: u64, arch: Option) { - let arch = arch - .map(|x| x.0) - .unwrap_or_else(|| self.get_function().arch().0); - unsafe { BNMediumLevelILSetCurrentAddress(self.handle, arch, value) } + pub fn set_current_address(&self, value: u64, arch: Option<&'static CoreArchitecture>) { + let arch = arch.unwrap_or_else(|| self.get_function().arch()); + unsafe { BNMediumLevelILSetCurrentAddress(self.handle, arch.as_ptr(), value) } } /// Returns the BasicBlock at the given MLIL `instruction`. @@ -649,7 +653,7 @@ pub type FunctionGraphType = binaryninjacore_sys::BNFunctionGraphType; pub struct ILReferenceSource { mlil: Ref, _func: Ref, - _arch: CoreArchitecture, + _arch: &'static CoreArchitecture, addr: u64, type_: FunctionGraphType, expr_id: usize, diff --git a/rust/src/mlil/instruction.rs b/rust/src/mlil/instruction.rs index 88564cc61..a75c64ec7 100644 --- a/rust/src/mlil/instruction.rs +++ b/rust/src/mlil/instruction.rs @@ -906,7 +906,7 @@ impl MediumLevelILInstruction { output: OperandIter::new(&*self.function, op.first_output, op.num_outputs) .vars() .collect(), - intrinsic: CoreIntrinsic(self.function.get_function().arch().0, op.intrinsic), + intrinsic: CoreIntrinsic(self.function.get_function().arch(), op.intrinsic), params: OperandIter::new(&*self.function, op.first_param, op.num_params) .exprs() .map(|expr| expr.lift()) @@ -925,7 +925,7 @@ impl MediumLevelILInstruction { output: OperandIter::new(&*self.function, op.first_output, op.num_outputs) .ssa_vars() .collect(), - intrinsic: CoreIntrinsic(self.function.get_function().arch().0, op.intrinsic), + intrinsic: CoreIntrinsic(self.function.get_function().arch(), op.intrinsic), params: OperandIter::new(&*self.function, op.first_param, op.num_params) .exprs() .map(|expr| expr.lift()) @@ -1040,7 +1040,7 @@ impl MediumLevelILInstruction { assert!(unsafe { BNGetMediumLevelILExprText( self.function.handle, - self.function.get_function().arch().0, + self.function.get_function().arch().as_ptr(), self.index, &mut tokens, &mut count, diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 11f76284b..33395b13e 100644 --- a/rust/src/platform.rs +++ b/rust/src/platform.rs @@ -14,7 +14,7 @@ //! Contains all information related to the execution environment of the binary, mainly the calling conventions used -use std::{borrow::Borrow, collections::HashMap, os::raw, path::Path, ptr, slice}; +use std::{collections::HashMap, os::raw, path::Path, ptr, slice}; use binaryninjacore_sys::*; @@ -54,7 +54,7 @@ macro_rules! cc_func { let arch = self.arch(); assert!( - cc.arch_handle.borrow().as_ref().0 == arch.0, + cc.arch_handle.core().as_ptr() as usize == arch.core().as_ptr() as usize, "use of calling convention with non-matching Platform architecture!" ); @@ -97,7 +97,7 @@ impl Platform { pub fn list_by_arch(arch: &CoreArchitecture) -> Array { unsafe { let mut count = 0; - let handles = BNGetPlatformListByArchitecture(arch.0, &mut count); + let handles = BNGetPlatformListByArchitecture(arch.core().as_ptr(), &mut count); Array::new(handles, count, ()) } @@ -124,7 +124,7 @@ impl Platform { let mut count = 0; let handles = BNGetPlatformListByOSAndArchitecture( raw_name.as_ref().as_ptr() as *mut _, - arch.0, + arch.core().as_ptr(), &mut count, ); @@ -144,7 +144,7 @@ impl Platform { pub fn new(arch: &A, name: S) -> Ref { let name = name.into_bytes_with_nul(); unsafe { - let handle = BNCreatePlatform(arch.as_ref().0, name.as_ref().as_ptr() as *mut _); + let handle = BNCreatePlatform(arch.core().as_ptr(), name.as_ref().as_ptr() as *mut _); assert!(!handle.is_null()); @@ -159,7 +159,7 @@ impl Platform { } } - pub fn arch(&self) -> CoreArchitecture { + pub fn arch(&self) -> &'static CoreArchitecture { unsafe { CoreArchitecture::from_raw(BNGetPlatformArchitecture(self.handle)) } } diff --git a/rust/src/references.rs b/rust/src/references.rs index d12c33c55..cd4728b07 100644 --- a/rust/src/references.rs +++ b/rust/src/references.rs @@ -11,7 +11,7 @@ use std::mem::ManuallyDrop; /// the enclosing array object. #[derive(Debug)] pub struct CodeReference { - arch: CoreArchitecture, + arch: &'static CoreArchitecture, func: ManuallyDrop>, pub address: u64, } @@ -46,7 +46,7 @@ impl<'a> CodeReference { /// A handle to the [CodeReference]'s [CoreArchitecture]. This type is [Copy] so reference /// shenanigans are not needed here. - pub fn architecture(&self) -> CoreArchitecture { + pub fn architecture(&self) -> &'static CoreArchitecture { self.arch } } diff --git a/rust/src/relocation.rs b/rust/src/relocation.rs index f9ece0435..662e932eb 100644 --- a/rust/src/relocation.rs +++ b/rust/src/relocation.rs @@ -1,7 +1,8 @@ use crate::rc::Guard; +use crate::architecture::Architecture; use crate::string::BnStrCompatible; use crate::{ - architecture::{Architecture, CoreArchitecture}, + architecture::CoreArchitecture, binaryview::BinaryView, llil, rc::{CoreArrayProvider, CoreArrayProviderInner, Ref, RefCountable}, @@ -191,7 +192,7 @@ impl Relocation { RelocationInfo::from_raw(unsafe { &BNRelocationGetInfo(self.0) }) } - pub fn architecture(&self) -> Option { + pub fn architecture(&self) -> Option<&'static CoreArchitecture> { let raw = unsafe { BNRelocationGetArchitecture(self.0) }; if raw.is_null() { return None; @@ -280,7 +281,7 @@ pub trait RelocationHandlerExt: RelocationHandler { BNRelocationHandlerDefaultApplyRelocation( self.as_ref().0, bv.handle, - arch.handle().as_ref().0, + arch.core().as_ptr(), reloc.0, dest.as_mut_ptr(), dest.len(), @@ -323,7 +324,7 @@ impl RelocationHandler for CoreRelocationHandler { BNRelocationHandlerGetRelocationInfo( self.0, bv.handle, - arch.handle().as_ref().0, + arch.core().as_ptr(), raw_info.as_mut_ptr(), raw_info.len(), ) @@ -345,7 +346,7 @@ impl RelocationHandler for CoreRelocationHandler { BNRelocationHandlerApplyRelocation( self.0, bv.handle, - arch.handle().as_ref().0, + arch.core().as_ptr(), reloc.0, dest.as_mut_ptr(), dest.len(), @@ -521,7 +522,7 @@ where }); BNArchitectureRegisterRelocationHandler( - arch.handle().as_ref().0, + arch.core().as_ptr(), name.as_ref().as_ptr() as *const _, handle.handle().as_ref().0, ); diff --git a/rust/src/tags.rs b/rust/src/tags.rs index 912ee81b1..fdd0bdde6 100644 --- a/rust/src/tags.rs +++ b/rust/src/tags.rs @@ -200,7 +200,7 @@ pub struct TagReference { ref_type: TagReferenceType, auto_defined: bool, tag: Ref, - arch: CoreArchitecture, + arch: &'static CoreArchitecture, func: Ref, addr: u64, } @@ -225,7 +225,7 @@ impl TagReference { pub fn tag(&self) -> &Tag { &self.tag } - pub fn arch(&self) -> CoreArchitecture { + pub fn arch(&self) -> &'static CoreArchitecture { self.arch } pub fn functions(&self) -> &Function { diff --git a/rust/src/types.rs b/rust/src/types.rs index 29cdb2d3d..c9b5b35e8 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -611,7 +611,7 @@ impl TypeBuilder { unsafe { Self::from_raw(BNCreatePointerTypeBuilder( - arch.as_ref().0, + arch.core().as_ptr(), &t.into().into(), &mut is_const, &mut is_volatile, @@ -626,7 +626,7 @@ impl TypeBuilder { unsafe { Self::from_raw(BNCreatePointerTypeBuilder( - arch.as_ref().0, + arch.core().as_ptr(), &t.into().into(), &mut is_const, &mut is_volatile, @@ -667,7 +667,7 @@ impl TypeBuilder { let mut is_volatile = Conf::new(is_volatile, max_confidence()).into(); unsafe { Self::from_raw(BNCreatePointerTypeBuilder( - arch.as_ref().0, + arch.core().as_ptr(), &t.into().into(), &mut is_const, &mut is_volatile, @@ -1131,7 +1131,7 @@ impl Type { let mut is_volatile = Conf::new(false, min_confidence()).into(); unsafe { Self::ref_from_raw(BNCreatePointerType( - arch.as_ref().0, + arch.core().as_ptr(), &t.into().into(), &mut is_const, &mut is_volatile, @@ -1148,7 +1148,7 @@ impl Type { let mut is_volatile = Conf::new(false, min_confidence()).into(); unsafe { Self::ref_from_raw(BNCreatePointerType( - arch.as_ref().0, + arch.core().as_ptr(), &t.into().into(), &mut is_const, &mut is_volatile, @@ -1188,7 +1188,7 @@ impl Type { let mut is_volatile = Conf::new(is_volatile, max_confidence()).into(); unsafe { Self::ref_from_raw(BNCreatePointerType( - arch.as_ref().0, + arch.core().as_ptr(), &t.into().into(), &mut is_const, &mut is_volatile, @@ -2753,6 +2753,36 @@ impl DataVariableAndName { } } +///////////////////////// +// ILIntrinsic + +#[derive(Clone, Copy, Debug)] +pub struct ILIntrinsic { + arch: &'static CoreArchitecture, + index: u32, +} + +impl PartialEq for ILIntrinsic { + fn eq(&self, other: &Self) -> bool { + self.arch.as_ptr() as usize == other.arch.as_ptr() as usize && self.index == other.index + } +} +impl Eq for ILIntrinsic {} + +impl ILIntrinsic { + pub(crate) fn new(arch: &'static CoreArchitecture, index: u32) -> Self { + Self { arch, index } + } + + pub fn name(&self) -> &str { + let name_ptr = unsafe { BNGetArchitectureIntrinsicName(self.arch.core().as_ptr(), self.index) }; + let name_raw = unsafe { core::ffi::CStr::from_ptr(name_ptr) }; + name_raw.to_str().unwrap() + } + + // TODO impl inputs and outputs function +} + ///////////////////////// // RegisterValueType @@ -3235,7 +3265,7 @@ impl Drop for LookupTableEntryRaw { #[derive(Copy, Clone, Eq, Hash, PartialEq)] pub struct ArchAndAddr { - pub arch: CoreArchitecture, + pub arch: &'static CoreArchitecture, pub address: u64, } @@ -3334,9 +3364,9 @@ unsafe impl CoreArrayProviderInner for ConstantReference { // IndirectBranchInfo pub struct IndirectBranchInfo { - pub source_arch: CoreArchitecture, + pub source_arch: &'static CoreArchitecture, pub source_addr: u64, - pub dest_arch: CoreArchitecture, + pub dest_arch: &'static CoreArchitecture, pub dest_addr: u64, pub auto_defined: bool, } @@ -3353,9 +3383,9 @@ impl IndirectBranchInfo { } pub fn into_raw(self) -> BNIndirectBranchInfo { BNIndirectBranchInfo { - sourceArch: self.source_arch.0, + sourceArch: self.source_arch.as_ptr(), sourceAddr: self.source_addr, - destArch: self.dest_arch.0, + destArch: self.dest_arch.as_ptr(), destAddr: self.dest_addr, autoDefined: self.auto_defined, } @@ -3606,11 +3636,11 @@ unsafe impl CoreArrayProviderInner for StackVariableReference { pub struct RegisterStackAdjustment { reg_id: u32, adjustment: Conf, - arch: A::Handle, + arch: &'static A, } impl RegisterStackAdjustment { - pub(crate) unsafe fn from_raw(value: BNRegisterStackAdjustment, arch: A::Handle) -> Self { + pub(crate) unsafe fn from_raw(value: BNRegisterStackAdjustment, arch: &'static A) -> Self { RegisterStackAdjustment { reg_id: value.regStack, adjustment: Conf::new(value.adjustment, value.confidence), @@ -3624,7 +3654,7 @@ impl RegisterStackAdjustment { confidence: self.adjustment.confidence, } } - pub fn new(reg_id: u32, adjustment: I, arch_handle: A::Handle) -> Self + pub fn new(reg_id: u32, adjustment: I, arch_handle: &'static A) -> Self where I: Into>, { @@ -3644,7 +3674,7 @@ impl RegisterStackAdjustment { impl CoreArrayProvider for RegisterStackAdjustment { type Raw = BNRegisterStackAdjustment; - type Context = A::Handle; + type Context = &'static A; type Wrapped<'a> = Self; } @@ -3653,7 +3683,7 @@ unsafe impl CoreArrayProviderInner for RegisterStackAdjustment< BNFreeRegisterStackAdjustments(raw) } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> { - Self::from_raw(*raw, context.clone()) + Self::from_raw(*raw, context) } }