Search in sources :

Example 51 with AllocNode

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

the class DemandCSPointsTo method processIncomingEdges.

protected void processIncomingEdges(IncomingEdgeHandler h, Stack<VarAndContext> worklist) {
    while (!worklist.isEmpty()) {
        incrementNodesTraversed();
        VarAndContext varAndContext = worklist.pop();
        if (DEBUG) {
            debugPrint("looking at " + varAndContext);
        }
        VarNode v = varAndContext.var;
        ImmutableStack<Integer> callingContext = varAndContext.context;
        Node[] newEdges = pag.allocInvLookup(v);
        for (int i = 0; i < newEdges.length; i++) {
            AllocNode allocNode = (AllocNode) newEdges[i];
            h.handleAlloc(allocNode, varAndContext);
            if (h.terminate()) {
                return;
            }
        }
        Collection<AssignEdge> assigns = filterAssigns(v, callingContext, true, true);
        for (AssignEdge assignEdge : assigns) {
            VarNode src = assignEdge.getSrc();
            // }
            if (h.shouldHandleSrc(src)) {
                ImmutableStack<Integer> newContext = callingContext;
                if (assignEdge.isParamEdge()) {
                    if (!callingContext.isEmpty()) {
                        if (!callEdgeInSCC(assignEdge)) {
                            assert assignEdge.getCallSite().equals(callingContext.peek()) : assignEdge + " " + callingContext;
                            newContext = callingContext.pop();
                        } else {
                            newContext = popRecursiveCallSites(callingContext);
                        }
                    }
                // } else if (refiningCallSite) {
                // if (!fieldCheckHeuristic.aggressiveVirtCallRefine())
                // {
                // // throw new CallSiteException();
                // }
                // }
                } else if (assignEdge.isReturnEdge()) {
                    if (DEBUG)
                        debugPrint("entering call site " + assignEdge.getCallSite());
                    // if (!isRecursive(callingContext, assignEdge)) {
                    // newContext = callingContext.push(assignEdge
                    // .getCallSite());
                    // }
                    newContext = pushWithRecursionCheck(callingContext, assignEdge);
                }
                if (assignEdge.isParamEdge()) {
                    Integer callSite = assignEdge.getCallSite();
                    if (csInfo.isVirtCall(callSite) && !weirdCall(callSite)) {
                        Set<SootMethod> targets = refineCallSite(callSite, newContext);
                        if (DEBUG) {
                            debugPrint(targets.toString());
                        }
                        SootMethod targetMethod = ((LocalVarNode) assignEdge.getDst()).getMethod();
                        if (!targets.contains(targetMethod)) {
                            if (DEBUG) {
                                debugPrint("skipping call because of call graph");
                            }
                            continue;
                        }
                    }
                }
                if (src instanceof GlobalVarNode) {
                    newContext = EMPTY_CALLSTACK;
                }
                h.handleAssignSrc(new VarAndContext(src, newContext), varAndContext, assignEdge);
                if (h.terminate()) {
                    return;
                }
            }
        }
        Set<VarNode> matchSources = vMatches.vMatchInvLookup(v);
        Node[] loads = pag.loadInvLookup(v);
        for (int i = 0; i < loads.length; i++) {
            FieldRefNode frNode = (FieldRefNode) loads[i];
            final VarNode loadBase = frNode.getBase();
            SparkField field = frNode.getField();
            // FieldRefNode>(v, frNode);
            for (Pair<VarNode, VarNode> store : fieldToStores.get(field)) {
                final VarNode storeBase = store.getO2();
                final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
                final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
                final VarNode matchSrc = store.getO1();
                if (matchSources.contains(matchSrc)) {
                    if (h.shouldHandleSrc(matchSrc)) {
                        if (DEBUG) {
                            debugPrint("match source " + matchSrc);
                        }
                        PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
                        boolean checkGetfield = fieldCheckHeuristic.validateMatchesForField(field);
                        h.handleMatchSrc(matchSrc, intersection, loadBase, storeBase, varAndContext, field, checkGetfield);
                        if (h.terminate())
                            return;
                    }
                }
            }
        }
    }
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) 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) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) AllocNode(soot.jimple.spark.pag.AllocNode) SootMethod(soot.SootMethod) LocalVarNode(soot.jimple.spark.pag.LocalVarNode)

Example 52 with AllocNode

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

the class DemandCSPointsTo method findVarContextsFromAlloc.

protected CallingContextSet findVarContextsFromAlloc(AllocAndContext allocAndContext, VarNode targetVar) {
    CallingContextSet tmpSet = checkAllocAndContextCache(allocAndContext, targetVar);
    if (tmpSet != null) {
        return tmpSet;
    }
    CallingContextSet ret = new CallingContextSet();
    allocAndContextCache.get(allocAndContext).put(targetVar, ret);
    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];
            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;
            if (curVar == targetVar) {
                ret.add(curContext);
            }
            // 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) 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 53 with AllocNode

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

the class DemandCSPointsTo method refineCallSite.

protected Set<SootMethod> refineCallSite(Integer callSite, ImmutableStack<Integer> origContext) {
    CallSiteAndContext callSiteAndContext = new CallSiteAndContext(callSite, origContext);
    if (queriedCallSites.contains(callSiteAndContext)) {
        // }
        return callSiteToResolvedTargets.get(callSiteAndContext);
    }
    if (callGraphStack.contains(callSiteAndContext)) {
        return Collections.<SootMethod>emptySet();
    } else {
        callGraphStack.push(callSiteAndContext);
    }
    final VarNode receiver = csInfo.getReceiverForVirtCallSite(callSite);
    final Type receiverType = receiver.getType();
    final SootMethod invokedMethod = csInfo.getInvokedMethod(callSite);
    final NumberedString methodSig = invokedMethod.getNumberedSubSignature();
    final Set<SootMethod> allTargets = csInfo.getCallSiteTargets(callSite);
    if (!refineCallGraph) {
        callGraphStack.pop();
        return allTargets;
    }
    if (DEBUG_VIRT) {
        debugPrint("refining call to " + invokedMethod + " on " + receiver + " " + origContext);
    }
    final HashSet<VarAndContext> marked = new HashSet<VarAndContext>();
    final Stack<VarAndContext> worklist = new Stack<VarAndContext>();
    final class Helper {

        void prop(VarAndContext varAndContext) {
            if (marked.add(varAndContext)) {
                worklist.push(varAndContext);
            }
        }
    }
    ;
    final Helper h = new Helper();
    h.prop(new VarAndContext(receiver, origContext));
    while (!worklist.isEmpty()) {
        incrementNodesTraversed();
        VarAndContext curVarAndContext = worklist.pop();
        if (DEBUG_VIRT) {
            debugPrint("virt looking at " + curVarAndContext);
        }
        VarNode curVar = curVarAndContext.var;
        ImmutableStack<Integer> curContext = curVarAndContext.context;
        // Set<SootMethod> curVarTargets = getCallTargets(curVar.getP2Set(),
        // methodSig, receiverType, allTargets);
        // if (curVarTargets.size() <= 1) {
        // for (SootMethod method : curVarTargets) {
        // callSiteToResolvedTargets.put(callSiteAndContext, method);
        // }
        // continue;
        // }
        Node[] newNodes = pag.allocInvLookup(curVar);
        for (int i = 0; i < newNodes.length; i++) {
            AllocNode allocNode = (AllocNode) newNodes[i];
            for (SootMethod method : getCallTargetsForType(allocNode.getType(), methodSig, receiverType, allTargets)) {
                callSiteToResolvedTargets.put(callSiteAndContext, method);
            }
        }
        Collection<AssignEdge> assigns = filterAssigns(curVar, curContext, true, true);
        for (AssignEdge assignEdge : assigns) {
            VarNode src = assignEdge.getSrc();
            ImmutableStack<Integer> newContext = curContext;
            if (assignEdge.isParamEdge()) {
                if (!curContext.isEmpty()) {
                    if (!callEdgeInSCC(assignEdge)) {
                        assert assignEdge.getCallSite().equals(curContext.peek());
                        newContext = curContext.pop();
                    } else {
                        newContext = popRecursiveCallSites(curContext);
                    }
                } else {
                    callSiteToResolvedTargets.putAll(callSiteAndContext, allTargets);
                    // }
                    continue;
                }
            } else if (assignEdge.isReturnEdge()) {
                // if (DEBUG)
                // logger.debug("entering call site "
                // + assignEdge.getCallSite());
                // if (!isRecursive(curContext, assignEdge)) {
                // newContext = curContext.push(assignEdge.getCallSite());
                // }
                newContext = pushWithRecursionCheck(curContext, assignEdge);
            } else if (src instanceof GlobalVarNode) {
                newContext = EMPTY_CALLSTACK;
            }
            h.prop(new VarAndContext(src, newContext));
        }
        // TODO respect heuristic
        Set<VarNode> matchSources = vMatches.vMatchInvLookup(curVar);
        final boolean oneMatch = matchSources.size() == 1;
        Node[] loads = pag.loadInvLookup(curVar);
        for (int i = 0; i < loads.length; i++) {
            FieldRefNode frNode = (FieldRefNode) loads[i];
            final VarNode loadBase = frNode.getBase();
            SparkField field = frNode.getField();
            for (Pair<VarNode, VarNode> store : fieldToStores.get(field)) {
                final VarNode storeBase = store.getO2();
                final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
                final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
                final VarNode matchSrc = store.getO1();
                if (matchSources.contains(matchSrc)) {
                    // optimize for common case of constructor init
                    boolean skipMatch = false;
                    if (oneMatch) {
                        PointsToSetInternal matchSrcPTo = matchSrc.getP2Set();
                        Set<SootMethod> matchSrcCallTargets = getCallTargets(matchSrcPTo, methodSig, receiverType, allTargets);
                        if (matchSrcCallTargets.size() <= 1) {
                            skipMatch = true;
                            for (SootMethod method : matchSrcCallTargets) {
                                callSiteToResolvedTargets.put(callSiteAndContext, method);
                            }
                        }
                    }
                    if (!skipMatch) {
                        final PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
                        AllocAndContextSet allocContexts = null;
                        boolean oldRefining = refiningCallSite;
                        int oldNesting = nesting;
                        try {
                            refiningCallSite = true;
                            allocContexts = findContextsForAllocs(new VarAndContext(loadBase, curContext), intersection);
                        } catch (CallSiteException e) {
                            callSiteToResolvedTargets.putAll(callSiteAndContext, allTargets);
                            continue;
                        } finally {
                            refiningCallSite = oldRefining;
                            nesting = oldNesting;
                        }
                        for (AllocAndContext allocAndContext : allocContexts) {
                            CallingContextSet matchSrcContexts;
                            if (fieldCheckHeuristic.validFromBothEnds(field)) {
                                matchSrcContexts = findUpContextsForVar(allocAndContext, new VarContextAndUp(storeBase, EMPTY_CALLSTACK, EMPTY_CALLSTACK));
                            } else {
                                matchSrcContexts = findVarContextsFromAlloc(allocAndContext, storeBase);
                            }
                            for (ImmutableStack<Integer> matchSrcContext : matchSrcContexts) {
                                VarAndContext newVarAndContext = new VarAndContext(matchSrc, matchSrcContext);
                                h.prop(newVarAndContext);
                            }
                        }
                    }
                }
            }
        }
    }
    if (DEBUG_VIRT) {
        debugPrint("call of " + invokedMethod + " on " + receiver + " " + origContext + " goes to " + callSiteToResolvedTargets.get(callSiteAndContext));
    }
    callGraphStack.pop();
    queriedCallSites.add(callSiteAndContext);
    return callSiteToResolvedTargets.get(callSiteAndContext);
}
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) HashSet(java.util.HashSet) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) NumberedString(soot.util.NumberedString) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) Stack(soot.jimple.spark.ondemand.genericutil.Stack) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) RefType(soot.RefType) AnySubType(soot.AnySubType) Type(soot.Type) ArrayType(soot.ArrayType) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) AllocNode(soot.jimple.spark.pag.AllocNode) SootMethod(soot.SootMethod)

Example 54 with AllocNode

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

the class PtInsNode method heap_sensitive_intersection.

/**
 * Query if this pointer and qv could point to the same object under any contexts
 */
@Override
public boolean heap_sensitive_intersection(IVarAbstraction qv) {
    int i, j;
    PtInsNode qn;
    SegmentNode p, q, pt[], qt[];
    qn = (PtInsNode) qv;
    for (Iterator<AllocNode> it = pt_objs.keySet().iterator(); it.hasNext(); ) {
        AllocNode an = it.next();
        if (an instanceof StringConstantNode)
            continue;
        qt = qn.find_points_to(an);
        if (qt == null)
            continue;
        pt = find_points_to(an);
        for (i = 0; i < PtInsIntervalManager.Divisions; ++i) {
            p = pt[i];
            while (p != null) {
                for (j = 0; j < PtInsIntervalManager.Divisions; ++j) {
                    q = qt[j];
                    while (q != null) {
                        if (quick_intersecting_test(p, q))
                            return true;
                        q = q.next;
                    }
                }
                p = p.next;
            }
        }
    }
    return false;
}
Also used : AllocNode(soot.jimple.spark.pag.AllocNode) StringConstantNode(soot.jimple.spark.pag.StringConstantNode) PlainConstraint(soot.jimple.spark.geom.dataRep.PlainConstraint) SegmentNode(soot.jimple.spark.geom.dataRep.SegmentNode)

Example 55 with AllocNode

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

the class PtInsNode method injectPts.

@Override
public void injectPts() {
    final GeomPointsTo geomPTA = (GeomPointsTo) Scene.v().getPointsToAnalysis();
    pt_objs = new HashMap<AllocNode, PtInsIntervalManager>();
    me.getP2Set().forall(new P2SetVisitor() {

        @Override
        public void visit(Node n) {
            if (geomPTA.isValidGeometricNode(n))
                pt_objs.put((AllocNode) n, (PtInsIntervalManager) stubManager);
        }
    });
    new_pts = null;
}
Also used : AllocNode(soot.jimple.spark.pag.AllocNode) GeomPointsTo(soot.jimple.spark.geom.geomPA.GeomPointsTo) SegmentNode(soot.jimple.spark.geom.dataRep.SegmentNode) StringConstantNode(soot.jimple.spark.pag.StringConstantNode) RectangleNode(soot.jimple.spark.geom.dataRep.RectangleNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Node(soot.jimple.spark.pag.Node) AllocNode(soot.jimple.spark.pag.AllocNode) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor)

Aggregations

AllocNode (soot.jimple.spark.pag.AllocNode)67 Node (soot.jimple.spark.pag.Node)37 VarNode (soot.jimple.spark.pag.VarNode)36 LocalVarNode (soot.jimple.spark.pag.LocalVarNode)28 PointsToSetInternal (soot.jimple.spark.sets.PointsToSetInternal)25 FieldRefNode (soot.jimple.spark.pag.FieldRefNode)22 P2SetVisitor (soot.jimple.spark.sets.P2SetVisitor)19 PlainConstraint (soot.jimple.spark.geom.dataRep.PlainConstraint)18 SegmentNode (soot.jimple.spark.geom.dataRep.SegmentNode)18 SootMethod (soot.SootMethod)17 ClassConstantNode (soot.jimple.spark.pag.ClassConstantNode)17 SparkField (soot.jimple.spark.pag.SparkField)16 RefType (soot.RefType)14 Type (soot.Type)13 AllocDotField (soot.jimple.spark.pag.AllocDotField)13 NewInstanceNode (soot.jimple.spark.pag.NewInstanceNode)11 HashSet (java.util.HashSet)10 GlobalVarNode (soot.jimple.spark.pag.GlobalVarNode)10 StringConstantNode (soot.jimple.spark.pag.StringConstantNode)10 SootClass (soot.SootClass)9