summaryrefslogtreecommitdiff
path: root/mediumlevelilinstruction.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-08-01 23:39:18 -0400
committerRusty Wagner <rusty@vector35.com>2017-08-05 20:49:14 -0400
commite47e2fb13369ff7d1c9e7728bb793ee56640afe1 (patch)
treeb6683fa3e28da3158c6559612959267a81fabbb2 /mediumlevelilinstruction.cpp
parent92ef6481d84d3289ba86a9b9ffe6553bb5842c5d (diff)
Refactor IL instruction access APIs
Diffstat (limited to 'mediumlevelilinstruction.cpp')
-rw-r--r--mediumlevelilinstruction.cpp2526
1 files changed, 2526 insertions, 0 deletions
diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp
new file mode 100644
index 00000000..73f2e59b
--- /dev/null
+++ b/mediumlevelilinstruction.cpp
@@ -0,0 +1,2526 @@
+// Copyright (c) 2015-2017 Vector 35 LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifdef BINARYNINJACORE_LIBRARY
+#include "mediumlevelilfunction.h"
+#include "mediumlevelilssafunction.h"
+#include "lowlevelilfunction.h"
+using namespace BinaryNinjaCore;
+#else
+#include "binaryninjaapi.h"
+#include "mediumlevelilinstruction.h"
+#include "lowlevelilinstruction.h"
+using namespace BinaryNinja;
+#endif
+
+using namespace std;
+
+
+unordered_map<MediumLevelILOperandUsage, MediumLevelILOperandType>
+ MediumLevelILInstructionBase::operandTypeForUsage = {
+ {SourceExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {SourceVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
+ {SourceSSAVariableMediumLevelOperandUsage, SSAVariableMediumLevelOperand},
+ {PartialSSAVariableSourceMediumLevelOperandUsage, SSAVariableMediumLevelOperand},
+ {DestExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {DestVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
+ {DestSSAVariableMediumLevelOperandUsage, SSAVariableMediumLevelOperand},
+ {LeftExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {RightExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {CarryExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {HighExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {LowExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {StackExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {ConditionExprMediumLevelOperandUsage, ExprMediumLevelOperand},
+ {HighVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
+ {LowVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
+ {HighSSAVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
+ {LowSSAVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
+ {OffsetMediumLevelOperandUsage, IntegerMediumLevelOperand},
+ {ConstantMediumLevelOperandUsage, IntegerMediumLevelOperand},
+ {VectorMediumLevelOperandUsage, IntegerMediumLevelOperand},
+ {TargetMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {TrueTargetMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {FalseTargetMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {DestMemoryVersionMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {SourceMemoryVersionMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {TargetListMediumLevelOperandUsage, IndexListMediumLevelOperand},
+ {SourceMemoryVersionsMediumLevelOperandUsage, IndexListMediumLevelOperand},
+ {OutputVariablesMediumLevelOperandUsage, VariableListMediumLevelOperand},
+ {OutputVariablesSubExprMediumLevelOperandUsage, VariableListMediumLevelOperand},
+ {OutputSSAVariablesMediumLevelOperandUsage, SSAVariableListMediumLevelOperand},
+ {OutputSSAMemoryVersionMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {ParameterExprsMediumLevelOperandUsage, ExprListMediumLevelOperand},
+ {SourceExprsMediumLevelOperandUsage, ExprListMediumLevelOperand},
+ {ParameterVariablesMediumLevelOperandUsage, VariableListMediumLevelOperand},
+ {ParameterSSAVariablesMediumLevelOperandUsage, SSAVariableListMediumLevelOperand},
+ {ParameterSSAMemoryVersionMediumLevelOperandUsage, IndexMediumLevelOperand},
+ {SourceSSAVariablesMediumLevelOperandUsages, SSAVariableListMediumLevelOperand}
+ };
+
+
+unordered_map<BNMediumLevelILOperation, vector<MediumLevelILOperandUsage>>
+ MediumLevelILInstructionBase::operationOperandUsage = {
+ {MLIL_NOP, {}},
+ {MLIL_NORET, {}},
+ {MLIL_BP, {}},
+ {MLIL_UNDEF, {}},
+ {MLIL_UNIMPL, {}},
+ {MLIL_SET_VAR, {DestVariableMediumLevelOperandUsage, SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_FIELD, {DestVariableMediumLevelOperandUsage, OffsetMediumLevelOperandUsage,
+ SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_SPLIT, {HighVariableMediumLevelOperandUsage, LowVariableMediumLevelOperandUsage,
+ SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_SSA, {DestSSAVariableMediumLevelOperandUsage, SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_SSA_FIELD, {DestSSAVariableMediumLevelOperandUsage, PartialSSAVariableSourceMediumLevelOperandUsage,
+ OffsetMediumLevelOperandUsage, SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_SPLIT_SSA, {HighSSAVariableMediumLevelOperandUsage, LowSSAVariableMediumLevelOperandUsage,
+ SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_ALIASED, {DestSSAVariableMediumLevelOperandUsage, PartialSSAVariableSourceMediumLevelOperandUsage,
+ SourceExprMediumLevelOperandUsage}},
+ {MLIL_SET_VAR_ALIASED_FIELD, {DestSSAVariableMediumLevelOperandUsage, PartialSSAVariableSourceMediumLevelOperandUsage,
+ OffsetMediumLevelOperandUsage, SourceExprMediumLevelOperandUsage}},
+ {MLIL_LOAD, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_LOAD_STRUCT, {SourceExprMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}},
+ {MLIL_LOAD_SSA, {SourceExprMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
+ {MLIL_LOAD_STRUCT_SSA, {SourceExprMediumLevelOperandUsage, OffsetMediumLevelOperandUsage,
+ SourceMemoryVersionMediumLevelOperandUsage}},
+ {MLIL_STORE, {DestExprMediumLevelOperandUsage, SourceExprMediumLevelOperandUsage}},
+ {MLIL_STORE_STRUCT, {DestExprMediumLevelOperandUsage, OffsetMediumLevelOperandUsage,
+ SourceExprMediumLevelOperandUsage}},
+ {MLIL_STORE_SSA, {DestExprMediumLevelOperandUsage, DestMemoryVersionMediumLevelOperandUsage,
+ SourceMemoryVersionMediumLevelOperandUsage, SourceExprMediumLevelOperandUsage}},
+ {MLIL_STORE_STRUCT_SSA, {DestExprMediumLevelOperandUsage, OffsetMediumLevelOperandUsage,
+ DestMemoryVersionMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage,
+ SourceExprMediumLevelOperandUsage}},
+ {MLIL_VAR, {SourceVariableMediumLevelOperandUsage}},
+ {MLIL_VAR_FIELD, {SourceVariableMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}},
+ {MLIL_VAR_SSA, {SourceSSAVariableMediumLevelOperandUsage}},
+ {MLIL_VAR_SSA_FIELD, {SourceSSAVariableMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}},
+ {MLIL_VAR_ALIASED, {SourceSSAVariableMediumLevelOperandUsage}},
+ {MLIL_VAR_ALIASED_FIELD, {SourceSSAVariableMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}},
+ {MLIL_ADDRESS_OF, {SourceVariableMediumLevelOperandUsage}},
+ {MLIL_ADDRESS_OF_FIELD, {SourceVariableMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}},
+ {MLIL_JUMP, {DestExprMediumLevelOperandUsage}},
+ {MLIL_JUMP_TO, {DestExprMediumLevelOperandUsage, TargetListMediumLevelOperandUsage}},
+ {MLIL_CALL, {OutputVariablesMediumLevelOperandUsage, DestExprMediumLevelOperandUsage,
+ ParameterExprsMediumLevelOperandUsage}},
+ {MLIL_CALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage, DestExprMediumLevelOperandUsage,
+ ParameterVariablesMediumLevelOperandUsage}},
+ {MLIL_SYSCALL, {OutputVariablesMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage}},
+ {MLIL_SYSCALL_UNTYPED, {OutputVariablesSubExprMediumLevelOperandUsage,
+ ParameterVariablesMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
+ {MLIL_CALL_SSA, {OutputSSAVariablesMediumLevelOperandUsage,
+ OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage,
+ ParameterExprsMediumLevelOperandUsage, SourceMemoryVersionMediumLevelOperandUsage}},
+ {MLIL_CALL_UNTYPED_SSA, {OutputSSAVariablesMediumLevelOperandUsage,
+ OutputSSAMemoryVersionMediumLevelOperandUsage, DestExprMediumLevelOperandUsage,
+ ParameterSSAVariablesMediumLevelOperandUsage, ParameterSSAMemoryVersionMediumLevelOperandUsage,
+ StackExprMediumLevelOperandUsage}},
+ {MLIL_SYSCALL_SSA, {OutputSSAVariablesMediumLevelOperandUsage,
+ OutputSSAMemoryVersionMediumLevelOperandUsage, ParameterExprsMediumLevelOperandUsage,
+ SourceMemoryVersionMediumLevelOperandUsage}},
+ {MLIL_SYSCALL_UNTYPED_SSA, {OutputSSAVariablesMediumLevelOperandUsage,
+ OutputSSAMemoryVersionMediumLevelOperandUsage, ParameterSSAVariablesMediumLevelOperandUsage,
+ ParameterSSAMemoryVersionMediumLevelOperandUsage, StackExprMediumLevelOperandUsage}},
+ {MLIL_RET, {SourceExprsMediumLevelOperandUsage}},
+ {MLIL_IF, {ConditionExprMediumLevelOperandUsage, TrueTargetMediumLevelOperandUsage,
+ FalseTargetMediumLevelOperandUsage}},
+ {MLIL_GOTO, {TargetMediumLevelOperandUsage}},
+ {MLIL_TRAP, {VectorMediumLevelOperandUsage}},
+ {MLIL_VAR_PHI, {DestSSAVariableMediumLevelOperandUsage, SourceSSAVariablesMediumLevelOperandUsages}},
+ {MLIL_MEM_PHI, {DestMemoryVersionMediumLevelOperandUsage, SourceMemoryVersionsMediumLevelOperandUsage}},
+ {MLIL_CONST, {ConstantMediumLevelOperandUsage}},
+ {MLIL_CONST_PTR, {ConstantMediumLevelOperandUsage}},
+ {MLIL_ADD, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_SUB, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_AND, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_OR, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_XOR, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_LSL, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_LSR, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_ASR, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_ROL, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_ROR, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_MUL, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_MULU_DP, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_MULS_DP, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_DIVU, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_DIVS, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_MODU, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_MODS, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_E, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_NE, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_SLT, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_ULT, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_SLE, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_ULE, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_SGE, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_UGE, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_SGT, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_CMP_UGT, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_TEST_BIT, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_ADD_OVERFLOW, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
+ {MLIL_ADC, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage,
+ CarryExprMediumLevelOperandUsage}},
+ {MLIL_SBB, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage,
+ CarryExprMediumLevelOperandUsage}},
+ {MLIL_RLC, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage,
+ CarryExprMediumLevelOperandUsage}},
+ {MLIL_RRC, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage,
+ CarryExprMediumLevelOperandUsage}},
+ {MLIL_DIVU_DP, {HighExprMediumLevelOperandUsage, LowExprMediumLevelOperandUsage,
+ RightExprMediumLevelOperandUsage}},
+ {MLIL_DIVS_DP, {HighExprMediumLevelOperandUsage, LowExprMediumLevelOperandUsage,
+ RightExprMediumLevelOperandUsage}},
+ {MLIL_MODU_DP, {HighExprMediumLevelOperandUsage, LowExprMediumLevelOperandUsage,
+ RightExprMediumLevelOperandUsage}},
+ {MLIL_MODS_DP, {HighExprMediumLevelOperandUsage, LowExprMediumLevelOperandUsage,
+ RightExprMediumLevelOperandUsage}},
+ {MLIL_NEG, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_NOT, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_SX, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_ZX, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_LOW_PART, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_BOOL_TO_INT, {SourceExprMediumLevelOperandUsage}},
+ {MLIL_UNIMPL_MEM, {SourceExprMediumLevelOperandUsage}}
+ };
+
+
+static unordered_map<BNMediumLevelILOperation, unordered_map<MediumLevelILOperandUsage, size_t>>
+ GetOperandIndexForOperandUsages()
+{
+ unordered_map<BNMediumLevelILOperation, unordered_map<MediumLevelILOperandUsage, size_t>> result;
+ for (auto& operation : MediumLevelILInstructionBase::operationOperandUsage)
+ {
+ result[operation.first] = unordered_map<MediumLevelILOperandUsage, size_t>();
+
+ size_t operand = 0;
+ for (auto usage : operation.second)
+ {
+ result[operation.first][usage] = operand;
+ switch (usage)
+ {
+ case PartialSSAVariableSourceMediumLevelOperandUsage:
+ // SSA variables are usually two slots, but this one has a previously defined
+ // variables and thus only takes one slot
+ operand++;
+ break;
+ case OutputVariablesSubExprMediumLevelOperandUsage:
+ case ParameterVariablesMediumLevelOperandUsage:
+ // Represented as subexpression, so only takes one slot even though it is a list
+ operand++;
+ break;
+ case OutputSSAVariablesMediumLevelOperandUsage:
+ // OutputSSAMemoryVersionMediumLevelOperandUsage follows at same operand
+ break;
+ case ParameterSSAVariablesMediumLevelOperandUsage:
+ // ParameterSSAMemoryVersionMediumLevelOperandUsage follows at same operand
+ break;
+ default:
+ switch (MediumLevelILInstructionBase::operandTypeForUsage[usage])
+ {
+ case SSAVariableMediumLevelOperand:
+ case IndexListMediumLevelOperand:
+ case VariableListMediumLevelOperand:
+ case SSAVariableListMediumLevelOperand:
+ case ExprListMediumLevelOperand:
+ // SSA variables and lists take two operand slots
+ operand += 2;
+ break;
+ default:
+ operand++;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+
+unordered_map<BNMediumLevelILOperation, unordered_map<MediumLevelILOperandUsage, size_t>>
+ MediumLevelILInstructionBase::operationOperandIndex = GetOperandIndexForOperandUsages();
+
+
+SSAVariable::SSAVariable(): version(0)
+{
+}
+
+
+SSAVariable::SSAVariable(const Variable& v, size_t i): var(v), version(i)
+{
+}
+
+
+SSAVariable::SSAVariable(const SSAVariable& v): var(v.var), version(v.version)
+{
+}
+
+
+SSAVariable& SSAVariable::operator=(const SSAVariable& v)
+{
+ var = v.var;
+ version = v.version;
+ return *this;
+}
+
+
+bool SSAVariable::operator==(const SSAVariable& v) const
+{
+ if (var != v.var)
+ return false;
+ return version == v.version;
+}
+
+
+bool SSAVariable::operator!=(const SSAVariable& v) const
+{
+ return !((*this) == v);
+}
+
+
+bool SSAVariable::operator<(const SSAVariable& v) const
+{
+ if (var < v.var)
+ return true;
+ if (v.var < var)
+ return false;
+ return version < v.version;
+}
+
+
+bool MediumLevelILIntegerList::ListIterator::operator==(const ListIterator& a) const
+{
+ return count == a.count;
+}
+
+
+bool MediumLevelILIntegerList::ListIterator::operator!=(const ListIterator& a) const
+{
+ return count != a.count;
+}
+
+
+bool MediumLevelILIntegerList::ListIterator::operator<(const ListIterator& a) const
+{
+ return count > a.count;
+}
+
+
+MediumLevelILIntegerList::ListIterator& MediumLevelILIntegerList::ListIterator::operator++()
+{
+ count--;
+ if (count == 0)
+ return *this;
+
+ operand++;
+ if (operand >= 4)
+ {
+ operand = 0;
+#ifdef BINARYNINJACORE_LIBRARY
+ instr = &function->GetRawExpr((size_t)instr->operands[4]);
+#else
+ instr = function->GetRawExpr((size_t)instr.operands[4]);
+#endif
+ }
+ return *this;
+}
+
+
+uint64_t MediumLevelILIntegerList::ListIterator::operator*()
+{
+#ifdef BINARYNINJACORE_LIBRARY
+ return instr->operands[operand];
+#else
+ return instr.operands[operand];
+#endif
+}
+
+
+MediumLevelILIntegerList::MediumLevelILIntegerList(MediumLevelILFunction* func,
+ const BNMediumLevelILInstruction& instr, size_t count)
+{
+ m_start.function = func;
+#ifdef BINARYNINJACORE_LIBRARY
+ m_start.instr = &instr;
+#else
+ m_start.instr = instr;
+#endif
+ m_start.operand = 0;
+ m_start.count = count;
+}
+
+
+MediumLevelILIntegerList::const_iterator MediumLevelILIntegerList::begin() const
+{
+ return m_start;
+}
+
+
+MediumLevelILIntegerList::const_iterator MediumLevelILIntegerList::end() const
+{
+ const_iterator result;
+ result.function = m_start.function;
+ result.operand = 0;
+ result.count = 0;
+ return result;
+}
+
+
+size_t MediumLevelILIntegerList::size() const
+{
+ return m_start.count;
+}
+
+
+uint64_t MediumLevelILIntegerList::operator[](size_t i) const
+{
+ if (i >= size())
+ throw MediumLevelILInstructionAccessException();
+ auto iter = begin();
+ for (size_t j = 0; j < i; j++)
+ ++iter;
+ return *iter;
+}
+
+
+MediumLevelILIntegerList::operator vector<uint64_t>() const
+{
+ vector<uint64_t> result;
+ for (auto i : *this)
+ result.push_back(i);
+ return result;
+}
+
+
+size_t MediumLevelILIndexList::ListIterator::operator*()
+{
+ return (size_t)*pos;
+}
+
+
+MediumLevelILIndexList::MediumLevelILIndexList(MediumLevelILFunction* func,
+ const BNMediumLevelILInstruction& instr, size_t count): m_list(func, instr, count)
+{
+}
+
+
+MediumLevelILIndexList::const_iterator MediumLevelILIndexList::begin() const
+{
+ const_iterator result;
+ result.pos = m_list.begin();
+ return result;
+}
+
+
+MediumLevelILIndexList::const_iterator MediumLevelILIndexList::end() const
+{
+ const_iterator result;
+ result.pos = m_list.end();
+ return result;
+}
+
+
+size_t MediumLevelILIndexList::size() const
+{
+ return m_list.size();
+}
+
+
+size_t MediumLevelILIndexList::operator[](size_t i) const
+{
+ if (i >= size())
+ throw MediumLevelILInstructionAccessException();
+ auto iter = begin();
+ for (size_t j = 0; j < i; j++)
+ ++iter;
+ return *iter;
+}
+
+
+MediumLevelILIndexList::operator vector<size_t>() const
+{
+ vector<size_t> result;
+ for (auto i : *this)
+ result.push_back(i);
+ return result;
+}
+
+
+const Variable MediumLevelILVariableList::ListIterator::operator*()
+{
+ return Variable::FromIdentifier(*pos);
+}
+
+
+MediumLevelILVariableList::MediumLevelILVariableList(MediumLevelILFunction* func,
+ const BNMediumLevelILInstruction& instr, size_t count): m_list(func, instr, count)
+{
+}
+
+
+MediumLevelILVariableList::const_iterator MediumLevelILVariableList::begin() const
+{
+ const_iterator result;
+ result.pos = m_list.begin();
+ return result;
+}
+
+
+MediumLevelILVariableList::const_iterator MediumLevelILVariableList::end() const
+{
+ const_iterator result;
+ result.pos = m_list.end();
+ return result;
+}
+
+
+size_t MediumLevelILVariableList::size() const
+{
+ return m_list.size();
+}
+
+
+const Variable MediumLevelILVariableList::operator[](size_t i) const
+{
+ if (i >= size())
+ throw MediumLevelILInstructionAccessException();
+ auto iter = begin();
+ for (size_t j = 0; j < i; j++)
+ ++iter;
+ return *iter;
+}
+
+
+MediumLevelILVariableList::operator vector<Variable>() const
+{
+ vector<Variable> result;
+ for (auto& i : *this)
+ result.push_back(i);
+ return result;
+}
+
+
+const SSAVariable MediumLevelILSSAVariableList::ListIterator::operator*()
+{
+ MediumLevelILIntegerList::const_iterator cur = pos;
+ Variable var = Variable::FromIdentifier(*cur);
+ ++cur;
+ size_t version = (size_t)*cur;
+ return SSAVariable(var, version);
+}
+
+
+MediumLevelILSSAVariableList::MediumLevelILSSAVariableList(MediumLevelILFunction* func,
+ const BNMediumLevelILInstruction& instr, size_t count): m_list(func, instr, count & (~1))
+{
+}
+
+
+MediumLevelILSSAVariableList::const_iterator MediumLevelILSSAVariableList::begin() const
+{
+ const_iterator result;
+ result.pos = m_list.begin();
+ return result;
+}
+
+
+MediumLevelILSSAVariableList::const_iterator MediumLevelILSSAVariableList::end() const
+{
+ const_iterator result;
+ result.pos = m_list.end();
+ return result;
+}
+
+
+size_t MediumLevelILSSAVariableList::size() const
+{
+ return m_list.size() / 2;
+}
+
+
+const SSAVariable MediumLevelILSSAVariableList::operator[](size_t i) const
+{
+ if (i >= size())
+ throw MediumLevelILInstructionAccessException();
+ auto iter = begin();
+ for (size_t j = 0; j < i; j++)
+ ++iter;
+ return *iter;
+}
+
+
+MediumLevelILSSAVariableList::operator vector<SSAVariable>() const
+{
+ vector<SSAVariable> result;
+ for (auto& i : *this)
+ result.push_back(i);
+ return result;
+}
+
+
+const MediumLevelILInstruction MediumLevelILInstructionList::ListIterator::operator*()
+{
+ return MediumLevelILInstruction(pos.GetFunction(), pos.GetFunction()->GetRawExpr((size_t)*pos),
+ (size_t)*pos, instructionIndex);
+}
+
+
+MediumLevelILInstructionList::MediumLevelILInstructionList(MediumLevelILFunction* func,
+ const BNMediumLevelILInstruction& instr, size_t count, size_t instrIndex):
+ m_list(func, instr, count), m_instructionIndex(instrIndex)
+{
+}
+
+
+MediumLevelILInstructionList::const_iterator MediumLevelILInstructionList::begin() const
+{
+ const_iterator result;
+ result.pos = m_list.begin();
+ result.instructionIndex = m_instructionIndex;
+ return result;
+}
+
+
+MediumLevelILInstructionList::const_iterator MediumLevelILInstructionList::end() const
+{
+ const_iterator result;
+ result.pos = m_list.end();
+ result.instructionIndex = m_instructionIndex;
+ return result;
+}
+
+
+size_t MediumLevelILInstructionList::size() const
+{
+ return m_list.size();
+}
+
+
+const MediumLevelILInstruction MediumLevelILInstructionList::operator[](size_t i) const
+{
+ if (i >= size())
+ throw MediumLevelILInstructionAccessException();
+ auto iter = begin();
+ for (size_t j = 0; j < i; j++)
+ ++iter;
+ return *iter;
+}
+
+
+MediumLevelILInstructionList::operator vector<MediumLevelILInstruction>() const
+{
+ vector<MediumLevelILInstruction> result;
+ for (auto& i : *this)
+ result.push_back(i);
+ return result;
+}
+
+
+MediumLevelILOperand::MediumLevelILOperand(const MediumLevelILInstruction& instr,
+ MediumLevelILOperandUsage usage, size_t operandIndex):
+ m_instr(instr), m_usage(usage), m_operandIndex(operandIndex)
+{
+ auto i = MediumLevelILInstructionBase::operandTypeForUsage.find(m_usage);
+ if (i == MediumLevelILInstructionBase::operandTypeForUsage.end())
+ throw MediumLevelILInstructionAccessException();
+ m_type = i->second;
+}
+
+
+uint64_t MediumLevelILOperand::GetInteger() const
+{
+ if (m_type != IntegerMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsInteger(m_operandIndex);
+}
+
+
+size_t MediumLevelILOperand::GetIndex() const
+{
+ if (m_type != IndexMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ if ((m_usage == OutputSSAMemoryVersionMediumLevelOperandUsage) ||
+ (m_usage == ParameterSSAMemoryVersionMediumLevelOperandUsage))
+ return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsIndex(0);
+ return m_instr.GetRawOperandAsIndex(m_operandIndex);
+}
+
+
+MediumLevelILInstruction MediumLevelILOperand::GetExpr() const
+{
+ if (m_type != ExprMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsExpr(m_operandIndex);
+}
+
+
+Variable MediumLevelILOperand::GetVariable() const
+{
+ if (m_type != VariableMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsVariable(m_operandIndex);
+}
+
+
+SSAVariable MediumLevelILOperand::GetSSAVariable() const
+{
+ if (m_type != SSAVariableMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ if (m_usage == PartialSSAVariableSourceMediumLevelOperandUsage)
+ return m_instr.GetRawOperandAsPartialSSAVariableSource(m_operandIndex - 2);
+ return m_instr.GetRawOperandAsSSAVariable(m_operandIndex);
+}
+
+
+MediumLevelILIndexList MediumLevelILOperand::GetIndexList() const
+{
+ if (m_type != IndexListMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsIndexList(m_operandIndex);
+}
+
+
+MediumLevelILVariableList MediumLevelILOperand::GetVariableList() const
+{
+ if (m_type != VariableListMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ if ((m_usage == OutputVariablesSubExprMediumLevelOperandUsage) ||
+ (m_usage == ParameterVariablesMediumLevelOperandUsage))
+ return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsVariableList(0);
+ return m_instr.GetRawOperandAsVariableList(m_operandIndex);
+}
+
+
+MediumLevelILSSAVariableList MediumLevelILOperand::GetSSAVariableList() const
+{
+ if (m_type != SSAVariableListMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ if ((m_usage == OutputSSAVariablesMediumLevelOperandUsage) ||
+ (m_usage == ParameterSSAVariablesMediumLevelOperandUsage))
+ return m_instr.GetRawOperandAsExpr(m_operandIndex).GetRawOperandAsSSAVariableList(1);
+ return m_instr.GetRawOperandAsSSAVariableList(m_operandIndex);
+}
+
+
+MediumLevelILInstructionList MediumLevelILOperand::GetExprList() const
+{
+ if (m_type != ExprListMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsExprList(m_operandIndex);
+}
+
+
+const MediumLevelILOperand MediumLevelILOperandList::ListIterator::operator*()
+{
+ MediumLevelILOperandUsage usage = *pos;
+ auto i = owner->m_operandIndexMap.find(usage);
+ if (i == owner->m_operandIndexMap.end())
+ throw MediumLevelILInstructionAccessException();
+ return MediumLevelILOperand(owner->m_instr, usage, i->second);
+}
+
+
+MediumLevelILOperandList::MediumLevelILOperandList(const MediumLevelILInstruction& instr,
+ const vector<MediumLevelILOperandUsage>& usageList,
+ const unordered_map<MediumLevelILOperandUsage, size_t>& operandIndexMap):
+ m_instr(instr), m_usageList(usageList), m_operandIndexMap(operandIndexMap)
+{
+}
+
+
+MediumLevelILOperandList::const_iterator MediumLevelILOperandList::begin() const
+{
+ const_iterator result;
+ result.owner = this;
+ result.pos = m_usageList.begin();
+ return result;
+}
+
+
+MediumLevelILOperandList::const_iterator MediumLevelILOperandList::end() const
+{
+ const_iterator result;
+ result.owner = this;
+ result.pos = m_usageList.end();
+ return result;
+}
+
+
+size_t MediumLevelILOperandList::size() const
+{
+ return m_usageList.size();
+}
+
+
+const MediumLevelILOperand MediumLevelILOperandList::operator[](size_t i) const
+{
+ MediumLevelILOperandUsage usage = m_usageList[i];
+ auto indexMap = m_operandIndexMap.find(usage);
+ if (indexMap == m_operandIndexMap.end())
+ throw MediumLevelILInstructionAccessException();
+ return MediumLevelILOperand(m_instr, usage, indexMap->second);
+}
+
+
+MediumLevelILOperandList::operator vector<MediumLevelILOperand>() const
+{
+ vector<MediumLevelILOperand> result;
+ for (auto& i : *this)
+ result.push_back(i);
+ return result;
+}
+
+
+MediumLevelILInstruction::MediumLevelILInstruction()
+{
+ operation = MLIL_UNDEF;
+ sourceOperand = BN_INVALID_OPERAND;
+ size = 0;
+ address = 0;
+ function = nullptr;
+ exprIndex = BN_INVALID_EXPR;
+ instructionIndex = BN_INVALID_EXPR;
+}
+
+
+MediumLevelILInstruction::MediumLevelILInstruction(MediumLevelILFunction* func,
+ const BNMediumLevelILInstruction& instr, size_t expr, size_t instrIdx)
+{
+ operation = instr.operation;
+ sourceOperand = instr.sourceOperand;
+ size = instr.size;
+ operands[0] = instr.operands[0];
+ operands[1] = instr.operands[1];
+ operands[2] = instr.operands[2];
+ operands[3] = instr.operands[3];
+ operands[4] = instr.operands[4];
+ address = instr.address;
+ function = func;
+ exprIndex = expr;
+ instructionIndex = instrIdx;
+}
+
+
+MediumLevelILInstruction::MediumLevelILInstruction(const MediumLevelILInstructionBase& instr)
+{
+ operation = instr.operation;
+ sourceOperand = instr.sourceOperand;
+ size = instr.size;
+ operands[0] = instr.operands[0];
+ operands[1] = instr.operands[1];
+ operands[2] = instr.operands[2];
+ operands[3] = instr.operands[3];
+ operands[4] = instr.operands[4];
+ address = instr.address;
+ function = instr.function;
+ exprIndex = instr.exprIndex;
+ instructionIndex = instr.instructionIndex;
+}
+
+
+MediumLevelILOperandList MediumLevelILInstructionBase::GetOperands() const
+{
+ auto usage = operationOperandUsage.find(operation);
+ if (usage == operationOperandUsage.end())
+ throw MediumLevelILInstructionAccessException();
+ auto operandIndex = operationOperandIndex.find(operation);
+ if (operandIndex == operationOperandIndex.end())
+ throw MediumLevelILInstructionAccessException();
+ return MediumLevelILOperandList(*(const MediumLevelILInstruction*)this, usage->second, operandIndex->second);
+}
+
+
+uint64_t MediumLevelILInstructionBase::GetRawOperandAsInteger(size_t operand) const
+{
+ return operands[operand];
+}
+
+
+size_t MediumLevelILInstructionBase::GetRawOperandAsIndex(size_t operand) const
+{
+ return (size_t)operands[operand];
+}
+
+
+MediumLevelILInstruction MediumLevelILInstructionBase::GetRawOperandAsExpr(size_t operand) const
+{
+ return MediumLevelILInstruction(function, function->GetRawExpr(operands[operand]), operands[operand], instructionIndex);
+}
+
+
+Variable MediumLevelILInstructionBase::GetRawOperandAsVariable(size_t operand) const
+{
+ return Variable::FromIdentifier(operands[operand]);
+}
+
+
+SSAVariable MediumLevelILInstructionBase::GetRawOperandAsSSAVariable(size_t operand) const
+{
+ return SSAVariable(Variable::FromIdentifier(operands[operand]), (size_t)operands[operand + 1]);
+}
+
+
+SSAVariable MediumLevelILInstructionBase::GetRawOperandAsPartialSSAVariableSource(size_t operand) const
+{
+ return SSAVariable(Variable::FromIdentifier(operands[operand]), (size_t)operands[operand + 2]);
+}
+
+
+MediumLevelILIndexList MediumLevelILInstructionBase::GetRawOperandAsIndexList(size_t operand) const
+{
+ return MediumLevelILIndexList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]);
+}
+
+
+MediumLevelILVariableList MediumLevelILInstructionBase::GetRawOperandAsVariableList(size_t operand) const
+{
+ return MediumLevelILVariableList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]);
+}
+
+
+MediumLevelILSSAVariableList MediumLevelILInstructionBase::GetRawOperandAsSSAVariableList(size_t operand) const
+{
+ return MediumLevelILSSAVariableList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]);
+}
+
+
+MediumLevelILInstructionList MediumLevelILInstructionBase::GetRawOperandAsExprList(size_t operand) const
+{
+ return MediumLevelILInstructionList(function, function->GetRawExpr(operands[operand + 1]), operands[operand],
+ instructionIndex);
+}
+
+
+void MediumLevelILInstructionBase::UpdateRawOperand(size_t operandIndex, ExprId value)
+{
+ operands[operandIndex] = value;
+ function->UpdateInstructionOperand(exprIndex, operandIndex, value);
+}
+
+
+void MediumLevelILInstructionBase::UpdateRawOperandAsSSAVariableList(size_t operandIndex, const vector<SSAVariable>& vars)
+{
+ UpdateRawOperand(operandIndex, vars.size() * 2);
+ UpdateRawOperand(operandIndex + 1, function->AddSSAVariableList(vars));
+}
+
+
+void MediumLevelILInstructionBase::UpdateRawOperandAsExprList(size_t operandIndex, const vector<MediumLevelILInstruction>& exprs)
+{
+ vector<ExprId> exprIndexList;
+ for (auto& i : exprs)
+ exprIndexList.push_back((ExprId)i.exprIndex);
+ UpdateRawOperand(operandIndex, exprIndexList.size());
+ UpdateRawOperand(operandIndex + 1, function->AddOperandList(exprIndexList));
+}
+
+
+void MediumLevelILInstructionBase::UpdateRawOperandAsExprList(size_t operandIndex, const vector<ExprId>& exprs)
+{
+ UpdateRawOperand(operandIndex, exprs.size());
+ UpdateRawOperand(operandIndex + 1, function->AddOperandList(exprs));
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetValue() const
+{
+ return function->GetExprValue(*(const MediumLevelILInstruction*)this);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleValues() const
+{
+ return function->GetPossibleExprValues(*(const MediumLevelILInstruction*)this);
+}
+
+
+Confidence<Ref<Type>> MediumLevelILInstructionBase::GetType() const
+{
+ return function->GetExprType(*(const MediumLevelILInstruction*)this);
+}
+
+
+size_t MediumLevelILInstructionBase::GetSSAVarVersion(const Variable& var)
+{
+ return function->GetSSAVarVersionAtInstruction(var, instructionIndex);
+}
+
+
+size_t MediumLevelILInstructionBase::GetSSAMemoryVersion()
+{
+ return function->GetSSAMemoryVersionAtInstruction(instructionIndex);
+}
+
+
+Variable MediumLevelILInstructionBase::GetVariableForRegister(uint32_t reg)
+{
+ return function->GetVariableForRegisterAtInstruction(reg, instructionIndex);
+}
+
+
+Variable MediumLevelILInstructionBase::GetVariableForFlag(uint32_t flag)
+{
+ return function->GetVariableForFlagAtInstruction(flag, instructionIndex);
+}
+
+
+Variable MediumLevelILInstructionBase::GetVariableForStackLocation(int64_t offset)
+{
+ return function->GetVariableForStackLocationAtInstruction(offset, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleSSAVarValues(const SSAVariable& var)
+{
+ return function->GetPossibleSSAVarValues(var, instructionIndex);
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetRegisterValue(uint32_t reg)
+{
+ return function->GetRegisterValueAtInstruction(reg, instructionIndex);
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetRegisterValueAfter(uint32_t reg)
+{
+ return function->GetRegisterValueAfterInstruction(reg, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleRegisterValues(uint32_t reg)
+{
+ return function->GetPossibleRegisterValuesAtInstruction(reg, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleRegisterValuesAfter(uint32_t reg)
+{
+ return function->GetPossibleRegisterValuesAfterInstruction(reg, instructionIndex);
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetFlagValue(uint32_t flag)
+{
+ return function->GetFlagValueAtInstruction(flag, instructionIndex);
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetFlagValueAfter(uint32_t flag)
+{
+ return function->GetFlagValueAfterInstruction(flag, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleFlagValues(uint32_t flag)
+{
+ return function->GetPossibleFlagValuesAtInstruction(flag, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleFlagValuesAfter(uint32_t flag)
+{
+ return function->GetPossibleFlagValuesAfterInstruction(flag, instructionIndex);
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetStackContents(int32_t offset, size_t len)
+{
+ return function->GetStackContentsAtInstruction(offset, len, instructionIndex);
+}
+
+
+RegisterValue MediumLevelILInstructionBase::GetStackContentsAfter(int32_t offset, size_t len)
+{
+ return function->GetStackContentsAfterInstruction(offset, len, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleStackContents(int32_t offset, size_t len)
+{
+ return function->GetPossibleStackContentsAtInstruction(offset, len, instructionIndex);
+}
+
+
+PossibleValueSet MediumLevelILInstructionBase::GetPossibleStackContentsAfter(int32_t offset, size_t len)
+{
+ return function->GetPossibleStackContentsAfterInstruction(offset, len, instructionIndex);
+}
+
+
+BNILBranchDependence MediumLevelILInstructionBase::GetBranchDependence(size_t branchInstr)
+{
+ return function->GetBranchDependenceAtInstruction(instructionIndex, branchInstr);
+}
+
+
+BNILBranchDependence MediumLevelILInstructionBase::GetBranchDependence(const MediumLevelILInstruction& branch)
+{
+ return GetBranchDependence(branch.instructionIndex);
+}
+
+
+unordered_map<size_t, BNILBranchDependence> MediumLevelILInstructionBase::GetAllBranchDependence()
+{
+ return function->GetAllBranchDependenceAtInstruction(instructionIndex);
+}
+
+
+size_t MediumLevelILInstructionBase::GetSSAInstructionIndex() const
+{
+ return function->GetSSAInstructionIndex(instructionIndex);
+}
+
+
+size_t MediumLevelILInstructionBase::GetNonSSAInstructionIndex() const
+{
+ return function->GetNonSSAInstructionIndex(instructionIndex);
+}
+
+
+size_t MediumLevelILInstructionBase::GetSSAExprIndex() const
+{
+ return function->GetSSAExprIndex(exprIndex);
+}
+
+
+size_t MediumLevelILInstructionBase::GetNonSSAExprIndex() const
+{
+ return function->GetNonSSAExprIndex(exprIndex);
+}
+
+
+MediumLevelILInstruction MediumLevelILInstructionBase::GetSSAForm() const
+{
+ Ref<MediumLevelILFunction> ssa = function->GetSSAForm().GetPtr();
+ if (!ssa)
+ return *this;
+ size_t expr = GetSSAExprIndex();
+ size_t instr = GetSSAInstructionIndex();
+ return MediumLevelILInstruction(ssa, ssa->GetRawExpr(GetSSAExprIndex()), expr, instr);
+}
+
+
+MediumLevelILInstruction MediumLevelILInstructionBase::GetNonSSAForm() const
+{
+ Ref<MediumLevelILFunction> nonSsa = function->GetNonSSAForm();
+ if (!nonSsa)
+ return *this;
+ size_t expr = GetNonSSAExprIndex();
+ size_t instr = GetNonSSAInstructionIndex();
+ return MediumLevelILInstruction(nonSsa, nonSsa->GetRawExpr(GetSSAExprIndex()), expr, instr);
+}
+
+
+size_t MediumLevelILInstructionBase::GetLowLevelILInstructionIndex() const
+{
+ return function->GetLowLevelILInstructionIndex(instructionIndex);
+}
+
+
+size_t MediumLevelILInstructionBase::GetLowLevelILExprIndex() const
+{
+ return function->GetLowLevelILExprIndex(exprIndex);
+}
+
+
+bool MediumLevelILInstructionBase::HasLowLevelIL() const
+{
+ Ref<LowLevelILFunction> func = function->GetLowLevelIL();
+ if (!func)
+ return false;
+ return GetLowLevelILExprIndex() < func->GetExprCount();
+}
+
+
+LowLevelILInstruction MediumLevelILInstructionBase::GetLowLevelIL() const
+{
+ Ref<LowLevelILFunction> func = function->GetLowLevelIL();
+ if (!func)
+ throw LowLevelILInstructionAccessException();
+ size_t expr = GetLowLevelILExprIndex();
+ if (GetLowLevelILExprIndex() >= func->GetExprCount())
+ throw LowLevelILInstructionAccessException();
+ return func->GetExpr(expr);
+}
+
+
+void MediumLevelILInstructionBase::MarkInstructionForRemoval()
+{
+ function->MarkInstructionForRemoval(instructionIndex);
+}
+
+
+void MediumLevelILInstructionBase::Replace(ExprId expr)
+{
+ function->ReplaceExpr(exprIndex, expr);
+}
+
+
+void MediumLevelILInstruction::VisitExprs(const std::function<bool(const MediumLevelILInstruction& expr)>& func) const
+{
+ if (!func(*this))
+ return;
+ switch (operation)
+ {
+ case MLIL_SET_VAR:
+ GetSourceExpr<MLIL_SET_VAR>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_SSA:
+ GetSourceExpr<MLIL_SET_VAR_SSA>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_ALIASED:
+ GetSourceExpr<MLIL_SET_VAR_ALIASED>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_SPLIT:
+ GetSourceExpr<MLIL_SET_VAR_SPLIT>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_SPLIT_SSA:
+ GetSourceExpr<MLIL_SET_VAR_SPLIT_SSA>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_FIELD:
+ GetSourceExpr<MLIL_SET_VAR_FIELD>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_SSA_FIELD:
+ GetSourceExpr<MLIL_SET_VAR_SSA_FIELD>().VisitExprs(func);
+ break;
+ case MLIL_SET_VAR_ALIASED_FIELD:
+ GetSourceExpr<MLIL_SET_VAR_ALIASED_FIELD>().VisitExprs(func);
+ break;
+ case MLIL_CALL:
+ GetDestExpr<MLIL_CALL>().VisitExprs(func);
+ for (auto& i : GetParameterExprs<MLIL_CALL>())
+ i.VisitExprs(func);
+ break;
+ case MLIL_CALL_UNTYPED:
+ GetDestExpr<MLIL_CALL_UNTYPED>().VisitExprs(func);
+ break;
+ case MLIL_CALL_SSA:
+ GetDestExpr<MLIL_CALL_SSA>().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);
+ break;
+ case MLIL_SYSCALL:
+ for (auto& i : GetParameterExprs<MLIL_SYSCALL>())
+ i.VisitExprs(func);
+ break;
+ case MLIL_SYSCALL_SSA:
+ for (auto& i : GetParameterExprs<MLIL_SYSCALL_SSA>())
+ i.VisitExprs(func);
+ break;
+ case MLIL_RET:
+ for (auto& i : GetSourceExprs<MLIL_RET>())
+ i.VisitExprs(func);
+ break;
+ case MLIL_STORE:
+ GetDestExpr<MLIL_STORE>().VisitExprs(func);
+ GetSourceExpr<MLIL_STORE>().VisitExprs(func);
+ break;
+ case MLIL_STORE_STRUCT:
+ GetDestExpr<MLIL_STORE_STRUCT>().VisitExprs(func);
+ GetSourceExpr<MLIL_STORE_STRUCT>().VisitExprs(func);
+ break;
+ case MLIL_STORE_SSA:
+ GetDestExpr<MLIL_STORE_SSA>().VisitExprs(func);
+ GetSourceExpr<MLIL_STORE_SSA>().VisitExprs(func);
+ break;
+ case MLIL_STORE_STRUCT_SSA:
+ GetDestExpr<MLIL_STORE_STRUCT_SSA>().VisitExprs(func);
+ GetSourceExpr<MLIL_STORE_STRUCT_SSA>().VisitExprs(func);
+ break;
+ case MLIL_NEG:
+ case MLIL_NOT:
+ case MLIL_SX:
+ case MLIL_ZX:
+ case MLIL_LOW_PART:
+ case MLIL_BOOL_TO_INT:
+ case MLIL_JUMP:
+ case MLIL_JUMP_TO:
+ case MLIL_IF:
+ case MLIL_UNIMPL_MEM:
+ case MLIL_LOAD:
+ case MLIL_LOAD_STRUCT:
+ case MLIL_LOAD_SSA:
+ case MLIL_LOAD_STRUCT_SSA:
+ AsOneOperand().GetSourceExpr().VisitExprs(func);
+ break;
+ case MLIL_ADD:
+ case MLIL_SUB:
+ case MLIL_AND:
+ case MLIL_OR:
+ case MLIL_XOR:
+ case MLIL_LSL:
+ case MLIL_LSR:
+ case MLIL_ASR:
+ case MLIL_ROL:
+ case MLIL_ROR:
+ case MLIL_MUL:
+ case MLIL_MULU_DP:
+ case MLIL_MULS_DP:
+ case MLIL_DIVU:
+ case MLIL_DIVS:
+ case MLIL_MODU:
+ case MLIL_MODS:
+ case MLIL_CMP_E:
+ case MLIL_CMP_NE:
+ case MLIL_CMP_SLT:
+ case MLIL_CMP_ULT:
+ case MLIL_CMP_SLE:
+ case MLIL_CMP_ULE:
+ case MLIL_CMP_SGE:
+ case MLIL_CMP_UGE:
+ case MLIL_CMP_SGT:
+ case MLIL_CMP_UGT:
+ case MLIL_TEST_BIT:
+ case MLIL_ADD_OVERFLOW:
+ AsTwoOperand().GetLeftExpr().VisitExprs(func);
+ AsTwoOperand().GetRightExpr().VisitExprs(func);
+ break;
+ case MLIL_ADC:
+ case MLIL_SBB:
+ case MLIL_RLC:
+ case MLIL_RRC:
+ AsTwoOperandWithCarry().GetLeftExpr().VisitExprs(func);
+ AsTwoOperandWithCarry().GetRightExpr().VisitExprs(func);
+ AsTwoOperandWithCarry().GetCarryExpr().VisitExprs(func);
+ break;
+ case MLIL_DIVU_DP:
+ case MLIL_DIVS_DP:
+ case MLIL_MODU_DP:
+ case MLIL_MODS_DP:
+ AsDoublePrecision().GetHighExpr().VisitExprs(func);
+ AsDoublePrecision().GetLowExpr().VisitExprs(func);
+ AsDoublePrecision().GetRightExpr().VisitExprs(func);
+ break;
+ default:
+ break;
+ }
+}
+
+
+ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest) const
+{
+ return CopyTo(dest, [&](const MediumLevelILInstruction& subExpr) {
+ return subExpr.CopyTo(dest);
+ });
+}
+
+
+ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
+ const std::function<ExprId(const MediumLevelILInstruction& subExpr)>& subExprHandler) const
+{
+ vector<ExprId> params;
+ vector<BNMediumLevelILLabel*> labelList;
+ BNMediumLevelILLabel* labelA;
+ BNMediumLevelILLabel* labelB;
+ switch (operation)
+ {
+ case MLIL_NOP:
+ return dest->Nop(*this);
+ case MLIL_SET_VAR:
+ return dest->SetVar(size, GetDestVariable<MLIL_SET_VAR>(),
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR>()), *this);
+ case MLIL_SET_VAR_SSA:
+ return dest->SetVarSSA(size, GetDestSSAVariable<MLIL_SET_VAR_SSA>(),
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR_SSA>()), *this);
+ case MLIL_SET_VAR_ALIASED:
+ return dest->SetVarAliased(size, GetDestSSAVariable<MLIL_SET_VAR_ALIASED>().var,
+ GetDestSSAVariable<MLIL_SET_VAR_ALIASED>().version,
+ GetSourceSSAVariable<MLIL_SET_VAR_ALIASED>().version,
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR_ALIASED>()), *this);
+ case MLIL_SET_VAR_SPLIT:
+ return dest->SetVarSplit(size, GetHighVariable<MLIL_SET_VAR_SPLIT>(),
+ GetLowVariable<MLIL_SET_VAR_SPLIT>(),
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR_SPLIT>()), *this);
+ case MLIL_SET_VAR_SPLIT_SSA:
+ return dest->SetVarSSASplit(size, GetHighSSAVariable<MLIL_SET_VAR_SPLIT_SSA>(),
+ GetLowSSAVariable<MLIL_SET_VAR_SPLIT_SSA>(),
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR_SPLIT_SSA>()), *this);
+ case MLIL_SET_VAR_FIELD:
+ return dest->SetVarField(size, GetDestVariable<MLIL_SET_VAR_FIELD>(),
+ GetOffset<MLIL_SET_VAR_FIELD>(), subExprHandler(GetSourceExpr<MLIL_SET_VAR_FIELD>()), *this);
+ case MLIL_SET_VAR_SSA_FIELD:
+ return dest->SetVarSSAField(size, GetDestSSAVariable<MLIL_SET_VAR_SSA_FIELD>().var,
+ GetDestSSAVariable<MLIL_SET_VAR_SSA_FIELD>().version,
+ GetSourceSSAVariable<MLIL_SET_VAR_SSA_FIELD>().version,
+ GetOffset<MLIL_SET_VAR_SSA_FIELD>(),
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR_SSA_FIELD>()), *this);
+ case MLIL_SET_VAR_ALIASED_FIELD:
+ return dest->SetVarAliasedField(size, GetDestSSAVariable<MLIL_SET_VAR_ALIASED_FIELD>().var,
+ GetDestSSAVariable<MLIL_SET_VAR_ALIASED_FIELD>().version,
+ GetSourceSSAVariable<MLIL_SET_VAR_ALIASED_FIELD>().version,
+ GetOffset<MLIL_SET_VAR_ALIASED_FIELD>(),
+ subExprHandler(GetSourceExpr<MLIL_SET_VAR_ALIASED_FIELD>()), *this);
+ case MLIL_VAR:
+ return dest->Var(size, GetSourceVariable<MLIL_VAR>(), *this);
+ case MLIL_VAR_FIELD:
+ return dest->VarField(size, GetSourceVariable<MLIL_VAR_FIELD>(),
+ GetOffset<MLIL_VAR_FIELD>(), *this);
+ case MLIL_VAR_SSA:
+ return dest->VarSSA(size, GetSourceSSAVariable<MLIL_VAR_SSA>(), *this);
+ case MLIL_VAR_SSA_FIELD:
+ return dest->VarSSAField(size, GetSourceSSAVariable<MLIL_VAR_SSA_FIELD>(),
+ GetOffset<MLIL_VAR_SSA_FIELD>(), *this);
+ case MLIL_VAR_ALIASED:
+ return dest->VarAliased(size, GetSourceSSAVariable<MLIL_VAR_ALIASED>().var,
+ GetSourceSSAVariable<MLIL_VAR_ALIASED>().version, *this);
+ case MLIL_VAR_ALIASED_FIELD:
+ return dest->VarAliasedField(size, GetSourceSSAVariable<MLIL_VAR_ALIASED_FIELD>().var,
+ GetSourceSSAVariable<MLIL_VAR_ALIASED_FIELD>().version,
+ GetOffset<MLIL_VAR_ALIASED_FIELD>(), *this);
+ case MLIL_ADDRESS_OF:
+ return dest->AddressOf(GetSourceVariable<MLIL_ADDRESS_OF>(), *this);
+ case MLIL_ADDRESS_OF_FIELD:
+ return dest->AddressOfField(GetSourceVariable<MLIL_ADDRESS_OF_FIELD>(),
+ GetOffset<MLIL_ADDRESS_OF_FIELD>(), *this);
+ case MLIL_CALL:
+ for (auto& i : GetParameterExprs<MLIL_CALL>())
+ params.push_back(subExprHandler(i));
+ return dest->Call(GetOutputVariables<MLIL_CALL>(), subExprHandler(GetDestExpr<MLIL_CALL>()),
+ params, *this);
+ case MLIL_CALL_UNTYPED:
+ return dest->CallUntyped(GetOutputVariables<MLIL_CALL_UNTYPED>(),
+ subExprHandler(GetDestExpr<MLIL_CALL_UNTYPED>()), GetParameterVariables<MLIL_CALL_UNTYPED>(),
+ subExprHandler(GetStackExpr<MLIL_CALL_UNTYPED>()), *this);
+ case MLIL_CALL_SSA:
+ for (auto& i : GetParameterExprs<MLIL_CALL_SSA>())
+ params.push_back(subExprHandler(i));
+ return dest->CallSSA(GetOutputSSAVariables<MLIL_CALL_SSA>(), subExprHandler(GetDestExpr<MLIL_CALL_SSA>()),
+ params, GetDestMemoryVersion<MLIL_CALL_SSA>(), GetSourceMemoryVersion<MLIL_CALL_SSA>(), *this);
+ case MLIL_CALL_UNTYPED_SSA:
+ return dest->CallUntypedSSA(GetOutputSSAVariables<MLIL_CALL_UNTYPED_SSA>(),
+ subExprHandler(GetDestExpr<MLIL_CALL_UNTYPED_SSA>()),
+ GetParameterSSAVariables<MLIL_CALL_UNTYPED_SSA>(),
+ GetDestMemoryVersion<MLIL_CALL_UNTYPED_SSA>(),
+ GetSourceMemoryVersion<MLIL_CALL_UNTYPED_SSA>(),
+ subExprHandler(GetStackExpr<MLIL_CALL_UNTYPED_SSA>()), *this);
+ case MLIL_SYSCALL:
+ for (auto& i : GetParameterExprs<MLIL_SYSCALL>())
+ params.push_back(subExprHandler(i));
+ return dest->Syscall(GetOutputVariables<MLIL_SYSCALL>(), params, *this);
+ case MLIL_SYSCALL_UNTYPED:
+ return dest->SyscallUntyped(GetOutputVariables<MLIL_SYSCALL_UNTYPED>(),
+ GetParameterVariables<MLIL_SYSCALL_UNTYPED>(),
+ subExprHandler(GetStackExpr<MLIL_SYSCALL_UNTYPED>()), *this);
+ case MLIL_SYSCALL_SSA:
+ for (auto& i : GetParameterExprs<MLIL_SYSCALL_SSA>())
+ params.push_back(subExprHandler(i));
+ return dest->SyscallSSA(GetOutputSSAVariables<MLIL_SYSCALL_SSA>(), params,
+ GetDestMemoryVersion<MLIL_SYSCALL_SSA>(), GetSourceMemoryVersion<MLIL_SYSCALL_SSA>(), *this);
+ case MLIL_SYSCALL_UNTYPED_SSA:
+ return dest->SyscallUntypedSSA(GetOutputSSAVariables<MLIL_SYSCALL_UNTYPED_SSA>(),
+ GetParameterSSAVariables<MLIL_SYSCALL_UNTYPED_SSA>(),
+ GetDestMemoryVersion<MLIL_SYSCALL_UNTYPED_SSA>(),
+ GetSourceMemoryVersion<MLIL_SYSCALL_UNTYPED_SSA>(),
+ subExprHandler(GetStackExpr<MLIL_SYSCALL_UNTYPED_SSA>()), *this);
+ case MLIL_RET:
+ for (auto& i : GetSourceExprs<MLIL_RET>())
+ params.push_back(subExprHandler(i));
+ return dest->Return(params, *this);
+ case MLIL_NORET:
+ return dest->NoReturn(*this);
+ case MLIL_STORE:
+ return dest->Store(size, subExprHandler(GetDestExpr<MLIL_STORE>()),
+ subExprHandler(GetSourceExpr<MLIL_STORE>()), *this);
+ case MLIL_STORE_STRUCT:
+ return dest->StoreStruct(size, subExprHandler(GetDestExpr<MLIL_STORE_STRUCT>()),
+ GetOffset<MLIL_STORE_STRUCT>(), subExprHandler(GetSourceExpr<MLIL_STORE_STRUCT>()), *this);
+ case MLIL_STORE_SSA:
+ return dest->StoreSSA(size, subExprHandler(GetDestExpr<MLIL_STORE_SSA>()),
+ GetDestMemoryVersion<MLIL_STORE_SSA>(), GetSourceMemoryVersion<MLIL_STORE_SSA>(),
+ subExprHandler(GetSourceExpr<MLIL_STORE_SSA>()), *this);
+ case MLIL_STORE_STRUCT_SSA:
+ return dest->StoreStructSSA(size, subExprHandler(GetDestExpr<MLIL_STORE_STRUCT_SSA>()),
+ GetOffset<MLIL_STORE_STRUCT_SSA>(),
+ GetDestMemoryVersion<MLIL_STORE_STRUCT_SSA>(), GetSourceMemoryVersion<MLIL_STORE_STRUCT_SSA>(),
+ subExprHandler(GetSourceExpr<MLIL_STORE_STRUCT_SSA>()), *this);
+ case MLIL_LOAD:
+ return dest->Load(size, subExprHandler(GetSourceExpr<MLIL_LOAD>()), *this);
+ case MLIL_LOAD_STRUCT:
+ return dest->LoadStruct(size, subExprHandler(GetSourceExpr<MLIL_LOAD_STRUCT>()),
+ GetOffset<MLIL_LOAD_STRUCT>(), *this);
+ case MLIL_LOAD_SSA:
+ return dest->LoadSSA(size, subExprHandler(GetSourceExpr<MLIL_LOAD_SSA>()),
+ GetSourceMemoryVersion<MLIL_LOAD_SSA>(), *this);
+ case MLIL_LOAD_STRUCT_SSA:
+ return dest->LoadStructSSA(size, subExprHandler(GetSourceExpr<MLIL_LOAD_STRUCT_SSA>()),
+ GetOffset<MLIL_LOAD_STRUCT_SSA>(), GetSourceMemoryVersion<MLIL_LOAD_STRUCT_SSA>(), *this);
+ case MLIL_NEG:
+ case MLIL_NOT:
+ case MLIL_SX:
+ case MLIL_ZX:
+ case MLIL_LOW_PART:
+ case MLIL_BOOL_TO_INT:
+ case MLIL_JUMP:
+ case MLIL_UNIMPL_MEM:
+ return dest->AddExprWithLocation(operation, *this, size,
+ subExprHandler(AsOneOperand().GetSourceExpr()));
+ case MLIL_ADD:
+ case MLIL_SUB:
+ case MLIL_AND:
+ case MLIL_OR:
+ case MLIL_XOR:
+ case MLIL_LSL:
+ case MLIL_LSR:
+ case MLIL_ASR:
+ case MLIL_ROL:
+ case MLIL_ROR:
+ case MLIL_MUL:
+ case MLIL_MULU_DP:
+ case MLIL_MULS_DP:
+ case MLIL_DIVU:
+ case MLIL_DIVS:
+ case MLIL_MODU:
+ case MLIL_MODS:
+ case MLIL_CMP_E:
+ case MLIL_CMP_NE:
+ case MLIL_CMP_SLT:
+ case MLIL_CMP_ULT:
+ case MLIL_CMP_SLE:
+ case MLIL_CMP_ULE:
+ case MLIL_CMP_SGE:
+ case MLIL_CMP_UGE:
+ case MLIL_CMP_SGT:
+ case MLIL_CMP_UGT:
+ case MLIL_TEST_BIT:
+ case MLIL_ADD_OVERFLOW:
+ return dest->AddExprWithLocation(operation, *this, size,
+ subExprHandler(AsTwoOperand().GetLeftExpr()), subExprHandler(AsTwoOperand().GetRightExpr()));
+ case MLIL_ADC:
+ case MLIL_SBB:
+ case MLIL_RLC:
+ case MLIL_RRC:
+ return dest->AddExprWithLocation(operation, *this, size,
+ subExprHandler(AsTwoOperandWithCarry().GetLeftExpr()),
+ subExprHandler(AsTwoOperandWithCarry().GetRightExpr()),
+ subExprHandler(AsTwoOperandWithCarry().GetCarryExpr()));
+ case MLIL_DIVU_DP:
+ case MLIL_DIVS_DP:
+ case MLIL_MODU_DP:
+ case MLIL_MODS_DP:
+ return dest->AddExprWithLocation(operation, *this, size,
+ subExprHandler(AsDoublePrecision().GetHighExpr()),
+ subExprHandler(AsDoublePrecision().GetLowExpr()),
+ subExprHandler(AsDoublePrecision().GetRightExpr()));
+ case MLIL_JUMP_TO:
+ for (auto target : GetTargetList<MLIL_JUMP_TO>())
+ {
+ labelA = dest->GetLabelForSourceInstruction(target);
+ if (!labelA)
+ return dest->Jump(subExprHandler(GetDestExpr<MLIL_JUMP_TO>()), *this);
+ labelList.push_back(labelA);
+ }
+ return dest->JumpTo(subExprHandler(GetDestExpr<MLIL_JUMP_TO>()), labelList, *this);
+ case MLIL_GOTO:
+ labelA = dest->GetLabelForSourceInstruction(GetTarget<MLIL_GOTO>());
+ if (!labelA)
+ {
+ return dest->Jump(dest->ConstPointer(function->GetArchitecture()->GetAddressSize(),
+ function->GetInstruction(GetTarget<MLIL_GOTO>()).address), *this);
+ }
+ return dest->Goto(*labelA, *this);
+ case MLIL_IF:
+ labelA = dest->GetLabelForSourceInstruction(GetTrueTarget<MLIL_IF>());
+ labelB = dest->GetLabelForSourceInstruction(GetFalseTarget<MLIL_IF>());
+ if ((!labelA) || (!labelB))
+ return dest->Undefined(*this);
+ return dest->If(subExprHandler(GetConditionExpr<MLIL_IF>()), *labelA, *labelB, *this);
+ case MLIL_CONST:
+ return dest->Const(size, GetConstant<MLIL_CONST>(), *this);
+ case MLIL_CONST_PTR:
+ return dest->ConstPointer(size, GetConstant<MLIL_CONST_PTR>(), *this);
+ case MLIL_BP:
+ return dest->Breakpoint(*this);
+ case MLIL_TRAP:
+ return dest->Trap(GetVector<MLIL_TRAP>(), *this);
+ case MLIL_UNDEF:
+ return dest->Undefined(*this);
+ case MLIL_UNIMPL:
+ return dest->Unimplemented(*this);
+ default:
+ throw MediumLevelILInstructionAccessException();
+ }
+}
+
+
+bool MediumLevelILInstruction::GetOperandIndexForUsage(MediumLevelILOperandUsage usage, size_t& operandIndex) const
+{
+ auto operationIter = MediumLevelILInstructionBase::operationOperandIndex.find(operation);
+ if (operationIter == MediumLevelILInstructionBase::operationOperandIndex.end())
+ return false;
+ auto usageIter = operationIter->second.find(usage);
+ if (usageIter == operationIter->second.end())
+ return false;
+ operandIndex = usageIter->second;
+ return true;
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetSourceExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+Variable MediumLevelILInstruction::GetSourceVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+SSAVariable MediumLevelILInstruction::GetSourceSSAVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceSSAVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsSSAVariable(operandIndex);
+ if (GetOperandIndexForUsage(PartialSSAVariableSourceMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsPartialSSAVariableSource(operandIndex - 2);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetDestExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(DestExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+Variable MediumLevelILInstruction::GetDestVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(DestVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+SSAVariable MediumLevelILInstruction::GetDestSSAVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(DestSSAVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsSSAVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetLeftExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(LeftExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetRightExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(RightExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetCarryExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(CarryExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetHighExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(HighExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetLowExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(LowExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetStackExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(StackExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstruction MediumLevelILInstruction::GetConditionExpr() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ConditionExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+Variable MediumLevelILInstruction::GetHighVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(HighVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+Variable MediumLevelILInstruction::GetLowVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(LowVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+SSAVariable MediumLevelILInstruction::GetHighSSAVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(HighSSAVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsSSAVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+SSAVariable MediumLevelILInstruction::GetLowSSAVariable() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(LowSSAVariableMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsSSAVariable(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+uint64_t MediumLevelILInstruction::GetOffset() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(OffsetMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsInteger(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+int64_t MediumLevelILInstruction::GetConstant() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ConstantMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsInteger(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+int64_t MediumLevelILInstruction::GetVector() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(VectorMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsInteger(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+size_t MediumLevelILInstruction::GetTarget() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(TargetMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndex(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+size_t MediumLevelILInstruction::GetTrueTarget() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(TrueTargetMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndex(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+size_t MediumLevelILInstruction::GetFalseTarget() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(FalseTargetMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndex(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+size_t MediumLevelILInstruction::GetDestMemoryVersion() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(DestMemoryVersionMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndex(operandIndex);
+ if (GetOperandIndexForUsage(OutputSSAMemoryVersionMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsIndex(0);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+size_t MediumLevelILInstruction::GetSourceMemoryVersion() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceMemoryVersionMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndex(operandIndex);
+ if (GetOperandIndexForUsage(ParameterSSAMemoryVersionMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsIndex(0);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILIndexList MediumLevelILInstruction::GetTargetList() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(TargetListMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndexList(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILIndexList MediumLevelILInstruction::GetSourceMemoryVersions() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceMemoryVersionsMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsIndexList(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILVariableList MediumLevelILInstruction::GetOutputVariables() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(OutputVariablesMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsVariableList(operandIndex);
+ if (GetOperandIndexForUsage(OutputVariablesSubExprMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsVariableList(0);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILSSAVariableList MediumLevelILInstruction::GetOutputSSAVariables() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(OutputSSAVariablesMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsSSAVariableList(1);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstructionList MediumLevelILInstruction::GetParameterExprs() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ParameterExprsMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExprList(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILInstructionList MediumLevelILInstruction::GetSourceExprs() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceExprsMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExprList(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILVariableList MediumLevelILInstruction::GetParameterVariables() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ParameterVariablesMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsVariableList(0);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILSSAVariableList MediumLevelILInstruction::GetParameterSSAVariables() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ParameterSSAVariablesMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsExpr(operandIndex).GetRawOperandAsSSAVariableList(1);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+MediumLevelILSSAVariableList MediumLevelILInstruction::GetSourceSSAVariables() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(SourceSSAVariablesMediumLevelOperandUsages, operandIndex))
+ return GetRawOperandAsSSAVariableList(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
+ExprId MediumLevelILFunction::Nop(const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_NOP, loc, 0);
+}
+
+
+ExprId MediumLevelILFunction::SetVar(size_t size, const Variable& dest, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR, loc, size, dest.ToIdentifier(), src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarField(size_t size, const Variable& dest, uint64_t offset, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_FIELD, loc, size, dest.ToIdentifier(), offset, src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_SPLIT, loc, size, high.ToIdentifier(), low.ToIdentifier(), src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarSSA(size_t size, const SSAVariable& dest, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_SSA, loc, size, dest.var.ToIdentifier(), dest.version, src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarSSAField(size_t size, const Variable& dest,
+ size_t newVersion, size_t prevVersion, uint64_t offset, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_SSA_FIELD, loc, size, dest.ToIdentifier(), newVersion, prevVersion,
+ offset, src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarSSASplit(size_t size, const SSAVariable& high, const SSAVariable& low,
+ ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_SPLIT_SSA, loc, size, high.var.ToIdentifier(), high.version,
+ low.var.ToIdentifier(), low.version, src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& dest,
+ size_t newMemVersion, size_t prevMemVersion,
+ ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_ALIASED, loc, size, dest.ToIdentifier(),
+ newMemVersion, prevMemVersion, src);
+}
+
+
+ExprId MediumLevelILFunction::SetVarAliasedField(size_t size, const Variable& dest,
+ size_t newMemVersion, size_t prevMemVersion,
+ uint64_t offset, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SET_VAR_ALIASED_FIELD, loc, size, dest.ToIdentifier(),
+ newMemVersion, prevMemVersion, offset, src);
+}
+
+
+ExprId MediumLevelILFunction::Load(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LOAD, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::LoadStruct(size_t size, ExprId src, uint64_t offset,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LOAD_STRUCT, loc, size, src, offset);
+}
+
+
+ExprId MediumLevelILFunction::LoadSSA(size_t size, ExprId src, size_t memVersion,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LOAD_SSA, loc, size, src, memVersion);
+}
+
+
+ExprId MediumLevelILFunction::LoadStructSSA(size_t size, ExprId src, uint64_t offset, size_t memVersion,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LOAD_STRUCT_SSA, loc, size, src, offset, memVersion);
+}
+
+
+ExprId MediumLevelILFunction::Store(size_t size, ExprId dest, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_STORE, loc, size, dest, src);
+}
+
+
+ExprId MediumLevelILFunction::StoreStruct(size_t size, ExprId dest, uint64_t offset, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_STORE_STRUCT, loc, size, dest, offset, src);
+}
+
+
+ExprId MediumLevelILFunction::StoreSSA(size_t size, ExprId dest,
+ size_t newMemVersion, size_t prevMemVersion, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_STORE_SSA, loc, size, dest, newMemVersion, prevMemVersion, src);
+}
+
+
+ExprId MediumLevelILFunction::StoreStructSSA(size_t size, ExprId dest, uint64_t offset,
+ size_t newMemVersion, size_t prevMemVersion, ExprId src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_STORE_STRUCT_SSA, loc, size, dest, offset, newMemVersion, prevMemVersion, src);
+}
+
+
+ExprId MediumLevelILFunction::Var(size_t size, const Variable& src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR, loc, size, src.ToIdentifier());
+}
+
+
+ExprId MediumLevelILFunction::VarField(size_t size, const Variable& src, uint64_t offset,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_FIELD, loc, size, src.ToIdentifier(), offset);
+}
+
+
+ExprId MediumLevelILFunction::VarSSA(size_t size, const SSAVariable& src,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_SSA, loc, size, src.var.ToIdentifier(), src.version);
+}
+
+
+ExprId MediumLevelILFunction::VarSSAField(size_t size, const SSAVariable& src, uint64_t offset,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_SSA_FIELD, loc, size, src.var.ToIdentifier(), src.version, offset);
+}
+
+
+ExprId MediumLevelILFunction::VarAliased(size_t size, const Variable& src, size_t memVersion,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_ALIASED, loc, size, src.ToIdentifier(), memVersion);
+}
+
+
+ExprId MediumLevelILFunction::VarAliasedField(size_t size, const Variable& src,
+ size_t memVersion, uint64_t offset, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_ALIASED_FIELD, loc, size, src.ToIdentifier(), memVersion, offset);
+}
+
+
+ExprId MediumLevelILFunction::AddressOf(const Variable& var, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ADDRESS_OF, loc, 0, var.ToIdentifier());
+}
+
+
+ExprId MediumLevelILFunction::AddressOfField(const Variable& var, uint64_t offset,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ADDRESS_OF_FIELD, loc, 0, var.ToIdentifier(), offset);
+}
+
+
+ExprId MediumLevelILFunction::Const(size_t size, uint64_t val, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CONST, loc, size, val);
+}
+
+
+ExprId MediumLevelILFunction::ConstPointer(size_t size, uint64_t val, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CONST_PTR, loc, size, val);
+}
+
+
+ExprId MediumLevelILFunction::Add(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ADD, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::AddWithCarry(size_t size, ExprId left, ExprId right, ExprId carry,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ADC, loc, size, left, right, carry);
+}
+
+
+ExprId MediumLevelILFunction::Sub(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SUB, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::SubWithBorrow(size_t size, ExprId left, ExprId right, ExprId carry,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SBB, loc, size, left, right, carry);
+}
+
+
+ExprId MediumLevelILFunction::And(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_AND, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::Or(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_OR, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::Xor(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_XOR, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::ShiftLeft(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LSL, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::LogicalShiftRight(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LSR, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::ArithShiftRight(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ASR, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::RotateLeft(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ROL, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::RotateLeftCarry(size_t size, ExprId left, ExprId right, ExprId carry,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_RRC, loc, size, left, right, carry);
+}
+
+
+ExprId MediumLevelILFunction::RotateRight(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ROR, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::RotateRightCarry(size_t size, ExprId left, ExprId right, ExprId carry,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_RRC, loc, size, left, right, carry);
+}
+
+
+ExprId MediumLevelILFunction::Mult(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MUL, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::MultDoublePrecSigned(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MULS_DP, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::MultDoublePrecUnsigned(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MULU_DP, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::DivSigned(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_DIVS, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::DivUnsigned(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_DIVU, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::DivDoublePrecSigned(size_t size, ExprId high, ExprId low, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_DIVS_DP, loc, size, high, low, right);
+}
+
+
+ExprId MediumLevelILFunction::DivDoublePrecUnsigned(size_t size, ExprId high, ExprId low, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_DIVU_DP, loc, size, high, low, right);
+}
+
+
+ExprId MediumLevelILFunction::ModSigned(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MODS, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::ModUnsigned(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MODU, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::ModDoublePrecSigned(size_t size, ExprId high, ExprId low, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MODS_DP, loc, size, high, low, right);
+}
+
+
+ExprId MediumLevelILFunction::ModDoublePrecUnsigned(size_t size, ExprId high, ExprId low, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MODU_DP, loc, size, high, low, right);
+}
+
+
+ExprId MediumLevelILFunction::Neg(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_NEG, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::Not(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_NOT, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::SignExtend(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SX, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::ZeroExtend(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ZX, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::LowPart(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_LOW_PART, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::Jump(ExprId dest, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_JUMP, loc, 0, dest);
+}
+
+
+ExprId MediumLevelILFunction::JumpTo(ExprId dest, const vector<BNMediumLevelILLabel*>& targets,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_JUMP_TO, loc, 0, dest, targets.size(), AddLabelList(targets));
+}
+
+
+ExprId MediumLevelILFunction::Call(const vector<Variable>& 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));
+}
+
+
+ExprId MediumLevelILFunction::CallUntyped(const vector<Variable>& output, ExprId dest,
+ const vector<Variable>& params, ExprId stack, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CALL_UNTYPED, loc, 0,
+ AddExprWithLocation(MLIL_CALL_OUTPUT, loc, 0, output.size(), AddVariableList(output)), dest,
+ AddExprWithLocation(MLIL_CALL_PARAM, loc, 0, params.size(), AddVariableList(params)), stack);
+}
+
+
+ExprId MediumLevelILFunction::Syscall(const vector<Variable>& output, const vector<ExprId>& params,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SYSCALL, loc, 0, output.size(), AddVariableList(output),
+ params.size(), AddOperandList(params));
+}
+
+
+ExprId MediumLevelILFunction::SyscallUntyped(const vector<Variable>& output, const vector<Variable>& params,
+ ExprId stack, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_SYSCALL_UNTYPED, loc, 0,
+ AddExprWithLocation(MLIL_CALL_OUTPUT, loc, 0, output.size(), AddVariableList(output)),
+ AddExprWithLocation(MLIL_CALL_PARAM, loc, 0, params.size(), AddVariableList(params)), stack);
+}
+
+
+ExprId MediumLevelILFunction::CallSSA(const vector<SSAVariable>& 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)), dest,
+ params.size(), AddOperandList(params), prevMemVersion);
+}
+
+
+ExprId MediumLevelILFunction::CallUntypedSSA(const vector<SSAVariable>& output, ExprId dest,
+ const vector<SSAVariable>& 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)), dest,
+ AddExprWithLocation(MLIL_CALL_PARAM_SSA, loc, 0, prevMemVersion,
+ params.size() * 2, AddSSAVariableList(params)), stack);
+}
+
+
+ExprId MediumLevelILFunction::SyscallSSA(const vector<SSAVariable>& 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)),
+ params.size(), AddOperandList(params), prevMemVersion);
+}
+
+
+ExprId MediumLevelILFunction::SyscallUntypedSSA(const vector<SSAVariable>& output,
+ const vector<SSAVariable>& 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_PARAM_SSA, loc, 0, prevMemVersion,
+ params.size() * 2, AddSSAVariableList(params)), stack);
+}
+
+
+ExprId MediumLevelILFunction::Return(const vector<ExprId>& sources, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_RET, loc, 0, sources.size(), AddOperandList(sources));
+}
+
+
+ExprId MediumLevelILFunction::NoReturn(const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_NORET, loc, 0);
+}
+
+
+ExprId MediumLevelILFunction::CompareEqual(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_E, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareNotEqual(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_NE, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareSignedLessThan(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_SLT, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareUnsignedLessThan(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_ULT, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareSignedLessEqual(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_SLE, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareUnsignedLessEqual(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_ULE, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareSignedGreaterEqual(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_SGE, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareUnsignedGreaterEqual(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_UGE, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareSignedGreaterThan(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_SGT, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::CompareUnsignedGreaterThan(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CMP_UGT, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::TestBit(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_TEST_BIT, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::BoolToInt(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_BOOL_TO_INT, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::AddOverflow(size_t size, ExprId left, ExprId right,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_ADD_OVERFLOW, loc, size, left, right);
+}
+
+
+ExprId MediumLevelILFunction::Breakpoint(const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_BP, loc, 0);
+}
+
+
+ExprId MediumLevelILFunction::Trap(int64_t vector, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_TRAP, loc, 0, vector);
+}
+
+
+ExprId MediumLevelILFunction::Undefined(const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_UNDEF, loc, 0);
+}
+
+
+ExprId MediumLevelILFunction::Unimplemented(const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_UNIMPL, loc, 0);
+}
+
+
+ExprId MediumLevelILFunction::UnimplementedMemoryRef(size_t size, ExprId target,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_UNIMPL_MEM, loc, size, target);
+}
+
+
+ExprId MediumLevelILFunction::VarPhi(const SSAVariable& dest, const vector<SSAVariable>& sources,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_VAR_PHI, loc, 0, dest.var.ToIdentifier(), dest.version,
+ sources.size() * 2, AddSSAVariableList(sources));
+}
+
+
+ExprId MediumLevelILFunction::MemoryPhi(size_t destMemVersion, const vector<size_t>& sourceMemVersions,
+ const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_MEM_PHI, loc, 0, destMemVersion,
+ sourceMemVersions.size(), AddIndexList(sourceMemVersions));
+}