-
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 performed Java analysis and optimization by running packs. Heros operates 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 a class that extends SceneTransformer. The following is a simple example using example IFDSReachingDefinitions found in Soot. IFDSReachingDefinitions was a quickly written example that is not necessarily kept up to date in Soot, and it may require corrections to properly handle special edges (usually related to Thread.run) added to the call graph by newer versions of Soot.
// 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 with 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.