Search in sources :

Example 1 with NewInstanceNode

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

the class PropAlias method handleVarNode.

/**
 * Propagates new points-to information of node src to all its successors.
 */
protected final boolean handleVarNode(final VarNode src) {
    boolean ret = false;
    if (src.getReplacement() != src)
        throw new RuntimeException("Got bad node " + src + " with rep " + src.getReplacement());
    final PointsToSetInternal newP2Set = src.getP2Set().getNewSet();
    if (newP2Set.isEmpty())
        return false;
    if (ofcg != null) {
        QueueReader<Node> addedEdges = pag.edgeReader();
        ofcg.updatedNode(src);
        ofcg.build();
        while (addedEdges.hasNext()) {
            Node addedSrc = (Node) addedEdges.next();
            Node addedTgt = (Node) addedEdges.next();
            ret = true;
            if (addedSrc instanceof VarNode) {
                VarNode edgeSrc = (VarNode) addedSrc;
                if (addedTgt instanceof VarNode) {
                    VarNode edgeTgt = (VarNode) addedTgt;
                    if (edgeTgt.makeP2Set().addAll(edgeSrc.getP2Set(), null))
                        addToWorklist(edgeTgt);
                } else if (addedTgt instanceof NewInstanceNode) {
                    NewInstanceNode edgeTgt = (NewInstanceNode) addedTgt.getReplacement();
                    if (edgeTgt.makeP2Set().addAll(edgeSrc.getP2Set(), null)) {
                        for (Node element : pag.assignInstanceLookup(edgeTgt)) {
                            addToWorklist((VarNode) element);
                        }
                    }
                }
            } else if (addedSrc instanceof AllocNode) {
                AllocNode edgeSrc = (AllocNode) addedSrc;
                VarNode edgeTgt = (VarNode) addedTgt;
                if (edgeTgt.makeP2Set().add(edgeSrc))
                    addToWorklist(edgeTgt);
            } else if (addedSrc instanceof NewInstanceNode && addedTgt instanceof VarNode) {
                final NewInstanceNode edgeSrc = (NewInstanceNode) addedSrc.getReplacement();
                final VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
                addedSrc.getP2Set().forall(new P2SetVisitor() {

                    @Override
                    public void visit(Node n) {
                        if (n instanceof ClassConstantNode) {
                            ClassConstantNode ccn = (ClassConstantNode) n;
                            Type ccnType = ccn.getClassConstant().toSootType();
                            // If the referenced class has not been loaded,
                            // we do this now
                            SootClass targetClass = ((RefType) ccnType).getSootClass();
                            if (targetClass.resolvingLevel() == SootClass.DANGLING)
                                Scene.v().forceResolve(targetClass.getName(), SootClass.SIGNATURES);
                            edgeTgt.makeP2Set().add(pag.makeAllocNode(edgeSrc.getValue(), ccnType, ccn.getMethod()));
                            addToWorklist(edgeTgt);
                        }
                    }
                });
            }
            FieldRefNode frn = null;
            if (addedSrc instanceof FieldRefNode)
                frn = (FieldRefNode) addedSrc;
            if (addedTgt instanceof FieldRefNode)
                frn = (FieldRefNode) addedTgt;
            if (frn != null) {
                VarNode base = frn.getBase();
                if (fieldToBase.put(frn.getField(), base)) {
                    aliasWorkList.add(base);
                }
            }
        }
    }
    Node[] simpleTargets = pag.simpleLookup(src);
    for (Node element : simpleTargets) {
        if (element.makeP2Set().addAll(newP2Set, null)) {
            addToWorklist((VarNode) element);
            ret = true;
        }
    }
    Node[] storeTargets = pag.storeLookup(src);
    for (Node element : storeTargets) {
        final FieldRefNode fr = (FieldRefNode) element;
        if (fr.makeP2Set().addAll(newP2Set, null)) {
            fieldRefWorkList.add(fr);
            ret = true;
        }
    }
    src.getP2Set().flushNew();
    return ret;
}
Also used : VarNode(soot.jimple.spark.pag.VarNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) SootClass(soot.SootClass) RefType(soot.RefType) Type(soot.Type) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) AllocNode(soot.jimple.spark.pag.AllocNode) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor)

Example 2 with NewInstanceNode

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

the class PropIter method propagate.

/**
 * Actually does the propagation.
 */
public final void propagate() {
    final OnFlyCallGraph ofcg = pag.getOnFlyCallGraph();
    new TopoSorter(pag, false).sort();
    for (Object object : pag.allocSources()) {
        handleAllocNode((AllocNode) object);
    }
    int iteration = 1;
    boolean change;
    do {
        change = false;
        TreeSet<VarNode> simpleSources = new TreeSet<VarNode>(pag.simpleSources());
        if (pag.getOpts().verbose()) {
            logger.debug("Iteration " + (iteration++));
        }
        for (VarNode object : simpleSources) {
            change = handleSimples(object) | change;
        }
        if (ofcg != null) {
            QueueReader<Node> addedEdges = pag.edgeReader();
            for (VarNode src : pag.getVarNodeNumberer()) {
                ofcg.updatedNode(src);
            }
            ofcg.build();
            while (addedEdges.hasNext()) {
                Node addedSrc = (Node) addedEdges.next();
                Node addedTgt = (Node) addedEdges.next();
                change = true;
                if (addedSrc instanceof VarNode) {
                    PointsToSetInternal p2set = ((VarNode) addedSrc).getP2Set();
                    if (p2set != null)
                        p2set.unFlushNew();
                } else if (addedSrc instanceof AllocNode) {
                    ((VarNode) addedTgt).makeP2Set().add(addedSrc);
                }
            }
            if (change) {
                new TopoSorter(pag, false).sort();
            }
        }
        for (FieldRefNode object : pag.loadSources()) {
            change = handleLoads(object) | change;
        }
        for (VarNode object : pag.storeSources()) {
            change = handleStores(object) | change;
        }
        for (NewInstanceNode object : pag.assignInstanceSources()) {
            change = handleNewInstances(object) | change;
        }
    } while (change);
}
Also used : VarNode(soot.jimple.spark.pag.VarNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) AllocNode(soot.jimple.spark.pag.AllocNode) TreeSet(java.util.TreeSet)

Example 3 with NewInstanceNode

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

the class PropWorklist method handleVarNode.

/**
 * Propagates new points-to information of node src to all its successors.
 */
protected final boolean handleVarNode(final VarNode src) {
    boolean ret = false;
    boolean flush = true;
    if (src.getReplacement() != src)
        throw new RuntimeException("Got bad node " + src + " with rep " + src.getReplacement());
    final PointsToSetInternal newP2Set = src.getP2Set().getNewSet();
    if (newP2Set.isEmpty())
        return false;
    if (ofcg != null) {
        QueueReader<Node> addedEdges = pag.edgeReader();
        ofcg.updatedNode(src);
        ofcg.build();
        while (addedEdges.hasNext()) {
            Node addedSrc = (Node) addedEdges.next();
            Node addedTgt = (Node) addedEdges.next();
            ret = true;
            if (addedSrc instanceof VarNode) {
                VarNode edgeSrc = (VarNode) addedSrc.getReplacement();
                if (addedTgt instanceof VarNode) {
                    VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
                    if (edgeTgt.makeP2Set().addAll(edgeSrc.getP2Set(), null)) {
                        varNodeWorkList.add(edgeTgt);
                        if (edgeTgt == src)
                            flush = false;
                    }
                } else if (addedTgt instanceof NewInstanceNode) {
                    NewInstanceNode edgeTgt = (NewInstanceNode) addedTgt.getReplacement();
                    if (edgeTgt.makeP2Set().addAll(edgeSrc.getP2Set(), null)) {
                        for (Node element : pag.assignInstanceLookup(edgeTgt)) {
                            varNodeWorkList.add((VarNode) element);
                            if (element == src)
                                flush = false;
                        }
                    }
                }
            } else if (addedSrc instanceof AllocNode) {
                VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
                if (edgeTgt.makeP2Set().add(addedSrc)) {
                    varNodeWorkList.add(edgeTgt);
                    if (edgeTgt == src)
                        flush = false;
                }
            } else if (addedSrc instanceof NewInstanceNode && addedTgt instanceof VarNode) {
                final NewInstanceNode edgeSrc = (NewInstanceNode) addedSrc.getReplacement();
                final VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
                addedSrc.getP2Set().forall(new P2SetVisitor() {

                    @Override
                    public void visit(Node n) {
                        if (n instanceof ClassConstantNode) {
                            ClassConstantNode ccn = (ClassConstantNode) n;
                            Type ccnType = ccn.getClassConstant().toSootType();
                            // If the referenced class has not been loaded,
                            // we do this now
                            SootClass targetClass = ((RefType) ccnType).getSootClass();
                            if (targetClass.resolvingLevel() == SootClass.DANGLING)
                                Scene.v().forceResolve(targetClass.getName(), SootClass.SIGNATURES);
                            // We can only create alloc nodes for types that
                            // we know
                            edgeTgt.makeP2Set().add(pag.makeAllocNode(edgeSrc.getValue(), ccnType, ccn.getMethod()));
                            varNodeWorkList.add(edgeTgt);
                        }
                    }
                });
                if (edgeTgt.makeP2Set().add(addedSrc)) {
                    if (edgeTgt == src)
                        flush = false;
                }
            }
        }
    }
    Node[] simpleTargets = pag.simpleLookup(src);
    for (Node element : simpleTargets) {
        if (element.makeP2Set().addAll(newP2Set, null)) {
            varNodeWorkList.add((VarNode) element);
            if (element == src)
                flush = false;
            ret = true;
        }
    }
    Node[] storeTargets = pag.storeLookup(src);
    for (Node element : storeTargets) {
        final FieldRefNode fr = (FieldRefNode) element;
        final SparkField f = fr.getField();
        ret = fr.getBase().getP2Set().forall(new P2SetVisitor() {

            public final void visit(Node n) {
                AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, f);
                if (nDotF.makeP2Set().addAll(newP2Set, null)) {
                    returnValue = true;
                }
            }
        }) | ret;
    }
    final HashSet<Node[]> storesToPropagate = new HashSet<Node[]>();
    final HashSet<Node[]> loadsToPropagate = new HashSet<Node[]>();
    for (final FieldRefNode fr : src.getAllFieldRefs()) {
        final SparkField field = fr.getField();
        final Node[] storeSources = pag.storeInvLookup(fr);
        if (storeSources.length > 0) {
            newP2Set.forall(new P2SetVisitor() {

                public final void visit(Node n) {
                    AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, field);
                    for (Node element : storeSources) {
                        Node[] pair = { element, nDotF.getReplacement() };
                        storesToPropagate.add(pair);
                    }
                }
            });
        }
        final Node[] loadTargets = pag.loadLookup(fr);
        if (loadTargets.length > 0) {
            newP2Set.forall(new P2SetVisitor() {

                public final void visit(Node n) {
                    AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, field);
                    if (nDotF != null) {
                        for (Node element : loadTargets) {
                            Node[] pair = { nDotF.getReplacement(), element };
                            loadsToPropagate.add(pair);
                        }
                    }
                }
            });
        }
    }
    if (flush)
        src.getP2Set().flushNew();
    for (Node[] p : storesToPropagate) {
        VarNode storeSource = (VarNode) p[0];
        AllocDotField nDotF = (AllocDotField) p[1];
        if (nDotF.makeP2Set().addAll(storeSource.getP2Set(), null)) {
            ret = true;
        }
    }
    for (Node[] p : loadsToPropagate) {
        AllocDotField nDotF = (AllocDotField) p[0];
        VarNode loadTarget = (VarNode) p[1];
        if (loadTarget.makeP2Set().addAll(nDotF.getP2Set(), null)) {
            varNodeWorkList.add(loadTarget);
            ret = true;
        }
    }
    return ret;
}
Also used : VarNode(soot.jimple.spark.pag.VarNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) AllocDotField(soot.jimple.spark.pag.AllocDotField) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) SparkField(soot.jimple.spark.pag.SparkField) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) SootClass(soot.SootClass) RefType(soot.RefType) Type(soot.Type) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) AllocNode(soot.jimple.spark.pag.AllocNode) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor) HashSet(java.util.HashSet)

Example 4 with NewInstanceNode

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

the class PropIter method handleNewInstances.

protected final boolean handleNewInstances(final NewInstanceNode src) {
    boolean ret = false;
    final Node[] newInstances = pag.assignInstanceLookup(src);
    for (final Node instance : newInstances) {
        ret = src.getP2Set().forall(new P2SetVisitor() {

            @Override
            public void visit(Node n) {
                if (n instanceof ClassConstantNode) {
                    ClassConstantNode ccn = (ClassConstantNode) n;
                    Type ccnType = ccn.getClassConstant().toSootType();
                    // If the referenced class has not been loaded, we do
                    // this now
                    SootClass targetClass = ((RefType) ccnType).getSootClass();
                    if (targetClass.resolvingLevel() == SootClass.DANGLING)
                        Scene.v().forceResolve(targetClass.getName(), SootClass.SIGNATURES);
                    instance.makeP2Set().add(pag.makeAllocNode(src.getValue(), ccnType, ccn.getMethod()));
                }
            }
        });
    }
    return ret;
}
Also used : RefType(soot.RefType) RefType(soot.RefType) Type(soot.Type) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) ClassConstantNode(soot.jimple.spark.pag.ClassConstantNode) SootClass(soot.SootClass) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor)

Example 5 with NewInstanceNode

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

the class MethodNodeFactory method caseVirtualInvokeExpr.

@Override
public void caseVirtualInvokeExpr(VirtualInvokeExpr v) {
    if (isReflectionNewInstance(v)) {
        NewInstanceNode newInstanceNode = pag.makeNewInstanceNode(v, Scene.v().getObjectType(), method);
        v.getBase().apply(this);
        Node srcNode = getNode();
        mpag.addInternalEdge(srcNode, newInstanceNode);
        setResult(newInstanceNode);
    } else
        throw new RuntimeException("Unhandled case of VirtualInvokeExpr");
}
Also used : NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode)

Aggregations

AllocNode (soot.jimple.spark.pag.AllocNode)5 NewInstanceNode (soot.jimple.spark.pag.NewInstanceNode)5 Node (soot.jimple.spark.pag.Node)5 VarNode (soot.jimple.spark.pag.VarNode)5 ClassConstantNode (soot.jimple.spark.pag.ClassConstantNode)4 FieldRefNode (soot.jimple.spark.pag.FieldRefNode)4 RefType (soot.RefType)3 SootClass (soot.SootClass)3 Type (soot.Type)3 P2SetVisitor (soot.jimple.spark.sets.P2SetVisitor)3 PointsToSetInternal (soot.jimple.spark.sets.PointsToSetInternal)3 HashSet (java.util.HashSet)1 TreeSet (java.util.TreeSet)1 AllocDotField (soot.jimple.spark.pag.AllocDotField)1 SparkField (soot.jimple.spark.pag.SparkField)1