Search in sources :

Example 1 with PointsToAnalysis

use of soot.PointsToAnalysis in project soot by Sable.

the class SparkTransformer method internalTransform.

protected void internalTransform(String phaseName, Map<String, String> options) {
    SparkOptions opts = new SparkOptions(options);
    final String output_dir = SourceLocator.v().getOutputDir();
    // Build pointer assignment graph
    ContextInsensitiveBuilder b = new ContextInsensitiveBuilder();
    if (opts.pre_jimplify())
        b.preJimplify();
    if (opts.force_gc())
        doGC();
    Date startBuild = new Date();
    final PAG pag = b.setup(opts);
    b.build();
    Date endBuild = new Date();
    reportTime("Pointer Assignment Graph", startBuild, endBuild);
    if (opts.force_gc())
        doGC();
    // Build type masks
    Date startTM = new Date();
    pag.getTypeManager().makeTypeMask();
    Date endTM = new Date();
    reportTime("Type masks", startTM, endTM);
    if (opts.force_gc())
        doGC();
    if (opts.verbose()) {
        logger.debug("VarNodes: " + pag.getVarNodeNumberer().size());
        logger.debug("FieldRefNodes: " + pag.getFieldRefNodeNumberer().size());
        logger.debug("AllocNodes: " + pag.getAllocNodeNumberer().size());
    }
    // Simplify pag
    Date startSimplify = new Date();
    // these option interdependencies more cleanly would be nice...
    if ((opts.simplify_sccs() && !opts.on_fly_cg()) || opts.vta()) {
        new SCCCollapser(pag, opts.ignore_types_for_sccs()).collapse();
    }
    if (opts.simplify_offline() && !opts.on_fly_cg()) {
        new EBBCollapser(pag).collapse();
    }
    if (true || opts.simplify_sccs() || opts.vta() || opts.simplify_offline()) {
        pag.cleanUpMerges();
    }
    Date endSimplify = new Date();
    reportTime("Pointer Graph simplified", startSimplify, endSimplify);
    if (opts.force_gc())
        doGC();
    // Dump pag
    PAGDumper dumper = null;
    if (opts.dump_pag() || opts.dump_solution()) {
        dumper = new PAGDumper(pag, output_dir);
    }
    if (opts.dump_pag())
        dumper.dump();
    // Propagate
    Date startProp = new Date();
    propagatePAG(opts, pag);
    Date endProp = new Date();
    reportTime("Propagation", startProp, endProp);
    reportTime("Solution found", startSimplify, endProp);
    if (opts.force_gc())
        doGC();
    if (!opts.on_fly_cg() || opts.vta()) {
        CallGraphBuilder cgb = new CallGraphBuilder(pag);
        cgb.build();
    }
    if (opts.verbose()) {
        logger.debug("[Spark] Number of reachable methods: " + Scene.v().getReachableMethods().size());
    }
    if (opts.set_mass())
        findSetMass(pag);
    if (opts.dump_answer())
        new ReachingTypeDumper(pag, output_dir).dump();
    if (opts.dump_solution())
        dumper.dumpPointsToSets();
    if (opts.dump_html())
        new PAG2HTML(pag, output_dir).dump();
    Scene.v().setPointsToAnalysis(pag);
    if (opts.add_tags()) {
        addTags(pag);
    }
    if (opts.geom_pta()) {
        if (opts.simplify_offline() || opts.simplify_sccs()) {
            logger.debug("" + "Please turn off the simplify-offline and simplify-sccs to run the geometric points-to analysis");
            logger.debug("Now, we keep the SPARK result for querying.");
        } else {
            // We perform the geometric points-to analysis
            GeomPointsTo geomPTA = (GeomPointsTo) pag;
            geomPTA.parametrize(endProp.getTime() - startSimplify.getTime());
            geomPTA.solve();
        }
    }
    if (opts.cs_demand()) {
        // replace by demand-driven refinement-based context-sensitive analysis
        Date startOnDemand = new Date();
        PointsToAnalysis onDemandAnalysis = DemandCSPointsTo.makeWithBudget(opts.traversal(), opts.passes(), opts.lazy_pts());
        Date endOndemand = new Date();
        reportTime("Initialized on-demand refinement-based context-sensitive analysis", startOnDemand, endOndemand);
        Scene.v().setPointsToAnalysis(onDemandAnalysis);
    }
}
Also used : PAGDumper(soot.jimple.spark.pag.PAGDumper) GeomPointsTo(soot.jimple.spark.geom.geomPA.GeomPointsTo) EBBCollapser(soot.jimple.spark.solver.EBBCollapser) ContextInsensitiveBuilder(soot.jimple.spark.builder.ContextInsensitiveBuilder) ReachingTypeDumper(soot.jimple.ReachingTypeDumper) Date(java.util.Date) SparkOptions(soot.options.SparkOptions) CallGraphBuilder(soot.jimple.toolkits.callgraph.CallGraphBuilder) PAG(soot.jimple.spark.pag.PAG) PAG2HTML(soot.jimple.spark.pag.PAG2HTML) SCCCollapser(soot.jimple.spark.solver.SCCCollapser) PointsToAnalysis(soot.PointsToAnalysis)

Example 2 with PointsToAnalysis

use of soot.PointsToAnalysis in project soot by Sable.

the class IFDSPossibleTypes method createFlowFunctionsFactory.

public FlowFunctions<Unit, Pair<Value, Type>, SootMethod> createFlowFunctionsFactory() {
    return new FlowFunctions<Unit, Pair<Value, Type>, SootMethod>() {

        public FlowFunction<Pair<Value, Type>> getNormalFlowFunction(Unit src, Unit dest) {
            if (src instanceof DefinitionStmt) {
                DefinitionStmt defnStmt = (DefinitionStmt) src;
                if (defnStmt.containsInvokeExpr())
                    return Identity.v();
                final Value right = defnStmt.getRightOp();
                final Value left = defnStmt.getLeftOp();
                // won't track primitive-typed variables
                if (right.getType() instanceof PrimType)
                    return Identity.v();
                if (right instanceof Constant || right instanceof NewExpr) {
                    return new FlowFunction<Pair<Value, Type>>() {

                        public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                            if (source == zeroValue()) {
                                Set<Pair<Value, Type>> res = new LinkedHashSet<Pair<Value, Type>>();
                                res.add(new Pair<Value, Type>(left, right.getType()));
                                res.add(zeroValue());
                                return res;
                            } else if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
                                // strong update for local variables
                                return Collections.emptySet();
                            } else {
                                return Collections.singleton(source);
                            }
                        }
                    };
                } else if (right instanceof Ref || right instanceof Local) {
                    return new FlowFunction<Pair<Value, Type>>() {

                        public Set<Pair<Value, Type>> computeTargets(final Pair<Value, Type> source) {
                            Value value = source.getO1();
                            if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
                                // strong update for local variables
                                return Collections.emptySet();
                            } else if (maybeSameLocation(value, right)) {
                                return new LinkedHashSet<Pair<Value, Type>>() {

                                    {
                                        add(new Pair<Value, Type>(left, source.getO2()));
                                        add(source);
                                    }
                                };
                            } else {
                                return Collections.singleton(source);
                            }
                        }

                        private boolean maybeSameLocation(Value v1, Value v2) {
                            if (!(v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) && !(v1 instanceof ArrayRef && v2 instanceof ArrayRef)) {
                                return v1.equivTo(v2);
                            }
                            if (v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) {
                                InstanceFieldRef ifr1 = (InstanceFieldRef) v1;
                                InstanceFieldRef ifr2 = (InstanceFieldRef) v2;
                                if (!ifr1.getField().getName().equals(ifr2.getField().getName()))
                                    return false;
                                Local base1 = (Local) ifr1.getBase();
                                Local base2 = (Local) ifr2.getBase();
                                PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
                                PointsToSet pts1 = pta.reachingObjects(base1);
                                PointsToSet pts2 = pta.reachingObjects(base2);
                                return pts1.hasNonEmptyIntersection(pts2);
                            } else {
                                // v1 instanceof ArrayRef && v2 instanceof ArrayRef
                                ArrayRef ar1 = (ArrayRef) v1;
                                ArrayRef ar2 = (ArrayRef) v2;
                                Local base1 = (Local) ar1.getBase();
                                Local base2 = (Local) ar2.getBase();
                                PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
                                PointsToSet pts1 = pta.reachingObjects(base1);
                                PointsToSet pts2 = pta.reachingObjects(base2);
                                return pts1.hasNonEmptyIntersection(pts2);
                            }
                        }
                    };
                }
            }
            return Identity.v();
        }

        public FlowFunction<Pair<Value, Type>> getCallFlowFunction(final Unit src, final SootMethod dest) {
            Stmt stmt = (Stmt) src;
            InvokeExpr ie = stmt.getInvokeExpr();
            final List<Value> callArgs = ie.getArgs();
            final List<Local> paramLocals = new ArrayList<Local>();
            for (int i = 0; i < dest.getParameterCount(); i++) {
                paramLocals.add(dest.getActiveBody().getParameterLocal(i));
            }
            return new FlowFunction<Pair<Value, Type>>() {

                public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                    if (!dest.getName().equals("<clinit>") && !dest.getSubSignature().equals("void run()")) {
                        Value value = source.getO1();
                        int argIndex = callArgs.indexOf(value);
                        if (argIndex > -1) {
                            return Collections.singleton(new Pair<Value, Type>(paramLocals.get(argIndex), source.getO2()));
                        }
                    }
                    return Collections.emptySet();
                }
            };
        }

        public FlowFunction<Pair<Value, Type>> getReturnFlowFunction(Unit callSite, SootMethod callee, Unit exitStmt, Unit retSite) {
            if (exitStmt instanceof ReturnStmt) {
                ReturnStmt returnStmt = (ReturnStmt) exitStmt;
                Value op = returnStmt.getOp();
                if (op instanceof Local) {
                    if (callSite instanceof DefinitionStmt) {
                        DefinitionStmt defnStmt = (DefinitionStmt) callSite;
                        Value leftOp = defnStmt.getLeftOp();
                        if (leftOp instanceof Local) {
                            final Local tgtLocal = (Local) leftOp;
                            final Local retLocal = (Local) op;
                            return new FlowFunction<Pair<Value, Type>>() {

                                public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                                    if (source == retLocal)
                                        return Collections.singleton(new Pair<Value, Type>(tgtLocal, source.getO2()));
                                    return Collections.emptySet();
                                }
                            };
                        }
                    }
                }
            }
            return KillAll.v();
        }

        public FlowFunction<Pair<Value, Type>> getCallToReturnFlowFunction(Unit call, Unit returnSite) {
            return Identity.v();
        }
    };
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PointsToSet(soot.PointsToSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Constant(soot.jimple.Constant) ArrayList(java.util.ArrayList) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) ArrayRef(soot.jimple.ArrayRef) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) PrimType(soot.PrimType) PointsToAnalysis(soot.PointsToAnalysis) Pair(soot.toolkits.scalar.Pair) PointsToSet(soot.PointsToSet) FlowFunction(heros.FlowFunction) Local(soot.Local) UnknownType(soot.UnknownType) Type(soot.Type) PrimType(soot.PrimType) ArrayRef(soot.jimple.ArrayRef) Ref(soot.jimple.Ref) InstanceFieldRef(soot.jimple.InstanceFieldRef) Value(soot.Value) NewExpr(soot.jimple.NewExpr) SootMethod(soot.SootMethod) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt)

Aggregations

PointsToAnalysis (soot.PointsToAnalysis)2 FlowFunction (heros.FlowFunction)1 FlowFunctions (heros.FlowFunctions)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1 Local (soot.Local)1 PointsToSet (soot.PointsToSet)1 PrimType (soot.PrimType)1 SootMethod (soot.SootMethod)1 Type (soot.Type)1 Unit (soot.Unit)1 UnknownType (soot.UnknownType)1 Value (soot.Value)1 ArrayRef (soot.jimple.ArrayRef)1 Constant (soot.jimple.Constant)1 DefinitionStmt (soot.jimple.DefinitionStmt)1 InstanceFieldRef (soot.jimple.InstanceFieldRef)1 InvokeExpr (soot.jimple.InvokeExpr)1