Example #1
0
 SymbolicExpr::VisitAction preVisit(const SymbolicExpr::Ptr &node) {
     if (!seen.insert(getRawPointer(node)).second)
         return SymbolicExpr::TRUNCATE;          // already processed this subexpression
     if (SymbolicExpr::LeafPtr leaf = node->isLeafNode()) {
         if (leaf->isVariable()) {
             if (defns->find(leaf->nameId()) == defns->end()) {
                 defns->insert(leaf->nameId());
                 yices_type bvtype = yices_mk_bitvector_type(self->context, leaf->nBits());
                 ASSERT_not_null(bvtype);
                 std::string name = "v" + StringUtility::numberToString(leaf->nameId());
                 yices_var_decl vdecl __attribute__((unused)) = yices_mk_var_decl(self->context, name.c_str(), bvtype);
                 ASSERT_not_null(vdecl);
             }
         } else if (leaf->isMemory()) {
             if (defns->find(leaf->nameId()) == defns->end()) {
                 defns->insert(leaf->nameId());
                 yices_type domain = yices_mk_bitvector_type(self->context, leaf->domainWidth());
                 yices_type range = yices_mk_bitvector_type(self->context, leaf->nBits());
                 yices_type ftype = yices_mk_function_type(self->context, &domain, 1, range);
                 ASSERT_not_null(ftype);
                 std::string name = "m" + StringUtility::numberToString(leaf->nameId());
                 yices_var_decl vdecl __attribute__((unused)) = yices_mk_var_decl(self->context, name.c_str(), ftype);
                 ASSERT_not_null(vdecl);
             }
         }
     }
     return SymbolicExpr::CONTINUE;
 }
void
appendExpression(SgAsmExprListExp *exprList, SgAsmExpression *expr) {
    ASSERT_not_null(exprList);
    ASSERT_not_null(expr);
    expr->set_parent(exprList);
    exprList->get_expressions().push_back(expr);
}
Example #3
0
void
RiscOperators::startInstruction(SgAsmInstruction *insn) {
    ASSERT_not_null(currentState());
    ASSERT_not_null(currentState()->memoryState());

    BaseSemantics::MemoryStatePtr mem = currentState()->memoryState();
    if (MemoryListStatePtr ml = boost::dynamic_pointer_cast<MemoryListState>(mem)) {
        ml->addressesRead().clear();
    } else if (MemoryMapStatePtr mm = boost::dynamic_pointer_cast<MemoryMapState>(mem)) {
        mm->addressesRead().clear();
    }
    SymbolicSemantics::RiscOperators::startInstruction(insn);
}
Example #4
0
/* Class method to register a new disassembler subclass. Thread safe. */
void
Disassembler::register_subclass(Disassembler *factory)
{
    boost::lock_guard<boost::mutex> lock(class_mutex);
    ASSERT_not_null(factory);
    disassemblers.push_back(factory);
}
Example #5
0
RiscOperatorsPtr
RiscOperators::promote(const BaseSemantics::RiscOperatorsPtr &ops)
{
    RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(ops);
    ASSERT_not_null(retval);
    return retval;
}
Example #6
0
// Output for "set" operator. (set a b c) gets translated to the symbolic expression (ite v1 a (ite v1 b c)), which
// in turn gets translated to Yices output.
void
YicesSolver::out_set(std::ostream &o, const SymbolicExpr::InteriorPtr &in) {
    ASSERT_not_null(in);
    ASSERT_require(in->getOperator() == SymbolicExpr::OP_SET);
    ASSERT_require(in->nChildren() >= 2);
    SymbolicExpr::Ptr ite = SymbolicExpr::setToIte(in);
    out_expr(o, ite);
}
Example #7
0
/** Emit type name for term. */
std::string
YicesSolver::get_typename(const SymbolicExpr::Ptr &expr) {
    ASSERT_not_null(expr);
    if (expr->isScalar())
        return "(bitvector " + StringUtility::numberToString(expr->nBits()) + ")";
    return ("(-> (bitvector " + StringUtility::numberToString(expr->domainWidth()) + ")"
            " (bitvector " + StringUtility::numberToString(expr->nBits()) + "))");
}
NoOperation::NoOperation(Disassembler *disassembler) {
    normalizer_ = StateNormalizer::instance();

    if (disassembler) {
        const RegisterDictionary *registerDictionary = disassembler->get_registers();
        ASSERT_not_null(registerDictionary);
        size_t addrWidth = disassembler->instructionPointerRegister().get_nbits();

        SMTSolver *solver = NULL;
        SymbolicSemantics::RiscOperatorsPtr ops = SymbolicSemantics::RiscOperators::instance(registerDictionary, solver);
        ops->computingDefiners(SymbolicSemantics::TRACK_NO_DEFINERS);
        ops->computingMemoryWriters(SymbolicSemantics::TRACK_LATEST_WRITER); // necessary to erase non-written memory

        BaseSemantics::MemoryCellListPtr mstate = BaseSemantics::MemoryCellList::promote(ops->currentState()->memoryState());
        ASSERT_not_null(mstate);
        mstate->occlusionsErased(true);

        cpu_ = disassembler->dispatcher()->create(ops, addrWidth, registerDictionary);
    }
}
Example #9
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 #10
0
size_t
RiscOperators::add_subdomain(const BaseSemantics::RiscOperatorsPtr &subdomain, const std::string &name, bool activate)
{
    ASSERT_not_null(subdomain);
    size_t idx = subdomains.size();
    subdomains.push_back(subdomain);
    active.push_back(activate);
    if (idx>=formatter.subdomain_names.size())
        formatter.subdomain_names.resize(idx+1, "");
    formatter.subdomain_names[idx] = name;
    SValue::promote(protoval())->set_subvalue(idx, subdomain->protoval());
    return idx;
}
BaseSemantics::StatePtr
NoOperation::initialState(SgAsmInstruction *insn) const {
    ASSERT_not_null(insn);
    ASSERT_not_null(cpu_);
    BaseSemantics::StatePtr state;
    if (normalizer_) {
        state = normalizer_->initialState(cpu_, insn);
    } else {
        state = cpu_->currentState()->clone();
        state->clear();
        RegisterDescriptor IP = cpu_->instructionPointerRegister();
        state->writeRegister(IP, cpu_->number_(IP.get_nbits(), insn->get_address()), cpu_->get_operators().get());
    }

    // Set the stack pointer to a concrete value
    if (initialSp_) {
        const RegisterDescriptor regSp = cpu_->stackPointerRegister();
        BaseSemantics::RiscOperatorsPtr ops = cpu_->get_operators();
        state->writeRegister(regSp, ops->number_(regSp.get_nbits(), *initialSp_), ops.get());
    }

    return state;
}
Example #12
0
/** Traverse an expression and produce Yices "define" statements for variables. */
void
YicesSolver::out_define(std::ostream &o, const std::vector<SymbolicExpr::Ptr> &exprs, Definitions *defns) {
    ASSERT_not_null(defns);

    struct T1: SymbolicExpr::Visitor {
        typedef std::set<const SymbolicExpr::Node*> SeenNodes;
        SeenNodes seen;
        std::ostream &o;
        Definitions *defns;

        T1(std::ostream &o, Definitions *defns)
            : o(o), defns(defns) {}

        SymbolicExpr::VisitAction preVisit(const SymbolicExpr::Ptr &node) {
            if (!seen.insert(getRawPointer(node)).second)
                return SymbolicExpr::TRUNCATE;          // already processed this subexpression
            if (SymbolicExpr::LeafPtr leaf = node->isLeafNode()) {
                if (leaf->isVariable()) {
                    if (defns->find(leaf->nameId())==defns->end()) {
                        defns->insert(leaf->nameId());
                        o <<"\n";
                        if (!leaf->comment().empty())
                            o <<StringUtility::prefixLines(leaf->comment(), "; ") <<"\n";
                        o <<"(define v" <<leaf->nameId() <<"::" <<get_typename(leaf) <<")\n";
                    }
                } else if (leaf->isMemory()) {
                    if (defns->find(leaf->nameId())==defns->end()) {
                        defns->insert(leaf->nameId());
                        o <<"\n";
                        if (!leaf->comment().empty())
                            o <<StringUtility::prefixLines(leaf->comment(), "; ") <<"\n";
                        o <<"(define m" <<leaf->nameId() <<"::" <<get_typename(leaf) <<")\n";
                    }
                }
            }
            return SymbolicExpr::CONTINUE;
        }

        SymbolicExpr::VisitAction postVisit(const SymbolicExpr::Ptr&) {
            return SymbolicExpr::CONTINUE;
        }
    } t1(o, defns);

    BOOST_FOREACH (const SymbolicExpr::Ptr &expr, exprs)
        expr->depthFirstTraversal(t1);
}
Example #13
0
SgAsmInstruction*
InstructionProvider::operator[](rose_addr_t va) const {
    SgAsmInstruction *insn = NULL;
    if (!insnMap_.getOptional(va).assignTo(insn)) {
        if (useDisassembler_ && memMap_.at(va).require(MemoryMap::EXECUTABLE).exists()) {
            try {
                insn = disassembler_->disassembleOne(&memMap_, va);
            } catch (const Disassembler::Exception &e) {
                insn = disassembler_->make_unknown_instruction(e);
                ASSERT_not_null(insn);
                uint8_t byte;
                if (1==memMap_.at(va).limit(1).require(MemoryMap::EXECUTABLE).read(&byte).size())
                    insn->set_raw_bytes(SgUnsignedCharList(1, byte));
                ASSERT_require(insn->get_address()==va);
                ASSERT_require(insn->get_size()==1);
            }
        }
        insnMap_.insert(va, insn);
    }
    return insn;
}
Example #14
0
RiscOperatorsPtr
RiscOperators::instance(const Partitioner2::Partitioner *partitioner,
                        const RegisterDictionary *regdict,
                        const SmtSolver::Ptr &solver) {
    BaseSemantics::SValuePtr protoval = SValue::instance();
    BaseSemantics::RegisterStatePtr registers = RegisterState::instance(protoval, regdict);
    BaseSemantics::MemoryStatePtr memory;
    switch (settings.searchMode) {
        case SEARCH_MULTI:
            // If we're sending multiple paths at a time to the SMT solver then we need to provide the SMT solver with
            // detailed information about how memory is affected on those different paths.
            memory = BaseSemantics::SymbolicMemory::instance(protoval, protoval);
            break;
        case SEARCH_SINGLE_DFS:
        case SEARCH_SINGLE_BFS:
            // We can perform memory-related operations and simplifications inside ROSE, which results in more but smaller
            // expressions being sent to the SMT solver.
            memory = SymbolicSemantics::MemoryState::instance(protoval, protoval);
            break;
    }
    ASSERT_not_null(memory);
    BaseSemantics::StatePtr state = State::instance(registers, memory);
    return RiscOperatorsPtr(new RiscOperators(partitioner, state, solver));
}
Example #15
0
void
InstructionProvider::insert(SgAsmInstruction *insn) {
    ASSERT_not_null(insn);
    insnMap_.insert(insn->get_address(), insn);
}
SgAsmFloatValueExpression*
buildValueFloat(const Sawyer::Container::BitVector &bv, SgAsmType *type) {
    ASSERT_not_null(type);
    ASSERT_require(bv.size() == type->get_nBits());
    return new SgAsmFloatValueExpression(bv, type);
}
SgAsmFloatValueExpression*
buildValueFloat(double x, SgAsmType *type) {
    ASSERT_not_null(type);
    return new SgAsmFloatValueExpression(x, type);
}
Example #18
0
/** 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;
        }
    }
}