import java.io.*;
import java.util.*;
-public class Transformer {
- public static void main(String[] args)
- {
- if(args.length == 0)
- {
- System.out.println("Syntax: java ashes.examples.countgotos.Main [soot options]");
+public class Transformer extends BodyTransformer {
+
+ private static Transformer instance = new Transformer();
+ private Transformer() {}
+ public static Transformer v() { return instance; }
+
+ public static void main(String[] args) {
+ if(args.length == 0) {
+ System.out.println("Syntax: java " + v().getClass().getName() + " [soot options]");
System.exit(0);
}
-
- PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", GotoInstrumenter.v()));
-
+ PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", Transformer.v()));
// Just in case, resolve the PrintStream SootClass.
Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
soot.Main.main(args);
}
- static class GotoInstrumenter extends BodyTransformer {
- private static GotoInstrumenter instance = new GotoInstrumenter();
- private GotoInstrumenter() {}
-
- public static GotoInstrumenter v() { return instance; }
-
- private boolean addedFieldToMainClassAndLoadedPrintStream = false;
- private SootClass javaIoPrintStream;
-
- private Local addTmpRef(Body body) {
- Local tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream"));
- body.getLocals().add(tmpRef);
- return tmpRef;
- }
-
- private Local addTmpLong(Body body) {
- Local tmpLong = Jimple.v().newLocal("tmpLong", LongType.v());
- body.getLocals().add(tmpLong);
- return tmpLong;
- }
-
- private void addStmtsToBefore(Chain units, Stmt s, SootField gotoCounter, Local tmpRef, Local tmpLong)
- {
- // insert "tmpRef = java.lang.System.out;"
- units.insertBefore(Jimple.v().newAssignStmt(
- tmpRef, Jimple.v().newStaticFieldRef(
- Scene.v().getField("<java.lang.System: java.io.PrintStream out>").makeRef())), s);
-
- // insert "tmpLong = gotoCounter;"
- units.insertBefore(Jimple.v().newAssignStmt(tmpLong,
- Jimple.v().newStaticFieldRef(gotoCounter.makeRef())), s);
-
- // insert "tmpRef.println(tmpLong);"
- SootMethod toCall = javaIoPrintStream.getMethod("void println(long)");
- units.insertBefore(Jimple.v().newInvokeStmt(
- Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), tmpLong)), s);
- }
-
- protected void internalTransform(Body body, String phaseName, Map options) {
- SootClass sClass = body.getMethod().getDeclaringClass();
- SootField gotoCounter = null;
- boolean addedLocals = false;
- Local tmpRef = null, tmpLong = null;
- Chain units = body.getUnits();
+ public static Local viaLocal(Value v, Body b, Chain c, Unit u) {
+ Local l = Jimple.v().newLocal("tmpRef", v.getType());
+ b.getLocals().add(l);
+ c.insertBefore(Jimple.v().newAssignStmt(l, v), u);
+ return l;
+ }
- System.out.println("sClass is " + sClass);
+ protected void internalTransform(Body body, String phaseName, Map options) {
+ SootClass sClass = body.getMethod().getDeclaringClass();
+ SootField gotoCounter = null;
+ boolean addedLocals = false;
+ Local tmpRef = null, tmpLong = null;
+ Chain units = body.getUnits();
- // Add code at the end of the main method to print out the
- // gotoCounter (this only works in simple cases, because you may have multiple returns or System.exit()'s )
- synchronized(this)
- {
- if (!Scene.v().getMainClass().
- declaresMethod("void main(java.lang.String[])"))
- throw new RuntimeException("couldn't find main() in mainClass");
-
- if (addedFieldToMainClassAndLoadedPrintStream)
- gotoCounter = Scene.v().getMainClass().getFieldByName("gotoCount");
- else
- {
- // Add gotoCounter field
- gotoCounter = new SootField("gotoCount", LongType.v(),
- Modifier.STATIC);
- Scene.v().getMainClass().addField(gotoCounter);
-
- javaIoPrintStream = Scene.v().getSootClass("java.io.PrintStream");
-
- addedFieldToMainClassAndLoadedPrintStream = true;
+ boolean isMainMethod = body.getMethod().getSubSignature().equals("void main(java.lang.String[])");
+ Iterator stmtIt = units.snapshotIterator();
+ while(stmtIt.hasNext()) {
+ Stmt s = (Stmt) stmtIt.next();
+ //if (isMainMethod) {
+ List l = s.getUseAndDefBoxes();
+ for(Iterator it = l.iterator(); it.hasNext();) {
+ Object o = it.next();
+ if (o instanceof ValueBox) {
+ ValueBox vb = (ValueBox)o;
+ Value v = vb.getValue();
+ if (v instanceof CastExpr) {
+ CastExpr ce = (CastExpr)v;
+ //System.out.println(">>> cast " + ce.getOp().getType() + " -> " + ce.getCastType());
+ } else if (v instanceof InstanceFieldRef) {
+ InstanceFieldRef ifr = (InstanceFieldRef)v;
+ SootField f = ifr.getField();
+ System.out.println(">>> getField " + f);
+ if (f.getName().equals("foo")) {
+ SootClass mc = Scene.v().getMainClass();
+ Type arrType = f.getType().makeArrayType();
+ SootField sf = mc.getField("arr_" + f.getName(), arrType);
+ StaticFieldRef sfr = Jimple.v().newStaticFieldRef(sf.makeRef());
+ ArrayRef ar = Jimple.v().newArrayRef(viaLocal(sfr, body, units, s), IntConstant.v(3));
+ System.out.println(">>>>> " + ar.getType());
+ System.out.println(">>>>> " + v.getType());
+ vb.setValue(ar);
}
- }
-
- // Add code to increase goto counter each time a goto is encountered
- {
- boolean isMainMethod = body.getMethod().getSubSignature().equals("void main(java.lang.String[])");
-
- Local tmpLocal = Jimple.v().newLocal("tmp", LongType.v());
- body.getLocals().add(tmpLocal);
-
- Iterator stmtIt = units.snapshotIterator();
-
- while(stmtIt.hasNext())
- {
- Stmt s = (Stmt) stmtIt.next();
-
- if(s instanceof GotoStmt)
- {
- AssignStmt toAdd1 = Jimple.v().newAssignStmt(tmpLocal,
- Jimple.v().newStaticFieldRef(gotoCounter.makeRef()));
- AssignStmt toAdd2 = Jimple.v().newAssignStmt(tmpLocal,
- Jimple.v().newAddExpr(tmpLocal, LongConstant.v(1L)));
- AssignStmt toAdd3 = Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(gotoCounter.makeRef()),
- tmpLocal);
-
- // insert "tmpLocal = gotoCounter;"
- units.insertBefore(toAdd1, s);
-
- // insert "tmpLocal = tmpLocal + 1L;"
- units.insertBefore(toAdd2, s);
-
- // insert "gotoCounter = tmpLocal;"
- units.insertBefore(toAdd3, s);
- }
- else if (s instanceof InvokeStmt)
- {
- InvokeExpr iexpr = (InvokeExpr) ((InvokeStmt)s).getInvokeExpr();
- if (iexpr instanceof StaticInvokeExpr)
- {
- SootMethod target = ((StaticInvokeExpr)iexpr).getMethod();
-
- if (target.getSignature().equals("<java.lang.System: void exit(int)>"))
- {
- if (!addedLocals)
- {
- tmpRef = addTmpRef(body); tmpLong = addTmpLong(body);
- addedLocals = true;
- }
- addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong);
- }
- }
- }
- else if (isMainMethod && (s instanceof ReturnStmt || s instanceof ReturnVoidStmt))
- {
- if (!addedLocals)
- {
- tmpRef = addTmpRef(body); tmpLong = addTmpLong(body);
- addedLocals = true;
- }
- addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong);
- }
}
+ }
}
}
}