Beispiel #1
0
pair<AST::Ptr, bool> BoundFactsCalculator::ExpandAssignment(Assignment::Ptr assign) {
    parsing_printf("Expand assignment : %s Instruction: %s\n", assign->format().c_str(), assign->insn()->format().c_str());
    if (expandCache.find(assign) != expandCache.end()) {
        AST::Ptr ast = expandCache[assign];
        if (ast) return make_pair(ast, true); else return make_pair(ast, false);

    } else {
        pair<AST::Ptr, bool> expandRet = SymEval::expand(assign, false);
	if (expandRet.second && expandRet.first) {
	    parsing_printf("Original expand: %s\n", expandRet.first->format().c_str());
	    AST::Ptr calculation = SimplifyAnAST(expandRet.first, assign->insn()->size());
	    expandCache[assign] = calculation;
	} else {
	    expandCache[assign] = AST::Ptr();
	}
	return make_pair( expandCache[assign], expandRet.second );
    }
}
Beispiel #2
0
SymEval::Retval_t SymEval::process(SliceNode::Ptr ptr,
                                   Result_t &dbase,
                                   std::set<Edge::Ptr> &skipEdges) {
    bool failedTranslation;
    bool skippedEdge = false;
    bool skippedInput = false;
    bool success = false;

    std::map<const AbsRegion*, std::set<Assignment::Ptr> > inputMap;

    expand_cerr << "Calling process on " << ptr->format() << endl;

    // Don't try an expansion of a widen node...
    if (!ptr->assign()) return WIDEN_NODE;

    EdgeIterator begin, end;
    ptr->ins(begin, end);

    for (; begin != end; ++begin) {
        SliceEdge::Ptr edge = boost::static_pointer_cast<SliceEdge>(*begin);
        SliceNode::Ptr source = boost::static_pointer_cast<SliceNode>(edge->source());

        // Skip this one to break a cycle.
        if (skipEdges.find(edge) != skipEdges.end()) {
            expand_cerr << "In process, skipping edge from "
                        << source->format() << endl;
            skippedEdge = true;
            continue;
        }

        Assignment::Ptr assign = source->assign();
        if (!assign) continue; // widen node

        expand_cerr << "Assigning input " << edge->data().format()
                    << " from assignment " << assign->format() << endl;
        inputMap[&edge->data()].insert(assign);
    }

    expand_cerr << "\t Input map has size " << inputMap.size() << endl;

    // All of the expanded inputs are in the parameter dbase
    // If not (like this one), add it

    AST::Ptr ast;
    boost::tie(ast, failedTranslation) = SymEval::expand(ptr->assign());
    // expand_cerr << "\t ... resulting in " << dbase.format() << endl;

    // We have an AST. Now substitute in all of its predecessors.
    for (std::map<const AbsRegion*, std::set<Assignment::Ptr> >::iterator iter = inputMap.begin();
            iter != inputMap.end(); ++iter) {
        // If we have multiple secondary definitions, we:
        //   if all definitions are equal, use the first
        //   otherwise, use nothing
        AST::Ptr definition;

        for (std::set<Assignment::Ptr>::iterator iter2 = iter->second.begin();
                iter2 != iter->second.end(); ++iter2) {
            AST::Ptr newDef = dbase[*iter2];
            if (!definition) {
                definition = newDef;
                continue;
            } else if (definition->equals(newDef)) {
                continue;
            } else {
                // Not equal
                definition = AST::Ptr();
                skippedInput = true;
                break;
            }
        }

        // The region used by the current assignment...
        const AbsRegion &reg = *iter->first;

        // Create an AST around this one
        VariableAST::Ptr use = VariableAST::create(Variable(reg, ptr->addr()));

        if (!definition) {
            // Can happen if we're expanding out of order, and is generally harmless.
            continue;
        }

        expand_cerr << "Before substitution: " << (ast ? ast->format() : "<NULL AST>") << endl;

        if (!ast) {
            expand_cerr << "Skipping substitution because of null AST" << endl;
        } else {
            ast = AST::substitute(ast, use, definition);
            success = true;
        }
        expand_cerr << "\t result is " << (ast ? ast->format() : "<NULL AST>") << endl;
    }
    expand_cerr << "Result of substitution: " << ptr->assign()->format() << " == "
                << (ast ? ast->format() : "<NULL AST>") << endl;

    // And attempt simplification again
    ast = simplifyStack(ast, ptr->addr(), ptr->func(), ptr->block());
    expand_cerr << "Result of post-substitution simplification: " << ptr->assign()->format() << " == "
                << (ast ? ast->format() : "<NULL AST>") << endl;

    dbase[ptr->assign()] = ast;
    if (failedTranslation) return FAILED_TRANSLATION;
    else if (skippedEdge || skippedInput) return SKIPPED_INPUT;
    else if (success) return SUCCESS;
    else return FAILED;
}