summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h26
-rw-r--r--binaryninjacore.h3
-rw-r--r--examples/mlil_parser/src/mlil_parser.cpp3
-rw-r--r--highlevelilinstruction.cpp10
-rw-r--r--highlevelilinstruction.h1
-rw-r--r--lowlevelilinstruction.cpp10
-rw-r--r--lowlevelilinstruction.h1
-rw-r--r--mediumlevelilinstruction.cpp223
-rw-r--r--mediumlevelilinstruction.h163
-rw-r--r--python/mediumlevelil.py350
-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
13 files changed, 637 insertions, 311 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index bc36f633..88d43f4e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -15695,6 +15695,7 @@ namespace BinaryNinja {
const ILSourceLocation& loc = ILSourceLocation());
ExprId VarSplitSSA(size_t size, const SSAVariable& high, const SSAVariable& low,
const ILSourceLocation& loc = ILSourceLocation());
+ ExprId VarOutputSSA(size_t size, const SSAVariable& dest, const ILSourceLocation& loc = ILSourceLocation());
ExprId AddressOf(const Variable& var, const ILSourceLocation& loc = ILSourceLocation());
ExprId AddressOfField(const Variable& var, uint64_t offset, const ILSourceLocation& loc = ILSourceLocation());
ExprId Const(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
@@ -15752,35 +15753,36 @@ namespace BinaryNinja {
ExprId JumpTo(ExprId dest, const std::map<uint64_t, BNMediumLevelILLabel*>& targets,
const ILSourceLocation& loc = ILSourceLocation());
ExprId ReturnHint(ExprId dest, const ILSourceLocation& loc = ILSourceLocation());
- ExprId Call(const std::vector<Variable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId Call(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId CallUntyped(const std::vector<Variable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId CallUntyped(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
ExprId stack, const ILSourceLocation& loc = ILSourceLocation());
- ExprId Syscall(const std::vector<Variable>& output, const std::vector<ExprId>& params,
+ ExprId Syscall(const std::vector<ExprId>& output, const std::vector<ExprId>& params,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId SyscallUntyped(const std::vector<Variable>& output, const std::vector<ExprId>& params, ExprId stack,
+ ExprId SyscallUntyped(const std::vector<ExprId>& output, const std::vector<ExprId>& params, ExprId stack,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId TailCall(const std::vector<Variable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId TailCall(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId TailCallUntyped(const std::vector<Variable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId TailCallUntyped(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
ExprId stack, const ILSourceLocation& loc = ILSourceLocation());
- ExprId CallSSA(const std::vector<SSAVariable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId CallSSA(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc = ILSourceLocation());
- ExprId CallUntypedSSA(const std::vector<SSAVariable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId CallUntypedSSA(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, ExprId stack,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId SyscallSSA(const std::vector<SSAVariable>& output, const std::vector<ExprId>& params,
+ ExprId SyscallSSA(const std::vector<ExprId>& output, const std::vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc = ILSourceLocation());
- ExprId SyscallUntypedSSA(const std::vector<SSAVariable>& output, const std::vector<ExprId>& params,
+ ExprId SyscallUntypedSSA(const std::vector<ExprId>& output, const std::vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, ExprId stack,
const ILSourceLocation& loc = ILSourceLocation());
- ExprId TailCallSSA(const std::vector<SSAVariable>& output, ExprId dest, const std::vector<ExprId>& params,
+ ExprId TailCallSSA(const std::vector<ExprId>& output, ExprId dest, const std::vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc = ILSourceLocation());
- ExprId TailCallUntypedSSA(const std::vector<SSAVariable>& output, ExprId dest,
+ ExprId TailCallUntypedSSA(const std::vector<ExprId>& output, ExprId dest,
const std::vector<ExprId>& params, size_t newMemVersion, size_t prevMemVersion, ExprId stack,
const ILSourceLocation& loc = ILSourceLocation());
ExprId SeparateParamList(const std::vector<ExprId>& params, const ILSourceLocation& loc = ILSourceLocation());
ExprId SharedParamSlot(const std::vector<ExprId>& params, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId VarOutput(size_t size, const Variable& var, const ILSourceLocation& loc = ILSourceLocation());
ExprId Return(const std::vector<ExprId>& sources, const ILSourceLocation& loc = ILSourceLocation());
ExprId NoReturn(const ILSourceLocation& loc = ILSourceLocation());
ExprId CompareEqual(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
diff --git a/binaryninjacore.h b/binaryninjacore.h
index fe9b3dbe..8a970276 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1424,12 +1424,12 @@ extern "C"
MLIL_RET_HINT, // Intermediate stages, does not appear in final forms
MLIL_CALL, // Not valid in SSA form (see MLIL_CALL_SSA)
MLIL_CALL_UNTYPED, // Not valid in SSA form (see MLIL_CALL_UNTYPED_SSA)
- MLIL_CALL_OUTPUT, // Only valid within MLIL_CALL, MLIL_SYSCALL, MLIL_TAILCALL family instructions
MLIL_CALL_PARAM, // Only valid within MLIL_CALL, MLIL_SYSCALL, MLIL_TAILCALL family instructions
MLIL_SEPARATE_PARAM_LIST, // Only valid within the MLIL_CALL_PARAM or MLIL_CALL_PARAM_SSA instructions inside
// untyped call variants
MLIL_SHARED_PARAM_SLOT, // Only valid within the MLIL_CALL_PARAM, MLIL_CALL_PARAM_SSA, or
// MLIL_SEPARATE_PARAM_LIST instructions inside untyped call variants
+ MLIL_VAR_OUTPUT, // Only valid within MLIL_CALL, MLIL_SYSCALL, MLIL_TAILCALL family instructions
MLIL_RET,
MLIL_NORET,
MLIL_IF,
@@ -1506,6 +1506,7 @@ extern "C"
// instructions
MLIL_CALL_OUTPUT_SSA, // Only valid within the MLIL_CALL_SSA or MLIL_SYSCALL_SSA, MLIL_TAILCALL_SSA family
// instructions
+ MLIL_VAR_OUTPUT_SSA, // Only valid within the MLIL_CALL_OUTPUT_SSA instruction
MLIL_MEMORY_INTRINSIC_OUTPUT_SSA, // Only valid within the MLIL_MEMORY_INTRINSIC_SSA instruction
MLIL_LOAD_SSA,
MLIL_LOAD_STRUCT_SSA,
diff --git a/examples/mlil_parser/src/mlil_parser.cpp b/examples/mlil_parser/src/mlil_parser.cpp
index 66dcd45e..11fabdaa 100644
--- a/examples/mlil_parser/src/mlil_parser.cpp
+++ b/examples/mlil_parser/src/mlil_parser.cpp
@@ -74,7 +74,6 @@ static void PrintOperation(BNMediumLevelILOperation operation)
ENUM_PRINTER(MLIL_JUMP_TO)
ENUM_PRINTER(MLIL_CALL)
ENUM_PRINTER(MLIL_CALL_UNTYPED)
- ENUM_PRINTER(MLIL_CALL_OUTPUT)
ENUM_PRINTER(MLIL_CALL_PARAM)
ENUM_PRINTER(MLIL_RET)
ENUM_PRINTER(MLIL_NORET)
@@ -99,6 +98,7 @@ static void PrintOperation(BNMediumLevelILOperation operation)
ENUM_PRINTER(MLIL_TAILCALL_UNTYPED)
ENUM_PRINTER(MLIL_SEPARATE_PARAM_LIST)
ENUM_PRINTER(MLIL_SHARED_PARAM_SLOT)
+ ENUM_PRINTER(MLIL_VAR_OUTPUT)
ENUM_PRINTER(MLIL_BP)
ENUM_PRINTER(MLIL_TRAP)
ENUM_PRINTER(MLIL_UNDEF)
@@ -121,6 +121,7 @@ static void PrintOperation(BNMediumLevelILOperation operation)
ENUM_PRINTER(MLIL_TAILCALL_UNTYPED_SSA)
ENUM_PRINTER(MLIL_CALL_PARAM_SSA)
ENUM_PRINTER(MLIL_CALL_OUTPUT_SSA)
+ ENUM_PRINTER(MLIL_VAR_OUTPUT_SSA)
ENUM_PRINTER(MLIL_LOAD_SSA)
ENUM_PRINTER(MLIL_LOAD_STRUCT_SSA)
ENUM_PRINTER(MLIL_STORE_SSA)
diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp
index 7f4bad39..f155ce03 100644
--- a/highlevelilinstruction.cpp
+++ b/highlevelilinstruction.cpp
@@ -477,6 +477,16 @@ HighLevelILInstructionList::operator vector<HighLevelILInstruction>() const
}
+HighLevelILInstructionList::operator vector<ExprId>() const
+{
+ vector<ExprId> result;
+ result.reserve(size());
+ for (auto i : *this)
+ result.push_back(i.exprIndex);
+ return result;
+}
+
+
const SSAVariable HighLevelILSSAVariableList::ListIterator::operator*()
{
HighLevelILIntegerList::const_iterator cur = pos;
diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h
index bf2b5162..0e7fdc60 100644
--- a/highlevelilinstruction.h
+++ b/highlevelilinstruction.h
@@ -305,6 +305,7 @@ namespace BinaryNinja
const HighLevelILInstruction operator[](size_t i) const;
operator _STD_VECTOR<HighLevelILInstruction>() const;
+ operator _STD_VECTOR<ExprId>() const;
};
/*!
diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp
index 3b92d310..228e8328 100644
--- a/lowlevelilinstruction.cpp
+++ b/lowlevelilinstruction.cpp
@@ -835,6 +835,16 @@ LowLevelILInstructionList::operator vector<LowLevelILInstruction>() const
}
+LowLevelILInstructionList::operator vector<ExprId>() const
+{
+ vector<ExprId> result;
+ result.reserve(size());
+ for (auto i : *this)
+ result.push_back(i.exprIndex);
+ return result;
+}
+
+
const RegisterOrFlag LowLevelILRegisterOrFlagList::ListIterator::operator*()
{
return RegisterOrFlag::FromIdentifier(*pos);
diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h
index 97f10c32..c7bbc7f4 100644
--- a/lowlevelilinstruction.h
+++ b/lowlevelilinstruction.h
@@ -533,6 +533,7 @@ namespace BinaryNinja
const LowLevelILInstruction operator[](size_t i) const;
operator _STD_VECTOR<LowLevelILInstruction>() const;
+ operator _STD_VECTOR<ExprId>() const;
};
/*!
diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp
index 0c89ace3..74b1d76f 100644
--- a/mediumlevelilinstruction.cpp
+++ b/mediumlevelilinstruction.cpp
@@ -84,8 +84,10 @@ static constexpr std::array s_operandTypeForUsage = {
OperandUsageType{SourceMemoryVersionsMediumLevelOperandUsage, IndexListMediumLevelOperand},
OperandUsageType{OutputVariablesMediumLevelOperandUsage, VariableListMediumLevelOperand},
OperandUsageType{OutputVariablesSubExprMediumLevelOperandUsage, VariableListMediumLevelOperand},
+ OperandUsageType{OutputVariablesSubExprMediumLevelOperandUsage, ExprListMediumLevelOperand},
OperandUsageType{OutputSSAVariablesMediumLevelOperandUsage, SSAVariableListMediumLevelOperand},
OperandUsageType{OutputSSAVariablesSubExprMediumLevelOperandUsage, SSAVariableListMediumLevelOperand},
+ OperandUsageType{OutputExprsSubExprMediumLevelOperandUsage, ExprListMediumLevelOperand},
OperandUsageType{OutputSSAMemoryVersionMediumLevelOperandUsage, IndexMediumLevelOperand},
OperandUsageType{ParameterExprsMediumLevelOperandUsage, ExprListMediumLevelOperand},
OperandUsageType{SourceExprsMediumLevelOperandUsage, ExprListMediumLevelOperand},
@@ -126,6 +128,7 @@ struct MediumLevelILOperationTraits
// Represented as subexpression, so only takes one slot even though it is a list
return 1;
case OutputSSAVariablesSubExprMediumLevelOperandUsage:
+ case OutputExprsSubExprMediumLevelOperandUsage:
// OutputSSAMemoryVersionMediumLevelOperandUsage follows at same operand
return 0;
case UntypedParameterSSAExprsMediumLevelOperandUsage:
@@ -206,12 +209,12 @@ static constexpr std::array s_instructionOperandUsage = {
OperandUsage{MLIL_JUMP, {DestExprMediumLevelOperandUsage}},
OperandUsage{MLIL_JUMP_TO, {DestExprMediumLevelOperandUsage, TargetsMediumLevelOperandUsage}},
OperandUsage{MLIL_RET_HINT, {DestExprMediumLevelOperandUsage}},
- OperandUsage{MLIL_CALL, {OutputVariablesMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
- OperandUsage{MLIL_CALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterExprsMediumLevelOperandUsage}},
- OperandUsage{MLIL_CALL_OUTPUT, {OutputVariablesMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CALL, {OutputExprsMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CALL_UNTYPED, {OutputExprsMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_CALL_PARAM, {ParameterExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_SEPARATE_PARAM_LIST, {ParameterExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_SHARED_PARAM_SLOT, {ParameterExprsMediumLevelOperandUsage}},
+ OperandUsage{MLIL_VAR_OUTPUT, {DestVariableMediumLevelOperandUsage}},
OperandUsage{MLIL_RET, {SourceExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_NORET},
OperandUsage{MLIL_IF, {ConditionExprMediumLevelOperandUsage, TrueTargetMediumLevelOperandUsage, FalseTargetMediumLevelOperandUsage}},
@@ -229,10 +232,10 @@ static constexpr std::array s_instructionOperandUsage = {
OperandUsage{MLIL_TEST_BIT, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
OperandUsage{MLIL_BOOL_TO_INT, {SourceExprMediumLevelOperandUsage}},
OperandUsage{MLIL_ADD_OVERFLOW, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
- OperandUsage{MLIL_SYSCALL, {OutputVariablesMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
- OperandUsage{MLIL_SYSCALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage, UntypedParameterExprsMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
- OperandUsage{MLIL_TAILCALL, {OutputVariablesMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
- OperandUsage{MLIL_TAILCALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterExprsMediumLevelOperandUsage}},
+ OperandUsage{MLIL_SYSCALL, {OutputExprsMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
+ OperandUsage{MLIL_SYSCALL_UNTYPED, {OutputExprsMediumLevelOperandUsage, UntypedParameterExprsMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_TAILCALL, {OutputExprsMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
+ OperandUsage{MLIL_TAILCALL_UNTYPED, {OutputExprsMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_INTRINSIC, {OutputVariablesMediumLevelOperandUsage, IntrinsicMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_FREE_VAR_SLOT, {DestVariableMediumLevelOperandUsage}},
OperandUsage{MLIL_BP},
@@ -274,14 +277,15 @@ static constexpr std::array s_instructionOperandUsage = {
OperandUsage{MLIL_VAR_SPLIT_SSA, {HighSSAVariableMediumLevelOperandUsage, LowSSAVariableMediumLevelOperandUsage}},
OperandUsage{MLIL_ASSERT_SSA, {SourceSSAVariableMediumLevelOperandUsage, ConstraintMediumLevelOperandUsage}},
OperandUsage{MLIL_FORCE_VER_SSA, {DestSSAVariableMediumLevelOperandUsage, SourceSSAVariableMediumLevelOperandUsage}},
- OperandUsage{MLIL_CALL_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
- OperandUsage{MLIL_CALL_UNTYPED_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterSSAExprsMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
- OperandUsage{MLIL_SYSCALL_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
- OperandUsage{MLIL_SYSCALL_UNTYPED_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, UntypedParameterSSAExprsMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
- OperandUsage{MLIL_TAILCALL_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
- OperandUsage{MLIL_TAILCALL_UNTYPED_SSA, {OutputSSAVariablesSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterSSAExprsMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CALL_SSA, {OutputExprsSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CALL_UNTYPED_SSA, {OutputExprsSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterSSAExprsMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_SYSCALL_SSA, {OutputExprsSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
+ OperandUsage{MLIL_SYSCALL_UNTYPED_SSA, {OutputExprsSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, UntypedParameterSSAExprsMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_TAILCALL_SSA, {OutputExprsSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
+ OperandUsage{MLIL_TAILCALL_UNTYPED_SSA, {OutputExprsSubExprMediumLevelOperandUsage, OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage, UntypedParameterSSAExprsMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
OperandUsage{MLIL_CALL_PARAM_SSA, {ParameterExprsMediumLevelOperandUsage}},
OperandUsage{MLIL_CALL_OUTPUT_SSA, {OutputSSAVariablesMediumLevelOperandUsage}},
+ OperandUsage{MLIL_VAR_OUTPUT_SSA, {DestSSAVariableMediumLevelOperandUsage}},
OperandUsage{MLIL_MEMORY_INTRINSIC_OUTPUT_SSA, {OutputSSAVariablesMediumLevelOperandUsage}},
OperandUsage{MLIL_LOAD_SSA, {SourceExprMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
OperandUsage{MLIL_LOAD_STRUCT_SSA, {SourceExprMediumLevelOperandUsage, OffsetMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
@@ -674,6 +678,16 @@ MediumLevelILInstructionList::operator vector<MediumLevelILInstruction>() const
}
+MediumLevelILInstructionList::operator vector<ExprId>() const
+{
+ vector<ExprId> result;
+ result.reserve(size());
+ for (auto i : *this)
+ result.push_back(i.exprIndex);
+ return result;
+}
+
+
MediumLevelILOperand::MediumLevelILOperand(
const MediumLevelILInstruction& instr, MediumLevelILOperandUsage usage, size_t operandIndex) :
m_instr(instr),
@@ -787,6 +801,8 @@ MediumLevelILInstructionList MediumLevelILOperand::GetExprList() const
return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsExprList(0);
if (m_usage == UntypedParameterSSAExprsMediumLevelOperandUsage)
return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsExprList(1);
+ if (m_usage == OutputExprsSubExprMediumLevelOperandUsage)
+ return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsExprList(1);
return m_instr.GetRawOperandAsExprList(m_operandIndex);
}
@@ -1379,57 +1395,81 @@ void MediumLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const Medi
break;
case MLIL_CALL:
GetDestExpr<MLIL_CALL>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_CALL>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_CALL>())
i.VisitExprs(func);
break;
case MLIL_CALL_UNTYPED:
GetDestExpr<MLIL_CALL_UNTYPED>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_CALL_UNTYPED>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_CALL_UNTYPED>())
i.VisitExprs(func);
break;
case MLIL_CALL_SSA:
GetDestExpr<MLIL_CALL_SSA>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_CALL_SSA>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_CALL_SSA>())
i.VisitExprs(func);
break;
case MLIL_CALL_UNTYPED_SSA:
GetDestExpr<MLIL_CALL_UNTYPED_SSA>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_CALL_UNTYPED_SSA>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_CALL_UNTYPED_SSA>())
i.VisitExprs(func);
break;
case MLIL_SYSCALL:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_SYSCALL>())
i.VisitExprs(func);
break;
case MLIL_SYSCALL_UNTYPED:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL_UNTYPED>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_SYSCALL_UNTYPED>())
i.VisitExprs(func);
break;
case MLIL_SYSCALL_SSA:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL_SSA>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_SYSCALL_SSA>())
i.VisitExprs(func);
break;
case MLIL_SYSCALL_UNTYPED_SSA:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL_UNTYPED_SSA>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_SYSCALL_UNTYPED_SSA>())
i.VisitExprs(func);
break;
case MLIL_TAILCALL:
GetDestExpr<MLIL_TAILCALL>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_TAILCALL>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_TAILCALL>())
i.VisitExprs(func);
break;
case MLIL_TAILCALL_UNTYPED:
GetDestExpr<MLIL_TAILCALL_UNTYPED>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_TAILCALL_UNTYPED>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_TAILCALL_UNTYPED>())
i.VisitExprs(func);
break;
case MLIL_TAILCALL_SSA:
GetDestExpr<MLIL_TAILCALL_SSA>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_TAILCALL_SSA>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_TAILCALL_SSA>())
i.VisitExprs(func);
break;
case MLIL_TAILCALL_UNTYPED_SSA:
GetDestExpr<MLIL_TAILCALL_UNTYPED_SSA>().VisitExprs(func);
+ for (auto i : GetOutputExprs<MLIL_TAILCALL_UNTYPED_SSA>())
+ i.VisitExprs(func);
for (auto i : GetParameterExprs<MLIL_TAILCALL_UNTYPED_SSA>())
i.VisitExprs(func);
break;
@@ -1569,7 +1609,7 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
bn::base::function_ref<ExprId(const MediumLevelILInstruction& subExpr)> subExprHandler,
const ILSourceLocation& sourceLocation) const
{
- vector<ExprId> params;
+ vector<ExprId> output, params;
BNMediumLevelILLabel* labelA;
BNMediumLevelILLabel* labelB;
@@ -1629,6 +1669,8 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
case MLIL_VAR_SPLIT_SSA:
return dest->VarSplitSSA(
size, GetHighSSAVariable<MLIL_VAR_SPLIT_SSA>(), GetLowSSAVariable<MLIL_VAR_SPLIT_SSA>(), loc);
+ case MLIL_VAR_OUTPUT_SSA:
+ return dest->VarOutputSSA(size, GetDestSSAVariable<MLIL_VAR_OUTPUT_SSA>(), loc);
case MLIL_FORCE_VER:
return dest->ForceVer(size, GetDestVariable<MLIL_FORCE_VER>(), GetSourceVariable<MLIL_FORCE_VER>(), loc);
case MLIL_FORCE_VER_SSA:
@@ -1643,69 +1685,93 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
return dest->AddressOfField(
GetSourceVariable<MLIL_ADDRESS_OF_FIELD>(), GetOffset<MLIL_ADDRESS_OF_FIELD>(), loc);
case MLIL_CALL:
+ for (auto i : GetOutputExprs<MLIL_CALL>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_CALL>())
params.push_back(subExprHandler(i));
- return dest->Call(GetOutputVariables<MLIL_CALL>(), subExprHandler(GetDestExpr<MLIL_CALL>()), params, loc);
+ return dest->Call(output, subExprHandler(GetDestExpr<MLIL_CALL>()), params, loc);
case MLIL_CALL_UNTYPED:
+ for (auto i : GetOutputExprs<MLIL_CALL_UNTYPED>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_CALL_UNTYPED>())
params.push_back(subExprHandler(i));
- return dest->CallUntyped(GetOutputVariables<MLIL_CALL_UNTYPED>(),
+ return dest->CallUntyped(output,
subExprHandler(GetDestExpr<MLIL_CALL_UNTYPED>()), params,
subExprHandler(GetStackExpr<MLIL_CALL_UNTYPED>()), loc);
case MLIL_CALL_SSA:
+ for (auto i : GetOutputExprs<MLIL_CALL_SSA>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_CALL_SSA>())
params.push_back(subExprHandler(i));
- return dest->CallSSA(GetOutputSSAVariables<MLIL_CALL_SSA>(), subExprHandler(GetDestExpr<MLIL_CALL_SSA>()),
+ return dest->CallSSA(output, subExprHandler(GetDestExpr<MLIL_CALL_SSA>()),
params, GetDestMemoryVersion<MLIL_CALL_SSA>(), GetSourceMemoryVersion<MLIL_CALL_SSA>(), loc);
case MLIL_CALL_UNTYPED_SSA:
+ for (auto i : GetOutputExprs<MLIL_CALL_UNTYPED_SSA>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_CALL_UNTYPED_SSA>())
params.push_back(subExprHandler(i));
- return dest->CallUntypedSSA(GetOutputSSAVariables<MLIL_CALL_UNTYPED_SSA>(),
+ return dest->CallUntypedSSA(output,
subExprHandler(GetDestExpr<MLIL_CALL_UNTYPED_SSA>()), params,
GetDestMemoryVersion<MLIL_CALL_UNTYPED_SSA>(), GetSourceMemoryVersion<MLIL_CALL_UNTYPED_SSA>(),
subExprHandler(GetStackExpr<MLIL_CALL_UNTYPED_SSA>()), loc);
case MLIL_SYSCALL:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_SYSCALL>())
params.push_back(subExprHandler(i));
- return dest->Syscall(GetOutputVariables<MLIL_SYSCALL>(), params, loc);
+ return dest->Syscall(output, params, loc);
case MLIL_SYSCALL_UNTYPED:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL_UNTYPED>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_SYSCALL_UNTYPED>())
params.push_back(subExprHandler(i));
- return dest->SyscallUntyped(GetOutputVariables<MLIL_SYSCALL_UNTYPED>(),
+ return dest->SyscallUntyped(output,
params, subExprHandler(GetStackExpr<MLIL_SYSCALL_UNTYPED>()), loc);
case MLIL_SYSCALL_SSA:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL_SSA>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_SYSCALL_SSA>())
params.push_back(subExprHandler(i));
- return dest->SyscallSSA(GetOutputSSAVariables<MLIL_SYSCALL_SSA>(), params,
+ return dest->SyscallSSA(output, params,
GetDestMemoryVersion<MLIL_SYSCALL_SSA>(), GetSourceMemoryVersion<MLIL_SYSCALL_SSA>(), loc);
case MLIL_SYSCALL_UNTYPED_SSA:
+ for (auto i : GetOutputExprs<MLIL_SYSCALL_UNTYPED_SSA>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_SYSCALL_UNTYPED_SSA>())
params.push_back(subExprHandler(i));
- return dest->SyscallUntypedSSA(GetOutputSSAVariables<MLIL_SYSCALL_UNTYPED_SSA>(),
+ return dest->SyscallUntypedSSA(output,
params, GetDestMemoryVersion<MLIL_SYSCALL_UNTYPED_SSA>(),
GetSourceMemoryVersion<MLIL_SYSCALL_UNTYPED_SSA>(),
subExprHandler(GetStackExpr<MLIL_SYSCALL_UNTYPED_SSA>()), loc);
case MLIL_TAILCALL:
+ for (auto i : GetOutputExprs<MLIL_TAILCALL>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_TAILCALL>())
params.push_back(subExprHandler(i));
return dest->TailCall(
- GetOutputVariables<MLIL_TAILCALL>(), subExprHandler(GetDestExpr<MLIL_TAILCALL>()), params, loc);
+ output, subExprHandler(GetDestExpr<MLIL_TAILCALL>()), params, loc);
case MLIL_TAILCALL_UNTYPED:
+ for (auto i : GetOutputExprs<MLIL_TAILCALL_UNTYPED>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_TAILCALL_UNTYPED>())
params.push_back(subExprHandler(i));
- return dest->TailCallUntyped(GetOutputVariables<MLIL_TAILCALL_UNTYPED>(),
+ return dest->TailCallUntyped(output,
subExprHandler(GetDestExpr<MLIL_TAILCALL_UNTYPED>()), params,
subExprHandler(GetStackExpr<MLIL_TAILCALL_UNTYPED>()), loc);
case MLIL_TAILCALL_SSA:
+ for (auto i : GetOutputExprs<MLIL_TAILCALL_SSA>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_TAILCALL_SSA>())
params.push_back(subExprHandler(i));
- return dest->TailCallSSA(GetOutputSSAVariables<MLIL_TAILCALL_SSA>(),
+ return dest->TailCallSSA(output,
subExprHandler(GetDestExpr<MLIL_TAILCALL_SSA>()), params, GetDestMemoryVersion<MLIL_TAILCALL_SSA>(),
GetSourceMemoryVersion<MLIL_TAILCALL_SSA>(), loc);
case MLIL_TAILCALL_UNTYPED_SSA:
+ for (auto i : GetOutputExprs<MLIL_TAILCALL_UNTYPED_SSA>())
+ output.push_back(subExprHandler(i));
for (auto i : GetParameterExprs<MLIL_TAILCALL_UNTYPED_SSA>())
params.push_back(subExprHandler(i));
- return dest->TailCallUntypedSSA(GetOutputSSAVariables<MLIL_TAILCALL_UNTYPED_SSA>(),
+ return dest->TailCallUntypedSSA(output,
subExprHandler(GetDestExpr<MLIL_TAILCALL_UNTYPED_SSA>()),
params, GetDestMemoryVersion<MLIL_TAILCALL_UNTYPED_SSA>(),
GetSourceMemoryVersion<MLIL_TAILCALL_UNTYPED_SSA>(),
@@ -1718,6 +1784,8 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
for (auto i : GetParameterExprs<MLIL_SHARED_PARAM_SLOT>())
params.push_back(subExprHandler(i));
return dest->SharedParamSlot(params, loc);
+ case MLIL_VAR_OUTPUT:
+ return dest->VarOutput(size, GetDestVariable<MLIL_VAR_OUTPUT>(), loc);
case MLIL_RET:
for (auto i : GetSourceExprs<MLIL_RET>())
params.push_back(subExprHandler(i));
@@ -2165,24 +2233,39 @@ MediumLevelILIndexList MediumLevelILInstruction::GetSourceMemoryVersions() const
}
-MediumLevelILVariableList MediumLevelILInstruction::GetOutputVariables() const
+vector<Variable> MediumLevelILInstruction::GetOutputVariables() const
{
size_t operandIndex;
if (GetOperandIndexForUsage(OutputVariablesMediumLevelOperandUsage, operandIndex))
return GetRawOperandAsVariableList(operandIndex);
if (GetOperandIndexForUsage(OutputVariablesSubExprMediumLevelOperandUsage, operandIndex))
return GetRawOperandAsExpr(operandIndex).GetRawOperandAsVariableList(0);
+ if (GetOperandIndexForUsage(OutputExprsMediumLevelOperandUsage, operandIndex))
+ return reinterpret_cast<const MediumLevelILCallInstruction*>(this)->GetOutputVariables();
throw MediumLevelILInstructionAccessException();
}
-MediumLevelILSSAVariableList MediumLevelILInstruction::GetOutputSSAVariables() const
+vector<SSAVariable> MediumLevelILInstruction::GetOutputSSAVariables() const
{
size_t operandIndex;
if (GetOperandIndexForUsage(OutputSSAVariablesMediumLevelOperandUsage, operandIndex))
return GetRawOperandAsSSAVariableList(operandIndex);
if (GetOperandIndexForUsage(OutputSSAVariablesSubExprMediumLevelOperandUsage, operandIndex))
return GetRawOperandAsExpr(operandIndex).GetRawOperandAsSSAVariableList(1);
+ if (GetOperandIndexForUsage(OutputExprsSubExprMediumLevelOperandUsage, operandIndex))
+ return reinterpret_cast<const MediumLevelILCallSSAInstruction*>(this)->GetOutputSSAVariables();
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstructionList MediumLevelILInstruction::GetOutputExprs() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(OutputExprsMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExprList(operandIndex);
+ if (GetOperandIndexForUsage(OutputExprsSubExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsExprList(1);
throw MediumLevelILInstructionAccessException();
}
@@ -2218,6 +2301,30 @@ MediumLevelILSSAVariableList MediumLevelILInstruction::GetSourceSSAVariables() c
}
+vector<Variable> MediumLevelILCallInstruction::GetOutputVariables() const
+{
+ vector<Variable> result;
+ for (auto i : GetOutputExprs())
+ {
+ if (i.operation == MLIL_VAR_OUTPUT)
+ result.push_back(i.GetDestVariable<MLIL_VAR_OUTPUT>());
+ }
+ return result;
+}
+
+
+vector<SSAVariable> MediumLevelILCallSSAInstruction::GetOutputSSAVariables() const
+{
+ vector<SSAVariable> result;
+ for (auto i : GetOutputExprs())
+ {
+ if (i.operation == MLIL_VAR_OUTPUT_SSA)
+ result.push_back(i.GetDestSSAVariable<MLIL_VAR_OUTPUT_SSA>());
+ }
+ return result;
+}
+
+
ExprId MediumLevelILFunction::Nop(const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_NOP, loc, 0);
@@ -2412,6 +2519,12 @@ ExprId MediumLevelILFunction::VarSplitSSA(
}
+ExprId MediumLevelILFunction::VarOutputSSA(size_t size, const SSAVariable& dest, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_OUTPUT_SSA, loc, size, dest.var.ToIdentifier(), dest.version);
+}
+
+
ExprId MediumLevelILFunction::AddressOf(const Variable& var, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_ADDRESS_OF, loc, 0, var.ToIdentifier());
@@ -2689,111 +2802,111 @@ ExprId MediumLevelILFunction::ReturnHint(ExprId dest, const ILSourceLocation& lo
ExprId MediumLevelILFunction::Call(
- const vector<Variable>& output, ExprId dest, const vector<ExprId>& params, const ILSourceLocation& loc)
+ const vector<ExprId>& output, ExprId dest, const vector<ExprId>& params, const ILSourceLocation& loc)
{
return AddExprWithLocation(
- MLIL_CALL, loc, 0, output.size(), AddVariableList(output), dest, params.size(), AddOperandList(params));
+ MLIL_CALL, loc, 0, output.size(), AddOperandList(output), dest, params.size(), AddOperandList(params));
}
-ExprId MediumLevelILFunction::CallUntyped(const vector<Variable>& output, ExprId dest, const vector<ExprId>& params,
+ExprId MediumLevelILFunction::CallUntyped(const vector<ExprId>& output, ExprId dest, const vector<ExprId>& params,
ExprId stack, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_CALL_UNTYPED, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT, loc, 0, output.size(), AddVariableList(output)), dest,
+ output.size(), AddOperandList(output), dest,
AddExprWithLocation(MLIL_CALL_PARAM, loc, 0, params.size(), AddOperandList(params)), stack);
}
ExprId MediumLevelILFunction::Syscall(
- const vector<Variable>& output, const vector<ExprId>& params, const ILSourceLocation& loc)
+ const vector<ExprId>& output, const vector<ExprId>& params, const ILSourceLocation& loc)
{
return AddExprWithLocation(
- MLIL_SYSCALL, loc, 0, output.size(), AddVariableList(output), params.size(), AddOperandList(params));
+ MLIL_SYSCALL, loc, 0, output.size(), AddOperandList(output), params.size(), AddOperandList(params));
}
ExprId MediumLevelILFunction::SyscallUntyped(
- const vector<Variable>& output, const vector<ExprId>& params, ExprId stack, const ILSourceLocation& loc)
+ const vector<ExprId>& output, const vector<ExprId>& params, ExprId stack, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_SYSCALL_UNTYPED, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT, loc, 0, output.size(), AddVariableList(output)),
+ output.size(), AddOperandList(output),
AddExprWithLocation(MLIL_CALL_PARAM, loc, 0, params.size(), AddOperandList(params)), stack);
}
ExprId MediumLevelILFunction::TailCall(
- const vector<Variable>& output, ExprId dest, const vector<ExprId>& params, const ILSourceLocation& loc)
+ const vector<ExprId>& output, ExprId dest, const vector<ExprId>& params, const ILSourceLocation& loc)
{
return AddExprWithLocation(
- MLIL_TAILCALL, loc, 0, output.size(), AddVariableList(output), dest, params.size(), AddOperandList(params));
+ MLIL_TAILCALL, loc, 0, output.size(), AddOperandList(output), dest, params.size(), AddOperandList(params));
}
-ExprId MediumLevelILFunction::TailCallUntyped(const vector<Variable>& output, ExprId dest,
+ExprId MediumLevelILFunction::TailCallUntyped(const vector<ExprId>& output, ExprId dest,
const vector<ExprId>& params, ExprId stack, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_TAILCALL_UNTYPED, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT, loc, 0, output.size(), AddVariableList(output)), dest,
+ output.size(), AddOperandList(output), dest,
AddExprWithLocation(MLIL_CALL_PARAM, loc, 0, params.size(), AddOperandList(params)), stack);
}
-ExprId MediumLevelILFunction::CallSSA(const vector<SSAVariable>& output, ExprId dest, const vector<ExprId>& params,
+ExprId MediumLevelILFunction::CallSSA(const vector<ExprId>& output, ExprId dest, const vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_CALL_SSA, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size() * 2, AddSSAVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size(), AddOperandList(output)),
dest, params.size(), AddOperandList(params), prevMemVersion);
}
-ExprId MediumLevelILFunction::CallUntypedSSA(const vector<SSAVariable>& output, ExprId dest,
+ExprId MediumLevelILFunction::CallUntypedSSA(const vector<ExprId>& output, ExprId dest,
const vector<ExprId>& params, size_t newMemVersion, size_t prevMemVersion, ExprId stack,
const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_CALL_UNTYPED_SSA, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size() * 2, AddSSAVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size(), AddOperandList(output)),
dest,
AddExprWithLocation(MLIL_CALL_PARAM_SSA, loc, 0, prevMemVersion, params.size(), AddOperandList(params)),
stack);
}
-ExprId MediumLevelILFunction::SyscallSSA(const vector<SSAVariable>& output, const vector<ExprId>& params,
+ExprId MediumLevelILFunction::SyscallSSA(const vector<ExprId>& output, const vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_SYSCALL_SSA, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size() * 2, AddSSAVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size(), AddOperandList(output)),
params.size(), AddOperandList(params), prevMemVersion);
}
-ExprId MediumLevelILFunction::SyscallUntypedSSA(const vector<SSAVariable>& output, const vector<ExprId>& params,
+ExprId MediumLevelILFunction::SyscallUntypedSSA(const vector<ExprId>& output, const vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, ExprId stack, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_SYSCALL_UNTYPED_SSA, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size() * 2, AddSSAVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size(), AddOperandList(output)),
AddExprWithLocation(MLIL_CALL_PARAM_SSA, loc, 0, prevMemVersion, params.size(), AddOperandList(params)),
stack);
}
-ExprId MediumLevelILFunction::TailCallSSA(const vector<SSAVariable>& output, ExprId dest, const vector<ExprId>& params,
+ExprId MediumLevelILFunction::TailCallSSA(const vector<ExprId>& output, ExprId dest, const vector<ExprId>& params,
size_t newMemVersion, size_t prevMemVersion, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_TAILCALL_SSA, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size() * 2, AddSSAVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size(), AddOperandList(output)),
dest, params.size(), AddOperandList(params), prevMemVersion);
}
-ExprId MediumLevelILFunction::TailCallUntypedSSA(const vector<SSAVariable>& output, ExprId dest,
+ExprId MediumLevelILFunction::TailCallUntypedSSA(const vector<ExprId>& output, ExprId dest,
const vector<ExprId>& params, size_t newMemVersion, size_t prevMemVersion, ExprId stack,
const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_TAILCALL_UNTYPED_SSA, loc, 0,
- AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size() * 2, AddSSAVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_OUTPUT_SSA, loc, 0, newMemVersion, output.size(), AddOperandList(output)),
dest,
AddExprWithLocation(MLIL_CALL_PARAM_SSA, loc, 0, prevMemVersion, params.size(), AddOperandList(params)),
stack);
@@ -2812,6 +2925,12 @@ ExprId MediumLevelILFunction::SharedParamSlot(const vector<ExprId>& params, cons
}
+ExprId MediumLevelILFunction::VarOutput(size_t size, const Variable& var, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_OUTPUT, loc, size, var.ToIdentifier());
+}
+
+
ExprId MediumLevelILFunction::Return(const vector<ExprId>& sources, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_RET, loc, 0, sources.size(), AddOperandList(sources));
diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h
index 3d7da6b9..c7663269 100644
--- a/mediumlevelilinstruction.h
+++ b/mediumlevelilinstruction.h
@@ -143,8 +143,10 @@ namespace BinaryNinja
SourceMemoryVersionsMediumLevelOperandUsage,
OutputVariablesMediumLevelOperandUsage,
OutputVariablesSubExprMediumLevelOperandUsage,
+ OutputExprsMediumLevelOperandUsage,
OutputSSAVariablesMediumLevelOperandUsage,
OutputSSAVariablesSubExprMediumLevelOperandUsage,
+ OutputExprsSubExprMediumLevelOperandUsage,
OutputSSAMemoryVersionMediumLevelOperandUsage,
ParameterExprsMediumLevelOperandUsage,
SourceExprsMediumLevelOperandUsage,
@@ -477,6 +479,7 @@ namespace BinaryNinja
const MediumLevelILInstruction operator[](size_t i) const;
operator _STD_VECTOR<MediumLevelILInstruction>() const;
+ operator _STD_VECTOR<ExprId>() const;
};
/*!
@@ -763,16 +766,21 @@ namespace BinaryNinja
return As<N>().GetSourceMemoryVersions();
}
template <BNMediumLevelILOperation N>
- MediumLevelILVariableList GetOutputVariables() const
+ _STD_VECTOR<Variable> GetOutputVariables() const
{
return As<N>().GetOutputVariables();
}
template <BNMediumLevelILOperation N>
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
+ _STD_VECTOR<SSAVariable> GetOutputSSAVariables() const
{
return As<N>().GetOutputSSAVariables();
}
template <BNMediumLevelILOperation N>
+ MediumLevelILInstructionList GetOutputExprs() const
+ {
+ return As<N>().GetOutputExprs();
+ }
+ template <BNMediumLevelILOperation N>
MediumLevelILInstructionList GetParameterExprs() const
{
return As<N>().GetParameterExprs();
@@ -829,6 +837,11 @@ namespace BinaryNinja
As<N>().SetOutputSSAVariables(vars);
}
template <BNMediumLevelILOperation N>
+ void SetOutputExprs(const _STD_VECTOR<MediumLevelILInstruction>& outputs)
+ {
+ As<N>().SetOutputExprs(outputs);
+ }
+ template <BNMediumLevelILOperation N>
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
As<N>().SetParameterExprs(params);
@@ -880,8 +893,9 @@ namespace BinaryNinja
size_t GetSourceMemoryVersion() const;
MediumLevelILIndexMap GetTargets() const;
MediumLevelILIndexList GetSourceMemoryVersions() const;
- MediumLevelILVariableList GetOutputVariables() const;
- MediumLevelILSSAVariableList GetOutputSSAVariables() const;
+ _STD_VECTOR<Variable> GetOutputVariables() const;
+ _STD_VECTOR<SSAVariable> GetOutputSSAVariables() const;
+ MediumLevelILInstructionList GetOutputExprs() const;
MediumLevelILInstructionList GetParameterExprs() const;
MediumLevelILInstructionList GetSourceExprs() const;
MediumLevelILSSAVariableList GetSourceSSAVariables() const;
@@ -1006,6 +1020,33 @@ namespace BinaryNinja
MediumLevelILInstruction GetCarryExpr() const { return GetRawOperandAsExpr(2); }
};
+ /*!
+ \ingroup mediumlevelil
+ */
+ struct MediumLevelILCallInstruction : public MediumLevelILInstructionBase
+ {
+ MediumLevelILInstructionList GetOutputExprs() const { return GetRawOperandAsExprList(0); }
+ _STD_VECTOR<Variable> GetOutputVariables() const;
+ };
+
+ /*!
+ \ingroup mediumlevelil
+ */
+ struct MediumLevelILCallSSAInstruction : public MediumLevelILInstructionBase
+ {
+ MediumLevelILInstructionList GetOutputExprs() const
+ {
+ return GetRawOperandAsExpr(0).GetRawOperandAsExprList(1);
+ }
+
+ _STD_VECTOR<SSAVariable> GetOutputSSAVariables() const;
+
+ void SetOutputExprs(const _STD_VECTOR<MediumLevelILInstruction>& outputs)
+ {
+ GetRawOperandAsExpr(0).UpdateRawOperandAsExprList(1, outputs);
+ }
+ };
+
// Implementations of each instruction to fetch the correct operand value for the valid operands, these
// are derived from MediumLevelILInstructionBase so that invalid operand accessor functions will generate
// a compiler error.
@@ -1190,6 +1231,12 @@ namespace BinaryNinja
void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); }
};
template <>
+ struct MediumLevelILInstructionAccessor<MLIL_VAR_OUTPUT_SSA> : public MediumLevelILInstructionBase
+ {
+ SSAVariable GetDestSSAVariable() const { return GetRawOperandAsSSAVariable(0); }
+ void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); }
+ };
+ template <>
struct MediumLevelILInstructionAccessor<MLIL_VAR_SSA_FIELD> : public MediumLevelILInstructionBase
{
SSAVariable GetSourceSSAVariable() const { return GetRawOperandAsSSAVariable(0); }
@@ -1248,65 +1295,50 @@ namespace BinaryNinja
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_CALL> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_CALL> : public MediumLevelILCallInstruction
{
- MediumLevelILVariableList GetOutputVariables() const { return GetRawOperandAsVariableList(0); }
MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(2); }
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(3); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_CALL_UNTYPED> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_CALL_UNTYPED> : public MediumLevelILCallInstruction
{
- MediumLevelILVariableList GetOutputVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsVariableList(0);
- }
- MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); }
+ MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(2); }
MediumLevelILInstructionList GetParameterExprs() const
{
- return GetRawOperandAsExpr(2).GetRawOperandAsExprList(0);
+ return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0);
}
- MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); }
+ MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(4); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_SYSCALL> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_SYSCALL> : public MediumLevelILCallInstruction
{
- MediumLevelILVariableList GetOutputVariables() const { return GetRawOperandAsVariableList(0); }
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(2); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_SYSCALL_UNTYPED> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_SYSCALL_UNTYPED> : public MediumLevelILCallInstruction
{
- MediumLevelILVariableList GetOutputVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsVariableList(0);
- }
MediumLevelILInstructionList GetParameterExprs() const
{
- return GetRawOperandAsExpr(1).GetRawOperandAsExprList(0);
+ return GetRawOperandAsExpr(2).GetRawOperandAsExprList(0);
}
- MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(2); }
+ MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_TAILCALL> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_TAILCALL> : public MediumLevelILCallInstruction
{
- MediumLevelILVariableList GetOutputVariables() const { return GetRawOperandAsVariableList(0); }
MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(2); }
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(3); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_UNTYPED> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_UNTYPED> : public MediumLevelILCallInstruction
{
- MediumLevelILVariableList GetOutputVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsVariableList(0);
- }
- MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); }
+ MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(2); }
MediumLevelILInstructionList GetParameterExprs() const
{
- return GetRawOperandAsExpr(2).GetRawOperandAsExprList(0);
+ return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0);
}
- MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); }
+ MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(4); }
};
template <>
struct MediumLevelILInstructionAccessor<MLIL_SEPARATE_PARAM_LIST> : public MediumLevelILInstructionBase
@@ -1318,24 +1350,21 @@ namespace BinaryNinja
{
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(0); }
};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_VAR_OUTPUT> : public MediumLevelILInstructionBase
+ {
+ Variable GetDestVariable() const { return GetRawOperandAsVariable(0); }
+ };
template <>
- struct MediumLevelILInstructionAccessor<MLIL_CALL_SSA> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_CALL_SSA> : public MediumLevelILCallSSAInstruction
{
size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); }
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1);
- }
MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); }
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(2); }
size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(4); }
void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); }
void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(4, version); }
- void SetOutputSSAVariables(const _STD_VECTOR<SSAVariable>& vars)
- {
- GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars);
- }
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
UpdateRawOperandAsExprList(2, params);
@@ -1343,13 +1372,9 @@ namespace BinaryNinja
void SetParameterExprs(const _STD_VECTOR<ExprId>& params) { UpdateRawOperandAsExprList(2, params); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_CALL_UNTYPED_SSA> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_CALL_UNTYPED_SSA> : public MediumLevelILCallSSAInstruction
{
size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); }
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1);
- }
MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); }
MediumLevelILInstructionList GetParameterExprs() const
{
@@ -1359,10 +1384,6 @@ namespace BinaryNinja
MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); }
void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); }
void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(0, version); }
- void SetOutputSSAVariables(const _STD_VECTOR<SSAVariable>& vars)
- {
- GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars);
- }
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
GetRawOperandAsExpr(2).UpdateRawOperandAsExprList(1, params);
@@ -1373,21 +1394,13 @@ namespace BinaryNinja
}
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_SYSCALL_SSA> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_SYSCALL_SSA> : public MediumLevelILCallSSAInstruction
{
size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); }
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1);
- }
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(1); }
size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(3); }
void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); }
void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(3, version); }
- void SetOutputSSAVariables(const _STD_VECTOR<SSAVariable>& vars)
- {
- GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars);
- }
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
UpdateRawOperandAsExprList(1, params);
@@ -1395,13 +1408,9 @@ namespace BinaryNinja
void SetParameterExprs(const _STD_VECTOR<ExprId>& params) { UpdateRawOperandAsExprList(1, params); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_SYSCALL_UNTYPED_SSA> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_SYSCALL_UNTYPED_SSA> : public MediumLevelILCallSSAInstruction
{
size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); }
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1);
- }
MediumLevelILInstructionList GetParameterExprs() const
{
return GetRawOperandAsExpr(1).GetRawOperandAsExprList(1);
@@ -1410,10 +1419,6 @@ namespace BinaryNinja
MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(2); }
void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); }
void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(1).UpdateRawOperand(0, version); }
- void SetOutputSSAVariables(const _STD_VECTOR<SSAVariable>& vars)
- {
- GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars);
- }
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
GetRawOperandAsExpr(1).UpdateRawOperandAsExprList(1, params);
@@ -1424,22 +1429,14 @@ namespace BinaryNinja
}
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_SSA> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_SSA> : public MediumLevelILCallSSAInstruction
{
size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); }
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1);
- }
MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); }
MediumLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(2); }
size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(4); }
void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); }
void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(4, version); }
- void SetOutputSSAVariables(const _STD_VECTOR<SSAVariable>& vars)
- {
- GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars);
- }
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
UpdateRawOperandAsExprList(2, params);
@@ -1447,13 +1444,9 @@ namespace BinaryNinja
void SetParameterExprs(const _STD_VECTOR<ExprId>& params) { UpdateRawOperandAsExprList(2, params); }
};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_UNTYPED_SSA> : public MediumLevelILInstructionBase
+ struct MediumLevelILInstructionAccessor<MLIL_TAILCALL_UNTYPED_SSA> : public MediumLevelILCallSSAInstruction
{
size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); }
- MediumLevelILSSAVariableList GetOutputSSAVariables() const
- {
- return GetRawOperandAsExpr(0).GetRawOperandAsSSAVariableList(1);
- }
MediumLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); }
MediumLevelILInstructionList GetParameterExprs() const
{
@@ -1463,10 +1456,6 @@ namespace BinaryNinja
MediumLevelILInstruction GetStackExpr() const { return GetRawOperandAsExpr(3); }
void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); }
void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(0, version); }
- void SetOutputSSAVariables(const _STD_VECTOR<SSAVariable>& vars)
- {
- GetRawOperandAsExpr(0).UpdateRawOperandAsSSAVariableList(1, vars);
- }
void SetParameterExprs(const _STD_VECTOR<MediumLevelILInstruction>& params)
{
GetRawOperandAsExpr(2).UpdateRawOperandAsExprList(1, params);
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 84ef1382..1a42fe27 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -62,6 +62,7 @@ MediumLevelILVisitorCallback = Callable[[str, MediumLevelILOperandType, str, Opt
StringOrType = Union[str, '_types.Type', '_types.TypeBuilder']
ILInstructionAttributeSet = Union[Set[ILInstructionAttribute], List[ILInstructionAttribute]]
LLILSSAToMLILInstructionMapping = MutableMapping['lowlevelil.InstructionIndex', InstructionIndex]
+CallOutputList = Union[List[ExpressionIndex], List['variable.CoreVariable']]
@dataclass(frozen=True)
@@ -267,16 +268,18 @@ class MediumLevelILInstruction(BaseILInstruction):
], MediumLevelILOperation.MLIL_JUMP: [("dest", "expr")], MediumLevelILOperation.MLIL_JUMP_TO: [
("dest", "expr"), ("targets", "target_map")
], MediumLevelILOperation.MLIL_RET_HINT: [("dest", "expr")], MediumLevelILOperation.MLIL_CALL: [
- ("output", "var_list"), ("dest", "expr"), ("params", "expr_list")
+ ("output", "expr_list"), ("dest", "expr"), ("params", "expr_list")
], MediumLevelILOperation.MLIL_CALL_UNTYPED: [
- ("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")
- ], MediumLevelILOperation.MLIL_CALL_OUTPUT: [("dest", "var_list")], MediumLevelILOperation.MLIL_CALL_PARAM: [
+ ("output", "expr_list"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")
+ ], MediumLevelILOperation.MLIL_CALL_PARAM: [
("src", "expr_list")
], MediumLevelILOperation.MLIL_SEPARATE_PARAM_LIST: [
("params", "expr_list")
], MediumLevelILOperation.MLIL_SHARED_PARAM_SLOT: [
("params", "expr_list")
- ], MediumLevelILOperation.MLIL_RET: [
+ ], MediumLevelILOperation.MLIL_VAR_OUTPUT: [
+ ("dest", "var")
+ ], MediumLevelILOperation.MLIL_RET: [
("src", "expr_list")
], MediumLevelILOperation.MLIL_NORET: [], MediumLevelILOperation.MLIL_IF: [
("condition", "expr"), ("true", "int"), ("false", "int")
@@ -304,12 +307,12 @@ class MediumLevelILInstruction(BaseILInstruction):
MediumLevelILOperation.MLIL_BOOL_TO_INT: [("src", "expr")], MediumLevelILOperation.MLIL_ADD_OVERFLOW: [
("left", "expr"), ("right", "expr")
], MediumLevelILOperation.MLIL_SYSCALL: [
- ("output", "var_list"), ("params", "expr_list")
+ ("output", "expr_list"), ("params", "expr_list")
], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED: [
- ("output", "expr"), ("params", "expr"), ("stack", "expr")
+ ("output", "expr_list"), ("params", "expr"), ("stack", "expr")
], MediumLevelILOperation.MLIL_TAILCALL: [
- ("output", "var_list"), ("dest", "expr"), ("params", "expr_list")
- ], MediumLevelILOperation.MLIL_TAILCALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"),
+ ("output", "expr_list"), ("dest", "expr"), ("params", "expr_list")
+ ], MediumLevelILOperation.MLIL_TAILCALL_UNTYPED: [("output", "expr_list"), ("dest", "expr"), ("params", "expr"),
("stack", "expr")], MediumLevelILOperation.MLIL_BP: [],
MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], MediumLevelILOperation.MLIL_INTRINSIC: [
("output", "var_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")
@@ -372,7 +375,9 @@ class MediumLevelILInstruction(BaseILInstruction):
("src", "var_ssa"), ("offset", "int")
], MediumLevelILOperation.MLIL_VAR_SPLIT_SSA: [
("high", "var_ssa"), ("low", "var_ssa")
- ], MediumLevelILOperation.MLIL_CALL_SSA: [
+ ], MediumLevelILOperation.MLIL_VAR_OUTPUT_SSA: [
+ ("dest", "var_ssa")
+ ], MediumLevelILOperation.MLIL_CALL_SSA: [
("output", "expr"), ("output_dest_memory", "int"), ("dest", "expr"),
("params", "expr_list"), ("src_memory", "int")
], MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [
@@ -845,11 +850,11 @@ class MediumLevelILInstruction(BaseILInstruction):
core.BNFreePossibleValueSet(value)
return result
- def get_ssa_var_version(self, var: variable.Variable) -> int:
+ def get_ssa_var_version(self, var: variable.CoreVariable) -> int:
var_data = var.to_BNVariable()
return core.BNGetMediumLevelILSSAVarVersionAtILInstruction(self.function.handle, var_data, self.instr_index)
- def get_ssa_var_version_after(self, var: variable.Variable) -> int:
+ def get_ssa_var_version_after(self, var: variable.CoreVariable) -> int:
var_data = var.to_BNVariable()
return core.BNGetMediumLevelILSSAVarVersionAfterILInstruction(self.function.handle, var_data, self.instr_index)
@@ -996,7 +1001,7 @@ class MediumLevelILInstruction(BaseILInstruction):
core.BNGetMediumLevelILBranchDependence(self.function.handle, self.instr_index, branch_instr)
)
- def get_split_var_for_definition(self, var: variable.Variable) -> variable.Variable:
+ def get_split_var_for_definition(self, var: variable.CoreVariable) -> variable.Variable:
"""
Gets the unique variable for a definition instruction. This unique variable can be passed
to ``Function.split_var`` to split a variable at a definition. The given ``var`` is the
@@ -1152,6 +1157,16 @@ class MediumLevelILInstruction(BaseILInstruction):
core.BNFreePossibleValueSet(value)
return result
+ def _var_written_for_function_call_output(self) -> Optional[variable.Variable]:
+ if isinstance(self, MediumLevelILVarOutput):
+ return self.dest
+ return None
+
+ def _ssa_var_written_for_function_call_output(self) -> Optional[SSAVariable]:
+ if isinstance(self, MediumLevelILVarOutputSsa):
+ return self.dest
+ return None
+
@dataclass(frozen=True, repr=False, eq=False)
class MediumLevelILConstBase(MediumLevelILInstruction, Constant):
@@ -1477,6 +1492,17 @@ class MediumLevelILSharedParamSlot(MediumLevelILInstruction):
@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILVarOutput(MediumLevelILInstruction, RegisterStack):
+ @property
+ def dest(self) -> variable.Variable:
+ return self._get_var(0)
+
+ @property
+ def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
+ return [("dest", self.dest, "Variable")]
+
+
+@dataclass(frozen=True, repr=False, eq=False)
class MediumLevelILRet(MediumLevelILInstruction, Return):
@property
def src(self) -> List[MediumLevelILInstruction]:
@@ -1626,6 +1652,21 @@ class MediumLevelILVarSsa(MediumLevelILInstruction, SSAVariableInstruction):
@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILVarOutputSsa(MediumLevelILInstruction, SSAVariableInstruction):
+ @property
+ def dest(self) -> SSAVariable:
+ return self._get_var_ssa(0, 1)
+
+ @property
+ def var(self) -> SSAVariable:
+ return self._get_var_ssa(0, 1)
+
+ @property
+ def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
+ return [("var", self.var, "SSAVariable")]
+
+
+@dataclass(frozen=True, repr=False, eq=False)
class MediumLevelILVarAliased(MediumLevelILInstruction, SSA, AliasedVariableInstruction):
@property
def src(self) -> SSAVariable:
@@ -1939,7 +1980,16 @@ class MediumLevelILAddOverflow(MediumLevelILBinaryBase, Arithmetic):
class MediumLevelILSyscall(MediumLevelILInstruction, Syscall):
@property
def output(self) -> List[variable.Variable]:
- return self._get_var_list(0, 1)
+ result = []
+ for expr in self.output_exprs:
+ var = expr._var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(0, 1)
@property
def params(self) -> List[MediumLevelILInstruction]:
@@ -2015,7 +2065,16 @@ class MediumLevelILCallOutputSsa(MediumLevelILInstruction, SSA):
@property
def dest(self) -> List[SSAVariable]:
- return self._get_var_ssa_list(1, 2)
+ result = []
+ for expr in self.dest_exprs:
+ var = expr._ssa_var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def dest_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(1, 2)
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
@@ -2251,19 +2310,26 @@ class MediumLevelILSetVarAliased(MediumLevelILInstruction, SetVar, SSA):
class MediumLevelILSyscallUntyped(MediumLevelILCallBase, Syscall):
@property
def output(self) -> List[variable.Variable]:
- inst = self._get_expr(0)
- assert isinstance(inst, MediumLevelILCallOutput), "MediumLevelILCallUntyped return bad type for 'output'"
- return inst.dest
+ result = []
+ for expr in self.output_exprs:
+ var = expr._var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(0, 1)
@property
def params(self) -> List[MediumLevelILInstruction]:
- inst = self._get_expr(1)
+ inst = self._get_expr(2)
assert isinstance(inst, MediumLevelILCallParam), "MediumLevelILCallUntyped return bad type for 'params'"
return inst.src
@property
def stack(self) -> MediumLevelILInstruction:
- return self._get_expr(2)
+ return self._get_expr(3)
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
@@ -2508,6 +2574,12 @@ class MediumLevelILSyscallSsa(MediumLevelILCallBase, Syscall, SSA):
return inst.dest
@property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ inst = self._get_expr(0)
+ assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
+ return inst.dest_exprs
+
+ @property
def output_dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILSyscallSsa return bad type for output"
@@ -2542,6 +2614,12 @@ class MediumLevelILSyscallUntypedSsa(MediumLevelILCallBase, Syscall, SSA):
return inst.dest
@property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ inst = self._get_expr(0)
+ assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
+ return inst.dest_exprs
+
+ @property
def output_dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(
@@ -2700,7 +2778,16 @@ class MediumLevelILRrc(MediumLevelILCarryBase):
class MediumLevelILCall(MediumLevelILCallBase, Localcall):
@property
def output(self) -> List[variable.Variable]:
- return self._get_var_list(0, 1)
+ result = []
+ for expr in self.output_exprs:
+ var = expr._var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(0, 1)
@property
def dest(self) -> MediumLevelILInstruction:
@@ -2746,23 +2833,30 @@ class MediumLevelILIf(MediumLevelILInstruction, Terminal):
class MediumLevelILTailcallUntyped(MediumLevelILCallBase, Tailcall):
@property
def output(self) -> List[variable.Variable]:
- inst = self._get_expr(0)
- assert isinstance(inst, MediumLevelILCallOutput), "MediumLevelILTailcallUntyped return bad type for 'output'"
- return inst.dest
+ result = []
+ for expr in self.output_exprs:
+ var = expr._var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(0, 1)
@property
def dest(self) -> MediumLevelILInstruction:
- return self._get_expr(1)
+ return self._get_expr(2)
@property
def params(self) -> List[MediumLevelILInstruction]:
- inst = self._get_expr(2)
+ inst = self._get_expr(3)
assert isinstance(inst, MediumLevelILCallParam), "MediumLevelILTailcallUntyped return bad type for 'params'"
return inst.src
@property
def stack(self) -> MediumLevelILInstruction:
- return self._get_expr(3)
+ return self._get_expr(4)
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
@@ -2783,6 +2877,12 @@ class MediumLevelILCallSsa(MediumLevelILCallBase, Localcall, SSA):
return inst.dest
@property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ inst = self._get_expr(0)
+ assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
+ return inst.dest_exprs
+
+ @property
def output_dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
@@ -2820,6 +2920,12 @@ class MediumLevelILCallUntypedSsa(MediumLevelILCallBase, Localcall, SSA):
return inst.dest
@property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ inst = self._get_expr(0)
+ assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
+ return inst.dest_exprs
+
+ @property
def output_dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallUntypedSsa return bad type for output"
@@ -2863,7 +2969,16 @@ class MediumLevelILCallUntypedSsa(MediumLevelILCallBase, Localcall, SSA):
class MediumLevelILTailcall(MediumLevelILCallBase, Tailcall):
@property
def output(self) -> List[variable.Variable]:
- return self._get_var_list(0, 1)
+ result = []
+ for expr in self.output_exprs:
+ var = expr._var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(0, 1)
@property
def dest(self) -> MediumLevelILInstruction:
@@ -2891,6 +3006,12 @@ class MediumLevelILTailcallSsa(MediumLevelILCallBase, Tailcall, SSA):
return inst.dest
@property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ inst = self._get_expr(0)
+ assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
+ return inst.dest_exprs
+
+ @property
def output_dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILTailcallSsa return bad type for output"
@@ -2930,6 +3051,12 @@ class MediumLevelILTailcallUntypedSsa(MediumLevelILCallBase, Tailcall, SSA):
return inst.dest
@property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ inst = self._get_expr(0)
+ assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output"
+ return inst.dest_exprs
+
+ @property
def output_dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(
@@ -2996,23 +3123,30 @@ class MediumLevelILStoreSsa(MediumLevelILInstruction, Store, SSA):
class MediumLevelILCallUntyped(MediumLevelILCallBase, Localcall):
@property
def output(self) -> List[variable.Variable]:
- inst = self._get_expr(0)
- assert isinstance(inst, MediumLevelILCallOutput), "MediumLevelILCallUntyped return bad type for 'output'"
- return inst.dest
+ result = []
+ for expr in self.output_exprs:
+ var = expr._var_written_for_function_call_output()
+ if var is not None:
+ result.append(var)
+ return result
+
+ @property
+ def output_exprs(self) -> List[MediumLevelILInstruction]:
+ return self._get_expr_list(0, 1)
@property
def dest(self) -> MediumLevelILInstruction:
- return self._get_expr(1)
+ return self._get_expr(2)
@property
def params(self) -> List[MediumLevelILInstruction]:
- inst = self._get_expr(2)
+ inst = self._get_expr(3)
assert isinstance(inst, MediumLevelILCallParam), "MediumLevelILCallUntyped return bad type for 'params'"
return inst.src
@property
def stack(self) -> MediumLevelILInstruction:
- return self._get_expr(3)
+ return self._get_expr(4)
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
@@ -3147,10 +3281,10 @@ ILInstruction = {
MediumLevelILOperation.MLIL_LOW_PART: MediumLevelILLowPart, # [("src", "expr")],
MediumLevelILOperation.MLIL_JUMP: MediumLevelILJump, # [("dest", "expr")],
MediumLevelILOperation.MLIL_RET_HINT: MediumLevelILRetHint, # [("dest", "expr")],
- MediumLevelILOperation.MLIL_CALL_OUTPUT: MediumLevelILCallOutput, # [("dest", "var_list")],
MediumLevelILOperation.MLIL_CALL_PARAM: MediumLevelILCallParam, # [("src", "expr_list")],
MediumLevelILOperation.MLIL_SEPARATE_PARAM_LIST: MediumLevelILSeparateParamList, # [("src", "expr_list")],
MediumLevelILOperation.MLIL_SHARED_PARAM_SLOT: MediumLevelILSharedParamSlot, # [("src", "expr_list")],
+ MediumLevelILOperation.MLIL_VAR_OUTPUT: MediumLevelILVarOutput, # [("dest", "var")],
MediumLevelILOperation.MLIL_RET: MediumLevelILRet, # [("src", "expr_list")],
MediumLevelILOperation.MLIL_GOTO: MediumLevelILGoto, # [("dest", "int")],
MediumLevelILOperation.MLIL_BOOL_TO_INT: MediumLevelILBoolToInt, # [("src", "expr")],
@@ -3170,6 +3304,7 @@ ILInstruction = {
MediumLevelILOperation.MLIL_FTRUNC: MediumLevelILFtrunc, # [("src", "expr")],
MediumLevelILOperation.MLIL_VAR_SSA: MediumLevelILVarSsa, # [("src", "var_ssa")],
MediumLevelILOperation.MLIL_VAR_ALIASED: MediumLevelILVarAliased, # [("src", "var_ssa")],
+ MediumLevelILOperation.MLIL_VAR_OUTPUT_SSA: MediumLevelILVarOutputSsa, # [("dest", "var_ssa")],
MediumLevelILOperation.MLIL_CMP_E: MediumLevelILCmpE, # [("left", "expr"), ("right", "expr")],
MediumLevelILOperation.MLIL_CMP_NE: MediumLevelILCmpNe, # [("left", "expr"), ("right", "expr")],
MediumLevelILOperation.MLIL_CMP_SLT: MediumLevelILCmpSlt, # [("left", "expr"), ("right", "expr")],
@@ -3182,7 +3317,7 @@ ILInstruction = {
MediumLevelILOperation.MLIL_CMP_UGT: MediumLevelILCmpUgt, # [("left", "expr"), ("right", "expr")],
MediumLevelILOperation.MLIL_TEST_BIT: MediumLevelILTestBit, # [("left", "expr"), ("right", "expr")],
MediumLevelILOperation.MLIL_ADD_OVERFLOW: MediumLevelILAddOverflow, # [("left", "expr"), ("right", "expr")],
- MediumLevelILOperation.MLIL_SYSCALL: MediumLevelILSyscall, # [("output", "var_list"), ("params", "expr_list")],
+ MediumLevelILOperation.MLIL_SYSCALL: MediumLevelILSyscall, # [("output", "expr_list"), ("params", "expr_list")],
MediumLevelILOperation.MLIL_VAR_SSA_FIELD: MediumLevelILVarSsaField, # [("src", "var_ssa"), ("offset", "int")],
MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD:
MediumLevelILVarAliasedField, # [("src", "var_ssa"), ("offset", "int")],
@@ -3211,9 +3346,9 @@ ILInstruction = {
MediumLevelILOperation.MLIL_SET_VAR_ALIASED:
MediumLevelILSetVarAliased, # [("prev", "var_ssa_dest_and_src"), ("src", "expr")],
MediumLevelILOperation.MLIL_SYSCALL_UNTYPED:
- MediumLevelILSyscallUntyped, # [("output", "expr"), ("params", "expr"), ("stack", "expr")],
+ MediumLevelILSyscallUntyped, # [("output", "expr_list"), ("params", "expr"), ("stack", "expr")],
MediumLevelILOperation.MLIL_TAILCALL:
- MediumLevelILTailcall, # [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")],
+ MediumLevelILTailcall, # [("output", "expr_list"), ("dest", "expr"), ("params", "expr_list")],
MediumLevelILOperation.MLIL_INTRINSIC:
MediumLevelILIntrinsic, # [("output", "var_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")],
MediumLevelILOperation.MLIL_INTRINSIC_SSA: MediumLevelILIntrinsicSsa, # [("output", "var_ssa_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")],
@@ -3242,7 +3377,7 @@ ILInstruction = {
MediumLevelILOperation.MLIL_RLC: MediumLevelILRlc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")],
MediumLevelILOperation.MLIL_RRC: MediumLevelILRrc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")],
MediumLevelILOperation.MLIL_TAILCALL_UNTYPED:
- MediumLevelILTailcallUntyped, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")],
+ MediumLevelILTailcallUntyped, # [("output", "expr_list"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")],
MediumLevelILOperation.MLIL_CALL_SSA:
MediumLevelILCallSsa, # [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")],
MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA:
@@ -3252,12 +3387,12 @@ ILInstruction = {
MediumLevelILOperation.MLIL_TAILCALL_UNTYPED_SSA:
MediumLevelILTailcallUntypedSsa, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")],
MediumLevelILOperation.MLIL_CALL:
- MediumLevelILCall, # [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")],
+ MediumLevelILCall, # [("output", "expr_list"), ("dest", "expr"), ("params", "expr_list")],
MediumLevelILOperation.MLIL_IF: MediumLevelILIf, # [("condition", "expr"), ("true", "int"), ("false", "int")],
MediumLevelILOperation.MLIL_STORE_SSA:
MediumLevelILStoreSsa, # [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
MediumLevelILOperation.MLIL_CALL_UNTYPED:
- MediumLevelILCallUntyped, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")],
+ MediumLevelILCallUntyped, # [("output", "expr_list"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")],
MediumLevelILOperation.MLIL_STORE_STRUCT_SSA:
MediumLevelILStoreStructSsa, # [("dest", "expr"), ("offset", "int"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
MediumLevelILOperation.MLIL_ASSERT: MediumLevelILAssert,
@@ -3719,6 +3854,9 @@ class MediumLevelILFunction:
if expr.operation == MediumLevelILOperation.MLIL_VAR_SPLIT:
expr: MediumLevelILVarSplit
return dest.var_split(expr.size, expr.high, expr.low, loc)
+ if expr.operation == MediumLevelILOperation.MLIL_VAR_OUTPUT:
+ expr: MediumLevelILVarOutput
+ return dest.var_output(expr.size, expr.dest, loc)
if expr.operation == MediumLevelILOperation.MLIL_FORCE_VER:
expr: MediumLevelILForceVer
return dest.force_ver(expr.size, expr.dest, expr.src, loc)
@@ -3733,13 +3871,15 @@ class MediumLevelILFunction:
return dest.address_of_field(expr.src, expr.offset, loc)
if expr.operation == MediumLevelILOperation.MLIL_CALL:
expr: MediumLevelILCall
+ output = [sub_expr_handler(output) for output in expr.output_exprs]
params = [sub_expr_handler(param) for param in expr.params]
- return dest.call(expr.output, sub_expr_handler(expr.dest), params, loc)
+ return dest.call(output, sub_expr_handler(expr.dest), params, loc)
if expr.operation == MediumLevelILOperation.MLIL_CALL_UNTYPED:
expr: MediumLevelILCallUntyped
+ output = [sub_expr_handler(output) for output in expr.output_exprs]
params = [sub_expr_handler(param) for param in expr.params]
return dest.call_untyped(
- expr.output,
+ output,
sub_expr_handler(expr.dest),
params,
sub_expr_handler(expr.stack),
@@ -3747,26 +3887,30 @@ class MediumLevelILFunction:
)
if expr.operation == MediumLevelILOperation.MLIL_SYSCALL:
expr: MediumLevelILSyscall
+ output = [sub_expr_handler(output) for output in expr.output_exprs]
params = [sub_expr_handler(param) for param in expr.params]
- return dest.system_call(expr.output, params, loc)
+ return dest.system_call(output, params, loc)
if expr.operation == MediumLevelILOperation.MLIL_SYSCALL_UNTYPED:
expr: MediumLevelILSyscallUntyped
+ output = [sub_expr_handler(output) for output in expr.output_exprs]
params = [sub_expr_handler(param) for param in expr.params]
return dest.system_call_untyped(
- expr.output,
+ output,
params,
sub_expr_handler(expr.stack),
loc
)
if expr.operation == MediumLevelILOperation.MLIL_TAILCALL:
expr: MediumLevelILTailcall
+ output = [sub_expr_handler(output) for output in expr.output_exprs]
params = [sub_expr_handler(param) for param in expr.params]
- return dest.tailcall(expr.output, sub_expr_handler(expr.dest), params, loc)
+ return dest.tailcall(output, sub_expr_handler(expr.dest), params, loc)
if expr.operation == MediumLevelILOperation.MLIL_TAILCALL_UNTYPED:
expr: MediumLevelILTailcallUntyped
+ output = [sub_expr_handler(output) for output in expr.output_exprs]
params = [sub_expr_handler(param) for param in expr.params]
return dest.tailcall_untyped(
- expr.output,
+ output,
sub_expr_handler(expr.dest),
params,
sub_expr_handler(expr.stack),
@@ -4138,6 +4282,15 @@ class MediumLevelILFunction:
return llil_ssa_to_mlil_expr_map
+ def _call_output_list(self, outputs: CallOutputList, loc: Optional['ILSourceLocation'] = None) -> List[ExpressionIndex]:
+ result = []
+ for output in outputs:
+ if isinstance(output, variable.CoreVariable):
+ result.append(self.var_output(0, output, loc))
+ else:
+ result.append(output)
+ return result
+
def nop(self, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
``nop`` no operation, this instruction does nothing
@@ -4149,7 +4302,7 @@ class MediumLevelILFunction:
return self.expr(MediumLevelILOperation.MLIL_NOP, source_location=loc)
def set_var(
- self, size: int, dest: 'variable.Variable', src: ExpressionIndex,
+ self, size: int, dest: 'variable.CoreVariable', src: ExpressionIndex,
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -4165,7 +4318,7 @@ class MediumLevelILFunction:
return self.expr(MediumLevelILOperation.MLIL_SET_VAR, dest.identifier, src, size=size, source_location=loc)
def set_var_field(
- self, size: int, dest: 'variable.Variable', offset: int, src: ExpressionIndex,
+ self, size: int, dest: 'variable.CoreVariable', offset: int, src: ExpressionIndex,
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -4182,7 +4335,7 @@ class MediumLevelILFunction:
return self.expr(MediumLevelILOperation.MLIL_SET_VAR_FIELD, dest.identifier, offset, src, size=size, source_location=loc)
def set_var_split(
- self, size: int, hi: 'variable.Variable', lo: 'variable.Variable', src: ExpressionIndex,
+ self, size: int, hi: 'variable.CoreVariable', lo: 'variable.CoreVariable', src: ExpressionIndex,
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -4257,7 +4410,7 @@ class MediumLevelILFunction:
"""
return self.expr(MediumLevelILOperation.MLIL_STORE_STRUCT, dest, offset, src, size=size, source_location=loc)
- def var(self, size: int, src: 'variable.Variable', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ def var(self, size: int, src: 'variable.CoreVariable', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
``var`` returns the variable ``src`` of size ``size``
@@ -4270,7 +4423,7 @@ class MediumLevelILFunction:
return self.expr(MediumLevelILOperation.MLIL_VAR, src.identifier, size=size, source_location=loc)
def var_field(
- self, size: int, src: 'variable.Variable', offset: int, loc: Optional['ILSourceLocation'] = None
+ self, size: int, src: 'variable.CoreVariable', offset: int, loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
``var_field`` returns the field at offset ``offset`` from variable ``src`` of size ``size``
@@ -4285,7 +4438,7 @@ class MediumLevelILFunction:
return self.expr(MediumLevelILOperation.MLIL_VAR_FIELD, src.identifier, offset, size=size, source_location=loc)
def var_split(
- self, size: int, hi: 'variable.Variable', lo: 'variable.Variable', loc: Optional['ILSourceLocation'] = None
+ self, size: int, hi: 'variable.CoreVariable', lo: 'variable.CoreVariable', loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
``var_split`` combines variables ``hi`` and ``lo`` of size ``size`` into an expression of size ``2*size``
@@ -4299,10 +4452,22 @@ class MediumLevelILFunction:
"""
return self.expr(MediumLevelILOperation.MLIL_VAR_SPLIT, hi.identifier, lo.identifier, size=size, source_location=loc)
+ def var_output(self, size: int, dest: 'variable.CoreVariable', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ """
+ ``var`` returns the output variable ``dest`` of size ``size``
+
+ :param int size: the size of the variable in bytes
+ :param Variable dest: the variable being written
+ :param ILSourceLocation loc: location of returned expression
+ :return: An expression for the given variable
+ :rtype: ExpressionIndex
+ """
+ return self.expr(MediumLevelILOperation.MLIL_VAR_OUTPUT, dest.identifier, size=size, source_location=loc)
+
def assert_expr(
self,
size: int,
- src: 'variable.Variable',
+ src: 'variable.CoreVariable',
constraint: 'variable.PossibleValueSet',
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
@@ -4322,8 +4487,8 @@ class MediumLevelILFunction:
def force_ver(
self,
size: int,
- dest: 'variable.Variable',
- src: 'variable.Variable',
+ dest: 'variable.CoreVariable',
+ src: 'variable.CoreVariable',
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -4340,7 +4505,7 @@ class MediumLevelILFunction:
"""
return self.expr(MediumLevelILOperation.MLIL_FORCE_VER, dest.identifier, src.identifier, size=size, source_location=loc)
- def address_of(self, var: 'variable.Variable', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ def address_of(self, var: 'variable.CoreVariable', loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
``address_of`` takes the address of ``var``
@@ -4351,7 +4516,7 @@ class MediumLevelILFunction:
"""
return self.expr(MediumLevelILOperation.MLIL_ADDRESS_OF, var.identifier, size=0, source_location=loc)
- def address_of_field(self, var: 'variable.Variable', offset: int, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
+ def address_of_field(self, var: 'variable.CoreVariable', offset: int, loc: Optional['ILSourceLocation'] = None) -> ExpressionIndex:
"""
``address_of_field`` takes the address of ``var`` at the offset ``offset``
@@ -4943,14 +5108,14 @@ class MediumLevelILFunction:
return self.expr(MediumLevelILOperation.MLIL_JUMP_TO, dest, len(targets) * 2, self.add_label_map(targets), size=0, source_location=loc)
def call(
- self, output: List['variable.Variable'], dest: ExpressionIndex, params: List[ExpressionIndex],
+ self, output: CallOutputList, dest: ExpressionIndex, params: List[ExpressionIndex],
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
``call`` returns an expression which calls the function in the expression ``dest``
with the parameters defined in ``params`` returning values in the variables in ``output``.
- :param List['variable.Variable'] output: output variables
+ :param CallOutputList output: output variables or expressions
:param ExpressionIndex dest: the expression to call
:param List[ExpressionIndex] params: parameter variables
:param ILSourceLocation loc: location of returned expression
@@ -4960,7 +5125,7 @@ class MediumLevelILFunction:
return self.expr(
MediumLevelILOperation.MLIL_CALL,
len(output),
- self.add_variable_list(output),
+ self.add_operand_list(self._call_output_list(output)),
dest,
len(params),
self.add_operand_list(params),
@@ -4969,7 +5134,7 @@ class MediumLevelILFunction:
)
def call_untyped(
- self, output: List['variable.Variable'], dest: ExpressionIndex, params: List[ExpressionIndex],
+ self, output: CallOutputList, dest: ExpressionIndex, params: List[ExpressionIndex],
stack: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -4977,7 +5142,7 @@ class MediumLevelILFunction:
with the parameters defined in ``params`` returning values in the variables in ``output``
where stack resolution could not be determined and the top of the stack has to be specified in ``stack``
- :param List['variable.Variable'] output: output variables
+ :param CallOutputList output: output variables or expressions
:param ExpressionIndex dest: the expression to call
:param List[ExpressionIndex] params: parameter variables
:param ExpressionIndex stack: expression of top of stack
@@ -4987,13 +5152,8 @@ class MediumLevelILFunction:
"""
return self.expr(
MediumLevelILOperation.MLIL_CALL_UNTYPED,
- self.expr(
- MediumLevelILOperation.MLIL_CALL_OUTPUT,
- len(output),
- self.add_variable_list(output),
- size=0,
- source_location=loc
- ),
+ len(output),
+ self.add_operand_list(self._call_output_list(output)),
dest,
self.expr(
MediumLevelILOperation.MLIL_CALL_PARAM,
@@ -5008,14 +5168,14 @@ class MediumLevelILFunction:
)
def system_call(
- self, output: List['variable.Variable'], params: List[ExpressionIndex],
+ self, output: CallOutputList, params: List[ExpressionIndex],
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
``system_call`` returns an expression which performs a system call
with the parameters defined in ``params`` returning values in the variables in ``output``.
- :param List['variable.Variable'] output: output variables
+ :param CallOutputList output: output variables or expressions
:param List[ExpressionIndex] params: parameter variables
:param ILSourceLocation loc: location of returned expression
:return: The expression ``output = syscall(dest, params...)``
@@ -5024,7 +5184,7 @@ class MediumLevelILFunction:
return self.expr(
MediumLevelILOperation.MLIL_SYSCALL,
len(output),
- self.add_variable_list(output),
+ self.add_operand_list(self._call_output_list(output)),
len(params),
self.add_operand_list(params),
size=0,
@@ -5032,7 +5192,7 @@ class MediumLevelILFunction:
)
def system_call_untyped(
- self, output: List['variable.Variable'], params: List[ExpressionIndex],
+ self, output: CallOutputList, params: List[ExpressionIndex],
stack: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -5040,7 +5200,7 @@ class MediumLevelILFunction:
with the parameters defined in ``params`` returning values in the variables in ``output``
where stack resolution could not be determined and the top of the stack has to be specified in ``stack``
- :param List['variable.Variable'] output: output variables
+ :param CallOutputList output: output variables or expressions
:param List[ExpressionIndex] params: parameter variables
:param ExpressionIndex stack: expression of top of stack
:param ILSourceLocation loc: location of returned expression
@@ -5049,13 +5209,8 @@ class MediumLevelILFunction:
"""
return self.expr(
MediumLevelILOperation.MLIL_SYSCALL_UNTYPED,
- self.expr(
- MediumLevelILOperation.MLIL_CALL_OUTPUT,
- len(output),
- self.add_variable_list(output),
- size=0,
- source_location=loc
- ),
+ len(output),
+ self.add_operand_list(self._call_output_list(output)),
self.expr(
MediumLevelILOperation.MLIL_CALL_PARAM,
len(params),
@@ -5069,14 +5224,14 @@ class MediumLevelILFunction:
)
def tailcall(
- self, output: List['variable.Variable'], dest: ExpressionIndex, params: List[ExpressionIndex],
+ self, output: CallOutputList, dest: ExpressionIndex, params: List[ExpressionIndex],
loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
``tailcall`` returns an expression which tailcalls the function in the expression ``dest``
with the parameters defined in ``params`` returning values in the variables in ``output``.
- :param List['variable.Variable'] output: output variables
+ :param CallOutputList output: output variables or expressions
:param ExpressionIndex dest: the expression to call
:param List[ExpressionIndex] params: parameter variables
:param ILSourceLocation loc: location of returned expression
@@ -5086,7 +5241,7 @@ class MediumLevelILFunction:
return self.expr(
MediumLevelILOperation.MLIL_TAILCALL,
len(output),
- self.add_variable_list(output),
+ self.add_operand_list(self._call_output_list(output)),
dest,
len(params),
self.add_operand_list(params),
@@ -5095,7 +5250,7 @@ class MediumLevelILFunction:
)
def tailcall_untyped(
- self, output: List['variable.Variable'], dest: ExpressionIndex, params: List[ExpressionIndex],
+ self, output: CallOutputList, dest: ExpressionIndex, params: List[ExpressionIndex],
stack: ExpressionIndex, loc: Optional['ILSourceLocation'] = None
) -> ExpressionIndex:
"""
@@ -5103,7 +5258,7 @@ class MediumLevelILFunction:
with the parameters defined in ``params`` returning values in the variables in ``output``
where stack resolution could not be determined and the top of the stack has to be specified in ``stack``
- :param List['variable.Variable'] output: output variables
+ :param CallOutputList output: output variables or expressions
:param ExpressionIndex dest: the expression to call
:param List[ExpressionIndex] params: parameter variables
:param ExpressionIndex stack: expression of top of stack
@@ -5113,13 +5268,8 @@ class MediumLevelILFunction:
"""
return self.expr(
MediumLevelILOperation.MLIL_TAILCALL_UNTYPED,
- self.expr(
- MediumLevelILOperation.MLIL_CALL_OUTPUT,
- len(output),
- self.add_variable_list(output),
- size=0,
- source_location=loc
- ),
+ len(output),
+ self.add_operand_list(self._call_output_list(output)),
dest,
self.expr(
MediumLevelILOperation.MLIL_CALL_PARAM,
@@ -5886,12 +6036,12 @@ class MediumLevelILFunction:
operand_list[i] = operands[i]
return ExpressionIndex(core.BNMediumLevelILAddOperandList(self.handle, operand_list, len(operands)))
- def add_variable_list(self, vars: List['variable.Variable']) -> ExpressionIndex:
+ def add_variable_list(self, vars: List['variable.CoreVariable']) -> ExpressionIndex:
"""
``add_variable_list`` returns a variable list expression for the given list of variables.
:param vars: list of variables
- :type vars: list(variable.Variable)
+ :type vars: list(variable.CoreVariable)
:return: a variable list expression
:rtype: ExpressionIndex
"""
@@ -5916,7 +6066,7 @@ class MediumLevelILFunction:
"""
core.BNFinalizeMediumLevelILFunction(self.handle)
- def generate_ssa_form(self, analyze_conditionals : bool = True, handle_aliases : bool = True, known_not_aliases: Optional[List["variable.Variable"]] = None, known_aliases: Optional[List["variable.Variable"]] = None) -> None:
+ def generate_ssa_form(self, analyze_conditionals : bool = True, handle_aliases : bool = True, known_not_aliases: Optional[List["variable.CoreVariable"]] = None, known_aliases: Optional[List["variable.CoreVariable"]] = None) -> None:
"""
``generate_ssa_form`` generate SSA form given the current MLIL
@@ -6051,13 +6201,13 @@ class MediumLevelILFunction:
"""
return core.BNIsMediumLevelILSSAVarLiveAt(self.handle, ssa_var.var.to_BNVariable(), ssa_var.version, instr)
- def is_var_live_at(self, var: 'variable.Variable', instr: InstructionIndex) -> bool:
+ def is_var_live_at(self, var: 'variable.CoreVariable', instr: InstructionIndex) -> bool:
"""
``is_var_live_at`` determines if ``var`` is live at a given point in the function
"""
return core.BNIsMediumLevelILVarLiveAt(self.handle, var.to_BNVariable(), instr)
- def get_var_definitions(self, var: 'variable.Variable') -> List[MediumLevelILInstruction]:
+ def get_var_definitions(self, var: 'variable.CoreVariable') -> List[MediumLevelILInstruction]:
count = ctypes.c_ulonglong()
var_data = var.to_BNVariable()
instrs = core.BNGetMediumLevelILVariableDefinitions(self.handle, var_data, count)
@@ -6068,7 +6218,7 @@ class MediumLevelILFunction:
core.BNFreeILInstructionList(instrs)
return result
- def get_var_uses(self, var: 'variable.Variable') -> List[MediumLevelILInstruction]:
+ def get_var_uses(self, var: 'variable.CoreVariable') -> List[MediumLevelILInstruction]:
count = ctypes.c_ulonglong()
var_data = var.to_BNVariable()
instrs = core.BNGetMediumLevelILVariableUses(self.handle, var_data, count)
@@ -6081,7 +6231,7 @@ class MediumLevelILFunction:
finally:
core.BNFreeILInstructionList(instrs)
- def get_live_instructions_for_var(self, var: 'variable.Variable', include_last_use: bool = True) -> List[MediumLevelILInstruction]:
+ def get_live_instructions_for_var(self, var: 'variable.CoreVariable', include_last_use: bool = True) -> List[MediumLevelILInstruction]:
"""
``get_live_instructions_for_var`` computes the list of instructions for which ``var`` is live.
If ``include_last_use`` is False, the last use of the variable will not be included in the
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 {