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 {
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); } }
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; }
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; }