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() {}
+ static int tfr = 0;
+ public static Local viaLocal(Value v, Body b, Unit u) {
+ Local l = Jimple.v().newLocal("tmpRef" + (tfr++), v.getType());
+ b.getLocals().add(l);
+ b.getUnits().insertBefore(Jimple.v().newAssignStmt(l, v), u);
+ return l;
+ }
+
+ HashMap map = new HashMap();
+ HashSet size_added = new HashSet();
+
+ public boolean isGladiator(SootClass c) { return c.implementsInterface("edu.berkeley.cs.megacz.Gladiator"); }
+ public boolean isGladiatorField(SootField f)
+ { return isGladiator(f.getDeclaringClass()) && !f.getName().equals("this") && f.getName().indexOf('$')==-1; }
+ public SootField getGladiatorField(SootField f) {
+ SootClass c = f.getDeclaringClass();
+ SootClass oc = Scene.v().getSootClass(c.getName().substring(0, c.getName().lastIndexOf('$')));
+ if (map.get(f) != null) return (SootField)map.get(f);
+ SootField nf = new SootField(c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$" + f.getName(),
+ f.getType().makeArrayType(),
+ f.getModifiers());
+ oc.addField(nf);
+ Body body = oc.getMethod("<init>", new LinkedList()).getActiveBody();
+ Expr newArr = Jimple.v().newNewArrayExpr(f.getType(), IntConstant.v(1000));
+ Local newArrLocal = Jimple.v().newLocal("tmpRef" + (tfr++), f.getType().makeArrayType());
+ body.getLocals().add(newArrLocal);
+ InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), nf.makeRef());
+ body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, newArrLocal));
+ body.getUnits().addFirst(Jimple.v().newAssignStmt(newArrLocal, newArr));
+ map.put(f, nf);
+ return nf;
+ }
- public static GotoInstrumenter v() { return instance; }
+ public SootFieldRef getGladiatorFieldSizeRef(SootClass c) {
+ SootClass mc = Scene.v().getMainClass();
+ String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "_size";
+ if (map.get(c) == null) {
+ SootField f = new SootField(name, IntType.v());
+ mc.addField(f);
+ Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
+ InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
+ body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(0)));
+
+ map.put(c, f);
+ }
+ return Scene.v().makeFieldRef(mc, name, IntType.v(), false);
+ }
+
+ public boolean isGladiatorType(Type t) {
+ return (t instanceof RefType) && isGladiator(((RefType)t).getSootClass());
+ }
- private boolean addedFieldToMainClassAndLoadedPrintStream = false;
- private SootClass javaIoPrintStream;
+ protected void internalTransform(Body body, String phaseName, Map options) {
+ SootClass c = body.getMethod().getDeclaringClass();
- private Local addTmpRef(Body body) {
- Local tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream"));
- body.getLocals().add(tmpRef);
- return tmpRef;
+ for(Iterator it = c.getFields().iterator(); it.hasNext();) {
+ SootField f = (SootField)it.next();
+ Type t = f.getType();
+ if (!(t instanceof RefType)) continue;
+ if (isGladiator(((RefType)t).getSootClass())) f.setType(IntType.v());
}
-
- private Local addTmpLong(Body body) {
- Local tmpLong = Jimple.v().newLocal("tmpLong", LongType.v());
- body.getLocals().add(tmpLong);
- return tmpLong;
+
+ for(Iterator it = c.methodIterator(); it.hasNext();) {
+ SootMethod m = (SootMethod)it.next();
+ System.out.println(m.getName() + " -- " + m.getActiveBody());
+ /*
+ List l2 = new LinkedList();
+ List l = m.getParameterTypes();
+ for(Iterator it2 = l.iterator(); it2.hasNext();) {
+ Type t = (Type)it2.next();
+ l2.add(isGladiatorType(t) ? IntType.v() : t);
+ }
+ m.setParameterTypes(l2);
+ Type t = m.getReturnType();
+ m.setReturnType(isGladiatorType(t) ? IntType.v() : t);
+ */
}
- 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);
+ for(Iterator it = body.getLocals().snapshotIterator(); it.hasNext();) {
+ Local l = (Local)it.next();
+ if (isGladiatorType(l.getType())) l.setType(IntType.v());
}
- 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();
-
- System.out.println("sClass is " + sClass);
-
- // 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;
+ Chain units = body.getUnits();
+ Iterator stmtIt = units.snapshotIterator();
+ while(stmtIt.hasNext()) {
+ Stmt s = (Stmt) stmtIt.next();
+ 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 InvokeExpr) {
+ InvokeExpr ie = (InvokeExpr)v;
+ SootMethod m = ie.getMethod();
+ if (isGladiator(m.getDeclaringClass())) {
+ body.getUnits().remove(s);
+ break;
+ }
+
+ } else if (v instanceof NewExpr) {
+ NewExpr ne = (NewExpr)v;
+ if (isGladiatorType(ne.getBaseType())) {
+ System.out.println("******");
+ SootClass mc = Scene.v().getMainClass();
+ SootClass sc = ((RefType)ne.getBaseType()).getSootClass();
+ System.out.println(sc);
+ InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(),
+ getGladiatorFieldSizeRef(sc));
+ Local ll = viaLocal(sfr, body, s);
+ Local ll2 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
+ body.getLocals().add(ll2);
+ Stmt stmt = Jimple.v().newAssignStmt(ll2, Jimple.v().newAddExpr(ll, IntConstant.v(1)));
+ units.insertBefore(stmt, s);
+ units.insertAfter(Jimple.v().newAssignStmt(sfr, ll2), stmt);
+ vb.setValue(ll);
+ }
+
+ } else if (v instanceof InstanceFieldRef) {
+ InstanceFieldRef ifr = (InstanceFieldRef)v;
+ Type t = ifr.getType();
+ if ((t instanceof RefType) && isGladiator(((RefType)t).getSootClass())) {
+ SootClass tc = ((RefType)t).getSootClass();
+ SootClass mc = Scene.v().getMainClass();
+ SootFieldRef fr = Scene.v().makeFieldRef(mc, "z", IntType.v(), false);
+ ifr.setFieldRef(fr);
+ }
+ SootField f = ifr.getField();
+ if (isGladiatorField(f)) {
+ f = getGladiatorField(f);
+ SootClass mc = Scene.v().getMainClass();
+ SootField sf = mc.getField(f.getName(), f.getType());
+ InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), sf.makeRef());
+ ArrayRef ar = Jimple.v().newArrayRef(viaLocal(sfr, body, s), ifr.getBase());
+ 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);
- }
}
+ }
}
}
}