summaryrefslogtreecommitdiff
path: root/rust/src/medium_level_il
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2025-12-23 13:12:02 -0700
committerRusty Wagner <rusty.wagner@gmail.com>2026-05-22 16:30:56 -0400
commit8d621c51b2797fda7b1dc22243dde611cfc04f68 (patch)
treeba5e6a90e644d21d13e75dabcbd0cc747444443a /rust/src/medium_level_il
parent08e34ac325743085911f96b62c81d9a1f2127806 (diff)
Refactor calling conventions to support correct representation of structures
Diffstat (limited to 'rust/src/medium_level_il')
-rw-r--r--rust/src/medium_level_il/instruction.rs55
-rw-r--r--rust/src/medium_level_il/lift.rs38
-rw-r--r--rust/src/medium_level_il/operation.rs51
3 files changed, 144 insertions, 0 deletions
diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs
index a223f21e..41f2bbe4 100644
--- a/rust/src/medium_level_il/instruction.rs
+++ b/rust/src/medium_level_il/instruction.rs
@@ -654,9 +654,22 @@ impl MediumLevelILInstruction {
MLIL_VAR_OUTPUT => Op::VarOutput(VarOutput {
dest: get_var(op.operands[0]),
}),
+ MLIL_VAR_OUTPUT_FIELD => Op::VarOutputField(VarOutputField {
+ dest: get_var(op.operands[0]),
+ offset: op.operands[1],
+ }),
+ MLIL_STORE_OUTPUT => Op::StoreOutput(StoreOutput {
+ dest: MediumLevelExpressionIndex::from(op.operands[0]),
+ }),
MLIL_ADDRESS_OF => Op::AddressOf(Var {
src: get_var(op.operands[0]),
}),
+ MLIL_PASS_BY_REF => Op::PassByRef(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
+ MLIL_RETURN_BY_REF => Op::ReturnByRef(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
MLIL_VAR_FIELD => Op::VarField(Field {
src: get_var(op.operands[0]),
offset: op.operands[1],
@@ -682,9 +695,27 @@ impl MediumLevelILInstruction {
MLIL_VAR_OUTPUT_SSA => Op::VarOutputSsa(VarOutputSsa {
dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
}),
+ MLIL_VAR_OUTPUT_SSA_FIELD => Op::VarOutputSsaField(VarOutputSsaField {
+ dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
+ prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
+ offset: op.operands[3],
+ }),
+ MLIL_VAR_OUTPUT_ALIASED => Op::VarOutputAliased(VarOutputAliased {
+ dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
+ prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
+ }),
+ MLIL_VAR_OUTPUT_ALIASED_FIELD => Op::VarOutputAliasedField(VarOutputAliasedField {
+ dest: get_var_ssa(op.operands[0], op.operands[1] as usize),
+ prev: get_var_ssa(op.operands[0], op.operands[2] as usize),
+ offset: op.operands[3],
+ }),
MLIL_TRAP => Op::Trap(Trap {
vector: op.operands[0],
}),
+ MLIL_BLOCK_TO_EXPAND => Op::BlockToExpand(BlockToExpand {
+ num_operands: op.operands[0] as usize,
+ first_operand: op.operands[1] as usize,
+ }),
};
Self {
@@ -1121,7 +1152,13 @@ impl MediumLevelILInstruction {
}),
Var(op) => Lifted::Var(op),
VarOutput(op) => Lifted::VarOutput(op),
+ VarOutputField(op) => Lifted::VarOutputField(op),
+ StoreOutput(op) => Lifted::StoreOutput(LiftedStoreOutput {
+ dest: self.lift_operand(op.dest),
+ }),
AddressOf(op) => Lifted::AddressOf(op),
+ PassByRef(op) => Lifted::PassByRef(self.lift_unary_op(op)),
+ ReturnByRef(op) => Lifted::ReturnByRef(self.lift_unary_op(op)),
VarField(op) => Lifted::VarField(op),
AddressOfField(op) => Lifted::AddressOfField(op),
VarSsa(op) => Lifted::VarSsa(op),
@@ -1129,7 +1166,17 @@ impl MediumLevelILInstruction {
VarSsaField(op) => Lifted::VarSsaField(op),
VarAliasedField(op) => Lifted::VarAliasedField(op),
VarOutputSsa(op) => Lifted::VarOutputSsa(op),
+ VarOutputSsaField(op) => Lifted::VarOutputSsaField(op),
+ VarOutputAliased(op) => Lifted::VarOutputAliased(op),
+ VarOutputAliasedField(op) => Lifted::VarOutputAliasedField(op),
Trap(op) => Lifted::Trap(op),
+ BlockToExpand(_op) => Lifted::BlockToExpand(LiftedBlockToExpand {
+ exprs: self
+ .get_expr_list(0)
+ .iter()
+ .map(|expr| expr.lift())
+ .collect(),
+ }),
};
MediumLevelILLiftedInstruction {
@@ -1823,6 +1870,8 @@ pub enum MediumLevelILInstructionKind {
SeparateParamList(SeparateParamList),
SharedParamSlot(SharedParamSlot),
VarOutput(VarOutput),
+ VarOutputField(VarOutputField),
+ StoreOutput(StoreOutput),
Neg(UnaryOp),
Not(UnaryOp),
Sx(UnaryOp),
@@ -1847,6 +1896,8 @@ pub enum MediumLevelILInstructionKind {
Ret(Ret),
Var(Var),
AddressOf(Var),
+ PassByRef(UnaryOp),
+ ReturnByRef(UnaryOp),
VarField(Field),
AddressOfField(Field),
VarSsa(VarSsa),
@@ -1854,7 +1905,11 @@ pub enum MediumLevelILInstructionKind {
VarSsaField(VarSsaField),
VarAliasedField(VarSsaField),
VarOutputSsa(VarOutputSsa),
+ VarOutputSsaField(VarOutputSsaField),
+ VarOutputAliased(VarOutputAliased),
+ VarOutputAliasedField(VarOutputAliasedField),
Trap(Trap),
+ BlockToExpand(BlockToExpand),
// A placeholder for instructions that the Rust bindings do not yet support.
// Distinct from `Unimpl` as that is a valid instruction.
NotYetImplemented,
diff --git a/rust/src/medium_level_il/lift.rs b/rust/src/medium_level_il/lift.rs
index 58ea8a13..aee8139f 100644
--- a/rust/src/medium_level_il/lift.rs
+++ b/rust/src/medium_level_il/lift.rs
@@ -176,7 +176,11 @@ pub enum MediumLevelILLiftedInstructionKind {
Ret(LiftedRet),
Var(Var),
VarOutput(VarOutput),
+ VarOutputField(VarOutputField),
+ StoreOutput(LiftedStoreOutput),
AddressOf(Var),
+ PassByRef(LiftedUnaryOp),
+ ReturnByRef(LiftedUnaryOp),
VarField(Field),
AddressOfField(Field),
VarSsa(VarSsa),
@@ -184,7 +188,11 @@ pub enum MediumLevelILLiftedInstructionKind {
VarSsaField(VarSsaField),
VarAliasedField(VarSsaField),
VarOutputSsa(VarOutputSsa),
+ VarOutputSsaField(VarOutputSsaField),
+ VarOutputAliased(VarOutputAliased),
+ VarOutputAliasedField(VarOutputAliasedField),
Trap(Trap),
+ BlockToExpand(LiftedBlockToExpand),
// A placeholder for instructions that the Rust bindings do not yet support.
// Distinct from `Unimpl` as that is a valid instruction.
NotYetImplemented,
@@ -301,6 +309,8 @@ impl MediumLevelILLiftedInstruction {
SeparateParamList(_) => "SeparateParamList",
SharedParamSlot(_) => "SharedParamSlot",
VarOutput(_) => "VarOutput",
+ VarOutputField(_) => "VarOutputField",
+ StoreOutput(_) => "StoreOutput",
Neg(_) => "Neg",
Not(_) => "Not",
Sx(_) => "Sx",
@@ -325,6 +335,8 @@ impl MediumLevelILLiftedInstruction {
Ret(_) => "Ret",
Var(_) => "Var",
AddressOf(_) => "AddressOf",
+ PassByRef(_) => "PassByRef",
+ ReturnByRef(_) => "ReturnByRef",
VarField(_) => "VarField",
AddressOfField(_) => "AddressOfField",
VarSsa(_) => "VarSsa",
@@ -332,7 +344,11 @@ impl MediumLevelILLiftedInstruction {
VarSsaField(_) => "VarSsaField",
VarAliasedField(_) => "VarAliasedField",
VarOutputSsa(_) => "VarOutputSsa",
+ VarOutputSsaField(_) => "VarOutputSsaField",
+ VarOutputAliased(_) => "VarOutputAliased",
+ VarOutputAliasedField(_) => "VarOutputAliasedField",
Trap(_) => "Trap",
+ BlockToExpand(_) => "BlockToExpand",
}
}
@@ -549,6 +565,13 @@ impl MediumLevelILLiftedInstruction {
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))],
+ VarOutputField(op) => vec![
+ ("dest", Operand::Var(op.dest)),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ StoreOutput(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
+ PassByRef(op) => vec![("src", Operand::Expr(*op.src.clone()))],
+ ReturnByRef(op) => vec![("src", Operand::Expr(*op.src.clone()))],
VarField(op) | AddressOfField(op) => vec![
("src", Operand::Var(op.src)),
("offset", Operand::Int(op.offset)),
@@ -559,7 +582,22 @@ impl MediumLevelILLiftedInstruction {
("offset", Operand::Int(op.offset)),
],
VarOutputSsa(op) => vec![("dest", Operand::VarSsa(op.dest))],
+ VarOutputSsaField(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("prev", Operand::VarSsa(op.prev)),
+ ("offset", Operand::Int(op.offset)),
+ ],
+ VarOutputAliased(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("prev", Operand::VarSsa(op.prev)),
+ ],
+ VarOutputAliasedField(op) => vec![
+ ("dest", Operand::VarSsa(op.dest)),
+ ("prev", Operand::VarSsa(op.prev)),
+ ("offset", Operand::Int(op.offset)),
+ ],
Trap(op) => vec![("vector", Operand::Int(op.vector))],
+ BlockToExpand(op) => vec![("exprs", Operand::ExprList(op.exprs.clone()))],
}
}
}
diff --git a/rust/src/medium_level_il/operation.rs b/rust/src/medium_level_il/operation.rs
index a9a791b0..1886b3d0 100644
--- a/rust/src/medium_level_il/operation.rs
+++ b/rust/src/medium_level_il/operation.rs
@@ -641,6 +641,23 @@ pub struct VarOutput {
pub dest: Variable,
}
+// VAR_OUTPUT_FIELD
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct VarOutputField {
+ pub dest: Variable,
+ pub offset: u64,
+}
+
+// STORE_OUTPUT
+#[derive(Debug, Copy, Clone)]
+pub struct StoreOutput {
+ pub dest: MediumLevelExpressionIndex,
+}
+#[derive(Clone, Debug, PartialEq)]
+pub struct LiftedStoreOutput {
+ pub dest: Box<MediumLevelILLiftedInstruction>,
+}
+
// VAR_FIELD, ADDRESS_OF_FIELD
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Field {
@@ -667,8 +684,42 @@ pub struct VarOutputSsa {
pub dest: SSAVariable,
}
+// VAR_OUTPUT_SSA_FIELD
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct VarOutputSsaField {
+ pub dest: SSAVariable,
+ pub prev: SSAVariable,
+ pub offset: u64,
+}
+
+// VAR_OUTPUT_ALIASED
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct VarOutputAliased {
+ pub dest: SSAVariable,
+ pub prev: SSAVariable,
+}
+
+// VAR_OUTPUT_ALIASED_FIELD
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct VarOutputAliasedField {
+ pub dest: SSAVariable,
+ pub prev: SSAVariable,
+ pub offset: u64,
+}
+
// TRAP
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct Trap {
pub vector: u64,
}
+
+// BLOCK_TO_EXPAND
+#[derive(Debug, Copy, Clone)]
+pub struct BlockToExpand {
+ pub first_operand: usize,
+ pub num_operands: usize,
+}
+#[derive(Clone, Debug, PartialEq)]
+pub struct LiftedBlockToExpand {
+ pub exprs: Vec<MediumLevelILLiftedInstruction>,
+}