Search in sources :

Example 86 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class AbstractInterproceduralAnalysis method doAnalysis.

/**
 * Carry out the analysis.
 *
 * Call this from your InterproceduralAnalysis constructor, just after
 * super(cg). Then , you will be able to call drawAsDot, for instance.
 *
 * @param verbose
 */
protected void doAnalysis(boolean verbose) {
    // queue class
    class IntComparator implements Comparator<SootMethod> {

        @Override
        public int compare(SootMethod o1, SootMethod o2) {
            return order.get(o1) - order.get(o2);
        }
    }
    SortedSet<SootMethod> queue = new TreeSet<SootMethod>(new IntComparator());
    // init
    for (SootMethod o : order.keySet()) {
        data.put(o, newInitialSummary());
        queue.add(o);
    }
    // only for debug pretty-printing
    Map<SootMethod, Integer> nb = new HashMap<SootMethod, Integer>();
    // fixpoint iterations
    while (!queue.isEmpty()) {
        SootMethod m = queue.first();
        queue.remove(m);
        S newSummary = newInitialSummary();
        S oldSummary = data.get(m);
        if (nb.containsKey(m)) {
            nb.put(m, nb.get(m) + 1);
        } else {
            nb.put(m, 1);
        }
        if (verbose) {
            logger.debug(" |- processing " + m.toString() + " (" + nb.get(m) + "-st time)");
        }
        analyseMethod(m, newSummary);
        if (!oldSummary.equals(newSummary)) {
            // summary for m changed!
            data.put(m, newSummary);
            queue.addAll(dg.getPredsOf(m));
        }
    }
    // fixpoint verification
    if (doCheck) {
        for (SootMethod m : order.keySet()) {
            S newSummary = newInitialSummary();
            S oldSummary = data.get(m);
            analyseMethod(m, newSummary);
            if (!oldSummary.equals(newSummary)) {
                logger.debug("inter-procedural fixpoint not reached for method " + m.toString());
                DotGraph gm = new DotGraph("false_fixpoint");
                DotGraph gmm = new DotGraph("next_iterate");
                gm.setGraphLabel("false fixpoint: " + m.toString());
                gmm.setGraphLabel("fixpoint next iterate: " + m.toString());
                fillDotGraph("", oldSummary, gm);
                fillDotGraph("", newSummary, gmm);
                gm.plot(m.toString() + "_false_fixpoint.dot");
                gmm.plot(m.toString() + "_false_fixpoint_next.dot");
                throw new Error("AbstractInterproceduralAnalysis sanity check failed!!!");
            }
        }
    }
}
Also used : DotGraph(soot.util.dot.DotGraph) SootMethod(soot.SootMethod)

Example 87 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class Main method main.

/**
 * @param args
 */
public static void main(String[] args) {
    PackManager.v().getPack("wjtp").add(new Transform("wjtp.ifds", new SceneTransformer() {

        protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes") Map options) {
            IFDSTabulationProblem<Unit, ?, SootMethod, InterproceduralCFG<Unit, SootMethod>> problem = new IFDSPossibleTypes(new JimpleBasedInterproceduralCFG());
            @SuppressWarnings({ "rawtypes", "unchecked" }) JimpleIFDSSolver<?, InterproceduralCFG<Unit, SootMethod>> solver = new JimpleIFDSSolver(problem);
            solver.solve();
        }
    }));
    soot.Main.main(args);
}
Also used : JimpleBasedInterproceduralCFG(soot.jimple.toolkits.ide.icfg.JimpleBasedInterproceduralCFG) InterproceduralCFG(heros.InterproceduralCFG) JimpleBasedInterproceduralCFG(soot.jimple.toolkits.ide.icfg.JimpleBasedInterproceduralCFG) Unit(soot.Unit) SceneTransformer(soot.SceneTransformer) IFDSPossibleTypes(soot.jimple.toolkits.ide.exampleproblems.IFDSPossibleTypes) SootMethod(soot.SootMethod) Transform(soot.Transform) Map(java.util.Map)

Example 88 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class IFDSLiveVariables method createFlowFunctionsFactory.

@Override
public FlowFunctions<Unit, Value, SootMethod> createFlowFunctionsFactory() {
    return new FlowFunctions<Unit, Value, SootMethod>() {

        @Override
        public FlowFunction<Value> getNormalFlowFunction(Unit curr, Unit succ) {
            if (curr.getUseAndDefBoxes().isEmpty())
                return Identity.v();
            final Stmt s = (Stmt) curr;
            return new FlowFunction<Value>() {

                public Set<Value> computeTargets(Value source) {
                    // kill defs
                    List<ValueBox> defs = s.getDefBoxes();
                    if (!defs.isEmpty()) {
                        if (defs.get(0).getValue().equivTo(source)) {
                            return Collections.emptySet();
                        }
                    }
                    // gen uses out of zero value
                    if (source.equals(zeroValue())) {
                        Set<Value> liveVars = new HashSet<Value>();
                        for (ValueBox useBox : s.getUseBoxes()) {
                            Value value = useBox.getValue();
                            liveVars.add(value);
                        }
                        return liveVars;
                    }
                    // else just propagate
                    return Collections.singleton(source);
                }
            };
        }

        @Override
        public FlowFunction<Value> getCallFlowFunction(Unit callStmt, final SootMethod destinationMethod) {
            final Stmt s = (Stmt) callStmt;
            return new FlowFunction<Value>() {

                public Set<Value> computeTargets(Value source) {
                    if (!s.getDefBoxes().isEmpty()) {
                        Value callerSideReturnValue = s.getDefBoxes().get(0).getValue();
                        if (callerSideReturnValue.equivTo(source)) {
                            Set<Value> calleeSideReturnValues = new HashSet<Value>();
                            for (Unit calleeUnit : interproceduralCFG().getStartPointsOf(destinationMethod)) {
                                if (calleeUnit instanceof ReturnStmt) {
                                    ReturnStmt returnStmt = (ReturnStmt) calleeUnit;
                                    calleeSideReturnValues.add(returnStmt.getOp());
                                }
                            }
                            return calleeSideReturnValues;
                        }
                    }
                    // no return value, nothing to propagate
                    return Collections.emptySet();
                }
            };
        }

        @Override
        public FlowFunction<Value> getReturnFlowFunction(final Unit callSite, SootMethod calleeMethod, final Unit exitStmt, Unit returnSite) {
            Stmt s = (Stmt) callSite;
            InvokeExpr ie = s.getInvokeExpr();
            final List<Value> callArgs = ie.getArgs();
            final List<Local> paramLocals = new ArrayList<Local>();
            for (int i = 0; i < calleeMethod.getParameterCount(); i++) {
                paramLocals.add(calleeMethod.getActiveBody().getParameterLocal(i));
            }
            return new FlowFunction<Value>() {

                public Set<Value> computeTargets(Value source) {
                    Set<Value> liveParamsAtCallee = new HashSet<Value>();
                    for (int i = 0; i < paramLocals.size(); i++) {
                        if (paramLocals.get(i).equivTo(source)) {
                            liveParamsAtCallee.add(callArgs.get(i));
                        }
                    }
                    return liveParamsAtCallee;
                }
            };
        }

        @Override
        public FlowFunction<Value> getCallToReturnFlowFunction(Unit callSite, Unit returnSite) {
            if (callSite.getUseAndDefBoxes().isEmpty())
                return Identity.v();
            final Stmt s = (Stmt) callSite;
            return new FlowFunction<Value>() {

                public Set<Value> computeTargets(Value source) {
                    // kill defs
                    List<ValueBox> defs = s.getDefBoxes();
                    if (!defs.isEmpty()) {
                        if (defs.get(0).getValue().equivTo(source)) {
                            return Collections.emptySet();
                        }
                    }
                    // gen uses out of zero value
                    if (source.equals(zeroValue())) {
                        Set<Value> liveVars = new HashSet<Value>();
                        // only "gen" those values that are not parameter values;
                        // the latter are taken care of by the return-flow function
                        List<Value> args = s.getInvokeExpr().getArgs();
                        for (ValueBox useBox : s.getUseBoxes()) {
                            Value value = useBox.getValue();
                            if (!args.contains(value)) {
                                liveVars.add(value);
                            }
                        }
                        return liveVars;
                    }
                    // else just propagate
                    return Collections.singleton(source);
                }
            };
        }
    };
}
Also used : FlowFunction(heros.FlowFunction) ArrayList(java.util.ArrayList) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) InvokeExpr(soot.jimple.InvokeExpr) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) ReturnStmt(soot.jimple.ReturnStmt) HashSet(java.util.HashSet)

Example 89 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class IFDSUninitializedVariables method createFlowFunctionsFactory.

@Override
public FlowFunctions<Unit, Local, SootMethod> createFlowFunctionsFactory() {
    return new FlowFunctions<Unit, Local, SootMethod>() {

        @Override
        public FlowFunction<Local> getNormalFlowFunction(Unit curr, Unit succ) {
            final SootMethod m = interproceduralCFG().getMethodOf(curr);
            if (Scene.v().getEntryPoints().contains(m) && interproceduralCFG().isStartPoint(curr)) {
                return new FlowFunction<Local>() {

                    @Override
                    public Set<Local> computeTargets(Local source) {
                        if (source == zeroValue()) {
                            Set<Local> res = new LinkedHashSet<Local>();
                            res.addAll(m.getActiveBody().getLocals());
                            for (int i = 0; i < m.getParameterCount(); i++) res.remove(m.getActiveBody().getParameterLocal(i));
                            return res;
                        }
                        return Collections.emptySet();
                    }
                };
            }
            if (curr instanceof DefinitionStmt) {
                final DefinitionStmt definition = (DefinitionStmt) curr;
                final Value leftOp = definition.getLeftOp();
                if (leftOp instanceof Local) {
                    final Local leftOpLocal = (Local) leftOp;
                    return new FlowFunction<Local>() {

                        @Override
                        public Set<Local> computeTargets(final Local source) {
                            List<ValueBox> useBoxes = definition.getUseBoxes();
                            for (ValueBox valueBox : useBoxes) {
                                if (valueBox.getValue().equivTo(source)) {
                                    LinkedHashSet<Local> res = new LinkedHashSet<Local>();
                                    res.add(source);
                                    res.add(leftOpLocal);
                                    return res;
                                }
                            }
                            if (leftOp.equivTo(source))
                                return Collections.emptySet();
                            return Collections.singleton(source);
                        }
                    };
                }
            }
            return Identity.v();
        }

        @Override
        public FlowFunction<Local> getCallFlowFunction(Unit callStmt, final SootMethod destinationMethod) {
            Stmt stmt = (Stmt) callStmt;
            InvokeExpr invokeExpr = stmt.getInvokeExpr();
            final List<Value> args = invokeExpr.getArgs();
            final List<Local> localArguments = new ArrayList<Local>();
            for (Value value : args) if (value instanceof Local)
                localArguments.add((Local) value);
            return new FlowFunction<Local>() {

                @Override
                public Set<Local> computeTargets(final Local source) {
                    // Do not map parameters for <clinit> edges
                    if (destinationMethod.getName().equals("<clinit>") || destinationMethod.getSubSignature().equals("void run()"))
                        return Collections.emptySet();
                    for (Local localArgument : localArguments) {
                        if (source.equivTo(localArgument)) {
                            return Collections.<Local>singleton(destinationMethod.getActiveBody().getParameterLocal(args.indexOf(localArgument)));
                        }
                    }
                    if (source == zeroValue()) {
                        // gen all locals that are not parameter locals
                        Collection<Local> locals = destinationMethod.getActiveBody().getLocals();
                        LinkedHashSet<Local> uninitializedLocals = new LinkedHashSet<Local>(locals);
                        for (int i = 0; i < destinationMethod.getParameterCount(); i++) {
                            uninitializedLocals.remove(destinationMethod.getActiveBody().getParameterLocal(i));
                        }
                        return uninitializedLocals;
                    }
                    return Collections.emptySet();
                }
            };
        }

        @Override
        public FlowFunction<Local> getReturnFlowFunction(final Unit callSite, SootMethod calleeMethod, final Unit exitStmt, Unit returnSite) {
            if (callSite instanceof DefinitionStmt) {
                final DefinitionStmt definition = (DefinitionStmt) callSite;
                if (definition.getLeftOp() instanceof Local) {
                    final Local leftOpLocal = (Local) definition.getLeftOp();
                    if (exitStmt instanceof ReturnStmt) {
                        final ReturnStmt returnStmt = (ReturnStmt) exitStmt;
                        return new FlowFunction<Local>() {

                            @Override
                            public Set<Local> computeTargets(Local source) {
                                if (returnStmt.getOp().equivTo(source))
                                    return Collections.singleton(leftOpLocal);
                                return Collections.emptySet();
                            }
                        };
                    } else if (exitStmt instanceof ThrowStmt) {
                        // if we throw an exception, LHS of call is undefined
                        return new FlowFunction<Local>() {

                            @Override
                            public Set<Local> computeTargets(final Local source) {
                                if (source == zeroValue())
                                    return Collections.singleton(leftOpLocal);
                                else
                                    return Collections.emptySet();
                            }
                        };
                    }
                }
            }
            return KillAll.v();
        }

        @Override
        public FlowFunction<Local> getCallToReturnFlowFunction(Unit callSite, Unit returnSite) {
            if (callSite instanceof DefinitionStmt) {
                DefinitionStmt definition = (DefinitionStmt) callSite;
                if (definition.getLeftOp() instanceof Local) {
                    final Local leftOpLocal = (Local) definition.getLeftOp();
                    return new Kill<Local>(leftOpLocal);
                }
            }
            return Identity.v();
        }
    };
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ThrowStmt(soot.jimple.ThrowStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) InvokeExpr(soot.jimple.InvokeExpr) Kill(heros.flowfunc.Kill) FlowFunction(heros.FlowFunction) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt)

Example 90 with SootMethod

use of soot.SootMethod in project soot by Sable.

the class DumpNumAppReachableMethods method internalTransform.

protected void internalTransform(String phaseName, Map options) {
    int numAppMethods = 0;
    for (Iterator mIt = Scene.v().getReachableMethods().listener(); mIt.hasNext(); ) {
        final SootMethod m = (SootMethod) mIt.next();
        if (isAppMethod(m)) {
            // System.out.println(m);
            // assert OnFlyCallGraphBuilder.processedMethods.contains(m) : m
            // + " not processed!!";
            numAppMethods++;
        }
    }
    logger.debug("Number of reachable methods in application: " + numAppMethods);
}
Also used : Iterator(java.util.Iterator) SootMethod(soot.SootMethod)

Aggregations

SootMethod (soot.SootMethod)237 SootClass (soot.SootClass)95 RefType (soot.RefType)56 ArrayList (java.util.ArrayList)49 Type (soot.Type)47 Unit (soot.Unit)47 Value (soot.Value)36 Stmt (soot.jimple.Stmt)35 Test (org.junit.Test)34 Local (soot.Local)34 Body (soot.Body)32 VoidType (soot.VoidType)31 PrimType (soot.PrimType)28 SootField (soot.SootField)28 BooleanType (soot.BooleanType)26 Iterator (java.util.Iterator)23 DoubleType (soot.DoubleType)23 FloatType (soot.FloatType)23 LongType (soot.LongType)23 InvokeExpr (soot.jimple.InvokeExpr)23