Search in sources :

Example 1 with GlobalVarNode

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

the class OfflineProcessor method setAllUserCodeVariablesUseful.

/**
 * All the pointers that we need their points-to information are marked.
 * @param virtualBaseSet
 */
protected void setAllUserCodeVariablesUseful() {
    for (int i = 0; i < n_var; ++i) {
        IVarAbstraction pn = int2var.get(i);
        if (pn != pn.getRepresentative())
            continue;
        Node node = pn.getWrappedNode();
        int sm_id = geomPTA.getMethodIDFromPtr(pn);
        if (!geomPTA.isReachableMethod(sm_id))
            continue;
        if (node instanceof VarNode) {
            // flag == true if node is defined in the Java library
            boolean defined_in_lib = false;
            if (node instanceof LocalVarNode) {
                defined_in_lib = ((LocalVarNode) node).getMethod().isJavaLibraryMethod();
            } else if (node instanceof GlobalVarNode) {
                SootClass sc = ((GlobalVarNode) node).getDeclaringClass();
                if (sc != null)
                    defined_in_lib = sc.isJavaLibraryClass();
            }
            if (!defined_in_lib && !geomPTA.isExceptionPointer(node)) {
                // Defined in the user code
                pn.willUpdate = true;
            }
        }
    }
}
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) 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) SootClass(soot.SootClass) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) PlainConstraint(soot.jimple.spark.geom.dataRep.PlainConstraint)

Example 2 with GlobalVarNode

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

the class DemandCSPointsTo method findUpContextsForVar.

protected CallingContextSet findUpContextsForVar(AllocAndContext allocAndContext, VarContextAndUp varContextAndUp) {
    final AllocNode alloc = allocAndContext.alloc;
    final ImmutableStack<Integer> allocContext = allocAndContext.context;
    CallingContextSet tmpSet = checkUpContextCache(varContextAndUp, allocAndContext);
    if (tmpSet != null) {
        return tmpSet;
    }
    final CallingContextSet ret = new CallingContextSet();
    upContextCache.get(varContextAndUp).put(allocAndContext, ret);
    nesting++;
    if (DEBUG) {
        debugPrint("finding up context for " + varContextAndUp + " to " + alloc + " " + allocContext);
    }
    try {
        final Set<VarAndContext> marked = new HashSet<VarAndContext>();
        final Stack<VarAndContext> worklist = new Stack<VarAndContext>();
        final Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
        p.prop(varContextAndUp);
        class UpContextEdgeHandler extends IncomingEdgeHandler {

            @Override
            public void handleAlloc(AllocNode allocNode, VarAndContext origVarAndContext) {
                VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
                if (allocNode == alloc) {
                    if (allocContext.topMatches(contextAndUp.context)) {
                        ImmutableStack<Integer> reverse = contextAndUp.upContext.reverse();
                        ImmutableStack<Integer> toAdd = allocContext.popAll(contextAndUp.context).pushAll(reverse);
                        if (DEBUG) {
                            debugPrint("found up context " + toAdd);
                        }
                        ret.add(toAdd);
                    } else if (contextAndUp.context.topMatches(allocContext)) {
                        ImmutableStack<Integer> toAdd = contextAndUp.upContext.reverse();
                        if (DEBUG) {
                            debugPrint("found up context " + toAdd);
                        }
                        ret.add(toAdd);
                    }
                }
            }

            @Override
            public void handleMatchSrc(VarNode matchSrc, PointsToSetInternal intersection, VarNode loadBase, VarNode storeBase, VarAndContext origVarAndContext, SparkField field, boolean refine) {
                VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
                if (DEBUG) {
                    debugPrint("CHECKING " + alloc);
                }
                PointsToSetInternal tmp = new HybridPointsToSet(alloc.getType(), pag);
                tmp.add(alloc);
                AllocAndContextSet allocContexts = findContextsForAllocs(new VarAndContext(matchSrc, EMPTY_CALLSTACK), tmp);
                // Set allocContexts = Collections.singleton(new Object());
                if (!refine) {
                    if (!allocContexts.isEmpty()) {
                        ret.add(contextAndUp.upContext.reverse());
                    }
                } else {
                    if (!allocContexts.isEmpty()) {
                        for (AllocAndContext t : allocContexts) {
                            ImmutableStack<Integer> discoveredAllocContext = t.context;
                            if (!allocContext.topMatches(discoveredAllocContext)) {
                                continue;
                            }
                            ImmutableStack<Integer> trueAllocContext = allocContext.popAll(discoveredAllocContext);
                            AllocAndContextSet allocAndContexts = findContextsForAllocs(new VarAndContext(storeBase, trueAllocContext), intersection);
                            for (AllocAndContext allocAndContext : allocAndContexts) {
                                // CallingContextSet upContexts;
                                if (fieldCheckHeuristic.validFromBothEnds(field)) {
                                    ret.addAll(findUpContextsForVar(allocAndContext, new VarContextAndUp(loadBase, contextAndUp.context, contextAndUp.upContext)));
                                } else {
                                    CallingContextSet tmpContexts = findVarContextsFromAlloc(allocAndContext, loadBase);
                                    // upContexts = new CallingContextSet();
                                    for (ImmutableStack<Integer> tmpContext : tmpContexts) {
                                        if (tmpContext.topMatches(contextAndUp.context)) {
                                            ImmutableStack<Integer> reverse = contextAndUp.upContext.reverse();
                                            ImmutableStack<Integer> toAdd = tmpContext.popAll(contextAndUp.context).pushAll(reverse);
                                            ret.add(toAdd);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            @Override
            Object getResult() {
                return ret;
            }

            @Override
            void handleAssignSrc(VarAndContext newVarAndContext, VarAndContext origVarAndContext, AssignEdge assignEdge) {
                VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
                ImmutableStack<Integer> upContext = contextAndUp.upContext;
                ImmutableStack<Integer> newUpContext = upContext;
                if (assignEdge.isParamEdge() && contextAndUp.context.isEmpty()) {
                    if (upContext.size() < ImmutableStack.getMaxSize()) {
                        newUpContext = pushWithRecursionCheck(upContext, assignEdge);
                    }
                    ;
                }
                p.prop(new VarContextAndUp(newVarAndContext.var, newVarAndContext.context, newUpContext));
            }

            @Override
            boolean shouldHandleSrc(VarNode src) {
                if (src instanceof GlobalVarNode) {
                    // // for now, just give up
                    throw new TerminateEarlyException();
                }
                return src.getP2Set().contains(alloc);
            }
        }
        ;
        UpContextEdgeHandler edgeHandler = new UpContextEdgeHandler();
        processIncomingEdges(edgeHandler, worklist);
        nesting--;
        // }
        return ret;
    } catch (CallSiteException e) {
        upContextCache.remove(varContextAndUp);
        throw e;
    }
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) SparkField(soot.jimple.spark.pag.SparkField) AssignEdge(soot.jimple.spark.ondemand.pautil.AssignEdge) Propagator(soot.jimple.spark.ondemand.genericutil.Propagator) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) 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) HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet) Stack(soot.jimple.spark.ondemand.genericutil.Stack) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) AllocNode(soot.jimple.spark.pag.AllocNode)

Example 3 with GlobalVarNode

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

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

the class SootUtil method buildStoreMap.

public static FieldAccessMap buildStoreMap(PAG pag) {
    FieldAccessMap ret = new FieldAccessMap();
    Iterator frNodeIter = pag.storeInvSourcesIterator();
    while (frNodeIter.hasNext()) {
        FieldRefNode frNode = (FieldRefNode) frNodeIter.next();
        SparkField field = frNode.getField();
        Node[] targets = pag.storeInvLookup(frNode);
        for (int i = 0; i < targets.length; i++) {
            VarNode target = (VarNode) targets[i];
            if (target instanceof GlobalVarNode)
                continue;
            ret.put(field, new Pair<FieldRefNode, LocalVarNode>(frNode, (LocalVarNode) target));
        }
    }
    return ret;
}
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) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) 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) LocalVarNode(soot.jimple.spark.pag.LocalVarNode)

Example 5 with GlobalVarNode

use of soot.jimple.spark.pag.GlobalVarNode 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)

Aggregations

AllocNode (soot.jimple.spark.pag.AllocNode)7 GlobalVarNode (soot.jimple.spark.pag.GlobalVarNode)7 LocalVarNode (soot.jimple.spark.pag.LocalVarNode)7 VarNode (soot.jimple.spark.pag.VarNode)7 Node (soot.jimple.spark.pag.Node)6 SparkField (soot.jimple.spark.pag.SparkField)6 AssignEdge (soot.jimple.spark.ondemand.pautil.AssignEdge)5 FieldRefNode (soot.jimple.spark.pag.FieldRefNode)5 PointsToSetInternal (soot.jimple.spark.sets.PointsToSetInternal)5 HashSet (java.util.HashSet)4 SootMethod (soot.SootMethod)4 ImmutableStack (soot.jimple.spark.ondemand.genericutil.ImmutableStack)4 Stack (soot.jimple.spark.ondemand.genericutil.Stack)4 Propagator (soot.jimple.spark.ondemand.genericutil.Propagator)3 Iterator (java.util.Iterator)1 AnySubType (soot.AnySubType)1 ArrayType (soot.ArrayType)1 RefType (soot.RefType)1 SootClass (soot.SootClass)1 Type (soot.Type)1