summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/src/high_level_il/function.rs21
-rw-r--r--rust/src/high_level_il/instruction.rs425
-rw-r--r--rust/src/high_level_il/lift.rs6
-rw-r--r--rust/src/high_level_il/operation.rs94
-rw-r--r--rust/src/language_representation.rs12
-rw-r--r--rust/src/low_level_il/operation.rs2
-rw-r--r--rust/src/medium_level_il/block.rs2
-rw-r--r--rust/src/medium_level_il/function.rs18
-rw-r--r--rust/src/medium_level_il/instruction.rs592
-rw-r--r--rust/src/medium_level_il/lift.rs8
-rw-r--r--rust/src/medium_level_il/operation.rs97
-rw-r--r--rust/tests/high_level_il.rs7
-rw-r--r--rust/tests/language_representation.rs10
-rw-r--r--rust/tests/medium_level_il.rs48
14 files changed, 744 insertions, 598 deletions
diff --git a/rust/src/high_level_il/function.rs b/rust/src/high_level_il/function.rs
index a65a244c..0a55470e 100644
--- a/rust/src/high_level_il/function.rs
+++ b/rust/src/high_level_il/function.rs
@@ -3,7 +3,9 @@ use std::hash::{Hash, Hasher};
use binaryninjacore_sys::*;
-use super::{HighLevelILBlock, HighLevelILInstruction, HighLevelInstructionIndex};
+use super::{
+ HighLevelExpressionIndex, HighLevelILBlock, HighLevelILInstruction, HighLevelInstructionIndex,
+};
use crate::basic_block::BasicBlock;
use crate::function::{Function, Location};
use crate::rc::{Array, Ref, RefCountable};
@@ -35,31 +37,34 @@ impl HighLevelILFunction {
if index.0 >= self.instruction_count() {
None
} else {
- Some(HighLevelILInstruction::new(self.to_owned(), index))
+ Some(HighLevelILInstruction::from_instr_index(
+ self.to_owned(),
+ index,
+ ))
}
}
pub fn instruction_from_expr_index(
&self,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
) -> Option<HighLevelILInstruction> {
if expr_index.0 >= self.expression_count() {
None
} else {
- Some(HighLevelILInstruction::new_expr(
+ Some(HighLevelILInstruction::from_expr_index(
self.to_owned(),
expr_index,
))
}
}
- // TODO: This returns an expression index!
- pub fn root_instruction_index(&self) -> HighLevelInstructionIndex {
- HighLevelInstructionIndex(unsafe { BNGetHighLevelILRootExpr(self.handle) })
+ pub fn root_expression_index(&self) -> HighLevelExpressionIndex {
+ HighLevelExpressionIndex(unsafe { BNGetHighLevelILRootExpr(self.handle) })
}
pub fn root(&self) -> HighLevelILInstruction {
- HighLevelILInstruction::new_expr(self.as_ast(), self.root_instruction_index())
+ self.instruction_from_expr_index(self.root_expression_index())
+ .expect("Invalid root expression index")
}
pub fn set_root(&self, new_root: &HighLevelILInstruction) {
diff --git a/rust/src/high_level_il/instruction.rs b/rust/src/high_level_il/instruction.rs
index 67225eea..e571354c 100644
--- a/rust/src/high_level_il/instruction.rs
+++ b/rust/src/high_level_il/instruction.rs
@@ -38,28 +38,76 @@ impl Display for HighLevelInstructionIndex {
}
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct HighLevelExpressionIndex(pub usize);
+
+impl HighLevelExpressionIndex {
+ pub fn next(&self) -> Self {
+ Self(self.0 + 1)
+ }
+}
+
+impl From<usize> for HighLevelExpressionIndex {
+ fn from(index: usize) -> Self {
+ Self(index)
+ }
+}
+
+impl From<u64> for HighLevelExpressionIndex {
+ fn from(index: u64) -> Self {
+ Self(index as usize)
+ }
+}
+
+impl Display for HighLevelExpressionIndex {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("{}", self.0))
+ }
+}
+
#[derive(Clone)]
pub struct HighLevelILInstruction {
pub function: Ref<HighLevelILFunction>,
pub address: u64,
- pub expr_index: HighLevelInstructionIndex,
+ pub instr_index: HighLevelInstructionIndex,
+ pub expr_index: HighLevelExpressionIndex,
pub size: usize,
pub kind: HighLevelILInstructionKind,
}
impl HighLevelILInstruction {
- pub(crate) fn new(
+ pub(crate) fn from_instr_index(
+ function: Ref<HighLevelILFunction>,
+ instr_index: HighLevelInstructionIndex,
+ ) -> Self {
+ // Get the associated expression index for the top-level instruction.
+ let expr_index_raw =
+ unsafe { BNGetHighLevelILIndexForInstruction(function.handle, instr_index.0) };
+ Self::new(
+ function,
+ instr_index,
+ HighLevelExpressionIndex(expr_index_raw),
+ )
+ }
+
+ pub(crate) fn from_expr_index(
function: Ref<HighLevelILFunction>,
- index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
) -> Self {
- let expr_index = unsafe { BNGetHighLevelILIndexForInstruction(function.handle, index.0) };
- Self::new_expr(function, HighLevelInstructionIndex(expr_index))
+ // Get the associated top-level instruction index for the expression.
+ let instr_index_raw =
+ unsafe { BNGetHighLevelILInstructionForExpr(function.handle, expr_index.0) };
+ Self::new(
+ function,
+ HighLevelInstructionIndex(instr_index_raw),
+ expr_index,
+ )
}
- // TODO: I need HighLevelILExpression YESTERDAY!!!!
- pub(crate) fn new_expr(
+ pub(crate) fn new(
function: Ref<HighLevelILFunction>,
- expr_index: HighLevelInstructionIndex,
+ instr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
) -> Self {
let op =
unsafe { BNGetHighLevelILByIndex(function.handle, expr_index.0, function.full_ast) };
@@ -76,234 +124,234 @@ impl HighLevelILInstruction {
HLIL_FORCE_VER | HLIL_FORCE_VER_SSA | HLIL_ASSERT | HLIL_ASSERT_SSA => Op::Undef,
HLIL_UNIMPL => Op::Unimpl,
HLIL_ADC => Op::Adc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
+ carry: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_SBB => Op::Sbb(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
+ carry: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_RLC => Op::Rlc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
+ carry: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_RRC => Op::Rrc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
+ carry: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_ADD => Op::Add(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_SUB => Op::Sub(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_AND => Op::And(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_OR => Op::Or(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_XOR => Op::Xor(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_LSL => Op::Lsl(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_LSR => Op::Lsr(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ASR => Op::Asr(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ROL => Op::Rol(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ROR => Op::Ror(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MUL => Op::Mul(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MULU_DP => Op::MuluDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MULS_DP => Op::MulsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_DIVU => Op::Divu(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_DIVU_DP => Op::DivuDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_DIVS => Op::Divs(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_DIVS_DP => Op::DivsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MODU => Op::Modu(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MODU_DP => Op::ModuDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MODS => Op::Mods(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_MODS_DP => Op::ModsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_E => Op::CmpE(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_NE => Op::CmpNe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_SLT => Op::CmpSlt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_ULT => Op::CmpUlt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_SLE => Op::CmpSle(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_ULE => Op::CmpUle(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_SGE => Op::CmpSge(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_UGE => Op::CmpUge(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_SGT => Op::CmpSgt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_CMP_UGT => Op::CmpUgt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_TEST_BIT => Op::TestBit(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FADD => Op::Fadd(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FSUB => Op::Fsub(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FMUL => Op::Fmul(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FDIV => Op::Fdiv(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_E => Op::FcmpE(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_NE => Op::FcmpNe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_LT => Op::FcmpLt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_LE => Op::FcmpLe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_GE => Op::FcmpGe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_GT => Op::FcmpGt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_O => Op::FcmpO(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_FCMP_UO => Op::FcmpUo(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: HighLevelExpressionIndex::from(op.operands[0]),
+ right: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ARRAY_INDEX => Op::ArrayIndex(ArrayIndex {
- src: op.operands[0] as usize,
- index: op.operands[1] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ index: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ARRAY_INDEX_SSA => Op::ArrayIndexSsa(ArrayIndexSsa {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
src_memory: op.operands[1],
- index: op.operands[2] as usize,
+ index: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_ASSIGN => Op::Assign(Assign {
- dest: op.operands[0] as usize,
- src: op.operands[1] as usize,
+ dest: HighLevelExpressionIndex::from(op.operands[0]),
+ src: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_ASSIGN_MEM_SSA => Op::AssignMemSsa(AssignMemSsa {
- dest: op.operands[0] as usize,
+ dest: HighLevelExpressionIndex::from(op.operands[0]),
dest_memory: op.operands[1],
- src: op.operands[2] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[2]),
src_memory: op.operands[3],
}),
HLIL_ASSIGN_UNPACK => Op::AssignUnpack(AssignUnpack {
num_dests: op.operands[0] as usize,
first_dest: op.operands[1] as usize,
- src: op.operands[2] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_ASSIGN_UNPACK_MEM_SSA => Op::AssignUnpackMemSsa(AssignUnpackMemSsa {
num_dests: op.operands[0] as usize,
first_dest: op.operands[1] as usize,
dest_memory: op.operands[2],
- src: op.operands[3] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[3]),
src_memory: op.operands[4],
}),
HLIL_BLOCK => Op::Block(Block {
@@ -311,17 +359,17 @@ impl HighLevelILInstruction {
first_param: op.operands[1] as usize,
}),
HLIL_CALL => Op::Call(Call {
- dest: op.operands[0] as usize,
+ dest: HighLevelExpressionIndex::from(op.operands[0]),
num_params: op.operands[1] as usize,
first_param: op.operands[2] as usize,
}),
HLIL_TAILCALL => Op::Tailcall(Call {
- dest: op.operands[0] as usize,
+ dest: HighLevelExpressionIndex::from(op.operands[0]),
num_params: op.operands[1] as usize,
first_param: op.operands[2] as usize,
}),
HLIL_CALL_SSA => Op::CallSsa(CallSsa {
- dest: op.operands[0] as usize,
+ dest: HighLevelExpressionIndex::from(op.operands[0]),
num_params: op.operands[1] as usize,
first_param: op.operands[2] as usize,
dest_memory: op.operands[3],
@@ -330,7 +378,7 @@ impl HighLevelILInstruction {
HLIL_CASE => Op::Case(Case {
num_values: op.operands[0] as usize,
first_value: op.operands[1] as usize,
- body: op.operands[2] as usize,
+ body: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_CONST => Op::Const(Const {
constant: op.operands[0],
@@ -347,70 +395,70 @@ impl HighLevelILInstruction {
size: op.size,
}),
HLIL_DEREF => Op::Deref(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_ADDRESS_OF => Op::AddressOf(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_NEG => Op::Neg(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_NOT => Op::Not(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_SX => Op::Sx(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_ZX => Op::Zx(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_LOW_PART => Op::LowPart(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FSQRT => Op::Fsqrt(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FNEG => Op::Fneg(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FABS => Op::Fabs(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FLOAT_CONV => Op::FloatConv(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FLOOR => Op::Floor(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_CEIL => Op::Ceil(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_FTRUNC => Op::Ftrunc(UnaryOp {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_DEREF_FIELD_SSA => Op::DerefFieldSsa(DerefFieldSsa {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
src_memory: op.operands[1],
offset: op.operands[2],
member_index: get_member_index(op.operands[3]),
}),
HLIL_DEREF_SSA => Op::DerefSsa(DerefSsa {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
src_memory: op.operands[1],
}),
HLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr {
@@ -421,17 +469,17 @@ impl HighLevelILInstruction {
constant: get_float(op.operands[0], op.size),
}),
HLIL_FOR => Op::For(ForLoop {
- init: op.operands[0] as usize,
- condition: op.operands[1] as usize,
- update: op.operands[2] as usize,
- body: op.operands[3] as usize,
+ init: HighLevelExpressionIndex::from(op.operands[0]),
+ condition: HighLevelExpressionIndex::from(op.operands[1]),
+ update: HighLevelExpressionIndex::from(op.operands[2]),
+ body: HighLevelExpressionIndex::from(op.operands[3]),
}),
HLIL_FOR_SSA => Op::ForSsa(ForLoopSsa {
- init: op.operands[0] as usize,
- condition_phi: op.operands[1] as usize,
- condition: op.operands[2] as usize,
- update: op.operands[3] as usize,
- body: op.operands[4] as usize,
+ init: HighLevelExpressionIndex::from(op.operands[0]),
+ condition_phi: HighLevelExpressionIndex::from(op.operands[1]),
+ condition: HighLevelExpressionIndex::from(op.operands[2]),
+ update: HighLevelExpressionIndex::from(op.operands[3]),
+ body: HighLevelExpressionIndex::from(op.operands[4]),
}),
HLIL_GOTO => Op::Goto(Label {
target: op.operands[0],
@@ -440,9 +488,9 @@ impl HighLevelILInstruction {
target: op.operands[0],
}),
HLIL_IF => Op::If(If {
- condition: op.operands[0] as usize,
- cond_true: op.operands[1] as usize,
- cond_false: op.operands[2] as usize,
+ condition: HighLevelExpressionIndex::from(op.operands[0]),
+ cond_true: HighLevelExpressionIndex::from(op.operands[1]),
+ cond_false: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_INTRINSIC => Op::Intrinsic(Intrinsic {
intrinsic: op.operands[0] as u32,
@@ -457,7 +505,7 @@ impl HighLevelILInstruction {
src_memory: op.operands[4],
}),
HLIL_JUMP => Op::Jump(Jump {
- dest: op.operands[0] as usize,
+ dest: HighLevelExpressionIndex::from(op.operands[0]),
}),
HLIL_MEM_PHI => Op::MemPhi(MemPhi {
dest: op.operands[0],
@@ -469,22 +517,22 @@ impl HighLevelILInstruction {
first_src: op.operands[1] as usize,
}),
HLIL_SPLIT => Op::Split(Split {
- high: op.operands[0] as usize,
- low: op.operands[1] as usize,
+ high: HighLevelExpressionIndex::from(op.operands[0]),
+ low: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_STRUCT_FIELD => Op::StructField(StructField {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
offset: op.operands[1],
member_index: get_member_index(op.operands[2]),
}),
HLIL_DEREF_FIELD => Op::DerefField(StructField {
- src: op.operands[0] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[0]),
offset: op.operands[1],
member_index: get_member_index(op.operands[2]),
}),
HLIL_SWITCH => Op::Switch(Switch {
- condition: op.operands[0] as usize,
- default: op.operands[1] as usize,
+ condition: HighLevelExpressionIndex::from(op.operands[0]),
+ default: HighLevelExpressionIndex::from(op.operands[1]),
num_cases: op.operands[2] as usize,
first_case: op.operands[3] as usize,
}),
@@ -509,11 +557,11 @@ impl HighLevelILInstruction {
}),
HLIL_VAR_INIT => Op::VarInit(VarInit {
dest: get_var(op.operands[0]),
- src: op.operands[1] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_VAR_INIT_SSA => Op::VarInitSsa(VarInitSsa {
dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
- src: op.operands[2] as usize,
+ src: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_VAR_PHI => Op::VarPhi(VarPhi {
dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
@@ -524,27 +572,28 @@ impl HighLevelILInstruction {
var: get_var_ssa((op.operands[0], op.operands[1] as usize)),
}),
HLIL_WHILE => Op::While(While {
- condition: op.operands[0] as usize,
- body: op.operands[1] as usize,
+ condition: HighLevelExpressionIndex::from(op.operands[0]),
+ body: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_DO_WHILE => Op::DoWhile(While {
- body: op.operands[0] as usize,
- condition: op.operands[1] as usize,
+ body: HighLevelExpressionIndex::from(op.operands[0]),
+ condition: HighLevelExpressionIndex::from(op.operands[1]),
}),
HLIL_WHILE_SSA => Op::WhileSsa(WhileSsa {
- condition_phi: op.operands[0] as usize,
- condition: op.operands[1] as usize,
- body: op.operands[2] as usize,
+ condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
+ condition: HighLevelExpressionIndex::from(op.operands[1]),
+ body: HighLevelExpressionIndex::from(op.operands[2]),
}),
HLIL_DO_WHILE_SSA => Op::DoWhileSsa(WhileSsa {
- condition_phi: op.operands[0] as usize,
- condition: op.operands[1] as usize,
- body: op.operands[2] as usize,
+ condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
+ condition: HighLevelExpressionIndex::from(op.operands[1]),
+ body: HighLevelExpressionIndex::from(op.operands[2]),
}),
};
Self {
function,
address: op.address,
+ instr_index,
expr_index,
size: op.size,
kind,
@@ -578,7 +627,7 @@ impl HighLevelILInstruction {
fn get_expr_list(&self, operand_idx: usize) -> Vec<HighLevelILInstruction> {
self.get_operand_list(operand_idx)
.into_iter()
- .map(|val| HighLevelInstructionIndex(val as usize))
+ .map(|val| HighLevelExpressionIndex(val as usize))
.filter_map(|idx| self.function.instruction_from_expr_index(idx))
.collect()
}
@@ -882,6 +931,7 @@ impl HighLevelILInstruction {
HighLevelILLiftedInstruction {
function: self.function.clone(),
address: self.address,
+ instr_index: self.instr_index,
expr_index: self.expr_index,
size: self.size,
kind,
@@ -932,18 +982,11 @@ impl HighLevelILInstruction {
SSAVariable::new(variable, version)
}
- fn lift_operand(&self, expr_idx: usize) -> Box<HighLevelILLiftedInstruction> {
- // TODO: UGH, if your gonna call it expr_idx, call the instruction and expression!!!!!
- // TODO: We dont even need to say instruction in the type!
- // TODO: IF you want to have an instruction type, there needs to be a separate expression type
- // TODO: See the lowlevelil module.
- let expr_idx_is_really_instr_idx = HighLevelInstructionIndex(expr_idx);
- // TODO: Ugh, this is so dumb..... i want HighLevelILLiftedExpression yesterday!!!
- let operand_instr = self
- .function
- .instruction_from_expr_index(expr_idx_is_really_instr_idx)
- .unwrap();
- // TODO: Why box it here??!?!?! insane.
+ fn lift_operand(
+ &self,
+ expr_idx: HighLevelExpressionIndex,
+ ) -> Box<HighLevelILLiftedInstruction> {
+ let operand_instr = self.function.instruction_from_expr_index(expr_idx).unwrap();
Box::new(operand_instr.lift())
}
@@ -1024,7 +1067,9 @@ unsafe impl CoreArrayProviderInner for HighLevelILInstruction {
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- Self::new(context.clone(), HighLevelInstructionIndex(*raw))
+ context
+ .instruction_from_index(HighLevelInstructionIndex(*raw))
+ .unwrap()
}
}
diff --git a/rust/src/high_level_il/lift.rs b/rust/src/high_level_il/lift.rs
index fd0b9398..ab04f44b 100644
--- a/rust/src/high_level_il/lift.rs
+++ b/rust/src/high_level_il/lift.rs
@@ -1,5 +1,5 @@
use super::operation::*;
-use super::{HighLevelILFunction, HighLevelInstructionIndex};
+use super::{HighLevelExpressionIndex, HighLevelILFunction, HighLevelInstructionIndex};
use std::fmt::{Debug, Formatter};
use crate::architecture::CoreIntrinsic;
@@ -30,8 +30,8 @@ pub enum HighLevelILLiftedOperand {
pub struct HighLevelILLiftedInstruction {
pub function: Ref<HighLevelILFunction>,
pub address: u64,
- // TODO: Please i need expression
- pub expr_index: HighLevelInstructionIndex,
+ pub instr_index: HighLevelInstructionIndex,
+ pub expr_index: HighLevelExpressionIndex,
pub size: usize,
pub kind: HighLevelILLiftedInstructionKind,
}
diff --git a/rust/src/high_level_il/operation.rs b/rust/src/high_level_il/operation.rs
index 9c218227..702ec38a 100644
--- a/rust/src/high_level_il/operation.rs
+++ b/rust/src/high_level_il/operation.rs
@@ -2,7 +2,7 @@ use binaryninjacore_sys::*;
use core::ffi;
use std::fmt::{Debug, Formatter};
-use super::HighLevelILLiftedInstruction;
+use super::{HighLevelExpressionIndex, HighLevelILLiftedInstruction};
use crate::architecture::CoreIntrinsic;
use crate::function::Function;
use crate::rc::Ref;
@@ -44,9 +44,9 @@ impl Debug for GotoLabel {
// ADC, SBB, RLC, RRC
#[derive(Debug, Copy, Clone)]
pub struct BinaryOpCarry {
- pub left: usize,
- pub right: usize,
- pub carry: usize,
+ pub left: HighLevelExpressionIndex,
+ pub right: HighLevelExpressionIndex,
+ pub carry: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedBinaryOpCarry {
@@ -58,8 +58,8 @@ pub struct LiftedBinaryOpCarry {
// 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, FADD, FSUB, FMUL, FDIV, FCMP_E, FCMP_NE, FCMP_LT, FCMP_LE, FCMP_GE, FCMP_GT, FCMP_O, FCMP_UO
#[derive(Debug, Copy, Clone)]
pub struct BinaryOp {
- pub left: usize,
- pub right: usize,
+ pub left: HighLevelExpressionIndex,
+ pub right: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedBinaryOp {
@@ -70,8 +70,8 @@ pub struct LiftedBinaryOp {
// ARRAY_INDEX
#[derive(Debug, Copy, Clone)]
pub struct ArrayIndex {
- pub src: usize,
- pub index: usize,
+ pub src: HighLevelExpressionIndex,
+ pub index: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedArrayIndex {
@@ -82,9 +82,9 @@ pub struct LiftedArrayIndex {
// ARRAY_INDEX_SSA
#[derive(Debug, Copy, Clone)]
pub struct ArrayIndexSsa {
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
pub src_memory: u64,
- pub index: usize,
+ pub index: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedArrayIndexSsa {
@@ -96,8 +96,8 @@ pub struct LiftedArrayIndexSsa {
// ASSIGN
#[derive(Debug, Copy, Clone)]
pub struct Assign {
- pub dest: usize,
- pub src: usize,
+ pub dest: HighLevelExpressionIndex,
+ pub src: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedAssign {
@@ -108,9 +108,9 @@ pub struct LiftedAssign {
// ASSIGN_MEM_SSA
#[derive(Debug, Copy, Clone)]
pub struct AssignMemSsa {
- pub dest: usize,
+ pub dest: HighLevelExpressionIndex,
pub dest_memory: u64,
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
@@ -126,7 +126,7 @@ pub struct LiftedAssignMemSsa {
pub struct AssignUnpack {
pub first_dest: usize,
pub num_dests: usize,
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedAssignUnpack {
@@ -140,7 +140,7 @@ pub struct AssignUnpackMemSsa {
pub first_dest: usize,
pub num_dests: usize,
pub dest_memory: u64,
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
@@ -165,7 +165,7 @@ pub struct LiftedBlock {
// CALL, TAILCALL
#[derive(Debug, Copy, Clone)]
pub struct Call {
- pub dest: usize,
+ pub dest: HighLevelExpressionIndex,
pub first_param: usize,
pub num_params: usize,
}
@@ -178,7 +178,7 @@ pub struct LiftedCall {
// CALL_SSA
#[derive(Debug, Copy, Clone)]
pub struct CallSsa {
- pub dest: usize,
+ pub dest: HighLevelExpressionIndex,
pub first_param: usize,
pub num_params: usize,
pub dest_memory: u64,
@@ -197,7 +197,7 @@ pub struct LiftedCallSsa {
pub struct Case {
pub first_value: usize,
pub num_values: usize,
- pub body: usize,
+ pub body: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCase {
@@ -227,7 +227,7 @@ pub struct LiftedConstData {
// DEREF, ADDRESS_OF, 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
#[derive(Debug, Copy, Clone)]
pub struct UnaryOp {
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedUnaryOp {
@@ -237,7 +237,7 @@ pub struct LiftedUnaryOp {
// DEREF_FIELD_SSA
#[derive(Debug, Copy, Clone)]
pub struct DerefFieldSsa {
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
pub src_memory: u64,
pub offset: u64,
pub member_index: Option<usize>,
@@ -254,7 +254,7 @@ pub struct LiftedDerefFieldSsa {
// DEREF_SSA
#[derive(Debug, Copy, Clone)]
pub struct DerefSsa {
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
pub src_memory: u64,
}
@@ -280,10 +280,10 @@ pub struct FloatConst {
// FOR
#[derive(Debug, Copy, Clone)]
pub struct ForLoop {
- pub init: usize,
- pub condition: usize,
- pub update: usize,
- pub body: usize,
+ pub init: HighLevelExpressionIndex,
+ pub condition: HighLevelExpressionIndex,
+ pub update: HighLevelExpressionIndex,
+ pub body: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
@@ -297,11 +297,11 @@ pub struct LiftedForLoop {
// FOR_SSA
#[derive(Debug, Copy, Clone)]
pub struct ForLoopSsa {
- pub init: usize,
- pub condition_phi: usize,
- pub condition: usize,
- pub update: usize,
- pub body: usize,
+ pub init: HighLevelExpressionIndex,
+ pub condition_phi: HighLevelExpressionIndex,
+ pub condition: HighLevelExpressionIndex,
+ pub update: HighLevelExpressionIndex,
+ pub body: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedForLoopSsa {
@@ -335,9 +335,9 @@ impl LiftedLabel {
// IF
#[derive(Debug, Copy, Clone)]
pub struct If {
- pub condition: usize,
- pub cond_true: usize,
- pub cond_false: usize,
+ pub condition: HighLevelExpressionIndex,
+ pub cond_true: HighLevelExpressionIndex,
+ pub cond_false: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedIf {
@@ -379,7 +379,7 @@ pub struct LiftedIntrinsicSsa {
// JUMP
#[derive(Debug, Copy, Clone)]
pub struct Jump {
- pub dest: usize,
+ pub dest: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedJump {
@@ -413,8 +413,8 @@ pub struct LiftedRet {
// SPLIT
#[derive(Debug, Copy, Clone)]
pub struct Split {
- pub high: usize,
- pub low: usize,
+ pub high: HighLevelExpressionIndex,
+ pub low: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSplit {
@@ -425,7 +425,7 @@ pub struct LiftedSplit {
// STRUCT_FIELD, DEREF_FIELD
#[derive(Debug, Copy, Clone)]
pub struct StructField {
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
pub offset: u64,
pub member_index: Option<usize>,
}
@@ -439,8 +439,8 @@ pub struct LiftedStructField {
// SWITCH
#[derive(Debug, Copy, Clone)]
pub struct Switch {
- pub condition: usize,
- pub default: usize,
+ pub condition: HighLevelExpressionIndex,
+ pub default: HighLevelExpressionIndex,
pub first_case: usize,
pub num_cases: usize,
}
@@ -493,7 +493,7 @@ pub struct Var {
#[derive(Debug, Copy, Clone)]
pub struct VarInit {
pub dest: Variable,
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedVarInit {
@@ -505,7 +505,7 @@ pub struct LiftedVarInit {
#[derive(Debug, Copy, Clone)]
pub struct VarInitSsa {
pub dest: SSAVariable,
- pub src: usize,
+ pub src: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedVarInitSsa {
@@ -535,8 +535,8 @@ pub struct VarSsa {
// WHILE, DO_WHILE
#[derive(Debug, Copy, Clone)]
pub struct While {
- pub condition: usize,
- pub body: usize,
+ pub condition: HighLevelExpressionIndex,
+ pub body: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedWhile {
@@ -547,9 +547,9 @@ pub struct LiftedWhile {
// WHILE_SSA, DO_WHILE_SSA
#[derive(Debug, Copy, Clone)]
pub struct WhileSsa {
- pub condition_phi: usize,
- pub condition: usize,
- pub body: usize,
+ pub condition_phi: HighLevelExpressionIndex,
+ pub condition: HighLevelExpressionIndex,
+ pub body: HighLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedWhileSsa {
diff --git a/rust/src/language_representation.rs b/rust/src/language_representation.rs
index 536203fe..6008ec0c 100644
--- a/rust/src/language_representation.rs
+++ b/rust/src/language_representation.rs
@@ -10,7 +10,7 @@ use crate::binary_view::BinaryView;
use crate::disassembly::{DisassemblySettings, DisassemblyTextLine};
use crate::function::{Function, HighlightColor};
use crate::high_level_il::token_emitter::HighLevelILTokenEmitter;
-use crate::high_level_il::{HighLevelILFunction, HighLevelInstructionIndex};
+use crate::high_level_il::{HighLevelExpressionIndex, HighLevelILFunction};
use crate::line_formatter::CoreLineFormatter;
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref, RefCountable};
use crate::string::{BnString, IntoCStr};
@@ -57,7 +57,7 @@ pub trait LanguageRepresentationFunction: Send + Sync {
fn expr_text(
&self,
il: &HighLevelILFunction,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
tokens: &HighLevelILTokenEmitter,
settings: &DisassemblySettings,
as_full_ast: bool,
@@ -68,14 +68,14 @@ pub trait LanguageRepresentationFunction: Send + Sync {
fn begin_lines(
&self,
il: &HighLevelILFunction,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
tokens: &HighLevelILTokenEmitter,
);
fn end_lines(
&self,
il: &HighLevelILFunction,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
tokens: &HighLevelILTokenEmitter,
);
@@ -281,7 +281,7 @@ impl CoreLanguageRepresentationFunction {
pub fn expr_text(
&self,
il: &HighLevelILFunction,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
settings: &DisassemblySettings,
as_full_ast: bool,
precedence: OperatorPrecedence,
@@ -306,7 +306,7 @@ impl CoreLanguageRepresentationFunction {
pub fn linear_lines(
&self,
il: &HighLevelILFunction,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
settings: &DisassemblySettings,
as_full_ast: bool,
) -> Array<DisassemblyTextLine> {
diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs
index bc8e579e..0db23c82 100644
--- a/rust/src/low_level_il/operation.rs
+++ b/rust/src/low_level_il/operation.rs
@@ -86,7 +86,7 @@ where
self.op.operands[operand_idx] as usize,
)
};
- PossibleValueSet::from_owned_raw(raw_pvs)
+ PossibleValueSet::from_owned_core_raw(raw_pvs)
}
}
diff --git a/rust/src/medium_level_il/block.rs b/rust/src/medium_level_il/block.rs
index 1fcd51ca..162b19b0 100644
--- a/rust/src/medium_level_il/block.rs
+++ b/rust/src/medium_level_il/block.rs
@@ -14,8 +14,6 @@ impl BlockContext for MediumLevelILBlock {
type Iter = MediumLevelILBlockIter;
fn start(&self, block: &BasicBlock<Self>) -> MediumLevelILInstruction {
- // TODO: instruction_from_index says that it is not mapped and will do the call
- // TODO: What if this IS already MAPPED!?!?!?
self.function
.instruction_from_index(block.start_index())
.unwrap()
diff --git a/rust/src/medium_level_il/function.rs b/rust/src/medium_level_il/function.rs
index bdbe3159..8751111b 100644
--- a/rust/src/medium_level_il/function.rs
+++ b/rust/src/medium_level_il/function.rs
@@ -2,7 +2,10 @@ use binaryninjacore_sys::*;
use std::fmt::{Debug, Formatter};
use std::hash::{Hash, Hasher};
-use super::{MediumLevelILBlock, MediumLevelILInstruction, MediumLevelInstructionIndex};
+use super::{
+ MediumLevelExpressionIndex, MediumLevelILBlock, MediumLevelILInstruction,
+ MediumLevelInstructionIndex,
+};
use crate::architecture::CoreArchitecture;
use crate::basic_block::BasicBlock;
use crate::confidence::Conf;
@@ -33,7 +36,7 @@ impl MediumLevelILFunction {
}
pub fn instruction_at<L: Into<Location>>(&self, loc: L) -> Option<MediumLevelILInstruction> {
- Some(MediumLevelILInstruction::new(
+ Some(MediumLevelILInstruction::from_instr_index(
self.to_owned(),
self.instruction_index_at(loc)?,
))
@@ -64,18 +67,21 @@ impl MediumLevelILFunction {
if index.0 >= self.instruction_count() {
None
} else {
- Some(MediumLevelILInstruction::new(self.to_owned(), index))
+ Some(MediumLevelILInstruction::from_instr_index(
+ self.to_owned(),
+ index,
+ ))
}
}
pub fn instruction_from_expr_index(
&self,
- expr_index: MediumLevelInstructionIndex,
+ expr_index: MediumLevelExpressionIndex,
) -> Option<MediumLevelILInstruction> {
if expr_index.0 >= self.expression_count() {
None
} else {
- Some(MediumLevelILInstruction::new_expr(
+ Some(MediumLevelILInstruction::from_expr_index(
self.to_owned(),
expr_index,
))
@@ -402,7 +408,7 @@ impl MediumLevelILFunction {
unsafe { BNMediumLevelILSetCurrentAddress(self.handle, arch, location.addr) }
}
- /// Returns the [`BasicBlock`] at the given instruction `index`.
+ /// Returns the [`BasicBlock`] at the given instruction `index`. Function must be finalized.
///
/// You can also retrieve this using [`MediumLevelILInstruction::basic_block`].
pub fn basic_block_containing_index(
diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs
index 70d69b7f..3af9e424 100644
--- a/rust/src/medium_level_il/instruction.rs
+++ b/rust/src/medium_level_il/instruction.rs
@@ -41,30 +41,76 @@ impl Display for MediumLevelInstructionIndex {
}
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct MediumLevelExpressionIndex(pub usize);
+
+impl MediumLevelExpressionIndex {
+ pub fn next(&self) -> Self {
+ Self(self.0 + 1)
+ }
+}
+
+impl From<usize> for MediumLevelExpressionIndex {
+ fn from(index: usize) -> Self {
+ Self(index)
+ }
+}
+
+impl From<u64> for MediumLevelExpressionIndex {
+ fn from(index: u64) -> Self {
+ Self(index as usize)
+ }
+}
+
+impl Display for MediumLevelExpressionIndex {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.write_fmt(format_args!("{}", self.0))
+ }
+}
+
#[derive(Clone)]
pub struct MediumLevelILInstruction {
pub function: Ref<MediumLevelILFunction>,
pub address: u64,
- // TODO; Because this structure is incorrectly named instruction, we want to make it clear that we actually have the expression index.
- pub expr_index: MediumLevelInstructionIndex,
+ pub instr_index: MediumLevelInstructionIndex,
+ pub expr_index: MediumLevelExpressionIndex,
pub size: usize,
pub kind: MediumLevelILInstructionKind,
}
impl MediumLevelILInstruction {
- pub(crate) fn new(
+ pub(crate) fn from_instr_index(
function: Ref<MediumLevelILFunction>,
- index: MediumLevelInstructionIndex,
+ instr_index: MediumLevelInstructionIndex,
) -> Self {
- // TODO: If op.sourceOperation == BN_INVALID_OPERAND && op.operation == MLIL_NOP return None
- let expr_index = unsafe { BNGetMediumLevelILIndexForInstruction(function.handle, index.0) };
- Self::new_expr(function, MediumLevelInstructionIndex(expr_index))
+ // Get the associated expression index for the top-level instruction.
+ let expr_index_raw =
+ unsafe { BNGetMediumLevelILIndexForInstruction(function.handle, instr_index.0) };
+ Self::new(
+ function,
+ instr_index,
+ MediumLevelExpressionIndex(expr_index_raw),
+ )
+ }
+
+ pub(crate) fn from_expr_index(
+ function: Ref<MediumLevelILFunction>,
+ expr_index: MediumLevelExpressionIndex,
+ ) -> Self {
+ // Get the associated top-level instruction index for the expression.
+ let instr_index_raw =
+ unsafe { BNGetMediumLevelILInstructionForExpr(function.handle, expr_index.0) };
+ Self::new(
+ function,
+ MediumLevelInstructionIndex(instr_index_raw),
+ expr_index,
+ )
}
- // TODO: I need MediumLevelILExpression YESTERDAY!!!!
- pub(crate) fn new_expr(
+ pub(crate) fn new(
function: Ref<MediumLevelILFunction>,
- expr_index: MediumLevelInstructionIndex,
+ instr_index: MediumLevelInstructionIndex,
+ expr_index: MediumLevelExpressionIndex,
) -> Self {
// TODO: If op.sourceOperation == BN_INVALID_OPERAND && op.operation == MLIL_NOP return None
let op = unsafe { BNGetMediumLevelILByIndex(function.handle, expr_index.0) };
@@ -78,7 +124,7 @@ impl MediumLevelILInstruction {
MLIL_ASSERT | MLIL_ASSERT_SSA | MLIL_FORCE_VER | MLIL_FORCE_VER_SSA => Op::Undef,
MLIL_UNIMPL => Op::Unimpl,
MLIL_IF => Op::If(MediumLevelILOperationIf {
- condition: op.operands[0] as usize,
+ condition: MediumLevelExpressionIndex::from(op.operands[0]),
dest_true: MediumLevelInstructionIndex(op.operands[1] as usize),
dest_false: MediumLevelInstructionIndex(op.operands[2] as usize),
}),
@@ -104,35 +150,35 @@ impl MediumLevelILInstruction {
size: op.size,
}),
MLIL_JUMP => Op::Jump(Jump {
- dest: op.operands[0] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
}),
MLIL_RET_HINT => Op::RetHint(Jump {
- dest: op.operands[0] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
}),
MLIL_STORE_SSA => Op::StoreSsa(StoreSsa {
- dest: op.operands[0] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
dest_memory: op.operands[1],
src_memory: op.operands[2],
- src: op.operands[3] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[3]),
}),
MLIL_STORE_STRUCT_SSA => Op::StoreStructSsa(StoreStructSsa {
- dest: op.operands[0] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
offset: op.operands[1],
dest_memory: op.operands[2],
src_memory: op.operands[3],
- src: op.operands[4] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[4]),
}),
MLIL_STORE_STRUCT => Op::StoreStruct(StoreStruct {
- dest: op.operands[0] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
offset: op.operands[1],
- src: op.operands[2] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_STORE => Op::Store(Store {
- dest: op.operands[0] as usize,
- src: op.operands[1] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
+ src: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_JUMP_TO => Op::JumpTo(JumpTo {
- dest: op.operands[0] as usize,
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
num_operands: op.operands[1] as usize,
first_operand: op.operands[2] as usize,
}),
@@ -145,11 +191,11 @@ impl MediumLevelILInstruction {
MLIL_SET_VAR_FIELD => Op::SetVarField(SetVarField {
dest: get_var(op.operands[0]),
offset: op.operands[1],
- src: op.operands[2] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_SET_VAR => Op::SetVar(SetVar {
dest: get_var(op.operands[0]),
- src: op.operands[1] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FREE_VAR_SLOT_SSA => Op::FreeVarSlotSsa(FreeVarSlotSsa {
dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
@@ -159,22 +205,22 @@ impl MediumLevelILInstruction {
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,
+ src: MediumLevelExpressionIndex::from(op.operands[4]),
}),
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,
+ src: MediumLevelExpressionIndex::from(op.operands[4]),
}),
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,
+ src: MediumLevelExpressionIndex::from(op.operands[3]),
}),
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,
+ src: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_VAR_PHI => Op::VarPhi(VarPhi {
dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
@@ -193,7 +239,7 @@ impl MediumLevelILInstruction {
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,
+ src: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_VAR_SPLIT_SSA => Op::VarSplitSsa(VarSplitSsa {
high: get_var_ssa(op.operands[0], op.operands[1] as usize),
@@ -202,212 +248,212 @@ impl MediumLevelILInstruction {
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,
+ src: MediumLevelExpressionIndex::from(op.operands[4]),
}),
MLIL_ADD => Op::Add(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_SUB => Op::Sub(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_AND => Op::And(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_OR => Op::Or(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_XOR => Op::Xor(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_LSL => Op::Lsl(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_LSR => Op::Lsr(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_ASR => Op::Asr(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_ROL => Op::Rol(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_ROR => Op::Ror(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MUL => Op::Mul(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MULU_DP => Op::MuluDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MULS_DP => Op::MulsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_DIVU => Op::Divu(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_DIVU_DP => Op::DivuDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_DIVS => Op::Divs(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_DIVS_DP => Op::DivsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MODU => Op::Modu(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MODU_DP => Op::ModuDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MODS => Op::Mods(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_MODS_DP => Op::ModsDp(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_E => Op::CmpE(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_NE => Op::CmpNe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_SLT => Op::CmpSlt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_ULT => Op::CmpUlt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_SLE => Op::CmpSle(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_ULE => Op::CmpUle(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_SGE => Op::CmpSge(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_UGE => Op::CmpUge(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_SGT => Op::CmpSgt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_CMP_UGT => Op::CmpUgt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_TEST_BIT => Op::TestBit(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_E => Op::FcmpE(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_NE => Op::FcmpNe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_LT => Op::FcmpLt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_LE => Op::FcmpLe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_GE => Op::FcmpGe(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_GT => Op::FcmpGt(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_O => Op::FcmpO(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FCMP_UO => Op::FcmpUo(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FADD => Op::Fadd(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FSUB => Op::Fsub(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FMUL => Op::Fmul(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_FDIV => Op::Fdiv(BinaryOp {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
}),
MLIL_ADC => Op::Adc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
+ carry: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_SBB => Op::Sbb(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
+ carry: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_RLC => Op::Rlc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
+ carry: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_RRC => Op::Rrc(BinaryOpCarry {
- left: op.operands[0] as usize,
- right: op.operands[1] as usize,
- carry: op.operands[2] as usize,
+ left: MediumLevelExpressionIndex::from(op.operands[0]),
+ right: MediumLevelExpressionIndex::from(op.operands[1]),
+ carry: MediumLevelExpressionIndex::from(op.operands[2]),
}),
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,
+ dest: MediumLevelExpressionIndex::from(op.operands[2]),
num_params: op.operands[3] as usize,
first_param: op.operands[4] as usize,
}),
@@ -432,7 +478,7 @@ impl MediumLevelILInstruction {
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,
+ dest: MediumLevelExpressionIndex::from(op.operands[2]),
num_params: op.operands[3] as usize,
first_param: op.operands[4] as usize,
}),
@@ -457,7 +503,7 @@ impl MediumLevelILInstruction {
first_param: op.operands[4] as usize,
}),
MLIL_MEMORY_INTRINSIC_SSA => Op::MemoryIntrinsicSsa(MemoryIntrinsicSsa {
- output: op.operands[0] as usize,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
intrinsic: op.operands[1] as u32,
num_params: op.operands[2] as usize,
first_param: op.operands[3] as usize,
@@ -471,124 +517,124 @@ impl MediumLevelILInstruction {
})
}
MLIL_CALL_SSA => Op::CallSsa(CallSsa {
- output: op.operands[0] as usize,
- dest: op.operands[1] as usize,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ dest: MediumLevelExpressionIndex::from(op.operands[1]),
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,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ dest: MediumLevelExpressionIndex::from(op.operands[1]),
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,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ dest: MediumLevelExpressionIndex::from(op.operands[1]),
+ params: MediumLevelExpressionIndex::from(op.operands[2]),
+ stack: MediumLevelExpressionIndex::from(op.operands[3]),
}),
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,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ dest: MediumLevelExpressionIndex::from(op.operands[1]),
+ params: MediumLevelExpressionIndex::from(op.operands[2]),
+ stack: MediumLevelExpressionIndex::from(op.operands[3]),
}),
MLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa {
- output: op.operands[0] as usize,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
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,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ params: MediumLevelExpressionIndex::from(op.operands[1]),
+ stack: MediumLevelExpressionIndex::from(op.operands[2]),
}),
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,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ dest: MediumLevelExpressionIndex::from(op.operands[1]),
+ params: MediumLevelExpressionIndex::from(op.operands[2]),
+ stack: MediumLevelExpressionIndex::from(op.operands[3]),
}),
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,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ dest: MediumLevelExpressionIndex::from(op.operands[1]),
+ params: MediumLevelExpressionIndex::from(op.operands[2]),
+ stack: MediumLevelExpressionIndex::from(op.operands[3]),
}),
MLIL_SYSCALL_UNTYPED => Op::SyscallUntyped(SyscallUntyped {
- output: op.operands[0] as usize,
- params: op.operands[1] as usize,
- stack: op.operands[2] as usize,
+ output: MediumLevelExpressionIndex::from(op.operands[0]),
+ params: MediumLevelExpressionIndex::from(op.operands[1]),
+ stack: MediumLevelExpressionIndex::from(op.operands[2]),
}),
MLIL_NEG => Op::Neg(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_NOT => Op::Not(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_SX => Op::Sx(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_ZX => Op::Zx(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_LOW_PART => Op::LowPart(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FSQRT => Op::Fsqrt(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FNEG => Op::Fneg(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FABS => Op::Fabs(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FLOAT_CONV => Op::FloatConv(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FLOOR => Op::Floor(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_CEIL => Op::Ceil(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_FTRUNC => Op::Ftrunc(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_LOAD => Op::Load(UnaryOp {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
MLIL_LOAD_STRUCT => Op::LoadStruct(LoadStruct {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
offset: op.operands[1],
}),
MLIL_LOAD_STRUCT_SSA => Op::LoadStructSsa(LoadStructSsa {
- src: op.operands[0] as usize,
+ src: MediumLevelExpressionIndex::from(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: MediumLevelExpressionIndex::from(op.operands[0]),
src_memory: op.operands[1],
}),
MLIL_RET => Op::Ret(Ret {
@@ -639,6 +685,7 @@ impl MediumLevelILInstruction {
Self {
function,
address: op.address,
+ instr_index,
expr_index,
size: op.size,
kind,
@@ -679,7 +726,7 @@ impl MediumLevelILInstruction {
fn get_expr_list(&self, operand_idx: usize) -> Vec<MediumLevelILInstruction> {
self.get_operand_list(operand_idx)
.into_iter()
- .map(|val| MediumLevelInstructionIndex(val as usize))
+ .map(|val| MediumLevelExpressionIndex(val as usize))
.filter_map(|idx| self.function.instruction_from_expr_index(idx))
.collect()
}
@@ -949,49 +996,60 @@ impl MediumLevelILInstruction {
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(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.output),
- )),
- params: self
- .get_expr_list(1)
- .iter()
- .map(|expr| expr.lift())
- .collect(),
- src_memory: op.src_memory,
- }),
- SyscallUntypedSsa(op) => Lifted::SyscallUntypedSsa(LiftedSyscallUntypedSsa {
- output: get_call_output_ssa(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.output),
- )),
- params: get_call_params_ssa(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.params),
- ))
- .iter()
- .map(|param| param.lift())
- .collect(),
- stack: self.lift_operand(op.stack),
- }),
+ SyscallSsa(op) => {
+ let output_instr = self
+ .function
+ .instruction_from_expr_index(op.output)
+ .expect("Valid output expression index");
+ Lifted::SyscallSsa(LiftedSyscallSsa {
+ output: get_call_output_ssa(&output_instr),
+ params: self
+ .get_expr_list(1)
+ .iter()
+ .map(|expr| expr.lift())
+ .collect(),
+ src_memory: op.src_memory,
+ })
+ }
+ SyscallUntypedSsa(op) => {
+ let output_instr = self
+ .function
+ .instruction_from_expr_index(op.output)
+ .expect("Valid output expression index");
+ let params_instr = self
+ .function
+ .instruction_from_expr_index(op.params)
+ .expect("Valid params expression index");
+ Lifted::SyscallUntypedSsa(LiftedSyscallUntypedSsa {
+ output: get_call_output_ssa(&output_instr),
+ params: get_call_params_ssa(&params_instr)
+ .iter()
+ .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(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.output),
- )),
- params: get_call_params(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.params),
- ))
- .iter()
- .map(|param| param.lift())
- .collect(),
- stack: self.lift_operand(op.stack),
- }),
+ SyscallUntyped(op) => {
+ let output_instr = self
+ .function
+ .instruction_from_expr_index(op.output)
+ .expect("Valid output expression index");
+ let params_instr = self
+ .function
+ .instruction_from_expr_index(op.params)
+ .expect("Valid params expression index");
+ Lifted::SyscallUntyped(LiftedSyscallUntyped {
+ output: get_call_output(&output_instr),
+ params: get_call_params(&params_instr)
+ .iter()
+ .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)),
@@ -1060,7 +1118,8 @@ impl MediumLevelILInstruction {
MediumLevelILLiftedInstruction {
function: self.function.clone(),
address: self.address,
- index: self.expr_index,
+ instr_index: self.instr_index,
+ expr_index: self.expr_index,
size: self.size,
kind,
}
@@ -1090,7 +1149,7 @@ impl MediumLevelILInstruction {
/// Returns the [`BasicBlock`] containing the given [`MediumLevelILInstruction`].
pub fn basic_block(&self) -> Option<Ref<BasicBlock<MediumLevelILBlock>>> {
// TODO: We might be able to .expect this if we guarantee that self.index is valid.
- self.function.basic_block_containing_index(self.expr_index)
+ self.function.basic_block_containing_index(self.instr_index)
}
/// Possible values of expression using path-sensitive static data flow analysis
@@ -1494,17 +1553,14 @@ impl MediumLevelILInstruction {
Variable::new(var.ty, index, var.storage)
}
- fn lift_operand(&self, expr_idx: usize) -> Box<MediumLevelILLiftedInstruction> {
- // TODO: UGH, if your gonna call it expr_idx, call the instruction and expression!!!!!
- // TODO: We dont even need to say instruction in the type!
- // TODO: IF you want to have an instruction type, there needs to be a separate expression type
- // TODO: See the lowlevelil module.
- let expr_idx_is_really_instr_idx = MediumLevelInstructionIndex(expr_idx);
- // TODO: See the comment in the unchecked function, ugh, i hate this..
+ fn lift_operand(
+ &self,
+ expr_idx: MediumLevelExpressionIndex,
+ ) -> Box<MediumLevelILLiftedInstruction> {
let operand_instr = self
.function
- .instruction_from_expr_index(expr_idx_is_really_instr_idx)
- .unwrap();
+ .instruction_from_expr_index(expr_idx)
+ .expect("Invalid operand expression index");
Box::new(operand_instr.lift())
}
@@ -1542,29 +1598,32 @@ impl MediumLevelILInstruction {
}
fn lift_call_untyped(&self, op: CallUntyped) -> LiftedCallUntyped {
+ let output_instr = self
+ .function
+ .instruction_from_expr_index(op.output)
+ .expect("Valid output expression index");
+ let params_instr = self
+ .function
+ .instruction_from_expr_index(op.params)
+ .expect("Valid params expression index");
LiftedCallUntyped {
- output: get_call_output(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.output),
- )),
+ output: get_call_output(&output_instr),
dest: self.lift_operand(op.dest),
- params: get_call_params(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.params),
- ))
- .iter()
- .map(|expr| expr.lift())
- .collect(),
+ params: get_call_params(&params_instr)
+ .iter()
+ .map(|expr| expr.lift())
+ .collect(),
stack: self.lift_operand(op.stack),
}
}
fn lift_call_ssa(&self, op: CallSsa) -> LiftedCallSsa {
+ let output_instr = self
+ .function
+ .instruction_from_expr_index(op.output)
+ .expect("Valid output expression index");
LiftedCallSsa {
- output: get_call_output_ssa(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.output),
- )),
+ output: get_call_output_ssa(&output_instr),
dest: self.lift_operand(op.dest),
params: self
.get_expr_list(2)
@@ -1576,19 +1635,21 @@ impl MediumLevelILInstruction {
}
fn lift_call_untyped_ssa(&self, op: CallUntypedSsa) -> LiftedCallUntypedSsa {
+ let output_instr = self
+ .function
+ .instruction_from_expr_index(op.output)
+ .expect("Valid output expression index");
+ let params_instr = self
+ .function
+ .instruction_from_expr_index(op.params)
+ .expect("Valid params expression index");
LiftedCallUntypedSsa {
- output: get_call_output_ssa(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.output),
- )),
+ output: get_call_output_ssa(&output_instr),
dest: self.lift_operand(op.dest),
- params: get_call_params_ssa(&MediumLevelILInstruction::new(
- self.function.clone(),
- MediumLevelInstructionIndex(op.params),
- ))
- .iter()
- .map(|param| param.lift())
- .collect(),
+ params: get_call_params_ssa(&params_instr)
+ .iter()
+ .map(|param| param.lift())
+ .collect(),
stack: self.lift_operand(op.stack),
}
}
@@ -1598,7 +1659,8 @@ impl Debug for MediumLevelILInstruction {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("MediumLevelILInstruction")
.field("address", &self.address)
- .field("index", &self.expr_index)
+ .field("instr_index", &self.instr_index)
+ .field("expr_index", &self.expr_index)
.field("size", &self.size)
.field("kind", &self.kind)
.finish()
@@ -1617,8 +1679,6 @@ unsafe impl CoreArrayProviderInner for MediumLevelILInstruction {
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
- // TODO: This needs to be tested!!!!
- // TODO: What if this does not need to be mapped!!!!
context
.instruction_from_index(MediumLevelInstructionIndex(*raw))
.unwrap()
@@ -1832,9 +1892,9 @@ unsafe impl CoreArrayProviderInner for BranchDependence {
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
Self {
- instruction: MediumLevelILInstruction::new(
+ instruction: MediumLevelILInstruction::from_expr_index(
context.clone(),
- MediumLevelInstructionIndex(raw.branch),
+ MediumLevelExpressionIndex(raw.branch),
),
dependence: raw.dependence,
}
diff --git a/rust/src/medium_level_il/lift.rs b/rust/src/medium_level_il/lift.rs
index 399bda78..e563f26d 100644
--- a/rust/src/medium_level_il/lift.rs
+++ b/rust/src/medium_level_il/lift.rs
@@ -1,5 +1,5 @@
use super::operation::*;
-use super::{MediumLevelILFunction, MediumLevelInstructionIndex};
+use super::{MediumLevelExpressionIndex, MediumLevelILFunction, MediumLevelInstructionIndex};
use crate::architecture::CoreIntrinsic;
use crate::rc::Ref;
use crate::variable::{ConstantData, SSAVariable, Variable};
@@ -27,7 +27,8 @@ pub enum MediumLevelILLiftedOperand {
pub struct MediumLevelILLiftedInstruction {
pub function: Ref<MediumLevelILFunction>,
pub address: u64,
- pub index: MediumLevelInstructionIndex,
+ pub instr_index: MediumLevelInstructionIndex,
+ pub expr_index: MediumLevelExpressionIndex,
pub size: usize,
pub kind: MediumLevelILLiftedInstructionKind,
}
@@ -36,7 +37,8 @@ impl Debug for MediumLevelILLiftedInstruction {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MediumLevelILLiftedInstruction")
.field("address", &self.address)
- .field("index", &self.index)
+ .field("instr_index", &self.instr_index)
+ .field("expr_index", &self.expr_index)
.field("size", &self.size)
.field("kind", &self.kind)
.finish()
diff --git a/rust/src/medium_level_il/operation.rs b/rust/src/medium_level_il/operation.rs
index e8b70cc6..578087d0 100644
--- a/rust/src/medium_level_il/operation.rs
+++ b/rust/src/medium_level_il/operation.rs
@@ -1,4 +1,6 @@
-use super::{MediumLevelILLiftedInstruction, MediumLevelInstructionIndex};
+use super::{
+ MediumLevelExpressionIndex, MediumLevelILLiftedInstruction, MediumLevelInstructionIndex,
+};
use crate::architecture::CoreIntrinsic;
use crate::variable::{ConstantData, SSAVariable, Variable};
use std::collections::BTreeMap;
@@ -6,7 +8,7 @@ use std::collections::BTreeMap;
// IF
#[derive(Debug, Copy, Clone)]
pub struct MediumLevelILOperationIf {
- pub condition: usize,
+ pub condition: MediumLevelExpressionIndex,
pub dest_true: MediumLevelInstructionIndex,
pub dest_false: MediumLevelInstructionIndex,
}
@@ -51,7 +53,7 @@ pub struct LiftedConstData {
// JUMP, RET_HINT
#[derive(Debug, Copy, Clone)]
pub struct Jump {
- pub dest: usize,
+ pub dest: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedJump {
@@ -61,10 +63,10 @@ pub struct LiftedJump {
// STORE_SSA
#[derive(Debug, Copy, Clone)]
pub struct StoreSsa {
- pub dest: usize,
+ pub dest: MediumLevelExpressionIndex,
pub dest_memory: u64,
pub src_memory: u64,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStoreSsa {
@@ -77,11 +79,11 @@ pub struct LiftedStoreSsa {
// STORE_STRUCT_SSA
#[derive(Debug, Copy, Clone)]
pub struct StoreStructSsa {
- pub dest: usize,
+ pub dest: MediumLevelExpressionIndex,
pub offset: u64,
pub dest_memory: u64,
pub src_memory: u64,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStoreStructSsa {
@@ -95,9 +97,9 @@ pub struct LiftedStoreStructSsa {
// STORE_STRUCT
#[derive(Debug, Copy, Clone)]
pub struct StoreStruct {
- pub dest: usize,
+ pub dest: MediumLevelExpressionIndex,
pub offset: u64,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStoreStruct {
@@ -109,8 +111,8 @@ pub struct LiftedStoreStruct {
// STORE
#[derive(Debug, Copy, Clone)]
pub struct Store {
- pub dest: usize,
- pub src: usize,
+ pub dest: MediumLevelExpressionIndex,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedStore {
@@ -121,7 +123,7 @@ pub struct LiftedStore {
// JUMP_TO
#[derive(Debug, Copy, Clone)]
pub struct JumpTo {
- pub dest: usize,
+ pub dest: MediumLevelExpressionIndex,
pub first_operand: usize,
pub num_operands: usize,
}
@@ -148,7 +150,7 @@ pub struct FreeVarSlot {
pub struct SetVarField {
pub dest: Variable,
pub offset: u64,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarField {
@@ -161,8 +163,7 @@ pub struct LiftedSetVarField {
#[derive(Debug, Copy, Clone)]
pub struct SetVar {
pub dest: Variable,
- // TODO: Expression?
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVar {
@@ -183,7 +184,7 @@ pub struct SetVarSsaField {
pub dest: SSAVariable,
pub prev: SSAVariable,
pub offset: u64,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSsaField {
@@ -198,7 +199,7 @@ pub struct LiftedSetVarSsaField {
pub struct SetVarAliased {
pub dest: SSAVariable,
pub prev: SSAVariable,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarAliased {
@@ -211,7 +212,7 @@ pub struct LiftedSetVarAliased {
#[derive(Debug, Copy, Clone)]
pub struct SetVarSsa {
pub dest: SSAVariable,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSsa {
@@ -257,7 +258,7 @@ pub struct VarSplit {
pub struct SetVarSplit {
pub high: Variable,
pub low: Variable,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSplit {
@@ -278,7 +279,7 @@ pub struct VarSplitSsa {
pub struct SetVarSplitSsa {
pub high: SSAVariable,
pub low: SSAVariable,
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSetVarSplitSsa {
@@ -290,8 +291,8 @@ pub struct LiftedSetVarSplitSsa {
// 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(Debug, Copy, Clone)]
pub struct BinaryOp {
- pub left: usize,
- pub right: usize,
+ pub left: MediumLevelExpressionIndex,
+ pub right: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedBinaryOp {
@@ -302,9 +303,9 @@ pub struct LiftedBinaryOp {
// ADC, SBB, RLC, RRC
#[derive(Debug, Copy, Clone)]
pub struct BinaryOpCarry {
- pub left: usize,
- pub right: usize,
- pub carry: usize,
+ pub left: MediumLevelExpressionIndex,
+ pub right: MediumLevelExpressionIndex,
+ pub carry: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedBinaryOpCarry {
@@ -318,7 +319,7 @@ pub struct LiftedBinaryOpCarry {
pub struct Call {
pub first_output: usize,
pub num_outputs: usize,
- pub dest: usize,
+ pub dest: MediumLevelExpressionIndex,
pub first_param: usize,
pub num_params: usize,
}
@@ -426,7 +427,7 @@ pub struct LiftedIntrinsicSsa {
// MEMORY_INTRINSIC_SSA
#[derive(Debug, Copy, Clone)]
pub struct MemoryIntrinsicSsa {
- pub output: usize,
+ pub output: MediumLevelExpressionIndex,
pub intrinsic: u32,
pub first_param: usize,
pub num_params: usize,
@@ -456,8 +457,8 @@ pub struct LiftedMemoryIntrinsicOutputSsa {
// CALL_SSA, TAILCALL_SSA
#[derive(Debug, Copy, Clone)]
pub struct CallSsa {
- pub output: usize,
- pub dest: usize,
+ pub output: MediumLevelExpressionIndex,
+ pub dest: MediumLevelExpressionIndex,
pub first_param: usize,
pub num_params: usize,
pub src_memory: u64,
@@ -473,10 +474,10 @@ pub struct LiftedCallSsa {
// CALL_UNTYPED_SSA, TAILCALL_UNTYPED_SSA
#[derive(Debug, Copy, Clone)]
pub struct CallUntypedSsa {
- pub output: usize,
- pub dest: usize,
- pub params: usize,
- pub stack: usize,
+ pub output: MediumLevelExpressionIndex,
+ pub dest: MediumLevelExpressionIndex,
+ pub params: MediumLevelExpressionIndex,
+ pub stack: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCallUntypedSsa {
@@ -489,7 +490,7 @@ pub struct LiftedCallUntypedSsa {
// SYSCALL_SSA
#[derive(Debug, Copy, Clone)]
pub struct SyscallSsa {
- pub output: usize,
+ pub output: MediumLevelExpressionIndex,
pub first_param: usize,
pub num_params: usize,
pub src_memory: u64,
@@ -504,9 +505,9 @@ pub struct LiftedSyscallSsa {
// SYSCALL_UNTYPED_SSA
#[derive(Debug, Copy, Clone)]
pub struct SyscallUntypedSsa {
- pub output: usize,
- pub params: usize,
- pub stack: usize,
+ pub output: MediumLevelExpressionIndex,
+ pub params: MediumLevelExpressionIndex,
+ pub stack: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSyscallUntypedSsa {
@@ -518,10 +519,10 @@ pub struct LiftedSyscallUntypedSsa {
// CALL_UNTYPED, TAILCALL_UNTYPED
#[derive(Debug, Copy, Clone)]
pub struct CallUntyped {
- pub output: usize,
- pub dest: usize,
- pub params: usize,
- pub stack: usize,
+ pub output: MediumLevelExpressionIndex,
+ pub dest: MediumLevelExpressionIndex,
+ pub params: MediumLevelExpressionIndex,
+ pub stack: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedCallUntyped {
@@ -534,9 +535,9 @@ pub struct LiftedCallUntyped {
// SYSCALL_UNTYPED
#[derive(Debug, Copy, Clone)]
pub struct SyscallUntyped {
- pub output: usize,
- pub params: usize,
- pub stack: usize,
+ pub output: MediumLevelExpressionIndex,
+ pub params: MediumLevelExpressionIndex,
+ pub stack: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedSyscallUntyped {
@@ -548,7 +549,7 @@ pub struct LiftedSyscallUntyped {
// 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(Debug, Copy, Clone)]
pub struct UnaryOp {
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
}
#[derive(Clone, Debug, PartialEq)]
pub struct LiftedUnaryOp {
@@ -558,7 +559,7 @@ pub struct LiftedUnaryOp {
// LOAD_STRUCT
#[derive(Debug, Copy, Clone)]
pub struct LoadStruct {
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
pub offset: u64,
}
#[derive(Clone, Debug, PartialEq)]
@@ -570,7 +571,7 @@ pub struct LiftedLoadStruct {
// LOAD_STRUCT_SSA
#[derive(Debug, Copy, Clone)]
pub struct LoadStructSsa {
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
pub offset: u64,
pub src_memory: u64,
}
@@ -584,7 +585,7 @@ pub struct LiftedLoadStructSsa {
// LOAD_SSA
#[derive(Debug, Copy, Clone)]
pub struct LoadSsa {
- pub src: usize,
+ pub src: MediumLevelExpressionIndex,
pub src_memory: u64,
}
#[derive(Clone, Debug, PartialEq)]
diff --git a/rust/tests/high_level_il.rs b/rust/tests/high_level_il.rs
index 4466678c..e757301e 100644
--- a/rust/tests/high_level_il.rs
+++ b/rust/tests/high_level_il.rs
@@ -1,6 +1,8 @@
use binaryninja::binary_view::BinaryViewExt;
use binaryninja::headless::Session;
-use binaryninja::high_level_il::{HighLevelILInstructionKind, HighLevelInstructionIndex};
+use binaryninja::high_level_il::{
+ HighLevelExpressionIndex, HighLevelILInstructionKind, HighLevelInstructionIndex,
+};
use std::path::PathBuf;
#[test]
@@ -23,7 +25,8 @@ fn test_hlil_info() {
// 00025f22 HLIL_CALL (HLIL_CONST_PTR.d __crt_interlocked_read_32)((HLIL_VAR.d arg1))))
// 00025f10 )
let instr_0 = hlil_instr_iter.next().unwrap();
- assert_eq!(instr_0.expr_index, HighLevelInstructionIndex(5));
+ assert_eq!(instr_0.instr_index, HighLevelInstructionIndex(0));
+ assert_eq!(instr_0.expr_index, HighLevelExpressionIndex(5));
assert_eq!(instr_0.address, image_base + 0x00025f22);
println!("{:?}", instr_0.kind);
match instr_0.kind {
diff --git a/rust/tests/language_representation.rs b/rust/tests/language_representation.rs
index c3d60966..f4aeb7bd 100644
--- a/rust/tests/language_representation.rs
+++ b/rust/tests/language_representation.rs
@@ -8,7 +8,7 @@ use binaryninja::disassembly::{
use binaryninja::function::Function;
use binaryninja::headless::Session;
use binaryninja::high_level_il::token_emitter::HighLevelILTokenEmitter;
-use binaryninja::high_level_il::{HighLevelILFunction, HighLevelInstructionIndex};
+use binaryninja::high_level_il::{HighLevelExpressionIndex, HighLevelILFunction};
use binaryninja::language_representation::{
register_language_representation_function_type, CoreLanguageRepresentationFunction,
CoreLanguageRepresentationFunctionType, LanguageRepresentationFunction,
@@ -60,7 +60,7 @@ impl LanguageRepresentationFunction for MyLangRepr {
fn expr_text(
&self,
il: &HighLevelILFunction,
- expr_index: HighLevelInstructionIndex,
+ expr_index: HighLevelExpressionIndex,
tokens: &HighLevelILTokenEmitter,
_settings: &DisassemblySettings,
_as_full_ast: bool,
@@ -101,7 +101,7 @@ impl LanguageRepresentationFunction for MyLangRepr {
fn begin_lines(
&self,
_il: &HighLevelILFunction,
- _expr_index: HighLevelInstructionIndex,
+ _expr_index: HighLevelExpressionIndex,
_tokens: &HighLevelILTokenEmitter,
) {
}
@@ -109,7 +109,7 @@ impl LanguageRepresentationFunction for MyLangRepr {
fn end_lines(
&self,
_il: &HighLevelILFunction,
- _expr_index: HighLevelInstructionIndex,
+ _expr_index: HighLevelExpressionIndex,
_tokens: &HighLevelILTokenEmitter,
) {
}
@@ -149,7 +149,7 @@ fn test_custom_language_representation() {
let il = func.high_level_il(false).unwrap();
let settings = DisassemblySettings::new();
- let root_idx = il.root_instruction_index();
+ let root_idx = il.root_expression_index();
let result = _repr.linear_lines(&il, root_idx, &settings, false);
let output: String = result.iter().map(|dis| dis.to_string()).collect();
assert_eq!(
diff --git a/rust/tests/medium_level_il.rs b/rust/tests/medium_level_il.rs
index b8c1c108..7d4d8af1 100644
--- a/rust/tests/medium_level_il.rs
+++ b/rust/tests/medium_level_il.rs
@@ -1,7 +1,8 @@
use binaryninja::binary_view::BinaryViewExt;
use binaryninja::headless::Session;
use binaryninja::medium_level_il::{
- MediumLevelILInstructionKind, MediumLevelILLiftedInstructionKind, MediumLevelInstructionIndex,
+ MediumLevelExpressionIndex, MediumLevelILInstructionKind, MediumLevelILLiftedInstructionKind,
+ MediumLevelInstructionIndex,
};
use std::path::PathBuf;
@@ -21,50 +22,54 @@ fn test_mlil_info() {
// 0 @ 00025f10 (MLIL_SET_VAR.d edi_1 = (MLIL_VAR.d edi))
let instr_0 = mlil_instr_iter.next().unwrap();
- assert_eq!(instr_0.expr_index, MediumLevelInstructionIndex(1));
+ assert_eq!(instr_0.instr_index, MediumLevelInstructionIndex(0));
+ assert_eq!(instr_0.expr_index, MediumLevelExpressionIndex(1));
assert_eq!(instr_0.address, image_base + 0x00025f10);
println!("{:?}", instr_0.kind);
match instr_0.kind {
MediumLevelILInstructionKind::SetVar(op) => {
assert_eq!(op.dest.index, 524288);
- assert_eq!(op.src, 0);
+ assert_eq!(op.src, MediumLevelExpressionIndex(0));
}
_ => panic!("Expected SetVar"),
}
// 1 @ 00025f15 (MLIL_SET_VAR.d eax = (MLIL_VAR.d arg1))
let instr_1 = mlil_instr_iter.next().unwrap();
- assert_eq!(instr_1.expr_index, MediumLevelInstructionIndex(3));
+ assert_eq!(instr_1.instr_index, MediumLevelInstructionIndex(1));
+ assert_eq!(instr_1.expr_index, MediumLevelExpressionIndex(3));
assert_eq!(instr_1.address, image_base + 0x00025f15);
println!("{:?}", instr_1.kind);
match instr_1.kind {
MediumLevelILInstructionKind::SetVar(op) => {
assert_eq!(op.dest.index, 5);
- assert_eq!(op.src, 2);
+ assert_eq!(op.src, MediumLevelExpressionIndex(2));
}
_ => panic!("Expected SetVar"),
}
// 2 @ 00025f18 (MLIL_SET_VAR.d var_8 = (MLIL_VAR.d eax))
let instr_2 = mlil_instr_iter.next().unwrap();
- assert_eq!(instr_2.expr_index, MediumLevelInstructionIndex(5));
+ assert_eq!(instr_2.instr_index, MediumLevelInstructionIndex(2));
+ assert_eq!(instr_2.expr_index, MediumLevelExpressionIndex(5));
assert_eq!(instr_2.address, image_base + 0x00025f18);
println!("{:?}", instr_2.kind);
match instr_2.kind {
MediumLevelILInstructionKind::SetVar(op) => {
assert_eq!(op.dest.index, 8);
- assert_eq!(op.src, 4);
+ assert_eq!(op.src, MediumLevelExpressionIndex(4));
}
_ => panic!("Expected SetVar"),
}
// 3 @ 00025f19 (MLIL_CALL eax_1 = (MLIL_CONST_PTR.d __crt_interlocked_read_32)((MLIL_VAR.d var_8)))
let instr_3 = mlil_instr_iter.next().unwrap();
- assert_eq!(instr_3.expr_index, MediumLevelInstructionIndex(10));
+ assert_eq!(instr_3.instr_index, MediumLevelInstructionIndex(3));
+ assert_eq!(instr_3.expr_index, MediumLevelExpressionIndex(10));
assert_eq!(instr_3.address, image_base + 0x00025f19);
println!("{:?}", instr_3.kind);
match instr_3.kind {
MediumLevelILInstructionKind::Call(op) => {
assert_eq!(op.first_output, 8);
assert_eq!(op.num_outputs, 1);
- assert_eq!(op.dest, 7);
+ assert_eq!(op.dest, MediumLevelExpressionIndex(7));
assert_eq!(op.first_param, 9);
assert_eq!(op.num_params, 1);
}
@@ -72,7 +77,7 @@ fn test_mlil_info() {
}
match instr_3.lift().kind {
MediumLevelILLiftedInstructionKind::Call(lifted_call) => {
- assert_eq!(lifted_call.dest.index, MediumLevelInstructionIndex(7));
+ assert_eq!(lifted_call.dest.expr_index, MediumLevelExpressionIndex(7));
assert_eq!(lifted_call.output.len(), 1);
assert_eq!(lifted_call.params.len(), 1);
}
@@ -80,7 +85,8 @@ fn test_mlil_info() {
}
// 4 @ 00025f22 (MLIL_RET return (MLIL_VAR.d eax_1))
let instr_4 = mlil_instr_iter.next().unwrap();
- assert_eq!(instr_4.expr_index, MediumLevelInstructionIndex(13));
+ assert_eq!(instr_4.instr_index, MediumLevelInstructionIndex(4));
+ assert_eq!(instr_4.expr_index, MediumLevelExpressionIndex(13));
assert_eq!(instr_4.address, image_base + 0x00025f22);
println!("{:?}", instr_4.kind);
match instr_4.kind {
@@ -91,3 +97,23 @@ fn test_mlil_info() {
_ => panic!("Expected Ret"),
}
}
+
+#[test]
+fn test_mlil_basic_blocks() {
+ let _session = Session::new().expect("Failed to initialize session");
+ let out_dir = env!("OUT_DIR").parse::<PathBuf>().unwrap();
+ let view = binaryninja::load(out_dir.join("atox.obj")).expect("Failed to create view");
+
+ // Make sure that all basic blocks are correctly associated with the instruction.
+ for func in &view.functions() {
+ let mlil_function = func.medium_level_il().expect("Failed to get MLIL");
+ for mlil_basic_block in &mlil_function.basic_blocks() {
+ for instr in mlil_basic_block.iter() {
+ let instr_basic_block = instr
+ .basic_block()
+ .expect("Instruction without basic block");
+ assert_eq!(instr_basic_block, mlil_basic_block.to_owned());
+ }
+ }
+ }
+}