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; }
/** Output for one expression. */ void YicesSolver::out_expr(std::ostream &o, const SymbolicExpr::Ptr &tn) { SymbolicExpr::LeafPtr ln = tn->isLeafNode(); SymbolicExpr::InteriorPtr in = tn->isInteriorNode(); std::string subExprName; if (termNames.getOptional(tn).assignTo(subExprName)) { o <<subExprName; } else if (ln) { if (ln->isNumber()) { if (ln->nBits() <= 64) { o <<"(mk-bv " <<ln->nBits() <<" " <<ln->toInt() <<")"; } else { o <<"0b" <<ln->bits().toBinary(); } } else if (ln->isMemory()) { o <<"m" <<ln->nameId(); } else { ASSERT_require(ln->isVariable()); o <<"v" <<ln->nameId(); } } else { ASSERT_not_null(in); switch (in->getOperator()) { case SymbolicExpr::OP_ADD: out_la(o, "bv-add", in, false); break; case SymbolicExpr::OP_AND: out_la(o, "and", in, true); break; case SymbolicExpr::OP_ASR: out_asr(o, in); break; case SymbolicExpr::OP_BV_AND: out_la(o, "bv-and", in, true); break; case SymbolicExpr::OP_BV_OR: out_la(o, "bv-or", in, false); break; case SymbolicExpr::OP_BV_XOR: out_la(o, "bv-xor", in, false); break; case SymbolicExpr::OP_EQ: out_binary(o, "=", in); break; case SymbolicExpr::OP_CONCAT: out_la(o, "bv-concat", in); break; case SymbolicExpr::OP_EXTRACT: out_extract(o, in); break; case SymbolicExpr::OP_INVERT: out_unary(o, "bv-not", in); break; case SymbolicExpr::OP_ITE: out_ite(o, in); break; case SymbolicExpr::OP_LSSB: throw Exception("OP_LSSB not implemented"); case SymbolicExpr::OP_MSSB: throw Exception("OP_MSSB not implemented"); case SymbolicExpr::OP_NE: out_binary(o, "/=", in); break; case SymbolicExpr::OP_NEGATE: out_unary(o, "bv-neg", in); break; case SymbolicExpr::OP_NOOP: o<<"0b1"; break; case SymbolicExpr::OP_OR: out_la(o, "or", in, false); break; case SymbolicExpr::OP_READ: out_read(o, in); break; case SymbolicExpr::OP_ROL: throw Exception("OP_ROL not implemented"); case SymbolicExpr::OP_ROR: throw Exception("OP_ROR not implemented"); case SymbolicExpr::OP_SDIV: throw Exception("OP_SDIV not implemented"); case SymbolicExpr::OP_SET: out_set(o, in); break; case SymbolicExpr::OP_SEXTEND: out_sext(o, in); break; case SymbolicExpr::OP_SLT: out_binary(o, "bv-slt", in); break; case SymbolicExpr::OP_SLE: out_binary(o, "bv-sle", in); break; case SymbolicExpr::OP_SHL0: out_shift(o, "bv-shift-left", in, false); break; case SymbolicExpr::OP_SHL1: out_shift(o, "bv-shift-left", in, true); break; case SymbolicExpr::OP_SHR0: out_shift(o, "bv-shift-right", in, false); break; case SymbolicExpr::OP_SHR1: out_shift(o, "bv-shift-right", in, true); break; case SymbolicExpr::OP_SGE: out_binary(o, "bv-sge", in); break; case SymbolicExpr::OP_SGT: out_binary(o, "bv-sgt", in); break; case SymbolicExpr::OP_SMOD: throw Exception("OP_SMOD not implemented"); case SymbolicExpr::OP_SMUL: out_mult(o, in); break; case SymbolicExpr::OP_UDIV: throw Exception("OP_UDIV not implemented"); case SymbolicExpr::OP_UEXTEND: out_uext(o, in); break; case SymbolicExpr::OP_UGE: out_binary(o, "bv-ge", in); break; case SymbolicExpr::OP_UGT: out_binary(o, "bv-gt", in); break; case SymbolicExpr::OP_ULE: out_binary(o, "bv-le", in); break; case SymbolicExpr::OP_ULT: out_binary(o, "bv-lt", in); break; case SymbolicExpr::OP_UMOD: throw Exception("OP_UMOD not implemented"); case SymbolicExpr::OP_UMUL: out_mult(o, in); break; case SymbolicExpr::OP_WRITE: out_write(o, in); break; case SymbolicExpr::OP_ZEROP: out_zerop(o, in); break; } } }