virtual status visit(const mov &node) { return handle_mov(node); }
//---------------------------------------------------------------------- bool jump_pattern_t::follow_tree(ea_t ea, int n) { if ( n == 0 ) return true; int rsaved[sizeof(r)]; bool ssaved[sizeof(spoiled)]; memcpy(rsaved, r, sizeof(r)); memcpy(ssaved, spoiled, sizeof(spoiled)); bool success = false; if ( n < 0 ) { success = true; n = -n; } jmsg("follow_tree(%a, %d)\n", ea, n); if ( !skip[n] ) { if ( eas[n] == BADADDR ) { cmd.ea = ea; bool found_insn = false; while ( true ) { if ( cmd.ea < minea ) break; farref = false; ea_t prev = BADADDR; if ( allow_noflows || isFlow(get_flags_novalue(cmd.ea)) ) prev = decode_prev_insn(cmd.ea); if ( prev == BADADDR ) { if ( !allow_farrefs ) break; ea_t cur_addr = cmd.ea; if ( decode_preceding_insn(cmd.ea, &farref) == BADADDR ) break; // skip branches which are used to glue blocks together if ( farref && is_branch_to(cur_addr) ) continue; } if ( handle_mov() ) continue; if ( (this->*check[n])() ) { found_insn = true; break; } if ( failed ) return false; jmsg("%a: can't be %d.", cmd.ea, n); jmsg(" rA=%d%s rB=%d%s rC=%d%s rD=%d%s rE=%d%s\n", r[1], spoiled[1] ? "*" : "", r[2], spoiled[2] ? "*" : "", r[3], spoiled[3] ? "*" : "", r[4], spoiled[4] ? "*" : "", r[5], spoiled[5] ? "*" : ""); check_spoiled(); } if ( !found_insn ) { memcpy(r, rsaved, sizeof(r)); if ( success ) goto SUCC; return false; } eas[n] = cmd.ea; } if ( eas[n] >= ea ) { jmsg("%a: depends on %a\n", ea, eas[n]); return success; } ea = eas[n]; jmsg("%a: found %d\n", cmd.ea, n); } SUCC: if ( depends[n][0] && !follow_tree(ea, depends[n][0]) ) return success; if ( depends[n][1] && !follow_tree(ea, depends[n][1]) ) return success; jmsg("follow_tree(%d) - ok\n", n); memcpy(spoiled, ssaved, sizeof(spoiled)); return true; }