summaryrefslogtreecommitdiff
path: root/rust/src/hlil/lift.rs
diff options
context:
space:
mode:
authorMichael Krasnitski <michael.krasnitski@gmail.com>2024-02-11 15:27:22 -0500
committerKyle Martin <krm504@nyu.edu>2024-03-18 17:46:37 -0400
commit9939d850f0b8ccaf1ae048bcb5f788a6c3e606bf (patch)
tree91b582cd51820d826efcd5312e234e56617ca7f9 /rust/src/hlil/lift.rs
parent970fe84875e2d6eed918f5bdc9ff689ef37b05ce (diff)
Refactor HLIL instructions
Similar to MLIL. Also, reintroduce `LiftedJump` and `LiftedLabel` types.
Diffstat (limited to 'rust/src/hlil/lift.rs')
-rw-r--r--rust/src/hlil/lift.rs470
1 files changed, 205 insertions, 265 deletions
diff --git a/rust/src/hlil/lift.rs b/rust/src/hlil/lift.rs
index 5ed7a33c..06338dea 100644
--- a/rust/src/hlil/lift.rs
+++ b/rust/src/hlil/lift.rs
@@ -1,7 +1,33 @@
use super::{operation::*, HighLevelILFunction};
+use crate::rc::Ref;
+use crate::types::{ConstantData, ILIntrinsic, SSAVariable, Variable};
+
+#[derive(Clone)]
+pub enum HighLevelILLiftedOperand {
+ ConstantData(ConstantData),
+ Expr(HighLevelILLiftedInstruction),
+ ExprList(Vec<HighLevelILLiftedInstruction>),
+ Float(f64),
+ Int(u64),
+ IntList(Vec<u64>),
+ Intrinsic(ILIntrinsic),
+ Label(GotoLabel),
+ MemberIndex(Option<usize>),
+ Var(Variable),
+ VarSsa(SSAVariable),
+ VarSsaList(Vec<SSAVariable>),
+}
+
#[derive(Clone, Debug, PartialEq)]
-pub enum HighLevelILLiftedInstruction {
+pub struct HighLevelILLiftedInstruction {
+ pub function: Ref<HighLevelILFunction>,
+ pub address: u64,
+ pub kind: HighLevelILLiftedInstructionKind,
+}
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum HighLevelILLiftedInstructionKind {
Adc(LiftedBinaryOpCarry),
Sbb(LiftedBinaryOpCarry),
Rlc(LiftedBinaryOpCarry),
@@ -91,21 +117,21 @@ pub enum HighLevelILLiftedInstruction {
FloatConst(FloatConst),
For(LiftedForLoop),
ForSsa(LiftedForLoopSsa),
- Goto(Label),
- Label(Label),
+ Goto(LiftedLabel),
+ Label(LiftedLabel),
If(LiftedIf),
Intrinsic(LiftedIntrinsic),
IntrinsicSsa(LiftedIntrinsicSsa),
- Jump(Jump),
+ Jump(LiftedJump),
MemPhi(LiftedMemPhi),
- Nop(NoArgs),
- Break(NoArgs),
- Continue(NoArgs),
- Noret(NoArgs),
- Unreachable(NoArgs),
- Bp(NoArgs),
- Undef(NoArgs),
- Unimpl(NoArgs),
+ Nop,
+ Break,
+ Continue,
+ Noret,
+ Unreachable,
+ Bp,
+ Undef,
+ Unimpl,
Ret(LiftedRet),
Split(LiftedSplit),
StructField(LiftedStructField),
@@ -127,259 +153,173 @@ pub enum HighLevelILLiftedInstruction {
}
impl HighLevelILLiftedInstruction {
- pub fn address(&self) -> u64 {
- use HighLevelILLiftedInstruction::*;
- match self {
- Adc(op) => op.address,
- Sbb(op) => op.address,
- Rlc(op) => op.address,
- Rrc(op) => op.address,
- Add(op) => op.address,
- Sub(op) => op.address,
- And(op) => op.address,
- Or(op) => op.address,
- Xor(op) => op.address,
- Lsl(op) => op.address,
- Lsr(op) => op.address,
- Asr(op) => op.address,
- Rol(op) => op.address,
- Ror(op) => op.address,
- Mul(op) => op.address,
- MuluDp(op) => op.address,
- MulsDp(op) => op.address,
- Divu(op) => op.address,
- DivuDp(op) => op.address,
- Divs(op) => op.address,
- DivsDp(op) => op.address,
- Modu(op) => op.address,
- ModuDp(op) => op.address,
- Mods(op) => op.address,
- ModsDp(op) => op.address,
- CmpE(op) => op.address,
- CmpNe(op) => op.address,
- CmpSlt(op) => op.address,
- CmpUlt(op) => op.address,
- CmpSle(op) => op.address,
- CmpUle(op) => op.address,
- CmpSge(op) => op.address,
- CmpUge(op) => op.address,
- CmpSgt(op) => op.address,
- CmpUgt(op) => op.address,
- TestBit(op) => op.address,
- AddOverflow(op) => op.address,
- Fadd(op) => op.address,
- Fsub(op) => op.address,
- Fmul(op) => op.address,
- Fdiv(op) => op.address,
- FcmpE(op) => op.address,
- FcmpNe(op) => op.address,
- FcmpLt(op) => op.address,
- FcmpLe(op) => op.address,
- FcmpGe(op) => op.address,
- FcmpGt(op) => op.address,
- FcmpO(op) => op.address,
- FcmpUo(op) => op.address,
- ArrayIndex(op) => op.address,
- ArrayIndexSsa(op) => op.address,
- Assign(op) => op.address,
- AssignMemSsa(op) => op.address,
- AssignUnpack(op) => op.address,
- AssignUnpackMemSsa(op) => op.address,
- Block(op) => op.address,
- Call(op) => op.address,
- Tailcall(op) => op.address,
- CallSsa(op) => op.address,
- Case(op) => op.address,
- Const(op) => op.address,
- ConstPtr(op) => op.address,
- Import(op) => op.address,
- ConstData(op) => op.address,
- Deref(op) => op.address,
- AddressOf(op) => op.address,
- Neg(op) => op.address,
- Not(op) => op.address,
- Sx(op) => op.address,
- Zx(op) => op.address,
- LowPart(op) => op.address,
- BoolToInt(op) => op.address,
- UnimplMem(op) => op.address,
- Fsqrt(op) => op.address,
- Fneg(op) => op.address,
- Fabs(op) => op.address,
- FloatToInt(op) => op.address,
- IntToFloat(op) => op.address,
- FloatConv(op) => op.address,
- RoundToInt(op) => op.address,
- Floor(op) => op.address,
- Ceil(op) => op.address,
- Ftrunc(op) => op.address,
- DerefFieldSsa(op) => op.address,
- DerefSsa(op) => op.address,
- ExternPtr(op) => op.address,
- FloatConst(op) => op.address,
- For(op) => op.address,
- ForSsa(op) => op.address,
- Goto(op) => op.address,
- Label(op) => op.address,
- If(op) => op.address,
- Intrinsic(op) => op.address,
- IntrinsicSsa(op) => op.address,
- Jump(op) => op.address,
- MemPhi(op) => op.address,
- Nop(op) => op.address,
- Break(op) => op.address,
- Continue(op) => op.address,
- Noret(op) => op.address,
- Unreachable(op) => op.address,
- Bp(op) => op.address,
- Undef(op) => op.address,
- Unimpl(op) => op.address,
- Ret(op) => op.address,
- Split(op) => op.address,
- StructField(op) => op.address,
- DerefField(op) => op.address,
- Switch(op) => op.address,
- Syscall(op) => op.address,
- SyscallSsa(op) => op.address,
- Trap(op) => op.address,
- VarDeclare(op) => op.address,
- Var(op) => op.address,
- VarInit(op) => op.address,
- VarInitSsa(op) => op.address,
- VarPhi(op) => op.address,
- VarSsa(op) => op.address,
- While(op) => op.address,
- DoWhile(op) => op.address,
- WhileSsa(op) => op.address,
- DoWhileSsa(op) => op.address,
- }
- }
-
- pub fn function(&self) -> &HighLevelILFunction {
- use HighLevelILLiftedInstruction::*;
- match self {
- Adc(op) => &op.function,
- Sbb(op) => &op.function,
- Rlc(op) => &op.function,
- Rrc(op) => &op.function,
- Add(op) => &op.function,
- Sub(op) => &op.function,
- And(op) => &op.function,
- Or(op) => &op.function,
- Xor(op) => &op.function,
- Lsl(op) => &op.function,
- Lsr(op) => &op.function,
- Asr(op) => &op.function,
- Rol(op) => &op.function,
- Ror(op) => &op.function,
- Mul(op) => &op.function,
- MuluDp(op) => &op.function,
- MulsDp(op) => &op.function,
- Divu(op) => &op.function,
- DivuDp(op) => &op.function,
- Divs(op) => &op.function,
- DivsDp(op) => &op.function,
- Modu(op) => &op.function,
- ModuDp(op) => &op.function,
- Mods(op) => &op.function,
- ModsDp(op) => &op.function,
- CmpE(op) => &op.function,
- CmpNe(op) => &op.function,
- CmpSlt(op) => &op.function,
- CmpUlt(op) => &op.function,
- CmpSle(op) => &op.function,
- CmpUle(op) => &op.function,
- CmpSge(op) => &op.function,
- CmpUge(op) => &op.function,
- CmpSgt(op) => &op.function,
- CmpUgt(op) => &op.function,
- TestBit(op) => &op.function,
- AddOverflow(op) => &op.function,
- Fadd(op) => &op.function,
- Fsub(op) => &op.function,
- Fmul(op) => &op.function,
- Fdiv(op) => &op.function,
- FcmpE(op) => &op.function,
- FcmpNe(op) => &op.function,
- FcmpLt(op) => &op.function,
- FcmpLe(op) => &op.function,
- FcmpGe(op) => &op.function,
- FcmpGt(op) => &op.function,
- FcmpO(op) => &op.function,
- FcmpUo(op) => &op.function,
- ArrayIndex(op) => &op.function,
- ArrayIndexSsa(op) => &op.function,
- Assign(op) => &op.function,
- AssignMemSsa(op) => &op.function,
- AssignUnpack(op) => &op.function,
- AssignUnpackMemSsa(op) => &op.function,
- Block(op) => &op.function,
- Call(op) => &op.function,
- Tailcall(op) => &op.function,
- CallSsa(op) => &op.function,
- Case(op) => &op.function,
- Const(op) => &op.function,
- ConstPtr(op) => &op.function,
- Import(op) => &op.function,
- ConstData(op) => &op.function,
- Deref(op) => &op.function,
- AddressOf(op) => &op.function,
- Neg(op) => &op.function,
- Not(op) => &op.function,
- Sx(op) => &op.function,
- Zx(op) => &op.function,
- LowPart(op) => &op.function,
- BoolToInt(op) => &op.function,
- UnimplMem(op) => &op.function,
- Fsqrt(op) => &op.function,
- Fneg(op) => &op.function,
- Fabs(op) => &op.function,
- FloatToInt(op) => &op.function,
- IntToFloat(op) => &op.function,
- FloatConv(op) => &op.function,
- RoundToInt(op) => &op.function,
- Floor(op) => &op.function,
- Ceil(op) => &op.function,
- Ftrunc(op) => &op.function,
- DerefFieldSsa(op) => &op.function,
- DerefSsa(op) => &op.function,
- ExternPtr(op) => &op.function,
- FloatConst(op) => &op.function,
- For(op) => &op.function,
- ForSsa(op) => &op.function,
- Goto(op) => &op.function,
- Label(op) => &op.function,
- If(op) => &op.function,
- Intrinsic(op) => &op.function,
- IntrinsicSsa(op) => &op.function,
- Jump(op) => &op.function,
- MemPhi(op) => &op.function,
- Nop(op) => &op.function,
- Break(op) => &op.function,
- Continue(op) => &op.function,
- Noret(op) => &op.function,
- Unreachable(op) => &op.function,
- Bp(op) => &op.function,
- Undef(op) => &op.function,
- Unimpl(op) => &op.function,
- Ret(op) => &op.function,
- Split(op) => &op.function,
- StructField(op) => &op.function,
- DerefField(op) => &op.function,
- Switch(op) => &op.function,
- Syscall(op) => &op.function,
- SyscallSsa(op) => &op.function,
- Trap(op) => &op.function,
- VarDeclare(op) => &op.function,
- Var(op) => &op.function,
- VarInit(op) => &op.function,
- VarInitSsa(op) => &op.function,
- VarPhi(op) => &op.function,
- VarSsa(op) => &op.function,
- While(op) => &op.function,
- DoWhile(op) => &op.function,
- WhileSsa(op) => &op.function,
- DoWhileSsa(op) => &op.function,
+ pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
+ use HighLevelILLiftedInstructionKind::*;
+ use HighLevelILLiftedOperand as Operand;
+ match &self.kind {
+ 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())),
+ ],
+ Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
+ 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())),
+ ],
}
}
}