Search in sources :

Example 86 with Unit

use of soot.Unit 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 87 with Unit

use of soot.Unit 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 88 with Unit

use of soot.Unit in project soot by Sable.

the class JimpleBasedInterproceduralCFG method initializeUnitToOwner.

public void initializeUnitToOwner(SootMethod m) {
    if (m.hasActiveBody()) {
        Body b = m.getActiveBody();
        PatchingChain<Unit> units = b.getUnits();
        for (Unit unit : units) {
            unitToOwner.put(unit, b);
        }
    }
}
Also used : Unit(soot.Unit) Body(soot.Body)

Example 89 with Unit

use of soot.Unit in project soot by Sable.

the class ReflectionTraceInfo method inferSource.

private Set<SootMethod> inferSource(String source, int lineNumber) {
    String className = source.substring(0, source.lastIndexOf("."));
    String methodName = source.substring(source.lastIndexOf(".") + 1);
    if (!Scene.v().containsClass(className)) {
        Scene.v().addBasicClass(className, SootClass.BODIES);
        Scene.v().loadBasicClasses();
        if (!Scene.v().containsClass(className)) {
            throw new RuntimeException("Trace file refers to unknown class: " + className);
        }
    }
    SootClass sootClass = Scene.v().getSootClass(className);
    Set<SootMethod> methodsWithRightName = new LinkedHashSet<SootMethod>();
    for (SootMethod m : sootClass.getMethods()) {
        if (m.isConcrete() && m.getName().equals(methodName)) {
            methodsWithRightName.add(m);
        }
    }
    if (methodsWithRightName.isEmpty()) {
        throw new RuntimeException("Trace file refers to unknown method with name " + methodName + " in Class " + className);
    } else if (methodsWithRightName.size() == 1) {
        return Collections.singleton(methodsWithRightName.iterator().next());
    } else {
        // more than one method with that name
        for (SootMethod sootMethod : methodsWithRightName) {
            if (coversLineNumber(lineNumber, sootMethod)) {
                return Collections.singleton(sootMethod);
            }
            if (sootMethod.isConcrete()) {
                if (!sootMethod.hasActiveBody())
                    sootMethod.retrieveActiveBody();
                Body body = sootMethod.getActiveBody();
                if (coversLineNumber(lineNumber, body)) {
                    return Collections.singleton(sootMethod);
                }
                for (Unit u : body.getUnits()) {
                    if (coversLineNumber(lineNumber, u)) {
                        return Collections.singleton(sootMethod);
                    }
                }
            }
        }
        // be conservative and return all method that we found
        return methodsWithRightName;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SootMethod(soot.SootMethod) SootClass(soot.SootClass) Unit(soot.Unit) Body(soot.Body)

Example 90 with Unit

use of soot.Unit in project soot by Sable.

the class ThisInliner method internalTransform.

public void internalTransform(Body b, String phaseName, Map options) {
    // assure body is a constructor
    if (!b.getMethod().getName().equals("<init>"))
        return;
    // if the first invoke is a this() and not a super() inline the this()
    InvokeStmt invokeStmt = getFirstSpecialInvoke(b);
    if (invokeStmt == null)
        return;
    SpecialInvokeExpr specInvokeExpr = (SpecialInvokeExpr) invokeStmt.getInvokeExpr();
    if (specInvokeExpr.getMethod().getDeclaringClass().equals(b.getMethod().getDeclaringClass())) {
        // put locals from inlinee into container
        if (!specInvokeExpr.getMethod().hasActiveBody()) {
            specInvokeExpr.getMethod().retrieveActiveBody();
        }
        HashMap<Local, Local> oldLocalsToNew = new HashMap<Local, Local>();
        for (Local l : specInvokeExpr.getMethod().getActiveBody().getLocals()) {
            Local newLocal = (Local) l.clone();
            b.getLocals().add(newLocal);
            oldLocalsToNew.put(l, newLocal);
        }
        // find identity stmt of original method
        IdentityStmt origIdStmt = findIdentityStmt(b);
        HashMap<Stmt, Stmt> oldStmtsToNew = new HashMap<Stmt, Stmt>();
        // System.out.println("locals: "+b.getLocals());
        Chain<Unit> containerUnits = b.getUnits();
        for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
            Stmt inlineeStmt = (Stmt) u;
            // handle identity stmts
            if (inlineeStmt instanceof IdentityStmt) {
                IdentityStmt idStmt = (IdentityStmt) inlineeStmt;
                if (idStmt.getRightOp() instanceof ThisRef) {
                    Stmt newThis = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), origIdStmt.getLeftOp());
                    containerUnits.insertBefore(newThis, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newThis);
                } else if (idStmt.getRightOp() instanceof CaughtExceptionRef) {
                    Stmt newInlinee = (Stmt) inlineeStmt.clone();
                    for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
                        if (next.getValue() instanceof Local) {
                            next.setValue((Local) oldLocalsToNew.get(next.getValue()));
                        }
                    }
                    containerUnits.insertBefore(newInlinee, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newInlinee);
                } else if (idStmt.getRightOp() instanceof ParameterRef) {
                    Stmt newParam = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), specInvokeExpr.getArg(((ParameterRef) idStmt.getRightOp()).getIndex()));
                    containerUnits.insertBefore(newParam, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newParam);
                }
            } else // from a constructor)
            if (inlineeStmt instanceof ReturnVoidStmt) {
                Stmt newRet = Jimple.v().newGotoStmt((Stmt) containerUnits.getSuccOf(invokeStmt));
                containerUnits.insertBefore(newRet, invokeStmt);
                System.out.println("adding to stmt map: " + inlineeStmt + " and " + newRet);
                oldStmtsToNew.put(inlineeStmt, newRet);
            } else {
                Stmt newInlinee = (Stmt) inlineeStmt.clone();
                for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
                    if (next.getValue() instanceof Local) {
                        next.setValue((Local) oldLocalsToNew.get(next.getValue()));
                    }
                }
                containerUnits.insertBefore(newInlinee, invokeStmt);
                oldStmtsToNew.put(inlineeStmt, newInlinee);
            }
        }
        // handleTraps
        for (Trap t : specInvokeExpr.getMethod().getActiveBody().getTraps()) {
            System.out.println("begin: " + t.getBeginUnit());
            Stmt newBegin = oldStmtsToNew.get(t.getBeginUnit());
            System.out.println("end: " + t.getEndUnit());
            Stmt newEnd = oldStmtsToNew.get(t.getEndUnit());
            System.out.println("handler: " + t.getHandlerUnit());
            Stmt newHandler = oldStmtsToNew.get(t.getHandlerUnit());
            if (newBegin == null || newEnd == null || newHandler == null)
                throw new RuntimeException("couldn't map trap!");
            b.getTraps().add(Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler));
        }
        // patch gotos
        for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
            Stmt inlineeStmt = (Stmt) u;
            if (inlineeStmt instanceof GotoStmt) {
                System.out.println("inlinee goto target: " + ((GotoStmt) inlineeStmt).getTarget());
                ((GotoStmt) oldStmtsToNew.get(inlineeStmt)).setTarget(oldStmtsToNew.get(((GotoStmt) inlineeStmt).getTarget()));
            }
        }
        // remove original invoke
        containerUnits.remove(invokeStmt);
        // resolve name collisions
        LocalNameStandardizer.v().transform(b, "ji.lns");
    }
// System.out.println("locals: "+b.getLocals());
// System.out.println("units: "+b.getUnits());
}
Also used : InvokeStmt(soot.jimple.InvokeStmt) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) Local(soot.Local) Trap(soot.Trap) Unit(soot.Unit) GotoStmt(soot.jimple.GotoStmt) Stmt(soot.jimple.Stmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) IdentityStmt(soot.jimple.IdentityStmt) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) GotoStmt(soot.jimple.GotoStmt) IdentityStmt(soot.jimple.IdentityStmt)

Aggregations

Unit (soot.Unit)240 Local (soot.Local)77 Stmt (soot.jimple.Stmt)77 Value (soot.Value)74 ArrayList (java.util.ArrayList)65 AssignStmt (soot.jimple.AssignStmt)58 SootMethod (soot.SootMethod)47 Body (soot.Body)37 InvokeStmt (soot.jimple.InvokeStmt)35 Type (soot.Type)34 HashSet (java.util.HashSet)33 ValueBox (soot.ValueBox)33 InvokeExpr (soot.jimple.InvokeExpr)33 Trap (soot.Trap)32 RefType (soot.RefType)30 IdentityStmt (soot.jimple.IdentityStmt)28 HashMap (java.util.HashMap)27 IfStmt (soot.jimple.IfStmt)27 DefinitionStmt (soot.jimple.DefinitionStmt)25 List (java.util.List)23