diff options
| author | Mason Reed <mason@vector35.com> | 2025-04-30 17:38:40 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-05-12 17:45:24 -0400 |
| commit | c3fdda9727f5507818e3f55576ad32215a22b0f9 (patch) | |
| tree | d522025055eb7253c7f2cb94732402aacf2afbfc /rust/src/low_level_il | |
| parent | c3f344a38ca4b027b4e69b0f82d3184622d6da79 (diff) | |
[Rust] Remove Architecture trait bound on LLIL related structures
Diffstat (limited to 'rust/src/low_level_il')
| -rw-r--r-- | rust/src/low_level_il/block.rs | 33 | ||||
| -rw-r--r-- | rust/src/low_level_il/expression.rs | 251 | ||||
| -rw-r--r-- | rust/src/low_level_il/function.rs | 86 | ||||
| -rw-r--r-- | rust/src/low_level_il/instruction.rs | 103 | ||||
| -rw-r--r-- | rust/src/low_level_il/lifting.rs | 309 | ||||
| -rw-r--r-- | rust/src/low_level_il/operation.rs | 415 |
6 files changed, 472 insertions, 725 deletions
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<A, M, F>, + pub(crate) function: &'func LowLevelILFunction<M, F>, } -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<Self>) -> LowLevelILInstruction<'func, A, M, F> { + fn start(&self, block: &BasicBlock<Self>) -> LowLevelILInstruction<'func, M, F> { self.function .instruction_from_index(block.start_index()) .unwrap() } - fn iter(&self, block: &BasicBlock<Self>) -> LowLevelILBlockIter<'func, A, M, F> { + fn iter(&self, block: &BasicBlock<Self>) -> 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<A, M, F>, + function: &'func LowLevelILFunction<M, F>, // TODO: Once step_trait is stable we can do Range<InstructionIndex> range: Range<usize>, } -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::Item> { 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<T>(&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<A, M, F>, + pub(crate) function: &'func LowLevelILFunction<M, F>, pub index: LowLevelExpressionIndex, // tag the 'return' type of this expression pub(crate) _ty: PhantomData<R>, } -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<A, M, F>, + function: &'func LowLevelILFunction<M, F>, 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<T>(&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<LiftedNonSSA>> - for LowLevelILExpression<'func, A, M, NonSSA<LiftedNonSSA>, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, NonSSA<LiftedNonSSA>> + for LowLevelILExpression<'func, M, NonSSA<LiftedNonSSA>, ValueExpr> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, A, M, NonSSA<LiftedNonSSA>> { + fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA<LiftedNonSSA>> { #[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<T>(&self, f: &mut T) -> VisitorAction where - T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA<LiftedNonSSA>, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA<LiftedNonSSA>, ValueExpr>) -> VisitorAction, { // Visit the current expression. match f(self) { @@ -176,13 +168,12 @@ where } } -impl<'func, A, M> ExpressionHandler<'func, A, M, NonSSA<RegularNonSSA>> - for LowLevelILExpression<'func, A, M, NonSSA<RegularNonSSA>, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, NonSSA<RegularNonSSA>> + for LowLevelILExpression<'func, M, NonSSA<RegularNonSSA>, ValueExpr> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, A, M, NonSSA<RegularNonSSA>> { + fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA<RegularNonSSA>> { 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<T>(&self, f: &mut T) -> VisitorAction where T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA<RegularNonSSA>, ValueExpr>, + &LowLevelILExpression<'func, M, NonSSA<RegularNonSSA>, 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>), + 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, A, M, F, operation::RegStackPop>), + RegStackPop(Operation<'func, 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>), + 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, A, M, F, operation::BinaryOp>), - MuluDp(Operation<'func, A, M, F, operation::BinaryOp>), + MulsDp(Operation<'func, M, F, operation::BinaryOp>), + MuluDp(Operation<'func, M, F, operation::BinaryOp>), - Divu(Operation<'func, A, M, F, operation::BinaryOp>), - Divs(Operation<'func, A, M, F, operation::BinaryOp>), + Divu(Operation<'func, M, F, operation::BinaryOp>), + Divs(Operation<'func, M, F, operation::BinaryOp>), - DivuDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), - DivsDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), + DivuDp(Operation<'func, M, F, operation::DoublePrecDivOp>), + DivsDp(Operation<'func, M, F, operation::DoublePrecDivOp>), - Modu(Operation<'func, A, M, F, operation::BinaryOp>), - Mods(Operation<'func, A, M, F, operation::BinaryOp>), + Modu(Operation<'func, M, F, operation::BinaryOp>), + Mods(Operation<'func, M, F, operation::BinaryOp>), - ModuDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), - ModsDp(Operation<'func, A, M, F, operation::DoublePrecDivOp>), + ModuDp(Operation<'func, M, F, operation::DoublePrecDivOp>), + ModsDp(Operation<'func, 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>), + 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<LiftedNonSSA>, operation::FlagCond>), + FlagCond(Operation<'func, M, NonSSA<LiftedNonSSA>, operation::FlagCond>), // Valid only in Lifted IL - FlagGroup(Operation<'func, A, M, NonSSA<LiftedNonSSA>, operation::FlagGroup>), + FlagGroup(Operation<'func, M, NonSSA<LiftedNonSSA>, 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>), + 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, A, M, F, operation::TestBit>), // TODO - BoolToInt(Operation<'func, A, M, F, operation::UnaryOp>), + //TestBit(Operation<'func, M, F, operation::TestBit>), // TODO + BoolToInt(Operation<'func, 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>), + 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, 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>), + 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<A, M, F>, + function: &'func LowLevelILFunction<M, F>, 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<T>(&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<LiftedNonSSA>> -where - A: 'func + Architecture, -{ - pub fn flag_write(&self) -> Option<A::FlagWrite> { +impl<'func> LowLevelILExpressionKind<'func, Mutable, NonSSA<LiftedNonSSA>> { + pub fn flag_write(&self) -> Option<CoreFlagWrite> { 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<V: NonSSAVariant> FunctionForm for NonSSA<V> {} -pub struct LowLevelILFunction<A: Architecture, M: FunctionMutability, F: FunctionForm> { - pub(crate) arch_handle: A::Handle, +pub struct LowLevelILFunction<M: FunctionMutability, F: FunctionForm> { pub(crate) handle: *mut BNLowLevelILFunction, - _arch: PhantomData<*mut A>, + arch: Option<CoreArchitecture>, _mutability: PhantomData<M>, _form: PhantomData<F>, } -impl<A, M, F> LowLevelILFunction<A, M, F> +impl<M, F> LowLevelILFunction<M, F> 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<CoreArchitecture>, ) -> 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<CoreArchitecture>, ) -> Ref<Self> { 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> { + Self::ref_from_raw_with_arch(handle, None) } - pub fn instruction_at<L: Into<Location>>( - &self, - loc: L, - ) -> Option<LowLevelILInstruction<A, M, F>> { + pub(crate) fn arch(&self) -> CoreArchitecture { + match self.arch { + None => self.function().arch(), + Some(arch) => arch, + } + } + + pub fn instruction_at<L: Into<Location>>(&self, loc: L) -> Option<LowLevelILInstruction<M, F>> { Some(LowLevelILInstruction::new( self, self.instruction_index_at(loc)?, @@ -128,7 +132,7 @@ where pub fn instruction_from_index( &self, index: LowLevelInstructionIndex, - ) -> Option<LowLevelILInstruction<A, M, F>> { + ) -> Option<LowLevelILInstruction<M, F>> { 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<A, F> LowLevelILFunction<A, Finalized, F> -where - A: Architecture, - F: FunctionForm, -{ - pub fn basic_blocks(&self) -> Array<BasicBlock<LowLevelILBlock<A, Finalized, F>>> { +impl<F: FunctionForm> LowLevelILFunction<Finalized, F> { + pub fn basic_blocks(&self) -> Array<BasicBlock<LowLevelILBlock<Finalized, F>>> { use binaryninjacore_sys::BNGetLowLevelILBasicBlockList; unsafe { @@ -179,7 +179,7 @@ where } // Allow instantiating Lifted IL functions for querying Lifted IL from Architectures -impl LowLevelILFunction<CoreArchitecture, Mutable, NonSSA<LiftedNonSSA>> { +impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { // 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<CoreArchitecture, Mutable, NonSSA<LiftedNonSSA>> { // 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<CoreArchitecture, Mutable, NonSSA<LiftedNonSSA>> { } } -impl<A, M, F> ToOwned for LowLevelILFunction<A, M, F> +impl<M, F> ToOwned for LowLevelILFunction<M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -219,17 +218,15 @@ where } } -unsafe impl<A, M, F> RefCountable for LowLevelILFunction<A, M, F> +unsafe impl<M, F> RefCountable for LowLevelILFunction<M, F> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { unsafe fn inc_ref(handle: &Self) -> Ref<Self> { 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<A, M, F> Debug for LowLevelILFunction<A, M, F> +impl<M, F> Debug for LowLevelILFunction<M, F> where - A: Architecture + Debug, M: FunctionMutability, F: FunctionForm, { @@ -255,26 +251,18 @@ where } } -unsafe impl<A: Architecture, M: FunctionMutability, F: FunctionForm> Send - for LowLevelILFunction<A, M, F> -{ -} -unsafe impl<A: Architecture, M: FunctionMutability, F: FunctionForm> Sync - for LowLevelILFunction<A, M, F> -{ -} +unsafe impl<M: FunctionMutability, F: FunctionForm> Send for LowLevelILFunction<M, F> {} +unsafe impl<M: FunctionMutability, F: FunctionForm> Sync for LowLevelILFunction<M, F> {} -impl<A: Architecture, M: FunctionMutability, F: FunctionForm> Eq for LowLevelILFunction<A, M, F> {} +impl<M: FunctionMutability, F: FunctionForm> Eq for LowLevelILFunction<M, F> {} -impl<A: Architecture, M: FunctionMutability, F: FunctionForm> PartialEq - for LowLevelILFunction<A, M, F> -{ +impl<M: FunctionMutability, F: FunctionForm> PartialEq for LowLevelILFunction<M, F> { fn eq(&self, rhs: &Self) -> bool { self.function().eq(&rhs.function()) } } -impl<A: Architecture, M: FunctionMutability, F: FunctionForm> Hash for LowLevelILFunction<A, M, F> { +impl<M: FunctionMutability, F: FunctionForm> Hash for LowLevelILFunction<M, F> { fn hash<H: Hasher>(&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<T>(&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<A, M, F>, + pub(crate) function: &'func LowLevelILFunction<M, F>, 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<Self> methinks - pub fn new( - function: &'func LowLevelILFunction<A, M, F>, - index: LowLevelInstructionIndex, - ) -> Self { + pub fn new(function: &'func LowLevelILFunction<M, F>, 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<T>(&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<LiftedNonSSA>> - for LowLevelILInstruction<'func, A, M, NonSSA<LiftedNonSSA>> +impl<'func, M> InstructionHandler<'func, M, NonSSA<LiftedNonSSA>> + for LowLevelILInstruction<'func, M, NonSSA<LiftedNonSSA>> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, A, M, NonSSA<LiftedNonSSA>> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA<LiftedNonSSA>> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -172,22 +162,19 @@ where fn visit_tree<T>(&self, f: &mut T) -> VisitorAction where - T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA<LiftedNonSSA>, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA<LiftedNonSSA>, 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<RegularNonSSA>> - for LowLevelILInstruction<'func, A, M, NonSSA<RegularNonSSA>> +impl<'func, M> InstructionHandler<'func, M, NonSSA<RegularNonSSA>> + for LowLevelILInstruction<'func, M, NonSSA<RegularNonSSA>> where - A: 'func + Architecture, M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, A, M, NonSSA<RegularNonSSA>> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA<RegularNonSSA>> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -204,7 +191,7 @@ where fn visit_tree<T>(&self, f: &mut T) -> VisitorAction where T: FnMut( - &LowLevelILExpression<'func, A, M, NonSSA<RegularNonSSA>, ValueExpr>, + &LowLevelILExpression<'func, M, NonSSA<RegularNonSSA>, 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<A, M, F>, + function: &'func LowLevelILFunction<M, F>, expr_index: LowLevelExpressionIndex, op: BNLowLevelILInstruction, ) -> Self { @@ -315,7 +300,7 @@ where fn visit_sub_expressions<T>(&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<A>, + 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<A>, + il: &'func MutableLiftedILFunction, expr: Self, size: usize, - ) -> MutableLiftedILExpr<'func, A, ValueExpr>; + ) -> MutableLiftedILExpr<'func, ValueExpr>; } #[derive(Copy, Clone)] pub enum LowLevelILRegisterOrConstant<R: ArchReg> { - Register(usize, LowLevelILRegister<R>), + Register(usize, LowLevelILRegisterKind<R>), Constant(usize, u64), } @@ -267,14 +265,9 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { 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<A::Register>, - il: &'func MutableLiftedILFunction<A>, -) -> 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<A::FlagClass>, - il: &'func MutableLiftedILFunction<A>, -) -> 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<A>, 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::<Self>(), val as i64 as u64) } } - impl<'a, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> for $x { - fn lift_with_size(il: &'a MutableLiftedILFunction<A>, 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<R> +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILRegisterKind<R> where - R: LiftableLowLevelIL<'a, A, Result = ValueExpr> + Into<LowLevelILRegister<R>>, + R: LiftableLowLevelIL<'a, Result = ValueExpr> + Into<LowLevelILRegisterKind<R>> + ArchReg, { type Result = ValueExpr; - fn lift( - il: &'a MutableLiftedILFunction<A>, - 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::<R>(t), ), } } } -impl<'a, R: ArchReg, A: 'a + Architecture> LiftableLowLevelILWithSize<'a, A> - for LowLevelILRegister<R> +impl<'a, R> LiftableLowLevelILWithSize<'a> for LowLevelILRegisterKind<R> where - R: LiftableLowLevelILWithSize<'a, A> + Into<LowLevelILRegister<R>>, + R: LiftableLowLevelILWithSize<'a> + Into<LowLevelILRegisterKind<R>> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction<A>, + 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::<R>::Temp(t)), } } } -impl<'a, R: ArchReg, A: 'a + Architecture> LiftableLowLevelIL<'a, A> - for LowLevelILRegisterOrConstant<R> +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILRegisterOrConstant<R> where - R: LiftableLowLevelILWithSize<'a, A, Result = ValueExpr> + Into<LowLevelILRegister<R>>, + R: LiftableLowLevelILWithSize<'a, Result = ValueExpr> + + Into<LowLevelILRegisterKind<R>> + + ArchReg, { type Result = ValueExpr; - fn lift( - il: &'a MutableLiftedILFunction<A>, - 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::<R>::lift_with_size(il, r, size) + LowLevelILRegisterKind::<R>::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<R> +impl<'a, R> LiftableLowLevelILWithSize<'a> for LowLevelILRegisterOrConstant<R> where - R: LiftableLowLevelILWithSize<'a, A> + Into<LowLevelILRegister<R>>, + R: LiftableLowLevelILWithSize<'a> + Into<LowLevelILRegisterKind<R>> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction<A>, + 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::<R>::lift_with_size(il, r, size) + LowLevelILRegisterKind::<R>::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<LiftedNonSSA>, R> +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, R> where - A: 'a + Architecture, R: ExpressionResultType, { type Result = R; - fn lift( - il: &'a MutableLiftedILFunction<A>, - 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<LiftedNonSSA>, ValueExpr> +impl<'a> LiftableLowLevelILWithSize<'a> + for LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction<A>, + 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<LiftedNonSSA>, R> +impl<'func, R> LowLevelILExpression<'func, Mutable, NonSSA<LiftedNonSSA>, 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<A, Mutable, NonSSA<LiftedNonSSA>>, + function: &'func LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>>, op: BNLowLevelILOperation, size: usize, flag_write: FlagWriteId, @@ -718,12 +697,11 @@ where _ty: PhantomData<R>, } -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<LiftedNonSSA>, R>) -> Self { + pub fn from_expr(expr: LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, 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<LiftedNonSSA>, R> { + pub fn build(self) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, 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<LiftedNonSSA>, R> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, 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<A>, - 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<A>, + 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<A, Mutable, NonSSA<LiftedNonSSA>, $result> { + pub fn $name(&self) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, $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<A, $result> { + 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<LiftedNonSSA>, $result> + ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, $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<A> LowLevelILFunction<A, Mutable, NonSSA<LiftedNonSSA>> -where - A: Architecture, -{ - pub const NO_INPUTS: [ExpressionBuilder<'static, A, ValueExpr>; 0] = []; - pub const NO_OUTPUTS: [LowLevelILRegister<A::Register>; 0] = []; +impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { + pub const NO_INPUTS: [ExpressionBuilder<'static, ValueExpr>; 0] = []; + pub const NO_OUTPUTS: [LowLevelILRegisterKind<CoreRegister>; 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<LiftedNonSSA>, E::Result> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, 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<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST; @@ -1052,7 +1020,7 @@ where &self, size: usize, val: u64, - ) -> LowLevelILExpression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, 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<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { self.const_ptr_sized(self.arch().address_size(), val) } - pub fn trap( - &self, - val: u64, - ) -> LowLevelILExpression<A, Mutable, NonSSA<LiftedNonSSA>, VoidExpr> { + pub fn trap(&self, val: u64) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, 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<LiftedNonSSA>, VoidExpr> + ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, 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<LiftedNonSSA>, VoidExpr> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, 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<R: Into<LowLevelILRegister<A::Register>>>( + pub fn reg<R: ArchReg, LR: Into<LowLevelILRegisterKind<R>>>( &self, size: usize, - reg: R, - ) -> LowLevelILExpression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + reg: LR, + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, 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<LowLevelILRegister<A::Register>>, - L: Into<LowLevelILRegister<A::Register>>, - >( + pub fn reg_split<R: ArchReg, LR: Into<LowLevelILRegisterKind<R>>>( &self, size: usize, - hi_reg: H, - lo_reg: L, - ) -> LowLevelILExpression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + hi_reg: LR, + lo_reg: LR, + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, 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<LowLevelILRegister<A::Register>>, - E: LiftableLowLevelILWithSize<'a, A>, + R: ArchReg, + LR: Into<LowLevelILRegisterKind<R>>, + 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<LowLevelILRegister<A::Register>>, - L: Into<LowLevelILRegister<A::Register>>, - E: LiftableLowLevelILWithSize<'a, A>, + R: ArchReg, + LR: Into<LowLevelILRegisterKind<R>>, + 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<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + flag: impl Flag, + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG; @@ -1288,7 +1250,7 @@ where pub fn flag_cond( &self, cond: FlagCondition, - ) -> LowLevelILExpression<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, 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<A, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + group: impl FlagGroup, + ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, 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<A>, 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<Item = O>, + intrinsic: impl Intrinsic, + inputs: impl IntoIterator<Item = P>, + ) -> ExpressionBuilder<'a, VoidExpr> where - O: Into<LowLevelILRegister<A::Register>>, - OL: IntoIterator<Item = O>, - I: Into<A::Intrinsic>, - P: LiftableLowLevelIL<'a, A, Result = ValueExpr>, - PL: IntoIterator<Item = P>, + R: ArchReg, + O: Into<LowLevelILRegisterKind<R>>, + 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<u64> = 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<A, M, F>, + pub(crate) function: &'func LowLevelILFunction<M, F>, pub(crate) op: BNLowLevelILInstruction, _args: PhantomData<O>, } -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<A, M, F>, + function: &'func LowLevelILFunction<M, F>, op: BNLowLevelILInstruction, ) -> Self { Self { @@ -56,13 +57,12 @@ where } } -impl<A, M, O> Operation<'_, A, M, NonSSA<LiftedNonSSA>, O> +impl<M, O> Operation<'_, M, NonSSA<LiftedNonSSA>, O> where - A: Architecture, M: FunctionMutability, O: OperationArguments, { - pub fn flag_write(&self) -> Option<A::FlagWrite> { + pub fn flag_write(&self) -> Option<CoreFlagWrite> { 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<A, M, F> Debug for Operation<'_, A, M, F, NoArgs> +impl<M, F> Debug for Operation<'_, M, F, NoArgs> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -87,9 +86,8 @@ where // LLIL_POP pub struct Pop; -impl<A, M, F> Operation<'_, A, M, F, Pop> +impl<M, F> Operation<'_, M, F, Pop> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -98,9 +96,8 @@ where } } -impl<A, M, F> Debug for Operation<'_, A, M, F, Pop> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Syscall> +impl<M, F> 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<A, M, F> Operation<'_, A, M, F, Intrinsic> +impl<M, F> Operation<'_, M, F, Intrinsic> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { // TODO: Support register and expression lists - pub fn intrinsic(&self) -> Option<A::Intrinsic> { + pub fn intrinsic(&self) -> Option<CoreIntrinsic> { let raw_id = self.op.operands[2] as u32; self.function.arch().intrinsic_from_id(IntrinsicId(raw_id)) } } -impl<A, M, F> Debug for Operation<'_, A, M, F, Intrinsic> +impl<M, F> 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<A::Register> { - 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<CoreRegister> { + 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<A, M, F> Debug for Operation<'_, A, M, F, SetReg> +impl<M, F> 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<A::Register> { - 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<CoreRegister> { + 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<A::Register> { - 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<CoreRegister> { + 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<A, M, F> Debug for Operation<'_, A, M, F, SetRegSplit> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, SetFlag> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Load> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Store> +impl<M, F> 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<A, M, F> Operation<'_, A, M, F, Reg> +impl<M, F> 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<A::Register> { - 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<CoreRegister> { + let raw_id = RegisterId(self.op.operands[0] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } } -impl<A, M, F> Debug for Operation<'_, A, M, F, Reg> +impl<M, F> 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<A, M, F> Operation<'_, A, M, F, RegSplit> +impl<M, F> 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<A::Register> { - 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<CoreRegister> { + 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<A::Register> { - 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<CoreRegister> { + let raw_id = RegisterId(self.op.operands[1] as u32); + LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id).expect("Bad register ID") } } -impl<A, M, F> Debug for Operation<'_, A, M, F, RegSplit> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, RegStackPush> +impl<M, F> 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<A, M, F> Operation<'_, A, M, F, RegStackPop> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, RegStackPop> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Flag> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, FlagBit> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Jump> +impl<M, F> 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<A, M, F>, + function: &'func LowLevelILFunction<M, F>, cursor: BNLowLevelILInstruction, cursor_operand: usize, } -impl<A, M, F> TargetListIter<'_, A, M, F> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, JumpTo> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Call> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Ret> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, If> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Goto> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, FlagCond> +impl<M, F> 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<A, M> Operation<'_, A, M, NonSSA<LiftedNonSSA>, FlagGroup> +impl<M> Operation<'_, M, NonSSA<LiftedNonSSA>, 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<A, M> Debug for Operation<'_, A, M, NonSSA<LiftedNonSSA>, FlagGroup> +impl<M> Debug for Operation<'_, M, NonSSA<LiftedNonSSA>, FlagGroup> where - A: Architecture, M: FunctionMutability, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -950,9 +811,8 @@ where } } -impl<A, M> Debug for Operation<'_, A, M, SSA, FlagGroup> +impl<M> 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<A, M, F> Operation<'_, A, M, F, Trap> +impl<M, F> Operation<'_, M, F, Trap> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -974,9 +833,8 @@ where } } -impl<A, M, F> Debug for Operation<'_, A, M, F, Trap> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, RegPhi> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, FlagPhi> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, MemPhi> +impl<M, F> 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<A, M, F> Operation<'_, A, M, F, Const> +impl<M, F> Operation<'_, M, F, Const> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1073,9 +927,8 @@ where } } -impl<A, M, F> Debug for Operation<'_, A, M, F, Const> +impl<M, F> 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<A, M, F> Operation<'_, A, M, F, Extern> +impl<M, F> Operation<'_, M, F, Extern> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { @@ -1131,9 +983,8 @@ where } } -impl<A, M, F> Debug for Operation<'_, A, M, F, Extern> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, BinaryOp> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, BinaryOpCarry> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, DoublePrecDivOp> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, UnaryOp> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, Condition> +impl<M, F> 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<A, M, F> Debug for Operation<'_, A, M, F, UnimplMem> +impl<M, F> Debug for Operation<'_, M, F, UnimplMem> where - A: Architecture, M: FunctionMutability, F: FunctionForm, { |
