summaryrefslogtreecommitdiff
path: root/rust/src/high_level_il/lift.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/high_level_il/lift.rs')
-rw-r--r--rust/src/high_level_il/lift.rs462
1 files changed, 462 insertions, 0 deletions
diff --git a/rust/src/high_level_il/lift.rs b/rust/src/high_level_il/lift.rs
new file mode 100644
index 00000000..0c7c2983
--- /dev/null
+++ b/rust/src/high_level_il/lift.rs
@@ -0,0 +1,462 @@
+use super::operation::*;
+use super::{HighLevelILFunction, HighLevelInstructionIndex};
+
+use crate::architecture::CoreIntrinsic;
+use crate::rc::Ref;
+use crate::variable::{ConstantData, SSAVariable, Variable};
+
+#[derive(Clone)]
+pub enum HighLevelILLiftedOperand {
+ ConstantData(ConstantData),
+ Expr(HighLevelILLiftedInstruction),
+ ExprList(Vec<HighLevelILLiftedInstruction>),
+ Float(f64),
+ Int(u64),
+ IntList(Vec<u64>),
+ Intrinsic(CoreIntrinsic),
+ Label(GotoLabel),
+ MemberIndex(Option<usize>),
+ Var(Variable),
+ VarSsa(SSAVariable),
+ VarSsaList(Vec<SSAVariable>),
+}
+
+// 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.
+#[derive(Clone, Debug, PartialEq)]
+pub struct HighLevelILLiftedInstruction {
+ pub function: Ref<HighLevelILFunction>,
+ pub address: u64,
+ // TODO: Please i need expression
+ pub expr_index: HighLevelInstructionIndex,
+ pub size: usize,
+ pub kind: HighLevelILLiftedInstructionKind,
+}
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum HighLevelILLiftedInstructionKind {
+ Nop,
+ Break,
+ Continue,
+ Noret,
+ Unreachable,
+ Bp,
+ Undef,
+ Unimpl,
+ Adc(LiftedBinaryOpCarry),
+ Sbb(LiftedBinaryOpCarry),
+ Rlc(LiftedBinaryOpCarry),
+ Rrc(LiftedBinaryOpCarry),
+ Add(LiftedBinaryOp),
+ Sub(LiftedBinaryOp),
+ And(LiftedBinaryOp),
+ Or(LiftedBinaryOp),
+ Xor(LiftedBinaryOp),
+ Lsl(LiftedBinaryOp),
+ Lsr(LiftedBinaryOp),
+ Asr(LiftedBinaryOp),
+ Rol(LiftedBinaryOp),
+ Ror(LiftedBinaryOp),
+ Mul(LiftedBinaryOp),
+ MuluDp(LiftedBinaryOp),
+ MulsDp(LiftedBinaryOp),
+ Divu(LiftedBinaryOp),
+ DivuDp(LiftedBinaryOp),
+ Divs(LiftedBinaryOp),
+ DivsDp(LiftedBinaryOp),
+ Modu(LiftedBinaryOp),
+ ModuDp(LiftedBinaryOp),
+ Mods(LiftedBinaryOp),
+ ModsDp(LiftedBinaryOp),
+ CmpE(LiftedBinaryOp),
+ CmpNe(LiftedBinaryOp),
+ CmpSlt(LiftedBinaryOp),
+ CmpUlt(LiftedBinaryOp),
+ CmpSle(LiftedBinaryOp),
+ CmpUle(LiftedBinaryOp),
+ CmpSge(LiftedBinaryOp),
+ CmpUge(LiftedBinaryOp),
+ CmpSgt(LiftedBinaryOp),
+ CmpUgt(LiftedBinaryOp),
+ TestBit(LiftedBinaryOp),
+ AddOverflow(LiftedBinaryOp),
+ Fadd(LiftedBinaryOp),
+ Fsub(LiftedBinaryOp),
+ Fmul(LiftedBinaryOp),
+ Fdiv(LiftedBinaryOp),
+ FcmpE(LiftedBinaryOp),
+ FcmpNe(LiftedBinaryOp),
+ FcmpLt(LiftedBinaryOp),
+ FcmpLe(LiftedBinaryOp),
+ FcmpGe(LiftedBinaryOp),
+ FcmpGt(LiftedBinaryOp),
+ FcmpO(LiftedBinaryOp),
+ FcmpUo(LiftedBinaryOp),
+ ArrayIndex(LiftedArrayIndex),
+ ArrayIndexSsa(LiftedArrayIndexSsa),
+ Assign(LiftedAssign),
+ AssignMemSsa(LiftedAssignMemSsa),
+ AssignUnpack(LiftedAssignUnpack),
+ AssignUnpackMemSsa(LiftedAssignUnpackMemSsa),
+ Block(LiftedBlock),
+ Call(LiftedCall),
+ Tailcall(LiftedCall),
+ CallSsa(LiftedCallSsa),
+ Case(LiftedCase),
+ Const(Const),
+ ConstPtr(Const),
+ Import(Const),
+ ConstData(LiftedConstData),
+ Deref(LiftedUnaryOp),
+ AddressOf(LiftedUnaryOp),
+ Neg(LiftedUnaryOp),
+ Not(LiftedUnaryOp),
+ Sx(LiftedUnaryOp),
+ Zx(LiftedUnaryOp),
+ LowPart(LiftedUnaryOp),
+ BoolToInt(LiftedUnaryOp),
+ UnimplMem(LiftedUnaryOp),
+ Fsqrt(LiftedUnaryOp),
+ Fneg(LiftedUnaryOp),
+ Fabs(LiftedUnaryOp),
+ FloatToInt(LiftedUnaryOp),
+ IntToFloat(LiftedUnaryOp),
+ FloatConv(LiftedUnaryOp),
+ RoundToInt(LiftedUnaryOp),
+ Floor(LiftedUnaryOp),
+ Ceil(LiftedUnaryOp),
+ Ftrunc(LiftedUnaryOp),
+ DerefFieldSsa(LiftedDerefFieldSsa),
+ DerefSsa(LiftedDerefSsa),
+ ExternPtr(ExternPtr),
+ FloatConst(FloatConst),
+ For(LiftedForLoop),
+ ForSsa(LiftedForLoopSsa),
+ Goto(LiftedLabel),
+ Label(LiftedLabel),
+ If(LiftedIf),
+ Intrinsic(LiftedIntrinsic),
+ IntrinsicSsa(LiftedIntrinsicSsa),
+ Jump(LiftedJump),
+ MemPhi(LiftedMemPhi),
+ Ret(LiftedRet),
+ Split(LiftedSplit),
+ StructField(LiftedStructField),
+ DerefField(LiftedStructField),
+ Switch(LiftedSwitch),
+ Syscall(LiftedSyscall),
+ SyscallSsa(LiftedSyscallSsa),
+ Trap(Trap),
+ VarDeclare(Var),
+ Var(Var),
+ VarInit(LiftedVarInit),
+ VarInitSsa(LiftedVarInitSsa),
+ VarPhi(LiftedVarPhi),
+ VarSsa(VarSsa),
+ While(LiftedWhile),
+ DoWhile(LiftedWhile),
+ WhileSsa(LiftedWhileSsa),
+ DoWhileSsa(LiftedWhileSsa),
+}
+
+impl HighLevelILLiftedInstruction {
+ pub fn name(&self) -> &'static str {
+ use HighLevelILLiftedInstructionKind::*;
+ match self.kind {
+ Nop => "Nop",
+ Break => "Break",
+ Continue => "Continue",
+ Noret => "Noret",
+ Unreachable => "Unreachable",
+ Bp => "Bp",
+ Undef => "Undef",
+ Unimpl => "Unimpl",
+ Adc(_) => "Adc",
+ Sbb(_) => "Sbb",
+ Rlc(_) => "Rlc",
+ Rrc(_) => "Rrc",
+ Add(_) => "Add",
+ Sub(_) => "Sub",
+ And(_) => "And",
+ Or(_) => "Or",
+ Xor(_) => "Xor",
+ Lsl(_) => "Lsl",
+ Lsr(_) => "Lsr",
+ Asr(_) => "Asr",
+ Rol(_) => "Rol",
+ Ror(_) => "Ror",
+ Mul(_) => "Mul",
+ MuluDp(_) => "MuluDp",
+ MulsDp(_) => "MulsDp",
+ Divu(_) => "Divu",
+ DivuDp(_) => "DivuDp",
+ Divs(_) => "Divs",
+ DivsDp(_) => "DivsDp",
+ Modu(_) => "Modu",
+ ModuDp(_) => "ModuDp",
+ Mods(_) => "Mods",
+ ModsDp(_) => "ModsDp",
+ CmpE(_) => "CmpE",
+ CmpNe(_) => "CmpNe",
+ CmpSlt(_) => "CmpSlt",
+ CmpUlt(_) => "CmpUlt",
+ CmpSle(_) => "CmpSle",
+ CmpUle(_) => "CmpUle",
+ CmpSge(_) => "CmpSge",
+ CmpUge(_) => "CmpUge",
+ CmpSgt(_) => "CmpSgt",
+ CmpUgt(_) => "CmpUgt",
+ TestBit(_) => "TestBit",
+ AddOverflow(_) => "AddOverflow",
+ Fadd(_) => "Fadd",
+ Fsub(_) => "Fsub",
+ Fmul(_) => "Fmul",
+ Fdiv(_) => "Fdiv",
+ FcmpE(_) => "FcmpE",
+ FcmpNe(_) => "FcmpNe",
+ FcmpLt(_) => "FcmpLt",
+ FcmpLe(_) => "FcmpLe",
+ FcmpGe(_) => "FcmpGe",
+ FcmpGt(_) => "FcmpGt",
+ FcmpO(_) => "FcmpO",
+ FcmpUo(_) => "FcmpUo",
+ ArrayIndex(_) => "ArrayIndex",
+ ArrayIndexSsa(_) => "ArrayIndexSsa",
+ Assign(_) => "Assign",
+ AssignMemSsa(_) => "AssignMemSsa",
+ AssignUnpack(_) => "AssignUnpack",
+ AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
+ Block(_) => "Block",
+ Call(_) => "Call",
+ Tailcall(_) => "Tailcall",
+ CallSsa(_) => "CallSsa",
+ Case(_) => "Case",
+ Const(_) => "Const",
+ ConstPtr(_) => "ConstPtr",
+ Import(_) => "Import",
+ ConstData(_) => "ConstData",
+ Deref(_) => "Deref",
+ AddressOf(_) => "AddressOf",
+ Neg(_) => "Neg",
+ Not(_) => "Not",
+ Sx(_) => "Sx",
+ Zx(_) => "Zx",
+ LowPart(_) => "LowPart",
+ BoolToInt(_) => "BoolToInt",
+ UnimplMem(_) => "UnimplMem",
+ Fsqrt(_) => "Fsqrt",
+ Fneg(_) => "Fneg",
+ Fabs(_) => "Fabs",
+ FloatToInt(_) => "FloatToInt",
+ IntToFloat(_) => "IntToFloat",
+ FloatConv(_) => "FloatConv",
+ RoundToInt(_) => "RoundToInt",
+ Floor(_) => "Floor",
+ Ceil(_) => "Ceil",
+ Ftrunc(_) => "Ftrunc",
+ DerefFieldSsa(_) => "DerefFieldSsa",
+ DerefSsa(_) => "DerefSsa",
+ ExternPtr(_) => "ExternPtr",
+ FloatConst(_) => "FloatConst",
+ For(_) => "For",
+ ForSsa(_) => "ForSsa",
+ Goto(_) => "Goto",
+ Label(_) => "Label",
+ If(_) => "If",
+ Intrinsic(_) => "Intrinsic",
+ IntrinsicSsa(_) => "IntrinsicSsa",
+ Jump(_) => "Jump",
+ MemPhi(_) => "MemPhi",
+ Ret(_) => "Ret",
+ Split(_) => "Split",
+ StructField(_) => "StructField",
+ DerefField(_) => "DerefField",
+ Switch(_) => "Switch",
+ Syscall(_) => "Syscall",
+ SyscallSsa(_) => "SyscallSsa",
+ Trap(_) => "Trap",
+ VarDeclare(_) => "VarDeclare",
+ Var(_) => "Var",
+ VarInit(_) => "VarInit",
+ VarInitSsa(_) => "VarInitSsa",
+ VarPhi(_) => "VarPhi",
+ VarSsa(_) => "VarSsa",
+ While(_) => "While",
+ DoWhile(_) => "DoWhile",
+ WhileSsa(_) => "WhileSsa",
+ DoWhileSsa(_) => "DoWhileSsa",
+ }
+ }
+
+ pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
+ use HighLevelILLiftedInstructionKind::*;
+ use HighLevelILLiftedOperand as Operand;
+ match &self.kind {
+ Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
+ Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
+ ("left", Operand::Expr(*op.left.clone())),
+ ("right", Operand::Expr(*op.right.clone())),
+ ("carry", Operand::Expr(*op.carry.clone())),
+ ],
+ Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
+ | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
+ | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op)
+ | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
+ | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
+ | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
+ | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
+ ("left", Operand::Expr(*op.left.clone())),
+ ("right", Operand::Expr(*op.right.clone())),
+ ],
+ ArrayIndex(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("index", Operand::Expr(*op.index.clone())),
+ ],
+ ArrayIndexSsa(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ("index", Operand::Expr(*op.index.clone())),
+ ],
+ Assign(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ AssignMemSsa(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ AssignUnpack(op) => vec![
+ ("dest", Operand::ExprList(op.dest.clone())),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ AssignUnpackMemSsa(op) => vec![
+ ("dest", Operand::ExprList(op.dest.clone())),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
+ Call(op) | Tailcall(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ],
+ CallSsa(op) => vec![
+ ("dest", Operand::Expr(*op.dest.clone())),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ Case(op) => vec![
+ ("values", Operand::ExprList(op.values.clone())),
+ ("body", Operand::Expr(*op.body.clone())),
+ ],
+ Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
+ ConstData(op) => vec![(
+ "constant_data",
+ Operand::ConstantData(op.constant_data.clone()),
+ )],
+ Deref(op) | AddressOf(op) | Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op)
+ | BoolToInt(op) | UnimplMem(op) | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op)
+ | IntToFloat(op) | FloatConv(op) | RoundToInt(op) | Floor(op) | Ceil(op)
+ | Ftrunc(op) => vec![("src", Operand::Expr(*op.src.clone()))],
+ DerefFieldSsa(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ("offset", Operand::Int(op.offset)),
+ ("member_index", Operand::MemberIndex(op.member_index)),
+ ],
+ DerefSsa(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ ExternPtr(op) => vec![
+ ("constant", Operand::Int(op.constant)),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
+ For(op) => vec![
+ ("init", Operand::Expr(*op.init.clone())),
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("update", Operand::Expr(*op.update.clone())),
+ ("body", Operand::Expr(*op.body.clone())),
+ ],
+ ForSsa(op) => vec![
+ ("init", Operand::Expr(*op.init.clone())),
+ ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("update", Operand::Expr(*op.update.clone())),
+ ("body", Operand::Expr(*op.body.clone())),
+ ],
+ Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
+ If(op) => vec![
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("cond_true", Operand::Expr(*op.cond_true.clone())),
+ ("cond_false", Operand::Expr(*op.cond_false.clone())),
+ ],
+ Intrinsic(op) => vec![
+ ("intrinsic", Operand::Intrinsic(op.intrinsic)),
+ ("params", Operand::ExprList(op.params.clone())),
+ ],
+ IntrinsicSsa(op) => vec![
+ ("intrinsic", Operand::Intrinsic(op.intrinsic)),
+ ("params", Operand::ExprList(op.params.clone())),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
+ MemPhi(op) => vec![
+ ("dest", Operand::Int(op.dest)),
+ ("src", Operand::IntList(op.src.clone())),
+ ],
+ Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
+ Split(op) => vec![
+ ("high", Operand::Expr(*op.high.clone())),
+ ("low", Operand::Expr(*op.low.clone())),
+ ],
+ StructField(op) | DerefField(op) => vec![
+ ("src", Operand::Expr(*op.src.clone())),
+ ("offset", Operand::Int(op.offset)),
+ ("member_index", Operand::MemberIndex(op.member_index)),
+ ],
+ Switch(op) => vec![
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("default", Operand::Expr(*op.default.clone())),
+ ("cases", Operand::ExprList(op.cases.clone())),
+ ],
+ Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
+ SyscallSsa(op) => vec![
+ ("params", Operand::ExprList(op.params.clone())),
+ ("dest_memory", Operand::Int(op.dest_memory)),
+ ("src_memory", Operand::Int(op.src_memory)),
+ ],
+ Trap(op) => vec![("vector", Operand::Int(op.vector))],
+ VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
+ VarInit(op) => vec![
+ ("dest", Operand::Var(op.dest)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ VarInitSsa(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("src", Operand::Expr(*op.src.clone())),
+ ],
+ VarPhi(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("src", Operand::VarSsaList(op.src.clone())),
+ ],
+ VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
+ While(op) | DoWhile(op) => vec![
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("body", Operand::Expr(*op.body.clone())),
+ ],
+ WhileSsa(op) | DoWhileSsa(op) => vec![
+ ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
+ ("condition", Operand::Expr(*op.condition.clone())),
+ ("body", Operand::Expr(*op.body.clone())),
+ ],
+ }
+ }
+}