summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorMichael Krasnitski <michael.krasnitski@gmail.com>2024-02-07 11:44:06 -0500
committerKyle Martin <krm504@nyu.edu>2024-03-18 17:46:37 -0400
commit5fcf6bc59ebc2110d053360d223e6570cdd2272c (patch)
treeed6eafd132cf53fd9e7105f541967324b4165db0 /rust/src
parentbdd012af7941c7d17b97b3e69628a7bc7cc2411e (diff)
Refactor MLIL instructions
* Turn `MediumLevelILInstruction` into a struct with a `kind` field to indicate the instruction variant, and pull out the `function` and `address` fields from each variant to live in the top-level struct. * Make variant fields public, remove field getter methods and centralize lifting logic to happen all at once. Split tuple fields into individual named fields. * Move the `operands` method to `MediumLevelILLiftedInstruction`, and make it return an owned `Vec` of operands rather than a borrowed iterator.
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/mlil/function.rs6
-rw-r--r--rust/src/mlil/instruction.rs1255
-rw-r--r--rust/src/mlil/lift.rs250
-rw-r--r--rust/src/mlil/operation.rs2337
4 files changed, 1121 insertions, 2727 deletions
diff --git a/rust/src/mlil/function.rs b/rust/src/mlil/function.rs
index 8f5ed73d..16cc5102 100644
--- a/rust/src/mlil/function.rs
+++ b/rust/src/mlil/function.rs
@@ -14,7 +14,7 @@ use crate::function::Function;
use crate::function::Location;
use crate::rc::{Array, Ref, RefCountable};
-use super::{MediumLevelILBlock, MediumLevelILInstruction};
+use super::{MediumLevelILBlock, MediumLevelILInstruction, MediumLevelILLiftedInstruction};
pub struct MediumLevelILFunction {
pub(crate) handle: *mut BNMediumLevelILFunction,
@@ -61,6 +61,10 @@ impl MediumLevelILFunction {
MediumLevelILInstruction::new(self.to_owned(), expr_idx)
}
+ pub fn lifted_instruction_from_idx(&self, expr_idx: usize) -> MediumLevelILLiftedInstruction {
+ self.instruction_from_idx(expr_idx).lift()
+ }
+
pub fn instruction_count(&self) -> usize {
unsafe { BNGetMediumLevelILInstructionCount(self.handle) }
}
diff --git a/rust/src/mlil/instruction.rs b/rust/src/mlil/instruction.rs
index 306a1352..50154f34 100644
--- a/rust/src/mlil/instruction.rs
+++ b/rust/src/mlil/instruction.rs
@@ -1,19 +1,27 @@
use binaryninjacore_sys::BNGetMediumLevelILByIndex;
use binaryninjacore_sys::BNMediumLevelILOperation;
-use crate::mlil::MediumLevelILLiftedInstruction;
use crate::rc::Ref;
+use crate::types::ILIntrinsic;
+use super::lift::*;
use super::operation::*;
use super::MediumLevelILFunction;
#[derive(Clone)]
-pub enum MediumLevelILInstruction {
- Nop(NoArgs),
- Noret(NoArgs),
- Bp(NoArgs),
- Undef(NoArgs),
- Unimpl(NoArgs),
+pub struct MediumLevelILInstruction {
+ pub function: Ref<MediumLevelILFunction>,
+ pub address: u64,
+ pub kind: MediumLevelILInstructionKind,
+}
+
+#[derive(Copy, Clone)]
+pub enum MediumLevelILInstructionKind {
+ Nop,
+ Noret,
+ Bp,
+ Undef,
+ Unimpl,
If(MediumLevelILOperationIf),
FloatConst(FloatConst),
Const(Constant),
@@ -147,7 +155,7 @@ impl core::fmt::Debug for MediumLevelILInstruction {
f,
"<{} at 0x{:08}>",
core::any::type_name::<Self>(),
- self.address(),
+ self.address,
)
}
}
@@ -156,54 +164,37 @@ impl MediumLevelILInstruction {
pub(crate) fn new(function: Ref<MediumLevelILFunction>, idx: usize) -> Self {
let op = unsafe { BNGetMediumLevelILByIndex(function.handle, idx) };
use BNMediumLevelILOperation::*;
- use MediumLevelILInstruction as Op;
- match op.operation {
- MLIL_NOP => Op::Nop(NoArgs::new(function, op.address)),
- MLIL_NORET => Op::Noret(NoArgs::new(function, op.address)),
- MLIL_BP => Op::Bp(NoArgs::new(function, op.address)),
- MLIL_UNDEF => Op::Undef(NoArgs::new(function, op.address)),
- MLIL_UNIMPL => Op::Unimpl(NoArgs::new(function, op.address)),
+ use MediumLevelILInstructionKind as Op;
+ let kind = match op.operation {
+ MLIL_NOP => Op::Nop,
+ MLIL_NORET => Op::Noret,
+ MLIL_BP => Op::Bp,
+ MLIL_UNDEF => Op::Undef,
+ MLIL_UNIMPL => Op::Unimpl,
MLIL_IF => Op::If(MediumLevelILOperationIf::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1],
op.operands[2],
)),
- MLIL_FLOAT_CONST => Op::FloatConst(FloatConst::new(
- function,
- op.address,
- op.operands[0],
- op.size,
- )),
- MLIL_CONST => Op::Const(Constant::new(function, op.address, op.operands[0])),
- MLIL_CONST_PTR => Op::ConstPtr(Constant::new(function, op.address, op.operands[0])),
- MLIL_IMPORT => Op::Import(Constant::new(function, op.address, op.operands[0])),
- MLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr::new(
- function,
- op.address,
- op.operands[0],
- op.operands[1],
- )),
+ MLIL_FLOAT_CONST => Op::FloatConst(FloatConst::new(op.operands[0], op.size)),
+ MLIL_CONST => Op::Const(Constant::new(op.operands[0])),
+ MLIL_CONST_PTR => Op::ConstPtr(Constant::new(op.operands[0])),
+ MLIL_IMPORT => Op::Import(Constant::new(op.operands[0])),
+ MLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr::new(op.operands[0], op.operands[1])),
MLIL_CONST_DATA => Op::ConstData(ConstantData::new(
- function,
- op.address,
- (op.operands[0], op.operands[1]),
+ op.operands[0] as u32,
+ op.operands[1] as i64,
op.size,
)),
- MLIL_JUMP => Op::Jump(Jump::new(function, op.address, op.operands[0] as usize)),
- MLIL_RET_HINT => Op::RetHint(Jump::new(function, op.address, op.operands[0] as usize)),
+ MLIL_JUMP => Op::Jump(Jump::new(op.operands[0] as usize)),
+ MLIL_RET_HINT => Op::RetHint(Jump::new(op.operands[0] as usize)),
MLIL_STORE_SSA => Op::StoreSsa(StoreSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1],
op.operands[2],
op.operands[3] as usize,
)),
MLIL_STORE_STRUCT_SSA => Op::StoreStructSsa(StoreStructSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1],
op.operands[2],
@@ -211,1099 +202,803 @@ impl MediumLevelILInstruction {
op.operands[4] as usize,
)),
MLIL_STORE_STRUCT => Op::StoreStruct(StoreStruct::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1],
op.operands[2] as usize,
)),
- MLIL_STORE => Op::Store(Store::new(
- function,
- op.address,
- op.operands[0] as usize,
- op.operands[1] as usize,
- )),
+ MLIL_STORE => Op::Store(Store::new(op.operands[0] as usize, op.operands[1] as usize)),
MLIL_JUMP_TO => Op::JumpTo(JumpTo::new(
- function,
- op.address,
op.operands[0] as usize,
- (op.operands[1] as usize, op.operands[2] as usize),
+ op.operands[1] as usize,
+ op.operands[2] as usize,
)),
- MLIL_GOTO => Op::Goto(Goto::new(function, op.address, op.operands[0])),
- MLIL_FREE_VAR_SLOT => {
- Op::FreeVarSlot(FreeVarSlot::new(function, op.address, op.operands[0]))
- }
+ MLIL_GOTO => Op::Goto(Goto::new(op.operands[0])),
+ MLIL_FREE_VAR_SLOT => Op::FreeVarSlot(FreeVarSlot::new(op.operands[0])),
MLIL_SET_VAR_FIELD => Op::SetVarField(SetVarField::new(
- function,
- op.address,
op.operands[0],
op.operands[1],
op.operands[2] as usize,
)),
- MLIL_SET_VAR => Op::SetVar(SetVar::new(
- function,
- op.address,
- op.operands[0],
- op.operands[1] as usize,
- )),
+ MLIL_SET_VAR => Op::SetVar(SetVar::new(op.operands[0], op.operands[1] as usize)),
MLIL_FREE_VAR_SLOT_SSA => Op::FreeVarSlotSsa(FreeVarSlotSsa::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
(op.operands[0], op.operands[2] as usize),
)),
MLIL_SET_VAR_SSA_FIELD => Op::SetVarSsaField(SetVarSsaField::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
(op.operands[0], op.operands[2] as usize),
op.operands[3],
op.operands[4] as usize,
)),
MLIL_SET_VAR_ALIASED_FIELD => Op::SetVarAliasedField(SetVarSsaField::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
(op.operands[0], op.operands[2] as usize),
op.operands[3],
op.operands[4] as usize,
)),
MLIL_SET_VAR_ALIASED => Op::SetVarAliased(SetVarAliased::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
(op.operands[0], op.operands[2] as usize),
op.operands[3] as usize,
)),
MLIL_SET_VAR_SSA => Op::SetVarSsa(SetVarSsa::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
op.operands[2] as usize,
)),
MLIL_VAR_PHI => Op::VarPhi(VarPhi::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
- (op.operands[2] as usize, op.operands[3] as usize),
+ op.operands[2] as usize,
+ op.operands[3] as usize,
)),
MLIL_MEM_PHI => Op::MemPhi(MemPhi::new(
- function,
- op.address,
- op.operands[0],
- (op.operands[1] as usize, op.operands[2] as usize),
- )),
- MLIL_VAR_SPLIT => Op::VarSplit(VarSplit::new(
- function,
- op.address,
op.operands[0],
- op.operands[1],
+ op.operands[1] as usize,
+ op.operands[2] as usize,
)),
+ MLIL_VAR_SPLIT => Op::VarSplit(VarSplit::new(op.operands[0], op.operands[1])),
MLIL_SET_VAR_SPLIT => Op::SetVarSplit(SetVarSplit::new(
- function,
- op.address,
op.operands[0],
op.operands[1],
op.operands[2] as usize,
)),
MLIL_VAR_SPLIT_SSA => Op::VarSplitSsa(VarSplitSsa::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
(op.operands[2], op.operands[3] as usize),
)),
MLIL_SET_VAR_SPLIT_SSA => Op::SetVarSplitSsa(SetVarSplitSsa::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
(op.operands[2], op.operands[3] as usize),
op.operands[4] as usize,
)),
MLIL_ADD => Op::Add(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_SUB => Op::Sub(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_AND => Op::And(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_OR => Op::Or(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_XOR => Op::Xor(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_LSL => Op::Lsl(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_LSR => Op::Lsr(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_ASR => Op::Asr(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_ROL => Op::Rol(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_ROR => Op::Ror(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MUL => Op::Mul(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MULU_DP => Op::MuluDp(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MULS_DP => Op::MulsDp(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_DIVU => Op::Divu(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_DIVU_DP => Op::DivuDp(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_DIVS => Op::Divs(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_DIVS_DP => Op::DivsDp(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MODU => Op::Modu(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MODU_DP => Op::ModuDp(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MODS => Op::Mods(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_MODS_DP => Op::ModsDp(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_E => Op::CmpE(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_NE => Op::CmpNe(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_SLT => Op::CmpSlt(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_ULT => Op::CmpUlt(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_SLE => Op::CmpSle(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_ULE => Op::CmpUle(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_SGE => Op::CmpSge(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_UGE => Op::CmpUge(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_SGT => Op::CmpSgt(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_CMP_UGT => Op::CmpUgt(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_TEST_BIT => Op::TestBit(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_E => Op::FcmpE(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_NE => Op::FcmpNe(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_LT => Op::FcmpLt(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_LE => Op::FcmpLe(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_GE => Op::FcmpGe(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_GT => Op::FcmpGt(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_O => Op::FcmpO(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FCMP_UO => Op::FcmpUo(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FADD => Op::Fadd(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FSUB => Op::Fsub(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FMUL => Op::Fmul(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_FDIV => Op::Fdiv(BinaryOp::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
)),
MLIL_ADC => Op::Adc(BinaryOpCarry::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
)),
MLIL_SBB => Op::Sbb(BinaryOpCarry::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
)),
MLIL_RLC => Op::Rlc(BinaryOpCarry::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
)),
MLIL_RRC => Op::Rrc(BinaryOpCarry::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
)),
MLIL_CALL => Op::Call(Call::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
+ op.operands[0] as usize,
+ op.operands[1] as usize,
op.operands[2] as usize,
- (op.operands[3] as usize, op.operands[4] as usize),
+ op.operands[3] as usize,
+ op.operands[4] as usize,
)),
MLIL_TAILCALL => Op::Tailcall(Call::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
+ op.operands[0] as usize,
+ op.operands[1] as usize,
op.operands[2] as usize,
- (op.operands[3] as usize, op.operands[4] as usize),
+ op.operands[3] as usize,
+ op.operands[4] as usize,
)),
MLIL_SYSCALL => Op::Syscall(Syscall::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
- (op.operands[2] as usize, op.operands[3] as usize),
+ op.operands[0] as usize,
+ op.operands[1] as usize,
+ op.operands[2] as usize,
+ op.operands[3] as usize,
)),
MLIL_INTRINSIC => Op::Intrinsic(Intrinsic::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
+ op.operands[0] as usize,
+ op.operands[1] as usize,
op.operands[2] as u32,
- (op.operands[3] as usize, op.operands[4] as usize),
+ op.operands[3] as usize,
+ op.operands[4] as usize,
)),
MLIL_INTRINSIC_SSA => Op::IntrinsicSsa(IntrinsicSsa::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
+ op.operands[0] as usize,
+ op.operands[1] as usize,
op.operands[2] as u32,
- (op.operands[3] as usize, op.operands[4] as usize),
+ op.operands[3] as usize,
+ op.operands[4] as usize,
)),
MLIL_CALL_SSA => Op::CallSsa(CallSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
- (op.operands[2] as usize, op.operands[3] as usize),
+ op.operands[2] as usize,
+ op.operands[3] as usize,
op.operands[4],
)),
MLIL_TAILCALL_SSA => Op::TailcallSsa(CallSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
- (op.operands[2] as usize, op.operands[3] as usize),
+ op.operands[2] as usize,
+ op.operands[3] as usize,
op.operands[4],
)),
MLIL_CALL_UNTYPED_SSA => Op::CallUntypedSsa(CallUntypedSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
op.operands[3] as usize,
)),
MLIL_TAILCALL_UNTYPED_SSA => Op::TailcallUntypedSsa(CallUntypedSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
op.operands[3] as usize,
)),
MLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa::new(
- function,
- op.address,
op.operands[0] as usize,
- (op.operands[1] as usize, op.operands[2] as usize),
+ op.operands[1] as usize,
+ op.operands[2] as usize,
op.operands[3],
)),
MLIL_SYSCALL_UNTYPED_SSA => Op::SyscallUntypedSsa(SyscallUntypedSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
)),
MLIL_CALL_UNTYPED => Op::CallUntyped(CallUntyped::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
op.operands[3] as usize,
)),
MLIL_TAILCALL_UNTYPED => Op::TailcallUntyped(CallUntyped::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
op.operands[3] as usize,
)),
MLIL_SYSCALL_UNTYPED => Op::SyscallUntyped(SyscallUntyped::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1] as usize,
op.operands[2] as usize,
)),
- MLIL_SEPARATE_PARAM_LIST => Op::SeparateParamList(SeparateParamList::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
- )),
- MLIL_SHARED_PARAM_SLOT => Op::SharedParamSlot(SharedParamSlot::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
- )),
- MLIL_NEG => Op::Neg(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_NOT => Op::Not(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_SX => Op::Sx(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_ZX => Op::Zx(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_LOW_PART => {
- Op::LowPart(UnaryOp::new(function, op.address, op.operands[0] as usize))
- }
- MLIL_BOOL_TO_INT => {
- Op::BoolToInt(UnaryOp::new(function, op.address, op.operands[0] as usize))
- }
- MLIL_UNIMPL_MEM => {
- Op::UnimplMem(UnaryOp::new(function, op.address, op.operands[0] as usize))
+ MLIL_NEG => Op::Neg(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_NOT => Op::Not(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_SX => Op::Sx(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_ZX => Op::Zx(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_LOW_PART => Op::LowPart(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FSQRT => Op::Fsqrt(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FNEG => Op::Fneg(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FABS => Op::Fabs(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FLOAT_CONV => Op::FloatConv(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FLOOR => Op::Floor(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_CEIL => Op::Ceil(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_FTRUNC => Op::Ftrunc(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_LOAD => Op::Load(UnaryOp::new(op.operands[0] as usize)),
+ MLIL_LOAD_STRUCT => {
+ Op::LoadStruct(LoadStruct::new(op.operands[0] as usize, op.operands[1]))
}
- MLIL_FSQRT => Op::Fsqrt(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_FNEG => Op::Fneg(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_FABS => Op::Fabs(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_FLOAT_TO_INT => {
- Op::FloatToInt(UnaryOp::new(function, op.address, op.operands[0] as usize))
- }
- MLIL_INT_TO_FLOAT => {
- Op::IntToFloat(UnaryOp::new(function, op.address, op.operands[0] as usize))
- }
- MLIL_FLOAT_CONV => {
- Op::FloatConv(UnaryOp::new(function, op.address, op.operands[0] as usize))
- }
- MLIL_ROUND_TO_INT => {
- Op::RoundToInt(UnaryOp::new(function, op.address, op.operands[0] as usize))
- }
- MLIL_FLOOR => Op::Floor(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_CEIL => Op::Ceil(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_FTRUNC => Op::Ftrunc(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_LOAD => Op::Load(UnaryOp::new(function, op.address, op.operands[0] as usize)),
- MLIL_LOAD_STRUCT => Op::LoadStruct(LoadStruct::new(
- function,
- op.address,
- op.operands[0] as usize,
- op.operands[1],
- )),
MLIL_LOAD_STRUCT_SSA => Op::LoadStructSsa(LoadStructSsa::new(
- function,
- op.address,
op.operands[0] as usize,
op.operands[1],
op.operands[2],
)),
- MLIL_LOAD_SSA => Op::LoadSsa(LoadSsa::new(
- function,
- op.address,
+ MLIL_LOAD_SSA => Op::LoadSsa(LoadSsa::new(op.operands[0] as usize, op.operands[1])),
+ MLIL_RET => Op::Ret(Ret::new(op.operands[0] as usize, op.operands[1] as usize)),
+ MLIL_SEPARATE_PARAM_LIST => Op::SeparateParamList(SeparateParamList::new(
op.operands[0] as usize,
- op.operands[1],
- )),
- MLIL_RET => Op::Ret(Ret::new(
- function,
- op.address,
- (op.operands[0] as usize, op.operands[1] as usize),
- )),
- MLIL_VAR => Op::Var(Var::new(function, op.address, op.operands[0])),
- MLIL_ADDRESS_OF => Op::AddressOf(Var::new(function, op.address, op.operands[0])),
- MLIL_VAR_FIELD => Op::VarField(Field::new(
- function,
- op.address,
- op.operands[0],
- op.operands[1],
- )),
- MLIL_ADDRESS_OF_FIELD => Op::AddressOfField(Field::new(
- function,
- op.address,
- op.operands[0],
- op.operands[1],
- )),
- MLIL_VAR_SSA => Op::VarSsa(VarSsa::new(
- function,
- op.address,
- (op.operands[0], op.operands[1] as usize),
+ op.operands[1] as usize,
)),
- MLIL_VAR_ALIASED => Op::VarAliased(VarSsa::new(
- function,
- op.address,
- (op.operands[0], op.operands[1] as usize),
+ MLIL_SHARED_PARAM_SLOT => Op::SharedParamSlot(SharedParamSlot::new(
+ op.operands[0] as usize,
+ op.operands[1] as usize,
)),
+ MLIL_VAR => Op::Var(Var::new(op.operands[0])),
+ MLIL_ADDRESS_OF => Op::AddressOf(Var::new(op.operands[0])),
+ MLIL_VAR_FIELD => Op::VarField(Field::new(op.operands[0], op.operands[1])),
+ MLIL_ADDRESS_OF_FIELD => Op::AddressOfField(Field::new(op.operands[0], op.operands[1])),
+ MLIL_VAR_SSA => Op::VarSsa(VarSsa::new((op.operands[0], op.operands[1] as usize))),
+ MLIL_VAR_ALIASED => {
+ Op::VarAliased(VarSsa::new((op.operands[0], op.operands[1] as usize)))
+ }
MLIL_VAR_SSA_FIELD => Op::VarSsaField(VarSsaField::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
op.operands[2],
)),
MLIL_VAR_ALIASED_FIELD => Op::VarAliasedField(VarSsaField::new(
- function,
- op.address,
(op.operands[0], op.operands[1] as usize),
op.operands[2],
)),
- MLIL_TRAP => Op::Trap(Trap::new(function, op.address, op.operands[0])),
+ MLIL_TRAP => Op::Trap(Trap::new(op.operands[0])),
// translated directly into a list for Expression or Variables
// TODO MLIL_MEMORY_INTRINSIC_SSA needs to be handled properly
MLIL_CALL_OUTPUT | MLIL_CALL_PARAM | MLIL_CALL_PARAM_SSA | MLIL_CALL_OUTPUT_SSA | MLIL_MEMORY_INTRINSIC_OUTPUT_SSA | MLIL_MEMORY_INTRINSIC_SSA => {
unreachable!()
}
+ };
+
+ Self {
+ function,
+ address: op.address,
+ kind,
}
}
- pub fn function(&self) -> &MediumLevelILFunction {
- use MediumLevelILInstruction::*;
- match self {
- Nop(op) => &op.function,
- Noret(op) => &op.function,
- Bp(op) => &op.function,
- Undef(op) => &op.function,
- Unimpl(op) => &op.function,
- If(op) => &op.function,
- FloatConst(op) => &op.function,
- Const(op) => &op.function,
- ConstPtr(op) => &op.function,
- Import(op) => &op.function,
- ExternPtr(op) => &op.function,
- ConstData(op) => &op.function,
- Jump(op) => &op.function,
- RetHint(op) => &op.function,
- StoreSsa(op) => &op.function,
- StoreStructSsa(op) => &op.function,
- StoreStruct(op) => &op.function,
- Store(op) => &op.function,
- JumpTo(op) => &op.function,
- Goto(op) => &op.function,
- FreeVarSlot(op) => &op.function,
- SetVarField(op) => &op.function,
- SetVar(op) => &op.function,
- FreeVarSlotSsa(op) => &op.function,
- SetVarSsaField(op) => &op.function,
- SetVarAliasedField(op) => &op.function,
- SetVarAliased(op) => &op.function,
- SetVarSsa(op) => &op.function,
- VarPhi(op) => &op.function,
- MemPhi(op) => &op.function,
- VarSplit(op) => &op.function,
- SetVarSplit(op) => &op.function,
- VarSplitSsa(op) => &op.function,
- SetVarSplitSsa(op) => &op.function,
- Add(op) => &op.function,
- Sub(op) => &op.function,
- And(op) => &op.function,
- Or(op) => &op.function,
- Xor(op) => &op.function,
- Lsl(op) => &op.function,
- Lsr(op) => &op.function,
- Asr(op) => &op.function,
- Rol(op) => &op.function,
- Ror(op) => &op.function,
- Mul(op) => &op.function,
- MuluDp(op) => &op.function,
- MulsDp(op) => &op.function,
- Divu(op) => &op.function,
- DivuDp(op) => &op.function,
- Divs(op) => &op.function,
- DivsDp(op) => &op.function,
- Modu(op) => &op.function,
- ModuDp(op) => &op.function,
- Mods(op) => &op.function,
- ModsDp(op) => &op.function,
- CmpE(op) => &op.function,
- CmpNe(op) => &op.function,
- CmpSlt(op) => &op.function,
- CmpUlt(op) => &op.function,
- CmpSle(op) => &op.function,
- CmpUle(op) => &op.function,
- CmpSge(op) => &op.function,
- CmpUge(op) => &op.function,
- CmpSgt(op) => &op.function,
- CmpUgt(op) => &op.function,
- TestBit(op) => &op.function,
- AddOverflow(op) => &op.function,
- FcmpE(op) => &op.function,
- FcmpNe(op) => &op.function,
- FcmpLt(op) => &op.function,
- FcmpLe(op) => &op.function,
- FcmpGe(op) => &op.function,
- FcmpGt(op) => &op.function,
- FcmpO(op) => &op.function,
- FcmpUo(op) => &op.function,
- Fadd(op) => &op.function,
- Fsub(op) => &op.function,
- Fmul(op) => &op.function,
- Fdiv(op) => &op.function,
- Adc(op) => &op.function,
- Sbb(op) => &op.function,
- Rlc(op) => &op.function,
- Rrc(op) => &op.function,
- Call(op) => &op.function,
- Tailcall(op) => &op.function,
- Syscall(op) => &op.function,
- Intrinsic(op) => &op.function,
- IntrinsicSsa(op) => &op.function,
- CallSsa(op) => &op.function,
- TailcallSsa(op) => &op.function,
- CallUntypedSsa(op) => &op.function,
- TailcallUntypedSsa(op) => &op.function,
- SyscallSsa(op) => &op.function,
- SyscallUntypedSsa(op) => &op.function,
- CallUntyped(op) => &op.function,
- TailcallUntyped(op) => &op.function,
- SyscallUntyped(op) => &op.function,
- SeparateParamList(op) => &op.function,
- SharedParamSlot(op) => &op.function,
- Neg(op) => &op.function,
- Not(op) => &op.function,
- Sx(op) => &op.function,
- Zx(op) => &op.function,
- LowPart(op) => &op.function,
- BoolToInt(op) => &op.function,
- UnimplMem(op) => &op.function,
- Fsqrt(op) => &op.function,
- Fneg(op) => &op.function,
- Fabs(op) => &op.function,
- FloatToInt(op) => &op.function,
- IntToFloat(op) => &op.function,
- FloatConv(op) => &op.function,
- RoundToInt(op) => &op.function,
- Floor(op) => &op.function,
- Ceil(op) => &op.function,
- Ftrunc(op) => &op.function,
- Load(op) => &op.function,
- LoadStruct(op) => &op.function,
- LoadStructSsa(op) => &op.function,
- LoadSsa(op) => &op.function,
- Ret(op) => &op.function,
- Var(op) => &op.function,
- AddressOf(op) => &op.function,
- VarField(op) => &op.function,
- AddressOfField(op) => &op.function,
- VarSsa(op) => &op.function,
- VarAliased(op) => &op.function,
- VarSsaField(op) => &op.function,
- VarAliasedField(op) => &op.function,
- Trap(op) => &op.function,
+ pub fn lift(&self) -> MediumLevelILLiftedInstruction {
+ use MediumLevelILInstructionKind::*;
+ use MediumLevelILLiftedInstructionKind as Lifted;
+
+ let kind = match self.kind {
+ Nop => Lifted::Nop,
+ Noret => Lifted::Noret,
+ Bp => Lifted::Bp,
+ Undef => Lifted::Undef,
+ Unimpl => Lifted::Unimpl,
+ If(op) => Lifted::If(LiftedIf {
+ condition: self.lift_operand(op.condition),
+ dest_true: op.dest_true,
+ dest_false: op.dest_false,
+ }),
+
+ FloatConst(op) => Lifted::FloatConst(op),
+ Const(op) => Lifted::Const(op),
+ ConstPtr(op) => Lifted::ConstPtr(op),
+ Import(op) => Lifted::Import(op),
+ ExternPtr(op) => Lifted::ExternPtr(op),
+
+ ConstData(op) => Lifted::ConstData(LiftedConstantData {
+ constant_data: get_constant_data(
+ &self.function,
+ op.constant_data_kind,
+ op.constant_data_value,
+ op.size,
+ ),
+ }),
+ Jump(op) => Lifted::Jump(LiftedJump {
+ dest: self.lift_operand(op.dest),
+ }),
+ RetHint(op) => Lifted::RetHint(LiftedJump {
+ dest: self.lift_operand(op.dest),
+ }),
+ StoreSsa(op) => Lifted::StoreSsa(LiftedStoreSsa {
+ dest: self.lift_operand(op.dest),
+ dest_memory: op.dest_memory,
+ src_memory: op.src_memory,
+ src: self.lift_operand(op.src),
+ }),
+ StoreStructSsa(op) => Lifted::StoreStructSsa(LiftedStoreStructSsa {
+ dest: self.lift_operand(op.dest),
+ offset: op.offset,
+ dest_memory: op.dest_memory,
+ src_memory: op.src_memory,
+ src: self.lift_operand(op.src),
+ }),
+ StoreStruct(op) => Lifted::StoreStruct(LiftedStoreStruct {
+ dest: self.lift_operand(op.dest),
+ offset: op.offset,
+ src: self.lift_operand(op.src),
+ }),
+ Store(op) => Lifted::Store(LiftedStore {
+ dest: self.lift_operand(op.dest),
+ src: self.lift_operand(op.src),
+ }),
+ JumpTo(op) => Lifted::JumpTo(LiftedJumpTo {
+ dest: self.lift_operand(op.dest),
+ targets: OperandIter::new(&self.function, op.first_operand, op.num_operands)
+ .as_pairs()
+ .collect(),
+ }),
+ Goto(op) => Lifted::Goto(op),
+ FreeVarSlot(op) => Lifted::FreeVarSlot(op),
+ SetVarField(op) => Lifted::SetVarField(LiftedSetVarField {
+ dest: op.dest,
+ offset: op.offset,
+ src: self.lift_operand(op.src),
+ }),
+ SetVar(op) => Lifted::SetVar(LiftedSetVar {
+ dest: op.dest,
+ src: self.lift_operand(op.src),
+ }),
+ FreeVarSlotSsa(op) => Lifted::FreeVarSlotSsa(op),
+ SetVarSsaField(op) => Lifted::SetVarSsaField(LiftedSetVarSsaField {
+ dest: op.dest,
+ prev: op.prev,
+ offset: op.offset,
+ src: self.lift_operand(op.src),
+ }),
+ SetVarAliasedField(op) => Lifted::SetVarAliasedField(LiftedSetVarSsaField {
+ dest: op.dest,
+ prev: op.prev,
+ offset: op.offset,
+ src: self.lift_operand(op.src),
+ }),
+ SetVarAliased(op) => Lifted::SetVarAliased(LiftedSetVarAliased {
+ dest: op.dest,
+ prev: op.prev,
+ src: self.lift_operand(op.src),
+ }),
+ SetVarSsa(op) => Lifted::SetVarSsa(LiftedSetVarSsa {
+ dest: op.dest,
+ src: self.lift_operand(op.src),
+ }),
+ VarPhi(op) => Lifted::VarPhi(LiftedVarPhi {
+ dest: op.dest,
+ src: OperandIter::new(&self.function, op.first_operand, op.num_operands)
+ .as_ssa_vars()
+ .collect(),
+ }),
+ MemPhi(op) => Lifted::MemPhi(LiftedMemPhi {
+ dest_memory: op.dest_memory,
+ src_memory: OperandIter::new(&self.function, op.first_operand, op.num_operands)
+ .collect(),
+ }),
+ VarSplit(op) => Lifted::VarSplit(op),
+ SetVarSplit(op) => Lifted::SetVarSplit(LiftedSetVarSplit {
+ high: op.high,
+ low: op.low,
+ src: self.lift_operand(op.src),
+ }),
+ VarSplitSsa(op) => Lifted::VarSplitSsa(op),
+ SetVarSplitSsa(op) => Lifted::SetVarSplitSsa(LiftedSetVarSplitSsa {
+ high: op.high,
+ low: op.low,
+ src: self.lift_operand(op.src),
+ }),
+
+ Add(op) => Lifted::Add(self.lift_binary_op(op)),
+ Sub(op) => Lifted::Sub(self.lift_binary_op(op)),
+ And(op) => Lifted::And(self.lift_binary_op(op)),
+ Or(op) => Lifted::Or(self.lift_binary_op(op)),
+ Xor(op) => Lifted::Xor(self.lift_binary_op(op)),
+ Lsl(op) => Lifted::Lsl(self.lift_binary_op(op)),
+ Lsr(op) => Lifted::Lsr(self.lift_binary_op(op)),
+ Asr(op) => Lifted::Asr(self.lift_binary_op(op)),
+ Rol(op) => Lifted::Rol(self.lift_binary_op(op)),
+ Ror(op) => Lifted::Ror(self.lift_binary_op(op)),
+ Mul(op) => Lifted::Mul(self.lift_binary_op(op)),
+ MuluDp(op) => Lifted::MuluDp(self.lift_binary_op(op)),
+ MulsDp(op) => Lifted::MulsDp(self.lift_binary_op(op)),
+ Divu(op) => Lifted::Divu(self.lift_binary_op(op)),
+ DivuDp(op) => Lifted::DivuDp(self.lift_binary_op(op)),
+ Divs(op) => Lifted::Divs(self.lift_binary_op(op)),
+ DivsDp(op) => Lifted::DivsDp(self.lift_binary_op(op)),
+ Modu(op) => Lifted::Modu(self.lift_binary_op(op)),
+ ModuDp(op) => Lifted::ModuDp(self.lift_binary_op(op)),
+ Mods(op) => Lifted::Mods(self.lift_binary_op(op)),
+ ModsDp(op) => Lifted::ModsDp(self.lift_binary_op(op)),
+ CmpE(op) => Lifted::CmpE(self.lift_binary_op(op)),
+ CmpNe(op) => Lifted::CmpNe(self.lift_binary_op(op)),
+ CmpSlt(op) => Lifted::CmpSlt(self.lift_binary_op(op)),
+ CmpUlt(op) => Lifted::CmpUlt(self.lift_binary_op(op)),
+ CmpSle(op) => Lifted::CmpSle(self.lift_binary_op(op)),
+ CmpUle(op) => Lifted::CmpUle(self.lift_binary_op(op)),
+ CmpSge(op) => Lifted::CmpSge(self.lift_binary_op(op)),
+ CmpUge(op) => Lifted::CmpUge(self.lift_binary_op(op)),
+ CmpSgt(op) => Lifted::CmpSgt(self.lift_binary_op(op)),
+ CmpUgt(op) => Lifted::CmpUgt(self.lift_binary_op(op)),
+ TestBit(op) => Lifted::TestBit(self.lift_binary_op(op)),
+ AddOverflow(op) => Lifted::AddOverflow(self.lift_binary_op(op)),
+ FcmpE(op) => Lifted::FcmpE(self.lift_binary_op(op)),
+ FcmpNe(op) => Lifted::FcmpNe(self.lift_binary_op(op)),
+ FcmpLt(op) => Lifted::FcmpLt(self.lift_binary_op(op)),
+ FcmpLe(op) => Lifted::FcmpLe(self.lift_binary_op(op)),
+ FcmpGe(op) => Lifted::FcmpGe(self.lift_binary_op(op)),
+ FcmpGt(op) => Lifted::FcmpGt(self.lift_binary_op(op)),
+ FcmpO(op) => Lifted::FcmpO(self.lift_binary_op(op)),
+ FcmpUo(op) => Lifted::FcmpUo(self.lift_binary_op(op)),
+ Fadd(op) => Lifted::Fadd(self.lift_binary_op(op)),
+ Fsub(op) => Lifted::Fsub(self.lift_binary_op(op)),
+ Fmul(op) => Lifted::Fmul(self.lift_binary_op(op)),
+ Fdiv(op) => Lifted::Fdiv(self.lift_binary_op(op)),
+
+ Adc(op) => Lifted::Adc(self.lift_binary_op_carry(op)),
+ Sbb(op) => Lifted::Sbb(self.lift_binary_op_carry(op)),
+ Rlc(op) => Lifted::Rlc(self.lift_binary_op_carry(op)),
+ Rrc(op) => Lifted::Rrc(self.lift_binary_op_carry(op)),
+
+ Call(op) => Lifted::Call(self.lift_call(op)),
+ Tailcall(op) => Lifted::Tailcall(self.lift_call(op)),
+
+ Intrinsic(op) => Lifted::Intrinsic(LiftedIntrinsic {
+ output: OperandIter::new(&self.function, op.first_output, op.num_outputs)
+ .as_vars()
+ .collect(),
+ intrinsic: ILIntrinsic::new(self.function.get_function().arch(), op.intrinsic),
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
+ Syscall(op) => Lifted::Syscall(LiftedSyscallCall {
+ output: OperandIter::new(&self.function, op.first_output, op.num_outputs)
+ .as_vars()
+ .collect(),
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
+ IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa {
+ output: OperandIter::new(&self.function, op.first_output, op.num_outputs)
+ .as_ssa_vars()
+ .collect(),
+ intrinsic: ILIntrinsic::new(self.function.get_function().arch(), op.intrinsic),
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
+
+ CallSsa(op) => Lifted::CallSsa(self.lift_call_ssa(op)),
+ TailcallSsa(op) => Lifted::TailcallSsa(self.lift_call_ssa(op)),
+
+ CallUntypedSsa(op) => Lifted::CallUntypedSsa(self.lift_call_untyped_ssa(op)),
+ TailcallUntypedSsa(op) => Lifted::TailcallUntypedSsa(self.lift_call_untyped_ssa(op)),
+
+ SyscallSsa(op) => Lifted::SyscallSsa(LiftedSyscallSsa {
+ output: get_call_output_ssa(&self.function, op.output).collect(),
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ src_memory: op.src_memory,
+ }),
+ SyscallUntypedSsa(op) => Lifted::SyscallUntypedSsa(LiftedSyscallUntypedSsa {
+ output: get_call_output_ssa(&self.function, op.output).collect(),
+ params: get_call_params_ssa(&self.function, op.params)
+ .map(|param| param.lift())
+ .collect(),
+ stack: self.lift_operand(op.stack),
+ }),
+
+ CallUntyped(op) => Lifted::CallUntyped(self.lift_call_untyped(op)),
+ TailcallUntyped(op) => Lifted::TailcallUntyped(self.lift_call_untyped(op)),
+ SyscallUntyped(op) => Lifted::SyscallUntyped(LiftedSyscallUntyped {
+ output: get_call_output(&self.function, op.output).collect(),
+ params: get_call_params(&self.function, op.params)
+ .map(|param| param.lift())
+ .collect(),
+ stack: self.lift_operand(op.stack),
+ }),
+
+ Neg(op) => Lifted::Neg(self.lift_unary_op(op)),
+ Not(op) => Lifted::Not(self.lift_unary_op(op)),
+ Sx(op) => Lifted::Sx(self.lift_unary_op(op)),
+ Zx(op) => Lifted::Zx(self.lift_unary_op(op)),
+ LowPart(op) => Lifted::LowPart(self.lift_unary_op(op)),
+ BoolToInt(op) => Lifted::BoolToInt(self.lift_unary_op(op)),
+ UnimplMem(op) => Lifted::UnimplMem(self.lift_unary_op(op)),
+ Fsqrt(op) => Lifted::Fsqrt(self.lift_unary_op(op)),
+ Fneg(op) => Lifted::Fneg(self.lift_unary_op(op)),
+ Fabs(op) => Lifted::Fabs(self.lift_unary_op(op)),
+ FloatToInt(op) => Lifted::FloatToInt(self.lift_unary_op(op)),
+ IntToFloat(op) => Lifted::IntToFloat(self.lift_unary_op(op)),
+ FloatConv(op) => Lifted::FloatConv(self.lift_unary_op(op)),
+ RoundToInt(op) => Lifted::RoundToInt(self.lift_unary_op(op)),
+ Floor(op) => Lifted::Floor(self.lift_unary_op(op)),
+ Ceil(op) => Lifted::Ceil(self.lift_unary_op(op)),
+ Ftrunc(op) => Lifted::Ftrunc(self.lift_unary_op(op)),
+ Load(op) => Lifted::Load(self.lift_unary_op(op)),
+
+ LoadStruct(op) => Lifted::LoadStruct(LiftedLoadStruct {
+ src: self.lift_operand(op.src),
+ offset: op.offset,
+ }),
+ LoadStructSsa(op) => Lifted::LoadStructSsa(LiftedLoadStructSsa {
+ src: self.lift_operand(op.src),
+ offset: op.offset,
+ src_memory: op.src_memory,
+ }),
+ LoadSsa(op) => Lifted::LoadSsa(LiftedLoadSsa {
+ src: self.lift_operand(op.src),
+ src_memory: op.src_memory,
+ }),
+ Ret(op) => Lifted::Ret(LiftedRet {
+ src: OperandIter::new(&self.function, op.first_operand, op.num_operands)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
+ SeparateParamList(op) => Lifted::SeparateParamList(LiftedSeparateParamList {
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
+ SharedParamSlot(op) => Lifted::SharedParamSlot(LiftedSharedParamSlot {
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
+ Var(op) => Lifted::Var(op),
+ AddressOf(op) => Lifted::AddressOf(op),
+ VarField(op) => Lifted::VarField(op),
+ AddressOfField(op) => Lifted::AddressOfField(op),
+ VarSsa(op) => Lifted::VarSsa(op),
+ VarAliased(op) => Lifted::VarAliased(op),
+ VarSsaField(op) => Lifted::VarSsaField(op),
+ VarAliasedField(op) => Lifted::VarAliasedField(op),
+ Trap(op) => Lifted::Trap(op),
+ };
+
+ MediumLevelILLiftedInstruction {
+ function: self.function.clone(),
+ address: self.address,
+ kind,
}
}
- pub fn address(&self) -> u64 {
- use MediumLevelILInstruction::*;
- match self {
- Nop(op) => op.address,
- Noret(op) => op.address,
- Bp(op) => op.address,
- Undef(op) => op.address,
- Unimpl(op) => op.address,
- If(op) => op.address,
- FloatConst(op) => op.address,
- Const(op) => op.address,
- ConstPtr(op) => op.address,
- Import(op) => op.address,
- ExternPtr(op) => op.address,
- ConstData(op) => op.address,
- Jump(op) => op.address,
- RetHint(op) => op.address,
- StoreSsa(op) => op.address,
- StoreStructSsa(op) => op.address,
- StoreStruct(op) => op.address,
- Store(op) => op.address,
- JumpTo(op) => op.address,
- Goto(op) => op.address,
- FreeVarSlot(op) => op.address,
- SetVarField(op) => op.address,
- SetVar(op) => op.address,
- FreeVarSlotSsa(op) => op.address,
- SetVarSsaField(op) => op.address,
- SetVarAliasedField(op) => op.address,
- SetVarAliased(op) => op.address,
- SetVarSsa(op) => op.address,
- VarPhi(op) => op.address,
- MemPhi(op) => op.address,
- VarSplit(op) => op.address,
- SetVarSplit(op) => op.address,
- VarSplitSsa(op) => op.address,
- SetVarSplitSsa(op) => op.address,
- Add(op) => op.address,
- Sub(op) => op.address,
- And(op) => op.address,
- Or(op) => op.address,
- Xor(op) => op.address,
- Lsl(op) => op.address,
- Lsr(op) => op.address,
- Asr(op) => op.address,
- Rol(op) => op.address,
- Ror(op) => op.address,
- Mul(op) => op.address,
- MuluDp(op) => op.address,
- MulsDp(op) => op.address,
- Divu(op) => op.address,
- DivuDp(op) => op.address,
- Divs(op) => op.address,
- DivsDp(op) => op.address,
- Modu(op) => op.address,
- ModuDp(op) => op.address,
- Mods(op) => op.address,
- ModsDp(op) => op.address,
- CmpE(op) => op.address,
- CmpNe(op) => op.address,
- CmpSlt(op) => op.address,
- CmpUlt(op) => op.address,
- CmpSle(op) => op.address,
- CmpUle(op) => op.address,
- CmpSge(op) => op.address,
- CmpUge(op) => op.address,
- CmpSgt(op) => op.address,
- CmpUgt(op) => op.address,
- TestBit(op) => op.address,
- AddOverflow(op) => op.address,
- FcmpE(op) => op.address,
- FcmpNe(op) => op.address,
- FcmpLt(op) => op.address,
- FcmpLe(op) => op.address,
- FcmpGe(op) => op.address,
- FcmpGt(op) => op.address,
- FcmpO(op) => op.address,
- FcmpUo(op) => op.address,
- Fadd(op) => op.address,
- Fsub(op) => op.address,
- Fmul(op) => op.address,
- Fdiv(op) => op.address,
- Adc(op) => op.address,
- Sbb(op) => op.address,
- Rlc(op) => op.address,
- Rrc(op) => op.address,
- Call(op) => op.address,
- Tailcall(op) => op.address,
- Syscall(op) => op.address,
- Intrinsic(op) => op.address,
- IntrinsicSsa(op) => op.address,
- CallSsa(op) => op.address,
- TailcallSsa(op) => op.address,
- CallUntypedSsa(op) => op.address,
- TailcallUntypedSsa(op) => op.address,
- SyscallSsa(op) => op.address,
- SyscallUntypedSsa(op) => op.address,
- CallUntyped(op) => op.address,
- TailcallUntyped(op) => op.address,
- SyscallUntyped(op) => op.address,
- SeparateParamList(op) => op.address,
- SharedParamSlot(op) => op.address,
- Neg(op) => op.address,
- Not(op) => op.address,
- Sx(op) => op.address,
- Zx(op) => op.address,
- LowPart(op) => op.address,
- BoolToInt(op) => op.address,
- UnimplMem(op) => op.address,
- Fsqrt(op) => op.address,
- Fneg(op) => op.address,
- Fabs(op) => op.address,
- FloatToInt(op) => op.address,
- IntToFloat(op) => op.address,
- FloatConv(op) => op.address,
- RoundToInt(op) => op.address,
- Floor(op) => op.address,
- Ceil(op) => op.address,
- Ftrunc(op) => op.address,
- Load(op) => op.address,
- LoadStruct(op) => op.address,
- LoadStructSsa(op) => op.address,
- LoadSsa(op) => op.address,
- Ret(op) => op.address,
- Var(op) => op.address,
- AddressOf(op) => op.address,
- VarField(op) => op.address,
- AddressOfField(op) => op.address,
- VarSsa(op) => op.address,
- VarAliased(op) => op.address,
- VarSsaField(op) => op.address,
- VarAliasedField(op) => op.address,
- Trap(op) => op.address,
+ fn lift_operand(&self, expr_idx: usize) -> Box<MediumLevelILLiftedInstruction> {
+ Box::new(self.function.lifted_instruction_from_idx(expr_idx))
+ }
+
+ fn lift_binary_op(&self, op: BinaryOp) -> LiftedBinaryOp {
+ LiftedBinaryOp {
+ left: self.lift_operand(op.left),
+ right: self.lift_operand(op.right),
}
}
- pub fn lift(&self) -> MediumLevelILLiftedInstruction {
- use MediumLevelILInstruction::*;
- use MediumLevelILLiftedInstruction as Lifted;
+ fn lift_binary_op_carry(&self, op: BinaryOpCarry) -> LiftedBinaryOpCarry {
+ LiftedBinaryOpCarry {
+ left: self.lift_operand(op.left),
+ right: self.lift_operand(op.right),
+ carry: self.lift_operand(op.carry),
+ }
+ }
- match self {
- Nop(op) => Lifted::Nop(op.clone()),
- Noret(op) => Lifted::Noret(op.clone()),
- Bp(op) => Lifted::Bp(op.clone()),
- Undef(op) => Lifted::Undef(op.clone()),
- Unimpl(op) => Lifted::Unimpl(op.clone()),
- If(op) => Lifted::If(op.lift()),
- FloatConst(op) => Lifted::FloatConst(op.clone()),
- Const(op) => Lifted::Const(op.clone()),
- ConstPtr(op) => Lifted::ConstPtr(op.clone()),
- Import(op) => Lifted::Import(op.clone()),
- ExternPtr(op) => Lifted::ExternPtr(op.clone()),
- ConstData(op) => Lifted::ConstData(op.lift()),
- Jump(op) => Lifted::Jump(op.lift()),
- RetHint(op) => Lifted::RetHint(op.lift()),
- StoreSsa(op) => Lifted::StoreSsa(op.lift()),
- StoreStructSsa(op) => Lifted::StoreStructSsa(op.lift()),
- StoreStruct(op) => Lifted::StoreStruct(op.lift()),
- Store(op) => Lifted::Store(op.lift()),
- JumpTo(op) => Lifted::JumpTo(op.lift()),
- Goto(op) => Lifted::Goto(op.clone()),
- FreeVarSlot(op) => Lifted::FreeVarSlot(op.clone()),
- SetVarField(op) => Lifted::SetVarField(op.lift()),
- SetVar(op) => Lifted::SetVar(op.lift()),
- FreeVarSlotSsa(op) => Lifted::FreeVarSlotSsa(op.lift()),
- SetVarSsaField(op) => Lifted::SetVarSsaField(op.lift()),
- SetVarAliasedField(op) => Lifted::SetVarAliasedField(op.lift()),
- SetVarAliased(op) => Lifted::SetVarAliased(op.lift()),
- SetVarSsa(op) => Lifted::SetVarSsa(op.lift()),
- VarPhi(op) => Lifted::VarPhi(op.lift()),
- MemPhi(op) => Lifted::MemPhi(op.lift()),
- VarSplit(op) => Lifted::VarSplit(op.lift()),
- SetVarSplit(op) => Lifted::SetVarSplit(op.lift()),
- VarSplitSsa(op) => Lifted::VarSplitSsa(op.lift()),
- SetVarSplitSsa(op) => Lifted::SetVarSplitSsa(op.lift()),
- Add(op) => Lifted::Add(op.lift()),
- Sub(op) => Lifted::Sub(op.lift()),
- And(op) => Lifted::And(op.lift()),
- Or(op) => Lifted::Or(op.lift()),
- Xor(op) => Lifted::Xor(op.lift()),
- Lsl(op) => Lifted::Lsl(op.lift()),
- Lsr(op) => Lifted::Lsr(op.lift()),
- Asr(op) => Lifted::Asr(op.lift()),
- Rol(op) => Lifted::Rol(op.lift()),
- Ror(op) => Lifted::Ror(op.lift()),
- Mul(op) => Lifted::Mul(op.lift()),
- MuluDp(op) => Lifted::MuluDp(op.lift()),
- MulsDp(op) => Lifted::MulsDp(op.lift()),
- Divu(op) => Lifted::Divu(op.lift()),
- DivuDp(op) => Lifted::DivuDp(op.lift()),
- Divs(op) => Lifted::Divs(op.lift()),
- DivsDp(op) => Lifted::DivsDp(op.lift()),
- Modu(op) => Lifted::Modu(op.lift()),
- ModuDp(op) => Lifted::ModuDp(op.lift()),
- Mods(op) => Lifted::Mods(op.lift()),
- ModsDp(op) => Lifted::ModsDp(op.lift()),
- CmpE(op) => Lifted::CmpE(op.lift()),
- CmpNe(op) => Lifted::CmpNe(op.lift()),
- CmpSlt(op) => Lifted::CmpSlt(op.lift()),
- CmpUlt(op) => Lifted::CmpUlt(op.lift()),
- CmpSle(op) => Lifted::CmpSle(op.lift()),
- CmpUle(op) => Lifted::CmpUle(op.lift()),
- CmpSge(op) => Lifted::CmpSge(op.lift()),
- CmpUge(op) => Lifted::CmpUge(op.lift()),
- CmpSgt(op) => Lifted::CmpSgt(op.lift()),
- CmpUgt(op) => Lifted::CmpUgt(op.lift()),
- TestBit(op) => Lifted::TestBit(op.lift()),
- AddOverflow(op) => Lifted::AddOverflow(op.lift()),
- FcmpE(op) => Lifted::FcmpE(op.lift()),
- FcmpNe(op) => Lifted::FcmpNe(op.lift()),
- FcmpLt(op) => Lifted::FcmpLt(op.lift()),
- FcmpLe(op) => Lifted::FcmpLe(op.lift()),
- FcmpGe(op) => Lifted::FcmpGe(op.lift()),
- FcmpGt(op) => Lifted::FcmpGt(op.lift()),
- FcmpO(op) => Lifted::FcmpO(op.lift()),
- FcmpUo(op) => Lifted::FcmpUo(op.lift()),
- Fadd(op) => Lifted::Fadd(op.lift()),
- Fsub(op) => Lifted::Fsub(op.lift()),
- Fmul(op) => Lifted::Fmul(op.lift()),
- Fdiv(op) => Lifted::Fdiv(op.lift()),
- Adc(op) => Lifted::Adc(op.lift()),
- Sbb(op) => Lifted::Sbb(op.lift()),
- Rlc(op) => Lifted::Rlc(op.lift()),
- Rrc(op) => Lifted::Rrc(op.lift()),
- Call(op) => Lifted::Call(op.lift()),
- Tailcall(op) => Lifted::Tailcall(op.lift()),
- Intrinsic(op) => Lifted::Intrinsic(op.lift()),
- Syscall(op) => Lifted::Syscall(op.lift()),
- IntrinsicSsa(op) => Lifted::IntrinsicSsa(op.lift()),
- CallSsa(op) => Lifted::CallSsa(op.lift()),
- TailcallSsa(op) => Lifted::TailcallSsa(op.lift()),
- CallUntypedSsa(op) => Lifted::CallUntypedSsa(op.lift()),
- TailcallUntypedSsa(op) => Lifted::TailcallUntypedSsa(op.lift()),
- SyscallSsa(op) => Lifted::SyscallSsa(op.lift()),
- SyscallUntypedSsa(op) => Lifted::SyscallUntypedSsa(op.lift()),
- CallUntyped(op) => Lifted::CallUntyped(op.lift()),
- TailcallUntyped(op) => Lifted::TailcallUntyped(op.lift()),
- SyscallUntyped(op) => Lifted::SyscallUntyped(op.lift()),
- SeparateParamList(op) => Lifted::SeparateParamList(op.lift()),
- SharedParamSlot(op) => Lifted::SharedParamSlot(op.lift()),
- Neg(op) => Lifted::Neg(op.lift()),
- Not(op) => Lifted::Not(op.lift()),
- Sx(op) => Lifted::Sx(op.lift()),
- Zx(op) => Lifted::Zx(op.lift()),
- LowPart(op) => Lifted::LowPart(op.lift()),
- BoolToInt(op) => Lifted::BoolToInt(op.lift()),
- UnimplMem(op) => Lifted::UnimplMem(op.lift()),
- Fsqrt(op) => Lifted::Fsqrt(op.lift()),
- Fneg(op) => Lifted::Fneg(op.lift()),
- Fabs(op) => Lifted::Fabs(op.lift()),
- FloatToInt(op) => Lifted::FloatToInt(op.lift()),
- IntToFloat(op) => Lifted::IntToFloat(op.lift()),
- FloatConv(op) => Lifted::FloatConv(op.lift()),
- RoundToInt(op) => Lifted::RoundToInt(op.lift()),
- Floor(op) => Lifted::Floor(op.lift()),
- Ceil(op) => Lifted::Ceil(op.lift()),
- Ftrunc(op) => Lifted::Ftrunc(op.lift()),
- Load(op) => Lifted::Load(op.lift()),
- LoadStruct(op) => Lifted::LoadStruct(op.lift()),
- LoadStructSsa(op) => Lifted::LoadStructSsa(op.lift()),
- LoadSsa(op) => Lifted::LoadSsa(op.lift()),
- Ret(op) => Lifted::Ret(op.lift()),
- Var(op) => Lifted::Var(op.clone()),
- AddressOf(op) => Lifted::AddressOf(op.clone()),
- VarField(op) => Lifted::VarField(op.clone()),
- AddressOfField(op) => Lifted::AddressOfField(op.clone()),
- VarSsa(op) => Lifted::VarSsa(op.clone()),
- VarAliased(op) => Lifted::VarAliased(op.clone()),
- VarSsaField(op) => Lifted::VarSsaField(op.clone()),
- VarAliasedField(op) => Lifted::VarAliasedField(op.clone()),
- Trap(op) => Lifted::Trap(op.clone()),
+ fn lift_unary_op(&self, op: UnaryOp) -> LiftedUnaryOp {
+ LiftedUnaryOp {
+ src: self.lift_operand(op.src),
}
}
- pub fn operands(&self) -> Box<dyn Iterator<Item = (&'static str, MediumLevelILOperand)> + '_> {
- use MediumLevelILInstruction::*;
- match self {
- Nop(_op) | Noret(_op) | Bp(_op) | Undef(_op) | Unimpl(_op) => Box::new([].into_iter()),
- If(op) => Box::new(op.operands()),
- FloatConst(op) => Box::new(op.operands()),
- Const(op) | ConstPtr(op) | Import(op) => Box::new(op.operands()),
- ExternPtr(op) => Box::new(op.operands()),
- ConstData(op) => Box::new(op.operands()),
- Jump(op) | RetHint(op) => Box::new(op.operands()),
- StoreSsa(op) => Box::new(op.operands()),
- StoreStructSsa(op) => Box::new(op.operands()),
- StoreStruct(op) => Box::new(op.operands()),
- Store(op) => Box::new(op.operands()),
- JumpTo(op) => Box::new(op.operands()),
- Goto(op) => Box::new(op.operands()),
- FreeVarSlot(op) => Box::new(op.operands()),
- SetVarField(op) => Box::new(op.operands()),
- SetVar(op) => Box::new(op.operands()),
- FreeVarSlotSsa(op) => Box::new(op.operands()),
- SetVarSsaField(op) | SetVarAliasedField(op) => Box::new(op.operands()),
- SetVarAliased(op) => Box::new(op.operands()),
- SetVarSsa(op) => Box::new(op.operands()),
- VarPhi(op) => Box::new(op.operands()),
- MemPhi(op) => Box::new(op.operands()),
- VarSplit(op) => Box::new(op.operands()),
- SetVarSplit(op) => Box::new(op.operands()),
- VarSplitSsa(op) => Box::new(op.operands()),
- SetVarSplitSsa(op) => Box::new(op.operands()),
- Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
- | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
- | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op)
- | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
- | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | FcmpE(op)
- | FcmpNe(op) | FcmpLt(op) | FcmpLe(op) | FcmpGe(op) | FcmpGt(op) | FcmpO(op)
- | FcmpUo(op) | Fadd(op) | Fsub(op) | Fmul(op) | Fdiv(op) => Box::new(op.operands()),
- Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => Box::new(op.operands()),
- Call(op) | Tailcall(op) => Box::new(op.operands()),
- Syscall(op) => Box::new(op.operands()),
- Intrinsic(op) => Box::new(op.operands()),
- IntrinsicSsa(op) => Box::new(op.operands()),
- CallSsa(op) | TailcallSsa(op) => Box::new(op.operands()),
- CallUntypedSsa(op) | TailcallUntypedSsa(op) => Box::new(op.operands()),
- SyscallSsa(op) => Box::new(op.operands()),
- SyscallUntypedSsa(op) => Box::new(op.operands()),
- CallUntyped(op) | TailcallUntyped(op) => Box::new(op.operands()),
- SyscallUntyped(op) => Box::new(op.operands()),
- SeparateParamList(op) => Box::new(op.operands()),
- SharedParamSlot(op) => Box::new(op.operands()),
- Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op)
- | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
- | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) | Load(op) => {
- Box::new(op.operands())
- }
- LoadStruct(op) => Box::new(op.operands()),
- LoadStructSsa(op) => Box::new(op.operands()),
- LoadSsa(op) => Box::new(op.operands()),
- Ret(op) => Box::new(op.operands()),
- Var(op) | AddressOf(op) => Box::new(op.operands()),
- VarField(op) | AddressOfField(op) => Box::new(op.operands()),
- VarSsa(op) | VarAliased(op) => Box::new(op.operands()),
- VarSsaField(op) | VarAliasedField(op) => Box::new(op.operands()),
- Trap(op) => Box::new(op.operands()),
+ fn lift_call(&self, op: Call) -> LiftedCall {
+ LiftedCall {
+ output: OperandIter::new(&self.function, op.first_output, op.num_outputs)
+ .as_vars()
+ .collect(),
+ dest: self.lift_operand(op.dest),
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ }
+ }
+
+ fn lift_call_untyped(&self, op: CallUntyped) -> LiftedCallUntyped {
+ LiftedCallUntyped {
+ output: get_call_output(&self.function, op.output).collect(),
+ dest: self.lift_operand(op.dest),
+ params: get_call_params(&self.function, op.params)
+ .map(|expr| expr.lift())
+ .collect(),
+ stack: self.lift_operand(op.stack),
+ }
+ }
+
+ fn lift_call_ssa(&self, op: CallSsa) -> LiftedCallSsa {
+ LiftedCallSsa {
+ output: get_call_output_ssa(&self.function, op.output).collect(),
+ dest: self.lift_operand(op.dest),
+ params: OperandIter::new(&self.function, op.first_param, op.num_params)
+ .as_exprs()
+ .map(|expr| expr.lift())
+ .collect(),
+ src_memory: op.src_memory,
+ }
+ }
+
+ fn lift_call_untyped_ssa(&self, op: CallUntypedSsa) -> LiftedCallUntypedSsa {
+ LiftedCallUntypedSsa {
+ output: get_call_output_ssa(&self.function, op.output).collect(),
+ dest: self.lift_operand(op.dest),
+ params: get_call_params_ssa(&self.function, op.params)
+ .map(|param| param.lift())
+ .collect(),
+ stack: self.lift_operand(op.stack),
}
}
}
diff --git a/rust/src/mlil/lift.rs b/rust/src/mlil/lift.rs
index bf7f16db..0cf669bf 100644
--- a/rust/src/mlil/lift.rs
+++ b/rust/src/mlil/lift.rs
@@ -1,12 +1,43 @@
+use std::collections::HashMap;
+
+use crate::rc::Ref;
+use crate::types;
+use crate::types::ILIntrinsic;
+use crate::types::{SSAVariable, Variable};
+
use super::operation::*;
+use super::MediumLevelILFunction;
+
+#[derive(Clone)]
+pub enum MediumLevelILLiftedOperand {
+ ConstantData(types::ConstantData),
+ Intrinsic(ILIntrinsic),
+ Expr(MediumLevelILLiftedInstruction),
+ ExprList(Vec<MediumLevelILLiftedInstruction>),
+ Float(f64),
+ Int(u64),
+ IntList(Vec<u64>),
+ TargetMap(HashMap<u64, u64>),
+ Var(Variable),
+ VarList(Vec<Variable>),
+ VarSsa(SSAVariable),
+ VarSsaList(Vec<SSAVariable>),
+}
#[derive(Clone, Debug, PartialEq)]
-pub enum MediumLevelILLiftedInstruction {
- Nop(NoArgs),
- Noret(NoArgs),
- Bp(NoArgs),
- Undef(NoArgs),
- Unimpl(NoArgs),
+pub struct MediumLevelILLiftedInstruction {
+ pub function: Ref<MediumLevelILFunction>,
+ pub address: u64,
+ pub kind: MediumLevelILLiftedInstructionKind,
+}
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum MediumLevelILLiftedInstructionKind {
+ Nop,
+ Noret,
+ Bp,
+ Undef,
+ Unimpl,
If(LiftedIf),
FloatConst(FloatConst),
Const(Constant),
@@ -133,3 +164,210 @@ pub enum MediumLevelILLiftedInstruction {
VarAliasedField(VarSsaField),
Trap(Trap),
}
+
+impl MediumLevelILLiftedInstruction {
+ pub fn operands(&self) -> Vec<(&'static str, MediumLevelILLiftedOperand)> {
+ use MediumLevelILLiftedInstructionKind::*;
+ use MediumLevelILLiftedOperand as Operand;
+ match &self.kind {
+ Nop | Noret | Bp | Undef | Unimpl => vec![],
+ If(op) => vec![
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("dest_true", Operand::Int(op.dest_true)),
+ ("dest_false", Operand::Int(op.dest_false)),
+ ],
+ FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
+ Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
+ ExternPtr(op) => vec![
+ ("constant", Operand::Int(op.constant)),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ ConstData(op) => vec![(
+ "constant_data",
+ Operand::ConstantData(op.constant_data.clone()),
+ )],
+ Jump(op) | RetHint(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
+ StoreSsa(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ StoreStructSsa(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("offset", Operand::Int(op.offset)),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ StoreStruct(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("offset", Operand::Int(op.offset)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ Store(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ JumpTo(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("targets", Operand::TargetMap(op.targets.clone())),
+ ],
+ Goto(op) => vec![("dest", Operand::Int(op.dest))],
+ FreeVarSlot(op) => vec![("dest", Operand::Var(op.dest))],
+ SetVarField(op) => vec![
+ ("dest", Operand::Var(op.dest)),
+ ("offset", Operand::Int(op.offset)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ SetVar(op) => vec![
+ ("dest", Operand::Var(op.dest)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ FreeVarSlotSsa(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("prev", Operand::VarSsa(op.prev)),
+ ],
+ SetVarSsaField(op) | SetVarAliasedField(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("prev", Operand::VarSsa(op.prev)),
+ ("offset", Operand::Int(op.offset)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ SetVarAliased(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("prev", Operand::VarSsa(op.prev)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ SetVarSsa(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ VarPhi(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("src", Operand::VarSsaList(op.src.clone())),
+ ],
+ MemPhi(op) => vec![
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src_memory", Operand::IntList(op.src_memory.clone())),
+ ],
+ VarSplit(op) => vec![
+ ("high", Operand::Var(op.high)),
+ ("low", Operand::Var(op.low)),
+ ],
+ SetVarSplit(op) => vec![
+ ("high", Operand::Var(op.high)),
+ ("low", Operand::Var(op.low)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ VarSplitSsa(op) => vec![
+ ("high", Operand::VarSsa(op.high)),
+ ("low", Operand::VarSsa(op.low)),
+ ],
+ SetVarSplitSsa(op) => vec![
+ ("high", Operand::VarSsa(op.high)),
+ ("low", Operand::VarSsa(op.low)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
+ | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
+ | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op)
+ | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
+ | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | FcmpE(op)
+ | FcmpNe(op) | FcmpLt(op) | FcmpLe(op) | FcmpGe(op) | FcmpGt(op) | FcmpO(op)
+ | FcmpUo(op) | Fadd(op) | Fsub(op) | Fmul(op) | Fdiv(op) => vec![
+ ("left", Operand::Expr(*op.left.clone())),
+ ("right", Operand::Expr(*op.right.clone())),
+ ],
+ Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
+ ("left", Operand::Expr(*op.left.clone())),
+ ("right", Operand::Expr(*op.right.clone())),
+ ("carry", Operand::Expr(*op.carry.clone())),
+ ],
+ Call(op) | Tailcall(op) => vec![
+ ("output", Operand::VarList(op.output.clone())),
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ],
+ Syscall(op) => vec![
+ ("output", Operand::VarList(op.output.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ],
+ Intrinsic(op) => vec![
+ ("output", Operand::VarList(op.output.clone())),
+ ("intrinsic", Operand::Intrinsic(op.intrinsic)),
+ ("params", Operand::ExprList(op.params.clone())),
+ ],
+ IntrinsicSsa(op) => vec![
+ ("output", Operand::VarSsaList(op.output.clone())),
+ ("intrinsic", Operand::Intrinsic(op.intrinsic)),
+ ("params", Operand::ExprList(op.params.clone())),
+ ],
+ CallSsa(op) | TailcallSsa(op) => vec![
+ ("output", Operand::VarSsaList(op.output.clone())),
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ CallUntypedSsa(op) | TailcallUntypedSsa(op) => vec![
+ ("output", Operand::VarSsaList(op.output.clone())),
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("stack", Operand::Expr(*op.stack.clone())),
+ ],
+ SyscallSsa(op) => vec![
+ ("output", Operand::VarSsaList(op.output.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ SyscallUntypedSsa(op) => vec![
+ ("output", Operand::VarSsaList(op.output.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("stack", Operand::Expr(*op.stack.clone())),
+ ],
+ CallUntyped(op) | TailcallUntyped(op) => vec![
+ ("output", Operand::VarList(op.output.clone())),
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("stack", Operand::Expr(*op.stack.clone())),
+ ],
+ SyscallUntyped(op) => vec![
+ ("output", Operand::VarList(op.output.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("stack", Operand::Expr(*op.stack.clone())),
+ ],
+ Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op)
+ | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
+ | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) | Load(op) => {
+ vec![("src", Operand::Expr(*op.src.clone()))]
+ }
+ LoadStruct(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ LoadStructSsa(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("offset", Operand::Int(op.offset)),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ LoadSsa(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
+ SeparateParamList(op) => vec![("params", Operand::ExprList(op.params.clone()))],
+ SharedParamSlot(op) => vec![("params", Operand::ExprList(op.params.clone()))],
+ Var(op) | AddressOf(op) => vec![("src", Operand::Var(op.src))],
+ VarField(op) | AddressOfField(op) => vec![
+ ("src", Operand::Var(op.src)),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ VarSsa(op) | VarAliased(op) => vec![("src", Operand::VarSsa(op.src))],
+ VarSsaField(op) | VarAliasedField(op) => vec![
+ ("src", Operand::VarSsa(op.src)),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ Trap(op) => vec![("vector", Operand::Int(op.vector))],
+ }
+ }
+}
diff --git a/rust/src/mlil/operation.rs b/rust/src/mlil/operation.rs
index 876337dd..544fe275 100644
--- a/rust/src/mlil/operation.rs
+++ b/rust/src/mlil/operation.rs
@@ -14,189 +14,170 @@ use crate::types::{SSAVariable, Variable};
use super::{MediumLevelILFunction, MediumLevelILInstruction, MediumLevelILLiftedInstruction};
-pub enum MediumLevelILOperand {
- ConstantData(types::ConstantData),
- Intrinsic(ILIntrinsic),
- Expr(MediumLevelILInstruction),
- ExprList(OperandExprList),
- Float(f64),
- Int(u64),
- IntList(OperandList),
- TargetMap(OperandDubleList),
- Var(Variable),
- VarList(OperandVariableList),
- VarSsa(SSAVariable),
- VarSsaList(OperandSSAVariableList),
-}
-
-// Iterator for the get_list, this is better then a inline iterator because
-// this also implement ExactSizeIterator, what a inline iterator does not.
-pub struct OperandList {
+pub struct OperandIter {
function: Ref<MediumLevelILFunction>,
remaining: usize,
- next_node_idx: Option<usize>,
-
- current_node: core::array::IntoIter<u64, 4>,
+ next_iter_idx: Option<usize>,
+ current_iter: OperandIterInner,
}
-impl OperandList {
- fn new(function: &MediumLevelILFunction, idx: usize, number: usize) -> Self {
- // alternative to core::array::IntoIter::empty();
- let mut iter = [0; 4].into_iter();
- for _ in 0..4 {
- let _ = iter.next();
- }
+
+impl OperandIter {
+ pub(crate) fn new(function: &MediumLevelILFunction, idx: usize, number: usize) -> Self {
Self {
function: function.to_owned(),
remaining: number,
- next_node_idx: Some(idx),
- current_node: iter,
+ next_iter_idx: Some(idx),
+ current_iter: OperandIterInner::empty(),
}
}
- fn duble(self) -> OperandDubleList {
+
+ pub fn as_pairs(self) -> OperandPairIter {
assert_eq!(self.len() % 2, 0);
- OperandDubleList(self)
+ OperandPairIter(self)
}
- fn map_expr(self) -> OperandExprList {
- OperandExprList(self)
+
+ pub fn as_exprs(self) -> OperandExprIter {
+ OperandExprIter(self)
}
- fn map_var(self) -> OperandVariableList {
- OperandVariableList(self)
+
+ pub fn as_vars(self) -> OperandVarIter {
+ OperandVarIter(self)
}
- fn map_ssa_var(self) -> OperandSSAVariableList {
- OperandSSAVariableList(self.duble())
+
+ pub fn as_ssa_vars(self) -> OperandSSAVarIter {
+ OperandSSAVarIter(self.as_pairs())
}
}
-impl Iterator for OperandList {
- type Item = u64;
+impl Iterator for OperandIter {
+ type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
- // if there is an item in this node, return it
- if let Some(current_node) = self.current_node.next() {
- return Some(current_node);
- }
+ if let Some(item) = self.current_iter.next() {
+ self.remaining -= 1;
+ Some(item)
+ } else {
+ // Will short-circuit and return `None` once iter is exhausted
+ let iter_idx = self.next_iter_idx?;
+ let node = unsafe { BNGetMediumLevelILByIndex(self.function.handle, iter_idx) };
+ assert_eq!(node.operation, BNMediumLevelILOperation::MLIL_UNDEF);
- // no more items to fetch
- if self.remaining == 0 {
- return None;
+ let next = if self.remaining > 4 {
+ self.next_iter_idx = Some(node.operands[4] as usize);
+ &node.operands[..4]
+ } else {
+ self.next_iter_idx = None;
+ &node.operands[..self.remaining]
+ };
+
+ self.current_iter = OperandIterInner::from_slice(next);
+ self.next()
}
+ }
+}
+impl ExactSizeIterator for OperandIter {
+ fn len(&self) -> usize {
+ self.remaining + self.current_iter.len()
+ }
+}
- // otherwise get the next node
- let next_idx = self.next_node_idx?;
- let node = unsafe { BNGetMediumLevelILByIndex(self.function.handle, next_idx) };
- assert_eq!(node.operation, BNMediumLevelILOperation::MLIL_UNDEF);
+struct OperandIterInner {
+ arr: [u64; 4],
+ idx: usize,
+}
- // each node contains at most 4, the last is reserved to next node idx
- let consume = if self.remaining > 4 {
- // there are more nodes after this one
- self.next_node_idx = Some(node.operands[4] as usize);
- self.remaining -= 4;
- &node.operands[0..4]
- } else {
- // last part of the list, there is no next node
- self.next_node_idx = None;
- let nodes = &node.operands[0..self.remaining];
- self.remaining = 0;
- nodes
- };
- // the iter need to have a space of 4, but we may have less then that,
- // solution is create a dummy elements at the start and discard it
- let mut nodes = [0; 4];
- let dummy_values = 4 - consume.len();
- nodes[dummy_values..4].copy_from_slice(consume);
- self.current_node = nodes.into_iter();
- for _ in 0..dummy_values {
- let _ = self.current_node.next();
- }
+impl OperandIterInner {
+ fn from_slice(slice: &[u64]) -> Self {
+ assert!(slice.len() <= 4);
+ let idx = 4 - slice.len();
+ let mut arr = [0; 4];
+ arr[idx..].copy_from_slice(slice);
+ Self { arr, idx }
+ }
- self.current_node.next()
+ fn empty() -> Self {
+ Self {
+ arr: [0; 4],
+ idx: 4,
+ }
}
+}
+
+impl Iterator for OperandIterInner {
+ type Item = u64;
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.len(), Some(self.len()))
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.idx < 4 {
+ let val = self.arr[self.idx];
+ self.idx += 1;
+ Some(val)
+ } else {
+ None
+ }
}
}
-impl ExactSizeIterator for OperandList {
+impl ExactSizeIterator for OperandIterInner {
fn len(&self) -> usize {
- self.remaining + self.current_node.len()
+ 4 - self.idx
}
}
-// Iterator similar to OperationList, but returns two elements
-pub struct OperandDubleList(OperandList);
-impl Iterator for OperandDubleList {
+pub struct OperandPairIter(OperandIter);
+impl Iterator for OperandPairIter {
type Item = (u64, u64);
fn next(&mut self) -> Option<Self::Item> {
let first = self.0.next()?;
- let second = self.0.next().unwrap();
+ let second = self.0.next()?;
Some((first, second))
}
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.len(), Some(self.len()))
- }
}
-impl ExactSizeIterator for OperandDubleList {
+impl ExactSizeIterator for OperandPairIter {
fn len(&self) -> usize {
self.0.len() / 2
}
}
-pub struct OperandExprList(OperandList);
-impl Iterator for OperandExprList {
+pub struct OperandExprIter(OperandIter);
+impl Iterator for OperandExprIter {
type Item = MediumLevelILInstruction;
fn next(&mut self) -> Option<Self::Item> {
self.0
.next()
- .map(|idx| get_operation(&self.0.function, idx as usize))
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.0.len(), Some(self.0.len()))
+ .map(|idx| self.0.function.instruction_from_idx(idx as usize))
}
}
-impl ExactSizeIterator for OperandExprList {
+impl ExactSizeIterator for OperandExprIter {
fn len(&self) -> usize {
self.0.len()
}
}
-pub struct OperandVariableList(OperandList);
-impl Iterator for OperandVariableList {
+pub struct OperandVarIter(OperandIter);
+impl Iterator for OperandVarIter {
type Item = Variable;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(get_var)
}
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.0.len(), Some(self.0.len()))
- }
}
-impl ExactSizeIterator for OperandVariableList {
+impl ExactSizeIterator for OperandVarIter {
fn len(&self) -> usize {
self.0.len()
}
}
-pub struct OperandSSAVariableList(OperandDubleList);
-impl Iterator for OperandSSAVariableList {
+pub struct OperandSSAVarIter(OperandPairIter);
+impl Iterator for OperandSSAVarIter {
type Item = SSAVariable;
fn next(&mut self) -> Option<Self::Item> {
- self.0.next().map(|(id, version)| {
- let raw = unsafe { BNFromVariableIdentifier(id) };
- let var = unsafe { Variable::from_raw(raw) };
- SSAVariable::new(var, version as usize)
- })
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.len(), Some(self.len()))
+ self.0
+ .next()
+ .map(|(id, version)| get_var_ssa(id, version as usize))
}
}
-impl ExactSizeIterator for OperandSSAVariableList {
+impl ExactSizeIterator for OperandSSAVarIter {
fn len(&self) -> usize {
self.0.len()
}
@@ -211,31 +192,23 @@ fn get_float(value: u64, size: usize) -> f64 {
}
}
-fn get_constant_data(
+pub(super) fn get_constant_data(
function: &MediumLevelILFunction,
- state: u64,
- value: u64,
+ state: u32,
+ value: i64,
size: usize,
) -> types::ConstantData {
types::ConstantData::new(
function.get_function(),
RegisterValue::new(
- RegisterValueType::from_raw_value(state as u32).unwrap(),
- value as i64,
+ RegisterValueType::from_raw_value(state).unwrap(),
+ value,
0,
size,
),
)
}
-fn get_intrinsic(function: &MediumLevelILFunction, idx: u32) -> ILIntrinsic {
- ILIntrinsic::new(function.get_function().arch(), idx)
-}
-
-fn get_operation(function: &MediumLevelILFunction, idx: usize) -> MediumLevelILInstruction {
- function.instruction_from_idx(idx)
-}
-
fn get_raw_operation(function: &MediumLevelILFunction, idx: usize) -> BNMediumLevelILInstruction {
unsafe { BNGetMediumLevelILByIndex(function.handle, idx) }
}
@@ -245,413 +218,168 @@ fn get_var(id: u64) -> Variable {
}
fn get_var_ssa(id: u64, version: usize) -> SSAVariable {
- let raw = unsafe { BNFromVariableIdentifier(id) };
- let var = unsafe { Variable::from_raw(raw) };
- SSAVariable::new(var, version)
-}
-
-fn get_call_list(
- function: &MediumLevelILFunction,
- op_type: BNMediumLevelILOperation,
- idx: usize,
-) -> OperandVariableList {
- let op = unsafe { BNGetMediumLevelILByIndex(function.handle, idx) };
- assert_eq!(op.operation, op_type);
- OperandList::new(function, op.operands[1] as usize, op.operands[0] as usize).map_var()
+ SSAVariable::new(get_var(id), version)
}
-fn get_call_exprs(
- function: &MediumLevelILFunction,
- op_type: BNMediumLevelILOperation,
- idx: usize,
-) -> OperandExprList {
- let op = unsafe { BNGetMediumLevelILByIndex(function.handle, idx) };
- assert_eq!(op.operation, op_type);
- OperandList::new(function, op.operands[1] as usize, op.operands[0] as usize).map_expr()
-}
-
-fn get_call_output(function: &MediumLevelILFunction, idx: usize) -> OperandVariableList {
- get_call_list(function, BNMediumLevelILOperation::MLIL_CALL_OUTPUT, idx)
-}
-
-fn get_call_params(function: &MediumLevelILFunction, idx: usize) -> OperandExprList {
- get_call_exprs(function, BNMediumLevelILOperation::MLIL_CALL_PARAM, idx)
+pub(super) fn get_call_output(function: &MediumLevelILFunction, idx: usize) -> OperandVarIter {
+ let op = get_raw_operation(function, idx);
+ assert_eq!(op.operation, BNMediumLevelILOperation::MLIL_CALL_OUTPUT);
+ OperandIter::new(function, op.operands[1] as usize, op.operands[0] as usize).as_vars()
}
-fn get_call_list_ssa(
- function: &MediumLevelILFunction,
- op_type: BNMediumLevelILOperation,
- idx: usize,
-) -> OperandSSAVariableList {
+pub(super) fn get_call_params(function: &MediumLevelILFunction, idx: usize) -> OperandExprIter {
let op = get_raw_operation(function, idx);
- assert_eq!(op.operation, op_type);
- OperandList::new(function, op.operands[2] as usize, op.operands[1] as usize).map_ssa_var()
+ assert_eq!(op.operation, BNMediumLevelILOperation::MLIL_CALL_PARAM);
+ OperandIter::new(function, op.operands[1] as usize, op.operands[0] as usize).as_exprs()
}
-fn get_call_exprs_ssa(
+pub(super) fn get_call_output_ssa(
function: &MediumLevelILFunction,
- op_type: BNMediumLevelILOperation,
idx: usize,
-) -> OperandExprList {
+) -> OperandSSAVarIter {
let op = get_raw_operation(function, idx);
- assert_eq!(op.operation, op_type);
- OperandList::new(function, op.operands[2] as usize, op.operands[1] as usize).map_expr()
-}
-
-fn get_call_output_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandSSAVariableList {
- get_call_list_ssa(
- function,
- BNMediumLevelILOperation::MLIL_CALL_OUTPUT_SSA,
- idx,
- )
-}
-
-fn get_call_params_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandExprList {
- get_call_exprs_ssa(function, BNMediumLevelILOperation::MLIL_CALL_PARAM_SSA, idx)
-}
-
-// NOP, NORET, BP, UNDEF, UNIMPL
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
-pub struct NoArgs {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
+ assert_eq!(op.operation, BNMediumLevelILOperation::MLIL_CALL_OUTPUT_SSA);
+ OperandIter::new(function, op.operands[2] as usize, op.operands[1] as usize).as_ssa_vars()
}
-impl NoArgs {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64) -> Self {
- Self { function, address }
- }
- // NOTE self is not required, it's present just in case data is added to
- // the struct in the future
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [].into_iter()
- }
+pub(super) fn get_call_params_ssa(function: &MediumLevelILFunction, idx: usize) -> OperandExprIter {
+ let op = get_raw_operation(function, idx);
+ assert_eq!(op.operation, BNMediumLevelILOperation::MLIL_CALL_PARAM_SSA);
+ OperandIter::new(function, op.operands[2] as usize, op.operands[1] as usize).as_exprs()
}
// IF
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct MediumLevelILOperationIf {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- condition: usize,
- dest_true: u64,
- dest_false: u64,
+ pub condition: usize,
+ pub dest_true: u64,
+ pub dest_false: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedIf {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub condition: Box<MediumLevelILLiftedInstruction>,
pub dest_true: u64,
pub dest_false: u64,
}
impl MediumLevelILOperationIf {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- condition: usize,
- dest_true: u64,
- dest_false: u64,
- ) -> Self {
+ pub(crate) fn new(condition: usize, dest_true: u64, dest_false: u64) -> Self {
Self {
- function,
- address,
condition,
dest_true,
dest_false,
}
}
- pub fn condition(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.condition)
- }
- pub fn dest_true(&self) -> u64 {
- self.dest_true
- }
- pub fn dest_false(&self) -> u64 {
- self.dest_false
- }
- pub fn lift(&self) -> LiftedIf {
- LiftedIf {
- function: self.function.clone(),
- address: self.address,
- condition: Box::new(self.condition().lift()),
- dest_true: self.dest_true(),
- dest_false: self.dest_false(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("condition", Expr(self.condition())),
- ("dest_true", Int(self.dest_true())),
- ("dest_false", Int(self.dest_false())),
- ]
- .into_iter()
- }
}
// FLOAT_CONST
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub struct FloatConst {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub constant: f64,
}
impl FloatConst {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- constant: u64,
- size: usize,
- ) -> Self {
+ pub(crate) fn new(constant: u64, size: usize) -> Self {
Self {
- function,
- address,
constant: get_float(constant, size),
}
}
- pub fn constant(&self) -> f64 {
- self.constant
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("constant", MediumLevelILOperand::Float(self.constant()))].into_iter()
- }
}
// CONST, CONST_PTR, IMPORT
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Constant {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub constant: u64,
}
impl Constant {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, constant: u64) -> Self {
- Self {
- function,
- address,
- constant,
- }
- }
- pub fn constant(&self) -> u64 {
- self.constant
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("constant", MediumLevelILOperand::Int(self.constant()))].into_iter()
+ pub(crate) fn new(constant: u64) -> Self {
+ Self { constant }
}
}
// EXTERN_PTR
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ExternPtr {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub constant: u64,
pub offset: u64,
}
impl ExternPtr {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- constant: u64,
- offset: u64,
- ) -> Self {
- Self {
- function,
- address,
- constant,
- offset,
- }
- }
- pub fn constant(&self) -> u64 {
- self.constant
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("constant", MediumLevelILOperand::Int(self.constant())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ]
- .into_iter()
+ pub(crate) fn new(constant: u64, offset: u64) -> Self {
+ Self { constant, offset }
}
}
// CONST_DATA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct ConstantData {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- constant_data: (u64, u64),
- size: usize,
+ pub constant_data_kind: u32,
+ pub constant_data_value: i64,
+ pub size: usize,
}
#[derive(Clone, Debug, Hash, PartialEq)]
pub struct LiftedConstantData {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub constant_data: types::ConstantData,
}
impl ConstantData {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- constant_data: (u64, u64),
- size: usize,
- ) -> Self {
+ pub(crate) fn new(constant_data_kind: u32, constant_data_value: i64, size: usize) -> Self {
Self {
- function,
- address,
- constant_data,
+ constant_data_kind,
+ constant_data_value,
size,
}
}
- pub fn constant_data(&self) -> types::ConstantData {
- get_constant_data(
- &self.function,
- self.constant_data.0,
- self.constant_data.1,
- self.size,
- )
- }
-
- pub fn lift(&self) -> LiftedConstantData {
- LiftedConstantData {
- function: self.function.clone(),
- address: self.address,
- constant_data: self.constant_data(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [(
- "contant_data",
- MediumLevelILOperand::ConstantData(self.constant_data()),
- )]
- .into_iter()
- }
}
// JUMP, RET_HINT
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct Jump {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: usize,
+ pub dest: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedJump {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Box<MediumLevelILLiftedInstruction>,
}
impl Jump {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, dest: usize) -> Self {
- Self {
- function,
- address,
- dest,
- }
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn lift(&self) -> LiftedJump {
- LiftedJump {
- function: self.function.clone(),
- address: self.address,
- dest: Box::new(self.dest().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("dest", MediumLevelILOperand::Expr(self.dest()))].into_iter()
+ pub(crate) fn new(dest: usize) -> Self {
+ Self { dest }
}
}
// STORE_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct StoreSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: usize,
- dest_memory: u64,
- src_memory: u64,
- src: usize,
+ pub dest: usize,
+ pub dest_memory: u64,
+ pub src_memory: u64,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStoreSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub dest_memory: u64,
pub src_memory: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl StoreSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: usize,
- dest_memory: u64,
- src_memory: u64,
- src: usize,
- ) -> Self {
+ pub(crate) fn new(dest: usize, dest_memory: u64, src_memory: u64, src: usize) -> Self {
Self {
- function,
- address,
dest,
dest_memory,
src_memory,
src,
}
}
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn dest_memory(&self) -> u64 {
- self.dest_memory
- }
- pub fn src_memory(&self) -> u64 {
- self.src_memory
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedStoreSsa {
- LiftedStoreSsa {
- function: self.function.clone(),
- address: self.address,
- dest: Box::new(self.dest().lift()),
- dest_memory: self.dest_memory(),
- src_memory: self.src_memory(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::Expr(self.dest())),
- ("dest_memory", MediumLevelILOperand::Int(self.dest_memory())),
- ("src_memory", MediumLevelILOperand::Int(self.src_memory())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// STORE_STRUCT_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct StoreStructSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: usize,
- offset: u64,
- dest_memory: u64,
- src_memory: u64,
- src: usize,
+ pub dest: usize,
+ pub offset: u64,
+ pub dest_memory: u64,
+ pub src_memory: u64,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStoreStructSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub offset: u64,
pub dest_memory: u64,
@@ -660,8 +388,6 @@ pub struct LiftedStoreStructSsa {
}
impl StoreStructSsa {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
dest: usize,
offset: u64,
dest_memory: u64,
@@ -669,8 +395,6 @@ impl StoreStructSsa {
src: usize,
) -> Self {
Self {
- function,
- address,
dest,
offset,
dest_memory,
@@ -678,1279 +402,512 @@ impl StoreStructSsa {
src,
}
}
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn dest_memory(&self) -> u64 {
- self.dest_memory
- }
- pub fn src_memory(&self) -> u64 {
- self.src_memory
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedStoreStructSsa {
- LiftedStoreStructSsa {
- function: self.function.clone(),
- address: self.address,
- dest: Box::new(self.dest().lift()),
- offset: self.offset(),
- dest_memory: self.dest_memory(),
- src_memory: self.src_memory(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::Expr(self.dest())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ("dest_memory", MediumLevelILOperand::Int(self.dest_memory())),
- ("src_memory", MediumLevelILOperand::Int(self.src_memory())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// STORE_STRUCT
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct StoreStruct {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: usize,
- offset: u64,
- src: usize,
+ pub dest: usize,
+ pub offset: u64,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStoreStruct {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub offset: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl StoreStruct {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: usize,
- offset: u64,
- src: usize,
- ) -> Self {
- Self {
- function,
- address,
- dest,
- offset,
- src,
- }
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedStoreStruct {
- LiftedStoreStruct {
- function: self.function.clone(),
- address: self.address,
- dest: Box::new(self.dest().lift()),
- offset: self.offset(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::Expr(self.dest())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
+ pub(crate) fn new(dest: usize, offset: u64, src: usize) -> Self {
+ Self { dest, offset, src }
}
}
// STORE
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct Store {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: usize,
- src: usize,
+ pub dest: usize,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStore {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl Store {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: usize,
- src: usize,
- ) -> Self {
- Self {
- function,
- address,
- dest,
- src,
- }
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedStore {
- LiftedStore {
- function: self.function.clone(),
- address: self.address,
- dest: Box::new(self.dest().lift()),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::Expr(self.dest())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
+ pub(crate) fn new(dest: usize, src: usize) -> Self {
+ Self { dest, src }
}
}
// JUMP_TO
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct JumpTo {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: usize,
- targets: (usize, usize),
+ pub dest: usize,
+ pub first_operand: usize,
+ pub num_operands: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedJumpTo {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub targets: HashMap<u64, u64>,
}
impl JumpTo {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: usize,
- targets: (usize, usize),
- ) -> Self {
+ pub(crate) fn new(dest: usize, num_operands: usize, first_operand: usize) -> Self {
Self {
- function,
- address,
dest,
- targets,
+ first_operand,
+ num_operands,
}
}
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn targets(&self) -> OperandDubleList {
- OperandList::new(&self.function, self.targets.1, self.targets.0).duble()
- }
- pub fn lift(&self) -> LiftedJumpTo {
- LiftedJumpTo {
- function: self.function.clone(),
- address: self.address,
- dest: Box::new(self.dest().lift()),
- targets: self.targets().collect(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("dest", Expr(self.dest())),
- ("targets", TargetMap(self.targets())),
- ]
- .into_iter()
- }
}
// GOTO
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Goto {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: u64,
}
impl Goto {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, dest: u64) -> Self {
- Self {
- function,
- address,
- dest,
- }
- }
- pub fn dest(&self) -> u64 {
- self.dest
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("dest", MediumLevelILOperand::Int(self.dest()))].into_iter()
+ pub(crate) fn new(dest: u64) -> Self {
+ Self { dest }
}
}
// FREE_VAR_SLOT
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct FreeVarSlot {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Variable,
}
impl FreeVarSlot {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, dest: u64) -> Self {
+ pub(crate) fn new(dest: u64) -> Self {
Self {
- function,
- address,
dest: get_var(dest),
}
}
- pub fn dest(&self) -> Variable {
- self.dest
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("dest", MediumLevelILOperand::Var(self.dest()))].into_iter()
- }
}
// SET_VAR_FIELD
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVarField {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: u64,
- offset: u64,
- src: usize,
+ pub dest: Variable,
+ pub offset: u64,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarField {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Variable,
pub offset: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVarField {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: u64,
- offset: u64,
- src: usize,
- ) -> Self {
+ pub(crate) fn new(dest: u64, offset: u64, src: usize) -> Self {
Self {
- function,
- address,
- dest,
+ dest: get_var(dest),
offset,
src,
}
}
- pub fn dest(&self) -> Variable {
- get_var(self.dest)
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVarField {
- LiftedSetVarField {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- offset: self.offset(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::Var(self.dest())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// SET_VAR
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVar {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: u64,
- src: usize,
+ pub dest: Variable,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVar {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: Variable,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVar {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: u64,
- src: usize,
- ) -> Self {
+ pub(crate) fn new(dest: u64, src: usize) -> Self {
Self {
- function,
- address,
- dest,
+ dest: get_var(dest),
src,
}
}
- pub fn dest(&self) -> Variable {
- get_var(self.dest)
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVar {
- LiftedSetVar {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::Var(self.dest())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// FREE_VAR_SLOT_SSA
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct FreeVarSlotSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: SSAVariable,
pub prev: SSAVariable,
}
impl FreeVarSlotSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: (u64, usize),
- prev: (u64, usize),
- ) -> Self {
+ pub(crate) fn new(dest: (u64, usize), prev: (u64, usize)) -> Self {
Self {
- function,
- address,
dest: get_var_ssa(dest.0, dest.1),
prev: get_var_ssa(prev.0, prev.1),
}
}
- pub fn dest(&self) -> SSAVariable {
- self.dest
- }
- pub fn prev(&self) -> SSAVariable {
- self.prev
- }
- pub fn lift(&self) -> FreeVarSlotSsa {
- FreeVarSlotSsa {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- prev: self.prev(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::VarSsa(self.dest())),
- ("prev", MediumLevelILOperand::VarSsa(self.prev())),
- ]
- .into_iter()
- }
}
// SET_VAR_SSA_FIELD, SET_VAR_ALIASED_FIELD
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVarSsaField {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: (u64, usize),
- prev: (u64, usize),
- offset: u64,
- src: usize,
+ pub dest: SSAVariable,
+ pub prev: SSAVariable,
+ pub offset: u64,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSsaField {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: SSAVariable,
pub prev: SSAVariable,
pub offset: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVarSsaField {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: (u64, usize),
- prev: (u64, usize),
- offset: u64,
- src: usize,
- ) -> Self {
+ pub(crate) fn new(dest: (u64, usize), prev: (u64, usize), offset: u64, src: usize) -> Self {
Self {
- function,
- address,
- dest,
- prev,
+ dest: get_var_ssa(dest.0, dest.1),
+ prev: get_var_ssa(prev.0, prev.1),
offset,
src,
}
}
- pub fn dest(&self) -> SSAVariable {
- get_var_ssa(self.dest.0, self.dest.1)
- }
- pub fn prev(&self) -> SSAVariable {
- get_var_ssa(self.prev.0, self.prev.1)
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVarSsaField {
- LiftedSetVarSsaField {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- prev: self.prev(),
- offset: self.offset(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::VarSsa(self.dest())),
- ("prev", MediumLevelILOperand::VarSsa(self.prev())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// SET_VAR_ALIASED
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVarAliased {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: (u64, usize),
- prev: (u64, usize),
- src: usize,
+ pub dest: SSAVariable,
+ pub prev: SSAVariable,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarAliased {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: SSAVariable,
pub prev: SSAVariable,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVarAliased {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: (u64, usize),
- prev: (u64, usize),
- src: usize,
- ) -> Self {
+ pub(crate) fn new(dest: (u64, usize), prev: (u64, usize), src: usize) -> Self {
Self {
- function,
- address,
- dest,
- prev,
+ dest: get_var_ssa(dest.0, dest.1),
+ prev: get_var_ssa(prev.0, prev.1),
src,
}
}
- pub fn dest(&self) -> SSAVariable {
- get_var_ssa(self.dest.0, self.dest.1)
- }
- pub fn prev(&self) -> SSAVariable {
- get_var_ssa(self.prev.0, self.prev.1)
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVarAliased {
- LiftedSetVarAliased {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- prev: self.prev(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::VarSsa(self.dest())),
- ("prev", MediumLevelILOperand::VarSsa(self.prev())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// SET_VAR_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVarSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: (u64, usize),
- src: usize,
+ pub dest: SSAVariable,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: SSAVariable,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVarSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: (u64, usize),
- src: usize,
- ) -> Self {
+ pub(crate) fn new(dest: (u64, usize), src: usize) -> Self {
Self {
- function,
- address,
- dest,
+ dest: get_var_ssa(dest.0, dest.1),
src,
}
}
- pub fn dest(&self) -> SSAVariable {
- get_var_ssa(self.dest.0, self.dest.1)
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVarSsa {
- LiftedSetVarSsa {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::VarSsa(self.dest())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// VAR_PHI
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct VarPhi {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest: (u64, usize),
- src: (usize, usize),
+ pub dest: SSAVariable,
+ pub first_operand: usize,
+ pub num_operands: usize,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct LiftedVarPhi {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest: SSAVariable,
pub src: Vec<SSAVariable>,
}
impl VarPhi {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest: (u64, usize),
- src: (usize, usize),
- ) -> Self {
+ pub(crate) fn new(dest: (u64, usize), num_operands: usize, first_operand: usize) -> Self {
Self {
- function,
- address,
- dest,
- src,
- }
- }
- pub fn dest(&self) -> SSAVariable {
- get_var_ssa(self.dest.0, self.dest.1)
- }
- pub fn src(&self) -> OperandSSAVariableList {
- OperandList::new(&self.function, self.src.1, self.src.0).map_ssa_var()
- }
- pub fn lift(&self) -> LiftedVarPhi {
- LiftedVarPhi {
- function: self.function.clone(),
- address: self.address,
- dest: self.dest(),
- src: self.src().collect(),
+ dest: get_var_ssa(dest.0, dest.1),
+ first_operand,
+ num_operands,
}
}
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("dest", MediumLevelILOperand::VarSsa(self.dest())),
- ("src", MediumLevelILOperand::VarSsaList(self.src())),
- ]
- .into_iter()
- }
}
// MEM_PHI
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct MemPhi {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- dest_memory: u64,
- src_memory: (usize, usize),
+ pub dest_memory: u64,
+ pub first_operand: usize,
+ pub num_operands: usize,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct LiftedMemPhi {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub dest_memory: u64,
pub src_memory: Vec<u64>,
}
impl MemPhi {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- dest_memory: u64,
- src_memory: (usize, usize),
- ) -> Self {
+ pub(crate) fn new(dest_memory: u64, num_operands: usize, first_operand: usize) -> Self {
Self {
- function,
- address,
dest_memory,
- src_memory,
+ first_operand,
+ num_operands,
}
}
- pub fn dest_memory(&self) -> u64 {
- self.dest_memory
- }
- pub fn src_memory(&self) -> OperandList {
- OperandList::new(&self.function, self.src_memory.1, self.src_memory.0)
- }
- pub fn lift(&self) -> LiftedMemPhi {
- LiftedMemPhi {
- function: self.function.clone(),
- address: self.address,
- dest_memory: self.dest_memory(),
- src_memory: self.src_memory().collect(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("dest_memory", Int(self.dest_memory())),
- ("src_memory", IntList(self.src_memory())),
- ]
- .into_iter()
- }
}
// VAR_SPLIT
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct VarSplit {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub high: Variable,
pub low: Variable,
}
impl VarSplit {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- high: u64,
- low: u64,
- ) -> Self {
+ pub(crate) fn new(high: u64, low: u64) -> Self {
Self {
- function,
- address,
high: get_var(high),
low: get_var(low),
}
}
- pub fn high(&self) -> Variable {
- self.high
- }
- pub fn low(&self) -> Variable {
- self.low
- }
- pub fn lift(&self) -> VarSplit {
- VarSplit {
- function: self.function.clone(),
- address: self.address,
- high: self.high(),
- low: self.low(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("high", MediumLevelILOperand::Var(self.high())),
- ("low", MediumLevelILOperand::Var(self.low())),
- ]
- .into_iter()
- }
}
// SET_VAR_SPLIT
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVarSplit {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- high: u64,
- low: u64,
- src: usize,
+ pub high: Variable,
+ pub low: Variable,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSplit {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub high: Variable,
pub low: Variable,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVarSplit {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- high: u64,
- low: u64,
- src: usize,
- ) -> Self {
+ pub(crate) fn new(high: u64, low: u64, src: usize) -> Self {
Self {
- function,
- address,
- high,
- low,
+ high: get_var(high),
+ low: get_var(low),
src,
}
}
- pub fn high(&self) -> Variable {
- get_var(self.high)
- }
- pub fn low(&self) -> Variable {
- get_var(self.low)
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVarSplit {
- LiftedSetVarSplit {
- function: self.function.clone(),
- address: self.address,
- high: self.high(),
- low: self.low(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("high", MediumLevelILOperand::Var(self.high())),
- ("low", MediumLevelILOperand::Var(self.low())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// VAR_SPLIT_SSA
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct VarSplitSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub high: SSAVariable,
pub low: SSAVariable,
}
impl VarSplitSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- high: (u64, usize),
- low: (u64, usize),
- ) -> Self {
+ pub(crate) fn new(high: (u64, usize), low: (u64, usize)) -> Self {
Self {
- function,
- address,
high: get_var_ssa(high.0, high.1),
low: get_var_ssa(low.0, low.1),
}
}
- pub fn high(&self) -> SSAVariable {
- self.high
- }
- pub fn low(&self) -> SSAVariable {
- self.low
- }
- pub fn lift(&self) -> VarSplitSsa {
- VarSplitSsa {
- function: self.function.clone(),
- address: self.address,
- high: self.high(),
- low: self.low(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("high", MediumLevelILOperand::VarSsa(self.high())),
- ("low", MediumLevelILOperand::VarSsa(self.low())),
- ]
- .into_iter()
- }
}
// SET_VAR_SPLIT_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SetVarSplitSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- high: (u64, usize),
- low: (u64, usize),
- src: usize,
+ pub high: SSAVariable,
+ pub low: SSAVariable,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSplitSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub high: SSAVariable,
pub low: SSAVariable,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl SetVarSplitSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- high: (u64, usize),
- low: (u64, usize),
- src: usize,
- ) -> Self {
+ pub(crate) fn new(high: (u64, usize), low: (u64, usize), src: usize) -> Self {
Self {
- function,
- address,
- high,
- low,
+ high: get_var_ssa(high.0, high.1),
+ low: get_var_ssa(low.0, low.1),
src,
}
}
- pub fn high(&self) -> SSAVariable {
- get_var_ssa(self.high.0, self.high.1)
- }
- pub fn low(&self) -> SSAVariable {
- get_var_ssa(self.low.0, self.low.1)
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedSetVarSplitSsa {
- LiftedSetVarSplitSsa {
- function: self.function.clone(),
- address: self.address,
- high: self.high(),
- low: self.low(),
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("high", MediumLevelILOperand::VarSsa(self.high())),
- ("low", MediumLevelILOperand::VarSsa(self.low())),
- ("src", MediumLevelILOperand::Expr(self.src())),
- ]
- .into_iter()
- }
}
// ADD, SUB, AND, OR, XOR, LSL, LSR, ASR, ROL, ROR, MUL, MULU_DP, MULS_DP, DIVU, DIVU_DP, DIVS, DIVS_DP, MODU, MODU_DP, MODS, MODS_DP, CMP_E, CMP_NE, CMP_SLT, CMP_ULT, CMP_SLE, CMP_ULE, CMP_SGE, CMP_UGE, CMP_SGT, CMP_UGT, TEST_BIT, ADD_OVERFLOW, FCMP_E, FCMP_NE, FCMP_LT, FCMP_LE, FCMP_GE, FCMP_GT, FCMP_O, FCMP_UO, FADD, FSUB, FMUL, FDIV
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct BinaryOp {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- left: usize,
- right: usize,
+ pub left: usize,
+ pub right: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedBinaryOp {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub left: Box<MediumLevelILLiftedInstruction>,
pub right: Box<MediumLevelILLiftedInstruction>,
}
impl BinaryOp {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- left: usize,
- right: usize,
- ) -> Self {
- Self {
- function,
- address,
- left,
- right,
- }
- }
- pub fn left(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.left)
- }
- pub fn right(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.right)
- }
- pub fn lift(&self) -> LiftedBinaryOp {
- LiftedBinaryOp {
- function: self.function.clone(),
- address: self.address,
- left: Box::new(self.left().lift()),
- right: Box::new(self.right().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("left", MediumLevelILOperand::Expr(self.left())),
- ("right", MediumLevelILOperand::Expr(self.right())),
- ]
- .into_iter()
+ pub(crate) fn new(left: usize, right: usize) -> Self {
+ Self { left, right }
}
}
// ADC, SBB, RLC, RRC
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct BinaryOpCarry {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- left: usize,
- right: usize,
- carry: usize,
+ pub left: usize,
+ pub right: usize,
+ pub carry: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedBinaryOpCarry {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub left: Box<MediumLevelILLiftedInstruction>,
pub right: Box<MediumLevelILLiftedInstruction>,
pub carry: Box<MediumLevelILLiftedInstruction>,
}
impl BinaryOpCarry {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- left: usize,
- right: usize,
- carry: usize,
- ) -> Self {
- Self {
- function,
- address,
- left,
- right,
- carry,
- }
- }
- pub fn left(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.left)
- }
- pub fn right(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.right)
- }
- pub fn carry(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.carry)
- }
- pub fn lift(&self) -> LiftedBinaryOpCarry {
- LiftedBinaryOpCarry {
- function: self.function.clone(),
- address: self.address,
- left: Box::new(self.left().lift()),
- right: Box::new(self.right().lift()),
- carry: Box::new(self.carry().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("left", MediumLevelILOperand::Expr(self.left())),
- ("right", MediumLevelILOperand::Expr(self.right())),
- ("carry", MediumLevelILOperand::Expr(self.carry())),
- ]
- .into_iter()
+ pub(crate) fn new(left: usize, right: usize, carry: usize) -> Self {
+ Self { left, right, carry }
}
}
// CALL, TAILCALL
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct Call {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: (usize, usize),
- dest: usize,
- params: (usize, usize),
+ pub first_output: usize,
+ pub num_outputs: usize,
+ pub dest: usize,
+ pub first_param: usize,
+ pub num_params: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCall {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<Variable>,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub params: Vec<MediumLevelILLiftedInstruction>,
}
impl Call {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: (usize, usize),
+ num_outputs: usize,
+ first_output: usize,
dest: usize,
- params: (usize, usize),
+ num_params: usize,
+ first_param: usize,
) -> Self {
Self {
- function,
- address,
- output,
+ num_outputs,
+ first_output,
dest,
- params,
+ num_params,
+ first_param,
}
}
- pub fn output(&self) -> OperandVariableList {
- OperandList::new(&self.function, self.output.1, self.output.0).map_var()
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn lift(&self) -> LiftedCall {
- LiftedCall {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- dest: Box::new(self.dest().lift()),
- params: self.params().map(|instr| instr.lift()).collect(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("output", MediumLevelILOperand::VarList(self.output())),
- ("dest", MediumLevelILOperand::Expr(self.dest())),
- ("params", MediumLevelILOperand::ExprList(self.params())),
- ]
- .into_iter()
- }
}
// SYSCALL
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct Syscall {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: (usize, usize),
- params: (usize, usize),
+ pub first_output: usize,
+ pub num_outputs: usize,
+ pub first_param: usize,
+ pub num_params: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSyscallCall {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<Variable>,
pub params: Vec<MediumLevelILLiftedInstruction>,
}
impl Syscall {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: (usize, usize),
- params: (usize, usize),
+ num_outputs: usize,
+ first_output: usize,
+ num_params: usize,
+ first_param: usize,
) -> Self {
Self {
- function,
- address,
- output,
- params,
+ num_outputs,
+ first_output,
+ num_params,
+ first_param,
}
}
- pub fn output(&self) -> OperandVariableList {
- OperandList::new(&self.function, self.output.1, self.output.0).map_var()
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn lift(&self) -> LiftedSyscallCall {
- LiftedSyscallCall {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- params: self.params().map(|instr| instr.lift()).collect(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarList(self.output())),
- ("params", ExprList(self.params())),
- ]
- .into_iter()
- }
}
// INTRINSIC
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct Intrinsic {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: (usize, usize),
- intrinsic: u32,
- params: (usize, usize),
+ pub first_output: usize,
+ pub num_outputs: usize,
+ pub intrinsic: u32,
+ pub first_param: usize,
+ pub num_params: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedIntrinsic {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<Variable>,
pub intrinsic: ILIntrinsic,
pub params: Vec<MediumLevelILLiftedInstruction>,
}
impl Intrinsic {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: (usize, usize),
+ num_outputs: usize,
+ first_output: usize,
intrinsic: u32,
- params: (usize, usize),
+ num_params: usize,
+ first_param: usize,
) -> Self {
Self {
- function,
- address,
- output,
+ num_outputs,
+ first_output,
intrinsic,
- params,
- }
- }
- pub fn output(&self) -> OperandVariableList {
- OperandList::new(&self.function, self.output.1, self.output.0).map_var()
- }
- pub fn intrinsic(&self) -> ILIntrinsic {
- get_intrinsic(&self.function, self.intrinsic)
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn lift(&self) -> LiftedIntrinsic {
- LiftedIntrinsic {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- intrinsic: self.intrinsic(),
- params: self.params().map(|instr| instr.lift()).collect(),
+ num_params,
+ first_param,
}
}
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarList(self.output())),
- ("intrinsic", Intrinsic(self.intrinsic())),
- ("params", ExprList(self.params())),
- ]
- .into_iter()
- }
}
// INTRINSIC_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct IntrinsicSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: (usize, usize),
- intrinsic: u32,
- params: (usize, usize),
+ pub first_output: usize,
+ pub num_outputs: usize,
+ pub intrinsic: u32,
+ pub first_param: usize,
+ pub num_params: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedIntrinsicSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<SSAVariable>,
pub intrinsic: ILIntrinsic,
pub params: Vec<MediumLevelILLiftedInstruction>,
}
impl IntrinsicSsa {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: (usize, usize),
+ num_outputs: usize,
+ first_output: usize,
intrinsic: u32,
- params: (usize, usize),
+ num_params: usize,
+ first_param: usize,
) -> Self {
Self {
- function,
- address,
- output,
+ num_outputs,
+ first_output,
intrinsic,
- params,
+ num_params,
+ first_param,
}
}
- pub fn output(&self) -> OperandSSAVariableList {
- OperandList::new(&self.function, self.output.1, self.output.0).map_ssa_var()
- }
- pub fn intrinsic(&self) -> ILIntrinsic {
- get_intrinsic(&self.function, self.intrinsic)
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn lift(&self) -> LiftedIntrinsicSsa {
- LiftedIntrinsicSsa {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- intrinsic: get_intrinsic(&self.function, self.intrinsic),
- params: self.params().map(|instr| instr.lift()).collect(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarSsaList(self.output())),
- ("intrinsic", Intrinsic(self.intrinsic())),
- ("params", ExprList(self.params())),
- ]
- .into_iter()
- }
}
// CALL_SSA, TAILCALL_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct CallSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: usize,
- dest: usize,
- params: (usize, usize),
- src_memory: u64,
+ pub output: usize,
+ pub dest: usize,
+ pub first_param: usize,
+ pub num_params: usize,
+ pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCallSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<SSAVariable>,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub params: Vec<MediumLevelILLiftedInstruction>,
@@ -1958,840 +915,340 @@ pub struct LiftedCallSsa {
}
impl CallSsa {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
output: usize,
dest: usize,
- params: (usize, usize),
+ num_params: usize,
+ first_param: usize,
src_memory: u64,
) -> Self {
Self {
- function,
- address,
output,
dest,
- params,
+ first_param,
+ num_params,
src_memory,
}
}
- pub fn output(&self) -> OperandSSAVariableList {
- get_call_output_ssa(&self.function, self.output)
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn src_memory(&self) -> u64 {
- self.src_memory
- }
- pub fn lift(&self) -> LiftedCallSsa {
- LiftedCallSsa {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- dest: Box::new(self.dest().lift()),
- params: self.params().map(|instr| instr.lift()).collect(),
- src_memory: self.src_memory(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarSsaList(self.output())),
- ("dest", Expr(self.dest())),
- ("params", ExprList(self.params())),
- ("src_memory", Int(self.src_memory())),
- ]
- .into_iter()
- }
}
// CALL_UNTYPED_SSA, TAILCALL_UNTYPED_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct CallUntypedSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: usize,
- dest: usize,
- params: usize,
- stack: usize,
+ pub output: usize,
+ pub dest: usize,
+ pub params: usize,
+ pub stack: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCallUntypedSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<SSAVariable>,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub params: Vec<MediumLevelILLiftedInstruction>,
pub stack: Box<MediumLevelILLiftedInstruction>,
}
impl CallUntypedSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: usize,
- dest: usize,
- params: usize,
- stack: usize,
- ) -> Self {
+ pub(crate) fn new(output: usize, dest: usize, params: usize, stack: usize) -> Self {
Self {
- function,
- address,
output,
dest,
params,
stack,
}
}
- pub fn output(&self) -> OperandSSAVariableList {
- get_call_output_ssa(&self.function, self.output)
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn params(&self) -> OperandExprList {
- get_call_params_ssa(&self.function, self.params)
- }
- pub fn stack(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.stack)
- }
- pub fn lift(&self) -> LiftedCallUntypedSsa {
- LiftedCallUntypedSsa {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- dest: Box::new(self.dest().lift()),
- params: self.params().map(|instr| instr.lift()).collect(),
- stack: Box::new(self.stack().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarSsaList(self.output())),
- ("dest", Expr(self.dest())),
- ("params", ExprList(self.params())),
- ("stack", Expr(self.stack())),
- ]
- .into_iter()
- }
}
// SYSCALL_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SyscallSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: usize,
- params: (usize, usize),
- src_memory: u64,
+ pub output: usize,
+ pub first_param: usize,
+ pub num_params: usize,
+ pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSyscallSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<SSAVariable>,
pub params: Vec<MediumLevelILLiftedInstruction>,
pub src_memory: u64,
}
impl SyscallSsa {
pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
output: usize,
- params: (usize, usize),
+ num_params: usize,
+ first_param: usize,
src_memory: u64,
) -> Self {
Self {
- function,
- address,
output,
- params,
+ first_param,
+ num_params,
src_memory,
}
}
- pub fn output(&self) -> OperandSSAVariableList {
- get_call_output_ssa(&self.function, self.output)
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn src_memory(&self) -> u64 {
- self.src_memory
- }
- pub fn lift(&self) -> LiftedSyscallSsa {
- LiftedSyscallSsa {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- params: self.params().map(|instr| instr.lift()).collect(),
- src_memory: self.src_memory(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarSsaList(self.output())),
- ("params", ExprList(self.params())),
- ("src_memory", MediumLevelILOperand::Int(self.src_memory())),
- ]
- .into_iter()
- }
}
// SYSCALL_UNTYPED_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SyscallUntypedSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: usize,
- params: usize,
- stack: usize,
+ pub output: usize,
+ pub params: usize,
+ pub stack: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSyscallUntypedSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<SSAVariable>,
pub params: Vec<MediumLevelILLiftedInstruction>,
pub stack: Box<MediumLevelILLiftedInstruction>,
}
impl SyscallUntypedSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: usize,
- params: usize,
- stack: usize,
- ) -> Self {
+ pub(crate) fn new(output: usize, params: usize, stack: usize) -> Self {
Self {
- function,
- address,
output,
params,
stack,
}
}
- pub fn output(&self) -> OperandSSAVariableList {
- get_call_output_ssa(&self.function, self.output)
- }
- pub fn params(&self) -> OperandExprList {
- get_call_params_ssa(&self.function, self.params)
- }
- pub fn stack(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.stack)
- }
- pub fn lift(&self) -> LiftedSyscallUntypedSsa {
- LiftedSyscallUntypedSsa {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- params: self.params().map(|instr| instr.lift()).collect(),
- stack: Box::new(self.stack().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarSsaList(self.output())),
- ("params", ExprList(self.params())),
- ("stack", Expr(self.stack())),
- ]
- .into_iter()
- }
}
// CALL_UNTYPED, TAILCALL_UNTYPED
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct CallUntyped {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: usize,
- dest: usize,
- params: usize,
- stack: usize,
+ pub output: usize,
+ pub dest: usize,
+ pub params: usize,
+ pub stack: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCallUntyped {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<Variable>,
pub dest: Box<MediumLevelILLiftedInstruction>,
pub params: Vec<MediumLevelILLiftedInstruction>,
pub stack: Box<MediumLevelILLiftedInstruction>,
}
impl CallUntyped {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: usize,
- dest: usize,
- params: usize,
- stack: usize,
- ) -> Self {
+ pub(crate) fn new(output: usize, dest: usize, params: usize, stack: usize) -> Self {
Self {
- function,
- address,
output,
dest,
params,
stack,
}
}
- pub fn output(&self) -> OperandVariableList {
- get_call_output(&self.function, self.output)
- }
- pub fn dest(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.dest)
- }
- pub fn params(&self) -> OperandExprList {
- get_call_params(&self.function, self.params)
- }
- pub fn stack(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.stack)
- }
- pub fn lift(&self) -> LiftedCallUntyped {
- LiftedCallUntyped {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- dest: Box::new(self.dest().lift()),
- params: self.params().map(|instr| instr.lift()).collect(),
- stack: Box::new(self.stack().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarList(self.output())),
- ("dest", Expr(self.dest())),
- ("params", ExprList(self.params())),
- ("stack", Expr(self.stack())),
- ]
- .into_iter()
- }
}
// SYSCALL_UNTYPED
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SyscallUntyped {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- output: usize,
- params: usize,
- stack: usize,
+ pub output: usize,
+ pub params: usize,
+ pub stack: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSyscallUntyped {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub output: Vec<Variable>,
pub params: Vec<MediumLevelILLiftedInstruction>,
pub stack: Box<MediumLevelILLiftedInstruction>,
}
impl SyscallUntyped {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- output: usize,
- params: usize,
- stack: usize,
- ) -> Self {
+ pub(crate) fn new(output: usize, params: usize, stack: usize) -> Self {
Self {
- function,
- address,
output,
params,
stack,
}
}
- pub fn output(&self) -> OperandVariableList {
- get_call_output(&self.function, self.output)
- }
- pub fn params(&self) -> OperandExprList {
- get_call_params(&self.function, self.params)
- }
- pub fn stack(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.stack)
- }
- pub fn lift(&self) -> LiftedSyscallUntyped {
- LiftedSyscallUntyped {
- function: self.function.clone(),
- address: self.address,
- output: self.output().collect(),
- params: self.params().map(|instr| instr.lift()).collect(),
- stack: Box::new(self.stack().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- use MediumLevelILOperand::*;
- [
- ("output", VarList(self.output())),
- ("params", ExprList(self.params())),
- ("stack", Expr(self.stack())),
- ]
- .into_iter()
- }
}
// NEG, NOT, SX, ZX, LOW_PART, BOOL_TO_INT, UNIMPL_MEM, FSQRT, FNEG, FABS, FLOAT_TO_INT, INT_TO_FLOAT, FLOAT_CONV, ROUND_TO_INT, FLOOR, CEIL, FTRUNC, LOAD
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct UnaryOp {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- src: usize,
+ pub src: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedUnaryOp {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
}
impl UnaryOp {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, src: usize) -> Self {
- Self {
- function,
- address,
- src,
- }
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn lift(&self) -> LiftedUnaryOp {
- LiftedUnaryOp {
- function: self.function.clone(),
- address: self.address,
- src: Box::new(self.src().lift()),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("src", MediumLevelILOperand::Expr(self.src()))].into_iter()
+ pub(crate) fn new(src: usize) -> Self {
+ Self { src }
}
}
// LOAD_STRUCT
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct LoadStruct {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- src: usize,
- offset: u64,
+ pub src: usize,
+ pub offset: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedLoadStruct {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
pub offset: u64,
}
impl LoadStruct {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: usize,
- offset: u64,
- ) -> Self {
- Self {
- function,
- address,
- src,
- offset,
- }
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn lift(&self) -> LiftedLoadStruct {
- LiftedLoadStruct {
- function: self.function.clone(),
- address: self.address,
- src: Box::new(self.src().lift()),
- offset: self.offset(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("src", MediumLevelILOperand::Expr(self.src())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ]
- .into_iter()
+ pub(crate) fn new(src: usize, offset: u64) -> Self {
+ Self { src, offset }
}
}
// LOAD_STRUCT_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct LoadStructSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- src: usize,
- offset: u64,
- src_memory: u64,
+ pub src: usize,
+ pub offset: u64,
+ pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedLoadStructSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
pub offset: u64,
pub src_memory: u64,
}
impl LoadStructSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: usize,
- offset: u64,
- src_memory: u64,
- ) -> Self {
+ pub(crate) fn new(src: usize, offset: u64, src_memory: u64) -> Self {
Self {
- function,
- address,
src,
offset,
src_memory,
}
}
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn src_memory(&self) -> u64 {
- self.src_memory
- }
- pub fn lift(&self) -> LiftedLoadStructSsa {
- LiftedLoadStructSsa {
- function: self.function.clone(),
- address: self.address,
- src: Box::new(self.src().lift()),
- offset: self.offset(),
- src_memory: self.src_memory(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("src", MediumLevelILOperand::Expr(self.src())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ("src_memory", MediumLevelILOperand::Int(self.src_memory())),
- ]
- .into_iter()
- }
}
// LOAD_SSA
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct LoadSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- src: usize,
- src_memory: u64,
+ pub src: usize,
+ pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedLoadSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Box<MediumLevelILLiftedInstruction>,
pub src_memory: u64,
}
impl LoadSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: usize,
- src_memory: u64,
- ) -> Self {
- Self {
- function,
- address,
- src,
- src_memory,
- }
- }
- pub fn src(&self) -> MediumLevelILInstruction {
- get_operation(&self.function, self.src)
- }
- pub fn src_memory(&self) -> u64 {
- self.src_memory
- }
- pub fn lift(&self) -> LiftedLoadSsa {
- LiftedLoadSsa {
- function: self.function.clone(),
- address: self.address,
- src: Box::new(self.src().lift()),
- src_memory: self.src_memory(),
- }
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("src", MediumLevelILOperand::Expr(self.src())),
- ("src_memory", MediumLevelILOperand::Int(self.src_memory())),
- ]
- .into_iter()
+ pub(crate) fn new(src: usize, src_memory: u64) -> Self {
+ Self { src, src_memory }
}
}
// RET
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct Ret {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- src: (usize, usize),
+ pub first_operand: usize,
+ pub num_operands: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedRet {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Vec<MediumLevelILLiftedInstruction>,
}
impl Ret {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: (usize, usize),
- ) -> Self {
+ pub(crate) fn new(num_operands: usize, first_operand: usize) -> Self {
Self {
- function,
- address,
- src,
- }
- }
- pub fn src(&self) -> OperandExprList {
- OperandList::new(&self.function, self.src.1, self.src.0).map_expr()
- }
- pub fn lift(&self) -> LiftedRet {
- LiftedRet {
- function: self.function.clone(),
- address: self.address,
- src: self.src().map(|instr| instr.lift()).collect(),
+ first_operand,
+ num_operands,
}
}
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("src", MediumLevelILOperand::ExprList(self.src()))].into_iter()
- }
}
// SEPARATE_PARAM_LIST
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SeparateParamList {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- params: (usize, usize),
+ pub first_param: usize,
+ pub num_params: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSeparateParamList {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub params: Vec<MediumLevelILLiftedInstruction>,
}
impl SeparateParamList {
- pub fn new(function: Ref<MediumLevelILFunction>, address: u64, params: (usize, usize)) -> Self {
+ pub fn new(num_params: usize, first_param: usize) -> Self {
Self {
- function,
- address,
- params,
- }
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn lift(&self) -> LiftedSeparateParamList {
- LiftedSeparateParamList {
- function: self.function.clone(),
- address: self.address,
- params: self.params().map(|instr| instr.lift()).collect(),
+ num_params,
+ first_param,
}
}
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> {
- [("params", MediumLevelILOperand::ExprList(self.params()))].into_iter()
- }
}
// SHARED_PARAM_SLOT
-#[derive(Clone)]
+#[derive(Copy, Clone)]
pub struct SharedParamSlot {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- params: (usize, usize),
+ pub first_param: usize,
+ pub num_params: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSharedParamSlot {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub params: Vec<MediumLevelILLiftedInstruction>,
}
impl SharedParamSlot {
- pub fn new(function: Ref<MediumLevelILFunction>, address: u64, params: (usize, usize)) -> Self {
+ pub fn new(num_params: usize, first_param: usize) -> Self {
Self {
- function,
- address,
- params,
- }
- }
- pub fn params(&self) -> OperandExprList {
- OperandList::new(&self.function, self.params.1, self.params.0).map_expr()
- }
- pub fn lift(&self) -> LiftedSharedParamSlot {
- LiftedSharedParamSlot {
- function: self.function.clone(),
- address: self.address,
- params: self.params().map(|instr| instr.lift()).collect(),
+ num_params,
+ first_param,
}
}
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> {
- [("params", MediumLevelILOperand::ExprList(self.params()))].into_iter()
- }
}
// VAR, ADDRESS_OF
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Var {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Variable,
}
impl Var {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, src: u64) -> Self {
- Self {
- function,
- address,
- src: get_var(src),
- }
- }
- pub fn src(&self) -> Variable {
- self.src
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("src", MediumLevelILOperand::Var(self.src()))].into_iter()
+ pub(crate) fn new(src: u64) -> Self {
+ Self { src: get_var(src) }
}
}
// VAR_FIELD, ADDRESS_OF_FIELD
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Field {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: Variable,
pub offset: u64,
}
impl Field {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: u64,
- offset: u64,
- ) -> Self {
+ pub(crate) fn new(src: u64, offset: u64) -> Self {
Self {
- function,
- address,
src: get_var(src),
offset,
}
}
- pub fn src(&self) -> Variable {
- self.src
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("src", MediumLevelILOperand::Var(self.src())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ]
- .into_iter()
- }
}
// VAR_SSA, VAR_ALIASED
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct VarSsa {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: SSAVariable,
}
impl VarSsa {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: (u64, usize),
- ) -> Self {
+ pub(crate) fn new(src: (u64, usize)) -> Self {
Self {
- function,
- address,
src: get_var_ssa(src.0, src.1),
}
}
- pub fn src(&self) -> SSAVariable {
- self.src
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("src", MediumLevelILOperand::VarSsa(self.src()))].into_iter()
- }
}
// VAR_SSA_FIELD, VAR_ALIASED_FIELD
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct VarSsaField {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub src: SSAVariable,
pub offset: u64,
}
impl VarSsaField {
- pub(crate) fn new(
- function: Ref<MediumLevelILFunction>,
- address: u64,
- src: (u64, usize),
- offset: u64,
- ) -> Self {
+ pub(crate) fn new(src: (u64, usize), offset: u64) -> Self {
Self {
- function,
- address,
src: get_var_ssa(src.0, src.1),
offset,
}
}
- pub fn src(&self) -> SSAVariable {
- self.src
- }
- pub fn offset(&self) -> u64 {
- self.offset
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [
- ("src", MediumLevelILOperand::VarSsa(self.src())),
- ("offset", MediumLevelILOperand::Int(self.offset())),
- ]
- .into_iter()
- }
}
// TRAP
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Trap {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
pub vector: u64,
}
impl Trap {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, address: u64, vector: u64) -> Self {
- Self {
- function,
- address,
- vector,
- }
- }
- pub fn vector(&self) -> u64 {
- self.vector
- }
- pub fn operands(&self) -> impl Iterator<Item = (&'static str, MediumLevelILOperand)> + '_ {
- [("vector", MediumLevelILOperand::Int(self.vector()))].into_iter()
+ pub(crate) fn new(vector: u64) -> Self {
+ Self { vector }
}
}