1 19 20 package soot.dava.toolkits.base.misc; 21 22 import soot.*; 23 import soot.util.*; 24 import java.util.*; 25 import soot.jimple.*; 26 import soot.jimple.toolkits.callgraph.*; 27 28 public class ThrowFinder 29 { 30 public ThrowFinder( Singletons.Global g ) {} 31 public static ThrowFinder v() { return G.v().soot_dava_toolkits_base_misc_ThrowFinder(); } 32 33 private HashSet registeredMethods; 34 private HashMap protectionSet; 35 36 public void find() 37 { 38 G.v().out.print( "Verifying exception handling.. "); 39 40 registeredMethods = new HashSet(); 41 protectionSet = new HashMap(); 42 43 CallGraph cg; 44 if( Scene.v().hasCallGraph() ) { 45 cg = Scene.v().getCallGraph(); 46 } else { 47 new CallGraphBuilder().build(); 48 cg = Scene.v().getCallGraph(); 49 Scene.v().releaseCallGraph(); 50 } 51 52 IterableSet worklist = new IterableSet(); 53 54 G.v().out.print( "\b. "); 55 G.v().out.flush(); 56 57 58 Iterator classIt = Scene.v().getApplicationClasses().iterator(); 60 while (classIt.hasNext()) { 61 Iterator methodIt = ((SootClass) classIt.next()).methodIterator(); 62 while (methodIt.hasNext()) { 63 SootMethod m = (SootMethod) methodIt.next(); 64 65 register_AreasOfProtection( m); 66 worklist.add( m); 67 } 68 } 69 70 71 HashMap 73 subClassSet = new HashMap(), 74 superClassSet = new HashMap(); 75 76 HashSet applicationClasses = new HashSet(); 77 applicationClasses.addAll( Scene.v().getApplicationClasses()); 78 79 classIt = Scene.v().getApplicationClasses().iterator(); 80 while (classIt.hasNext()) { 81 SootClass c = (SootClass) classIt.next(); 82 83 IterableSet superClasses = (IterableSet) superClassSet.get( c); 84 if (superClasses == null) { 85 superClasses = new IterableSet(); 86 superClassSet.put( c, superClasses); 87 } 88 89 IterableSet subClasses = (IterableSet) subClassSet.get( c); 90 if (subClasses == null) { 91 subClasses = new IterableSet(); 92 subClassSet.put( c, subClasses); 93 } 94 95 if (c.hasSuperclass()) { 96 SootClass superClass = c.getSuperclass(); 97 98 IterableSet superClassSubClasses = (IterableSet) subClassSet.get( superClass); 99 if (superClassSubClasses == null) { 100 superClassSubClasses = new IterableSet(); 101 subClassSet.put( superClass, superClassSubClasses); 102 } 103 superClassSubClasses.add( c); 104 superClasses.add( superClass); 105 } 106 107 Iterator interfaceIt = c.getInterfaces().iterator(); 108 while (interfaceIt.hasNext()) { 109 SootClass interfaceClass = (SootClass) interfaceIt.next(); 110 111 IterableSet interfaceClassSubClasses = (IterableSet) subClassSet.get( interfaceClass); 112 if (interfaceClassSubClasses == null) { 113 interfaceClassSubClasses = new IterableSet(); 114 subClassSet.put( interfaceClass, interfaceClassSubClasses); 115 } 116 interfaceClassSubClasses.add( c); 117 superClasses.add( interfaceClass); 118 } 119 } 120 121 HashMap agreementMethodSet = new HashMap(); 123 124 Iterator worklistIt = worklist.iterator(); 126 while (worklistIt.hasNext()) { 127 SootMethod m = (SootMethod) worklistIt.next(); 128 129 if (!m.isAbstract() && !m.isNative() ) { 130 131 List exceptionList = m.getExceptions(); 132 IterableSet exceptionSet = new IterableSet( exceptionList); 133 boolean changed = false; 134 135 Iterator it = m.retrieveActiveBody().getUnits().iterator(); 136 while (it.hasNext()) { 137 Unit u = (Unit) it.next(); 138 HashSet handled = (HashSet) protectionSet.get(u); 139 140 if (u instanceof ThrowStmt) { 141 Type t = ((ThrowStmt) u).getOp().getType(); 142 143 if (t instanceof RefType) { 144 SootClass c = ((RefType) t).getSootClass(); 145 146 if ((handled_Exception( handled, c) == false) && (exceptionSet.contains( c) == false)) { 147 exceptionSet.add( c); 148 changed = true; 149 } 150 } 151 } 152 } 153 154 it = cg.edgesOutOf(m); 155 while (it.hasNext()) { 156 Edge e = (Edge) it.next(); 157 Stmt callSite = e.srcStmt(); 158 if( callSite == null ) continue; 159 HashSet handled = (HashSet) protectionSet.get( callSite); 160 161 SootMethod target = e.tgt(); 162 163 Iterator exceptionIt = target.getExceptions().iterator(); 164 while (exceptionIt.hasNext()) { 165 SootClass exception = (SootClass) exceptionIt.next(); 166 167 if ((handled_Exception( handled, exception) == false) && (exceptionSet.contains( exception) == false)) { 168 exceptionSet.add( exception); 169 changed = true; 170 } 171 } 172 } 173 174 if (changed) { 175 exceptionList.clear(); 176 exceptionList.addAll( exceptionSet); 177 } 178 } 179 180 find_OtherMethods( m, agreementMethodSet, subClassSet, applicationClasses); 182 find_OtherMethods( m, agreementMethodSet, superClassSet, applicationClasses); 183 } 184 185 while (worklist.isEmpty() == false) { 187 188 SootMethod m = (SootMethod) worklist.getFirst(); 189 worklist.removeFirst(); 190 191 IterableSet agreementMethods = (IterableSet) agreementMethodSet.get( m); 192 if (agreementMethods != null) { 193 Iterator amit = agreementMethods.iterator(); 194 while (amit.hasNext()) { 195 SootMethod otherMethod = (SootMethod) amit.next(); 196 197 List otherExceptionsList = otherMethod.getExceptions(); 198 IterableSet otherExceptionSet = new IterableSet( otherExceptionsList); 199 boolean changed = false; 200 201 Iterator exceptionIt = m.getExceptions().iterator(); 202 while (exceptionIt.hasNext()) { 203 SootClass exception = (SootClass) exceptionIt.next(); 204 205 if (otherExceptionSet.contains( exception) == false) { 206 otherExceptionSet.add( exception); 207 changed = true; 208 } 209 } 210 211 if (changed) { 212 otherExceptionsList.clear(); 213 otherExceptionsList.addAll( otherExceptionSet); 214 215 if (worklist.contains( otherMethod) == false) 216 worklist.addLast( otherMethod); 217 } 218 } 219 } 220 221 Iterator it = cg.edgesOutOf(m); 222 while (it.hasNext()) { 223 Edge e = (Edge) it.next(); 224 Stmt callingSite = e.srcStmt(); 225 if( callingSite == null ) continue; 226 SootMethod callingMethod = e.src(); 227 List exceptionList = callingMethod.getExceptions(); 228 IterableSet exceptionSet = new IterableSet( exceptionList); 229 HashSet handled = (HashSet) protectionSet.get( callingSite); 230 boolean changed = false; 231 232 Iterator exceptionIt = m.getExceptions().iterator(); 233 while (exceptionIt.hasNext()) { 234 SootClass exception = (SootClass) exceptionIt.next(); 235 236 if ((handled_Exception( handled, exception) == false) && (exceptionSet.contains( exception) == false)) { 237 exceptionSet.add( exception); 238 changed = true; 239 } 240 } 241 242 if (changed) { 243 exceptionList.clear(); 244 exceptionList.addAll( exceptionSet); 245 246 if (worklist.contains( callingMethod) == false) 247 worklist.addLast( callingMethod); 248 } 249 } 250 } 251 252 G.v().out.println(); 253 G.v().out.flush(); 254 } 255 256 257 private void find_OtherMethods( SootMethod startingMethod, HashMap methodMapping, HashMap classMapping, HashSet applicationClasses) 258 { 259 IterableSet worklist = (IterableSet) ((IterableSet) classMapping.get( startingMethod.getDeclaringClass())).clone(); 260 261 HashSet touchSet = new HashSet(); 262 touchSet.addAll( worklist); 263 264 String signature = startingMethod.getSubSignature(); 265 266 while (worklist.isEmpty() == false) { 267 SootClass currentClass = (SootClass) worklist.getFirst(); 268 worklist.removeFirst(); 269 270 if (applicationClasses.contains( currentClass) == false) 271 continue; 272 273 if (currentClass.declaresMethod( signature)) { 274 IterableSet otherMethods = (IterableSet) methodMapping.get( startingMethod); 275 if (otherMethods == null) { 276 otherMethods = new IterableSet(); 277 methodMapping.put( startingMethod, otherMethods); 278 } 279 280 otherMethods.add( currentClass.getMethod( signature)); 281 } 282 283 else { 284 IterableSet otherClasses = (IterableSet) classMapping.get( currentClass); 285 if (otherClasses != null) { 286 Iterator ocit = otherClasses.iterator(); 287 while (ocit.hasNext()) { 288 SootClass otherClass = (SootClass) ocit.next(); 289 290 if (touchSet.contains( otherClass) == false) { 291 worklist.addLast( otherClass); 292 touchSet.add( otherClass); 293 } 294 } 295 } 296 } 297 } 298 } 299 300 private void register_AreasOfProtection( SootMethod m) 301 { 302 if (registeredMethods.contains( m)) 303 return; 304 305 registeredMethods.add( m); 306 307 if (m.hasActiveBody() == false) 308 return; 309 310 Body b = (Body) m.getActiveBody(); 311 Chain stmts = b.getUnits(); 312 313 Iterator trapIt = b.getTraps().iterator(); 314 while (trapIt.hasNext()) { 315 Trap t = (Trap) trapIt.next(); 316 SootClass exception = t.getException(); 317 318 Iterator sit = stmts.iterator( t.getBeginUnit(), stmts.getPredOf( t.getEndUnit())); 319 while (sit.hasNext()) { 320 Stmt s = (Stmt) sit.next(); 321 322 HashSet handled = null; 323 if ((handled = (HashSet) protectionSet.get( s)) == null) { 324 handled = new HashSet(); 325 protectionSet.put( s, handled); 326 } 327 328 if (handled.contains( exception) == false) 329 handled.add( exception); 330 } 331 } 332 } 333 334 private boolean handled_Exception( HashSet handledExceptions, SootClass c) 335 { 336 SootClass thrownException = c; 337 338 if (is_HandledByRuntime( thrownException)) 339 return true; 340 341 if (handledExceptions == null) 342 return false; 343 344 while (true) { 345 if (handledExceptions.contains( thrownException)) 346 return true; 347 348 if (thrownException.hasSuperclass() == false) 349 return false; 350 351 thrownException = thrownException.getSuperclass(); 352 } 353 } 354 355 private boolean is_HandledByRuntime( SootClass c) 356 { 357 SootClass 358 thrownException = c, 359 runtimeException = Scene.v().getSootClass( "java.lang.RuntimeException"), 360 error = Scene.v().getSootClass( "java.lang.Error"); 361 362 while (true) { 363 if ((thrownException == runtimeException) || (thrownException == error)) 364 return true; 365 366 if (thrownException.hasSuperclass() == false) 367 return false; 368 369 thrownException = thrownException.getSuperclass(); 370 } 371 } 372 } 373 | Popular Tags |