Esempio n. 1
0
/** Return control flow successors. See base class for full documentation. */
BinaryAnalysis::Disassembler::AddressSet
SgAsmX86Instruction::getSuccessors(const std::vector<SgAsmInstruction*>& insns, bool *complete, const MemoryMap *initial_memory)
{
    using namespace rose::BinaryAnalysis::InstructionSemantics;
    Stream debug(mlog[DEBUG]);

    if (debug) {
        debug <<"SgAsmX86Instruction::getSuccessors(" <<StringUtility::addrToString(insns.front()->get_address())
              <<" for " <<insns.size() <<" instruction" <<(1==insns.size()?"":"s") <<"):" <<"\n";
    }

    BinaryAnalysis::Disassembler::AddressSet successors = SgAsmInstruction::getSuccessors(insns, complete);

    /* If we couldn't determine all the successors, or a cursory analysis couldn't narrow it down to a single successor then
     * we'll do a more thorough analysis now. In the case where the cursory analysis returned a complete set containing two
     * successors, a thorough analysis might be able to narrow it down to a single successor. We should not make special
     * assumptions about CALL and FARCALL instructions -- their only successor is the specified address operand. */
    if (!*complete || successors.size()>1) {

#if 0
        /* Use the most robust semantic analysis available.  Warning: this can be very slow, especially when an SMT solver is
         * involved! */
# if defined(ROSE_YICES) || defined(ROSE_HAVE_LIBYICES)
        YicesSolver yices;
        if (yices.available_linkage() & YicesSolver::LM_LIBRARY) {
            yices.set_linkage(YicesSolver::LM_LIBRARY);
        } else {
            yices.set_linkage(YicesSolver::LM_EXECUTABLE);
        }
        SMTSolver *solver = &yices;
# else
        SMTSolver *solver = NULL;
# endif
        if (debug && solver)
            solver->set_debug(stderr);
        typedef SymbolicSemantics::Policy<> Policy;
        typedef SymbolicSemantics::ValueType<32> RegisterType;
        typedef X86InstructionSemantics<Policy, SymbolicSemantics::ValueType> Semantics;
        Policy policy(solver);
#else
        typedef PartialSymbolicSemantics::Policy<> Policy;
        typedef PartialSymbolicSemantics::ValueType<32> RegisterType;
        typedef X86InstructionSemantics<Policy, PartialSymbolicSemantics::ValueType> Semantics;
        Policy policy;
        policy.set_map(initial_memory);
#endif
        try {
            Semantics semantics(policy);
            for (size_t i=0; i<insns.size(); i++) {
                SgAsmX86Instruction* insn = isSgAsmX86Instruction(insns[i]);
                semantics.processInstruction(insn);
                if (debug) {
                    debug << "  state after " <<unparseInstructionWithAddress(insn) <<"\n"
                          <<policy.get_state();
                }
            }
            const RegisterType &newip = policy.get_ip();
            if (newip.is_known()) {
                successors.clear();
                successors.insert(newip.known_value());
                *complete = true; /*this is the complete set of successors*/
            }
        } catch(const Semantics::Exception& e) {
            /* Abandon entire basic block if we hit an instruction that's not implemented. */
            debug <<e <<"\n";
        } catch(const Policy::Exception& e) {
            /* Abandon entire basic block if the semantics policy cannot handle the instruction. */
            debug <<e <<"\n";
        }
    }

    if (debug) {
        debug <<"  successors:";
        for (BinaryAnalysis::Disassembler::AddressSet::const_iterator si=successors.begin(); si!=successors.end(); ++si)
            debug <<" " <<StringUtility::addrToString(*si);
        debug <<(*complete?"":"...") <<"\n";
    }

    return successors;
}