use of heros.FlowFunctions 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);
}
};
}
};
}
use of heros.FlowFunctions 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();
}
};
}
use of heros.FlowFunctions 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();
}
};
}
use of heros.FlowFunctions 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();
}
};
}
use of heros.FlowFunctions 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);
}
}
};
}
};
}
Aggregations