1 19 20 25 26 package soot.jimple.toolkits.annotation.arraycheck; 27 import soot.options.*; 28 29 import soot.*; 30 import soot.jimple.*; 31 import soot.toolkits.graph.*; 32 import soot.util.*; 33 import soot.tagkit.*; 34 import soot.jimple.toolkits.annotation.tags.*; 35 import java.util.*; 36 import soot.options.ABCOptions; 37 38 public class ArrayBoundsChecker extends BodyTransformer 39 { 40 public ArrayBoundsChecker( Singletons.Global g ) {} 41 public static ArrayBoundsChecker v() { return G.v().soot_jimple_toolkits_annotation_arraycheck_ArrayBoundsChecker(); } 42 43 protected boolean takeClassField = false; 44 protected boolean takeFieldRef = false; 45 protected boolean takeArrayRef = false; 46 protected boolean takeCSE = false; 47 protected boolean takeRectArray = false; 48 protected boolean addColorTags = false; 49 50 protected void internalTransform(Body body, String phaseName, Map opts) 51 { 52 ABCOptions options = new ABCOptions( opts ); 53 if (options.with_all()) 54 { 55 takeClassField = true; 56 takeFieldRef = true; 57 takeArrayRef = true; 58 takeCSE = true; 59 takeRectArray = true; 60 } 61 else 62 { 63 takeClassField = options.with_classfield(); 64 takeFieldRef = options.with_fieldref(); 65 takeArrayRef = options.with_arrayref(); 66 takeCSE = options.with_cse(); 67 takeRectArray = options.with_rectarray(); 68 } 69 70 addColorTags = options.add_color_tags(); 71 72 { 73 SootMethod m = body.getMethod(); 74 75 Date start = new Date(); 76 77 if (Options.v().verbose()) 78 { 79 G.v().out.println("[abc] Analyzing array bounds information for "+m.getName()); 80 G.v().out.println("[abc] Started on "+start); 81 } 82 83 ArrayBoundsCheckerAnalysis analysis = null; 84 85 if (hasArrayLocals(body)) 86 { 87 analysis = 88 new ArrayBoundsCheckerAnalysis(body, 89 takeClassField, 90 takeFieldRef, 91 takeArrayRef, 92 takeCSE, 93 takeRectArray); 94 } 95 96 SootClass counterClass = null; 97 SootMethod increase = null; 98 99 if (options.profiling()) 100 { 101 counterClass = Scene.v().loadClassAndSupport("MultiCounter"); 102 increase = counterClass.getMethod("void increase(int)") ; 103 } 104 105 Chain units = body.getUnits(); 106 107 IntContainer zero = new IntContainer(0); 108 109 Iterator unitIt = units.snapshotIterator(); 110 111 while (unitIt.hasNext()) 112 { 113 Stmt stmt = (Stmt)unitIt.next(); 114 115 if (stmt.containsArrayRef()) 116 { 117 ArrayRef aref = (ArrayRef)stmt.getArrayRef(); 118 119 { 120 WeightedDirectedSparseGraph vgraph = 121 (WeightedDirectedSparseGraph)analysis.getFlowBefore(stmt); 122 123 int res = interpretGraph(vgraph, aref, stmt, zero); 124 125 boolean lowercheck = true; 126 boolean uppercheck = true; 127 128 if (res == 0) { 129 lowercheck = true; 130 uppercheck = true; 131 } 132 else if (res == 1) { 133 lowercheck = true; 134 uppercheck = false; 135 } 136 else if (res == 2) { 137 lowercheck = false; 138 uppercheck = true; 139 } 140 else if (res == 3) { 141 lowercheck = false; 142 uppercheck = false; 143 } 144 145 if (addColorTags){ 146 if (res == 0) { 147 aref.getIndexBox().addTag(new ColorTag(255, 0, 0, false, "ArrayCheckTag")); 148 } 149 else if (res == 1) { 150 aref.getIndexBox().addTag(new ColorTag(255, 248, 35, false, "ArrayCheckTag")); 151 } 152 else if (res == 2) { 153 aref.getIndexBox().addTag(new ColorTag(255, 163, 0, false, "ArrayCheckTag")); 154 } 155 else if (res == 3) { 156 aref.getIndexBox().addTag(new ColorTag(45, 255, 84, false, "ArrayCheckTag")); 157 } 158 SootClass bodyClass = body.getMethod().getDeclaringClass(); 159 Iterator keysIt = bodyClass.getTags().iterator(); 160 boolean keysAdded = false; 161 while (keysIt.hasNext()){ 162 Object next = keysIt.next(); 163 if (next instanceof KeyTag){ 164 if (((KeyTag)next).analysisType().equals("ArrayCheckTag")){ 165 keysAdded = true; 166 } 167 } 168 } 169 if (!keysAdded){ 170 bodyClass.addTag(new KeyTag(255, 0, 0, "ArrayBounds: Unsafe Lower and Unsafe Upper", "ArrayCheckTag")); 171 bodyClass.addTag(new KeyTag(255, 248, 35, "ArrayBounds: Unsafe Lower and Safe Upper", "ArrayCheckTag")); 172 bodyClass.addTag(new KeyTag(255, 163, 0, "ArrayBounds: Safe Lower and Unsafe Upper", "ArrayCheckTag")); 173 bodyClass.addTag(new KeyTag(45, 255, 84, "ArrayBounds: Safe Lower and Safe Upper", "ArrayCheckTag")); 174 } 175 } 176 177 227 228 if (options.profiling()) 229 { 230 int lowercounter = 0; 231 if (!lowercheck) 232 lowercounter = 1; 233 234 units.insertBefore (Jimple.v().newInvokeStmt( 235 Jimple.v().newStaticInvokeExpr(increase.makeRef(), 236 IntConstant.v(lowercounter))), stmt); 237 238 int uppercounter = 2; 239 if (!uppercheck) 240 uppercounter = 3; 241 242 units.insertBefore (Jimple.v().newInvokeStmt( 243 Jimple.v().newStaticInvokeExpr(increase.makeRef(), 244 IntConstant.v(uppercounter))), stmt) ; 245 246 261 } 262 else 263 { 264 Tag checkTag = new ArrayCheckTag(lowercheck, uppercheck); 265 stmt.addTag(checkTag); 266 } 267 } 268 } 269 } 270 271 if( addColorTags && takeRectArray ) { 272 RectangularArrayFinder raf = RectangularArrayFinder.v(); 273 for( Iterator vbIt = body.getUseAndDefBoxes().iterator(); vbIt.hasNext(); ) { 274 final ValueBox vb = (ValueBox) vbIt.next(); 275 Value v = vb.getValue(); 276 if( !(v instanceof Local) ) continue; 277 Type t = v.getType(); 278 if( !(t instanceof ArrayType) ) continue; 279 ArrayType at = (ArrayType) t; 280 if( at.numDimensions <= 1 ) continue; 281 vb.addTag( new ColorTag( 282 raf.isRectangular( new MethodLocal(m, (Local) v) ) 283 ? ColorTag.GREEN 284 : ColorTag.RED )); 285 } 286 } 287 288 Date finish = new Date(); 289 if (Options.v().verbose()) 290 { 291 long runtime = finish.getTime() - start.getTime(); 292 G.v().out.println("[abc] ended on "+finish 293 +". It took "+(runtime/60000)+" min. " 294 +((runtime%60000)/1000)+" sec."); 295 } 296 } 297 } 298 299 private boolean hasArrayLocals(Body body) 300 { 301 Iterator localIt = body.getLocals().iterator(); 302 303 while (localIt.hasNext()) 304 { 305 Local local = (Local)localIt.next(); 306 if (local.getType() instanceof ArrayType) 307 return true; 308 } 309 310 return false; 311 } 312 313 protected int interpretGraph(WeightedDirectedSparseGraph vgraph, ArrayRef aref, Stmt stmt, IntContainer zero){ 314 315 boolean lowercheck = true; 316 boolean uppercheck = true; 317 318 { 319 if (Options.v().debug()) 320 { 321 if (!vgraph.makeShortestPathGraph()) 322 { 323 G.v().out.println(stmt+" :"); 324 G.v().out.println(vgraph); 325 } 326 } 327 328 Value base = aref.getBase(); 329 Value index = aref.getIndex(); 330 331 if (index instanceof IntConstant) 332 { 333 int indexv = ((IntConstant)index).value; 334 335 if (vgraph.hasEdge(base, zero)) 336 { 337 int alength = vgraph.edgeWeight(base, zero); 338 339 if (-alength > indexv) 340 uppercheck = false; 341 } 342 343 if (indexv >= 0) 344 lowercheck = false; 345 } 346 else 347 { 348 if (vgraph.hasEdge(base, index)) 349 { 350 int upperdistance = vgraph.edgeWeight(base, index); 351 if (upperdistance < 0) 352 uppercheck = false; 353 } 354 355 if (vgraph.hasEdge(index, zero)) 356 { 357 int lowerdistance = vgraph.edgeWeight(index, zero); 358 359 if (lowerdistance <= 0) 360 lowercheck = false; 361 } 362 } 363 } 364 365 366 if (lowercheck && uppercheck) return 0; 367 else if (lowercheck && !uppercheck) return 1; 368 else if (!lowercheck && uppercheck) return 2; 369 else return 3; 370 } 371 } 372 | Popular Tags |