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!!!");
}
}
}
}
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);
}
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);
}
};
}
};
}
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();
}
};
}
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);
}
Aggregations