diff options
Diffstat (limited to 'rust/src/high_level_il/lift.rs')
| -rw-r--r-- | rust/src/high_level_il/lift.rs | 462 |
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())), + ], + } + } +} |
