diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2026-04-27 16:39:21 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2026-05-22 16:30:56 -0400 |
| commit | 08e34ac325743085911f96b62c81d9a1f2127806 (patch) | |
| tree | 4eb72a14340041bdce2d81b0633e8398adc4ddb4 /rust/src | |
| parent | aca1c6f63911057018341869b9aaf74f486a1474 (diff) | |
Extend MLIL call instruction outputs to be expressions
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/medium_level_il/instruction.rs | 102 | ||||
| -rw-r--r-- | rust/src/medium_level_il/lift.rs | 22 | ||||
| -rw-r--r-- | rust/src/medium_level_il/operation.rs | 34 |
3 files changed, 100 insertions, 58 deletions
diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs index c1cd26a3..a223f21e 100644 --- a/rust/src/medium_level_il/instruction.rs +++ b/rust/src/medium_level_il/instruction.rs @@ -457,10 +457,6 @@ impl MediumLevelILInstruction { num_params: op.operands[3] as usize, first_param: op.operands[4] as usize, }), - MLIL_CALL_OUTPUT => Op::CallOutput(CallOutput { - first_output: op.operands[0] as usize, - num_outputs: op.operands[1] as usize, - }), MLIL_CALL_PARAM => Op::CallParam(CallParam { first_param: op.operands[0] as usize, num_params: op.operands[1] as usize, @@ -554,21 +550,24 @@ impl MediumLevelILInstruction { stack: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_CALL_UNTYPED => Op::CallUntyped(CallUntyped { - output: MediumLevelExpressionIndex::from(op.operands[0]), - dest: MediumLevelExpressionIndex::from(op.operands[1]), - params: MediumLevelExpressionIndex::from(op.operands[2]), - stack: MediumLevelExpressionIndex::from(op.operands[3]), + num_outputs: op.operands[0] as usize, + first_output: op.operands[1] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[2]), + params: MediumLevelExpressionIndex::from(op.operands[3]), + stack: MediumLevelExpressionIndex::from(op.operands[4]), }), MLIL_TAILCALL_UNTYPED => Op::TailcallUntyped(CallUntyped { - output: MediumLevelExpressionIndex::from(op.operands[0]), - dest: MediumLevelExpressionIndex::from(op.operands[1]), - params: MediumLevelExpressionIndex::from(op.operands[2]), - stack: MediumLevelExpressionIndex::from(op.operands[3]), + num_outputs: op.operands[0] as usize, + first_output: op.operands[1] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[2]), + params: MediumLevelExpressionIndex::from(op.operands[3]), + stack: MediumLevelExpressionIndex::from(op.operands[4]), }), MLIL_SYSCALL_UNTYPED => Op::SyscallUntyped(SyscallUntyped { - output: MediumLevelExpressionIndex::from(op.operands[0]), - params: MediumLevelExpressionIndex::from(op.operands[1]), - stack: MediumLevelExpressionIndex::from(op.operands[2]), + num_outputs: op.operands[0] as usize, + first_output: op.operands[1] as usize, + params: MediumLevelExpressionIndex::from(op.operands[2]), + stack: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_NEG => Op::Neg(UnaryOp { src: MediumLevelExpressionIndex::from(op.operands[0] as usize), @@ -652,6 +651,9 @@ impl MediumLevelILInstruction { MLIL_VAR => Op::Var(Var { src: get_var(op.operands[0]), }), + MLIL_VAR_OUTPUT => Op::VarOutput(VarOutput { + dest: get_var(op.operands[0]), + }), MLIL_ADDRESS_OF => Op::AddressOf(Var { src: get_var(op.operands[0]), }), @@ -677,6 +679,9 @@ impl MediumLevelILInstruction { src: get_var_ssa(op.operands[0], op.operands[1] as usize), offset: op.operands[2], }), + MLIL_VAR_OUTPUT_SSA => Op::VarOutputSsa(VarOutputSsa { + dest: get_var_ssa(op.operands[0], op.operands[1] as usize), + }), MLIL_TRAP => Op::Trap(Trap { vector: op.operands[0], }), @@ -949,7 +954,11 @@ impl MediumLevelILInstruction { .collect(), }), Syscall(_op) => Lifted::Syscall(LiftedSyscallCall { - output: self.get_var_list(0), + output: self + .get_expr_list(0) + .iter() + .map(|expr| expr.lift()) + .collect(), params: self .get_expr_list(2) .iter() @@ -1002,7 +1011,10 @@ impl MediumLevelILInstruction { .instruction_from_expr_index(op.output) .expect("Valid output expression index"); Lifted::SyscallSsa(LiftedSyscallSsa { - output: get_call_output_ssa(&output_instr), + output: get_call_output_ssa(&output_instr) + .iter() + .map(|expr| expr.lift()) + .collect(), params: self .get_expr_list(1) .iter() @@ -1021,7 +1033,10 @@ impl MediumLevelILInstruction { .instruction_from_expr_index(op.params) .expect("Valid params expression index"); Lifted::SyscallUntypedSsa(LiftedSyscallUntypedSsa { - output: get_call_output_ssa(&output_instr), + output: get_call_output_ssa(&output_instr) + .iter() + .map(|expr| expr.lift()) + .collect(), params: get_call_params_ssa(¶ms_instr) .iter() .map(|param| param.lift()) @@ -1033,16 +1048,16 @@ impl MediumLevelILInstruction { CallUntyped(op) => Lifted::CallUntyped(self.lift_call_untyped(op)), TailcallUntyped(op) => Lifted::TailcallUntyped(self.lift_call_untyped(op)), 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), + output: self + .get_expr_list(0) + .iter() + .map(|expr| expr.lift()) + .collect(), params: get_call_params(¶ms_instr) .iter() .map(|param| param.lift()) @@ -1105,6 +1120,7 @@ impl MediumLevelILInstruction { .collect(), }), Var(op) => Lifted::Var(op), + VarOutput(op) => Lifted::VarOutput(op), AddressOf(op) => Lifted::AddressOf(op), VarField(op) => Lifted::VarField(op), AddressOfField(op) => Lifted::AddressOfField(op), @@ -1112,6 +1128,7 @@ impl MediumLevelILInstruction { VarAliased(op) => Lifted::VarAliased(op), VarSsaField(op) => Lifted::VarSsaField(op), VarAliasedField(op) => Lifted::VarAliasedField(op), + VarOutputSsa(op) => Lifted::VarOutputSsa(op), Trap(op) => Lifted::Trap(op), }; @@ -1590,7 +1607,11 @@ impl MediumLevelILInstruction { fn lift_call(&self, op: Call) -> LiftedCall { LiftedCall { - output: self.get_var_list(0), + output: self + .get_expr_list(0) + .iter() + .map(|expr| expr.lift()) + .collect(), dest: self.lift_operand(op.dest), params: self .get_expr_list(3) @@ -1601,16 +1622,16 @@ 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(&output_instr), + output: self + .get_expr_list(0) + .iter() + .map(|expr| expr.lift()) + .collect(), dest: self.lift_operand(op.dest), params: get_call_params(¶ms_instr) .iter() @@ -1626,7 +1647,10 @@ impl MediumLevelILInstruction { .instruction_from_expr_index(op.output) .expect("Valid output expression index"); LiftedCallSsa { - output: get_call_output_ssa(&output_instr), + output: get_call_output_ssa(&output_instr) + .iter() + .map(|expr| expr.lift()) + .collect(), dest: self.lift_operand(op.dest), params: self .get_expr_list(2) @@ -1647,7 +1671,10 @@ impl MediumLevelILInstruction { .instruction_from_expr_index(op.params) .expect("Valid params expression index"); LiftedCallUntypedSsa { - output: get_call_output_ssa(&output_instr), + output: get_call_output_ssa(&output_instr) + .iter() + .map(|expr| expr.lift()) + .collect(), dest: self.lift_operand(op.dest), params: get_call_params_ssa(¶ms_instr) .iter() @@ -1795,6 +1822,7 @@ pub enum MediumLevelILInstructionKind { SyscallUntyped(SyscallUntyped), SeparateParamList(SeparateParamList), SharedParamSlot(SharedParamSlot), + VarOutput(VarOutput), Neg(UnaryOp), Not(UnaryOp), Sx(UnaryOp), @@ -1825,6 +1853,7 @@ pub enum MediumLevelILInstructionKind { VarAliased(VarSsa), VarSsaField(VarSsaField), VarAliasedField(VarSsaField), + VarOutputSsa(VarOutputSsa), Trap(Trap), // A placeholder for instructions that the Rust bindings do not yet support. // Distinct from `Unimpl` as that is a valid instruction. @@ -1848,13 +1877,6 @@ fn get_var_ssa(id: u64, version: usize) -> SSAVariable { SSAVariable::new(get_var(id), version) } -fn get_call_output(instr: &MediumLevelILInstruction) -> Vec<Variable> { - match instr.kind { - MediumLevelILInstructionKind::CallOutput(_op) => instr.get_var_list(0), - _ => vec![], - } -} - fn get_call_params(instr: &MediumLevelILInstruction) -> Vec<MediumLevelILInstruction> { match instr.kind { MediumLevelILInstructionKind::CallParam(_op) => instr.get_expr_list(0), @@ -1862,9 +1884,9 @@ fn get_call_params(instr: &MediumLevelILInstruction) -> Vec<MediumLevelILInstruc } } -fn get_call_output_ssa(instr: &MediumLevelILInstruction) -> Vec<SSAVariable> { +fn get_call_output_ssa(instr: &MediumLevelILInstruction) -> Vec<MediumLevelILInstruction> { match instr.kind { - MediumLevelILInstructionKind::CallOutputSsa(_op) => instr.get_ssa_var_list(1), + MediumLevelILInstructionKind::CallOutputSsa(_op) => instr.get_expr_list(1), _ => vec![], } } diff --git a/rust/src/medium_level_il/lift.rs b/rust/src/medium_level_il/lift.rs index ff12c0e2..58ea8a13 100644 --- a/rust/src/medium_level_il/lift.rs +++ b/rust/src/medium_level_il/lift.rs @@ -175,6 +175,7 @@ pub enum MediumLevelILLiftedInstructionKind { LoadSsa(LiftedLoadSsa), Ret(LiftedRet), Var(Var), + VarOutput(VarOutput), AddressOf(Var), VarField(Field), AddressOfField(Field), @@ -182,6 +183,7 @@ pub enum MediumLevelILLiftedInstructionKind { VarAliased(VarSsa), VarSsaField(VarSsaField), VarAliasedField(VarSsaField), + VarOutputSsa(VarOutputSsa), Trap(Trap), // A placeholder for instructions that the Rust bindings do not yet support. // Distinct from `Unimpl` as that is a valid instruction. @@ -298,6 +300,7 @@ impl MediumLevelILLiftedInstruction { SyscallUntyped(_) => "SyscallUntyped", SeparateParamList(_) => "SeparateParamList", SharedParamSlot(_) => "SharedParamSlot", + VarOutput(_) => "VarOutput", Neg(_) => "Neg", Not(_) => "Not", Sx(_) => "Sx", @@ -328,6 +331,7 @@ impl MediumLevelILLiftedInstruction { VarAliased(_) => "VarAliased", VarSsaField(_) => "VarSsaField", VarAliasedField(_) => "VarAliasedField", + VarOutputSsa(_) => "VarOutputSsa", Trap(_) => "Trap", } } @@ -451,7 +455,7 @@ impl MediumLevelILLiftedInstruction { ("carry", Operand::Expr(*op.carry.clone())), ], Call(op) | Tailcall(op) => vec![ - ("output", Operand::VarList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("dest", Operand::Expr(*op.dest.clone())), ("params", Operand::ExprList(op.params.clone())), ], @@ -466,7 +470,7 @@ impl MediumLevelILLiftedInstruction { ("src_memory", Operand::Int(op.src_memory)), ], Syscall(op) => vec![ - ("output", Operand::VarList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("params", Operand::ExprList(op.params.clone())), ], Intrinsic(op) => vec![ @@ -490,35 +494,35 @@ impl MediumLevelILLiftedInstruction { ("output", Operand::VarSsaList(op.output.clone())), ], CallSsa(op) | TailcallSsa(op) => vec![ - ("output", Operand::VarSsaList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("dest", Operand::Expr(*op.dest.clone())), ("params", Operand::ExprList(op.params.clone())), ("src_memory", Operand::Int(op.src_memory)), ], CallUntypedSsa(op) | TailcallUntypedSsa(op) => vec![ - ("output", Operand::VarSsaList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("dest", Operand::Expr(*op.dest.clone())), ("params", Operand::ExprList(op.params.clone())), ("stack", Operand::Expr(*op.stack.clone())), ], SyscallSsa(op) => vec![ - ("output", Operand::VarSsaList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("params", Operand::ExprList(op.params.clone())), ("src_memory", Operand::Int(op.src_memory)), ], SyscallUntypedSsa(op) => vec![ - ("output", Operand::VarSsaList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("params", Operand::ExprList(op.params.clone())), ("stack", Operand::Expr(*op.stack.clone())), ], CallUntyped(op) | TailcallUntyped(op) => vec![ - ("output", Operand::VarList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("dest", Operand::Expr(*op.dest.clone())), ("params", Operand::ExprList(op.params.clone())), ("stack", Operand::Expr(*op.stack.clone())), ], SyscallUntyped(op) => vec![ - ("output", Operand::VarList(op.output.clone())), + ("output", Operand::ExprList(op.output.clone())), ("params", Operand::ExprList(op.params.clone())), ("stack", Operand::Expr(*op.stack.clone())), ], @@ -544,6 +548,7 @@ impl MediumLevelILLiftedInstruction { SeparateParamList(op) => vec![("params", Operand::ExprList(op.params.clone()))], SharedParamSlot(op) => vec![("params", Operand::ExprList(op.params.clone()))], Var(op) | AddressOf(op) => vec![("src", Operand::Var(op.src))], + VarOutput(op) => vec![("dest", Operand::Var(op.dest))], VarField(op) | AddressOfField(op) => vec![ ("src", Operand::Var(op.src)), ("offset", Operand::Int(op.offset)), @@ -553,6 +558,7 @@ impl MediumLevelILLiftedInstruction { ("src", Operand::VarSsa(op.src)), ("offset", Operand::Int(op.offset)), ], + VarOutputSsa(op) => vec![("dest", Operand::VarSsa(op.dest))], Trap(op) => vec![("vector", Operand::Int(op.vector))], } } diff --git a/rust/src/medium_level_il/operation.rs b/rust/src/medium_level_il/operation.rs index 578087d0..a9a791b0 100644 --- a/rust/src/medium_level_il/operation.rs +++ b/rust/src/medium_level_il/operation.rs @@ -325,7 +325,7 @@ pub struct Call { } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCall { - pub output: Vec<Variable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub dest: Box<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, } @@ -388,7 +388,7 @@ pub struct Syscall { } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallCall { - pub output: Vec<Variable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, } @@ -465,7 +465,7 @@ pub struct CallSsa { } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCallSsa { - pub output: Vec<SSAVariable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub dest: Box<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, pub src_memory: u64, @@ -481,7 +481,7 @@ pub struct CallUntypedSsa { } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCallUntypedSsa { - pub output: Vec<SSAVariable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub dest: Box<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, @@ -497,7 +497,7 @@ pub struct SyscallSsa { } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallSsa { - pub output: Vec<SSAVariable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, pub src_memory: u64, } @@ -511,7 +511,7 @@ pub struct SyscallUntypedSsa { } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallUntypedSsa { - pub output: Vec<SSAVariable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, } @@ -519,14 +519,15 @@ pub struct LiftedSyscallUntypedSsa { // CALL_UNTYPED, TAILCALL_UNTYPED #[derive(Debug, Copy, Clone)] pub struct CallUntyped { - pub output: MediumLevelExpressionIndex, + pub first_output: usize, + pub num_outputs: usize, pub dest: MediumLevelExpressionIndex, pub params: MediumLevelExpressionIndex, pub stack: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCallUntyped { - pub output: Vec<Variable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub dest: Box<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, @@ -535,13 +536,14 @@ pub struct LiftedCallUntyped { // SYSCALL_UNTYPED #[derive(Debug, Copy, Clone)] pub struct SyscallUntyped { - pub output: MediumLevelExpressionIndex, + pub first_output: usize, + pub num_outputs: usize, pub params: MediumLevelExpressionIndex, pub stack: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallUntyped { - pub output: Vec<Variable>, + pub output: Vec<MediumLevelILLiftedInstruction>, pub params: Vec<MediumLevelILLiftedInstruction>, pub stack: Box<MediumLevelILLiftedInstruction>, } @@ -633,6 +635,12 @@ pub struct Var { pub src: Variable, } +// VAR_OUTPUT +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +pub struct VarOutput { + pub dest: Variable, +} + // VAR_FIELD, ADDRESS_OF_FIELD #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Field { @@ -653,6 +661,12 @@ pub struct VarSsaField { pub offset: u64, } +// VAR_OUTPUT_SSA +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +pub struct VarOutputSsa { + pub dest: SSAVariable, +} + // TRAP #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Trap { |
