Search in sources :

Example 41 with VarNode

use of soot.jimple.spark.pag.VarNode 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 42 with VarNode

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

the class DemandCSPointsTo method computeReachingObjects.

/**
 * Computes the possibly refined set of reaching objects for l.
 */
protected PointsToSet computeReachingObjects(Local l) {
    VarNode v = pag.findLocalVarNode(l);
    if (v == null) {
        // no reaching objects
        return EmptyPointsToSet.v();
    }
    PointsToSet contextSensitiveResult = computeRefinedReachingObjects(v);
    if (contextSensitiveResult == null) {
        // had to abort; return Spark's points-to set in a wrapper
        return new WrappedPointsToSet(v.getP2Set());
    } else {
        return contextSensitiveResult;
    }
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) EmptyPointsToSet(soot.jimple.spark.sets.EmptyPointsToSet) EqualsSupportingPointsToSet(soot.jimple.spark.sets.EqualsSupportingPointsToSet) HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet) PointsToSet(soot.PointsToSet)

Example 43 with VarNode

use of soot.jimple.spark.pag.VarNode 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 44 with VarNode

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

the class SparkLibraryHelper method caseRefType.

/**
 * A new local will be created and connected to
 * {@link SparkLibraryHelper#node} of type {@link RefType}. For this new
 * local an allocation edge to {@link AnySubType} of its declared type will
 * be added.
 */
@Override
public void caseRefType(RefType t) {
    // var tmp;
    VarNode local = pag.makeLocalVarNode(new Object(), t, method);
    // new T();
    AllocNode alloc = pag.makeAllocNode(new Object(), AnySubType.v(t), method);
    // tmp = new T();
    pag.addAllocEdge(alloc, local);
    // x = tmp;
    pag.addEdge(local, node);
}
Also used : LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode)

Example 45 with VarNode

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

the class SootUtil method storesOnField.

public static FieldToEdgesMap storesOnField(PAG pag) {
    FieldToEdgesMap storesOnField = new FieldToEdgesMap();
    Iterator frNodeIter = pag.storeInvSourcesIterator();
    while (frNodeIter.hasNext()) {
        FieldRefNode frNode = (FieldRefNode) frNodeIter.next();
        VarNode source = frNode.getBase();
        SparkField field = frNode.getField();
        Node[] targets = pag.storeInvLookup(frNode);
        for (int i = 0; i < targets.length; i++) {
            VarNode target = (VarNode) targets[i];
            storesOnField.put(field, new Pair<VarNode, VarNode>(target, source));
        }
    }
    return storesOnField;
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) SparkField(soot.jimple.spark.pag.SparkField) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) StringConstantNode(soot.jimple.spark.pag.StringConstantNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) Iterator(java.util.Iterator)

Aggregations

VarNode (soot.jimple.spark.pag.VarNode)47 AllocNode (soot.jimple.spark.pag.AllocNode)37 Node (soot.jimple.spark.pag.Node)29 FieldRefNode (soot.jimple.spark.pag.FieldRefNode)24 LocalVarNode (soot.jimple.spark.pag.LocalVarNode)23 PointsToSetInternal (soot.jimple.spark.sets.PointsToSetInternal)22 GlobalVarNode (soot.jimple.spark.pag.GlobalVarNode)17 SparkField (soot.jimple.spark.pag.SparkField)15 HashSet (java.util.HashSet)11 NewInstanceNode (soot.jimple.spark.pag.NewInstanceNode)11 SootMethod (soot.SootMethod)10 ClassConstantNode (soot.jimple.spark.pag.ClassConstantNode)10 RefType (soot.RefType)8 Type (soot.Type)8 P2SetVisitor (soot.jimple.spark.sets.P2SetVisitor)8 AssignEdge (soot.jimple.spark.ondemand.pautil.AssignEdge)7 Iterator (java.util.Iterator)6 ImmutableStack (soot.jimple.spark.ondemand.genericutil.ImmutableStack)6 Stack (soot.jimple.spark.ondemand.genericutil.Stack)6 AllocDotField (soot.jimple.spark.pag.AllocDotField)6