summaryrefslogtreecommitdiff
path: root/rust/src/mlil
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/mlil')
-rw-r--r--rust/src/mlil/block.rs63
-rw-r--r--rust/src/mlil/function.rs727
-rw-r--r--rust/src/mlil/instruction.rs1585
-rw-r--r--rust/src/mlil/lift.rs510
-rw-r--r--rust/src/mlil/mod.rs10
-rw-r--r--rust/src/mlil/operation.rs581
6 files changed, 0 insertions, 3476 deletions
diff --git a/rust/src/mlil/block.rs b/rust/src/mlil/block.rs
deleted file mode 100644
index 015c7ba4..00000000
--- a/rust/src/mlil/block.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use std::ops::Range;
-
-use binaryninjacore_sys::BNGetMediumLevelILIndexForInstruction;
-
-use crate::basicblock::{BasicBlock, BlockContext};
-use crate::rc::Ref;
-
-use super::{MediumLevelILFunction, MediumLevelILInstruction};
-
-pub struct MediumLevelILBlockIter {
- function: Ref<MediumLevelILFunction>,
- range: Range<u64>,
-}
-
-impl Iterator for MediumLevelILBlockIter {
- type Item = MediumLevelILInstruction;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.range
- .next()
- .map(|i| unsafe {
- BNGetMediumLevelILIndexForInstruction(self.function.handle, i as usize)
- })
- .map(|i| MediumLevelILInstruction::new(self.function.to_owned(), i))
- }
-}
-
-pub struct MediumLevelILBlock {
- pub(crate) function: Ref<MediumLevelILFunction>,
-}
-
-impl core::fmt::Debug for MediumLevelILBlock {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- write!(f, "mlil_bb {:?}", self.function)
- }
-}
-
-impl BlockContext for MediumLevelILBlock {
- type Iter = MediumLevelILBlockIter;
- type Instruction = MediumLevelILInstruction;
-
- fn start(&self, block: &BasicBlock<Self>) -> MediumLevelILInstruction {
- let expr_idx = unsafe {
- BNGetMediumLevelILIndexForInstruction(self.function.handle, block.raw_start() as usize)
- };
- MediumLevelILInstruction::new(self.function.to_owned(), expr_idx)
- }
-
- fn iter(&self, block: &BasicBlock<Self>) -> MediumLevelILBlockIter {
- MediumLevelILBlockIter {
- function: self.function.to_owned(),
- range: block.raw_start()..block.raw_end(),
- }
- }
-}
-
-impl Clone for MediumLevelILBlock {
- fn clone(&self) -> Self {
- MediumLevelILBlock {
- function: self.function.to_owned(),
- }
- }
-}
diff --git a/rust/src/mlil/function.rs b/rust/src/mlil/function.rs
deleted file mode 100644
index 928f1b6a..00000000
--- a/rust/src/mlil/function.rs
+++ /dev/null
@@ -1,727 +0,0 @@
-use core::hash::{Hash, Hasher};
-use std::ffi::c_char;
-
-use binaryninjacore_sys::*;
-
-use crate::architecture::CoreArchitecture;
-use crate::basicblock::BasicBlock;
-use crate::disassembly::DisassemblySettings;
-use crate::flowgraph::FlowGraph;
-use crate::function::{Function, Location};
-use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref, RefCountable};
-use crate::string::BnStrCompatible;
-use crate::types::{
- Conf, PossibleValueSet, RegisterValue, SSAVariable, Type, UserVariableValues, Variable,
-};
-
-use super::{MediumLevelILBlock, MediumLevelILInstruction, MediumLevelILLiftedInstruction};
-
-pub struct MediumLevelILFunction {
- pub(crate) handle: *mut BNMediumLevelILFunction,
-}
-
-unsafe impl Send for MediumLevelILFunction {}
-unsafe impl Sync for MediumLevelILFunction {}
-
-impl Eq for MediumLevelILFunction {}
-impl PartialEq for MediumLevelILFunction {
- fn eq(&self, rhs: &Self) -> bool {
- self.get_function().eq(&rhs.get_function())
- }
-}
-
-impl Hash for MediumLevelILFunction {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.get_function().hash(state)
- }
-}
-
-impl MediumLevelILFunction {
- pub(crate) unsafe fn ref_from_raw(handle: *mut BNMediumLevelILFunction) -> Ref<Self> {
- debug_assert!(!handle.is_null());
-
- Self { handle }.to_owned()
- }
-
- pub fn instruction_at<L: Into<Location>>(&self, loc: L) -> Option<MediumLevelILInstruction> {
- let loc: Location = loc.into();
- let arch_handle = loc.arch.unwrap();
-
- let expr_idx =
- unsafe { BNMediumLevelILGetInstructionStart(self.handle, arch_handle.0, loc.addr) };
-
- if expr_idx >= self.instruction_count() {
- None
- } else {
- Some(MediumLevelILInstruction::new(self.to_owned(), expr_idx))
- }
- }
-
- pub fn instruction_from_idx(&self, expr_idx: usize) -> MediumLevelILInstruction {
- 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_from_instruction_idx(&self, instr_idx: usize) -> MediumLevelILInstruction {
- MediumLevelILInstruction::new(self.to_owned(), unsafe {
- BNGetMediumLevelILIndexForInstruction(self.handle, instr_idx)
- })
- }
-
- pub fn lifted_instruction_from_instruction_idx(
- &self,
- instr_idx: usize,
- ) -> MediumLevelILLiftedInstruction {
- self.instruction_from_instruction_idx(instr_idx).lift()
- }
-
- pub fn instruction_count(&self) -> usize {
- unsafe { BNGetMediumLevelILInstructionCount(self.handle) }
- }
-
- pub fn ssa_form(&self) -> MediumLevelILFunction {
- let ssa = unsafe { BNGetMediumLevelILSSAForm(self.handle) };
- assert!(!ssa.is_null());
- MediumLevelILFunction { handle: ssa }
- }
-
- pub fn get_function(&self) -> Ref<Function> {
- unsafe {
- let func = BNGetMediumLevelILOwnerFunction(self.handle);
- Function::from_raw(func)
- }
- }
-
- pub fn basic_blocks(&self) -> Array<BasicBlock<MediumLevelILBlock>> {
- let mut count = 0;
- let blocks = unsafe { BNGetMediumLevelILBasicBlockList(self.handle, &mut count) };
- let context = MediumLevelILBlock {
- function: self.to_owned(),
- };
-
- unsafe { Array::new(blocks, count, context) }
- }
-
- pub fn get_var_definitions<'a>(&'a self, var: &Variable) -> MediumLevelILInstructionList<'a> {
- let mut count = 0;
- let raw_instrs =
- unsafe { BNGetMediumLevelILVariableDefinitions(self.handle, &var.raw(), &mut count) };
- assert!(!raw_instrs.is_null());
- let instrs = unsafe { core::slice::from_raw_parts(raw_instrs, count) };
- MediumLevelILInstructionList {
- mlil: self,
- ptr: raw_instrs,
- instr_idxs: instrs.iter(),
- }
- }
-
- pub fn create_user_stack_var<'a, S: BnStrCompatible, C: Into<Conf<&'a Type>>>(
- self,
- offset: i64,
- var_type: C,
- name: S,
- ) {
- let var_type = var_type.into();
- let mut raw_var_type: BNTypeWithConfidence = var_type.into();
- let name = name.into_bytes_with_nul();
- unsafe {
- BNCreateUserStackVariable(
- self.get_function().handle,
- offset,
- &mut raw_var_type,
- name.as_ref().as_ptr() as *const c_char,
- )
- }
- }
-
- pub fn delete_user_stack_var(self, offset: i64) {
- unsafe { BNDeleteUserStackVariable(self.get_function().handle, offset) }
- }
-
- pub fn create_user_var<'a, S: BnStrCompatible, C: Into<Conf<&'a Type>>>(
- &self,
- var: &Variable,
- var_type: C,
- name: S,
- ignore_disjoint_uses: bool,
- ) {
- let var_type = var_type.into();
- let raw_var_type: BNTypeWithConfidence = var_type.into();
- let name = name.into_bytes_with_nul();
- unsafe {
- BNCreateUserVariable(
- self.get_function().handle,
- &var.raw(),
- &raw_var_type as *const _ as *mut _,
- name.as_ref().as_ptr() as *const _,
- ignore_disjoint_uses,
- )
- }
- }
-
- pub fn delete_user_var(&self, var: &Variable) {
- unsafe { BNDeleteUserVariable(self.get_function().handle, &var.raw()) }
- }
-
- pub fn is_var_user_defined(&self, var: &Variable) -> bool {
- unsafe { BNIsVariableUserDefined(self.get_function().handle, &var.raw()) }
- }
-
- /// Allows the user to specify a PossibleValueSet value for an MLIL
- /// variable at its definition site.
- ///
- /// .. warning:: Setting the variable value, triggers a reanalysis of the
- /// function and allows the dataflow to compute and propagate values which
- /// depend on the current variable. This implies that branch conditions
- /// whose values can be determined statically will be computed, leading to
- /// potential branch elimination at the HLIL layer.
- ///
- /// * `var` - Variable for which the value is to be set
- /// * `addr` - Address of the definition site of the variable
- /// * `value` - Informed value of the variable
- ///
- /// # Example
- /// ```no_run
- /// # use binaryninja::mlil::MediumLevelILFunction;
- /// # use binaryninja::types::PossibleValueSet;
- /// # let mlil_fun: MediumLevelILFunction = todo!();
- /// let (mlil_var, arch_addr, _val) = mlil_fun.user_var_values().all().next().unwrap();
- /// let def_address = arch_addr.address;
- /// let var_value = PossibleValueSet::ConstantValue{value: 5};
- /// mlil_fun.set_user_var_value(&mlil_var, def_address, var_value).unwrap();
- /// ```
- pub fn set_user_var_value(
- &self,
- var: &Variable,
- addr: u64,
- value: PossibleValueSet,
- ) -> Result<(), ()> {
- let Some(_def_site) = self
- .get_var_definitions(var)
- .find(|def| def.address == addr)
- else {
- // Error "No definition for Variable found at given address"
- return Err(());
- };
- let function = self.get_function();
- let def_site = BNArchitectureAndAddress {
- arch: function.arch().0,
- address: addr,
- };
- let value = value.into_raw();
-
- unsafe { BNSetUserVariableValue(function.handle, &var.raw(), &def_site, value.as_ffi()) }
- Ok(())
- }
-
- /// Clears a previously defined user variable value.
- ///
- /// * `var` - Variable for which the value was informed
- /// * `def_addr` - Address of the definition site of the variable
- pub fn clear_user_var_value(&self, var: &Variable, addr: u64) -> Result<(), ()> {
- let Some(_var_def) = self
- .get_var_definitions(var)
- .find(|site| site.address == addr)
- else {
- //error "Could not get definition for Variable"
- return Err(());
- };
-
- let function = self.get_function();
- let def_site = BNArchitectureAndAddress {
- arch: function.arch().0,
- address: addr,
- };
-
- unsafe { BNClearUserVariableValue(function.handle, &var.raw(), &def_site) };
- Ok(())
- }
-
- /// Returns a map of current defined user variable values.
- /// Returns a Map of user current defined user variable values and their definition sites.
- pub fn user_var_values(&self) -> UserVariableValues {
- let mut count = 0;
- let function = self.get_function();
- let var_values = unsafe { BNGetAllUserVariableValues(function.handle, &mut count) };
- assert!(!var_values.is_null());
- UserVariableValues {
- vars: core::ptr::slice_from_raw_parts(var_values, count),
- }
- }
-
- /// Clear all user defined variable values.
- pub fn clear_user_var_values(&self) -> Result<(), ()> {
- for (var, arch_and_addr, _value) in self.user_var_values().all() {
- self.clear_user_var_value(&var, arch_and_addr.address)?;
- }
- Ok(())
- }
-
- pub fn create_auto_stack_var<'a, T: Into<Conf<&'a Type>>, S: BnStrCompatible>(
- &self,
- offset: i64,
- var_type: T,
- name: S,
- ) {
- let var_type: Conf<&Type> = var_type.into();
- let mut var_type = var_type.into();
- let name = name.into_bytes_with_nul();
- let name_c_str = name.as_ref();
- unsafe {
- BNCreateAutoStackVariable(
- self.get_function().handle,
- offset,
- &mut var_type,
- name_c_str.as_ptr() as *const c_char,
- )
- }
- }
-
- pub fn delete_auto_stack_var(&self, offset: i64) {
- unsafe { BNDeleteAutoStackVariable(self.get_function().handle, offset) }
- }
-
- pub fn create_auto_var<'a, S: BnStrCompatible, C: Into<Conf<&'a Type>>>(
- &self,
- var: &Variable,
- var_type: C,
- name: S,
- ignore_disjoint_uses: bool,
- ) {
- let var_type: Conf<&Type> = var_type.into();
- let mut var_type = var_type.into();
- let name = name.into_bytes_with_nul();
- let name_c_str = name.as_ref();
- unsafe {
- BNCreateAutoVariable(
- self.get_function().handle,
- &var.raw(),
- &mut var_type,
- name_c_str.as_ptr() as *const c_char,
- ignore_disjoint_uses,
- )
- }
- }
-
- /// Returns a list of ILReferenceSource objects (IL xrefs or cross-references)
- /// that reference the given variable. The variable is a local variable that can be either on the stack,
- /// in a register, or in a flag.
- /// This function is related to get_hlil_var_refs(), which returns variable references collected
- /// from HLIL. The two can be different in several cases, e.g., multiple variables in MLIL can be merged
- /// into a single variable in HLIL.
- ///
- /// * `var` - Variable for which to query the xref
- ///
- /// # Example
- /// ```no_run
- /// # use binaryninja::mlil::MediumLevelILFunction;
- /// # use binaryninja::types::Variable;
- /// # let mlil_fun: MediumLevelILFunction = todo!();
- /// # let mlil_var: Variable = todo!();
- /// let instr = mlil_fun.var_refs(&mlil_var).get(0).expr();
- /// ```
- pub fn var_refs(&self, var: &Variable) -> Array<ILReferenceSource> {
- let mut count = 0;
- let refs = unsafe {
- BNGetMediumLevelILVariableReferences(
- self.get_function().handle,
- &mut var.raw(),
- &mut count,
- )
- };
- assert!(!refs.is_null());
- unsafe { Array::new(refs, count, self.to_owned()) }
- }
-
- /// Returns a list of variables referenced by code in the function ``func``,
- /// of the architecture ``arch``, and at the address ``addr``. If no function is specified, references from
- /// all functions and containing the address will be returned. If no architecture is specified, the
- /// architecture of the function will be used.
- /// This function is related to get_hlil_var_refs_from(), which returns variable references collected
- /// from HLIL. The two can be different in several cases, e.g., multiple variables in MLIL can be merged
- /// into a single variable in HLIL.
- ///
- /// * `addr` - virtual address to query for variable references
- /// * `length` - optional length of query
- /// * `arch` - optional architecture of query
- pub fn var_refs_from(
- &self,
- addr: u64,
- length: Option<u64>,
- arch: Option<CoreArchitecture>,
- ) -> Array<VariableReferenceSource> {
- let function = self.get_function();
- let arch = arch.unwrap_or_else(|| function.arch());
- let mut count = 0;
-
- let refs = if let Some(length) = length {
- unsafe {
- BNGetMediumLevelILVariableReferencesInRange(
- function.handle,
- arch.0,
- addr,
- length,
- &mut count,
- )
- }
- } else {
- unsafe {
- BNGetMediumLevelILVariableReferencesFrom(function.handle, arch.0, addr, &mut count)
- }
- };
- assert!(!refs.is_null());
- unsafe { Array::new(refs, count, self.to_owned()) }
- }
-
- /// Current IL Address
- pub fn current_address(&self) -> u64 {
- unsafe { BNMediumLevelILGetCurrentAddress(self.handle) }
- }
-
- /// Set the current IL Address
- pub fn set_current_address(&self, value: u64, arch: Option<CoreArchitecture>) {
- let arch = arch
- .map(|x| x.0)
- .unwrap_or_else(|| self.get_function().arch().0);
- unsafe { BNMediumLevelILSetCurrentAddress(self.handle, arch, value) }
- }
-
- /// Returns the BasicBlock at the given MLIL `instruction`.
- pub fn basic_block_containing(
- &self,
- instruction: &MediumLevelILInstruction,
- ) -> Option<BasicBlock<MediumLevelILBlock>> {
- let index = instruction.index;
- let block = unsafe { BNGetMediumLevelILBasicBlockForInstruction(self.handle, index) };
- (!block.is_null()).then(|| unsafe {
- BasicBlock::from_raw(
- block,
- MediumLevelILBlock {
- function: self.to_owned(),
- },
- )
- })
- }
- /// ends the function and computes the list of basic blocks.
- pub fn finalize(&self) {
- unsafe { BNFinalizeMediumLevelILFunction(self.handle) }
- }
-
- /// Generate SSA form given the current MLIL
- ///
- /// * `analyze_conditionals` - whether or not to analyze conditionals
- /// * `handle_aliases` - whether or not to handle aliases
- /// * `known_not_aliases` - optional list of variables known to be not aliased
- /// * `known_aliases` - optional list of variables known to be aliased
- pub fn generate_ssa_form(
- &self,
- analyze_conditionals: bool,
- handle_aliases: bool,
- known_not_aliases: impl IntoIterator<Item = Variable>,
- known_aliases: impl IntoIterator<Item = Variable>,
- ) {
- let mut known_not_aliases: Box<[_]> =
- known_not_aliases.into_iter().map(|x| x.raw()).collect();
- let mut known_aliases: Box<[_]> = known_aliases.into_iter().map(|x| x.raw()).collect();
- let (known_not_aliases_ptr, known_not_aliases_len) = if known_not_aliases.is_empty() {
- (core::ptr::null_mut(), 0)
- } else {
- (known_not_aliases.as_mut_ptr(), known_not_aliases.len())
- };
- let (known_aliases_ptr, known_aliases_len) = if known_not_aliases.is_empty() {
- (core::ptr::null_mut(), 0)
- } else {
- (known_aliases.as_mut_ptr(), known_aliases.len())
- };
- unsafe {
- BNGenerateMediumLevelILSSAForm(
- self.handle,
- analyze_conditionals,
- handle_aliases,
- known_not_aliases_ptr,
- known_not_aliases_len,
- known_aliases_ptr,
- known_aliases_len,
- )
- }
- }
-
- /// Gets the instruction that contains the given SSA variable's definition.
- ///
- /// Since SSA variables can only be defined once, this will return the single instruction where that occurs.
- /// For SSA variable version 0s, which don't have definitions, this will return None instead.
- pub fn ssa_variable_definition(&self, var: SSAVariable) -> Option<MediumLevelILInstruction> {
- let result = unsafe {
- BNGetMediumLevelILSSAVarDefinition(self.handle, &var.variable.raw(), var.version)
- };
- (result < self.instruction_count())
- .then(|| MediumLevelILInstruction::new(self.to_owned(), result))
- }
-
- pub fn ssa_memory_definition(&self, version: usize) -> Option<MediumLevelILInstruction> {
- let result = unsafe { BNGetMediumLevelILSSAMemoryDefinition(self.handle, version) };
- (result < self.instruction_count())
- .then(|| MediumLevelILInstruction::new(self.to_owned(), result))
- }
-
- ///Gets all the instructions that use the given SSA variable.
- pub fn ssa_variable_uses(&self, ssa_var: SSAVariable) -> Array<MediumLevelILInstruction> {
- let mut count = 0;
- let uses = unsafe {
- BNGetMediumLevelILSSAVarUses(
- self.handle,
- &ssa_var.variable.raw(),
- ssa_var.version,
- &mut count,
- )
- };
- assert!(!uses.is_null());
- unsafe { Array::new(uses, count, self.to_owned()) }
- }
-
- pub fn ssa_memory_uses(&self, version: usize) -> Array<MediumLevelILInstruction> {
- let mut count = 0;
- let uses = unsafe { BNGetMediumLevelILSSAMemoryUses(self.handle, version, &mut count) };
- assert!(!uses.is_null());
- unsafe { Array::new(uses, count, self.to_owned()) }
- }
-
- /// determines if `ssa_var` is live at any point in the function
- pub fn is_ssa_variable_live(&self, ssa_var: SSAVariable) -> bool {
- unsafe {
- BNIsMediumLevelILSSAVarLive(self.handle, &ssa_var.variable.raw(), ssa_var.version)
- }
- }
-
- pub fn variable_definitions(&self, variable: Variable) -> Array<MediumLevelILInstruction> {
- let mut count = 0;
- let defs = unsafe {
- BNGetMediumLevelILVariableDefinitions(self.handle, &variable.raw(), &mut count)
- };
- unsafe { Array::new(defs, count, self.to_owned()) }
- }
-
- pub fn variable_uses(&self, variable: Variable) -> Array<MediumLevelILInstruction> {
- let mut count = 0;
- let uses =
- unsafe { BNGetMediumLevelILVariableUses(self.handle, &variable.raw(), &mut count) };
- unsafe { Array::new(uses, count, self.to_owned()) }
- }
-
- /// Computes the list of instructions for which `var` is live.
- /// If `include_last_use` is false, the last use of the variable will not be included in the
- /// list (this allows for easier computation of overlaps in liveness between two variables).
- /// If the variable is never used, this function will return an empty list.
- ///
- /// `var` - the variable to query
- /// `include_last_use` - whether to include the last use of the variable in the list of instructions
- pub fn live_instruction_for_variable(
- &self,
- variable: Variable,
- include_last_user: bool,
- ) -> Array<MediumLevelILInstruction> {
- let mut count = 0;
- let uses = unsafe {
- BNGetMediumLevelILLiveInstructionsForVariable(
- self.handle,
- &variable.raw(),
- include_last_user,
- &mut count,
- )
- };
- unsafe { Array::new(uses, count, self.to_owned()) }
- }
-
- pub fn ssa_variable_value(&self, ssa_var: SSAVariable) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILSSAVarValue(self.handle, &ssa_var.variable.raw(), ssa_var.version)
- }
- .into()
- }
-
- pub fn create_graph(&self, settings: Option<DisassemblySettings>) -> FlowGraph {
- let settings = settings.map(|x| x.handle).unwrap_or(core::ptr::null_mut());
- let graph = unsafe { BNCreateMediumLevelILFunctionGraph(self.handle, settings) };
- unsafe { FlowGraph::from_raw(graph) }
- }
-
- /// This gets just the MLIL variables - you may be interested in the union
- /// of [MediumLevelILFunction::aliased_variables] and
- /// [crate::function::Function::parameter_variables] for all the
- /// variables used in the function
- pub fn variables(&self) -> Array<Variable> {
- let mut count = 0;
- let uses = unsafe { BNGetMediumLevelILVariables(self.handle, &mut count) };
- unsafe { Array::new(uses, count, ()) }
- }
-
- /// This returns a list of Variables that are taken reference to and used
- /// elsewhere. You may also wish to consider [MediumLevelILFunction::variables]
- /// and [crate::function::Function::parameter_variables]
- pub fn aliased_variables(&self) -> Array<Variable> {
- let mut count = 0;
- let uses = unsafe { BNGetMediumLevelILAliasedVariables(self.handle, &mut count) };
- unsafe { Array::new(uses, count, ()) }
- }
-
- /// This gets just the MLIL SSA variables - you may be interested in the
- /// union of [MediumLevelILFunction::aliased_variables] and
- /// [crate::function::Function::parameter_variables] for all the
- /// variables used in the function.
- pub fn ssa_variables(&self) -> Array<Array<SSAVariable>> {
- let mut count = 0;
- let vars = unsafe { BNGetMediumLevelILVariables(self.handle, &mut count) };
- unsafe { Array::new(vars, count, self.to_owned()) }
- }
-}
-
-impl ToOwned for MediumLevelILFunction {
- type Owned = Ref<Self>;
-
- fn to_owned(&self) -> Self::Owned {
- unsafe { RefCountable::inc_ref(self) }
- }
-}
-
-unsafe impl RefCountable for MediumLevelILFunction {
- unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
- Ref::new(Self {
- handle: BNNewMediumLevelILFunctionReference(handle.handle),
- })
- }
-
- unsafe fn dec_ref(handle: &Self) {
- BNFreeMediumLevelILFunction(handle.handle);
- }
-}
-
-impl core::fmt::Debug for MediumLevelILFunction {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- write!(f, "<mlil func handle {:p}>", self.handle)
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct MediumLevelILInstructionList<'a> {
- mlil: &'a MediumLevelILFunction,
- ptr: *mut usize,
- instr_idxs: core::slice::Iter<'a, usize>,
-}
-
-impl Drop for MediumLevelILInstructionList<'_> {
- fn drop(&mut self) {
- unsafe { BNFreeILInstructionList(self.ptr) };
- }
-}
-
-impl Iterator for MediumLevelILInstructionList<'_> {
- type Item = MediumLevelILInstruction;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.instr_idxs
- .next()
- .map(|i| self.mlil.instruction_from_instruction_idx(*i))
- }
-}
-
-impl DoubleEndedIterator for MediumLevelILInstructionList<'_> {
- fn next_back(&mut self) -> Option<Self::Item> {
- self.instr_idxs
- .next_back()
- .map(|i| self.mlil.instruction_from_instruction_idx(*i))
- }
-}
-
-impl ExactSizeIterator for MediumLevelILInstructionList<'_> {}
-impl core::iter::FusedIterator for MediumLevelILInstructionList<'_> {}
-
-/////////////////////////
-// FunctionGraphType
-
-pub type FunctionGraphType = binaryninjacore_sys::BNFunctionGraphType;
-
-/////////////////////////
-// ILReferenceSource
-
-pub struct ILReferenceSource {
- mlil: Ref<MediumLevelILFunction>,
- _func: Ref<Function>,
- _arch: CoreArchitecture,
- addr: u64,
- type_: FunctionGraphType,
- expr_id: usize,
-}
-
-impl ILReferenceSource {
- unsafe fn from_raw(value: BNILReferenceSource, mlil: Ref<MediumLevelILFunction>) -> Self {
- Self {
- mlil,
- _func: Function::from_raw(value.func),
- _arch: CoreArchitecture::from_raw(value.arch),
- addr: value.addr,
- type_: value.type_,
- expr_id: value.exprId,
- }
- }
- pub fn addr(&self) -> u64 {
- self.addr
- }
- pub fn graph_type(&self) -> FunctionGraphType {
- self.type_
- }
- pub fn expr(&self) -> MediumLevelILInstruction {
- self.mlil.instruction_from_idx(self.expr_id)
- }
-}
-
-impl CoreArrayProvider for ILReferenceSource {
- type Raw = BNILReferenceSource;
- type Context = Ref<MediumLevelILFunction>;
- type Wrapped<'a> = Self;
-}
-unsafe impl CoreArrayProviderInner for ILReferenceSource {
- unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
- BNFreeILReferences(raw, count)
- }
- unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- Self::from_raw(*raw, context.to_owned())
- }
-}
-
-/////////////////////////
-// VariableReferenceSource
-
-pub struct VariableReferenceSource {
- var: Variable,
- source: ILReferenceSource,
-}
-
-impl VariableReferenceSource {
- pub fn variable(&self) -> &Variable {
- &self.var
- }
- pub fn source(&self) -> &ILReferenceSource {
- &self.source
- }
-}
-
-impl CoreArrayProvider for VariableReferenceSource {
- type Raw = BNVariableReferenceSource;
- type Context = Ref<MediumLevelILFunction>;
- type Wrapped<'a> = Self;
-}
-
-unsafe impl CoreArrayProviderInner for VariableReferenceSource {
- unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
- BNFreeVariableReferenceSourceList(raw, count)
- }
- unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- Self {
- var: Variable::from_raw(raw.var),
- source: ILReferenceSource::from_raw(raw.source, context.to_owned()),
- }
- }
-}
diff --git a/rust/src/mlil/instruction.rs b/rust/src/mlil/instruction.rs
deleted file mode 100644
index 88564cc6..00000000
--- a/rust/src/mlil/instruction.rs
+++ /dev/null
@@ -1,1585 +0,0 @@
-use binaryninjacore_sys::*;
-
-use crate::architecture::CoreIntrinsic;
-use crate::disassembly::InstructionTextToken;
-use crate::operand_iter::OperandIter;
-use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref};
-use crate::types::{
- Conf, ConstantData, DataFlowQueryOption, ILBranchDependence, PossibleValueSet,
- RegisterValue, RegisterValueType, SSAVariable, Type, Variable,
-};
-
-use super::lift::*;
-use super::operation::*;
-use super::MediumLevelILFunction;
-
-#[derive(Clone)]
-pub struct MediumLevelILInstruction {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- pub index: usize,
- pub size: usize,
- pub kind: MediumLevelILInstructionKind,
-}
-
-#[derive(Copy, Clone)]
-pub enum MediumLevelILInstructionKind {
- Nop,
- Noret,
- Bp,
- Undef,
- Unimpl,
- If(MediumLevelILOperationIf),
- FloatConst(FloatConst),
- Const(Constant),
- ConstPtr(Constant),
- Import(Constant),
- ExternPtr(ExternPtr),
- ConstData(ConstData),
- Jump(Jump),
- RetHint(Jump),
- StoreSsa(StoreSsa),
- StoreStructSsa(StoreStructSsa),
- StoreStruct(StoreStruct),
- Store(Store),
- JumpTo(JumpTo),
- Goto(Goto),
- FreeVarSlot(FreeVarSlot),
- SetVarField(SetVarField),
- SetVar(SetVar),
- FreeVarSlotSsa(FreeVarSlotSsa),
- SetVarSsaField(SetVarSsaField),
- SetVarAliasedField(SetVarSsaField),
- SetVarAliased(SetVarAliased),
- SetVarSsa(SetVarSsa),
- VarPhi(VarPhi),
- MemPhi(MemPhi),
- VarSplit(VarSplit),
- SetVarSplit(SetVarSplit),
- VarSplitSsa(VarSplitSsa),
- SetVarSplitSsa(SetVarSplitSsa),
- Add(BinaryOp),
- Sub(BinaryOp),
- And(BinaryOp),
- Or(BinaryOp),
- Xor(BinaryOp),
- Lsl(BinaryOp),
- Lsr(BinaryOp),
- Asr(BinaryOp),
- Rol(BinaryOp),
- Ror(BinaryOp),
- Mul(BinaryOp),
- MuluDp(BinaryOp),
- MulsDp(BinaryOp),
- Divu(BinaryOp),
- DivuDp(BinaryOp),
- Divs(BinaryOp),
- DivsDp(BinaryOp),
- Modu(BinaryOp),
- ModuDp(BinaryOp),
- Mods(BinaryOp),
- ModsDp(BinaryOp),
- CmpE(BinaryOp),
- CmpNe(BinaryOp),
- CmpSlt(BinaryOp),
- CmpUlt(BinaryOp),
- CmpSle(BinaryOp),
- CmpUle(BinaryOp),
- CmpSge(BinaryOp),
- CmpUge(BinaryOp),
- CmpSgt(BinaryOp),
- CmpUgt(BinaryOp),
- TestBit(BinaryOp),
- AddOverflow(BinaryOp),
- FcmpE(BinaryOp),
- FcmpNe(BinaryOp),
- FcmpLt(BinaryOp),
- FcmpLe(BinaryOp),
- FcmpGe(BinaryOp),
- FcmpGt(BinaryOp),
- FcmpO(BinaryOp),
- FcmpUo(BinaryOp),
- Fadd(BinaryOp),
- Fsub(BinaryOp),
- Fmul(BinaryOp),
- Fdiv(BinaryOp),
- Adc(BinaryOpCarry),
- Sbb(BinaryOpCarry),
- Rlc(BinaryOpCarry),
- Rrc(BinaryOpCarry),
- Call(Call),
- Tailcall(Call),
- Syscall(Syscall),
- Intrinsic(Intrinsic),
- IntrinsicSsa(IntrinsicSsa),
- CallSsa(CallSsa),
- TailcallSsa(CallSsa),
- CallUntypedSsa(CallUntypedSsa),
- TailcallUntypedSsa(CallUntypedSsa),
- SyscallSsa(SyscallSsa),
- SyscallUntypedSsa(SyscallUntypedSsa),
- CallUntyped(CallUntyped),
- TailcallUntyped(CallUntyped),
- SyscallUntyped(SyscallUntyped),
- SeparateParamList(SeparateParamList),
- SharedParamSlot(SharedParamSlot),
- Neg(UnaryOp),
- Not(UnaryOp),
- Sx(UnaryOp),
- Zx(UnaryOp),
- LowPart(UnaryOp),
- BoolToInt(UnaryOp),
- UnimplMem(UnaryOp),
- Fsqrt(UnaryOp),
- Fneg(UnaryOp),
- Fabs(UnaryOp),
- FloatToInt(UnaryOp),
- IntToFloat(UnaryOp),
- FloatConv(UnaryOp),
- RoundToInt(UnaryOp),
- Floor(UnaryOp),
- Ceil(UnaryOp),
- Ftrunc(UnaryOp),
- Load(UnaryOp),
- LoadStruct(LoadStruct),
- LoadStructSsa(LoadStructSsa),
- LoadSsa(LoadSsa),
- Ret(Ret),
- Var(Var),
- AddressOf(Var),
- VarField(Field),
- AddressOfField(Field),
- VarSsa(VarSsa),
- VarAliased(VarSsa),
- VarSsaField(VarSsaField),
- VarAliasedField(VarSsaField),
- Trap(Trap),
-}
-
-impl core::fmt::Debug for MediumLevelILInstruction {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- write!(
- f,
- "<{} at 0x{:08}>",
- core::any::type_name::<Self>(),
- self.address,
- )
- }
-}
-
-impl MediumLevelILInstruction {
- pub(crate) fn new(function: Ref<MediumLevelILFunction>, index: usize) -> Self {
- let op = unsafe { BNGetMediumLevelILByIndex(function.handle, index) };
- use BNMediumLevelILOperation::*;
- 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 {
- condition: op.operands[0] as usize,
- dest_true: op.operands[1],
- dest_false: op.operands[2],
- }),
- MLIL_FLOAT_CONST => Op::FloatConst(FloatConst {
- constant: get_float(op.operands[0], op.size),
- }),
- MLIL_CONST => Op::Const(Constant {
- constant: op.operands[0],
- }),
- MLIL_CONST_PTR => Op::ConstPtr(Constant {
- constant: op.operands[0],
- }),
- MLIL_IMPORT => Op::Import(Constant {
- constant: op.operands[0],
- }),
- MLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr {
- constant: op.operands[0],
- offset: op.operands[1],
- }),
- MLIL_CONST_DATA => Op::ConstData(ConstData {
- constant_data_kind: op.operands[0] as u32,
- constant_data_value: op.operands[1] as i64,
- size: op.size,
- }),
- MLIL_JUMP => Op::Jump(Jump {
- dest: op.operands[0] as usize,
- }),
- MLIL_RET_HINT => Op::RetHint(Jump {
- dest: op.operands[0] as usize,
- }),
- MLIL_STORE_SSA => Op::StoreSsa(StoreSsa {
- dest: op.operands[0] as usize,
- dest_memory: op.operands[1],
- src_memory: op.operands[2],
- src: op.operands[3] as usize,
- }),
- MLIL_STORE_STRUCT_SSA => Op::StoreStructSsa(StoreStructSsa {
- dest: op.operands[0] as usize,
- offset: op.operands[1],
- dest_memory: op.operands[2],
- src_memory: op.operands[3],
- src: op.operands[4] as usize,
- }),
- MLIL_STORE_STRUCT => Op::StoreStruct(StoreStruct {
- dest: op.operands[0] as usize,
- offset: op.operands[1],
- src: op.operands[2] as usize,
- }),
- MLIL_STORE => Op::Store(Store {
- dest: op.operands[0] as usize,
- src: op.operands[1] as usize,
- }),
- MLIL_JUMP_TO => Op::JumpTo(JumpTo {
- dest: op.operands[0] as usize,
- num_operands: op.operands[1] as usize,
- first_operand: op.operands[2] as usize,
- }),
- MLIL_GOTO => Op::Goto(Goto {
- dest: op.operands[0],
- }),
- MLIL_FREE_VAR_SLOT => Op::FreeVarSlot(FreeVarSlot {
- dest: get_var(op.operands[0]),
- }),
- MLIL_SET_VAR_FIELD => Op::SetVarField(SetVarField {
- dest: get_var(op.operands[0]),
- offset: op.operands[1],
- src: op.operands[2] as usize,
- }),
- MLIL_SET_VAR => Op::SetVar(SetVar {
- dest: get_var(op.operands[0]),
- src: op.operands[1] as usize,
- }),
- MLIL_FREE_VAR_SLOT_SSA => Op::FreeVarSlotSsa(FreeVarSlotSsa {
- dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
- prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
- }),
- MLIL_SET_VAR_SSA_FIELD => Op::SetVarSsaField(SetVarSsaField {
- dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
- prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
- offset: op.operands[3],
- src: op.operands[4] as usize,
- }),
- MLIL_SET_VAR_ALIASED_FIELD => Op::SetVarAliasedField(SetVarSsaField {
- dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
- prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
- offset: op.operands[3],
- src: op.operands[4] as usize,
- }),
- MLIL_SET_VAR_ALIASED => Op::SetVarAliased(SetVarAliased {
- dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
- prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
- src: op.operands[3] as usize,
- }),
- MLIL_SET_VAR_SSA => Op::SetVarSsa(SetVarSsa {
- dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
- src: op.operands[2] as usize,
- }),
- MLIL_VAR_PHI => Op::VarPhi(VarPhi {
- dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
- num_operands: op.operands[2] as usize,
- first_operand: op.operands[3] as usize,
- }),
- MLIL_MEM_PHI => Op::MemPhi(MemPhi {
- dest_memory: op.operands[0],
- num_operands: op.operands[1] as usize,
- first_operand: op.operands[2] as usize,
- }),
- MLIL_VAR_SPLIT => Op::VarSplit(VarSplit {
- high: get_var(op.operands[0]),
- low: get_var(op.operands[1]),
- }),
- MLIL_SET_VAR_SPLIT => Op::SetVarSplit(SetVarSplit {
- high: get_var(op.operands[0]),
- low: get_var(op.operands[1]),
- src: op.operands[2] as usize,
- }),
- MLIL_VAR_SPLIT_SSA => Op::VarSplitSsa(VarSplitSsa {
- high: get_var_ssa(op.operands[0], op.operands[1] as usize),
- low: get_var_ssa(op.operands[2], op.operands[3] as usize),
- }),
- MLIL_SET_VAR_SPLIT_SSA => Op::SetVarSplitSsa(SetVarSplitSsa {
- high: get_var_ssa(op.operands[0], op.operands[1] as usize),
- low: get_var_ssa(op.operands[2], op.operands[3] as usize),
- src: op.operands[4] as usize,
- }),
- MLIL_ADD => Op::Add(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_SUB => Op::Sub(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_AND => Op::And(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_OR => Op::Or(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_XOR => Op::Xor(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_LSL => Op::Lsl(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_LSR => Op::Lsr(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_ASR => Op::Asr(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_ROL => Op::Rol(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_ROR => Op::Ror(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MUL => Op::Mul(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MULU_DP => Op::MuluDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MULS_DP => Op::MulsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_DIVU => Op::Divu(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_DIVU_DP => Op::DivuDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_DIVS => Op::Divs(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_DIVS_DP => Op::DivsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MODU => Op::Modu(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MODU_DP => Op::ModuDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MODS => Op::Mods(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_MODS_DP => Op::ModsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_E => Op::CmpE(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_NE => Op::CmpNe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_SLT => Op::CmpSlt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_ULT => Op::CmpUlt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_SLE => Op::CmpSle(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_ULE => Op::CmpUle(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_SGE => Op::CmpSge(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_UGE => Op::CmpUge(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_SGT => Op::CmpSgt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_CMP_UGT => Op::CmpUgt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_TEST_BIT => Op::TestBit(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_E => Op::FcmpE(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_NE => Op::FcmpNe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_LT => Op::FcmpLt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_LE => Op::FcmpLe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_GE => Op::FcmpGe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_GT => Op::FcmpGt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_O => Op::FcmpO(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FCMP_UO => Op::FcmpUo(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FADD => Op::Fadd(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FSUB => Op::Fsub(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FMUL => Op::Fmul(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_FDIV => Op::Fdiv(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- }),
- MLIL_ADC => Op::Adc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
- }),
- MLIL_SBB => Op::Sbb(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
- }),
- MLIL_RLC => Op::Rlc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
- }),
- MLIL_RRC => Op::Rrc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
- }),
- MLIL_CALL => Op::Call(Call {
- num_outputs: op.operands[0] as usize,
- first_output: op.operands[1] as usize,
- dest: op.operands[2] as usize,
- num_params: op.operands[3] as usize,
- first_param: op.operands[4] as usize,
- }),
- MLIL_TAILCALL => Op::Tailcall(Call {
- num_outputs: op.operands[0] as usize,
- first_output: op.operands[1] as usize,
- dest: op.operands[2] as usize,
- num_params: op.operands[3] as usize,
- first_param: op.operands[4] as usize,
- }),
- MLIL_SYSCALL => Op::Syscall(Syscall {
- num_outputs: op.operands[0] as usize,
- first_output: op.operands[1] as usize,
- num_params: op.operands[2] as usize,
- first_param: op.operands[3] as usize,
- }),
- MLIL_INTRINSIC => Op::Intrinsic(Intrinsic {
- num_outputs: op.operands[0] as usize,
- first_output: op.operands[1] as usize,
- intrinsic: op.operands[2] as u32,
- num_params: op.operands[3] as usize,
- first_param: op.operands[4] as usize,
- }),
- MLIL_INTRINSIC_SSA => Op::IntrinsicSsa(IntrinsicSsa {
- num_outputs: op.operands[0] as usize,
- first_output: op.operands[1] as usize,
- intrinsic: op.operands[2] as u32,
- num_params: op.operands[3] as usize,
- first_param: op.operands[4] as usize,
- }),
- MLIL_CALL_SSA => Op::CallSsa(CallSsa {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
- num_params: op.operands[2] as usize,
- first_param: op.operands[3] as usize,
- src_memory: op.operands[4],
- }),
- MLIL_TAILCALL_SSA => Op::TailcallSsa(CallSsa {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
- num_params: op.operands[2] as usize,
- first_param: op.operands[3] as usize,
- src_memory: op.operands[4],
- }),
- MLIL_CALL_UNTYPED_SSA => Op::CallUntypedSsa(CallUntypedSsa {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
- params: op.operands[2] as usize,
- stack: op.operands[3] as usize,
- }),
- MLIL_TAILCALL_UNTYPED_SSA => Op::TailcallUntypedSsa(CallUntypedSsa {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
- params: op.operands[2] as usize,
- stack: op.operands[3] as usize,
- }),
- MLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa {
- output: op.operands[0] as usize,
- num_params: op.operands[1] as usize,
- first_param: op.operands[2] as usize,
- src_memory: op.operands[3],
- }),
- MLIL_SYSCALL_UNTYPED_SSA => Op::SyscallUntypedSsa(SyscallUntypedSsa {
- output: op.operands[0] as usize,
- params: op.operands[1] as usize,
- stack: op.operands[2] as usize,
- }),
- MLIL_CALL_UNTYPED => Op::CallUntyped(CallUntyped {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
- params: op.operands[2] as usize,
- stack: op.operands[3] as usize,
- }),
- MLIL_TAILCALL_UNTYPED => Op::TailcallUntyped(CallUntyped {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
- params: op.operands[2] as usize,
- stack: op.operands[3] as usize,
- }),
- MLIL_SYSCALL_UNTYPED => Op::SyscallUntyped(SyscallUntyped {
- output: op.operands[0] as usize,
- params: op.operands[1] as usize,
- stack: op.operands[2] as usize,
- }),
- MLIL_NEG => Op::Neg(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_NOT => Op::Not(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_SX => Op::Sx(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_ZX => Op::Zx(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_LOW_PART => Op::LowPart(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FSQRT => Op::Fsqrt(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FNEG => Op::Fneg(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FABS => Op::Fabs(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FLOAT_CONV => Op::FloatConv(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FLOOR => Op::Floor(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_CEIL => Op::Ceil(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_FTRUNC => Op::Ftrunc(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_LOAD => Op::Load(UnaryOp {
- src: op.operands[0] as usize,
- }),
- MLIL_LOAD_STRUCT => Op::LoadStruct(LoadStruct {
- src: op.operands[0] as usize,
- offset: op.operands[1],
- }),
- MLIL_LOAD_STRUCT_SSA => Op::LoadStructSsa(LoadStructSsa {
- src: op.operands[0] as usize,
- offset: op.operands[1],
- src_memory: op.operands[2],
- }),
- MLIL_LOAD_SSA => Op::LoadSsa(LoadSsa {
- src: op.operands[0] as usize,
- src_memory: op.operands[1],
- }),
- MLIL_RET => Op::Ret(Ret {
- num_operands: op.operands[0] as usize,
- first_operand: op.operands[1] as usize,
- }),
- MLIL_SEPARATE_PARAM_LIST => Op::SeparateParamList(SeparateParamList {
- num_params: op.operands[0] as usize,
- first_param: op.operands[1] as usize,
- }),
- MLIL_SHARED_PARAM_SLOT => Op::SharedParamSlot(SharedParamSlot {
- num_params: op.operands[0] as usize,
- first_param: op.operands[1] as usize,
- }),
- MLIL_VAR => Op::Var(Var {
- src: get_var(op.operands[0]),
- }),
- MLIL_ADDRESS_OF => Op::AddressOf(Var {
- src: get_var(op.operands[0]),
- }),
- MLIL_VAR_FIELD => Op::VarField(Field {
- src: get_var(op.operands[0]),
- offset: op.operands[1],
- }),
- MLIL_ADDRESS_OF_FIELD => Op::AddressOfField(Field {
- src: get_var(op.operands[0]),
- offset: op.operands[1],
- }),
- MLIL_VAR_SSA => Op::VarSsa(VarSsa {
- src: get_var_ssa(op.operands[0], op.operands[1] as usize),
- }),
- MLIL_VAR_ALIASED => Op::VarAliased(VarSsa {
- src: get_var_ssa(op.operands[0], op.operands[1] as usize),
- }),
- MLIL_VAR_SSA_FIELD => Op::VarSsaField(VarSsaField {
- src: get_var_ssa(op.operands[0], op.operands[1] as usize),
- offset: op.operands[2],
- }),
- MLIL_VAR_ALIASED_FIELD => Op::VarAliasedField(VarSsaField {
- src: get_var_ssa(op.operands[0], op.operands[1] as usize),
- offset: op.operands[2],
- }),
- MLIL_TRAP => Op::Trap(Trap {
- vector: 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,
- index,
- size: op.size,
- kind,
- }
- }
-
- 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(LiftedConstData {
- constant_data: ConstantData::new(
- self.function.get_function(),
- RegisterValue {
- state: RegisterValueType::from_raw_value(op.constant_data_kind).unwrap(),
- value: op.constant_data_value,
- offset: 0,
- size: 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)
- .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)
- .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)
- .vars()
- .collect(),
- intrinsic: CoreIntrinsic(self.function.get_function().arch().0, op.intrinsic),
- params: OperandIter::new(&*self.function, op.first_param, op.num_params)
- .exprs()
- .map(|expr| expr.lift())
- .collect(),
- }),
- Syscall(op) => Lifted::Syscall(LiftedSyscallCall {
- output: OperandIter::new(&*self.function, op.first_output, op.num_outputs)
- .vars()
- .collect(),
- params: OperandIter::new(&*self.function, op.first_param, op.num_params)
- .exprs()
- .map(|expr| expr.lift())
- .collect(),
- }),
- IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa {
- output: OperandIter::new(&*self.function, op.first_output, op.num_outputs)
- .ssa_vars()
- .collect(),
- intrinsic: CoreIntrinsic(self.function.get_function().arch().0, op.intrinsic),
- params: OperandIter::new(&*self.function, op.first_param, op.num_params)
- .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)
- .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)
- .exprs()
- .map(|expr| expr.lift())
- .collect(),
- }),
- SeparateParamList(op) => Lifted::SeparateParamList(LiftedSeparateParamList {
- params: OperandIter::new(&*self.function, op.first_param, op.num_params)
- .exprs()
- .map(|expr| expr.lift())
- .collect(),
- }),
- SharedParamSlot(op) => Lifted::SharedParamSlot(LiftedSharedParamSlot {
- params: OperandIter::new(&*self.function, op.first_param, op.num_params)
- .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,
- index: self.index,
- size: self.size,
- kind,
- }
- }
-
- pub fn tokens(&self) -> Array<InstructionTextToken> {
- let mut count = 0;
- let mut tokens = core::ptr::null_mut();
- assert!(unsafe {
- BNGetMediumLevelILExprText(
- self.function.handle,
- self.function.get_function().arch().0,
- self.index,
- &mut tokens,
- &mut count,
- core::ptr::null_mut(),
- )
- });
- unsafe { Array::new(tokens, count, ()) }
- }
-
- /// Value of expression if constant or a known value
- pub fn value(&self) -> RegisterValue {
- unsafe { BNGetMediumLevelILExprValue(self.function.handle, self.index) }.into()
- }
-
- /// Possible values of expression using path-sensitive static data flow analysis
- pub fn possible_values(&self, options: Option<&[DataFlowQueryOption]>) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleExprValues(
- self.function.handle,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- pub fn possible_ssa_variable_values(
- &self,
- ssa_var: SSAVariable,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleSSAVarValues(
- self.function.handle,
- &ssa_var.variable.raw(),
- ssa_var.version,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- /// return the variable version used at this instruction
- pub fn ssa_variable_version(&self, var: Variable) -> SSAVariable {
- let version = unsafe {
- BNGetMediumLevelILSSAVarVersionAtILInstruction(
- self.function.handle,
- &var.raw(),
- self.index,
- )
- };
- SSAVariable::new(var, version)
- }
-
- /// Set of branching instructions that must take the true or false path to reach this instruction
- pub fn branch_dependence(&self) -> Array<BranchDependence> {
- let mut count = 0;
- let deps = unsafe {
- BNGetAllMediumLevelILBranchDependence(self.function.handle, self.index, &mut count)
- };
- assert!(!deps.is_null());
- unsafe { Array::new(deps, count, self.function.clone()) }
- }
-
- pub fn branch_dependence_at(&self, instruction: MediumLevelILInstruction) -> BranchDependence {
- let deps = unsafe {
- BNGetMediumLevelILBranchDependence(self.function.handle, self.index, instruction.index)
- };
- BranchDependence {
- instruction,
- dependence: deps,
- }
- }
-
- /// Version of active memory contents in SSA form for this instruction
- pub fn ssa_memory_version(&self) -> usize {
- unsafe {
- BNGetMediumLevelILSSAMemoryVersionAtILInstruction(self.function.handle, self.index)
- }
- }
-
- /// Type of expression
- pub fn expr_type(&self) -> Option<Conf<Ref<Type>>> {
- let result = unsafe { BNGetMediumLevelILExprType(self.function.handle, self.index) };
- (!result.type_.is_null()).then(|| {
- Conf::new(
- unsafe { Type::ref_from_raw(result.type_) },
- result.confidence,
- )
- })
- }
-
- /// Set type of expression
- ///
- /// This API is only meant for workflows or for debugging purposes, since the changes they make are not persistent
- /// and get lost after a database save and reload. To make persistent changes to the analysis, one should use other
- /// APIs to, for example, change the type of variables. The analysis will then propagate the type of the variable
- /// and update the type of related expressions.
- pub fn set_expr_type<'a, T: Into<Conf<&'a Type>>>(&self, value: T) {
- let type_: Conf<&'a Type> = value.into();
- let mut type_raw: BNTypeWithConfidence = BNTypeWithConfidence {
- type_: type_.contents.handle,
- confidence: type_.confidence,
- };
- unsafe { BNSetMediumLevelILExprType(self.function.handle, self.index, &mut type_raw) }
- }
-
- pub fn variable_for_register(&self, reg_id: u32) -> Variable {
- let result = unsafe {
- BNGetMediumLevelILVariableForRegisterAtInstruction(
- self.function.handle,
- reg_id,
- self.index,
- )
- };
- unsafe { Variable::from_raw(result) }
- }
-
- pub fn variable_for_flag(&self, flag_id: u32) -> Variable {
- let result = unsafe {
- BNGetMediumLevelILVariableForFlagAtInstruction(
- self.function.handle,
- flag_id,
- self.index,
- )
- };
- unsafe { Variable::from_raw(result) }
- }
-
- pub fn variable_for_stack_location(&self, offset: i64) -> Variable {
- let result = unsafe {
- BNGetMediumLevelILVariableForStackLocationAtInstruction(
- self.function.handle,
- offset,
- self.index,
- )
- };
- unsafe { Variable::from_raw(result) }
- }
-
- pub fn register_value(&self, reg_id: u32) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILRegisterValueAtInstruction(self.function.handle, reg_id, self.index)
- }
- .into()
- }
-
- pub fn register_value_after(&self, reg_id: u32) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILRegisterValueAfterInstruction(
- self.function.handle,
- reg_id,
- self.index,
- )
- }
- .into()
- }
-
- pub fn possible_register_values(
- &self,
- reg_id: u32,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleRegisterValuesAtInstruction(
- self.function.handle,
- reg_id,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- pub fn possible_register_values_after(
- &self,
- reg_id: u32,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(
- self.function.handle,
- reg_id,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- pub fn flag_value(&self, flag_id: u32) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILFlagValueAtInstruction(self.function.handle, flag_id, self.index)
- }
- .into()
- }
-
- pub fn flag_value_after(&self, flag_id: u32) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILFlagValueAfterInstruction(self.function.handle, flag_id, self.index)
- }
- .into()
- }
-
- pub fn possible_flag_values(
- &self,
- flag_id: u32,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleFlagValuesAtInstruction(
- self.function.handle,
- flag_id,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- pub fn possible_flag_values_after(
- &self,
- flag_id: u32,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleFlagValuesAfterInstruction(
- self.function.handle,
- flag_id,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- pub fn stack_contents(&self, offset: i64, size: usize) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILStackContentsAtInstruction(
- self.function.handle,
- offset,
- size,
- self.index,
- )
- }
- .into()
- }
-
- pub fn stack_contents_after(&self, offset: i64, size: usize) -> RegisterValue {
- unsafe {
- BNGetMediumLevelILStackContentsAfterInstruction(
- self.function.handle,
- offset,
- size,
- self.index,
- )
- }
- .into()
- }
-
- pub fn possible_stack_contents(
- &self,
- offset: i64,
- size: usize,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleStackContentsAtInstruction(
- self.function.handle,
- offset,
- size,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- pub fn possible_stack_contents_after(
- &self,
- offset: i64,
- size: usize,
- options: Option<&[DataFlowQueryOption]>,
- ) -> PossibleValueSet {
- let options_ptr = options
- .map(|op| op.as_ptr() as *mut DataFlowQueryOption)
- .unwrap_or(core::ptr::null_mut());
- let options_len = options.map(|op| op.len()).unwrap_or(0);
- let mut value = unsafe {
- BNGetMediumLevelILPossibleStackContentsAfterInstruction(
- self.function.handle,
- offset,
- size,
- self.index,
- options_ptr,
- options_len,
- )
- };
- let result = unsafe { PossibleValueSet::from_raw(value) };
- unsafe { BNFreePossibleValueSet(&mut value) }
- result
- }
-
- /// Gets the unique variable for a definition instruction. This unique variable can be passed
- /// to [crate::function::Function::split_variable] to split a variable at a definition. The given `var` is the
- /// assigned variable to query.
- ///
- /// * `var` - variable to query
- pub fn split_var_for_definition(&self, var: Variable) -> Variable {
- let index = unsafe {
- BNGetDefaultIndexForMediumLevelILVariableDefinition(
- self.function.handle,
- &var.raw(),
- self.index,
- )
- };
- Variable::new(var.t, index, var.storage)
- }
-
- /// alias for [MediumLevelILInstruction::split_var_for_definition]
- #[inline]
- pub fn get_split_var_for_definition(&self, var: &Variable) -> Variable {
- self.split_var_for_definition(*var)
- }
-
- 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),
- }
- }
-
- 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),
- }
- }
-
- fn lift_unary_op(&self, op: UnaryOp) -> LiftedUnaryOp {
- LiftedUnaryOp {
- src: self.lift_operand(op.src),
- }
- }
-
- fn lift_call(&self, op: Call) -> LiftedCall {
- LiftedCall {
- output: OperandIter::new(&*self.function, op.first_output, op.num_outputs)
- .vars()
- .collect(),
- dest: self.lift_operand(op.dest),
- params: OperandIter::new(&*self.function, op.first_param, op.num_params)
- .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)
- .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),
- }
- }
-}
-
-impl CoreArrayProvider for MediumLevelILInstruction {
- type Raw = usize;
- type Context = Ref<MediumLevelILFunction>;
- type Wrapped<'a> = Self;
-}
-
-unsafe impl CoreArrayProviderInner for MediumLevelILInstruction {
- unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
- BNFreeILInstructionList(raw)
- }
-
- unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- context.instruction_from_idx(*raw)
- }
-}
-
-fn get_float(value: u64, size: usize) -> f64 {
- match size {
- 4 => f32::from_bits(value as u32) as f64,
- 8 => f64::from_bits(value),
- // TODO how to handle this value?
- size => todo!("float size {}", size),
- }
-}
-
-fn get_raw_operation(function: &MediumLevelILFunction, idx: usize) -> BNMediumLevelILInstruction {
- unsafe { BNGetMediumLevelILByIndex(function.handle, idx) }
-}
-
-fn get_var(id: u64) -> Variable {
- unsafe { Variable::from_identifier(id) }
-}
-
-fn get_var_ssa(id: u64, version: usize) -> SSAVariable {
- SSAVariable::new(get_var(id), version)
-}
-
-fn get_call_output(function: &MediumLevelILFunction, idx: usize) -> impl Iterator<Item = Variable> {
- 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).vars()
-}
-
-fn get_call_params(
- function: &MediumLevelILFunction,
- idx: usize,
-) -> impl Iterator<Item = MediumLevelILInstruction> {
- let op = get_raw_operation(function, idx);
- assert_eq!(op.operation, BNMediumLevelILOperation::MLIL_CALL_PARAM);
- OperandIter::new(function, op.operands[1] as usize, op.operands[0] as usize).exprs()
-}
-
-fn get_call_output_ssa(
- function: &MediumLevelILFunction,
- idx: usize,
-) -> impl Iterator<Item = SSAVariable> {
- let op = get_raw_operation(function, idx);
- assert_eq!(op.operation, BNMediumLevelILOperation::MLIL_CALL_OUTPUT_SSA);
- OperandIter::new(function, op.operands[2] as usize, op.operands[1] as usize).ssa_vars()
-}
-
-fn get_call_params_ssa(
- function: &MediumLevelILFunction,
- idx: usize,
-) -> impl Iterator<Item = MediumLevelILInstruction> {
- 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).exprs()
-}
-
-/// Conditional branching instruction and an expected conditional result
-pub struct BranchDependence {
- pub instruction: MediumLevelILInstruction,
- pub dependence: ILBranchDependence,
-}
-
-impl CoreArrayProvider for BranchDependence {
- type Raw = BNILBranchInstructionAndDependence;
- type Context = Ref<MediumLevelILFunction>;
- type Wrapped<'a> = Self;
-}
-
-unsafe impl CoreArrayProviderInner for BranchDependence {
- unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
- unsafe { BNFreeILBranchDependenceList(raw) };
- }
-
- unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- Self {
- instruction: MediumLevelILInstruction::new(context.clone(), raw.branch),
- dependence: raw.dependence,
- }
- }
-}
diff --git a/rust/src/mlil/lift.rs b/rust/src/mlil/lift.rs
deleted file mode 100644
index 7a5e159b..00000000
--- a/rust/src/mlil/lift.rs
+++ /dev/null
@@ -1,510 +0,0 @@
-use std::collections::BTreeMap;
-
-use crate::architecture::CoreIntrinsic;
-use crate::rc::Ref;
-use crate::types::{ConstantData, SSAVariable, Variable};
-
-use super::operation::*;
-use super::MediumLevelILFunction;
-
-#[derive(Clone)]
-pub enum MediumLevelILLiftedOperand {
- ConstantData(ConstantData),
- Intrinsic(CoreIntrinsic),
- Expr(MediumLevelILLiftedInstruction),
- ExprList(Vec<MediumLevelILLiftedInstruction>),
- Float(f64),
- Int(u64),
- IntList(Vec<u64>),
- TargetMap(BTreeMap<u64, u64>),
- Var(Variable),
- VarList(Vec<Variable>),
- VarSsa(SSAVariable),
- VarSsaList(Vec<SSAVariable>),
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct MediumLevelILLiftedInstruction {
- pub function: Ref<MediumLevelILFunction>,
- pub address: u64,
- pub index: usize,
- pub size: usize,
- pub kind: MediumLevelILLiftedInstructionKind,
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub enum MediumLevelILLiftedInstructionKind {
- Nop,
- Noret,
- Bp,
- Undef,
- Unimpl,
- If(LiftedIf),
- FloatConst(FloatConst),
- Const(Constant),
- ConstPtr(Constant),
- Import(Constant),
- ExternPtr(ExternPtr),
- ConstData(LiftedConstData),
- Jump(LiftedJump),
- RetHint(LiftedJump),
- StoreSsa(LiftedStoreSsa),
- StoreStructSsa(LiftedStoreStructSsa),
- StoreStruct(LiftedStoreStruct),
- Store(LiftedStore),
- JumpTo(LiftedJumpTo),
- Goto(Goto),
- FreeVarSlot(FreeVarSlot),
- SetVarField(LiftedSetVarField),
- SetVar(LiftedSetVar),
- FreeVarSlotSsa(FreeVarSlotSsa),
- SetVarSsaField(LiftedSetVarSsaField),
- SetVarAliasedField(LiftedSetVarSsaField),
- SetVarAliased(LiftedSetVarAliased),
- SetVarSsa(LiftedSetVarSsa),
- VarPhi(LiftedVarPhi),
- MemPhi(LiftedMemPhi),
- VarSplit(VarSplit),
- SetVarSplit(LiftedSetVarSplit),
- VarSplitSsa(VarSplitSsa),
- SetVarSplitSsa(LiftedSetVarSplitSsa),
- Add(LiftedBinaryOp),
- Sub(LiftedBinaryOp),
- And(LiftedBinaryOp),
- Or(LiftedBinaryOp),
- Xor(LiftedBinaryOp),
- Lsl(LiftedBinaryOp),
- Lsr(LiftedBinaryOp),
- Asr(LiftedBinaryOp),
- Rol(LiftedBinaryOp),
- Ror(LiftedBinaryOp),
- Mul(LiftedBinaryOp),
- MuluDp(LiftedBinaryOp),
- MulsDp(LiftedBinaryOp),
- Divu(LiftedBinaryOp),
- DivuDp(LiftedBinaryOp),
- Divs(LiftedBinaryOp),
- DivsDp(LiftedBinaryOp),
- Modu(LiftedBinaryOp),
- ModuDp(LiftedBinaryOp),
- Mods(LiftedBinaryOp),
- ModsDp(LiftedBinaryOp),
- CmpE(LiftedBinaryOp),
- CmpNe(LiftedBinaryOp),
- CmpSlt(LiftedBinaryOp),
- CmpUlt(LiftedBinaryOp),
- CmpSle(LiftedBinaryOp),
- CmpUle(LiftedBinaryOp),
- CmpSge(LiftedBinaryOp),
- CmpUge(LiftedBinaryOp),
- CmpSgt(LiftedBinaryOp),
- CmpUgt(LiftedBinaryOp),
- TestBit(LiftedBinaryOp),
- AddOverflow(LiftedBinaryOp),
- FcmpE(LiftedBinaryOp),
- FcmpNe(LiftedBinaryOp),
- FcmpLt(LiftedBinaryOp),
- FcmpLe(LiftedBinaryOp),
- FcmpGe(LiftedBinaryOp),
- FcmpGt(LiftedBinaryOp),
- FcmpO(LiftedBinaryOp),
- FcmpUo(LiftedBinaryOp),
- Fadd(LiftedBinaryOp),
- Fsub(LiftedBinaryOp),
- Fmul(LiftedBinaryOp),
- Fdiv(LiftedBinaryOp),
- Adc(LiftedBinaryOpCarry),
- Sbb(LiftedBinaryOpCarry),
- Rlc(LiftedBinaryOpCarry),
- Rrc(LiftedBinaryOpCarry),
- Call(LiftedCall),
- Tailcall(LiftedCall),
- Intrinsic(LiftedIntrinsic),
- Syscall(LiftedSyscallCall),
- IntrinsicSsa(LiftedIntrinsicSsa),
- CallSsa(LiftedCallSsa),
- TailcallSsa(LiftedCallSsa),
- CallUntypedSsa(LiftedCallUntypedSsa),
- TailcallUntypedSsa(LiftedCallUntypedSsa),
- SyscallSsa(LiftedSyscallSsa),
- SyscallUntypedSsa(LiftedSyscallUntypedSsa),
- CallUntyped(LiftedCallUntyped),
- TailcallUntyped(LiftedCallUntyped),
- SyscallUntyped(LiftedSyscallUntyped),
- SeparateParamList(LiftedSeparateParamList),
- SharedParamSlot(LiftedSharedParamSlot),
- Neg(LiftedUnaryOp),
- Not(LiftedUnaryOp),
- Sx(LiftedUnaryOp),
- Zx(LiftedUnaryOp),
- LowPart(LiftedUnaryOp),
- BoolToInt(LiftedUnaryOp),
- UnimplMem(LiftedUnaryOp),
- Fsqrt(LiftedUnaryOp),
- Fneg(LiftedUnaryOp),
- Fabs(LiftedUnaryOp),
- FloatToInt(LiftedUnaryOp),
- IntToFloat(LiftedUnaryOp),
- FloatConv(LiftedUnaryOp),
- RoundToInt(LiftedUnaryOp),
- Floor(LiftedUnaryOp),
- Ceil(LiftedUnaryOp),
- Ftrunc(LiftedUnaryOp),
- Load(LiftedUnaryOp),
- LoadStruct(LiftedLoadStruct),
- LoadStructSsa(LiftedLoadStructSsa),
- LoadSsa(LiftedLoadSsa),
- Ret(LiftedRet),
- Var(Var),
- AddressOf(Var),
- VarField(Field),
- AddressOfField(Field),
- VarSsa(VarSsa),
- VarAliased(VarSsa),
- VarSsaField(VarSsaField),
- VarAliasedField(VarSsaField),
- Trap(Trap),
-}
-
-impl MediumLevelILLiftedInstruction {
- pub fn name(&self) -> &'static str {
- use MediumLevelILLiftedInstructionKind::*;
- match self.kind {
- Nop => "Nop",
- Noret => "Noret",
- Bp => "Bp",
- Undef => "Undef",
- Unimpl => "Unimpl",
- If(_) => "If",
- FloatConst(_) => "FloatConst",
- Const(_) => "Const",
- ConstPtr(_) => "ConstPtr",
- Import(_) => "Import",
- ExternPtr(_) => "ExternPtr",
- ConstData(_) => "ConstData",
- Jump(_) => "Jump",
- RetHint(_) => "RetHint",
- StoreSsa(_) => "StoreSsa",
- StoreStructSsa(_) => "StoreStructSsa",
- StoreStruct(_) => "StoreStruct",
- Store(_) => "Store",
- JumpTo(_) => "JumpTo",
- Goto(_) => "Goto",
- FreeVarSlot(_) => "FreeVarSlot",
- SetVarField(_) => "SetVarField",
- SetVar(_) => "SetVar",
- FreeVarSlotSsa(_) => "FreeVarSlotSsa",
- SetVarSsaField(_) => "SetVarSsaField",
- SetVarAliasedField(_) => "SetVarAliasedField",
- SetVarAliased(_) => "SetVarAliased",
- SetVarSsa(_) => "SetVarSsa",
- VarPhi(_) => "VarPhi",
- MemPhi(_) => "MemPhi",
- VarSplit(_) => "VarSplit",
- SetVarSplit(_) => "SetVarSplit",
- VarSplitSsa(_) => "VarSplitSsa",
- SetVarSplitSsa(_) => "SetVarSplitSsa",
- Add(_) => "Add",
- Sub(_) => "Sub",
- And(_) => "And",
- Or(_) => "Or",
- Xor(_) => "Xor",
- Lsl(_) => "Lsl",
- Lsr(_) => "Lsr",
- Asr(_) => "Asr",
- Rol(_) => "Rol",
- Ror(_) => "Ror",
- Mul(_) => "Mul",
- MuluDp(_) => "MuluDp",
- MulsDp(_) => "MulsDp",
- Divu(_) => "Divu",
- DivuDp(_) => "DivuDp",
- Divs(_) => "Divs",
- DivsDp(_) => "DivsDp",
- Modu(_) => "Modu",
- ModuDp(_) => "ModuDp",
- Mods(_) => "Mods",
- ModsDp(_) => "ModsDp",
- CmpE(_) => "CmpE",
- CmpNe(_) => "CmpNe",
- CmpSlt(_) => "CmpSlt",
- CmpUlt(_) => "CmpUlt",
- CmpSle(_) => "CmpSle",
- CmpUle(_) => "CmpUle",
- CmpSge(_) => "CmpSge",
- CmpUge(_) => "CmpUge",
- CmpSgt(_) => "CmpSgt",
- CmpUgt(_) => "CmpUgt",
- TestBit(_) => "TestBit",
- AddOverflow(_) => "AddOverflow",
- FcmpE(_) => "FcmpE",
- FcmpNe(_) => "FcmpNe",
- FcmpLt(_) => "FcmpLt",
- FcmpLe(_) => "FcmpLe",
- FcmpGe(_) => "FcmpGe",
- FcmpGt(_) => "FcmpGt",
- FcmpO(_) => "FcmpO",
- FcmpUo(_) => "FcmpUo",
- Fadd(_) => "Fadd",
- Fsub(_) => "Fsub",
- Fmul(_) => "Fmul",
- Fdiv(_) => "Fdiv",
- Adc(_) => "Adc",
- Sbb(_) => "Sbb",
- Rlc(_) => "Rlc",
- Rrc(_) => "Rrc",
- Call(_) => "Call",
- Tailcall(_) => "Tailcall",
- Syscall(_) => "Syscall",
- Intrinsic(_) => "Intrinsic",
- IntrinsicSsa(_) => "IntrinsicSsa",
- CallSsa(_) => "CallSsa",
- TailcallSsa(_) => "TailcallSsa",
- CallUntypedSsa(_) => "CallUntypedSsa",
- TailcallUntypedSsa(_) => "TailcallUntypedSsa",
- SyscallSsa(_) => "SyscallSsa",
- SyscallUntypedSsa(_) => "SyscallUntypedSsa",
- CallUntyped(_) => "CallUntyped",
- TailcallUntyped(_) => "TailcallUntyped",
- SyscallUntyped(_) => "SyscallUntyped",
- SeparateParamList(_) => "SeparateParamList",
- SharedParamSlot(_) => "SharedParamSlot",
- Neg(_) => "Neg",
- Not(_) => "Not",
- Sx(_) => "Sx",
- Zx(_) => "Zx",
- LowPart(_) => "LowPart",
- BoolToInt(_) => "BoolToInt",
- UnimplMem(_) => "UnimplMem",
- Fsqrt(_) => "Fsqrt",
- Fneg(_) => "Fneg",
- Fabs(_) => "Fabs",
- FloatToInt(_) => "FloatToInt",
- IntToFloat(_) => "IntToFloat",
- FloatConv(_) => "FloatConv",
- RoundToInt(_) => "RoundToInt",
- Floor(_) => "Floor",
- Ceil(_) => "Ceil",
- Ftrunc(_) => "Ftrunc",
- Load(_) => "Load",
- LoadStruct(_) => "LoadStruct",
- LoadStructSsa(_) => "LoadStructSsa",
- LoadSsa(_) => "LoadSsa",
- Ret(_) => "Ret",
- Var(_) => "Var",
- AddressOf(_) => "AddressOf",
- VarField(_) => "VarField",
- AddressOfField(_) => "AddressOfField",
- VarSsa(_) => "VarSsa",
- VarAliased(_) => "VarAliased",
- VarSsaField(_) => "VarSsaField",
- VarAliasedField(_) => "VarAliasedField",
- Trap(_) => "Trap",
- }
- }
-
- 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/mod.rs b/rust/src/mlil/mod.rs
deleted file mode 100644
index 8a9103ac..00000000
--- a/rust/src/mlil/mod.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-mod block;
-mod function;
-mod instruction;
-mod lift;
-pub mod operation;
-
-pub use self::block::*;
-pub use self::function::*;
-pub use self::instruction::*;
-pub use self::lift::*;
diff --git a/rust/src/mlil/operation.rs b/rust/src/mlil/operation.rs
deleted file mode 100644
index 278d1edb..00000000
--- a/rust/src/mlil/operation.rs
+++ /dev/null
@@ -1,581 +0,0 @@
-use std::collections::BTreeMap;
-
-use crate::{architecture::CoreIntrinsic, types::{ConstantData, SSAVariable, Variable}};
-
-use super::MediumLevelILLiftedInstruction;
-
-// IF
-#[derive(Copy, Clone)]
-pub struct MediumLevelILOperationIf {
- pub condition: usize,
- pub dest_true: u64,
- pub dest_false: u64,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedIf {
- pub condition: Box<MediumLevelILLiftedInstruction>,
- pub dest_true: u64,
- pub dest_false: u64,
-}
-
-// FLOAT_CONST
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub struct FloatConst {
- pub constant: f64,
-}
-
-// CONST, CONST_PTR, IMPORT
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct Constant {
- pub constant: u64,
-}
-
-// EXTERN_PTR
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct ExternPtr {
- pub constant: u64,
- pub offset: u64,
-}
-
-// CONST_DATA
-#[derive(Copy, Clone)]
-pub struct ConstData {
- pub constant_data_kind: u32,
- pub constant_data_value: i64,
- pub size: usize,
-}
-#[derive(Clone, Debug, Hash, PartialEq)]
-pub struct LiftedConstData {
- pub constant_data: ConstantData,
-}
-
-// JUMP, RET_HINT
-#[derive(Copy, Clone)]
-pub struct Jump {
- pub dest: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedJump {
- pub dest: Box<MediumLevelILLiftedInstruction>,
-}
-
-// STORE_SSA
-#[derive(Copy, Clone)]
-pub struct StoreSsa {
- pub dest: usize,
- pub dest_memory: u64,
- pub src_memory: u64,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedStoreSsa {
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub dest_memory: u64,
- pub src_memory: u64,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// STORE_STRUCT_SSA
-#[derive(Copy, Clone)]
-pub struct StoreStructSsa {
- 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 dest: Box<MediumLevelILLiftedInstruction>,
- pub offset: u64,
- pub dest_memory: u64,
- pub src_memory: u64,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// STORE_STRUCT
-#[derive(Copy, Clone)]
-pub struct StoreStruct {
- pub dest: usize,
- pub offset: u64,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedStoreStruct {
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub offset: u64,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// STORE
-#[derive(Copy, Clone)]
-pub struct Store {
- pub dest: usize,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedStore {
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// JUMP_TO
-#[derive(Copy, Clone)]
-pub struct JumpTo {
- pub dest: usize,
- pub first_operand: usize,
- pub num_operands: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedJumpTo {
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub targets: BTreeMap<u64, u64>,
-}
-
-// GOTO
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct Goto {
- pub dest: u64,
-}
-
-// FREE_VAR_SLOT
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct FreeVarSlot {
- pub dest: Variable,
-}
-
-// SET_VAR_FIELD
-#[derive(Copy, Clone)]
-pub struct SetVarField {
- pub dest: Variable,
- pub offset: u64,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVarField {
- pub dest: Variable,
- pub offset: u64,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// SET_VAR
-#[derive(Copy, Clone)]
-pub struct SetVar {
- pub dest: Variable,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVar {
- pub dest: Variable,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// FREE_VAR_SLOT_SSA
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct FreeVarSlotSsa {
- pub dest: SSAVariable,
- pub prev: SSAVariable,
-}
-
-// SET_VAR_SSA_FIELD, SET_VAR_ALIASED_FIELD
-#[derive(Copy, Clone)]
-pub struct SetVarSsaField {
- pub dest: SSAVariable,
- pub prev: SSAVariable,
- pub offset: u64,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVarSsaField {
- pub dest: SSAVariable,
- pub prev: SSAVariable,
- pub offset: u64,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// SET_VAR_ALIASED
-#[derive(Copy, Clone)]
-pub struct SetVarAliased {
- pub dest: SSAVariable,
- pub prev: SSAVariable,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVarAliased {
- pub dest: SSAVariable,
- pub prev: SSAVariable,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// SET_VAR_SSA
-#[derive(Copy, Clone)]
-pub struct SetVarSsa {
- pub dest: SSAVariable,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVarSsa {
- pub dest: SSAVariable,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// VAR_PHI
-#[derive(Copy, Clone)]
-pub struct VarPhi {
- pub dest: SSAVariable,
- pub first_operand: usize,
- pub num_operands: usize,
-}
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
-pub struct LiftedVarPhi {
- pub dest: SSAVariable,
- pub src: Vec<SSAVariable>,
-}
-
-// MEM_PHI
-#[derive(Copy, Clone)]
-pub struct MemPhi {
- pub dest_memory: u64,
- pub first_operand: usize,
- pub num_operands: usize,
-}
-#[derive(Clone, Debug, Hash, PartialEq, Eq)]
-pub struct LiftedMemPhi {
- pub dest_memory: u64,
- pub src_memory: Vec<u64>,
-}
-
-// VAR_SPLIT
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct VarSplit {
- pub high: Variable,
- pub low: Variable,
-}
-
-// SET_VAR_SPLIT
-#[derive(Copy, Clone)]
-pub struct SetVarSplit {
- pub high: Variable,
- pub low: Variable,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVarSplit {
- pub high: Variable,
- pub low: Variable,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// VAR_SPLIT_SSA
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct VarSplitSsa {
- pub high: SSAVariable,
- pub low: SSAVariable,
-}
-
-// SET_VAR_SPLIT_SSA
-#[derive(Copy, Clone)]
-pub struct SetVarSplitSsa {
- pub high: SSAVariable,
- pub low: SSAVariable,
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSetVarSplitSsa {
- pub high: SSAVariable,
- pub low: SSAVariable,
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// 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(Copy, Clone)]
-pub struct BinaryOp {
- pub left: usize,
- pub right: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedBinaryOp {
- pub left: Box<MediumLevelILLiftedInstruction>,
- pub right: Box<MediumLevelILLiftedInstruction>,
-}
-
-// ADC, SBB, RLC, RRC
-#[derive(Copy, Clone)]
-pub struct BinaryOpCarry {
- pub left: usize,
- pub right: usize,
- pub carry: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedBinaryOpCarry {
- pub left: Box<MediumLevelILLiftedInstruction>,
- pub right: Box<MediumLevelILLiftedInstruction>,
- pub carry: Box<MediumLevelILLiftedInstruction>,
-}
-
-// CALL, TAILCALL
-#[derive(Copy, Clone)]
-pub struct Call {
- 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 output: Vec<Variable>,
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// SYSCALL
-#[derive(Copy, Clone)]
-pub struct Syscall {
- pub first_output: usize,
- pub num_outputs: usize,
- pub first_param: usize,
- pub num_params: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSyscallCall {
- pub output: Vec<Variable>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// INTRINSIC
-#[derive(Copy, Clone)]
-pub struct Intrinsic {
- 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 output: Vec<Variable>,
- pub intrinsic: CoreIntrinsic,
- pub params: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// INTRINSIC_SSA
-#[derive(Copy, Clone)]
-pub struct IntrinsicSsa {
- 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 output: Vec<SSAVariable>,
- pub intrinsic: CoreIntrinsic,
- pub params: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// CALL_SSA, TAILCALL_SSA
-#[derive(Copy, Clone)]
-pub struct CallSsa {
- 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 output: Vec<SSAVariable>,
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
- pub src_memory: u64,
-}
-
-// CALL_UNTYPED_SSA, TAILCALL_UNTYPED_SSA
-#[derive(Copy, Clone)]
-pub struct CallUntypedSsa {
- pub output: usize,
- pub dest: usize,
- pub params: usize,
- pub stack: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedCallUntypedSsa {
- pub output: Vec<SSAVariable>,
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
- pub stack: Box<MediumLevelILLiftedInstruction>,
-}
-
-// SYSCALL_SSA
-#[derive(Copy, Clone)]
-pub struct SyscallSsa {
- pub output: usize,
- pub first_param: usize,
- pub num_params: usize,
- pub src_memory: u64,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSyscallSsa {
- pub output: Vec<SSAVariable>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
- pub src_memory: u64,
-}
-
-// SYSCALL_UNTYPED_SSA
-#[derive(Copy, Clone)]
-pub struct SyscallUntypedSsa {
- pub output: usize,
- pub params: usize,
- pub stack: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSyscallUntypedSsa {
- pub output: Vec<SSAVariable>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
- pub stack: Box<MediumLevelILLiftedInstruction>,
-}
-
-// CALL_UNTYPED, TAILCALL_UNTYPED
-#[derive(Copy, Clone)]
-pub struct CallUntyped {
- pub output: usize,
- pub dest: usize,
- pub params: usize,
- pub stack: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedCallUntyped {
- pub output: Vec<Variable>,
- pub dest: Box<MediumLevelILLiftedInstruction>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
- pub stack: Box<MediumLevelILLiftedInstruction>,
-}
-
-// SYSCALL_UNTYPED
-#[derive(Copy, Clone)]
-pub struct SyscallUntyped {
- pub output: usize,
- pub params: usize,
- pub stack: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSyscallUntyped {
- pub output: Vec<Variable>,
- pub params: Vec<MediumLevelILLiftedInstruction>,
- pub stack: Box<MediumLevelILLiftedInstruction>,
-}
-
-// 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(Copy, Clone)]
-pub struct UnaryOp {
- pub src: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedUnaryOp {
- pub src: Box<MediumLevelILLiftedInstruction>,
-}
-
-// LOAD_STRUCT
-#[derive(Copy, Clone)]
-pub struct LoadStruct {
- pub src: usize,
- pub offset: u64,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedLoadStruct {
- pub src: Box<MediumLevelILLiftedInstruction>,
- pub offset: u64,
-}
-
-// LOAD_STRUCT_SSA
-#[derive(Copy, Clone)]
-pub struct LoadStructSsa {
- pub src: usize,
- pub offset: u64,
- pub src_memory: u64,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedLoadStructSsa {
- pub src: Box<MediumLevelILLiftedInstruction>,
- pub offset: u64,
- pub src_memory: u64,
-}
-
-// LOAD_SSA
-#[derive(Copy, Clone)]
-pub struct LoadSsa {
- pub src: usize,
- pub src_memory: u64,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedLoadSsa {
- pub src: Box<MediumLevelILLiftedInstruction>,
- pub src_memory: u64,
-}
-
-// RET
-#[derive(Copy, Clone)]
-pub struct Ret {
- pub first_operand: usize,
- pub num_operands: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedRet {
- pub src: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// SEPARATE_PARAM_LIST
-#[derive(Copy, Clone)]
-pub struct SeparateParamList {
- pub first_param: usize,
- pub num_params: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSeparateParamList {
- pub params: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// SHARED_PARAM_SLOT
-#[derive(Copy, Clone)]
-pub struct SharedParamSlot {
- pub first_param: usize,
- pub num_params: usize,
-}
-#[derive(Clone, Debug, PartialEq)]
-pub struct LiftedSharedParamSlot {
- pub params: Vec<MediumLevelILLiftedInstruction>,
-}
-
-// VAR, ADDRESS_OF
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct Var {
- pub src: Variable,
-}
-
-// VAR_FIELD, ADDRESS_OF_FIELD
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct Field {
- pub src: Variable,
- pub offset: u64,
-}
-
-// VAR_SSA, VAR_ALIASED
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct VarSsa {
- pub src: SSAVariable,
-}
-
-// VAR_SSA_FIELD, VAR_ALIASED_FIELD
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct VarSsaField {
- pub src: SSAVariable,
- pub offset: u64,
-}
-
-// TRAP
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
-pub struct Trap {
- pub vector: u64,
-}