Search in sources :

Example 1 with FlowFunction

use of heros.FlowFunction 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 2 with FlowFunction

use of heros.FlowFunction 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 3 with FlowFunction

use of heros.FlowFunction 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)

Example 4 with FlowFunction

use of heros.FlowFunction in project soot by Sable.

the class IFDSLocalInfoFlow method createFlowFunctionsFactory.

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

        @Override
        public FlowFunction<Local> getNormalFlowFunction(Unit src, Unit dest) {
            if (src instanceof IdentityStmt && interproceduralCFG().getMethodOf(src) == Scene.v().getMainMethod()) {
                IdentityStmt is = (IdentityStmt) src;
                Local leftLocal = (Local) is.getLeftOp();
                Value right = is.getRightOp();
                if (right instanceof ParameterRef) {
                    return new Gen<Local>(leftLocal, zeroValue());
                }
            }
            if (src instanceof AssignStmt) {
                AssignStmt assignStmt = (AssignStmt) src;
                Value right = assignStmt.getRightOp();
                if (assignStmt.getLeftOp() instanceof Local) {
                    final Local leftLocal = (Local) assignStmt.getLeftOp();
                    if (right instanceof Local) {
                        final Local rightLocal = (Local) right;
                        return new Transfer<Local>(leftLocal, rightLocal);
                    } else {
                        return new Kill<Local>(leftLocal);
                    }
                }
            }
            return Identity.v();
        }

        @Override
        public FlowFunction<Local> getCallFlowFunction(Unit src, final SootMethod dest) {
            Stmt s = (Stmt) src;
            InvokeExpr ie = s.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<Local>() {

                public Set<Local> computeTargets(Local source) {
                    // ignore implicit calls to static initializers
                    if (dest.getName().equals(SootMethod.staticInitializerName) && dest.getParameterCount() == 0)
                        return Collections.emptySet();
                    Set<Local> taintsInCaller = new HashSet<Local>();
                    for (int i = 0; i < callArgs.size(); i++) {
                        if (callArgs.get(i).equivTo(source)) {
                            taintsInCaller.add(paramLocals.get(i));
                        }
                    }
                    return taintsInCaller;
                }
            };
        }

        @Override
        public FlowFunction<Local> 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<Local>() {

                                public Set<Local> computeTargets(Local source) {
                                    if (source == retLocal)
                                        return Collections.singleton(tgtLocal);
                                    return Collections.emptySet();
                                }
                            };
                        }
                    }
                }
            }
            return KillAll.v();
        }

        @Override
        public FlowFunction<Local> getCallToReturnFlowFunction(Unit call, Unit returnSite) {
            return Identity.v();
        }
    };
}
Also used : AssignStmt(soot.jimple.AssignStmt) FlowFunction(heros.FlowFunction) ArrayList(java.util.ArrayList) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) Gen(heros.flowfunc.Gen) ParameterRef(soot.jimple.ParameterRef) InvokeExpr(soot.jimple.InvokeExpr) Value(soot.Value) Transfer(heros.flowfunc.Transfer) SootMethod(soot.SootMethod) Kill(heros.flowfunc.Kill) ReturnStmt(soot.jimple.ReturnStmt) DefinitionStmt(soot.jimple.DefinitionStmt) IdentityStmt(soot.jimple.IdentityStmt) HashSet(java.util.HashSet)

Example 5 with FlowFunction

use of heros.FlowFunction in project soot by Sable.

the class IFDSReachingDefinitions method createFlowFunctionsFactory.

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

        @Override
        public FlowFunction<Pair<Value, Set<DefinitionStmt>>> getNormalFlowFunction(final Unit curr, Unit succ) {
            if (curr instanceof DefinitionStmt) {
                final DefinitionStmt assignment = (DefinitionStmt) curr;
                return new FlowFunction<Pair<Value, Set<DefinitionStmt>>>() {

                    @Override
                    public Set<Pair<Value, Set<DefinitionStmt>>> computeTargets(Pair<Value, Set<DefinitionStmt>> source) {
                        if (source != zeroValue()) {
                            if (source.getO1().equivTo(assignment.getLeftOp())) {
                                return Collections.emptySet();
                            }
                            return Collections.singleton(source);
                        } else {
                            LinkedHashSet<Pair<Value, Set<DefinitionStmt>>> res = new LinkedHashSet<Pair<Value, Set<DefinitionStmt>>>();
                            res.add(new Pair<Value, Set<DefinitionStmt>>(assignment.getLeftOp(), Collections.<DefinitionStmt>singleton(assignment)));
                            return res;
                        }
                    }
                };
            }
            return Identity.v();
        }

        @Override
        public FlowFunction<Pair<Value, Set<DefinitionStmt>>> 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>(args.size());
            for (Value value : args) {
                if (value instanceof Local)
                    localArguments.add((Local) value);
                else
                    localArguments.add(null);
            }
            return new FlowFunction<Pair<Value, Set<DefinitionStmt>>>() {

                @Override
                public Set<Pair<Value, Set<DefinitionStmt>>> computeTargets(Pair<Value, Set<DefinitionStmt>> source) {
                    if (!destinationMethod.getName().equals("<clinit>") && !destinationMethod.getSubSignature().equals("void run()"))
                        if (localArguments.contains(source.getO1())) {
                            int paramIndex = args.indexOf(source.getO1());
                            Pair<Value, Set<DefinitionStmt>> pair = new Pair<Value, Set<DefinitionStmt>>(new EquivalentValue(Jimple.v().newParameterRef(destinationMethod.getParameterType(paramIndex), paramIndex)), source.getO2());
                            return Collections.singleton(pair);
                        }
                    return Collections.emptySet();
                }
            };
        }

        @Override
        public FlowFunction<Pair<Value, Set<DefinitionStmt>>> getReturnFlowFunction(final Unit callSite, SootMethod calleeMethod, final Unit exitStmt, Unit returnSite) {
            if (!(callSite instanceof DefinitionStmt))
                return KillAll.v();
            if (exitStmt instanceof ReturnVoidStmt)
                return KillAll.v();
            return new FlowFunction<Pair<Value, Set<DefinitionStmt>>>() {

                @Override
                public Set<Pair<Value, Set<DefinitionStmt>>> computeTargets(Pair<Value, Set<DefinitionStmt>> source) {
                    if (exitStmt instanceof ReturnStmt) {
                        ReturnStmt returnStmt = (ReturnStmt) exitStmt;
                        if (returnStmt.getOp().equivTo(source.getO1())) {
                            DefinitionStmt definitionStmt = (DefinitionStmt) callSite;
                            Pair<Value, Set<DefinitionStmt>> pair = new Pair<Value, Set<DefinitionStmt>>(definitionStmt.getLeftOp(), source.getO2());
                            return Collections.singleton(pair);
                        }
                    }
                    return Collections.emptySet();
                }
            };
        }

        @Override
        public FlowFunction<Pair<Value, Set<DefinitionStmt>>> getCallToReturnFlowFunction(Unit callSite, Unit returnSite) {
            if (!(callSite instanceof DefinitionStmt))
                return Identity.v();
            final DefinitionStmt definitionStmt = (DefinitionStmt) callSite;
            return new FlowFunction<Pair<Value, Set<DefinitionStmt>>>() {

                @Override
                public Set<Pair<Value, Set<DefinitionStmt>>> computeTargets(Pair<Value, Set<DefinitionStmt>> source) {
                    if (source.getO1().equivTo(definitionStmt.getLeftOp())) {
                        return Collections.emptySet();
                    } else {
                        return Collections.singleton(source);
                    }
                }
            };
        }
    };
}
Also used : LinkedHashSet(java.util.LinkedHashSet) EquivalentValue(soot.EquivalentValue) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) FlowFunction(heros.FlowFunction) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) ArrayList(java.util.ArrayList) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) InvokeExpr(soot.jimple.InvokeExpr) EquivalentValue(soot.EquivalentValue) Value(soot.Value) SootMethod(soot.SootMethod) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt) Pair(soot.toolkits.scalar.Pair)

Aggregations

FlowFunction (heros.FlowFunction)5 FlowFunctions (heros.FlowFunctions)5 ArrayList (java.util.ArrayList)5 Local (soot.Local)5 SootMethod (soot.SootMethod)5 Unit (soot.Unit)5 Value (soot.Value)5 InvokeExpr (soot.jimple.InvokeExpr)5 ReturnStmt (soot.jimple.ReturnStmt)5 Stmt (soot.jimple.Stmt)5 DefinitionStmt (soot.jimple.DefinitionStmt)4 JimpleLocal (soot.jimple.internal.JimpleLocal)4 LinkedHashSet (java.util.LinkedHashSet)3 Set (java.util.Set)3 Kill (heros.flowfunc.Kill)2 HashSet (java.util.HashSet)2 ValueBox (soot.ValueBox)2 Pair (soot.toolkits.scalar.Pair)2 Gen (heros.flowfunc.Gen)1 Transfer (heros.flowfunc.Transfer)1