Example #1
0
    // Mark a node complete, updating its children.
    // Removes the node from the data structure
    void mark_done(SliceNode::Ptr n) {
        // First pull all of the children of this node
        // that are not on the skip list

        set<SliceNode::Ptr> children;

        EdgeIterator begin, end;
        n->outs(begin, end);
        for (; begin != end; ++begin) {
            Edge::Ptr edge = *begin;
            if(skip_edges.find(edge) == skip_edges.end()) {
                SliceNode::Ptr child =
                    boost::static_pointer_cast<SliceNode>(
                        edge->target());
                if(remove(child))
                    children.insert(child);
            }
        }

        // remove n and set done
        remove(n);
        done.insert(n);

        // put the children back
        set<SliceNode::Ptr>::iterator cit = children.begin();
        for( ; cit != children.end(); ++cit) {
            insert(*cit);
        }
    }
Example #2
0
// Do the previous, but use a Graph as a guide for
// performing forward substitution on the AST results
SymEval::Retval_t SymEval::expand(Dyninst::Graph::Ptr slice, DataflowAPI::Result_t &res) {
    bool failedTranslation = false;
    bool skippedInput = false;

    //cout << "Calling expand" << endl;
    // Other than the substitution this is pretty similar to the first example.
    NodeIterator gbegin, gend;
    slice->allNodes(gbegin, gend);

    // First, we'll sort the nodes in some deterministic order so that the loop removal
    // is deterministic
    std::vector<SliceNode::Ptr> sortVector;
    for ( ; gbegin != gend; ++gbegin) {
        Node::Ptr ptr = *gbegin;
        expand_cerr << "pushing " << (*gbegin)->format() << " to sortVector" << endl;
        SliceNode::Ptr cur = boost::static_pointer_cast<SliceNode>(ptr);
        sortVector.push_back(cur);
    }
    std::stable_sort(sortVector.begin(), sortVector.end(), vectorSort);

    // Optimal ordering of search
    ExpandOrder worklist;

    std::queue<Node::Ptr> dfs_worklist;
    std::vector<SliceNode::Ptr>::iterator vit = sortVector.begin();
    for ( ; vit != sortVector.end(); ++vit) {
        SliceNode::Ptr ptr = *vit;
        Node::Ptr cur = boost::static_pointer_cast<Node>(ptr);
        dfs_worklist.push(cur);
    }

    /* First, we'll do DFS to check for circularities in the graph;
     * if so, mark them so we don't do infinite substitution */
    std::map<Node::Ptr, int> state;
    while (!dfs_worklist.empty()) {
        Node::Ptr ptr = dfs_worklist.front();
        dfs_worklist.pop();
        dfs(ptr, state, worklist.skipEdges());
    }

    slice->allNodes(gbegin, gend);
    for (; gbegin != gend; ++gbegin) {
        expand_cerr << "adding " << (*gbegin)->format() << " to worklist" << endl;
        Node::Ptr ptr = *gbegin;
        SliceNode::Ptr sptr =
            boost::static_pointer_cast<SliceNode>(ptr);
        worklist.insert(sptr,false);
    }

    /* have a list
     * for each node, process
     * if processessing succeeded, remove the element
     * if the size of the list has changed, continue */

    while (1) {
        SliceNode::Ptr aNode;
        int order;

        boost::tie(aNode,order) = worklist.pop_next();
        if (order == -1) // empty
            break;

        if (!aNode->assign()) {
            worklist.mark_done(aNode);
            continue; // Could be a widen point
        }

        expand_cerr << "Visiting node " << aNode->assign()->format()
                    << " order " << order << endl;

        if (order != 0) {
            cerr << "ERROR: order is non zero: " << order << endl;
        }
        assert(order == 0); // there are no loops

        AST::Ptr prev = res[aNode->assign()];
        Retval_t result = process(aNode, res, worklist.skipEdges());
        AST::Ptr post = res[aNode->assign()];
        switch (result) {
        case FAILED:
            return FAILED;
            break;
        case WIDEN_NODE:
            // Okay...
            break;
        case FAILED_TRANSLATION:
            failedTranslation = true;
            break;
        case SKIPPED_INPUT:
            skippedInput = true;
            break;
        case SUCCESS:
            break;
        }

        // We've visited this node, freeing its children
        // to be visited in turn
        worklist.mark_done(aNode);

        if (post && !(post->equals(prev))) {
            expand_cerr << "Adding successors to list, as new expansion " << endl
                        << "\t" << post->format() << endl
                        << " != " << endl
                        << "\t" << (prev ? prev->format() : "<NULL>") << endl;
            EdgeIterator oB, oE;
            aNode->outs(oB, oE);
            for (; oB != oE; ++oB) {
                if(worklist.skipEdges().find(*oB) == worklist.skipEdges().end()) {
                    SliceNode::Ptr out =
                        boost::static_pointer_cast<SliceNode>(
                            (*oB)->target());
                    worklist.insert(out);
                }
            }
        }
    }
    if (failedTranslation) return FAILED_TRANSLATION;
    else if (skippedInput) return SKIPPED_INPUT;
    else return SUCCESS;
}