From 7e32ee8b629e3e4f8d061cbe0729ff961b3502d7 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Sat, 10 May 2025 19:24:35 -0400 Subject: [Rust] Remove `NonSSAVariant` bound from `LowLevelILFunction` We don't do enough with the lifted il != non lifted il to justify the bound. This makes modifying IL much less work as the historical lifted il bound is gone. --- rust/src/low_level_il/expression.rs | 48 ++----------- rust/src/low_level_il/function.rs | 27 +++---- rust/src/low_level_il/instruction.rs | 37 +--------- rust/src/low_level_il/lifting.rs | 132 +++++++++++++++-------------------- rust/src/low_level_il/operation.rs | 20 +++--- 5 files changed, 90 insertions(+), 174 deletions(-) (limited to 'rust/src/low_level_il') diff --git a/rust/src/low_level_il/expression.rs b/rust/src/low_level_il/expression.rs index 73bec38d..8df8dfe0 100644 --- a/rust/src/low_level_il/expression.rs +++ b/rust/src/low_level_il/expression.rs @@ -135,12 +135,12 @@ where } } -impl<'func, M> ExpressionHandler<'func, M, NonSSA> - for LowLevelILExpression<'func, M, NonSSA, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, NonSSA> + for LowLevelILExpression<'func, M, NonSSA, ValueExpr> where M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, 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) }; @@ -154,41 +154,7 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, - { - // Visit the current expression. - match f(self) { - VisitorAction::Descend => { - // Recursively visit sub expressions. - self.kind().visit_sub_expressions(|e| e.visit_tree(f)) - } - action => action, - } - } -} - -impl<'func, M> ExpressionHandler<'func, M, NonSSA> - for LowLevelILExpression<'func, M, NonSSA, ValueExpr> -where - M: FunctionMutability, -{ - fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA> { - use binaryninjacore_sys::BNLowLevelILOperation::*; - let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; - match op.operation { - // Any invalid ops for Non-Lifted IL will be checked here. - LLIL_FLAG_COND => unreachable!("LLIL_FLAG_COND is only valid in Lifted IL"), - LLIL_FLAG_GROUP => unreachable!("LLIL_FLAG_GROUP is only valid in Lifted IL"), - // SAFETY: We have checked for illegal operations. - _ => LowLevelILExpressionKind::from_raw(self.function, op, self.index), - } - } - - fn visit_tree(&self, f: &mut T) -> VisitorAction - where - T: FnMut( - &LowLevelILExpression<'func, M, NonSSA, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, { // Visit the current expression. match f(self) { @@ -272,9 +238,9 @@ where LowPart(Operation<'func, M, F, operation::UnaryOp>), // Valid only in Lifted IL - FlagCond(Operation<'func, M, NonSSA, operation::FlagCond>), + FlagCond(Operation<'func, M, F, operation::FlagCond>), // Valid only in Lifted IL - FlagGroup(Operation<'func, M, NonSSA, operation::FlagGroup>), + FlagGroup(Operation<'func, M, F, operation::FlagGroup>), CmpE(Operation<'func, M, F, operation::Condition>), CmpNe(Operation<'func, M, F, operation::Condition>), @@ -708,7 +674,7 @@ where } } -impl LowLevelILExpressionKind<'_, Mutable, NonSSA> { +impl LowLevelILExpressionKind<'_, Mutable, NonSSA> { pub fn flag_write(&self) -> Option { use self::LowLevelILExpressionKind::*; diff --git a/rust/src/low_level_il/function.rs b/rust/src/low_level_il/function.rs index 62811b1d..495aae79 100644 --- a/rust/src/low_level_il/function.rs +++ b/rust/src/low_level_il/function.rs @@ -35,23 +35,14 @@ pub trait FunctionMutability: 'static + Debug {} impl FunctionMutability for Mutable {} impl FunctionMutability for Finalized {} -#[derive(Copy, Clone, Debug)] -pub struct LiftedNonSSA; -#[derive(Copy, Clone, Debug)] -pub struct RegularNonSSA; - -pub trait NonSSAVariant: 'static + Debug {} -impl NonSSAVariant for LiftedNonSSA {} -impl NonSSAVariant for RegularNonSSA {} - #[derive(Copy, Clone, Debug)] pub struct SSA; #[derive(Copy, Clone, Debug)] -pub struct NonSSA(V); +pub struct NonSSA; pub trait FunctionForm: 'static + Debug {} impl FunctionForm for SSA {} -impl FunctionForm for NonSSA {} +impl FunctionForm for NonSSA {} pub struct LowLevelILFunction { pub(crate) handle: *mut BNLowLevelILFunction, @@ -170,7 +161,7 @@ where } } -impl LowLevelILFunction> { +impl LowLevelILFunction { /// Retrieve the SSA form of the function. pub fn ssa_form(&self) -> Option>> { let handle = unsafe { BNGetLowLevelILSSAForm(self.handle) }; @@ -182,7 +173,7 @@ impl LowLevelILFunction> { } // 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. @@ -208,6 +199,16 @@ impl LowLevelILFunction> { } } +impl Ref> { + pub fn finalized(self) -> Ref> { + unsafe { + BNFinalizeLowLevelILFunction(self.handle); + // Now that we have finalized return the function as is so the caller can reference the "finalized function". + LowLevelILFunction::from_raw(self.handle).to_owned() + } + } +} + impl ToOwned for LowLevelILFunction where M: FunctionMutability, diff --git a/rust/src/low_level_il/instruction.rs b/rust/src/low_level_il/instruction.rs index 19b721af..ef546412 100644 --- a/rust/src/low_level_il/instruction.rs +++ b/rust/src/low_level_il/instruction.rs @@ -141,12 +141,11 @@ where } } -impl<'func, M> InstructionHandler<'func, M, NonSSA> - for LowLevelILInstruction<'func, M, NonSSA> +impl<'func, M> InstructionHandler<'func, M, NonSSA> for LowLevelILInstruction<'func, M, NonSSA> where M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -162,37 +161,7 @@ where fn visit_tree(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, - { - // Recursively visit sub expressions. - self.kind().visit_sub_expressions(|e| e.visit_tree(f)) - } -} - -impl<'func, M> InstructionHandler<'func, M, NonSSA> - for LowLevelILInstruction<'func, M, NonSSA> -where - M: FunctionMutability, -{ - fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA> { - #[allow(unused_imports)] - use binaryninjacore_sys::BNLowLevelILOperation::*; - let raw_op = self.into_raw(); - #[allow(clippy::match_single_binding)] - match raw_op.operation { - // Any invalid ops for Non-Lifted IL will be checked here. - // SAFETY: We have checked for illegal operations. - _ => unsafe { - LowLevelILInstructionKind::from_raw(self.function, self.expr_idx(), raw_op) - }, - } - } - - fn visit_tree(&self, f: &mut T) -> VisitorAction - where - T: FnMut( - &LowLevelILExpression<'func, 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)) diff --git a/rust/src/low_level_il/lifting.rs b/rust/src/low_level_il/lifting.rs index b0f85f11..f2850776 100644 --- a/rust/src/low_level_il/lifting.rs +++ b/rust/src/low_level_il/lifting.rs @@ -29,17 +29,17 @@ pub trait LiftableLowLevelIL<'func> { type Result: ExpressionResultType; fn lift( - il: &'func MutableLiftedILFunction, + il: &'func LowLevelILMutableFunction, expr: Self, - ) -> MutableLiftedILExpr<'func, Self::Result>; + ) -> LowLevelILMutableExpression<'func, Self::Result>; } pub trait LiftableLowLevelILWithSize<'func>: LiftableLowLevelIL<'func, Result = ValueExpr> { fn lift_with_size( - il: &'func MutableLiftedILFunction, + il: &'func LowLevelILMutableFunction, expr: Self, size: usize, - ) -> MutableLiftedILExpr<'func, ValueExpr>; + ) -> LowLevelILMutableExpression<'func, ValueExpr>; } #[derive(Copy, Clone)] @@ -459,8 +459,8 @@ pub fn get_default_flag_write_llil<'func, A>( arch: &A, role: FlagRole, op: LowLevelILFlagWriteOp, - il: &'func MutableLiftedILFunction, -) -> MutableLiftedILExpr<'func, ValueExpr> + il: &'func LowLevelILMutableFunction, +) -> LowLevelILMutableExpression<'func, ValueExpr> where A: 'func + Architecture, { @@ -487,8 +487,8 @@ pub fn get_default_flag_cond_llil<'func, A>( arch: &A, cond: FlagCondition, class: Option, - il: &'func MutableLiftedILFunction, -) -> MutableLiftedILExpr<'func, ValueExpr> + il: &'func LowLevelILMutableFunction, +) -> LowLevelILMutableExpression<'func, ValueExpr> where A: 'func + Architecture, { @@ -512,16 +512,16 @@ macro_rules! prim_int_lifter { impl<'a> LiftableLowLevelIL<'a> for $x { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, val: Self) - -> MutableLiftedILExpr<'a, Self::Result> + fn lift(il: &'a LowLevelILMutableFunction, val: Self) + -> LowLevelILMutableExpression<'a, Self::Result> { il.const_int(std::mem::size_of::(), val as i64 as u64) } } impl<'a> LiftableLowLevelILWithSize<'a> for $x { - fn lift_with_size(il: &'a MutableLiftedILFunction, val: Self, size: usize) - -> MutableLiftedILExpr<'a, ValueExpr> + fn lift_with_size(il: &'a LowLevelILMutableFunction, val: Self, size: usize) + -> LowLevelILMutableExpression<'a, ValueExpr> { let raw = val as i64; @@ -560,7 +560,10 @@ where { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, reg: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + reg: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { match reg { LowLevelILRegisterKind::Arch(r) => R::lift(il, r), LowLevelILRegisterKind::Temp(t) => il.reg( @@ -576,10 +579,10 @@ where R: LiftableLowLevelILWithSize<'a> + Into> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { match reg { LowLevelILRegisterKind::Arch(r) => R::lift_with_size(il, r, size), LowLevelILRegisterKind::Temp(t) => il.reg(size, LowLevelILRegisterKind::::Temp(t)), @@ -595,7 +598,10 @@ where { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, reg: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + reg: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { match reg { LowLevelILRegisterOrConstant::Register(size, r) => { LowLevelILRegisterKind::::lift_with_size(il, r, size) @@ -612,10 +618,10 @@ where R: LiftableLowLevelILWithSize<'a> + Into> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { // TODO ensure requested size is compatible with size of this constant match reg { LowLevelILRegisterOrConstant::Register(_, r) => { @@ -628,26 +634,27 @@ where } } -impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILExpression<'a, Mutable, NonSSA, R> +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILExpression<'a, Mutable, NonSSA, R> where R: ExpressionResultType, { type Result = R; - fn lift(il: &'a MutableLiftedILFunction, expr: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + expr: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { debug_assert!(expr.function.handle == il.handle); expr } } -impl<'a> LiftableLowLevelILWithSize<'a> - for LowLevelILExpression<'a, Mutable, NonSSA, ValueExpr> -{ +impl<'a> LiftableLowLevelILWithSize<'a> for LowLevelILExpression<'a, Mutable, NonSSA, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, expr: Self, _size: usize, - ) -> MutableLiftedILExpr<'a, Self::Result> { + ) -> LowLevelILMutableExpression<'a, Self::Result> { #[cfg(debug_assertions)] { use crate::low_level_il::ExpressionHandler; @@ -667,7 +674,7 @@ impl<'a> LiftableLowLevelILWithSize<'a> } } -impl LowLevelILExpression<'_, Mutable, NonSSA, R> +impl LowLevelILExpression<'_, Mutable, NonSSA, R> where R: ExpressionResultType, { @@ -686,7 +693,7 @@ pub struct ExpressionBuilder<'func, R> where R: ExpressionResultType, { - function: &'func LowLevelILFunction>, + function: &'func LowLevelILFunction, op: BNLowLevelILOperation, size: usize, flag_write: FlagWriteId, @@ -701,7 +708,7 @@ impl<'a, R> ExpressionBuilder<'a, R> where R: ExpressionResultType, { - pub fn from_expr(expr: LowLevelILExpression<'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) }; @@ -725,7 +732,7 @@ where self } - pub fn build(self) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { + pub fn build(self) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { use binaryninjacore_sys::BNLowLevelILAddExpr; let expr_idx = unsafe { @@ -744,10 +751,7 @@ where LowLevelILExpression::new(self.function, LowLevelExpressionIndex(expr_idx)) } - pub fn with_source_operand( - self, - op: u32, - ) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { + pub fn with_source_operand(self, op: u32) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { self.build().with_source_operand(op) } @@ -763,7 +767,10 @@ where { type Result = R; - fn lift(il: &'a MutableLiftedILFunction, expr: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + expr: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { debug_assert!(expr.function.handle == il.handle); expr.build() @@ -772,10 +779,10 @@ where impl<'a> LiftableLowLevelILWithSize<'a> for ExpressionBuilder<'a, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, expr: Self, _size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { #[cfg(debug_assertions)] { use binaryninjacore_sys::BNLowLevelILOperation::{LLIL_UNIMPL, LLIL_UNIMPL_MEM}; @@ -796,7 +803,7 @@ impl<'a> LiftableLowLevelILWithSize<'a> for ExpressionBuilder<'a, ValueExpr> { macro_rules! no_arg_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name(&self) -> LowLevelILExpression, $result> { + pub fn $name(&self) -> LowLevelILExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -829,10 +836,7 @@ macro_rules! sized_no_arg_lifter { macro_rules! unsized_unary_op_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name<'a, E>( - &'a self, - expr: E, - ) -> LowLevelILExpression<'a, Mutable, NonSSA, $result> + pub fn $name<'a, E>(&'a self, expr: E) -> LowLevelILExpression<'a, Mutable, NonSSA, $result> where E: LiftableLowLevelIL<'a, Result = ValueExpr>, { @@ -967,14 +971,14 @@ macro_rules! binary_op_carry_lifter { }; } -impl LowLevelILFunction> { +impl LowLevelILMutableFunction { pub const NO_INPUTS: [ExpressionBuilder<'static, ValueExpr>; 0] = []; pub const NO_OUTPUTS: [LowLevelILRegisterKind; 0] = []; pub fn expression<'a, E: LiftableLowLevelIL<'a>>( &'a self, expr: E, - ) -> LowLevelILExpression<'a, Mutable, NonSSA, E::Result> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, E::Result> { E::lift(self, expr) } @@ -1002,11 +1006,7 @@ impl LowLevelILFunction> { true } - pub fn const_int( - &self, - size: usize, - val: u64, - ) -> LowLevelILExpression, ValueExpr> { + pub fn const_int(&self, size: usize, val: u64) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST; @@ -1016,11 +1016,7 @@ impl LowLevelILFunction> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn const_ptr_sized( - &self, - size: usize, - val: u64, - ) -> LowLevelILExpression, ValueExpr> { + pub fn const_ptr_sized(&self, size: usize, val: u64) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST_PTR; @@ -1030,14 +1026,11 @@ impl LowLevelILFunction> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn const_ptr( - &self, - val: u64, - ) -> LowLevelILExpression, ValueExpr> { + pub fn const_ptr(&self, val: u64) -> LowLevelILMutableExpression { self.const_ptr_sized(self.arch().address_size(), val) } - pub fn trap(&self, val: u64) -> LowLevelILExpression, VoidExpr> { + pub fn trap(&self, val: u64) -> LowLevelILExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_TRAP; @@ -1064,7 +1057,7 @@ impl LowLevelILFunction> { cond: C, true_label: &'b mut LowLevelILLabel, false_label: &'b mut LowLevelILLabel, - ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> + ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> where C: LiftableLowLevelIL<'b, Result = ValueExpr>, { @@ -1104,7 +1097,7 @@ impl LowLevelILFunction> { pub fn goto<'a: 'b, 'b>( &'a self, label: &'b mut LowLevelILLabel, - ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> { use binaryninjacore_sys::BNLowLevelILGoto; let mut raw_label = BNLowLevelILLabel::from(*label); @@ -1125,7 +1118,7 @@ impl LowLevelILFunction> { &self, size: usize, reg: LR, - ) -> LowLevelILExpression, ValueExpr> { + ) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG; @@ -1143,7 +1136,7 @@ impl LowLevelILFunction> { size: usize, hi_reg: LR, lo_reg: LR, - ) -> LowLevelILExpression, ValueExpr> { + ) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG_SPLIT; @@ -1232,10 +1225,7 @@ impl LowLevelILFunction> { } } - pub fn flag( - &self, - flag: impl Flag, - ) -> LowLevelILExpression, ValueExpr> { + pub fn flag(&self, flag: impl Flag) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG; @@ -1247,10 +1237,7 @@ impl LowLevelILFunction> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn flag_cond( - &self, - cond: FlagCondition, - ) -> LowLevelILExpression, ValueExpr> { + pub fn flag_cond(&self, cond: FlagCondition) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_COND; @@ -1261,10 +1248,7 @@ impl LowLevelILFunction> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn flag_group( - &self, - group: impl FlagGroup, - ) -> LowLevelILExpression, ValueExpr> { + pub fn flag_group(&self, group: impl FlagGroup) -> LowLevelILMutableExpression { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_GROUP; diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs index f2ce9d1a..6e0dda91 100644 --- a/rust/src/low_level_il/operation.rs +++ b/rust/src/low_level_il/operation.rs @@ -90,11 +90,14 @@ where } } -impl Operation<'_, M, NonSSA, O> +impl Operation<'_, M, NonSSA, O> where M: FunctionMutability, O: OperationArguments, { + /// Get the [`CoreFlagWrite`] for the operation. + /// + /// NOTE: This is only expected to be present for lifted IL. pub fn flag_write(&self) -> Option { match self.op.flags { 0 => None, @@ -1419,9 +1422,10 @@ where // Valid only in Lifted IL pub struct FlagGroup; -impl Operation<'_, M, NonSSA, FlagGroup> +impl Operation<'_, M, F, FlagGroup> where M: FunctionMutability, + F: FunctionForm, { pub fn flag_group(&self) -> CoreFlagGroup { let id = self.op.operands[0] as u32; @@ -1432,9 +1436,10 @@ where } } -impl Debug for Operation<'_, M, NonSSA, FlagGroup> +impl Debug for Operation<'_, M, F, FlagGroup> where M: FunctionMutability, + F: FunctionForm, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("FlagGroup") @@ -1443,15 +1448,6 @@ where } } -impl Debug for Operation<'_, M, SSA, FlagGroup> -where - M: FunctionMutability, -{ - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("FlagGroup").finish() - } -} - // LLIL_TRAP pub struct Trap; -- cgit v1.3.1