Skip to content

Example: Using Heros with Soot

Eric Bodden edited this page Jul 9, 2020 · 6 revisions

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.

Overview

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).

Heros SceneTransformer class to load into Soot 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");
    }
}

Setup and Run Heros in Soot

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.