Search in sources :

Example 6 with LocalVarNode

use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.

the class EvalResults method checkCallGraph.

/**
 * Report the virtual callsites resolution result for the user's code.
 */
public void checkCallGraph() {
    int[] limits = new int[] { 1, 2, 4, 8 };
    evalRes.total_call_edges = new Histogram(limits);
    CallGraph cg = Scene.v().getCallGraph();
    for (Stmt callsite : ptsProvider.multiCallsites) {
        Iterator<Edge> edges = cg.edgesOutOf(callsite);
        if (!edges.hasNext())
            continue;
        evalRes.n_callsites++;
        // get an edge
        Edge anyEdge = edges.next();
        SootMethod src = anyEdge.src();
        if (!ptsProvider.isReachableMethod(src) || !ptsProvider.isValidMethod(src))
            continue;
        // get the base pointer
        CgEdge p = ptsProvider.getInternalEdgeFromSootEdge(anyEdge);
        LocalVarNode vn = (LocalVarNode) p.base_var;
        // test the call graph
        int edge_cnt = 1;
        while (edges.hasNext()) {
            ++edge_cnt;
            edges.next();
        }
        evalRes.n_geom_call_edges += edge_cnt;
        if (edge_cnt == 1)
            ++evalRes.n_geom_solved_all;
        // test app method
        if (!src.isJavaLibraryMethod()) {
            InvokeExpr ie = callsite.getInvokeExpr();
            if (edge_cnt == 1) {
                ++evalRes.n_geom_solved_app;
                if (ptsProvider.getOpts().verbose()) {
                    outputer.println();
                    outputer.println("<<<<<<<<<   Additional Solved Call   >>>>>>>>>>");
                    outputer.println(src.toString());
                    outputer.println(ie.toString());
                }
            } else {
                // We try to test if this callsite is solvable
                // under some contexts
                Histogram call_edges = new Histogram(limits);
                test_1cfa_call_graph(vn, src, ie.getMethod(), call_edges);
                evalRes.total_call_edges.merge(call_edges);
                call_edges = null;
            }
            evalRes.n_geom_user_edges += edge_cnt;
            evalRes.n_user_callsites++;
        }
    }
    ptsProvider.ps.println();
    ptsProvider.ps.println("--------> Virtual Callsites Evaluation <---------");
    ptsProvider.ps.printf("Total virtual callsites (app code): %d (%d)\n", evalRes.n_callsites, evalRes.n_user_callsites);
    ptsProvider.ps.printf("Total virtual call edges (app code): %d (%d)\n", evalRes.n_geom_call_edges, evalRes.n_geom_user_edges);
    ptsProvider.ps.printf("Virtual callsites additionally solved by geomPTA compared to SPARK (app code) = %d (%d)\n", evalRes.n_geom_solved_all, evalRes.n_geom_solved_app);
    evalRes.total_call_edges.printResult(ptsProvider.ps, "Testing of unsolved callsites on 1-CFA call graph: ");
    if (ptsProvider.getOpts().verbose())
        ptsProvider.outputNotEvaluatedMethods();
}
Also used : CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) Histogram(soot.jimple.spark.geom.utils.Histogram) InvokeExpr(soot.jimple.InvokeExpr) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) SootMethod(soot.SootMethod) Edge(soot.jimple.toolkits.callgraph.Edge) CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt)

Example 7 with LocalVarNode

use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.

the class DemandCSPointsTo method getFlowsToHelper.

protected Set<VarNode> getFlowsToHelper(AllocAndContext allocAndContext) {
    Set<VarNode> ret = new ArraySet<VarNode>();
    try {
        HashSet<VarAndContext> marked = new HashSet<VarAndContext>();
        Stack<VarAndContext> worklist = new Stack<VarAndContext>();
        Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
        AllocNode alloc = allocAndContext.alloc;
        ImmutableStack<Integer> allocContext = allocAndContext.context;
        Node[] newBarNodes = pag.allocLookup(alloc);
        for (int i = 0; i < newBarNodes.length; i++) {
            VarNode v = (VarNode) newBarNodes[i];
            ret.add(v);
            p.prop(new VarAndContext(v, allocContext));
        }
        while (!worklist.isEmpty()) {
            incrementNodesTraversed();
            VarAndContext curVarAndContext = worklist.pop();
            if (DEBUG) {
                debugPrint("looking at " + curVarAndContext);
            }
            VarNode curVar = curVarAndContext.var;
            ImmutableStack<Integer> curContext = curVarAndContext.context;
            ret.add(curVar);
            // assign
            Collection<AssignEdge> assignEdges = filterAssigns(curVar, curContext, false, true);
            for (AssignEdge assignEdge : assignEdges) {
                VarNode dst = assignEdge.getDst();
                ImmutableStack<Integer> newContext = curContext;
                if (assignEdge.isReturnEdge()) {
                    if (!curContext.isEmpty()) {
                        if (!callEdgeInSCC(assignEdge)) {
                            assert assignEdge.getCallSite().equals(curContext.peek()) : assignEdge + " " + curContext;
                            newContext = curContext.pop();
                        } else {
                            newContext = popRecursiveCallSites(curContext);
                        }
                    }
                } else if (assignEdge.isParamEdge()) {
                    if (DEBUG)
                        debugPrint("entering call site " + assignEdge.getCallSite());
                    // if (!isRecursive(curContext, assignEdge)) {
                    // newContext = curContext.push(assignEdge
                    // .getCallSite());
                    // }
                    newContext = pushWithRecursionCheck(curContext, assignEdge);
                }
                if (assignEdge.isReturnEdge() && curContext.isEmpty() && csInfo.isVirtCall(assignEdge.getCallSite())) {
                    Set<SootMethod> targets = refineCallSite(assignEdge.getCallSite(), newContext);
                    if (!targets.contains(((LocalVarNode) assignEdge.getDst()).getMethod())) {
                        continue;
                    }
                }
                if (dst instanceof GlobalVarNode) {
                    newContext = EMPTY_CALLSTACK;
                }
                p.prop(new VarAndContext(dst, newContext));
            }
            // putfield_bars
            Set<VarNode> matchTargets = vMatches.vMatchLookup(curVar);
            Node[] pfTargets = pag.storeLookup(curVar);
            for (int i = 0; i < pfTargets.length; i++) {
                FieldRefNode frNode = (FieldRefNode) pfTargets[i];
                final VarNode storeBase = frNode.getBase();
                SparkField field = frNode.getField();
                // FieldRefNode>(curVar, frNode);
                for (Pair<VarNode, VarNode> load : fieldToLoads.get(field)) {
                    final VarNode loadBase = load.getO2();
                    final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
                    final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
                    final VarNode matchTgt = load.getO1();
                    if (matchTargets.contains(matchTgt)) {
                        if (DEBUG) {
                            debugPrint("match source " + matchTgt);
                        }
                        PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
                        boolean checkField = fieldCheckHeuristic.validateMatchesForField(field);
                        if (checkField) {
                            AllocAndContextSet sharedAllocContexts = findContextsForAllocs(new VarAndContext(storeBase, curContext), intersection);
                            for (AllocAndContext curAllocAndContext : sharedAllocContexts) {
                                CallingContextSet upContexts;
                                if (fieldCheckHeuristic.validFromBothEnds(field)) {
                                    upContexts = findUpContextsForVar(curAllocAndContext, new VarContextAndUp(loadBase, EMPTY_CALLSTACK, EMPTY_CALLSTACK));
                                } else {
                                    upContexts = findVarContextsFromAlloc(curAllocAndContext, loadBase);
                                }
                                for (ImmutableStack<Integer> upContext : upContexts) {
                                    p.prop(new VarAndContext(matchTgt, upContext));
                                }
                            }
                        } else {
                            p.prop(new VarAndContext(matchTgt, EMPTY_CALLSTACK));
                        }
                    // h.handleMatchSrc(matchSrc, intersection,
                    // storeBase,
                    // loadBase, varAndContext, checkGetfield);
                    // if (h.terminate())
                    // return;
                    }
                }
            }
        }
        return ret;
    } catch (CallSiteException e) {
        allocAndContextCache.remove(allocAndContext);
        throw e;
    }
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) AssignEdge(soot.jimple.spark.ondemand.pautil.AssignEdge) SparkField(soot.jimple.spark.pag.SparkField) Propagator(soot.jimple.spark.ondemand.genericutil.Propagator) HashSet(java.util.HashSet) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) ArraySet(soot.jimple.spark.ondemand.genericutil.ArraySet) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) Stack(soot.jimple.spark.ondemand.genericutil.Stack) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) AllocNode(soot.jimple.spark.pag.AllocNode) SootMethod(soot.SootMethod) LocalVarNode(soot.jimple.spark.pag.LocalVarNode)

Example 8 with LocalVarNode

use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.

the class GeomQueries method kCFA.

/**
 * Standard K-CFA querying for arbitrary K.
 *
 * @param callEdgeChain: last K call edges leading to the method that contains l. callEdgeChain[0] is the farthest call edge in the chain.
 * @param l: the querying pointer
 * @param visitor: the querying result container
 * @return false, l does not have points-to information under the given context
 */
@SuppressWarnings("rawtypes")
public boolean kCFA(Edge[] callEdgeChain, Local l, PtSensVisitor visitor) {
    // Prepare for initial contexts
    SootMethod firstMethod = callEdgeChain[0].src();
    int firstMethodID = geomPTA.getIDFromSootMethod(firstMethod);
    if (firstMethodID == -1)
        return false;
    // Obtain the internal representation for querying pointer
    LocalVarNode vn = geomPTA.findLocalVarNode(l);
    if (vn == null) {
        // Normally this could not happen, perhaps it's a bug
        return false;
    }
    IVarAbstraction pn = geomPTA.findInternalNode(vn);
    if (pn == null) {
        // This pointer is no longer reachable
        return false;
    }
    pn = pn.getRepresentative();
    if (!pn.hasPTResult())
        return false;
    SootMethod sm = vn.getMethod();
    if (geomPTA.getIDFromSootMethod(sm) == -1)
        return false;
    // Iterate the call edges and compute the contexts mapping iteratively
    visitor.prepare();
    long L = 1;
    for (int i = 0; i < callEdgeChain.length; ++i) {
        Edge sootEdge = callEdgeChain[i];
        CgEdge ctxt = geomPTA.getInternalEdgeFromSootEdge(sootEdge);
        if (ctxt == null || ctxt.is_obsoleted == true)
            return false;
        // Following searching procedure works for both methods in SCC and out of SCC
        // with blocking scheme or without blocking scheme
        int caller = geomPTA.getIDFromSootMethod(sootEdge.src());
        // We obtain the block that contains current offset L
        long block_size = max_context_size_block[rep_cg[caller]];
        long in_block_offset = (L - 1) % block_size;
        // Transfer to the target block with the same in-block offset
        L = ctxt.map_offset + in_block_offset;
    }
    long ctxtLength = max_context_size_block[rep_cg[firstMethodID]];
    long R = L + ctxtLength;
    pn.get_all_context_sensitive_objects(L, R, visitor);
    visitor.finish();
    return visitor.numOfDiffObjects() != 0;
}
Also used : CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) SootMethod(soot.SootMethod) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) Edge(soot.jimple.toolkits.callgraph.Edge)

Example 9 with LocalVarNode

use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.

the class GeomQueries method contextsGoBy.

/**
 * Answer contexts-go-by query.
 *
 * Usually, users specify the last K paths as the context. We call it k-CFA context.
 * However, k-CFA is too restrictive.
 * In contexts-go-by query, user specifies arbitrary call edge in the call graph.
 * The query searches for all contexts induced by the specified call edge and collect points-to results under these contexts.
 *
 * @param sootEdge: the specified context edge in soot edge format
 * @param l: the querying pointer
 * @param visitor: container for querying result
 * @return false, l does not have points-to information under the contexts induced by the given call edge
 */
@SuppressWarnings("rawtypes")
public boolean contextsGoBy(Edge sootEdge, Local l, PtSensVisitor visitor) {
    // Obtain the internal representation of specified context
    CgEdge ctxt = geomPTA.getInternalEdgeFromSootEdge(sootEdge);
    if (ctxt == null || ctxt.is_obsoleted == true)
        return false;
    // Obtain the internal representation for querying pointer
    LocalVarNode vn = geomPTA.findLocalVarNode(l);
    if (vn == null) {
        // Normally this could not happen, perhaps it's a bug
        return false;
    }
    IVarAbstraction pn = geomPTA.findInternalNode(vn);
    if (pn == null) {
        // This pointer is no longer reachable
        return false;
    }
    pn = pn.getRepresentative();
    if (!pn.hasPTResult())
        return false;
    // Obtain the internal representation of the method that encloses the querying pointer
    SootMethod sm = vn.getMethod();
    int target = geomPTA.getIDFromSootMethod(sm);
    if (target == -1)
        return false;
    // Start call graph traversal
    long L = ctxt.map_offset;
    long R = L + max_context_size_block[rep_cg[ctxt.s]];
    assert L < R;
    visitor.prepare();
    prepareIntervalPropagations();
    if (propagateIntervals(ctxt.t, L, R, target)) {
        // We calculate the points-to results
        ContextsCollector targetContexts = contextsForMethods[target];
        for (SimpleInterval si : targetContexts.bars) {
            assert si.L < si.R;
            pn.get_all_context_sensitive_objects(si.L, si.R, visitor);
        }
        // Reset
        targetContexts.clear();
    }
    visitor.finish();
    return visitor.numOfDiffObjects() != 0;
}
Also used : CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) SootMethod(soot.SootMethod) SimpleInterval(soot.jimple.spark.geom.dataRep.SimpleInterval) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) ContextsCollector(soot.jimple.spark.geom.dataMgr.ContextsCollector)

Example 10 with LocalVarNode

use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.

the class GeomQueries method isAlias.

/**
 * Decide if under any contexts, pointers @param l1 and @param l2 can be an alias.
 */
public boolean isAlias(Local l1, Local l2) {
    // Obtain the internal representation for querying pointers
    LocalVarNode vn1 = geomPTA.findLocalVarNode(l1);
    LocalVarNode vn2 = geomPTA.findLocalVarNode(l2);
    if (vn1 == null || vn2 == null) {
        // Normally this could not happen, perhaps it's a bug
        return false;
    }
    IVarAbstraction pn1 = geomPTA.findInternalNode(vn1);
    IVarAbstraction pn2 = geomPTA.findInternalNode(vn2);
    if (pn1 == null || pn2 == null) {
        return isAliasCI(l1, l2);
    }
    pn1 = pn1.getRepresentative();
    pn2 = pn2.getRepresentative();
    if (!pn1.hasPTResult() || !pn2.hasPTResult()) {
        return isAliasCI(l1, l2);
    }
    return pn1.heap_sensitive_intersection(pn2);
}
Also used : LocalVarNode(soot.jimple.spark.pag.LocalVarNode)

Aggregations

LocalVarNode (soot.jimple.spark.pag.LocalVarNode)22 SootMethod (soot.SootMethod)16 AllocNode (soot.jimple.spark.pag.AllocNode)15 Node (soot.jimple.spark.pag.Node)13 VarNode (soot.jimple.spark.pag.VarNode)11 FieldRefNode (soot.jimple.spark.pag.FieldRefNode)8 PointsToSetInternal (soot.jimple.spark.sets.PointsToSetInternal)6 RefType (soot.RefType)5 GlobalVarNode (soot.jimple.spark.pag.GlobalVarNode)5 SootClass (soot.SootClass)4 CgEdge (soot.jimple.spark.geom.dataRep.CgEdge)4 PlainConstraint (soot.jimple.spark.geom.dataRep.PlainConstraint)4 AssignEdge (soot.jimple.spark.ondemand.pautil.AssignEdge)4 ContextVarNode (soot.jimple.spark.pag.ContextVarNode)4 SparkField (soot.jimple.spark.pag.SparkField)4 StringConstantNode (soot.jimple.spark.pag.StringConstantNode)4 HashSet (java.util.HashSet)3 Hierarchy (soot.Hierarchy)3 Unit (soot.Unit)3 AssignStmt (soot.jimple.AssignStmt)3