NoOperation::IndexIntervals
NoOperation::findNoopSubsequences(const std::vector<SgAsmInstruction*> &insns) const {
    IndexIntervals retval;
    Sawyer::Message::Stream debug(mlog[DEBUG]);

    if (debug) {
        debug <<"findNoopSubsequences(\n";
        BOOST_FOREACH (SgAsmInstruction *insn, insns)
            debug <<"  " <<unparseInstructionWithAddress(insn) <<"\n";
        debug <<")\n";
    }

    // If we have no instruction semantics then assume that all instructions have an effect.
    if (!cpu_ || insns.empty())
        return retval;

    // Process each instruction as if insns were a basic block. Store insns[i]'s initial state in states[i] and its final state
    // in states[i+1].  States don't generally have a way to compare them for equality, so use a simple string-based comparison
    // for now. FIXME[Robb P. Matzke 2015-05-11]
    std::vector<std::string> states;
    bool hadError = false;
    cpu_->get_operators()->currentState(initialState(insns.front()));
    const RegisterDescriptor regIP = cpu_->instructionPointerRegister();
    try {
        BOOST_FOREACH (SgAsmInstruction *insn, insns) {
            cpu_->get_operators()->writeRegister(regIP, cpu_->get_operators()->number_(regIP.get_nbits(), insn->get_address()));
            states.push_back(normalizeState(cpu_->currentState()));
            if (debug) {
                debug <<"  normalized state #" <<states.size()-1 <<":\n" <<StringUtility::prefixLines(states.back(), "    ");
                debug <<"  instruction: " <<unparseInstructionWithAddress(insn) <<"\n";
            }
            cpu_->processInstruction(insn);
        }
    } catch (const BaseSemantics::Exception &e) {
        hadError = true;
        SAWYER_MESG(debug) <<"  semantic exception: " <<e <<"\n";
    }
    if (!hadError) {
        states.push_back(normalizeState(cpu_->currentState()));
        if (debug)
            debug <<"  normalized state #" <<states.size()-1 <<":\n" <<StringUtility::prefixLines(states.back(), "    ");
    }

    // Look for pairs of states that are the same, and call that sequence of instructions a no-op
    for (size_t i=0; i+1<states.size(); ++i) {
        for (size_t j=i+1; j<states.size(); ++j) {
            if (states[i]==states[j]) {
                retval.push_back(IndexInterval::hull(i, j-1));
                SAWYER_MESG(debug) <<"  no-op: " <<i <<".." <<(j-1) <<"\n";
            }
        }
    }
    
    return retval;
}
void
AddressUser::print(std::ostream &out) const {
    if (insn_!=NULL) {
        out <<"{";
        if (bblocks_.empty()) {
            out <<"{B-none ";
        } else {
            BOOST_FOREACH (const BasicBlock::Ptr &bb, bblocks_)
                out <<"B-" <<StringUtility::addrToString(bb->address()) <<" ";
        }
        out <<unparseInstructionWithAddress(insn_) <<"}";
    } else {
Example #3
0
void
RiscOperators::startInstruction(SgAsmInstruction *insn) {
    ASSERT_not_null(partitioner_);
    Super::startInstruction(insn);
    if (mlog[DEBUG]) {
        SymbolicSemantics::Formatter fmt = symbolicFormat("      ");
        mlog[DEBUG] <<"  +-------------------------------------------------\n"
                    <<"  | " <<unparseInstructionWithAddress(insn) <<"\n"
                    <<"  +-------------------------------------------------\n"
                    <<"    state before instruction:\n"
                    <<(*currentState() + fmt);
    }
}
Example #4
0
std::string
RiscOperators::commentForVariable(RegisterDescriptor reg, const std::string &accessMode) const {
    const RegisterDictionary *regs = currentState()->registerState()->get_register_dictionary();
    std::string varComment = RegisterNames(regs)(reg) + " first " + accessMode;
    if (pathInsnIndex_ == (size_t)(-1) && currentInstruction() == NULL) {
        varComment += " by initialization";
    } else {
        if (pathInsnIndex_ != (size_t)(-1))
            varComment += " at path position #" + StringUtility::numberToString(pathInsnIndex_);
        if (SgAsmInstruction *insn = currentInstruction())
            varComment += " by " + unparseInstructionWithAddress(insn);
    }
    return varComment;
}
Example #5
0
std::string
RiscOperators::commentForVariable(const BaseSemantics::SValuePtr &addr, const std::string &accessMode, size_t byteNumber,
                                  size_t nBytes) const {
    std::string varComment = "first " + accessMode + " at ";
    if (pathInsnIndex_ != (size_t)(-1))
        varComment += "path position #" + StringUtility::numberToString(pathInsnIndex_) + ", ";
    varComment += "instruction " + unparseInstructionWithAddress(currentInstruction());

    // Sometimes we can save useful information about the address.
    if (nBytes != 1) {
        SymbolicExpr::Ptr addrExpr = SValue::promote(addr)->get_expression();
        if (SymbolicExpr::LeafPtr addrLeaf = addrExpr->isLeafNode()) {
            if (addrLeaf->isNumber()) {
                varComment += "\n";
                if (nBytes > 1) {
                    varComment += StringUtility::numberToString(byteNumber) + " of " +
                                  StringUtility::numberToString(nBytes) + " bytes starting ";
                }
                varComment += "at address " + addrLeaf->toString();
            }
        } else if (SymbolicExpr::InteriorPtr addrINode = addrExpr->isInteriorNode()) {
            if (addrINode->getOperator() == SymbolicExpr::OP_ADD && addrINode->nChildren() == 2 &&
                addrINode->child(0)->isLeafNode() && addrINode->child(0)->isLeafNode()->isVariable() &&
                addrINode->child(1)->isLeafNode() && addrINode->child(1)->isLeafNode()->isNumber()) {
                SymbolicExpr::LeafPtr base = addrINode->child(0)->isLeafNode();
                SymbolicExpr::LeafPtr offset = addrINode->child(1)->isLeafNode();
                varComment += "\n";
                if (nBytes > 1) {
                    varComment += StringUtility::numberToString(byteNumber) + " of " +
                                  StringUtility::numberToString(nBytes) + " bytes starting ";
                }
                varComment += "at address ";
                if (base->comment().empty()) {
                    varComment = base->toString();
                } else {
                    varComment += base->comment();
                }
                Sawyer::Container::BitVector tmp = offset->bits();
                if (tmp.get(tmp.size()-1)) {
                    varComment += " - 0x" + tmp.negate().toHex();
                } else {
                    varComment += " + 0x" + tmp.toHex();
                }
            }
        }
    }
    return varComment;
}