1 19 20 25 26 27 28 package ashes.examples.countgotos; 29 30 import soot.*; 31 import soot.jimple.*; 32 import soot.util.*; 33 import java.io.*; 34 import java.util.*; 35 36 39 public class Main 40 { 41 public static void main(String [] args) 42 { 43 if(args.length == 0) 44 { 45 System.out.println("Syntax: java ashes.examples.countgotos.Main [soot options]"); 46 System.exit(0); 47 } 48 49 PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", GotoInstrumenter.v())); 50 51 Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES); 53 soot.Main.main(args); 54 } 55 } 56 57 66 67 class GotoInstrumenter extends BodyTransformer 68 { 69 private static GotoInstrumenter instance = new GotoInstrumenter(); 70 private GotoInstrumenter() {} 71 72 public static GotoInstrumenter v() { return instance; } 73 74 private boolean addedFieldToMainClassAndLoadedPrintStream = false; 75 private SootClass javaIoPrintStream; 76 77 private Local addTmpRef(Body body) 78 { 79 Local tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream")); 80 body.getLocals().add(tmpRef); 81 return tmpRef; 82 } 83 84 private Local addTmpLong(Body body) 85 { 86 Local tmpLong = Jimple.v().newLocal("tmpLong", LongType.v()); 87 body.getLocals().add(tmpLong); 88 return tmpLong; 89 } 90 91 private void addStmtsToBefore(Chain units, Stmt s, SootField gotoCounter, Local tmpRef, Local tmpLong) 92 { 93 units.insertBefore(Jimple.v().newAssignStmt( 95 tmpRef, Jimple.v().newStaticFieldRef( 96 Scene.v().getField("<java.lang.System: java.io.PrintStream out>").makeRef())), s); 97 98 units.insertBefore(Jimple.v().newAssignStmt(tmpLong, 100 Jimple.v().newStaticFieldRef(gotoCounter.makeRef())), s); 101 102 SootMethod toCall = javaIoPrintStream.getMethod("void println(long)"); 104 units.insertBefore(Jimple.v().newInvokeStmt( 105 Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), tmpLong)), s); 106 } 107 108 protected void internalTransform(Body body, String phaseName, Map options) 109 { 110 SootClass sClass = body.getMethod().getDeclaringClass(); 111 SootField gotoCounter = null; 112 boolean addedLocals = false; 113 Local tmpRef = null, tmpLong = null; 114 Chain units = body.getUnits(); 115 116 synchronized(this) 119 { 120 if (!Scene.v().getMainClass(). 121 declaresMethod("void main(java.lang.String[])")) 122 throw new RuntimeException ("couldn't find main() in mainClass"); 123 124 if (addedFieldToMainClassAndLoadedPrintStream) 125 gotoCounter = Scene.v().getMainClass().getFieldByName("gotoCount"); 126 else 127 { 128 gotoCounter = new SootField("gotoCount", LongType.v(), 130 Modifier.STATIC); 131 Scene.v().getMainClass().addField(gotoCounter); 132 133 javaIoPrintStream = Scene.v().getSootClass("java.io.PrintStream"); 134 135 addedFieldToMainClassAndLoadedPrintStream = true; 136 } 137 } 138 139 { 141 boolean isMainMethod = body.getMethod().getSubSignature().equals("void main(java.lang.String[])"); 142 143 Local tmpLocal = Jimple.v().newLocal("tmp", LongType.v()); 144 body.getLocals().add(tmpLocal); 145 146 Iterator stmtIt = units.snapshotIterator(); 147 148 while(stmtIt.hasNext()) 149 { 150 Stmt s = (Stmt) stmtIt.next(); 151 152 if(s instanceof GotoStmt) 153 { 154 AssignStmt toAdd1 = Jimple.v().newAssignStmt(tmpLocal, 155 Jimple.v().newStaticFieldRef(gotoCounter.makeRef())); 156 AssignStmt toAdd2 = Jimple.v().newAssignStmt(tmpLocal, 157 Jimple.v().newAddExpr(tmpLocal, LongConstant.v(1L))); 158 AssignStmt toAdd3 = Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(gotoCounter.makeRef()), 159 tmpLocal); 160 161 units.insertBefore(toAdd1, s); 163 164 units.insertBefore(toAdd2, s); 166 167 units.insertBefore(toAdd3, s); 169 } 170 else if (s instanceof InvokeStmt) 171 { 172 InvokeExpr iexpr = (InvokeExpr) ((InvokeStmt)s).getInvokeExpr(); 173 if (iexpr instanceof StaticInvokeExpr) 174 { 175 SootMethod target = ((StaticInvokeExpr)iexpr).getMethod(); 176 177 if (target.getSignature().equals("<java.lang.System: void exit(int)>")) 178 { 179 if (!addedLocals) 180 { 181 tmpRef = addTmpRef(body); tmpLong = addTmpLong(body); 182 addedLocals = true; 183 } 184 addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong); 185 } 186 } 187 } 188 else if (isMainMethod && (s instanceof ReturnStmt || s instanceof ReturnVoidStmt)) 189 { 190 if (!addedLocals) 191 { 192 tmpRef = addTmpRef(body); tmpLong = addTmpLong(body); 193 addedLocals = true; 194 } 195 addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong); 196 } 197 } 198 } 199 } 200 } 201 | Popular Tags |