diff options
| author | Michael Krasnitski <michael.krasnitski@gmail.com> | 2024-02-07 11:44:06 -0500 |
|---|---|---|
| committer | Kyle Martin <krm504@nyu.edu> | 2024-03-18 17:46:37 -0400 |
| commit | 5fcf6bc59ebc2110d053360d223e6570cdd2272c (patch) | |
| tree | ed6eafd132cf53fd9e7105f541967324b4165db0 /rust/src/mlil/operation.rs | |
| parent | bdd012af7941c7d17b97b3e69628a7bc7cc2411e (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/mlil/operation.rs')
| -rw-r--r-- | rust/src/mlil/operation.rs | 2337 |
1 files changed, 397 insertions, 1940 deletions
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 } } } |
