Search in sources :

Example 1 with ChunkedQueue

use of soot.util.queue.ChunkedQueue in project soot by Sable.

the class GeomPointsTo method updateCallGraph.

/**
 * Remove unreachable call targets at the virtual callsites using the up-to-date points-to information.
 */
private int updateCallGraph() {
    int all_virtual_edges = 0, n_obsoleted = 0;
    CallGraph cg = Scene.v().getCallGraph();
    ChunkedQueue<SootMethod> targetsQueue = new ChunkedQueue<SootMethod>();
    QueueReader<SootMethod> targets = targetsQueue.reader();
    Set<SootMethod> resolvedMethods = new HashSet<SootMethod>();
    // We first update the virtual callsites
    for (Iterator<Stmt> csIt = multiCallsites.iterator(); csIt.hasNext(); ) {
        Stmt callsite = csIt.next();
        Iterator<Edge> edges = cg.edgesOutOf(callsite);
        if (!edges.hasNext()) {
            csIt.remove();
            continue;
        }
        Edge anyEdge = edges.next();
        CgEdge p = edgeMapping.get(anyEdge);
        SootMethod src = anyEdge.src();
        if (!isReachableMethod(src)) {
            // The source method is no longer reachable
            // We move this callsite
            csIt.remove();
            continue;
        }
        if (!edges.hasNext()) {
            // We keep this resolved site for call graph profiling
            continue;
        }
        IVarAbstraction pn = consG.get(p.base_var);
        if (pn != null) {
            pn = pn.getRepresentative();
            // We resolve the call targets with the new points-to result
            getCallTargets(pn, src, callsite, targetsQueue);
            resolvedMethods.clear();
            while (targets.hasNext()) {
                resolvedMethods.add(targets.next());
            }
            // We delete the edges that are proven to be spurious
            while (true) {
                SootMethod tgt = anyEdge.tgt();
                if (!resolvedMethods.contains(tgt) && !anyEdge.kind().isFake()) {
                    p = edgeMapping.get(anyEdge);
                    p.is_obsoleted = true;
                }
                if (!edges.hasNext())
                    break;
                anyEdge = edges.next();
            }
        }
    }
    // We delete the spurious edges
    for (int i = 1; i < n_func; ++i) {
        // New outgoing edge list is pointed to by q
        CgEdge p = call_graph[i];
        CgEdge q = null;
        while (p != null) {
            if (vis_cg[i] == 0) {
                // If this method is unreachable, we delete all its outgoing edges
                p.is_obsoleted = true;
            }
            if (p.base_var != null) {
                ++all_virtual_edges;
            }
            CgEdge temp = p.next;
            if (p.is_obsoleted == false) {
                p.next = q;
                q = p;
            } else {
                // Update the corresponding SOOT call graph
                // ps.println("%%% Remove an call edge: " + p.toString());
                cg.removeEdge(p.sootEdge);
                // We record this obsoleted edge
                // obsoletedEdges.add(p);
                ++n_obsoleted;
            }
            p = temp;
        }
        call_graph[i] = q;
    }
    ps.printf("%d of %d virtual call edges are proved to be spurious.\n", n_obsoleted, all_virtual_edges);
    return n_obsoleted;
}
Also used : CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) ChunkedQueue(soot.util.queue.ChunkedQueue) PlainConstraint(soot.jimple.spark.geom.dataRep.PlainConstraint) Stmt(soot.jimple.Stmt) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) SootMethod(soot.SootMethod) Edge(soot.jimple.toolkits.callgraph.Edge) CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) HashSet(java.util.HashSet)

Example 2 with ChunkedQueue

use of soot.util.queue.ChunkedQueue in project soot by Sable.

the class SootUtil method getCallTargets.

public static Collection<? extends SootMethod> getCallTargets(Type type, SootMethod invokedMethod) {
    if (isConstructor(invokedMethod)) {
        return Collections.singleton(invokedMethod);
    }
    Type receiverType = invokedMethod.getDeclaringClass().getType();
    ChunkedQueue chunkedQueue = new ChunkedQueue();
    Iterator iter = chunkedQueue.reader();
    VirtualCalls.v().resolve(type, receiverType, invokedMethod.getNumberedSubSignature(), null, chunkedQueue);
    Set<SootMethod> ret = new ArraySet<SootMethod>();
    for (; iter.hasNext(); ) {
        SootMethod target = (SootMethod) iter.next();
        ret.add(target);
    }
    return ret;
}
Also used : RefType(soot.RefType) ArrayType(soot.ArrayType) Type(soot.Type) ArraySet(soot.jimple.spark.ondemand.genericutil.ArraySet) ChunkedQueue(soot.util.queue.ChunkedQueue) Iterator(java.util.Iterator) SootMethod(soot.SootMethod)

Aggregations

SootMethod (soot.SootMethod)2 ChunkedQueue (soot.util.queue.ChunkedQueue)2 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 ArrayType (soot.ArrayType)1 RefType (soot.RefType)1 Type (soot.Type)1 Stmt (soot.jimple.Stmt)1 CgEdge (soot.jimple.spark.geom.dataRep.CgEdge)1 PlainConstraint (soot.jimple.spark.geom.dataRep.PlainConstraint)1 ArraySet (soot.jimple.spark.ondemand.genericutil.ArraySet)1 CallGraph (soot.jimple.toolkits.callgraph.CallGraph)1 Edge (soot.jimple.toolkits.callgraph.Edge)1