From 3296f799f2ad228bbfa71575a93917fac1bb0759 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 | 34 +- rust/src/architecture.rs | 412 +++++++++++++----------- rust/src/basicblock.rs | 2 +- rust/src/binaryview.rs | 6 +- rust/src/callingconvention.rs | 57 ++-- rust/src/custombinaryview.rs | 9 +- rust/src/demangle.rs | 4 +- rust/src/function.rs | 17 +- rust/src/functionrecognizer.rs | 6 +- rust/src/llil/function.rs | 26 +- rust/src/llil/lifting.rs | 14 +- rust/src/mlil/function.rs | 6 +- rust/src/platform.rs | 12 +- rust/src/references.rs | 4 +- rust/src/relocation.rs | 13 +- rust/src/types.rs | 27 +- 18 files changed, 354 insertions(+), 336 deletions(-) diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs index 645bb45a2..3670aa00d 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 } } @@ -2869,22 +2866,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 cbc4f07a3..2c809c583 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 dc23f2ff1..17ffb9b16 100644 --- a/rust/examples/pdb-ng/src/type_parser.rs +++ b/rust/examples/pdb-ng/src/type_parser.rs @@ -673,31 +673,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)))), @@ -843,10 +843,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { Type::structure(builder.finalize().as_ref()), max_confidence(), ), - name: bitfield_name( - last_bitfield_offset, - last_bitfield_idx, - ), + name: bitfield_name(last_bitfield_offset, last_bitfield_idx), offset: last_bitfield_offset, access: MemberAccess::PublicAccess, scope: MemberScope::NoScope, @@ -880,10 +877,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> { Type::structure(builder.finalize().as_ref()), max_confidence(), ), - name: bitfield_name( - last_bitfield_offset, - last_bitfield_idx, - ), + name: bitfield_name(last_bitfield_offset, last_bitfield_idx), offset: last_bitfield_offset, access: MemberAccess::PublicAccess, scope: MemberScope::NoScope, @@ -1081,7 +1075,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, @@ -1106,7 +1100,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(), @@ -1224,7 +1218,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( @@ -1507,7 +1501,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), @@ -1562,7 +1556,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 9a7b3e723..86d55e405 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. @@ -1044,15 +1042,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 { @@ -1062,17 +1074,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 _ } } @@ -1083,8 +1099,6 @@ impl AsRef for CoreArchitecture { } impl Architecture for CoreArchitecture { - type Handle = Self; - type RegisterInfo = CoreRegisterInfo; type Register = CoreRegister; type RegisterStackInfo = CoreRegisterStackInfo; @@ -1096,40 +1110,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(), @@ -1155,7 +1170,7 @@ impl Architecture for CoreArchitecture { unsafe { if BNGetInstructionText( - self.0, + self.core().as_ptr(), data.as_ptr(), addr, &mut consumed as *mut _, @@ -1172,7 +1187,7 @@ impl Architecture for CoreArchitecture { } } } - + fn instruction_llil( &self, data: &[u8], @@ -1181,7 +1196,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 { @@ -1221,11 +1242,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1237,11 +1258,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1253,11 +1275,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1269,11 +1291,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1285,11 +1307,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1301,11 +1324,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1317,11 +1340,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1333,11 +1357,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1349,11 +1374,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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(regs); @@ -1372,7 +1398,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 _, @@ -1380,7 +1406,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().as_ptr(), *flag)) .collect(); BNFreeRegisterList(flags); @@ -1390,57 +1416,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().as_ptr(), 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().as_ptr(), reg)), } } fn register_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreRegister(self.0, id)) + Some(CoreRegister(self.core().as_ptr(), id)) } fn register_stack_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreRegisterStack(self.0, id)) + Some(CoreRegisterStack(self.core().as_ptr(), id)) } fn flag_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlag(self.0, id)) + Some(CoreFlag(self.core().as_ptr(), id)) } fn flag_write_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlagWrite(self.0, id)) + Some(CoreFlagWrite(self.core().as_ptr(), id)) } fn flag_class_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlagClass(self.0, id)) + Some(CoreFlagClass(self.core().as_ptr(), id)) } fn flag_group_from_id(&self, id: u32) -> Option { // TODO validate in debug builds - Some(CoreFlagGroup(self.0, id)) + Some(CoreFlagGroup(self.core().as_ptr(), 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().as_ptr(), *reg)) .collect(); BNFreeRegisterList(intrinsics); @@ -1450,16 +1477,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().as_ptr(), 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> { @@ -1472,7 +1499,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(), @@ -1494,32 +1521,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(), @@ -1528,54 +1575,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); } } }; @@ -1587,7 +1642,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), @@ -1624,7 +1679,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; @@ -1641,7 +1696,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; @@ -1661,14 +1717,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); } } @@ -1677,8 +1733,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}; @@ -1686,8 +1742,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: A, func: F, @@ -1695,26 +1751,23 @@ 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 = ptr::read(&custom_arch.func); ptr::write( &mut custom_arch.arch, - create(custom_arch_handle, CoreArchitecture(obj)), + 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() @@ -1722,7 +1775,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() @@ -1730,7 +1783,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() @@ -1738,7 +1791,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() @@ -1746,7 +1799,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() @@ -1754,7 +1807,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() @@ -1765,12 +1818,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( @@ -1781,7 +1834,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) }; @@ -1805,7 +1858,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) }; @@ -1842,15 +1895,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)) => { @@ -1863,7 +1913,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) }; @@ -1875,7 +1925,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) }; @@ -1887,7 +1937,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) }; @@ -1899,7 +1949,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) }; @@ -1911,7 +1961,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) }; @@ -1950,7 +2000,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(); @@ -1960,7 +2010,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(); @@ -1970,7 +2020,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(); @@ -1980,7 +2030,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(); @@ -1990,7 +2040,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(); @@ -2000,7 +2050,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(); @@ -2010,7 +2060,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(); @@ -2020,7 +2070,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(); @@ -2030,7 +2080,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) }; @@ -2051,7 +2101,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); @@ -2066,7 +2116,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) }; @@ -2087,7 +2137,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) }; @@ -2122,7 +2172,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 _); @@ -2135,7 +2185,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) }; @@ -2155,7 +2205,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 @@ -2176,17 +2226,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) { @@ -2206,7 +2253,7 @@ where unsafe { BNGetDefaultArchitectureFlagWriteLowLevelIL( - custom_arch.as_ref().0, + custom_arch.core().as_ptr(), op, size, role, @@ -2229,16 +2276,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; @@ -2253,14 +2297,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) { @@ -2286,7 +2327,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 }; @@ -2307,7 +2348,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) }; @@ -2320,7 +2361,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) }; @@ -2333,7 +2374,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) }; @@ -2345,7 +2386,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(); @@ -2358,7 +2399,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 }; @@ -2384,7 +2425,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) @@ -2392,7 +2433,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) { @@ -2403,7 +2444,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(); @@ -2416,7 +2457,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) }; @@ -2447,7 +2488,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) }; @@ -2467,7 +2508,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) }; @@ -2501,7 +2542,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() { @@ -2513,7 +2554,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() @@ -2527,7 +2568,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()); @@ -2562,7 +2603,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) }; @@ -2576,7 +2617,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) }; @@ -2590,7 +2631,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) }; @@ -2604,7 +2645,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) }; @@ -2618,7 +2659,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) }; @@ -2632,7 +2673,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) }; @@ -2646,7 +2687,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) }; @@ -2660,7 +2701,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) }; @@ -2675,7 +2716,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) }; @@ -2782,38 +2823,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 73ad9362b..dedecb75d 100644 --- a/rust/src/basicblock.rs +++ b/rust/src/basicblock.rs @@ -136,7 +136,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 52d688b84..9b6b0a2a6 100644 --- a/rust/src/binaryview.rs +++ b/rust/src/binaryview.rs @@ -367,7 +367,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); @@ -381,7 +381,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()); } } @@ -405,7 +405,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 815f4d42a..5a06b92ba 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, @@ -407,26 +409,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 {} @@ -435,12 +435,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, }) } @@ -532,7 +531,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() @@ -552,7 +551,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() @@ -594,28 +593,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, } } @@ -641,8 +640,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, }) } @@ -653,7 +651,7 @@ unsafe impl RefCountable for CallingConvention { impl CoreArrayProvider for CallingConvention { type Raw = *mut BNCallingConvention; - type Context = A::Handle; + type Context = &'static A; } unsafe impl CoreOwnedArrayProvider for CallingConvention { @@ -669,8 +667,7 @@ unsafe impl<'a, A: Architecture> CoreArrayWrapper<'a> for CallingConvention { Guard::new( CallingConvention { handle: *raw, - arch_handle: context.clone(), - _arch: Default::default(), + arch_handle: context, }, context, ) @@ -704,8 +701,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 {} @@ -725,7 +721,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(); @@ -741,7 +737,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); } @@ -751,7 +747,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(), @@ -773,8 +769,7 @@ impl ConventionBuilder { are_argument_registers_used_for_var_args: false, - arch_handle: arch.handle(), - _arch: PhantomData, + arch_handle: arch, } } @@ -799,9 +794,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 956be9bdc..425cd762b 100644 --- a/rust/src/custombinaryview.rs +++ b/rust/src/custombinaryview.rs @@ -191,7 +191,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(), + ); } } @@ -199,7 +204,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 19eb085c9..083165eba 100644 --- a/rust/src/demangle.rs +++ b/rust/src/demangle.rs @@ -38,7 +38,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, @@ -94,7 +94,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 273a08612..fcf887fd6 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -30,12 +30,11 @@ pub use binaryninjacore_sys::BNAnalysisSkipReason as AnalysisSkipReason; pub use binaryninjacore_sys::BNFunctionAnalysisSkipOverride as FunctionAnalysisSkipOverride; pub use binaryninjacore_sys::BNFunctionUpdateType as FunctionUpdateType; - use std::hash::Hash; use std::{fmt, mem}; pub struct Location { - pub arch: Option, + pub arch: Option<&'static CoreArchitecture>, pub addr: u64, } @@ -45,8 +44,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, @@ -55,7 +54,7 @@ impl From<(CoreArchitecture, u64)> for Location { } pub struct NativeBlockIter { - arch: CoreArchitecture, + arch: &'static CoreArchitecture, bv: Ref, cur: u64, end: u64, @@ -71,7 +70,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 @@ -126,7 +125,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) @@ -221,7 +220,7 @@ impl Function { addr: u64, ) -> Option>> { 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() { @@ -430,7 +429,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/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 16cc51020..2407829b0 100644 --- a/rust/src/mlil/function.rs +++ b/rust/src/mlil/function.rs @@ -9,6 +9,7 @@ use binaryninjacore_sys::BNMediumLevelILFunction; use binaryninjacore_sys::BNMediumLevelILGetInstructionStart; use binaryninjacore_sys::BNNewMediumLevelILFunctionReference; +use crate::architecture::Architecture; use crate::basicblock::BasicBlock; use crate::function::Function; use crate::function::Location; @@ -47,8 +48,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 diff --git a/rust/src/platform.rs b/rust/src/platform.rs index 3df5e7c47..8d534d052 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 76ac44934..9fd942ac9 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 f9cbb3c52..638353469 100644 --- a/rust/src/relocation.rs +++ b/rust/src/relocation.rs @@ -1,6 +1,7 @@ +use crate::architecture::Architecture; use crate::string::BnStrCompatible; use crate::{ - architecture::{Architecture, CoreArchitecture}, + architecture::CoreArchitecture, binaryview::BinaryView, llil, rc::{CoreArrayProvider, CoreArrayWrapper, CoreOwnedArrayProvider, Ref, RefCountable}, @@ -189,7 +190,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; @@ -281,7 +282,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(), @@ -324,7 +325,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(), ) @@ -346,7 +347,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(), @@ -526,7 +527,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/types.rs b/rust/src/types.rs index 8f14cf00e..3a4bf8abd 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -615,7 +615,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, @@ -630,7 +630,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, @@ -671,7 +671,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, @@ -1133,7 +1133,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, @@ -1150,7 +1150,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, @@ -1190,7 +1190,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, @@ -2591,19 +2591,26 @@ impl DataVariableAndName { ///////////////////////// // ILIntrinsic -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug)] pub struct ILIntrinsic { - arch: CoreArchitecture, + 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: CoreArchitecture, index: u32) -> Self { + 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.0, self.index) }; + 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() }