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.util.*; 32 import soot.tagkit.*; 33 import soot.toolkits.scalar.*; 34 import soot.toolkits.graph.*; 35 import java.io.*; 36 import java.util.*; 37 38 39 public class ClassFieldAnalysis 40 { 41 public ClassFieldAnalysis( Singletons.Global g ) {} 42 public static ClassFieldAnalysis v() { return G.v().soot_jimple_toolkits_annotation_arraycheck_ClassFieldAnalysis(); } 43 44 private boolean final_in = true; 45 private boolean private_in = true; 46 47 51 52 private Map classToFieldInfoMap = new HashMap(); 53 54 protected void internalTransform(SootClass c) 55 { 56 if (classToFieldInfoMap.containsKey(c)) 57 return; 58 59 60 Date start = new Date(); 61 if (Options.v().verbose()) 62 G.v().out.println("[] ClassFieldAnalysis started on : " 63 +start+" for " 64 +c.getPackageName()+c.getName()); 65 66 Hashtable fieldInfoTable = new Hashtable(); 67 classToFieldInfoMap.put(c, fieldInfoTable); 68 69 72 HashSet candidSet = new HashSet(); 73 74 int arrayTypeFieldNum = 0; 75 76 Iterator fieldIt = c.getFields().iterator(); 77 while(fieldIt.hasNext()) 78 { 79 SootField field = (SootField)fieldIt.next(); 80 int modifiers = field.getModifiers(); 81 82 Type type = field.getType(); 83 if (type instanceof ArrayType) 84 { 85 if ( (final_in 86 && ((modifiers & Modifier.FINAL) != 0)) 87 || (private_in 88 && ((modifiers & Modifier.PRIVATE) != 0))) 89 { 90 candidSet.add(field); 91 arrayTypeFieldNum ++; 92 } 93 } 94 } 95 96 if (arrayTypeFieldNum == 0) 97 { 98 if (Options.v().verbose()) 99 G.v().out.println("[] ClassFieldAnalysis finished with nothing"); 100 return; 101 } 102 103 104 105 107 108 109 113 114 Iterator methodIt = c.methodIterator(); 115 while (methodIt.hasNext()) 116 { 117 ScanMethod ((SootMethod)methodIt.next(), 118 candidSet, 119 fieldInfoTable); 120 } 121 122 Date finish = new Date(); 123 if (Options.v().verbose()) 124 { 125 long runtime=finish.getTime()-start.getTime(); 126 long mins=runtime/60000; 127 long secs=(runtime%60000)/1000; 128 G.v().out.println("[] ClassFieldAnalysis finished normally. " 129 +"It took "+mins+" mins and "+secs+" secs."); 130 } 131 } 132 133 public Object getFieldInfo(SootField field) 134 { 135 SootClass c = field.getDeclaringClass(); 136 137 Hashtable fieldInfoTable = (Hashtable)classToFieldInfoMap.get(c); 138 139 if (fieldInfoTable == null) 140 { 141 internalTransform(c); 142 fieldInfoTable = (Hashtable)classToFieldInfoMap.get(c); 143 } 144 145 return fieldInfoTable.get(field); 146 } 147 148 152 153 public void ScanMethod (SootMethod method, 154 Set candidates, 155 Hashtable fieldinfo) 156 { 157 if (!method.isConcrete()) 158 return; 159 160 Body body = method.retrieveActiveBody(); 161 162 if (body == null) 163 return; 164 165 166 { 167 boolean hasArrayLocal = false; 168 169 Chain locals = body.getLocals(); 170 171 Iterator localIt = locals.iterator(); 172 while (localIt.hasNext()) 173 { 174 Local local = (Local)localIt.next(); 175 Type type = local.getType(); 176 177 if (type instanceof ArrayType) 178 { 179 hasArrayLocal = true; 180 break; 181 } 182 } 183 184 if (!hasArrayLocal) 185 { 186 return; 187 } 188 } 189 190 191 192 193 194 197 198 HashMap stmtfield = new HashMap(); 199 200 { 201 Iterator unitIt = body.getUnits().iterator(); 202 while (unitIt.hasNext()) 203 { 204 Stmt stmt = (Stmt)unitIt.next(); 205 if (stmt.containsFieldRef()) 206 { 207 Value leftOp = ((AssignStmt)stmt).getLeftOp(); 208 if (leftOp instanceof FieldRef) 209 { 210 FieldRef fref = (FieldRef)leftOp; 211 SootField field = fref.getField(); 212 213 if (candidates.contains(field)) 214 stmtfield.put(stmt, field); 215 } 216 } 217 } 218 219 if (stmtfield.size() == 0) 220 { 221 return; 222 } 223 } 224 225 226 if (Options.v().verbose()) 227 { 228 G.v().out.println("[] ScanMethod for field started."); 229 } 230 231 232 { 233 UnitGraph g = new ExceptionalUnitGraph(body); 234 LocalDefs localDefs = new SmartLocalDefs(g, new SimpleLiveLocals(g)); 235 236 Set entries = stmtfield.entrySet(); 237 238 Iterator entryIt = entries.iterator(); 239 while (entryIt.hasNext()) 240 { 241 Map.Entry entry = (Map.Entry)entryIt.next(); 242 Stmt where = (Stmt)entry.getKey(); 243 SootField which = (SootField)entry.getValue(); 244 245 IntValueContainer length = new IntValueContainer(); 246 247 Value rightOp = ((AssignStmt)where).getRightOp(); 249 250 if (rightOp instanceof Local) 251 { 252 Local local = (Local)rightOp; 254 DefinitionStmt usestmt = (DefinitionStmt)where; 255 256 while (length.isBottom()) 257 { 258 List defs = localDefs.getDefsOfAt(local, usestmt); 259 if (defs.size() == 1) 260 { 261 usestmt = (DefinitionStmt)defs.get(0); 262 263 if (Options.v().debug()) 264 G.v().out.println(" "+usestmt); 265 266 Value tmp_rhs = usestmt.getRightOp(); 267 if ( (tmp_rhs instanceof NewArrayExpr) 268 ||(tmp_rhs instanceof NewMultiArrayExpr)) 269 { 270 Value size; 271 272 if (tmp_rhs instanceof NewArrayExpr) 273 size = ((NewArrayExpr)tmp_rhs).getSize(); 274 else 275 size = ((NewMultiArrayExpr)tmp_rhs).getSize(0); 276 277 if (size instanceof IntConstant) 278 length.setValue(((IntConstant)size).value); 279 else 280 if (size instanceof Local) 281 { 282 local = (Local)size; 283 284 286 continue; 287 } 288 else 289 length.setTop(); 290 } 291 else 292 if (tmp_rhs instanceof IntConstant) 293 { 294 length.setValue(((IntConstant)tmp_rhs).value); 295 } 296 else 297 if (tmp_rhs instanceof Local) 298 { 299 local = (Local)tmp_rhs; 301 302 continue; 303 } 304 else 305 length.setTop(); 306 } 307 else 308 length.setTop(); 309 } 310 } 311 else 312 313 continue; 314 315 IntValueContainer oldv = (IntValueContainer)fieldinfo.get(which); 316 317 318 if (length.isTop()) 319 { 320 if (oldv == null) 321 fieldinfo.put(which, length.dup()); 322 else 323 oldv.setTop(); 324 325 326 candidates.remove(which); 327 } 328 else 329 if (length.isInteger()) 330 { 331 if (oldv == null) 332 { 333 fieldinfo.put(which, length.dup()); 334 } 335 else 336 { 337 if (oldv.isInteger() 338 && oldv.getValue() != length.getValue()) 339 { 340 oldv.setTop(); 341 candidates.remove(which); 342 } 343 } 344 } 345 } 346 } 347 348 if (Options.v().verbose()) 349 { 350 G.v().out.println("[] ScanMethod finished."); 351 } 352 } 353 } 354 355 356 357 358 | Popular Tags |