From d260db48d05dc38f1a60cedb8633434a7b6237b6 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 20 Feb 2023 13:59:48 -0500 Subject: Refactor VisitExprs to give separate API to gather subexpressions --- highlevelilinstruction.cpp | 525 ++++++++++++++++++++++++--------------------- 1 file changed, 285 insertions(+), 240 deletions(-) (limited to 'highlevelilinstruction.cpp') diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 608b2fac..3c838c1a 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -1037,11 +1037,257 @@ HighLevelILInstruction HighLevelILInstructionBase::GetParent() const } -void HighLevelILInstruction::VisitExprs(const std::function& func) const +void HighLevelILInstruction::CollectSubExprs(stack& toProcess) const { - stack toProcess; vector exprs; + switch (operation) + { + case HLIL_BLOCK: + exprs = GetBlockExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_IF: + if (ast) + { + toProcess.push(GetFalseExpr().exprIndex); + toProcess.push(GetTrueExpr().exprIndex); + } + toProcess.push(GetConditionExpr().exprIndex); + break; + case HLIL_WHILE: + if (ast) + toProcess.push(GetLoopExpr().exprIndex); + toProcess.push(GetConditionExpr().exprIndex); + break; + case HLIL_WHILE_SSA: + if (ast) + toProcess.push(GetLoopExpr().exprIndex); + toProcess.push(GetConditionExpr().exprIndex); + toProcess.push(GetConditionPhiExpr().exprIndex); + break; + case HLIL_DO_WHILE: + toProcess.push(GetConditionExpr().exprIndex); + if (ast) + toProcess.push(GetLoopExpr().exprIndex); + break; + case HLIL_DO_WHILE_SSA: + toProcess.push(GetConditionExpr().exprIndex); + toProcess.push(GetConditionPhiExpr().exprIndex); + if (ast) + toProcess.push(GetLoopExpr().exprIndex); + break; + case HLIL_FOR: + if (ast) + toProcess.push(GetLoopExpr().exprIndex); + toProcess.push(GetUpdateExpr().exprIndex); + toProcess.push(GetConditionExpr().exprIndex); + toProcess.push(GetInitExpr().exprIndex); + break; + case HLIL_FOR_SSA: + if (ast) + toProcess.push(GetLoopExpr().exprIndex); + toProcess.push(GetUpdateExpr().exprIndex); + toProcess.push(GetConditionExpr().exprIndex); + toProcess.push(GetConditionPhiExpr().exprIndex); + toProcess.push(GetInitExpr().exprIndex); + break; + case HLIL_SWITCH: + if (ast) + { + exprs = GetCases(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + toProcess.push(GetDefaultExpr().exprIndex); + } + toProcess.push(GetConditionExpr().exprIndex); + break; + case HLIL_CASE: + toProcess.push(GetTrueExpr().exprIndex); + exprs = GetValueExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_VAR_INIT: + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_VAR_INIT_SSA: + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_ASSIGN: + toProcess.push(GetDestExpr().exprIndex); + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_ASSIGN_UNPACK: + exprs = GetDestExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_ASSIGN_MEM_SSA: + toProcess.push(GetDestExpr().exprIndex); + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_ASSIGN_UNPACK_MEM_SSA: + exprs = GetDestExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_STRUCT_FIELD: + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_ARRAY_INDEX: + toProcess.push(GetSourceExpr().exprIndex); + toProcess.push(GetIndexExpr().exprIndex); + break; + case HLIL_ARRAY_INDEX_SSA: + toProcess.push(GetSourceExpr().exprIndex); + toProcess.push(GetIndexExpr().exprIndex); + break; + case HLIL_SPLIT: + toProcess.push(GetLowExpr().exprIndex); + toProcess.push(GetHighExpr().exprIndex); + break; + case HLIL_DEREF_FIELD: + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_DEREF_SSA: + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_DEREF_FIELD_SSA: + toProcess.push(GetSourceExpr().exprIndex); + break; + case HLIL_CALL: + toProcess.push(GetDestExpr().exprIndex); + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_SYSCALL: + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_TAILCALL: + toProcess.push(GetDestExpr().exprIndex); + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_CALL_SSA: + toProcess.push(GetDestExpr().exprIndex); + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_SYSCALL_SSA: + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_RET: + exprs = GetSourceExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_DEREF: + case HLIL_ADDRESS_OF: + case HLIL_NEG: + case HLIL_NOT: + case HLIL_SX: + case HLIL_ZX: + case HLIL_LOW_PART: + case HLIL_BOOL_TO_INT: + case HLIL_JUMP: + case HLIL_UNIMPL_MEM: + case HLIL_FSQRT: + case HLIL_FNEG: + case HLIL_FABS: + case HLIL_FLOAT_TO_INT: + case HLIL_INT_TO_FLOAT: + case HLIL_FLOAT_CONV: + case HLIL_ROUND_TO_INT: + case HLIL_FLOOR: + case HLIL_CEIL: + case HLIL_FTRUNC: + toProcess.push(AsOneOperand().GetSourceExpr().exprIndex); + break; + case HLIL_ADD: + case HLIL_SUB: + case HLIL_AND: + case HLIL_OR: + case HLIL_XOR: + case HLIL_LSL: + case HLIL_LSR: + case HLIL_ASR: + case HLIL_ROL: + case HLIL_ROR: + case HLIL_MUL: + case HLIL_MULU_DP: + case HLIL_MULS_DP: + case HLIL_DIVU: + case HLIL_DIVS: + case HLIL_MODU: + case HLIL_MODS: + case HLIL_DIVU_DP: + case HLIL_DIVS_DP: + case HLIL_MODU_DP: + case HLIL_MODS_DP: + case HLIL_CMP_E: + case HLIL_CMP_NE: + case HLIL_CMP_SLT: + case HLIL_CMP_ULT: + case HLIL_CMP_SLE: + case HLIL_CMP_ULE: + case HLIL_CMP_SGE: + case HLIL_CMP_UGE: + case HLIL_CMP_SGT: + case HLIL_CMP_UGT: + case HLIL_TEST_BIT: + case HLIL_ADD_OVERFLOW: + case HLIL_FADD: + case HLIL_FSUB: + case HLIL_FMUL: + case HLIL_FDIV: + case HLIL_FCMP_E: + case HLIL_FCMP_NE: + case HLIL_FCMP_LT: + case HLIL_FCMP_LE: + case HLIL_FCMP_GE: + case HLIL_FCMP_GT: + case HLIL_FCMP_O: + case HLIL_FCMP_UO: + toProcess.push(AsTwoOperand().GetRightExpr().exprIndex); + toProcess.push(AsTwoOperand().GetLeftExpr().exprIndex); + break; + case HLIL_ADC: + case HLIL_SBB: + case HLIL_RLC: + case HLIL_RRC: + toProcess.push(AsTwoOperandWithCarry().GetCarryExpr().exprIndex); + toProcess.push(AsTwoOperandWithCarry().GetRightExpr().exprIndex); + toProcess.push(AsTwoOperandWithCarry().GetLeftExpr().exprIndex); + break; + case HLIL_INTRINSIC: + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + case HLIL_INTRINSIC_SSA: + exprs = GetParameterExprs(); + for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) + toProcess.push(i->exprIndex); + break; + default: + break; + } +} + +void HighLevelILInstruction::VisitExprs(const std::function& func) const +{ + stack toProcess; toProcess.push(exprIndex); while (!toProcess.empty()) { @@ -1049,247 +1295,46 @@ void HighLevelILInstruction::VisitExprs(const std::function& preFunc, + const std::function& postFunc) const +{ + stack>> toProcess; + HighLevelILInstruction cur = *this; + if (!preFunc(cur)) + return; + + stack subExprs; + cur.CollectSubExprs(subExprs); + + while (true) + { + if (subExprs.size() == 0) { - case HLIL_BLOCK: - exprs = cur.GetBlockExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_IF: - if (ast) - { - toProcess.push(cur.GetFalseExpr().exprIndex); - toProcess.push(cur.GetTrueExpr().exprIndex); - } - toProcess.push(cur.GetConditionExpr().exprIndex); - break; - case HLIL_WHILE: - if (ast) - toProcess.push(cur.GetLoopExpr().exprIndex); - toProcess.push(cur.GetConditionExpr().exprIndex); - break; - case HLIL_WHILE_SSA: - if (ast) - toProcess.push(cur.GetLoopExpr().exprIndex); - toProcess.push(cur.GetConditionExpr().exprIndex); - toProcess.push(cur.GetConditionPhiExpr().exprIndex); - break; - case HLIL_DO_WHILE: - toProcess.push(cur.GetConditionExpr().exprIndex); - if (ast) - toProcess.push(cur.GetLoopExpr().exprIndex); - break; - case HLIL_DO_WHILE_SSA: - toProcess.push(cur.GetConditionExpr().exprIndex); - toProcess.push(cur.GetConditionPhiExpr().exprIndex); - if (ast) - toProcess.push(cur.GetLoopExpr().exprIndex); - break; - case HLIL_FOR: - if (ast) - toProcess.push(cur.GetLoopExpr().exprIndex); - toProcess.push(cur.GetUpdateExpr().exprIndex); - toProcess.push(cur.GetConditionExpr().exprIndex); - toProcess.push(cur.GetInitExpr().exprIndex); - break; - case HLIL_FOR_SSA: - if (ast) - toProcess.push(cur.GetLoopExpr().exprIndex); - toProcess.push(cur.GetUpdateExpr().exprIndex); - toProcess.push(cur.GetConditionExpr().exprIndex); - toProcess.push(cur.GetConditionPhiExpr().exprIndex); - toProcess.push(cur.GetInitExpr().exprIndex); - break; - case HLIL_SWITCH: - if (ast) + postFunc(cur); + + if (toProcess.empty()) + break; + cur = toProcess.top().first; + subExprs = toProcess.top().second; + toProcess.pop(); + } + else + { + HighLevelILInstruction next = function->GetExpr(subExprs.top()); + subExprs.pop(); + + if (preFunc(next)) { - exprs = cur.GetCases(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - toProcess.push(cur.GetDefaultExpr().exprIndex); + toProcess.push(std::pair>(cur, subExprs)); + cur = next; + subExprs = stack(); + cur.CollectSubExprs(subExprs); } - toProcess.push(cur.GetConditionExpr().exprIndex); - break; - case HLIL_CASE: - toProcess.push(cur.GetTrueExpr().exprIndex); - exprs = cur.GetValueExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_VAR_INIT: - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_VAR_INIT_SSA: - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_ASSIGN: - toProcess.push(cur.GetSourceExpr().exprIndex); - toProcess.push(cur.GetDestExpr().exprIndex); - break; - case HLIL_ASSIGN_UNPACK: - toProcess.push(cur.GetSourceExpr().exprIndex); - exprs = cur.GetDestExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_ASSIGN_MEM_SSA: - toProcess.push(cur.GetSourceExpr().exprIndex); - toProcess.push(cur.GetDestExpr().exprIndex); - break; - case HLIL_ASSIGN_UNPACK_MEM_SSA: - toProcess.push(cur.GetSourceExpr().exprIndex); - exprs = cur.GetDestExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_STRUCT_FIELD: - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_ARRAY_INDEX: - toProcess.push(cur.GetIndexExpr().exprIndex); - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_ARRAY_INDEX_SSA: - toProcess.push(cur.GetIndexExpr().exprIndex); - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_SPLIT: - toProcess.push(cur.GetLowExpr().exprIndex); - toProcess.push(cur.GetHighExpr().exprIndex); - break; - case HLIL_DEREF_FIELD: - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_DEREF_SSA: - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_DEREF_FIELD_SSA: - toProcess.push(cur.GetSourceExpr().exprIndex); - break; - case HLIL_CALL: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - toProcess.push(cur.GetDestExpr().exprIndex); - break; - case HLIL_SYSCALL: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_TAILCALL: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - toProcess.push(cur.GetDestExpr().exprIndex); - break; - case HLIL_CALL_SSA: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - toProcess.push(cur.GetDestExpr().exprIndex); - break; - case HLIL_SYSCALL_SSA: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_RET: - exprs = cur.GetSourceExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_DEREF: - case HLIL_ADDRESS_OF: - case HLIL_NEG: - case HLIL_NOT: - case HLIL_SX: - case HLIL_ZX: - case HLIL_LOW_PART: - case HLIL_BOOL_TO_INT: - case HLIL_JUMP: - case HLIL_UNIMPL_MEM: - case HLIL_FSQRT: - case HLIL_FNEG: - case HLIL_FABS: - case HLIL_FLOAT_TO_INT: - case HLIL_INT_TO_FLOAT: - case HLIL_FLOAT_CONV: - case HLIL_ROUND_TO_INT: - case HLIL_FLOOR: - case HLIL_CEIL: - case HLIL_FTRUNC: - toProcess.push(cur.AsOneOperand().GetSourceExpr().exprIndex); - break; - case HLIL_ADD: - case HLIL_SUB: - case HLIL_AND: - case HLIL_OR: - case HLIL_XOR: - case HLIL_LSL: - case HLIL_LSR: - case HLIL_ASR: - case HLIL_ROL: - case HLIL_ROR: - case HLIL_MUL: - case HLIL_MULU_DP: - case HLIL_MULS_DP: - case HLIL_DIVU: - case HLIL_DIVS: - case HLIL_MODU: - case HLIL_MODS: - case HLIL_DIVU_DP: - case HLIL_DIVS_DP: - case HLIL_MODU_DP: - case HLIL_MODS_DP: - case HLIL_CMP_E: - case HLIL_CMP_NE: - case HLIL_CMP_SLT: - case HLIL_CMP_ULT: - case HLIL_CMP_SLE: - case HLIL_CMP_ULE: - case HLIL_CMP_SGE: - case HLIL_CMP_UGE: - case HLIL_CMP_SGT: - case HLIL_CMP_UGT: - case HLIL_TEST_BIT: - case HLIL_ADD_OVERFLOW: - case HLIL_FADD: - case HLIL_FSUB: - case HLIL_FMUL: - case HLIL_FDIV: - case HLIL_FCMP_E: - case HLIL_FCMP_NE: - case HLIL_FCMP_LT: - case HLIL_FCMP_LE: - case HLIL_FCMP_GE: - case HLIL_FCMP_GT: - case HLIL_FCMP_O: - case HLIL_FCMP_UO: - toProcess.push(cur.AsTwoOperand().GetRightExpr().exprIndex); - toProcess.push(cur.AsTwoOperand().GetLeftExpr().exprIndex); - break; - case HLIL_ADC: - case HLIL_SBB: - case HLIL_RLC: - case HLIL_RRC: - toProcess.push(cur.AsTwoOperandWithCarry().GetCarryExpr().exprIndex); - toProcess.push(cur.AsTwoOperandWithCarry().GetRightExpr().exprIndex); - toProcess.push(cur.AsTwoOperandWithCarry().GetLeftExpr().exprIndex); - break; - case HLIL_INTRINSIC: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - case HLIL_INTRINSIC_SSA: - exprs = cur.GetParameterExprs(); - for (auto i = exprs.rbegin(); i != exprs.rend(); ++i) - toProcess.push(i->exprIndex); - break; - default: - break; } } } -- cgit v1.3.1