From e47e2fb13369ff7d1c9e7728bb793ee56640afe1 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Tue, 1 Aug 2017 23:39:18 -0400 Subject: Refactor IL instruction access APIs --- mediumlevelilinstruction.cpp | 2526 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2526 insertions(+) create mode 100644 mediumlevelilinstruction.cpp (limited to 'mediumlevelilinstruction.cpp') 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 + 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> + 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> + GetOperandIndexForOperandUsages() +{ + unordered_map> result; + for (auto& operation : MediumLevelILInstructionBase::operationOperandUsage) + { + result[operation.first] = unordered_map(); + + 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> + 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() const +{ + vector 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() const +{ + vector 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() const +{ + vector 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() const +{ + vector 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() const +{ + vector 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& usageList, + const unordered_map& 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() const +{ + vector 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& vars) +{ + UpdateRawOperand(operandIndex, vars.size() * 2); + UpdateRawOperand(operandIndex + 1, function->AddSSAVariableList(vars)); +} + + +void MediumLevelILInstructionBase::UpdateRawOperandAsExprList(size_t operandIndex, const vector& exprs) +{ + vector 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& 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> 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 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 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 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 func = function->GetLowLevelIL(); + if (!func) + return false; + return GetLowLevelILExprIndex() < func->GetExprCount(); +} + + +LowLevelILInstruction MediumLevelILInstructionBase::GetLowLevelIL() const +{ + Ref 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& func) const +{ + if (!func(*this)) + return; + switch (operation) + { + case MLIL_SET_VAR: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_SSA: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_ALIASED: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_SPLIT: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_SPLIT_SSA: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_FIELD: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_SSA_FIELD: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_SET_VAR_ALIASED_FIELD: + GetSourceExpr().VisitExprs(func); + break; + case MLIL_CALL: + GetDestExpr().VisitExprs(func); + for (auto& i : GetParameterExprs()) + i.VisitExprs(func); + break; + case MLIL_CALL_UNTYPED: + GetDestExpr().VisitExprs(func); + break; + case MLIL_CALL_SSA: + GetDestExpr().VisitExprs(func); + for (auto& i : GetParameterExprs()) + i.VisitExprs(func); + break; + case MLIL_CALL_UNTYPED_SSA: + GetDestExpr().VisitExprs(func); + break; + case MLIL_SYSCALL: + for (auto& i : GetParameterExprs()) + i.VisitExprs(func); + break; + case MLIL_SYSCALL_SSA: + for (auto& i : GetParameterExprs()) + i.VisitExprs(func); + break; + case MLIL_RET: + for (auto& i : GetSourceExprs()) + i.VisitExprs(func); + break; + case MLIL_STORE: + GetDestExpr().VisitExprs(func); + GetSourceExpr().VisitExprs(func); + break; + case MLIL_STORE_STRUCT: + GetDestExpr().VisitExprs(func); + GetSourceExpr().VisitExprs(func); + break; + case MLIL_STORE_SSA: + GetDestExpr().VisitExprs(func); + GetSourceExpr().VisitExprs(func); + break; + case MLIL_STORE_STRUCT_SSA: + GetDestExpr().VisitExprs(func); + GetSourceExpr().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& subExprHandler) const +{ + vector params; + vector labelList; + BNMediumLevelILLabel* labelA; + BNMediumLevelILLabel* labelB; + switch (operation) + { + case MLIL_NOP: + return dest->Nop(*this); + case MLIL_SET_VAR: + return dest->SetVar(size, GetDestVariable(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_SSA: + return dest->SetVarSSA(size, GetDestSSAVariable(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_ALIASED: + return dest->SetVarAliased(size, GetDestSSAVariable().var, + GetDestSSAVariable().version, + GetSourceSSAVariable().version, + subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_SPLIT: + return dest->SetVarSplit(size, GetHighVariable(), + GetLowVariable(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_SPLIT_SSA: + return dest->SetVarSSASplit(size, GetHighSSAVariable(), + GetLowSSAVariable(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_FIELD: + return dest->SetVarField(size, GetDestVariable(), + GetOffset(), subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_SSA_FIELD: + return dest->SetVarSSAField(size, GetDestSSAVariable().var, + GetDestSSAVariable().version, + GetSourceSSAVariable().version, + GetOffset(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_SET_VAR_ALIASED_FIELD: + return dest->SetVarAliasedField(size, GetDestSSAVariable().var, + GetDestSSAVariable().version, + GetSourceSSAVariable().version, + GetOffset(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_VAR: + return dest->Var(size, GetSourceVariable(), *this); + case MLIL_VAR_FIELD: + return dest->VarField(size, GetSourceVariable(), + GetOffset(), *this); + case MLIL_VAR_SSA: + return dest->VarSSA(size, GetSourceSSAVariable(), *this); + case MLIL_VAR_SSA_FIELD: + return dest->VarSSAField(size, GetSourceSSAVariable(), + GetOffset(), *this); + case MLIL_VAR_ALIASED: + return dest->VarAliased(size, GetSourceSSAVariable().var, + GetSourceSSAVariable().version, *this); + case MLIL_VAR_ALIASED_FIELD: + return dest->VarAliasedField(size, GetSourceSSAVariable().var, + GetSourceSSAVariable().version, + GetOffset(), *this); + case MLIL_ADDRESS_OF: + return dest->AddressOf(GetSourceVariable(), *this); + case MLIL_ADDRESS_OF_FIELD: + return dest->AddressOfField(GetSourceVariable(), + GetOffset(), *this); + case MLIL_CALL: + for (auto& i : GetParameterExprs()) + params.push_back(subExprHandler(i)); + return dest->Call(GetOutputVariables(), subExprHandler(GetDestExpr()), + params, *this); + case MLIL_CALL_UNTYPED: + return dest->CallUntyped(GetOutputVariables(), + subExprHandler(GetDestExpr()), GetParameterVariables(), + subExprHandler(GetStackExpr()), *this); + case MLIL_CALL_SSA: + for (auto& i : GetParameterExprs()) + params.push_back(subExprHandler(i)); + return dest->CallSSA(GetOutputSSAVariables(), subExprHandler(GetDestExpr()), + params, GetDestMemoryVersion(), GetSourceMemoryVersion(), *this); + case MLIL_CALL_UNTYPED_SSA: + return dest->CallUntypedSSA(GetOutputSSAVariables(), + subExprHandler(GetDestExpr()), + GetParameterSSAVariables(), + GetDestMemoryVersion(), + GetSourceMemoryVersion(), + subExprHandler(GetStackExpr()), *this); + case MLIL_SYSCALL: + for (auto& i : GetParameterExprs()) + params.push_back(subExprHandler(i)); + return dest->Syscall(GetOutputVariables(), params, *this); + case MLIL_SYSCALL_UNTYPED: + return dest->SyscallUntyped(GetOutputVariables(), + GetParameterVariables(), + subExprHandler(GetStackExpr()), *this); + case MLIL_SYSCALL_SSA: + for (auto& i : GetParameterExprs()) + params.push_back(subExprHandler(i)); + return dest->SyscallSSA(GetOutputSSAVariables(), params, + GetDestMemoryVersion(), GetSourceMemoryVersion(), *this); + case MLIL_SYSCALL_UNTYPED_SSA: + return dest->SyscallUntypedSSA(GetOutputSSAVariables(), + GetParameterSSAVariables(), + GetDestMemoryVersion(), + GetSourceMemoryVersion(), + subExprHandler(GetStackExpr()), *this); + case MLIL_RET: + for (auto& i : GetSourceExprs()) + 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()), + subExprHandler(GetSourceExpr()), *this); + case MLIL_STORE_STRUCT: + return dest->StoreStruct(size, subExprHandler(GetDestExpr()), + GetOffset(), subExprHandler(GetSourceExpr()), *this); + case MLIL_STORE_SSA: + return dest->StoreSSA(size, subExprHandler(GetDestExpr()), + GetDestMemoryVersion(), GetSourceMemoryVersion(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_STORE_STRUCT_SSA: + return dest->StoreStructSSA(size, subExprHandler(GetDestExpr()), + GetOffset(), + GetDestMemoryVersion(), GetSourceMemoryVersion(), + subExprHandler(GetSourceExpr()), *this); + case MLIL_LOAD: + return dest->Load(size, subExprHandler(GetSourceExpr()), *this); + case MLIL_LOAD_STRUCT: + return dest->LoadStruct(size, subExprHandler(GetSourceExpr()), + GetOffset(), *this); + case MLIL_LOAD_SSA: + return dest->LoadSSA(size, subExprHandler(GetSourceExpr()), + GetSourceMemoryVersion(), *this); + case MLIL_LOAD_STRUCT_SSA: + return dest->LoadStructSSA(size, subExprHandler(GetSourceExpr()), + GetOffset(), GetSourceMemoryVersion(), *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()) + { + labelA = dest->GetLabelForSourceInstruction(target); + if (!labelA) + return dest->Jump(subExprHandler(GetDestExpr()), *this); + labelList.push_back(labelA); + } + return dest->JumpTo(subExprHandler(GetDestExpr()), labelList, *this); + case MLIL_GOTO: + labelA = dest->GetLabelForSourceInstruction(GetTarget()); + if (!labelA) + { + return dest->Jump(dest->ConstPointer(function->GetArchitecture()->GetAddressSize(), + function->GetInstruction(GetTarget()).address), *this); + } + return dest->Goto(*labelA, *this); + case MLIL_IF: + labelA = dest->GetLabelForSourceInstruction(GetTrueTarget()); + labelB = dest->GetLabelForSourceInstruction(GetFalseTarget()); + if ((!labelA) || (!labelB)) + return dest->Undefined(*this); + return dest->If(subExprHandler(GetConditionExpr()), *labelA, *labelB, *this); + case MLIL_CONST: + return dest->Const(size, GetConstant(), *this); + case MLIL_CONST_PTR: + return dest->ConstPointer(size, GetConstant(), *this); + case MLIL_BP: + return dest->Breakpoint(*this); + case MLIL_TRAP: + return dest->Trap(GetVector(), *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& targets, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_JUMP_TO, loc, 0, dest, targets.size(), AddLabelList(targets)); +} + + +ExprId MediumLevelILFunction::Call(const vector& output, ExprId dest, + const vector& params, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_CALL, loc, 0, output.size(), AddVariableList(output), dest, + params.size(), AddOperandList(params)); +} + + +ExprId MediumLevelILFunction::CallUntyped(const vector& output, ExprId dest, + const vector& 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& output, const vector& params, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_SYSCALL, loc, 0, output.size(), AddVariableList(output), + params.size(), AddOperandList(params)); +} + + +ExprId MediumLevelILFunction::SyscallUntyped(const vector& output, const vector& 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& output, ExprId dest, const vector& 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& output, ExprId dest, + const vector& 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& output, const vector& 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& output, + const vector& 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& 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& 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& sourceMemVersions, + const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_MEM_PHI, loc, 0, destMemVersion, + sourceMemVersions.size(), AddIndexList(sourceMemVersions)); +} -- cgit v1.3.1