summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2026-04-27 16:39:21 -0400
committerRusty Wagner <rusty.wagner@gmail.com>2026-05-22 16:30:56 -0400
commit08e34ac325743085911f96b62c81d9a1f2127806 (patch)
tree4eb72a14340041bdce2d81b0633e8398adc4ddb4 /rust/src
parentaca1c6f63911057018341869b9aaf74f486a1474 (diff)
Extend MLIL call instruction outputs to be expressions
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/medium_level_il/instruction.rs102
-rw-r--r--rust/src/medium_level_il/lift.rs22
-rw-r--r--rust/src/medium_level_il/operation.rs34
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(&params_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(&params_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(&params_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(&params_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 {