diff --git a/irdb-libs/ir_builders/back_search.hpp b/irdb-libs/ir_builders/back_search.hpp index 3ffd09d9c925416fd3cfd5bf7628c4b173564c0b..a3dd6bba72daad1e2d0e04cc487545cfc1fea8d5 100644 --- a/irdb-libs/ir_builders/back_search.hpp +++ b/irdb-libs/ir_builders/back_search.hpp @@ -59,17 +59,19 @@ void calc_preds(FileIR_t* firp) } -// search for an expression in prior instructions. -bool backup_until(const string &insn_type_regex_str, // what to search for +// search for an expression in prior instructions. Return whether expression was found. +// If an assignment is found, stopped_because_set is set to this instruction and false is returned +bool backup_until_or_move(const string &insn_type_regex_str, // what to search for Instruction_t *& prev, // output param -- the instruction we found. Instruction_t* orig, // where to start the search. + Instruction_t *& stopped_because_set, // output param -- the instruction that stopped the search because of stop_if_set. nullptr if the search was not stopped because of this reason const string & stop_if_set="", // stop if an operand that's written matches this expression. const string & stop_if_opcode="", // stop if an opcode matches this expression bool recursive=false, // search recursively? uint32_t max_insns=10000u, // max number of instructions to search through. uint32_t max_recursions=5u) // make number of blocks to recusive into { - + stopped_because_set = static_cast<Instruction_t *>(nullptr); const auto find_or_build_regex=[&] (const string& s) -> regex_t& { // declare a freer for regexs so they go away when the program ends. @@ -130,8 +132,10 @@ bool backup_until(const string &insn_type_regex_str, // what to search for { for(const auto &operand : disasm->getOperands()) { - if(operand->isWritten() && regexec(&stop_operand_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) - return false; + if(operand->isWritten() && regexec(&stop_operand_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) { + stopped_because_set = prev; + return false; + } } } // if we have a stop_if_opcode expresison, check the opcode to see if it matches. @@ -156,14 +160,16 @@ bool backup_until(const string &insn_type_regex_str, // what to search for { for(const auto &operand : disasm->getOperands()) { - if(operand->isWritten() && regexec(&stop_operand_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) - return false; + if(operand->isWritten() && regexec(&stop_operand_expression, operand->getString().c_str(), 0, nullptr, 0) == 0) { + stopped_because_set = pred; + return false; + } } } // if we have a stop_if_opcode expresison, check the opcode to see if it matches. if(stop_if_opcode!="" && regexec(&stop_opcode_expression, disasm->getMnemonic().c_str(), 0, nullptr, 0) == 0) return false; - if(backup_until(insn_type_regex_str, prev, pred, stop_if_set, stop_if_opcode, recursive, max_insns, max_recursions/mypreds.size())) + if(backup_until_or_move(insn_type_regex_str, prev, pred, stopped_because_set, stop_if_set, stop_if_opcode, recursive, max_insns, max_recursions/mypreds.size())) return true; // reset for next call @@ -173,5 +179,28 @@ bool backup_until(const string &insn_type_regex_str, // what to search for return false; } +// search for an expression in prior instructions. +bool backup_until(const string &insn_type_regex_str, // what to search for + Instruction_t *& prev, // output param -- the instruction we found. + Instruction_t* orig, // where to start the search. + const string & stop_if_set="", // stop if an operand that's written matches this expression. + const string & stop_if_opcode="", // stop if an opcode matches this expression + bool recursive=false, // search recursively? + uint32_t max_insns=10000u, // max number of instructions to search through. + uint32_t max_recursions=5u) // make number of blocks to recusive into +{ + // This function is just a proxy to keep the old API intact + auto discard = static_cast<Instruction_t *>(nullptr); + + return backup_until_or_move(insn_type_regex_str, + prev, + orig, + discard, + stop_if_set, + stop_if_opcode, + recursive, + max_insns, + max_recursions); +} #endif