-
Notifications
You must be signed in to change notification settings - Fork 86
Example: Using Heros with Soot
This page is an example of using the Heros' IFDS solver with Soot. It was written using Soot v. 3.1.0 and Heros v. 1.0.1.
Soot performs Java analysis and optimization by running packs. Heros is a whole-program analysis and needs to run in a whole-program pack. In this example, Heros is run in the Whole-Jimple Transformation Pack (wjtp).
In order to add an analysis, like Heros, to a whole-program pack in Soot, it must be implemented as a class that extends SceneTransformer. The following is a simple example using IFDSReachingDefinitions found in Soot. IFDSReachingDefinitions is a simple toy example, do not use it for empirical studies! This here is a good example of a more elaborate IFDS instance.
import java.util.Map;
import java.util.Set;
import heros.IFDSTabulationProblem;
import heros.InterproceduralCFG;
import heros.solver.IFDSSolver;
import soot.SceneTransformer;
import soot.SootMethod;
import soot.Unit;
import soot.Value;
import soot.jimple.DefinitionStmt;
import soot.jimple.toolkits.ide.exampleproblems.IFDSReachingDefinitions;
import soot.jimple.toolkits.ide.icfg.JimpleBasedInterproceduralCFG;
import soot.toolkits.scalar.Pair;
// Subclass of SceneTransformer to run Heros IFDS solver in Soot's "wjtp" pack
public class IFDSDataFlowTransformer extends SceneTransformer {
@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
JimpleBasedInterproceduralCFG icfg= new JimpleBasedInterproceduralCFG();
IFDSTabulationProblem<Unit, Pair<Value,
Set<DefinitionStmt>>, SootMethod,
InterproceduralCFG<Unit, SootMethod>> problem = new IFDSReachingDefinitions(icfg);
IFDSSolver<Unit, Pair<Value, Set<DefinitionStmt>>,
SootMethod, InterproceduralCFG<Unit, SootMethod>> solver =
new IFDSSolver<Unit, Pair<Value, Set<DefinitionStmt>>, SootMethod,
InterproceduralCFG<Unit, SootMethod>>(problem);
System.out.println("Starting solver");
solver.solve();
System.out.println("Done");
}
}
Soot must be run with the whole-program option enabled when using Heros. Here, Soot is configured to run in whole-program mode and construct a call-graph using SPARK.
// Set Soot's internal classpath
Options.v().set_soot_classpath(classpath);
// Enable whole-program mode
Options.v().set_whole_program(true);
Options.v().set_app(true);
// Call-graph options
Options.v().setPhaseOption("cg", "safe-newinstance:true");
Options.v().setPhaseOption("cg.cha","enabled:false");
// Enable SPARK call-graph construction
Options.v().setPhaseOption("cg.spark","enabled:true");
Options.v().setPhaseOption("cg.spark","verbose:true");
Options.v().setPhaseOption("cg.spark","on-fly-cg:true");
Options.v().set_allow_phantom_refs(true);
// Set the main class of the application to be analysed
Options.v().set_main_class(mainClass);
// Load the main class
SootClass c = Scene.v().loadClass(mainClass, SootClass.BODIES);
c.setApplicationClass();
// Load the "main" method of the main class and set it as a Soot entry point
SootMethod entryPoint = c.getMethodByName("main");
List<SootMethod> entryPoints = new ArrayList<SootMethod>();
entryPoints.add(entryPoint);
Scene.v().setEntryPoints(entryPoints);
Next, an instance of the Heros analysis class above is added to the Soot Whole-Jimple Transform Pack (wjtp). Note that the name I used here, "wjtp.herosifds", must begin with "wjtp.", but the rest is arbitrarily chosen; You can use whatever name you want after "wjtp.".
PackManager.v().getPack("wjtp").add(new Transform("wjtp.herosifds", new IFDSDataFlowTransformer()));
Finally, execute Soot
soot.Main.main();
This example does not include any code to work with the IFDS solution provided by Heros, and such code can be added in several places, including at the end of the "IFDSDataFlowTransformer" class above.