From c3fdda9727f5507818e3f55576ad32215a22b0f9 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Wed, 30 Apr 2025 17:38:40 -0400 Subject: [Rust] Remove Architecture trait bound on LLIL related structures --- rust/src/architecture.rs | 65 +++--- rust/src/disassembly.rs | 11 +- rust/src/flowgraph.rs | 11 +- rust/src/function.rs | 23 +- rust/src/function_recognizer.rs | 4 +- rust/src/low_level_il.rs | 129 ++++++++--- rust/src/low_level_il/block.rs | 33 ++- rust/src/low_level_il/expression.rs | 275 +++++++++++------------ rust/src/low_level_il/function.rs | 86 ++++---- rust/src/low_level_il/instruction.rs | 103 ++++----- rust/src/low_level_il/lifting.rs | 309 +++++++++++--------------- rust/src/low_level_il/operation.rs | 415 +++++++++++------------------------ rust/src/relocation.rs | 8 +- rust/src/workflow.rs | 19 +- 14 files changed, 640 insertions(+), 851 deletions(-) (limited to 'rust/src') diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index 7ad10dfb..c0fe138e 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -80,6 +80,13 @@ macro_rules! newtype { } newtype!(RegisterId, u32); + +impl RegisterId { + pub fn is_temporary(&self) -> bool { + self.0 & 0x8000_0000 != 0 + } +} + newtype!(RegisterStackId, u32); newtype!(FlagId, u32); // TODO: Make this NonZero? @@ -418,7 +425,7 @@ pub trait Intrinsic: Debug + Sized + Clone + Copy { fn outputs(&self) -> Vec>>; } -pub trait Architecture: 'static + Sized + AsRef + Debug { +pub trait Architecture: 'static + Sized + AsRef { type Handle: Borrow + Clone; type RegisterInfo: RegisterInfo; @@ -460,7 +467,7 @@ pub trait Architecture: 'static + Sized + AsRef + Debug { &self, data: &[u8], addr: u64, - il: &mut MutableLiftedILFunction, + il: &mut MutableLiftedILFunction, ) -> Option<(usize, bool)>; /// Fallback flag value calculation path. This method is invoked when the core is unable to @@ -477,8 +484,8 @@ pub trait Architecture: 'static + Sized + AsRef + Debug { flag: Self::Flag, flag_write_type: Self::FlagWrite, op: LowLevelILFlagWriteOp, - il: &'a mut MutableLiftedILFunction, - ) -> Option> { + il: &'a mut MutableLiftedILFunction, + ) -> Option> { let role = flag.role(flag_write_type.class()); Some(get_default_flag_write_llil(self, role, op, il)) } @@ -506,8 +513,8 @@ pub trait Architecture: 'static + Sized + AsRef + Debug { &self, cond: FlagCondition, class: Option, - il: &'a mut MutableLiftedILFunction, - ) -> Option> { + il: &'a mut MutableLiftedILFunction, + ) -> Option> { Some(get_default_flag_cond_llil(self, cond, class, il)) } @@ -528,8 +535,8 @@ pub trait Architecture: 'static + Sized + AsRef + Debug { fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, - _il: &'a mut MutableLiftedILFunction, - ) -> Option> { + _il: &'a mut MutableLiftedILFunction, + ) -> Option> { None } @@ -1505,7 +1512,7 @@ impl Architecture for CoreArchitecture { &self, data: &[u8], addr: u64, - il: &mut MutableLiftedILFunction, + il: &mut MutableLiftedILFunction, ) -> Option<(usize, bool)> { let mut size = data.len(); let success = unsafe { @@ -1530,8 +1537,8 @@ impl Architecture for CoreArchitecture { _flag: Self::Flag, _flag_write: Self::FlagWrite, _op: LowLevelILFlagWriteOp, - _il: &'a mut MutableLiftedILFunction, - ) -> Option> { + _il: &'a mut MutableLiftedILFunction, + ) -> Option> { None } @@ -1567,16 +1574,16 @@ impl Architecture for CoreArchitecture { &self, _cond: FlagCondition, _class: Option, - _il: &'a mut MutableLiftedILFunction, - ) -> Option> { + _il: &'a mut MutableLiftedILFunction, + ) -> Option> { None } fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, - _il: &'a mut MutableLiftedILFunction, - ) -> Option> { + _il: &'a mut MutableLiftedILFunction, + ) -> Option> { None } @@ -2218,12 +2225,9 @@ where 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 { std::slice::from_raw_parts(data, *len) }; - let mut lifter = unsafe { MutableLiftedILFunction::from_raw(custom_arch_handle, il) }; + let mut lifter = + unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; match custom_arch.instruction_llil(data, addr, &mut lifter) { Some((res_len, res_value)) => { @@ -2606,14 +2610,11 @@ where 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(FlagWriteId(flag_write)); let flag = custom_arch.flag_from_id(FlagId(flag)); let operands = unsafe { std::slice::from_raw_parts(operands_raw, operand_count) }; - let mut lifter = unsafe { MutableLiftedILFunction::from_raw(custom_arch_handle, il) }; + let mut lifter = + unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; if let (Some(flag_write), Some(flag)) = (flag_write, flag) { if let Some(op) = LowLevelILFlagWriteOp::from_op(custom_arch, size, op, operands) { @@ -2659,13 +2660,10 @@ where 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(FlagClassId(class)); - let mut lifter = unsafe { MutableLiftedILFunction::from_raw(custom_arch_handle, il) }; + let mut lifter = + unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; if let Some(expr) = custom_arch.flag_cond_llil(cond, class, &mut lifter) { // TODO verify that returned expr is a bool value return expr.index.0; @@ -2683,11 +2681,8 @@ where 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 { MutableLiftedILFunction::from_raw(custom_arch_handle, il) }; + let mut lifter = + unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; if let Some(group) = custom_arch.flag_group_from_id(FlagGroupId(group)) { if let Some(expr) = custom_arch.flag_group_llil(group, &mut lifter) { diff --git a/rust/src/disassembly.rs b/rust/src/disassembly.rs index 9dfd160f..99a6b22e 100644 --- a/rust/src/disassembly.rs +++ b/rust/src/disassembly.rs @@ -1022,8 +1022,8 @@ impl DisassemblyTextRenderer { unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) } } - pub fn from_llil( - func: &LowLevelILFunction, + pub fn from_llil( + func: &LowLevelILFunction, settings: Option<&DisassemblySettings>, ) -> Ref { let settings_ptr = settings.map(|s| s.handle).unwrap_or(ptr::null_mut()); @@ -1058,14 +1058,11 @@ impl DisassemblyTextRenderer { unsafe { Function::ref_from_raw(result) } } - pub fn llil( - &self, - ) -> Ref> { - let arch = self.arch(); + pub fn llil(&self) -> Ref> { let result = unsafe { BNGetDisassemblyTextRendererLowLevelILFunction(self.handle.as_ptr()) }; assert!(!result.is_null()); - unsafe { LowLevelILFunction::ref_from_raw(arch.handle(), result) } + unsafe { LowLevelILFunction::ref_from_raw(result) } } pub fn mlil(&self) -> Ref { diff --git a/rust/src/flowgraph.rs b/rust/src/flowgraph.rs index c8a9e4a7..976764eb 100644 --- a/rust/src/flowgraph.rs +++ b/rust/src/flowgraph.rs @@ -14,7 +14,6 @@ //! Interfaces for creating and displaying pretty CFGs in Binary Ninja. -use crate::architecture::CoreArchitecture; use crate::disassembly::DisassemblyTextLine; use crate::rc::*; use binaryninjacore_sys::*; @@ -55,17 +54,11 @@ impl FlowGraph { unsafe { Array::new(nodes_ptr, count, ()) } } - pub fn low_level_il(&self) -> Result>, ()> { + pub fn low_level_il(&self) -> Result, ()> { unsafe { let llil_ptr = BNGetFlowGraphLowLevelILFunction(self.handle); match llil_ptr.is_null() { - false => { - let func_ptr = BNGetLowLevelILOwnerFunction(llil_ptr); - let arch_ptr = BNGetFunctionArchitecture(func_ptr); - let arch = CoreArchitecture::from_raw(arch_ptr); - BNFreeFunction(func_ptr); - Ok(RegularLowLevelILFunction::ref_from_raw(arch, llil_ptr)) - } + false => Ok(RegularLowLevelILFunction::ref_from_raw(llil_ptr)), true => Err(()), } } diff --git a/rust/src/function.rs b/rust/src/function.rs index 7990f109..c882ab08 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -529,45 +529,38 @@ impl Function { } } - pub fn low_level_il(&self) -> Result>, ()> { + pub fn low_level_il(&self) -> Result, ()> { unsafe { let llil_ptr = BNGetFunctionLowLevelIL(self.handle); match llil_ptr.is_null() { - false => Ok(RegularLowLevelILFunction::ref_from_raw( - self.arch(), - llil_ptr, - )), + false => Ok(RegularLowLevelILFunction::ref_from_raw(llil_ptr)), true => Err(()), } } } - pub fn low_level_il_if_available( - &self, - ) -> Option>> { + pub fn low_level_il_if_available(&self) -> Option> { let llil_ptr = unsafe { BNGetFunctionLowLevelILIfAvailable(self.handle) }; match llil_ptr.is_null() { - false => { - Some(unsafe { RegularLowLevelILFunction::ref_from_raw(self.arch(), llil_ptr) }) - } + false => Some(unsafe { RegularLowLevelILFunction::ref_from_raw(llil_ptr) }), true => None, } } - pub fn lifted_il(&self) -> Result>, ()> { + pub fn lifted_il(&self) -> Result, ()> { unsafe { let llil_ptr = BNGetFunctionLiftedIL(self.handle); match llil_ptr.is_null() { - false => Ok(LiftedILFunction::ref_from_raw(self.arch(), llil_ptr)), + false => Ok(LiftedILFunction::ref_from_raw(llil_ptr)), true => Err(()), } } } - pub fn lifted_il_if_available(&self) -> Option>> { + pub fn lifted_il_if_available(&self) -> Option> { let llil_ptr = unsafe { BNGetFunctionLiftedILIfAvailable(self.handle) }; match llil_ptr.is_null() { - false => Some(unsafe { LiftedILFunction::ref_from_raw(self.arch(), llil_ptr) }), + false => Some(unsafe { LiftedILFunction::ref_from_raw(llil_ptr) }), true => None, } } diff --git a/rust/src/function_recognizer.rs b/rust/src/function_recognizer.rs index 64e33806..cd5592ee 100644 --- a/rust/src/function_recognizer.rs +++ b/rust/src/function_recognizer.rs @@ -10,7 +10,7 @@ pub trait FunctionRecognizer { &self, _bv: &BinaryView, _func: &Function, - _llil: &RegularLowLevelILFunction, + _llil: &RegularLowLevelILFunction, ) -> bool { false } @@ -49,7 +49,7 @@ where let context = unsafe { &*(ctxt as *mut FunctionRecognizerHandlerContext) }; let bv = unsafe { BinaryView::from_raw(bv).to_owned() }; let func = unsafe { Function::from_raw(func).to_owned() }; - let llil = unsafe { LowLevelILFunction::from_raw(func.arch(), llil).to_owned() }; + let llil = unsafe { LowLevelILFunction::from_raw(llil).to_owned() }; context.recognizer.recognize_low_level_il(&bv, &func, &llil) } diff --git a/rust/src/low_level_il.rs b/rust/src/low_level_il.rs index d6303c13..453e0546 100644 --- a/rust/src/low_level_il.rs +++ b/rust/src/low_level_il.rs @@ -20,8 +20,8 @@ use std::fmt; // requirements on load/store memory address sizes? // can reg/set_reg be used with sizes that differ from what is in BNRegisterInfo? -use crate::architecture::Register as ArchReg; use crate::architecture::{Architecture, RegisterId}; +use crate::architecture::{CoreRegister, Register as ArchReg}; use crate::function::Location; pub mod block; @@ -35,52 +35,123 @@ use self::expression::*; use self::function::*; use self::instruction::*; -pub type MutableLiftedILFunction = LowLevelILFunction>; -pub type LiftedILFunction = LowLevelILFunction>; -pub type MutableLiftedILExpr<'a, Arch, ReturnType> = - LowLevelILExpression<'a, Arch, Mutable, NonSSA, ReturnType>; -pub type RegularLowLevelILFunction = - LowLevelILFunction>; -pub type RegularLowLevelILInstruction<'a, Arch> = - LowLevelILInstruction<'a, Arch, Finalized, NonSSA>; -pub type RegularLowLevelILInstructionKind<'a, Arch> = - LowLevelILInstructionKind<'a, Arch, Finalized, NonSSA>; -pub type RegularLowLevelILExpression<'a, Arch, ReturnType> = - LowLevelILExpression<'a, Arch, Finalized, NonSSA, ReturnType>; -pub type RegularLowLevelILExpressionKind<'a, Arch> = - LowLevelILExpressionKind<'a, Arch, Finalized, NonSSA>; -pub type LowLevelILSSAFunction = LowLevelILFunction; +pub type MutableLiftedILFunction = LowLevelILFunction>; +pub type LiftedILFunction = LowLevelILFunction>; +pub type MutableLiftedILExpr<'a, ReturnType> = + LowLevelILExpression<'a, Mutable, NonSSA, ReturnType>; +pub type RegularLowLevelILFunction = LowLevelILFunction>; +pub type RegularLowLevelILInstruction<'a> = + LowLevelILInstruction<'a, Finalized, NonSSA>; +pub type RegularLowLevelILInstructionKind<'a> = + LowLevelILInstructionKind<'a, Finalized, NonSSA>; +pub type RegularLowLevelILExpression<'a, ReturnType> = + LowLevelILExpression<'a, Finalized, NonSSA, ReturnType>; +pub type RegularLowLevelILExpressionKind<'a> = + LowLevelILExpressionKind<'a, Finalized, NonSSA>; +pub type LowLevelILSSAFunction = LowLevelILFunction; + +#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct LowLevelILTempRegister { + /// The temporary id for the register, this will **NOT** be the referenced id in the core. + /// + /// Do not attempt to pass this to the core. Use [`LowLevelILTempRegister::id`] instead. + temp_id: RegisterId, +} + +impl LowLevelILTempRegister { + pub fn new(temp_id: u32) -> Self { + Self { + temp_id: RegisterId(temp_id), + } + } + + pub fn from_id(id: RegisterId) -> Option { + match id.is_temporary() { + true => { + let temp_id = RegisterId(id.0 & 0x7fff_ffff); + Some(Self { temp_id }) + } + false => None, + } + } + + /// The temporary registers core id, with the temporary bit set. + pub fn id(&self) -> RegisterId { + RegisterId(self.temp_id.0 | 0x8000_0000) + } +} + +impl fmt::Debug for LowLevelILTempRegister { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "temp{}", self.temp_id) + } +} + +impl TryFrom for LowLevelILTempRegister { + type Error = (); + + fn try_from(value: RegisterId) -> Result { + Self::from_id(value).ok_or(()) + } +} + +impl From for LowLevelILTempRegister { + fn from(value: u32) -> Self { + Self::new(value) + } +} #[derive(Copy, Clone, PartialEq, Eq)] -pub enum LowLevelILRegister { - ArchReg(R), - // TODO: Might want to be changed to TempRegisterId. - // TODO: If we do that then we would need to get rid of `Register::id()` - Temp(u32), +pub enum LowLevelILRegisterKind { + Arch(R), + Temp(LowLevelILTempRegister), } -impl LowLevelILRegister { +impl LowLevelILRegisterKind { + pub fn from_raw(arch: &impl Architecture, val: RegisterId) -> Option { + match val.is_temporary() { + true => { + let temp_reg = LowLevelILTempRegister::from_id(val)?; + Some(LowLevelILRegisterKind::Temp(temp_reg)) + } + false => { + let arch_reg = arch.register_from_id(val)?; + Some(LowLevelILRegisterKind::Arch(arch_reg)) + } + } + } + + pub fn from_temp(temp: impl Into) -> Self { + LowLevelILRegisterKind::Temp(temp.into()) + } + fn id(&self) -> RegisterId { match *self { - LowLevelILRegister::ArchReg(ref r) => r.id(), - LowLevelILRegister::Temp(id) => RegisterId(0x8000_0000 | id), + LowLevelILRegisterKind::Arch(ref r) => r.id(), + LowLevelILRegisterKind::Temp(temp) => temp.id(), } } } -impl fmt::Debug for LowLevelILRegister { +impl fmt::Debug for LowLevelILRegisterKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - LowLevelILRegister::ArchReg(ref r) => write!(f, "{}", r.name().as_ref()), - LowLevelILRegister::Temp(id) => write!(f, "temp{}", id), + LowLevelILRegisterKind::Arch(ref r) => r.fmt(f), + LowLevelILRegisterKind::Temp(id) => id.fmt(f), } } } +impl From for LowLevelILRegisterKind { + fn from(reg: LowLevelILTempRegister) -> Self { + LowLevelILRegisterKind::Temp(reg) + } +} + #[derive(Copy, Clone, Debug)] pub enum LowLevelILSSARegister { - Full(LowLevelILRegister, u32), // no such thing as partial access to a temp register, I think - Partial(R, u32, R), // partial accesses only possible for arch registers, I think + Full(LowLevelILRegisterKind, u32), // no such thing as partial access to a temp register, I think + Partial(R, u32, R), // partial accesses only possible for arch registers, I think } impl LowLevelILSSARegister { diff --git a/rust/src/low_level_il/block.rs b/rust/src/low_level_il/block.rs index ac0be449..519c707e 100644 --- a/rust/src/low_level_il/block.rs +++ b/rust/src/low_level_il/block.rs @@ -15,38 +15,35 @@ use std::fmt::Debug; use std::ops::Range; -use crate::architecture::Architecture; use crate::basic_block::{BasicBlock, BlockContext}; use super::*; #[derive(Copy)] -pub struct LowLevelILBlock<'func, A, M, F> +pub struct LowLevelILBlock<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - pub(crate) function: &'func LowLevelILFunction, + pub(crate) function: &'func LowLevelILFunction, } -impl<'func, A, M, F> BlockContext for LowLevelILBlock<'func, A, M, F> +impl<'func, M, F> BlockContext for LowLevelILBlock<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - type Instruction = LowLevelILInstruction<'func, A, M, F>; + type Instruction = LowLevelILInstruction<'func, M, F>; type InstructionIndex = LowLevelInstructionIndex; - type Iter = LowLevelILBlockIter<'func, A, M, F>; + type Iter = LowLevelILBlockIter<'func, M, F>; - fn start(&self, block: &BasicBlock) -> LowLevelILInstruction<'func, A, M, F> { + fn start(&self, block: &BasicBlock) -> LowLevelILInstruction<'func, M, F> { self.function .instruction_from_index(block.start_index()) .unwrap() } - fn iter(&self, block: &BasicBlock) -> LowLevelILBlockIter<'func, A, M, F> { + fn iter(&self, block: &BasicBlock) -> LowLevelILBlockIter<'func, M, F> { LowLevelILBlockIter { function: self.function, range: (block.start_index().0)..(block.end_index().0), @@ -54,9 +51,8 @@ where } } -impl<'func, A, M, F> Debug for LowLevelILBlock<'func, A, M, F> +impl<'func, M, F> Debug for LowLevelILBlock<'func, M, F> where - A: 'func + Architecture + Debug, M: FunctionMutability, F: FunctionForm, { @@ -67,9 +63,8 @@ where } } -impl<'func, A, M, F> Clone for LowLevelILBlock<'func, A, M, F> +impl<'func, M, F> Clone for LowLevelILBlock<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { @@ -80,24 +75,22 @@ where } } -pub struct LowLevelILBlockIter<'func, A, M, F> +pub struct LowLevelILBlockIter<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - function: &'func LowLevelILFunction, + function: &'func LowLevelILFunction, // TODO: Once step_trait is stable we can do Range range: Range, } -impl<'func, A, M, F> Iterator for LowLevelILBlockIter<'func, A, M, F> +impl<'func, M, F> Iterator for LowLevelILBlockIter<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - type Item = LowLevelILInstruction<'func, A, M, F>; + type Item = LowLevelILInstruction<'func, M, F>; fn next(&mut self) -> Option { self.range diff --git a/rust/src/low_level_il/expression.rs b/rust/src/low_level_il/expression.rs index f8fcf9f7..331ab980 100644 --- a/rust/src/low_level_il/expression.rs +++ b/rust/src/low_level_il/expression.rs @@ -19,7 +19,7 @@ use super::operation; use super::operation::Operation; use super::VisitorAction; use super::*; -use crate::architecture::Architecture; +use crate::architecture::CoreFlagWrite; use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::marker::PhantomData; @@ -47,42 +47,39 @@ impl Display for LowLevelExpressionIndex { } // TODO: Probably want to rename this with a LowLevelIL prefix to avoid collisions when we add handlers for other ILs -pub trait ExpressionHandler<'func, A, M, F> +pub trait ExpressionHandler<'func, M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - fn kind(&self) -> LowLevelILExpressionKind<'func, A, M, F>; + fn kind(&self) -> LowLevelILExpressionKind<'func, M, F>; fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, A, M, F, ValueExpr>) -> VisitorAction; + T: FnMut(&LowLevelILExpression<'func, M, F, ValueExpr>) -> VisitorAction; } -pub struct LowLevelILExpression<'func, A, M, F, R> +pub struct LowLevelILExpression<'func, M, F, R> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, R: ExpressionResultType, { - pub(crate) function: &'func LowLevelILFunction, + pub(crate) function: &'func LowLevelILFunction, pub index: LowLevelExpressionIndex, // tag the 'return' type of this expression pub(crate) _ty: PhantomData, } -impl<'func, A, M, F, R> LowLevelILExpression<'func, A, M, F, R> +impl<'func, M, F, R> LowLevelILExpression<'func, M, F, R> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, R: ExpressionResultType, { pub(crate) fn new( - function: &'func LowLevelILFunction, + function: &'func LowLevelILFunction, index: LowLevelExpressionIndex, ) -> Self { // TODO: Validate expression here? @@ -94,27 +91,25 @@ where } } -impl<'func, A, M, F, R> fmt::Debug for LowLevelILExpression<'func, A, M, F, R> +impl<'func, M, F, R> fmt::Debug for LowLevelILExpression<'func, M, F, R> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, R: ExpressionResultType, { fn fmt(&self, f: &mut Formatter) -> fmt::Result { let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; - let t = unsafe { LowLevelILExpressionKind::from_raw(self.function, op) }; - t.fmt(f) + // SAFETY: This is safe we are not exposing the expression kind to the caller. + let kind = unsafe { LowLevelILExpressionKind::from_raw(self.function, op) }; + kind.fmt(f) } } -impl<'func, A, M> ExpressionHandler<'func, A, M, SSA> - for LowLevelILExpression<'func, A, M, SSA, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, SSA> for LowLevelILExpression<'func, M, SSA, ValueExpr> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, A, M, SSA> { + fn kind(&self) -> LowLevelILExpressionKind<'func, M, SSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; @@ -128,7 +123,7 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, A, M, SSA, ValueExpr>) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, SSA, ValueExpr>) -> VisitorAction, { // Visit the current expression. match f(self) { @@ -141,13 +136,12 @@ where } } -impl<'func, A, M> ExpressionHandler<'func, A, M, NonSSA> - for LowLevelILExpression<'func, A, M, NonSSA, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, NonSSA> + for LowLevelILExpression<'func, M, NonSSA, ValueExpr> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, A, M, NonSSA> { + fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; @@ -161,9 +155,7 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, { // Visit the current expression. match f(self) { @@ -176,13 +168,12 @@ where } } -impl<'func, A, M> ExpressionHandler<'func, A, M, NonSSA> - for LowLevelILExpression<'func, A, M, NonSSA, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, NonSSA> + for LowLevelILExpression<'func, M, NonSSA, ValueExpr> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, A, M, NonSSA> { + fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA> { use binaryninjacore_sys::BNLowLevelILOperation::*; let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; match op.operation { @@ -197,7 +188,7 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA, ValueExpr>, + &LowLevelILExpression<'func, M, NonSSA, ValueExpr>, ) -> VisitorAction, { // Visit the current expression. @@ -211,129 +202,126 @@ where } } -impl<'func, A, F> LowLevelILExpression<'func, A, Finalized, F, ValueExpr> +impl<'func, F> LowLevelILExpression<'func, Finalized, F, ValueExpr> where - A: 'func + Architecture, F: FunctionForm, { // TODO possible values } #[derive(Debug)] -pub enum LowLevelILExpressionKind<'func, A, M, F> +pub enum LowLevelILExpressionKind<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - Load(Operation<'func, A, M, F, operation::Load>), - Pop(Operation<'func, A, M, F, operation::Pop>), - Reg(Operation<'func, A, M, F, operation::Reg>), - RegSplit(Operation<'func, A, M, F, operation::RegSplit>), - Const(Operation<'func, A, M, F, operation::Const>), - ConstPtr(Operation<'func, A, M, F, operation::Const>), - Flag(Operation<'func, A, M, F, operation::Flag>), - FlagBit(Operation<'func, A, M, F, operation::FlagBit>), - ExternPtr(Operation<'func, A, M, F, operation::Extern>), - - RegStackPop(Operation<'func, A, M, F, operation::RegStackPop>), - - Add(Operation<'func, A, M, F, operation::BinaryOp>), - Adc(Operation<'func, A, M, F, operation::BinaryOpCarry>), - Sub(Operation<'func, A, M, F, operation::BinaryOp>), - Sbb(Operation<'func, A, M, F, operation::BinaryOpCarry>), - And(Operation<'func, A, M, F, operation::BinaryOp>), - Or(Operation<'func, A, M, F, operation::BinaryOp>), - Xor(Operation<'func, A, M, F, operation::BinaryOp>), - Lsl(Operation<'func, A, M, F, operation::BinaryOp>), - Lsr(Operation<'func, A, M, F, operation::BinaryOp>), - Asr(Operation<'func, A, M, F, operation::BinaryOp>), - Rol(Operation<'func, A, M, F, operation::BinaryOp>), - Rlc(Operation<'func, A, M, F, operation::BinaryOpCarry>), - Ror(Operation<'func, A, M, F, operation::BinaryOp>), - Rrc(Operation<'func, A, M, F, operation::BinaryOpCarry>), - Mul(Operation<'func, A, M, F, operation::BinaryOp>), - - MulsDp(Operation<'func, A, M, F, operation::BinaryOp>), - MuluDp(Operation<'func, A, M, F, operation::BinaryOp>), - - Divu(Operation<'func, A, M, F, operation::BinaryOp>), - Divs(Operation<'func, A, M, F, operation::BinaryOp>), - - DivuDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), - DivsDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), - - Modu(Operation<'func, A, M, F, operation::BinaryOp>), - Mods(Operation<'func, A, M, F, operation::BinaryOp>), - - ModuDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), - ModsDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), - - Neg(Operation<'func, A, M, F, operation::UnaryOp>), - Not(Operation<'func, A, M, F, operation::UnaryOp>), - Sx(Operation<'func, A, M, F, operation::UnaryOp>), - Zx(Operation<'func, A, M, F, operation::UnaryOp>), - LowPart(Operation<'func, A, M, F, operation::UnaryOp>), + Load(Operation<'func, M, F, operation::Load>), + Pop(Operation<'func, M, F, operation::Pop>), + Reg(Operation<'func, M, F, operation::Reg>), + RegSplit(Operation<'func, M, F, operation::RegSplit>), + Const(Operation<'func, M, F, operation::Const>), + ConstPtr(Operation<'func, M, F, operation::Const>), + Flag(Operation<'func, M, F, operation::Flag>), + FlagBit(Operation<'func, M, F, operation::FlagBit>), + ExternPtr(Operation<'func, M, F, operation::Extern>), + + RegStackPop(Operation<'func, M, F, operation::RegStackPop>), + + Add(Operation<'func, M, F, operation::BinaryOp>), + Adc(Operation<'func, M, F, operation::BinaryOpCarry>), + Sub(Operation<'func, M, F, operation::BinaryOp>), + Sbb(Operation<'func, M, F, operation::BinaryOpCarry>), + And(Operation<'func, M, F, operation::BinaryOp>), + Or(Operation<'func, M, F, operation::BinaryOp>), + Xor(Operation<'func, M, F, operation::BinaryOp>), + Lsl(Operation<'func, M, F, operation::BinaryOp>), + Lsr(Operation<'func, M, F, operation::BinaryOp>), + Asr(Operation<'func, M, F, operation::BinaryOp>), + Rol(Operation<'func, M, F, operation::BinaryOp>), + Rlc(Operation<'func, M, F, operation::BinaryOpCarry>), + Ror(Operation<'func, M, F, operation::BinaryOp>), + Rrc(Operation<'func, M, F, operation::BinaryOpCarry>), + Mul(Operation<'func, M, F, operation::BinaryOp>), + + MulsDp(Operation<'func, M, F, operation::BinaryOp>), + MuluDp(Operation<'func, M, F, operation::BinaryOp>), + + Divu(Operation<'func, M, F, operation::BinaryOp>), + Divs(Operation<'func, M, F, operation::BinaryOp>), + + DivuDp(Operation<'func, M, F, operation::DoublePrecDivOp>), + DivsDp(Operation<'func, M, F, operation::DoublePrecDivOp>), + + Modu(Operation<'func, M, F, operation::BinaryOp>), + Mods(Operation<'func, M, F, operation::BinaryOp>), + + ModuDp(Operation<'func, M, F, operation::DoublePrecDivOp>), + ModsDp(Operation<'func, M, F, operation::DoublePrecDivOp>), + + Neg(Operation<'func, M, F, operation::UnaryOp>), + Not(Operation<'func, M, F, operation::UnaryOp>), + Sx(Operation<'func, M, F, operation::UnaryOp>), + Zx(Operation<'func, M, F, operation::UnaryOp>), + LowPart(Operation<'func, M, F, operation::UnaryOp>), // Valid only in Lifted IL - FlagCond(Operation<'func, A, M, NonSSA, operation::FlagCond>), + FlagCond(Operation<'func, M, NonSSA, operation::FlagCond>), // Valid only in Lifted IL - FlagGroup(Operation<'func, A, M, NonSSA, operation::FlagGroup>), - - CmpE(Operation<'func, A, M, F, operation::Condition>), - CmpNe(Operation<'func, A, M, F, operation::Condition>), - CmpSlt(Operation<'func, A, M, F, operation::Condition>), - CmpUlt(Operation<'func, A, M, F, operation::Condition>), - CmpSle(Operation<'func, A, M, F, operation::Condition>), - CmpUle(Operation<'func, A, M, F, operation::Condition>), - CmpSge(Operation<'func, A, M, F, operation::Condition>), - CmpUge(Operation<'func, A, M, F, operation::Condition>), - CmpSgt(Operation<'func, A, M, F, operation::Condition>), - CmpUgt(Operation<'func, A, M, F, operation::Condition>), - - //TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO - BoolToInt(Operation<'func, A, M, F, operation::UnaryOp>), - - Fadd(Operation<'func, A, M, F, operation::BinaryOp>), - Fsub(Operation<'func, A, M, F, operation::BinaryOp>), - Fmul(Operation<'func, A, M, F, operation::BinaryOp>), - Fdiv(Operation<'func, A, M, F, operation::BinaryOp>), - Fsqrt(Operation<'func, A, M, F, operation::UnaryOp>), - Fneg(Operation<'func, A, M, F, operation::UnaryOp>), - Fabs(Operation<'func, A, M, F, operation::UnaryOp>), - FloatToInt(Operation<'func, A, M, F, operation::UnaryOp>), - IntToFloat(Operation<'func, A, M, F, operation::UnaryOp>), - FloatConv(Operation<'func, A, M, F, operation::UnaryOp>), - RoundToInt(Operation<'func, A, M, F, operation::UnaryOp>), - Floor(Operation<'func, A, M, F, operation::UnaryOp>), - Ceil(Operation<'func, A, M, F, operation::UnaryOp>), - Ftrunc(Operation<'func, A, M, F, operation::UnaryOp>), - - FcmpE(Operation<'func, A, M, F, operation::Condition>), - FcmpNE(Operation<'func, A, M, F, operation::Condition>), - FcmpLT(Operation<'func, A, M, F, operation::Condition>), - FcmpLE(Operation<'func, A, M, F, operation::Condition>), - FcmpGE(Operation<'func, A, M, F, operation::Condition>), - FcmpGT(Operation<'func, A, M, F, operation::Condition>), - FcmpO(Operation<'func, A, M, F, operation::Condition>), - FcmpUO(Operation<'func, A, M, F, operation::Condition>), + FlagGroup(Operation<'func, M, NonSSA, operation::FlagGroup>), + + CmpE(Operation<'func, M, F, operation::Condition>), + CmpNe(Operation<'func, M, F, operation::Condition>), + CmpSlt(Operation<'func, M, F, operation::Condition>), + CmpUlt(Operation<'func, M, F, operation::Condition>), + CmpSle(Operation<'func, M, F, operation::Condition>), + CmpUle(Operation<'func, M, F, operation::Condition>), + CmpSge(Operation<'func, M, F, operation::Condition>), + CmpUge(Operation<'func, M, F, operation::Condition>), + CmpSgt(Operation<'func, M, F, operation::Condition>), + CmpUgt(Operation<'func, M, F, operation::Condition>), + + //TestBit(Operation<'func, M, F, operation::TestBit>), // TODO + BoolToInt(Operation<'func, M, F, operation::UnaryOp>), + + Fadd(Operation<'func, M, F, operation::BinaryOp>), + Fsub(Operation<'func, M, F, operation::BinaryOp>), + Fmul(Operation<'func, M, F, operation::BinaryOp>), + Fdiv(Operation<'func, M, F, operation::BinaryOp>), + Fsqrt(Operation<'func, M, F, operation::UnaryOp>), + Fneg(Operation<'func, M, F, operation::UnaryOp>), + Fabs(Operation<'func, M, F, operation::UnaryOp>), + FloatToInt(Operation<'func, M, F, operation::UnaryOp>), + IntToFloat(Operation<'func, M, F, operation::UnaryOp>), + FloatConv(Operation<'func, M, F, operation::UnaryOp>), + RoundToInt(Operation<'func, M, F, operation::UnaryOp>), + Floor(Operation<'func, M, F, operation::UnaryOp>), + Ceil(Operation<'func, M, F, operation::UnaryOp>), + Ftrunc(Operation<'func, M, F, operation::UnaryOp>), + + FcmpE(Operation<'func, M, F, operation::Condition>), + FcmpNE(Operation<'func, M, F, operation::Condition>), + FcmpLT(Operation<'func, M, F, operation::Condition>), + FcmpLE(Operation<'func, M, F, operation::Condition>), + FcmpGE(Operation<'func, M, F, operation::Condition>), + FcmpGT(Operation<'func, M, F, operation::Condition>), + FcmpO(Operation<'func, M, F, operation::Condition>), + FcmpUO(Operation<'func, M, F, operation::Condition>), // TODO ADD_OVERFLOW - Unimpl(Operation<'func, A, M, F, operation::NoArgs>), - UnimplMem(Operation<'func, A, M, F, operation::UnimplMem>), + Unimpl(Operation<'func, M, F, operation::NoArgs>), + UnimplMem(Operation<'func, M, F, operation::UnimplMem>), - Undef(Operation<'func, A, M, F, operation::NoArgs>), + Undef(Operation<'func, M, F, operation::NoArgs>), } -impl<'func, A, M, F> LowLevelILExpressionKind<'func, A, M, F> +impl<'func, M, F> LowLevelILExpressionKind<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { // TODO: Document what "unchecked" means and how to consume this safely. pub(crate) unsafe fn from_raw( - function: &'func LowLevelILFunction, + function: &'func LowLevelILFunction, op: BNLowLevelILInstruction, ) -> Self { use binaryninjacore_sys::BNLowLevelILOperation::*; @@ -472,7 +460,7 @@ where } _ => Some(self.raw_struct().size), - //TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO + //TestBit(Operation<'func, M, F, operation::TestBit>), // TODO } } @@ -492,7 +480,7 @@ where } } - pub fn as_cmp_op(&self) -> Option<&Operation<'func, A, M, F, operation::Condition>> { + pub fn as_cmp_op(&self) -> Option<&Operation<'func, M, F, operation::Condition>> { use self::LowLevelILExpressionKind::*; match *self { @@ -504,7 +492,7 @@ where } } - pub fn as_binary_op(&self) -> Option<&Operation<'func, A, M, F, operation::BinaryOp>> { + pub fn as_binary_op(&self) -> Option<&Operation<'func, M, F, operation::BinaryOp>> { use self::LowLevelILExpressionKind::*; match *self { @@ -516,9 +504,7 @@ where } } - pub fn as_binary_op_carry( - &self, - ) -> Option<&Operation<'func, A, M, F, operation::BinaryOpCarry>> { + pub fn as_binary_op_carry(&self) -> Option<&Operation<'func, M, F, operation::BinaryOpCarry>> { use self::LowLevelILExpressionKind::*; match *self { @@ -529,7 +515,7 @@ where pub fn as_double_prec_div_op( &self, - ) -> Option<&Operation<'func, A, M, F, operation::DoublePrecDivOp>> { + ) -> Option<&Operation<'func, M, F, operation::DoublePrecDivOp>> { use self::LowLevelILExpressionKind::*; match *self { @@ -538,7 +524,7 @@ where } } - pub fn as_unary_op(&self) -> Option<&Operation<'func, A, M, F, operation::UnaryOp>> { + pub fn as_unary_op(&self) -> Option<&Operation<'func, M, F, operation::UnaryOp>> { use self::LowLevelILExpressionKind::*; match *self { @@ -552,7 +538,7 @@ where pub fn visit_sub_expressions(&self, mut visitor: T) -> VisitorAction where - T: FnMut(LowLevelILExpression<'func, A, M, F, ValueExpr>) -> VisitorAction, + T: FnMut(LowLevelILExpression<'func, M, F, ValueExpr>) -> VisitorAction, { use LowLevelILExpressionKind::*; @@ -659,16 +645,13 @@ where | Floor(ref op) | Ceil(ref op) | Ftrunc(ref op) => &op.op, UnimplMem(ref op) => &op.op, - //TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO + //TestBit(Operation<'func, M, F, operation::TestBit>), // TODO } } } -impl<'func, A> LowLevelILExpressionKind<'func, A, Mutable, NonSSA> -where - A: 'func + Architecture, -{ - pub fn flag_write(&self) -> Option { +impl<'func> LowLevelILExpressionKind<'func, Mutable, NonSSA> { + pub fn flag_write(&self) -> Option { use self::LowLevelILExpressionKind::*; match *self { @@ -720,7 +703,7 @@ where | Floor(ref op) | Ceil(ref op) | Ftrunc(ref op) => op.flag_write(), UnimplMem(ref op) => op.flag_write(), - //TestBit(Operation<'func, A, M, F, operation::TestBit>), // TODO + //TestBit(Operation<'func, M, F, operation::TestBit>), // TODO } } } diff --git a/rust/src/low_level_il/function.rs b/rust/src/low_level_il/function.rs index 301c3f09..21eebc3c 100644 --- a/rust/src/low_level_il/function.rs +++ b/rust/src/low_level_il/function.rs @@ -17,7 +17,6 @@ use binaryninjacore_sys::BNGetLowLevelILOwnerFunction; use binaryninjacore_sys::BNLowLevelILFunction; use binaryninjacore_sys::BNNewLowLevelILFunctionReference; -use std::borrow::Borrow; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; @@ -57,51 +56,56 @@ pub trait FunctionForm: 'static + Debug {} impl FunctionForm for SSA {} impl FunctionForm for NonSSA {} -pub struct LowLevelILFunction { - pub(crate) arch_handle: A::Handle, +pub struct LowLevelILFunction { pub(crate) handle: *mut BNLowLevelILFunction, - _arch: PhantomData<*mut A>, + arch: Option, _mutability: PhantomData, _form: PhantomData, } -impl LowLevelILFunction +impl LowLevelILFunction where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub(crate) unsafe fn from_raw( - arch_handle: A::Handle, + pub(crate) unsafe fn from_raw_with_arch( handle: *mut BNLowLevelILFunction, + arch: Option, ) -> Self { debug_assert!(!handle.is_null()); Self { - arch_handle, handle, - _arch: PhantomData, + arch, _mutability: PhantomData, _form: PhantomData, } } - pub(crate) unsafe fn ref_from_raw( - arch_handle: A::Handle, + pub(crate) unsafe fn from_raw(handle: *mut BNLowLevelILFunction) -> Self { + Self::from_raw_with_arch(handle, None) + } + + pub(crate) unsafe fn ref_from_raw_with_arch( handle: *mut BNLowLevelILFunction, + arch: Option, ) -> Ref { debug_assert!(!handle.is_null()); - Ref::new(Self::from_raw(arch_handle, handle)) + Ref::new(Self::from_raw_with_arch(handle, arch)) } - pub(crate) fn arch(&self) -> &A { - self.arch_handle.borrow() + pub(crate) unsafe fn ref_from_raw(handle: *mut BNLowLevelILFunction) -> Ref { + Self::ref_from_raw_with_arch(handle, None) } - pub fn instruction_at>( - &self, - loc: L, - ) -> Option> { + pub(crate) fn arch(&self) -> CoreArchitecture { + match self.arch { + None => self.function().arch(), + Some(arch) => arch, + } + } + + pub fn instruction_at>(&self, loc: L) -> Option> { Some(LowLevelILInstruction::new( self, self.instruction_index_at(loc)?, @@ -128,7 +132,7 @@ where pub fn instruction_from_index( &self, index: LowLevelInstructionIndex, - ) -> Option> { + ) -> Option> { if index.0 >= self.instruction_count() { None } else { @@ -161,12 +165,8 @@ where // LLIL basic blocks are not available until the function object // is finalized, so ensure we can't try requesting basic blocks // during lifting -impl LowLevelILFunction -where - A: Architecture, - F: FunctionForm, -{ - pub fn basic_blocks(&self) -> Array>> { +impl LowLevelILFunction { + pub fn basic_blocks(&self) -> Array>> { use binaryninjacore_sys::BNGetLowLevelILBasicBlockList; unsafe { @@ -179,7 +179,7 @@ where } // Allow instantiating Lifted IL functions for querying Lifted IL from Architectures -impl LowLevelILFunction> { +impl LowLevelILFunction> { // TODO: Document what happens when you pass None for `source_func`. // TODO: Doing so would construct a LowLevelILFunction with no basic blocks // TODO: Document why you would want to do that. @@ -196,7 +196,7 @@ impl LowLevelILFunction> { // BNCreateLowLevelILFunction should always return a valid object. assert!(!handle.is_null()); - unsafe { Self::ref_from_raw(arch, handle) } + unsafe { Self::ref_from_raw_with_arch(handle, Some(arch)) } } pub fn generate_ssa_form(&self) { @@ -206,9 +206,8 @@ impl LowLevelILFunction> { } } -impl ToOwned for LowLevelILFunction +impl ToOwned for LowLevelILFunction where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -219,17 +218,15 @@ where } } -unsafe impl RefCountable for LowLevelILFunction +unsafe impl RefCountable for LowLevelILFunction where - A: Architecture, M: FunctionMutability, F: FunctionForm, { unsafe fn inc_ref(handle: &Self) -> Ref { Ref::new(Self { - arch_handle: handle.arch_handle.clone(), handle: BNNewLowLevelILFunctionReference(handle.handle), - _arch: PhantomData, + arch: handle.arch, _mutability: PhantomData, _form: PhantomData, }) @@ -240,9 +237,8 @@ where } } -impl Debug for LowLevelILFunction +impl Debug for LowLevelILFunction where - A: Architecture + Debug, M: FunctionMutability, F: FunctionForm, { @@ -255,26 +251,18 @@ where } } -unsafe impl Send - for LowLevelILFunction -{ -} -unsafe impl Sync - for LowLevelILFunction -{ -} +unsafe impl Send for LowLevelILFunction {} +unsafe impl Sync for LowLevelILFunction {} -impl Eq for LowLevelILFunction {} +impl Eq for LowLevelILFunction {} -impl PartialEq - for LowLevelILFunction -{ +impl PartialEq for LowLevelILFunction { fn eq(&self, rhs: &Self) -> bool { self.function().eq(&rhs.function()) } } -impl Hash for LowLevelILFunction { +impl Hash for LowLevelILFunction { fn hash(&self, state: &mut H) { self.function().hash(state) } diff --git a/rust/src/low_level_il/instruction.rs b/rust/src/low_level_il/instruction.rs index 977dcff4..a1253df5 100644 --- a/rust/src/low_level_il/instruction.rs +++ b/rust/src/low_level_il/instruction.rs @@ -16,7 +16,6 @@ use super::operation; use super::operation::Operation; use super::VisitorAction; use super::*; -use crate::architecture::Architecture; use binaryninjacore_sys::BNGetLowLevelILByIndex; use binaryninjacore_sys::BNGetLowLevelILIndexForInstruction; use binaryninjacore_sys::BNLowLevelILInstruction; @@ -51,44 +50,38 @@ impl Display for LowLevelInstructionIndex { } // TODO: Probably want to rename this with a LowLevelIL prefix to avoid collisions when we add handlers for other ILs -pub trait InstructionHandler<'func, A, M, F> +pub trait InstructionHandler<'func, M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - fn kind(&self) -> LowLevelILInstructionKind<'func, A, M, F>; + fn kind(&self) -> LowLevelILInstructionKind<'func, M, F>; /// Visit the sub expressions of this instruction. /// /// NOTE: This does not visit the root expression, i.e. the instruction. fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, A, M, F, ValueExpr>) -> VisitorAction; + T: FnMut(&LowLevelILExpression<'func, M, F, ValueExpr>) -> VisitorAction; } -pub struct LowLevelILInstruction<'func, A, M, F> +pub struct LowLevelILInstruction<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - pub(crate) function: &'func LowLevelILFunction, + pub(crate) function: &'func LowLevelILFunction, pub index: LowLevelInstructionIndex, } -impl<'func, A, M, F> LowLevelILInstruction<'func, A, M, F> +impl<'func, M, F> LowLevelILInstruction<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { // TODO: Should we check the instruction count here with BNGetLowLevelILInstructionCount? // TODO: If we _can_ then this should become an Option methinks - pub fn new( - function: &'func LowLevelILFunction, - index: LowLevelInstructionIndex, - ) -> Self { + pub fn new(function: &'func LowLevelILFunction, index: LowLevelInstructionIndex) -> Self { Self { function, index } } @@ -107,9 +100,8 @@ where } } -impl<'func, A, M, F> Debug for LowLevelILInstruction<'func, A, M, F> +impl<'func, M, F> Debug for LowLevelILInstruction<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { @@ -122,12 +114,11 @@ where } } -impl<'func, A, M> InstructionHandler<'func, A, M, SSA> for LowLevelILInstruction<'func, A, M, SSA> +impl<'func, M> InstructionHandler<'func, M, SSA> for LowLevelILInstruction<'func, M, SSA> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, A, M, SSA> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, SSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -143,20 +134,19 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, A, M, SSA, ValueExpr>) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, SSA, ValueExpr>) -> VisitorAction, { // Recursively visit sub expressions. self.kind().visit_sub_expressions(|e| e.visit_tree(f)) } } -impl<'func, A, M> InstructionHandler<'func, A, M, NonSSA> - for LowLevelILInstruction<'func, A, M, NonSSA> +impl<'func, M> InstructionHandler<'func, M, NonSSA> + for LowLevelILInstruction<'func, M, NonSSA> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, A, M, NonSSA> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -172,22 +162,19 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, { // Recursively visit sub expressions. self.kind().visit_sub_expressions(|e| e.visit_tree(f)) } } -impl<'func, A, M> InstructionHandler<'func, A, M, NonSSA> - for LowLevelILInstruction<'func, A, M, NonSSA> +impl<'func, M> InstructionHandler<'func, M, NonSSA> + for LowLevelILInstruction<'func, M, NonSSA> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, A, M, NonSSA> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -204,7 +191,7 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA, ValueExpr>, + &LowLevelILExpression<'func, M, NonSSA, ValueExpr>, ) -> VisitorAction, { // Recursively visit sub expressions. @@ -213,52 +200,50 @@ where } #[derive(Debug)] -pub enum LowLevelILInstructionKind<'func, A, M, F> +pub enum LowLevelILInstructionKind<'func, M, F> where - A: 'func + Architecture, M: FunctionMutability, F: FunctionForm, { - Nop(Operation<'func, A, M, F, operation::NoArgs>), - SetReg(Operation<'func, A, M, F, operation::SetReg>), - SetRegSplit(Operation<'func, A, M, F, operation::SetRegSplit>), - SetFlag(Operation<'func, A, M, F, operation::SetFlag>), - Store(Operation<'func, A, M, F, operation::Store>), + Nop(Operation<'func, M, F, operation::NoArgs>), + SetReg(Operation<'func, M, F, operation::SetReg>), + SetRegSplit(Operation<'func, M, F, operation::SetRegSplit>), + SetFlag(Operation<'func, M, F, operation::SetFlag>), + Store(Operation<'func, M, F, operation::Store>), // TODO needs a real op - Push(Operation<'func, A, M, F, operation::UnaryOp>), + Push(Operation<'func, M, F, operation::UnaryOp>), - RegStackPush(Operation<'func, A, M, F, operation::RegStackPush>), + RegStackPush(Operation<'func, M, F, operation::RegStackPush>), - Jump(Operation<'func, A, M, F, operation::Jump>), - JumpTo(Operation<'func, A, M, F, operation::JumpTo>), + Jump(Operation<'func, M, F, operation::Jump>), + JumpTo(Operation<'func, M, F, operation::JumpTo>), - Call(Operation<'func, A, M, F, operation::Call>), - TailCall(Operation<'func, A, M, F, operation::Call>), + Call(Operation<'func, M, F, operation::Call>), + TailCall(Operation<'func, M, F, operation::Call>), - Ret(Operation<'func, A, M, F, operation::Ret>), - NoRet(Operation<'func, A, M, F, operation::NoArgs>), + Ret(Operation<'func, M, F, operation::Ret>), + NoRet(Operation<'func, M, F, operation::NoArgs>), - If(Operation<'func, A, M, F, operation::If>), - Goto(Operation<'func, A, M, F, operation::Goto>), + If(Operation<'func, M, F, operation::If>), + Goto(Operation<'func, M, F, operation::Goto>), - Syscall(Operation<'func, A, M, F, operation::Syscall>), - Intrinsic(Operation<'func, A, M, F, operation::Intrinsic>), - Bp(Operation<'func, A, M, F, operation::NoArgs>), - Trap(Operation<'func, A, M, F, operation::Trap>), - Undef(Operation<'func, A, M, F, operation::NoArgs>), + Syscall(Operation<'func, M, F, operation::Syscall>), + Intrinsic(Operation<'func, M, F, operation::Intrinsic>), + Bp(Operation<'func, M, F, operation::NoArgs>), + Trap(Operation<'func, M, F, operation::Trap>), + Undef(Operation<'func, M, F, operation::NoArgs>), /// The instruction is an expression. - Value(LowLevelILExpression<'func, A, M, F, ValueExpr>), + Value(LowLevelILExpression<'func, M, F, ValueExpr>), } -impl<'func, A, M, F> LowLevelILInstructionKind<'func, A, M, F> +impl<'func, M, F> LowLevelILInstructionKind<'func, M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { pub(crate) unsafe fn from_raw( - function: &'func LowLevelILFunction, + function: &'func LowLevelILFunction, expr_index: LowLevelExpressionIndex, op: BNLowLevelILInstruction, ) -> Self { @@ -315,7 +300,7 @@ where fn visit_sub_expressions(&self, mut visitor: T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, A, M, F, ValueExpr>) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, F, ValueExpr>) -> VisitorAction, { use LowLevelILInstructionKind::*; diff --git a/rust/src/low_level_il/lifting.rs b/rust/src/low_level_il/lifting.rs index 7401c99b..c40f68f2 100644 --- a/rust/src/low_level_il/lifting.rs +++ b/rust/src/low_level_il/lifting.rs @@ -18,35 +18,33 @@ use binaryninjacore_sys::{BNAddLowLevelILLabelForAddress, BNLowLevelILOperation} use binaryninjacore_sys::{BNLowLevelILLabel, BNRegisterOrConstant}; use super::*; -use crate::architecture::Register as ArchReg; use crate::architecture::{Architecture, FlagWriteId, RegisterId}; +use crate::architecture::{CoreRegister, Register as ArchReg}; use crate::architecture::{ Flag, FlagClass, FlagCondition, FlagGroup, FlagRole, FlagWrite, Intrinsic, }; use crate::function::Location; -pub trait LiftableLowLevelIL<'func, A: 'func + Architecture> { +pub trait LiftableLowLevelIL<'func> { type Result: ExpressionResultType; fn lift( - il: &'func MutableLiftedILFunction, + il: &'func MutableLiftedILFunction, expr: Self, - ) -> MutableLiftedILExpr<'func, A, Self::Result>; + ) -> MutableLiftedILExpr<'func, Self::Result>; } -pub trait LiftableLowLevelILWithSize<'func, A: 'func + Architecture>: - LiftableLowLevelIL<'func, A, Result = ValueExpr> -{ +pub trait LiftableLowLevelILWithSize<'func>: LiftableLowLevelIL<'func, Result = ValueExpr> { fn lift_with_size( - il: &'func MutableLiftedILFunction, + il: &'func MutableLiftedILFunction, expr: Self, size: usize, - ) -> MutableLiftedILExpr<'func, A, ValueExpr>; + ) -> MutableLiftedILExpr<'func, ValueExpr>; } #[derive(Copy, Clone)] pub enum LowLevelILRegisterOrConstant { - Register(usize, LowLevelILRegister), + Register(usize, LowLevelILRegisterKind), Constant(usize, u64), } @@ -267,14 +265,9 @@ impl LowLevelILFlagWriteOp { if operand.constant { LowLevelILRegisterOrConstant::Constant(size, operand.value) } else { - let il_reg = if 0x8000_0000 & operand.reg == 0 { - LowLevelILRegister::ArchReg( - arch.register_from_id(RegisterId(operand.reg)).unwrap(), - ) - } else { - LowLevelILRegister::Temp(operand.reg) - }; - + let raw_id = RegisterId(operand.reg); + let il_reg = + LowLevelILRegisterKind::from_raw(arch, raw_id).expect("Bad register ID"); LowLevelILRegisterOrConstant::Register(size, il_reg) } } @@ -466,8 +459,8 @@ pub fn get_default_flag_write_llil<'func, A>( arch: &A, role: FlagRole, op: LowLevelILFlagWriteOp, - il: &'func MutableLiftedILFunction, -) -> MutableLiftedILExpr<'func, A, ValueExpr> + il: &'func MutableLiftedILFunction, +) -> MutableLiftedILExpr<'func, ValueExpr> where A: 'func + Architecture, { @@ -494,8 +487,8 @@ pub fn get_default_flag_cond_llil<'func, A>( arch: &A, cond: FlagCondition, class: Option, - il: &'func MutableLiftedILFunction, -) -> MutableLiftedILExpr<'func, A, ValueExpr> + il: &'func MutableLiftedILFunction, +) -> MutableLiftedILExpr<'func, ValueExpr> where A: 'func + Architecture, { @@ -516,19 +509,19 @@ where macro_rules! prim_int_lifter { ($x:ty) => { - impl<'a, A: 'a + Architecture> LiftableLowLevelIL<'a, A> for $x { + impl<'a> LiftableLowLevelIL<'a> for $x { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, val: Self) - -> MutableLiftedILExpr<'a, A, Self::Result> + fn lift(il: &'a MutableLiftedILFunction, val: Self) + -> MutableLiftedILExpr<'a, Self::Result> { il.const_int(std::mem::size_of::(), val as i64 as u64) } } - impl<'a, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> for $x { - fn lift_with_size(il: &'a MutableLiftedILFunction, val: Self, size: usize) - -> MutableLiftedILExpr<'a, A, ValueExpr> + impl<'a> LiftableLowLevelILWithSize<'a> for $x { + fn lift_with_size(il: &'a MutableLiftedILFunction, val: Self, size: usize) + -> MutableLiftedILExpr<'a, ValueExpr> { let raw = val as i64; @@ -561,57 +554,51 @@ prim_int_lifter!(u16); prim_int_lifter!(u32); prim_int_lifter!(u64); -impl<'a, R: ArchReg, A: 'a + Architecture> LiftableLowLevelIL<'a, A> for LowLevelILRegister +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILRegisterKind where - R: LiftableLowLevelIL<'a, A, Result = ValueExpr> + Into>, + R: LiftableLowLevelIL<'a, Result = ValueExpr> + Into> + ArchReg, { type Result = ValueExpr; - fn lift( - il: &'a MutableLiftedILFunction, - reg: Self, - ) -> MutableLiftedILExpr<'a, A, Self::Result> { + fn lift(il: &'a MutableLiftedILFunction, reg: Self) -> MutableLiftedILExpr<'a, Self::Result> { match reg { - LowLevelILRegister::ArchReg(r) => R::lift(il, r), - LowLevelILRegister::Temp(t) => il.reg( + LowLevelILRegisterKind::Arch(r) => R::lift(il, r), + LowLevelILRegisterKind::Temp(t) => il.reg( il.arch().default_integer_size(), - LowLevelILRegister::Temp(t), + LowLevelILRegisterKind::Temp::(t), ), } } } -impl<'a, R: ArchReg, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> - for LowLevelILRegister +impl<'a, R> LiftableLowLevelILWithSize<'a> for LowLevelILRegisterKind where - R: LiftableLowLevelILWithSize<'a, A> + Into>, + R: LiftableLowLevelILWithSize<'a> + Into> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a MutableLiftedILFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, A, ValueExpr> { + ) -> MutableLiftedILExpr<'a, ValueExpr> { match reg { - LowLevelILRegister::ArchReg(r) => R::lift_with_size(il, r, size), - LowLevelILRegister::Temp(t) => il.reg(size, LowLevelILRegister::Temp(t)), + LowLevelILRegisterKind::Arch(r) => R::lift_with_size(il, r, size), + LowLevelILRegisterKind::Temp(t) => il.reg(size, LowLevelILRegisterKind::::Temp(t)), } } } -impl<'a, R: ArchReg, A: 'a + Architecture> LiftableLowLevelIL<'a, A> - for LowLevelILRegisterOrConstant +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILRegisterOrConstant where - R: LiftableLowLevelILWithSize<'a, A, Result = ValueExpr> + Into>, + R: LiftableLowLevelILWithSize<'a, Result = ValueExpr> + + Into> + + ArchReg, { type Result = ValueExpr; - fn lift( - il: &'a MutableLiftedILFunction, - reg: Self, - ) -> MutableLiftedILExpr<'a, A, Self::Result> { + fn lift(il: &'a MutableLiftedILFunction, reg: Self) -> MutableLiftedILExpr<'a, Self::Result> { match reg { LowLevelILRegisterOrConstant::Register(size, r) => { - LowLevelILRegister::::lift_with_size(il, r, size) + LowLevelILRegisterKind::::lift_with_size(il, r, size) } LowLevelILRegisterOrConstant::Constant(size, value) => { u64::lift_with_size(il, value, size) @@ -620,20 +607,19 @@ where } } -impl<'a, R: ArchReg, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> - for LowLevelILRegisterOrConstant +impl<'a, R> LiftableLowLevelILWithSize<'a> for LowLevelILRegisterOrConstant where - R: LiftableLowLevelILWithSize<'a, A> + Into>, + R: LiftableLowLevelILWithSize<'a> + Into> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a MutableLiftedILFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, A, ValueExpr> { + ) -> MutableLiftedILExpr<'a, ValueExpr> { // TODO ensure requested size is compatible with size of this constant match reg { LowLevelILRegisterOrConstant::Register(_, r) => { - LowLevelILRegister::::lift_with_size(il, r, size) + LowLevelILRegisterKind::::lift_with_size(il, r, size) } LowLevelILRegisterOrConstant::Constant(_, value) => { u64::lift_with_size(il, value, size) @@ -642,31 +628,26 @@ where } } -impl<'a, A, R> LiftableLowLevelIL<'a, A> - for LowLevelILExpression<'a, A, Mutable, NonSSA, R> +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILExpression<'a, Mutable, NonSSA, R> where - A: 'a + Architecture, R: ExpressionResultType, { type Result = R; - fn lift( - il: &'a MutableLiftedILFunction, - expr: Self, - ) -> MutableLiftedILExpr<'a, A, Self::Result> { + fn lift(il: &'a MutableLiftedILFunction, expr: Self) -> MutableLiftedILExpr<'a, Self::Result> { debug_assert!(expr.function.handle == il.handle); expr } } -impl<'a, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> - for LowLevelILExpression<'a, A, Mutable, NonSSA, ValueExpr> +impl<'a> LiftableLowLevelILWithSize<'a> + for LowLevelILExpression<'a, Mutable, NonSSA, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a MutableLiftedILFunction, expr: Self, _size: usize, - ) -> MutableLiftedILExpr<'a, A, Self::Result> { + ) -> MutableLiftedILExpr<'a, Self::Result> { #[cfg(debug_assertions)] { use crate::low_level_il::ExpressionHandler; @@ -686,9 +667,8 @@ impl<'a, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> } } -impl<'func, A, R> LowLevelILExpression<'func, A, Mutable, NonSSA, R> +impl<'func, R> LowLevelILExpression<'func, Mutable, NonSSA, R> where - A: 'func + Architecture, R: ExpressionResultType, { pub fn with_source_operand(self, op: u32) -> Self { @@ -702,12 +682,11 @@ where } } -pub struct ExpressionBuilder<'func, A, R> +pub struct ExpressionBuilder<'func, R> where - A: 'func + Architecture, R: ExpressionResultType, { - function: &'func LowLevelILFunction>, + function: &'func LowLevelILFunction>, op: BNLowLevelILOperation, size: usize, flag_write: FlagWriteId, @@ -718,12 +697,11 @@ where _ty: PhantomData, } -impl<'a, A, R> ExpressionBuilder<'a, A, R> +impl<'a, R> ExpressionBuilder<'a, R> where - A: 'a + Architecture, R: ExpressionResultType, { - pub fn from_expr(expr: LowLevelILExpression<'a, A, Mutable, NonSSA, R>) -> Self { + pub fn from_expr(expr: LowLevelILExpression<'a, Mutable, NonSSA, R>) -> Self { use binaryninjacore_sys::BNGetLowLevelILByIndex; let instr = unsafe { BNGetLowLevelILByIndex(expr.function.handle, expr.index.0) }; @@ -741,13 +719,13 @@ where } } - pub fn with_flag_write(mut self, flag_write: A::FlagWrite) -> Self { + pub fn with_flag_write(mut self, flag_write: impl FlagWrite) -> Self { // TODO verify valid id self.flag_write = flag_write.id(); self } - pub fn build(self) -> LowLevelILExpression<'a, A, Mutable, NonSSA, R> { + pub fn build(self) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { use binaryninjacore_sys::BNLowLevelILAddExpr; let expr_idx = unsafe { @@ -769,7 +747,7 @@ where pub fn with_source_operand( self, op: u32, - ) -> LowLevelILExpression<'a, A, Mutable, NonSSA, R> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { self.build().with_source_operand(op) } @@ -779,32 +757,25 @@ where } } -impl<'a, A, R> LiftableLowLevelIL<'a, A> for ExpressionBuilder<'a, A, R> +impl<'a, R> LiftableLowLevelIL<'a> for ExpressionBuilder<'a, R> where - A: 'a + Architecture, R: ExpressionResultType, { type Result = R; - fn lift( - il: &'a MutableLiftedILFunction, - expr: Self, - ) -> MutableLiftedILExpr<'a, A, Self::Result> { + fn lift(il: &'a MutableLiftedILFunction, expr: Self) -> MutableLiftedILExpr<'a, Self::Result> { debug_assert!(expr.function.handle == il.handle); expr.build() } } -impl<'a, A> LiftableLowLevelILWithSize<'a, A> for ExpressionBuilder<'a, A, ValueExpr> -where - A: 'a + Architecture, -{ +impl<'a> LiftableLowLevelILWithSize<'a> for ExpressionBuilder<'a, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a MutableLiftedILFunction, expr: Self, _size: usize, - ) -> MutableLiftedILExpr<'a, A, ValueExpr> { + ) -> MutableLiftedILExpr<'a, ValueExpr> { #[cfg(debug_assertions)] { use binaryninjacore_sys::BNLowLevelILOperation::{LLIL_UNIMPL, LLIL_UNIMPL_MEM}; @@ -825,7 +796,7 @@ where macro_rules! no_arg_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name(&self) -> LowLevelILExpression, $result> { + pub fn $name(&self) -> LowLevelILExpression, $result> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -838,7 +809,7 @@ macro_rules! no_arg_lifter { macro_rules! sized_no_arg_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name(&self, size: usize) -> ExpressionBuilder { + pub fn $name(&self, size: usize) -> ExpressionBuilder<$result> { use binaryninjacore_sys::BNLowLevelILOperation::$op; ExpressionBuilder { @@ -861,9 +832,9 @@ macro_rules! unsized_unary_op_lifter { pub fn $name<'a, E>( &'a self, expr: E, - ) -> LowLevelILExpression<'a, A, Mutable, NonSSA, $result> + ) -> LowLevelILExpression<'a, Mutable, NonSSA, $result> where - E: LiftableLowLevelIL<'a, A, Result = ValueExpr>, + E: LiftableLowLevelIL<'a, Result = ValueExpr>, { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -881,9 +852,9 @@ macro_rules! unsized_unary_op_lifter { macro_rules! sized_unary_op_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name<'a, E>(&'a self, size: usize, expr: E) -> ExpressionBuilder<'a, A, $result> + pub fn $name<'a, E>(&'a self, size: usize, expr: E) -> ExpressionBuilder<'a, $result> where - E: LiftableLowLevelILWithSize<'a, A>, + E: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -906,9 +877,9 @@ macro_rules! sized_unary_op_lifter { macro_rules! size_changing_unary_op_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name<'a, E>(&'a self, size: usize, expr: E) -> ExpressionBuilder<'a, A, $result> + pub fn $name<'a, E>(&'a self, size: usize, expr: E) -> ExpressionBuilder<'a, $result> where - E: LiftableLowLevelILWithSize<'a, A>, + E: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -936,10 +907,10 @@ macro_rules! binary_op_lifter { size: usize, left: L, right: R, - ) -> ExpressionBuilder<'a, A, ValueExpr> + ) -> ExpressionBuilder<'a, ValueExpr> where - L: LiftableLowLevelILWithSize<'a, A>, - R: LiftableLowLevelILWithSize<'a, A>, + L: LiftableLowLevelILWithSize<'a>, + R: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -969,11 +940,11 @@ macro_rules! binary_op_carry_lifter { left: L, right: R, carry: C, - ) -> ExpressionBuilder<'a, A, ValueExpr> + ) -> ExpressionBuilder<'a, ValueExpr> where - L: LiftableLowLevelILWithSize<'a, A>, - R: LiftableLowLevelILWithSize<'a, A>, - C: LiftableLowLevelILWithSize<'a, A>, + L: LiftableLowLevelILWithSize<'a>, + R: LiftableLowLevelILWithSize<'a>, + C: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -996,21 +967,18 @@ macro_rules! binary_op_carry_lifter { }; } -impl LowLevelILFunction> -where - A: Architecture, -{ - pub const NO_INPUTS: [ExpressionBuilder<'static, A, ValueExpr>; 0] = []; - pub const NO_OUTPUTS: [LowLevelILRegister; 0] = []; +impl LowLevelILFunction> { + pub const NO_INPUTS: [ExpressionBuilder<'static, ValueExpr>; 0] = []; + pub const NO_OUTPUTS: [LowLevelILRegisterKind; 0] = []; - pub fn expression<'a, E: LiftableLowLevelIL<'a, A>>( + pub fn expression<'a, E: LiftableLowLevelIL<'a>>( &'a self, expr: E, - ) -> LowLevelILExpression<'a, A, Mutable, NonSSA, E::Result> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, E::Result> { E::lift(self, expr) } - pub fn add_instruction<'a, E: LiftableLowLevelIL<'a, A>>(&'a self, expr: E) { + pub fn add_instruction<'a, E: LiftableLowLevelIL<'a>>(&'a self, expr: E) { let expr = self.expression(expr); unsafe { @@ -1019,7 +987,7 @@ where } } - pub unsafe fn replace_expression<'a, E: LiftableLowLevelIL<'a, A>>( + pub unsafe fn replace_expression<'a, E: LiftableLowLevelIL<'a>>( &'a self, replaced_expr_index: LowLevelExpressionIndex, replacement: E, @@ -1038,7 +1006,7 @@ where &self, size: usize, val: u64, - ) -> LowLevelILExpression, ValueExpr> { + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST; @@ -1052,7 +1020,7 @@ where &self, size: usize, val: u64, - ) -> LowLevelILExpression, ValueExpr> { + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST_PTR; @@ -1065,14 +1033,11 @@ where pub fn const_ptr( &self, val: u64, - ) -> LowLevelILExpression, ValueExpr> { + ) -> LowLevelILExpression, ValueExpr> { self.const_ptr_sized(self.arch().address_size(), val) } - pub fn trap( - &self, - val: u64, - ) -> LowLevelILExpression, VoidExpr> { + pub fn trap(&self, val: u64) -> LowLevelILExpression, VoidExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_TRAP; @@ -1099,9 +1064,9 @@ where cond: C, true_label: &'b mut LowLevelILLabel, false_label: &'b mut LowLevelILLabel, - ) -> LowLevelILExpression<'a, A, Mutable, NonSSA, VoidExpr> + ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> where - C: LiftableLowLevelIL<'b, A, Result = ValueExpr>, + C: LiftableLowLevelIL<'b, Result = ValueExpr>, { use binaryninjacore_sys::BNLowLevelILIf; @@ -1139,7 +1104,7 @@ where pub fn goto<'a: 'b, 'b>( &'a self, label: &'b mut LowLevelILLabel, - ) -> LowLevelILExpression<'a, A, Mutable, NonSSA, VoidExpr> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> { use binaryninjacore_sys::BNLowLevelILGoto; let mut raw_label = BNLowLevelILLabel::from(*label); @@ -1156,11 +1121,11 @@ where LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn reg>>( + pub fn reg>>( &self, size: usize, - reg: R, - ) -> LowLevelILExpression, ValueExpr> { + reg: LR, + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG; @@ -1173,15 +1138,12 @@ where LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn reg_split< - H: Into>, - L: Into>, - >( + pub fn reg_split>>( &self, size: usize, - hi_reg: H, - lo_reg: L, - ) -> LowLevelILExpression, ValueExpr> { + hi_reg: LR, + lo_reg: LR, + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG_SPLIT; @@ -1205,15 +1167,16 @@ where LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn set_reg<'a, R, E>( + pub fn set_reg<'a, R, LR, E>( &'a self, size: usize, - dest_reg: R, + dest_reg: LR, expr: E, - ) -> ExpressionBuilder<'a, A, VoidExpr> + ) -> ExpressionBuilder<'a, VoidExpr> where - R: Into>, - E: LiftableLowLevelILWithSize<'a, A>, + R: ArchReg, + LR: Into>, + E: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::LLIL_SET_REG; @@ -1236,17 +1199,17 @@ where } } - pub fn set_reg_split<'a, H, L, E>( + pub fn set_reg_split<'a, R, LR, E>( &'a self, size: usize, - hi_reg: H, - lo_reg: L, + hi_reg: LR, + lo_reg: LR, expr: E, - ) -> ExpressionBuilder<'a, A, VoidExpr> + ) -> ExpressionBuilder<'a, VoidExpr> where - H: Into>, - L: Into>, - E: LiftableLowLevelILWithSize<'a, A>, + R: ArchReg, + LR: Into>, + E: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::LLIL_SET_REG_SPLIT; @@ -1260,7 +1223,6 @@ where function: self, op: LLIL_SET_REG_SPLIT, size, - // TODO: Make these optional? flag_write: FlagWriteId(0), op1: hi_reg.0 as u64, op2: lo_reg.0 as u64, @@ -1272,8 +1234,8 @@ where pub fn flag( &self, - flag: A::Flag, - ) -> LowLevelILExpression, ValueExpr> { + flag: impl Flag, + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG; @@ -1288,7 +1250,7 @@ where pub fn flag_cond( &self, cond: FlagCondition, - ) -> LowLevelILExpression, ValueExpr> { + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_COND; @@ -1301,8 +1263,8 @@ where pub fn flag_group( &self, - group: A::FlagGroup, - ) -> LowLevelILExpression, ValueExpr> { + group: impl FlagGroup, + ) -> LowLevelILExpression, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_GROUP; @@ -1325,11 +1287,11 @@ where pub fn set_flag<'a, E>( &'a self, - dest_flag: A::Flag, + dest_flag: impl Flag, expr: E, - ) -> ExpressionBuilder<'a, A, VoidExpr> + ) -> ExpressionBuilder<'a, VoidExpr> where - E: LiftableLowLevelILWithSize<'a, A>, + E: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::LLIL_SET_FLAG; @@ -1355,9 +1317,9 @@ where FlagBit(usize, Flag, u64), */ - pub fn load<'a, E>(&'a self, size: usize, source_mem: E) -> ExpressionBuilder<'a, A, ValueExpr> + pub fn load<'a, E>(&'a self, size: usize, source_mem: E) -> ExpressionBuilder<'a, ValueExpr> where - E: LiftableLowLevelIL<'a, A, Result = ValueExpr>, + E: LiftableLowLevelIL<'a, Result = ValueExpr>, { use binaryninjacore_sys::BNLowLevelILOperation::LLIL_LOAD; @@ -1381,10 +1343,10 @@ where size: usize, dest_mem: D, value: V, - ) -> ExpressionBuilder<'a, A, VoidExpr> + ) -> ExpressionBuilder<'a, VoidExpr> where - D: LiftableLowLevelIL<'a, A, Result = ValueExpr>, - V: LiftableLowLevelILWithSize<'a, A>, + D: LiftableLowLevelIL<'a, Result = ValueExpr>, + V: LiftableLowLevelILWithSize<'a>, { use binaryninjacore_sys::BNLowLevelILOperation::LLIL_STORE; @@ -1404,18 +1366,17 @@ where } } - pub fn intrinsic<'a, O, OL, I, P, PL>( + // TODO: Reposition arguments. + pub fn intrinsic<'a, R, O, P>( &'a self, - outputs: OL, - intrinsic: I, - inputs: PL, - ) -> ExpressionBuilder<'a, A, VoidExpr> + outputs: impl IntoIterator, + intrinsic: impl Intrinsic, + inputs: impl IntoIterator, + ) -> ExpressionBuilder<'a, VoidExpr> where - O: Into>, - OL: IntoIterator, - I: Into, - P: LiftableLowLevelIL<'a, A, Result = ValueExpr>, - PL: IntoIterator, + R: ArchReg, + O: Into>, + P: LiftableLowLevelIL<'a, Result = ValueExpr>, { use binaryninjacore_sys::BNLowLevelILOperation::{LLIL_CALL_PARAM, LLIL_INTRINSIC}; use binaryninjacore_sys::{BNLowLevelILAddExpr, BNLowLevelILAddOperandList}; @@ -1427,8 +1388,6 @@ where let output_expr_idx = unsafe { BNLowLevelILAddOperandList(self.handle, outputs.as_mut_ptr(), outputs.len()) }; - let intrinsic: A::Intrinsic = intrinsic.into(); - let mut inputs: Vec = inputs .into_iter() .map(|input| { diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs index b1bc8ef4..bd68bbb1 100644 --- a/rust/src/low_level_il/operation.rs +++ b/rust/src/low_level_il/operation.rs @@ -15,33 +15,34 @@ use binaryninjacore_sys::{BNGetLowLevelILByIndex, BNLowLevelILInstruction}; use super::*; -use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId}; +use crate::architecture::{ + CoreFlag, CoreFlagGroup, CoreFlagWrite, CoreIntrinsic, CoreRegister, CoreRegisterStack, + FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId, +}; use std::collections::BTreeMap; use std::fmt::{Debug, Formatter}; use std::marker::PhantomData; use std::mem; -pub struct Operation<'func, A, M, F, O> +pub struct Operation<'func, M, F, O> where - A: Architecture, M: FunctionMutability, F: FunctionForm, O: OperationArguments, { - pub(crate) function: &'func LowLevelILFunction, + pub(crate) function: &'func LowLevelILFunction, pub(crate) op: BNLowLevelILInstruction, _args: PhantomData, } -impl<'func, A, M, F, O> Operation<'func, A, M, F, O> +impl<'func, M, F, O> Operation<'func, M, F, O> where - A: Architecture, M: FunctionMutability, F: FunctionForm, O: OperationArguments, { pub(crate) fn new( - function: &'func LowLevelILFunction, + function: &'func LowLevelILFunction, op: BNLowLevelILInstruction, ) -> Self { Self { @@ -56,13 +57,12 @@ where } } -impl Operation<'_, A, M, NonSSA, O> +impl Operation<'_, M, NonSSA, O> where - A: Architecture, M: FunctionMutability, O: OperationArguments, { - pub fn flag_write(&self) -> Option { + pub fn flag_write(&self) -> Option { match self.op.flags { 0 => None, id => self.function.arch().flag_write_from_id(FlagWriteId(id)), @@ -73,9 +73,8 @@ where // LLIL_NOP, LLIL_NORET, LLIL_BP, LLIL_UNDEF, LLIL_UNIMPL pub struct NoArgs; -impl Debug for Operation<'_, A, M, F, NoArgs> +impl Debug for Operation<'_, M, F, NoArgs> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -87,9 +86,8 @@ where // LLIL_POP pub struct Pop; -impl Operation<'_, A, M, F, Pop> +impl Operation<'_, M, F, Pop> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -98,9 +96,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Pop> +impl Debug for Operation<'_, M, F, Pop> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -115,9 +112,8 @@ where // LLIL_SYSCALL, LLIL_SYSCALL_SSA pub struct Syscall; -impl Debug for Operation<'_, A, M, F, Syscall> +impl Debug for Operation<'_, M, F, Syscall> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -129,22 +125,20 @@ where // LLIL_INTRINSIC, LLIL_INTRINSIC_SSA pub struct Intrinsic; -impl Operation<'_, A, M, F, Intrinsic> +impl Operation<'_, M, F, Intrinsic> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { // TODO: Support register and expression lists - pub fn intrinsic(&self) -> Option { + pub fn intrinsic(&self) -> Option { let raw_id = self.op.operands[2] as u32; self.function.arch().intrinsic_from_id(IntrinsicId(raw_id)) } } -impl Debug for Operation<'_, A, M, F, Intrinsic> +impl Debug for Operation<'_, M, F, Intrinsic> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -159,9 +153,8 @@ where // LLIL_SET_REG, LLIL_SET_REG_SSA, LLIL_SET_REG_PARTIAL_SSA pub struct SetReg; -impl<'func, A, M, F> Operation<'func, A, M, F, SetReg> +impl<'func, M, F> Operation<'func, M, F, SetReg> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -169,28 +162,12 @@ where self.op.size } - pub fn dest_reg(&self) -> LowLevelILRegister { - let raw_id = self.op.operands[0] as u32; - - if raw_id >= 0x8000_0000 { - LowLevelILRegister::Temp(raw_id & 0x7fff_ffff) - } else { - self.function - .arch() - .register_from_id(RegisterId(raw_id)) - .map(LowLevelILRegister::ArchReg) - .unwrap_or_else(|| { - log::error!( - "got garbage register from LLIL_SET_REG @ 0x{:x}", - self.op.address - ); - - LowLevelILRegister::Temp(0) - }) - } + pub fn dest_reg(&self) -> LowLevelILRegisterKind { + let raw_id = RegisterId(self.op.operands[0] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } - pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn source_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -198,9 +175,8 @@ where } } -impl Debug for Operation<'_, A, M, F, SetReg> +impl Debug for Operation<'_, M, F, SetReg> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -217,9 +193,8 @@ where // LLIL_SET_REG_SPLIT, LLIL_SET_REG_SPLIT_SSA pub struct SetRegSplit; -impl<'func, A, M, F> Operation<'func, A, M, F, SetRegSplit> +impl<'func, M, F> Operation<'func, M, F, SetRegSplit> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -227,49 +202,17 @@ where self.op.size } - pub fn dest_reg_high(&self) -> LowLevelILRegister { - let raw_id = self.op.operands[0] as u32; - - if raw_id >= 0x8000_0000 { - LowLevelILRegister::Temp(raw_id & 0x7fff_ffff) - } else { - self.function - .arch() - .register_from_id(RegisterId(raw_id)) - .map(LowLevelILRegister::ArchReg) - .unwrap_or_else(|| { - log::error!( - "got garbage register from LLIL_SET_REG_SPLIT @ 0x{:x}", - self.op.address - ); - - LowLevelILRegister::Temp(0) - }) - } + pub fn dest_reg_high(&self) -> LowLevelILRegisterKind { + let raw_id = RegisterId(self.op.operands[0] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } - pub fn dest_reg_low(&self) -> LowLevelILRegister { - let raw_id = self.op.operands[1] as u32; - - if raw_id >= 0x8000_0000 { - LowLevelILRegister::Temp(raw_id & 0x7fff_ffff) - } else { - self.function - .arch() - .register_from_id(RegisterId(raw_id)) - .map(LowLevelILRegister::ArchReg) - .unwrap_or_else(|| { - log::error!( - "got garbage register from LLIL_SET_REG_SPLIT @ 0x{:x}", - self.op.address - ); - - LowLevelILRegister::Temp(0) - }) - } + pub fn dest_reg_low(&self) -> LowLevelILRegisterKind { + let raw_id = RegisterId(self.op.operands[1] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } - pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn source_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[2] as usize), @@ -277,9 +220,8 @@ where } } -impl Debug for Operation<'_, A, M, F, SetRegSplit> +impl Debug for Operation<'_, M, F, SetRegSplit> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -297,13 +239,12 @@ where // LLIL_SET_FLAG, LLIL_SET_FLAG_SSA pub struct SetFlag; -impl<'func, A, M, F> Operation<'func, A, M, F, SetFlag> +impl<'func, M, F> Operation<'func, M, F, SetFlag> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn dest_flag(&self) -> A::Flag { + pub fn dest_flag(&self) -> CoreFlag { // TODO: Error handling? // TODO: Test this. self.function @@ -312,7 +253,7 @@ where .unwrap() } - pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn source_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -320,9 +261,8 @@ where } } -impl Debug for Operation<'_, A, M, F, SetFlag> +impl Debug for Operation<'_, M, F, SetFlag> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -338,9 +278,8 @@ where // LLIL_LOAD, LLIL_LOAD_SSA pub struct Load; -impl<'func, A, M, F> Operation<'func, A, M, F, Load> +impl<'func, M, F> Operation<'func, M, F, Load> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -348,7 +287,7 @@ where self.op.size } - pub fn source_mem_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn source_mem_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -356,9 +295,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Load> +impl Debug for Operation<'_, M, F, Load> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -374,9 +312,8 @@ where // LLIL_STORE, LLIL_STORE_SSA pub struct Store; -impl<'func, A, M, F> Operation<'func, A, M, F, Store> +impl<'func, M, F> Operation<'func, M, F, Store> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -384,14 +321,14 @@ where self.op.size } - pub fn dest_mem_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn dest_mem_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), ) } - pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn source_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -399,9 +336,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Store> +impl Debug for Operation<'_, M, F, Store> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -415,12 +351,11 @@ where } } -// LLIL_REG, LLIL_REG_SSA, LLIL_REG_SSA_PARTIAL +// LLIL_REG, LLIL_REG_SSLLIL_REG_SSA_PARTIAL pub struct Reg; -impl Operation<'_, A, M, F, Reg> +impl Operation<'_, M, F, Reg> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -428,31 +363,14 @@ where self.op.size } - pub fn source_reg(&self) -> LowLevelILRegister { - let raw_id = self.op.operands[0] as u32; - - if raw_id >= 0x8000_0000 { - LowLevelILRegister::Temp(raw_id & 0x7fff_ffff) - } else { - self.function - .arch() - .register_from_id(RegisterId(raw_id)) - .map(LowLevelILRegister::ArchReg) - .unwrap_or_else(|| { - log::error!( - "got garbage register from LLIL_REG @ 0x{:x}", - self.op.address - ); - - LowLevelILRegister::Temp(0) - }) - } + pub fn source_reg(&self) -> LowLevelILRegisterKind { + let raw_id = RegisterId(self.op.operands[0] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } } -impl Debug for Operation<'_, A, M, F, Reg> +impl Debug for Operation<'_, M, F, Reg> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -468,9 +386,8 @@ where // LLIL_REG_SPLIT, LLIL_REG_SPLIT_SSA pub struct RegSplit; -impl Operation<'_, A, M, F, RegSplit> +impl Operation<'_, M, F, RegSplit> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -478,52 +395,19 @@ where self.op.size } - pub fn low_reg(&self) -> LowLevelILRegister { - let raw_id = self.op.operands[0] as u32; - - if raw_id >= 0x8000_0000 { - LowLevelILRegister::Temp(raw_id & 0x7fff_ffff) - } else { - self.function - .arch() - .register_from_id(RegisterId(raw_id)) - .map(LowLevelILRegister::ArchReg) - .unwrap_or_else(|| { - log::error!( - "got garbage register from LLIL_REG @ 0x{:x}", - self.op.address - ); - - LowLevelILRegister::Temp(0) - }) - } + pub fn low_reg(&self) -> LowLevelILRegisterKind { + let raw_id = RegisterId(self.op.operands[0] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } - pub fn high_reg(&self) -> LowLevelILRegister { - let raw_id = self.op.operands[1] as u32; - - if raw_id >= 0x8000_0000 { - LowLevelILRegister::Temp(raw_id & 0x7fff_ffff) - } else { - self.function - .arch() - .register_from_id(RegisterId(raw_id)) - .map(LowLevelILRegister::ArchReg) - .unwrap_or_else(|| { - log::error!( - "got garbage register from LLIL_REG @ 0x{:x}", - self.op.address - ); - - LowLevelILRegister::Temp(0) - }) - } + pub fn high_reg(&self) -> LowLevelILRegisterKind { + let raw_id = RegisterId(self.op.operands[1] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } } -impl Debug for Operation<'_, A, M, F, RegSplit> +impl Debug for Operation<'_, M, F, RegSplit> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -540,9 +424,8 @@ where // LLIL_REG_STACK_PUSH pub struct RegStackPush; -impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPush> +impl<'func, M, F> Operation<'func, M, F, RegStackPush> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -550,7 +433,7 @@ where self.op.size } - pub fn dest_reg_stack(&self) -> A::RegisterStack { + pub fn dest_reg_stack(&self) -> CoreRegisterStack { let raw_id = self.op.operands[0] as u32; self.function .arch() @@ -558,7 +441,7 @@ where .expect("Bad register stack ID") } - pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn source_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -566,9 +449,8 @@ where } } -impl Debug for Operation<'_, A, M, F, RegStackPush> +impl Debug for Operation<'_, M, F, RegStackPush> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -585,9 +467,8 @@ where // LLIL_REG_STACK_POP pub struct RegStackPop; -impl Operation<'_, A, M, F, RegStackPop> +impl Operation<'_, M, F, RegStackPop> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -595,7 +476,7 @@ where self.op.size } - pub fn source_reg_stack(&self) -> A::RegisterStack { + pub fn source_reg_stack(&self) -> CoreRegisterStack { let raw_id = self.op.operands[0] as u32; self.function .arch() @@ -604,9 +485,8 @@ where } } -impl Debug for Operation<'_, A, M, F, RegStackPop> +impl Debug for Operation<'_, M, F, RegStackPop> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -622,9 +502,8 @@ where // LLIL_FLAG, LLIL_FLAG_SSA pub struct Flag; -impl Debug for Operation<'_, A, M, F, Flag> +impl Debug for Operation<'_, M, F, Flag> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -636,9 +515,8 @@ where // LLIL_FLAG_BIT, LLIL_FLAG_BIT_SSA pub struct FlagBit; -impl Debug for Operation<'_, A, M, F, FlagBit> +impl Debug for Operation<'_, M, F, FlagBit> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -650,13 +528,12 @@ where // LLIL_JUMP pub struct Jump; -impl<'func, A, M, F> Operation<'func, A, M, F, Jump> +impl<'func, M, F> Operation<'func, M, F, Jump> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn target(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn target(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -664,9 +541,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Jump> +impl Debug for Operation<'_, M, F, Jump> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -680,20 +556,18 @@ where // LLIL_JUMP_TO pub struct JumpTo; -struct TargetListIter<'func, A, M, F> +struct TargetListIter<'func, M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - function: &'func LowLevelILFunction, + function: &'func LowLevelILFunction, cursor: BNLowLevelILInstruction, cursor_operand: usize, } -impl TargetListIter<'_, A, M, F> +impl TargetListIter<'_, M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -710,13 +584,12 @@ where } } -impl<'func, A, M, F> Operation<'func, A, M, F, JumpTo> +impl<'func, M, F> Operation<'func, M, F, JumpTo> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn target(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn target(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -744,9 +617,8 @@ where } } -impl Debug for Operation<'_, A, M, F, JumpTo> +impl Debug for Operation<'_, M, F, JumpTo> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -761,13 +633,12 @@ where // LLIL_CALL, LLIL_CALL_SSA pub struct Call; -impl<'func, A, M, F> Operation<'func, A, M, F, Call> +impl<'func, M, F> Operation<'func, M, F, Call> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn target(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn target(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -785,9 +656,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Call> +impl Debug for Operation<'_, M, F, Call> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -802,13 +672,12 @@ where // LLIL_RET pub struct Ret; -impl<'func, A, M, F> Operation<'func, A, M, F, Ret> +impl<'func, M, F> Operation<'func, M, F, Ret> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn target(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn target(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -816,9 +685,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Ret> +impl Debug for Operation<'_, M, F, Ret> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -832,27 +700,26 @@ where // LLIL_IF pub struct If; -impl<'func, A, M, F> Operation<'func, A, M, F, If> +impl<'func, M, F> Operation<'func, M, F, If> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn condition(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn condition(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), ) } - pub fn true_target(&self) -> LowLevelILInstruction<'func, A, M, F> { + pub fn true_target(&self) -> LowLevelILInstruction<'func, M, F> { LowLevelILInstruction::new( self.function, LowLevelInstructionIndex(self.op.operands[1] as usize), ) } - pub fn false_target(&self) -> LowLevelILInstruction<'func, A, M, F> { + pub fn false_target(&self) -> LowLevelILInstruction<'func, M, F> { LowLevelILInstruction::new( self.function, LowLevelInstructionIndex(self.op.operands[2] as usize), @@ -860,9 +727,8 @@ where } } -impl Debug for Operation<'_, A, M, F, If> +impl Debug for Operation<'_, M, F, If> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -878,13 +744,12 @@ where // LLIL_GOTO pub struct Goto; -impl<'func, A, M, F> Operation<'func, A, M, F, Goto> +impl<'func, M, F> Operation<'func, M, F, Goto> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { - pub fn target(&self) -> LowLevelILInstruction<'func, A, M, F> { + pub fn target(&self) -> LowLevelILInstruction<'func, M, F> { LowLevelILInstruction::new( self.function, LowLevelInstructionIndex(self.op.operands[0] as usize), @@ -892,9 +757,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Goto> +impl Debug for Operation<'_, M, F, Goto> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -909,9 +773,8 @@ where // Valid only in Lifted IL pub struct FlagCond; -impl Debug for Operation<'_, A, M, F, FlagCond> +impl Debug for Operation<'_, M, F, FlagCond> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -924,12 +787,11 @@ where // Valid only in Lifted IL pub struct FlagGroup; -impl Operation<'_, A, M, NonSSA, FlagGroup> +impl Operation<'_, M, NonSSA, FlagGroup> where - A: Architecture, M: FunctionMutability, { - pub fn flag_group(&self) -> A::FlagGroup { + pub fn flag_group(&self) -> CoreFlagGroup { let id = self.op.operands[0] as u32; self.function .arch() @@ -938,9 +800,8 @@ where } } -impl Debug for Operation<'_, A, M, NonSSA, FlagGroup> +impl Debug for Operation<'_, M, NonSSA, FlagGroup> where - A: Architecture, M: FunctionMutability, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -950,9 +811,8 @@ where } } -impl Debug for Operation<'_, A, M, SSA, FlagGroup> +impl Debug for Operation<'_, M, SSA, FlagGroup> where - A: Architecture, M: FunctionMutability, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -963,9 +823,8 @@ where // LLIL_TRAP pub struct Trap; -impl Operation<'_, A, M, F, Trap> +impl Operation<'_, M, F, Trap> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -974,9 +833,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Trap> +impl Debug for Operation<'_, M, F, Trap> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -990,9 +848,8 @@ where // LLIL_REG_PHI pub struct RegPhi; -impl Debug for Operation<'_, A, M, F, RegPhi> +impl Debug for Operation<'_, M, F, RegPhi> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1004,9 +861,8 @@ where // LLIL_FLAG_PHI pub struct FlagPhi; -impl Debug for Operation<'_, A, M, F, FlagPhi> +impl Debug for Operation<'_, M, F, FlagPhi> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1018,9 +874,8 @@ where // LLIL_MEM_PHI pub struct MemPhi; -impl Debug for Operation<'_, A, M, F, MemPhi> +impl Debug for Operation<'_, M, F, MemPhi> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1032,9 +887,8 @@ where // LLIL_CONST, LLIL_CONST_PTR pub struct Const; -impl Operation<'_, A, M, F, Const> +impl Operation<'_, M, F, Const> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1073,9 +927,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Const> +impl Debug for Operation<'_, M, F, Const> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1090,9 +943,8 @@ where // LLIL_EXTERN_PTR pub struct Extern; -impl Operation<'_, A, M, F, Extern> +impl Operation<'_, M, F, Extern> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1131,9 +983,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Extern> +impl Debug for Operation<'_, M, F, Extern> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1152,9 +1003,8 @@ where // LLIL_MODS pub struct BinaryOp; -impl<'func, A, M, F> Operation<'func, A, M, F, BinaryOp> +impl<'func, M, F> Operation<'func, M, F, BinaryOp> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1162,14 +1012,14 @@ where self.op.size } - pub fn left(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn left(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), ) } - pub fn right(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn right(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -1177,9 +1027,8 @@ where } } -impl Debug for Operation<'_, A, M, F, BinaryOp> +impl Debug for Operation<'_, M, F, BinaryOp> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1195,9 +1044,8 @@ where // LLIL_ADC, LLIL_SBB, LLIL_RLC, LLIL_RRC pub struct BinaryOpCarry; -impl<'func, A, M, F> Operation<'func, A, M, F, BinaryOpCarry> +impl<'func, M, F> Operation<'func, M, F, BinaryOpCarry> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1205,21 +1053,21 @@ where self.op.size } - pub fn left(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn left(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), ) } - pub fn right(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn right(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), ) } - pub fn carry(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn carry(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[2] as usize), @@ -1227,9 +1075,8 @@ where } } -impl Debug for Operation<'_, A, M, F, BinaryOpCarry> +impl Debug for Operation<'_, M, F, BinaryOpCarry> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1246,9 +1093,8 @@ where // LLIL_DIVS_DP, LLIL_DIVU_DP, LLIL_MODU_DP, LLIL_MODS_DP pub struct DoublePrecDivOp; -impl<'func, A, M, F> Operation<'func, A, M, F, DoublePrecDivOp> +impl<'func, M, F> Operation<'func, M, F, DoublePrecDivOp> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1256,14 +1102,14 @@ where self.op.size } - pub fn high(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn high(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), ) } - pub fn low(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn low(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -1271,7 +1117,7 @@ where } // TODO: I don't think this actually exists? - pub fn right(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn right(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[2] as usize), @@ -1279,9 +1125,8 @@ where } } -impl Debug for Operation<'_, A, M, F, DoublePrecDivOp> +impl Debug for Operation<'_, M, F, DoublePrecDivOp> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1300,9 +1145,8 @@ where // LLIL_ZX, LLIL_LOW_PART, LLIL_BOOL_TO_INT, LLIL_UNIMPL_MEM pub struct UnaryOp; -impl<'func, A, M, F> Operation<'func, A, M, F, UnaryOp> +impl<'func, M, F> Operation<'func, M, F, UnaryOp> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1310,7 +1154,7 @@ where self.op.size } - pub fn operand(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn operand(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -1318,9 +1162,8 @@ where } } -impl Debug for Operation<'_, A, M, F, UnaryOp> +impl Debug for Operation<'_, M, F, UnaryOp> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1335,9 +1178,8 @@ where // LLIL_CMP_X pub struct Condition; -impl<'func, A, M, F> Operation<'func, A, M, F, Condition> +impl<'func, M, F> Operation<'func, M, F, Condition> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1345,14 +1187,14 @@ where self.op.size } - pub fn left(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn left(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), ) } - pub fn right(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn right(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[1] as usize), @@ -1360,9 +1202,8 @@ where } } -impl Debug for Operation<'_, A, M, F, Condition> +impl Debug for Operation<'_, M, F, Condition> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1378,9 +1219,8 @@ where // LLIL_UNIMPL_MEM pub struct UnimplMem; -impl<'func, A, M, F> Operation<'func, A, M, F, UnimplMem> +impl<'func, M, F> Operation<'func, M, F, UnimplMem> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1388,7 +1228,7 @@ where self.op.size } - pub fn mem_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> { + pub fn mem_expr(&self) -> LowLevelILExpression<'func, M, F, ValueExpr> { LowLevelILExpression::new( self.function, LowLevelExpressionIndex(self.op.operands[0] as usize), @@ -1396,9 +1236,8 @@ where } } -impl Debug for Operation<'_, A, M, F, UnimplMem> +impl Debug for Operation<'_, M, F, UnimplMem> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { diff --git a/rust/src/relocation.rs b/rust/src/relocation.rs index 8fa9a86b..f10115c8 100644 --- a/rust/src/relocation.rs +++ b/rust/src/relocation.rs @@ -83,7 +83,7 @@ impl From for usize { } // TODO: How to handle related relocation linked lists? -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct RelocationInfo { pub type_: RelocationType, pub pc_relative: bool, @@ -265,7 +265,7 @@ pub trait RelocationHandler: 'static + Sized + AsRef { _data: &[u8], _addr: u64, // TODO: Are we sure this is not a liftedilfunction? - _il: &RegularLowLevelILFunction, + _il: &RegularLowLevelILFunction, _reloc: &Relocation, ) -> RelocationOperand { RelocationOperand::AutocoerceExternPtr @@ -363,7 +363,7 @@ impl RelocationHandler for CoreRelocationHandler { &self, data: &[u8], addr: u64, - il: &RegularLowLevelILFunction, + il: &RegularLowLevelILFunction, reloc: &Relocation, ) -> RelocationOperand { unsafe { @@ -496,7 +496,7 @@ where return RelocationOperand::Invalid.into(); } let arch = unsafe { CoreArchitecture::from_raw(arch) }; - let il = unsafe { RegularLowLevelILFunction::from_raw(arch, il) }; + let il = unsafe { RegularLowLevelILFunction::from_raw_with_arch(il, Some(arch)) }; custom_handler .get_operand_for_external_relocation(data, addr, &il, &reloc) diff --git a/rust/src/workflow.rs b/rust/src/workflow.rs index b9c67a5d..ca42ff68 100644 --- a/rust/src/workflow.rs +++ b/rust/src/workflow.rs @@ -1,8 +1,5 @@ use binaryninjacore_sys::*; -use std::ffi::{c_char, c_void}; -use std::ptr::NonNull; -use crate::architecture::CoreArchitecture; use crate::basic_block::BasicBlock; use crate::binary_view::BinaryView; use crate::flowgraph::FlowGraph; @@ -13,6 +10,8 @@ use crate::low_level_il::MutableLiftedILFunction; use crate::medium_level_il::MediumLevelILFunction; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::string::{BnStrCompatible, BnString}; +use std::ffi::{c_char, c_void}; +use std::ptr::NonNull; #[repr(transparent)] /// The AnalysisContext struct is used to represent the current state of @@ -47,21 +46,17 @@ impl AnalysisContext { } /// [`LowLevelILFunction`] used to represent Low Level IL - pub unsafe fn lifted_il_function( - &self, - ) -> Option>> { + pub unsafe fn lifted_il_function(&self) -> Option> { let func = self.function(); let result = unsafe { BNGetFunctionLiftedIL(func.handle) }; - let arch = self.function().arch(); unsafe { Some(LowLevelILFunction::ref_from_raw( - arch, NonNull::new(result)?.as_ptr(), )) } } - pub fn set_lifted_il_function(&self, value: &MutableLiftedILFunction) { + pub fn set_lifted_il_function(&self, value: &MutableLiftedILFunction) { unsafe { BNSetLiftedILFunction(self.handle.as_ptr(), value.handle) } } @@ -70,12 +65,10 @@ impl AnalysisContext { /// [`LowLevelILFunction`] used to represent Low Level IL pub unsafe fn llil_function( &self, - ) -> Option>>> { + ) -> Option>>> { let result = unsafe { BNAnalysisContextGetLowLevelILFunction(self.handle.as_ptr()) }; - let arch = self.function().arch(); unsafe { Some(LowLevelILFunction::ref_from_raw( - arch, NonNull::new(result)?.as_ptr(), )) } @@ -85,7 +78,7 @@ impl AnalysisContext { // TODO: At some point we need to take the lifting code and make it available to regular IL. pub fn set_llil_function( &self, - value: &LowLevelILFunction>, + value: &LowLevelILFunction>, ) { unsafe { BNSetLowLevelILFunction(self.handle.as_ptr(), value.handle) } } -- cgit v1.3.1