1 19 20 25 26 package soot.jimple.toolkits.invoke; 27 import soot.options.*; 28 29 import soot.*; 30 import soot.jimple.*; 31 import soot.jimple.toolkits.scalar.*; 32 import soot.jimple.toolkits.callgraph.*; 33 import soot.toolkits.scalar.*; 34 import soot.toolkits.graph.*; 35 import java.util.*; 36 import soot.util.*; 37 38 39 public class StaticMethodBinder extends SceneTransformer 40 { 41 public StaticMethodBinder( Singletons.Global g ) {} 42 public static StaticMethodBinder v() { return G.v().soot_jimple_toolkits_invoke_StaticMethodBinder(); } 43 44 protected void internalTransform(String phaseName, Map opts) 45 { 46 Filter instanceInvokesFilter = new Filter( new InstanceInvokeEdgesPred() ); 47 SMBOptions options = new SMBOptions( opts ); 48 String modifierOptions = PhaseOptions.getString( opts, "allowed-modifier-changes"); 49 HashMap instanceToStaticMap = new HashMap(); 50 51 CallGraph cg = Scene.v().getCallGraph(); 52 Hierarchy hierarchy = Scene.v().getActiveHierarchy(); 53 54 Iterator classesIt = Scene.v().getApplicationClasses().iterator(); 55 while (classesIt.hasNext()) 56 { 57 SootClass c = (SootClass)classesIt.next(); 58 59 LinkedList methodsList = new LinkedList(); 60 for( Iterator it = c.methodIterator(); it.hasNext(); ) { 61 methodsList.add(it.next()); 62 } 63 64 while (!methodsList.isEmpty()) 65 { 66 SootMethod container = (SootMethod)methodsList.removeFirst(); 67 68 if (!container.isConcrete()) 69 continue; 70 71 if (!instanceInvokesFilter.wrap( cg.edgesOutOf(container) ).hasNext()) 72 continue; 73 74 JimpleBody b = (JimpleBody)container.getActiveBody(); 75 76 List unitList = new ArrayList(); unitList.addAll(b.getUnits()); 77 Iterator unitIt = unitList.iterator(); 78 79 while (unitIt.hasNext()) 80 { 81 Stmt s = (Stmt)unitIt.next(); 82 if (!s.containsInvokeExpr()) 83 continue; 84 85 86 InvokeExpr ie = (InvokeExpr)s.getInvokeExpr(); 87 88 if (ie instanceof StaticInvokeExpr || 89 ie instanceof SpecialInvokeExpr) 90 continue; 91 92 Iterator targets = new Targets( 93 instanceInvokesFilter.wrap( cg.edgesOutOf(s) ) ); 94 if( !targets.hasNext() ) continue; 95 SootMethod target = (SootMethod)targets.next(); 96 if( targets.hasNext() ) continue; 97 98 100 101 if (!AccessManager.ensureAccess(container, target, modifierOptions)) 102 continue; 103 104 if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete()) 105 continue; 106 107 if (target.getDeclaringClass()==Scene.v().getSootClass("java.lang.Object")) 109 continue; 110 111 boolean targetUsesThis = true; 114 if (!instanceToStaticMap.containsKey(target)) 115 { 116 List newParameterTypes = new ArrayList(); 117 if (targetUsesThis) 118 newParameterTypes.add 119 (RefType.v(target.getDeclaringClass().getName())); 120 121 newParameterTypes.addAll(target.getParameterTypes()); 122 123 String newName = target.getName() + "_static"; 125 while (target.getDeclaringClass().declaresMethod(newName, 126 newParameterTypes, 127 target.getReturnType())) 128 newName = newName + "_static"; 129 130 SootMethod ct = new SootMethod(newName, newParameterTypes, 131 target.getReturnType(), target.getModifiers() | Modifier.STATIC, 132 target.getExceptions()); 133 target.getDeclaringClass().addMethod(ct); 134 135 methodsList.addLast(ct); 136 137 ct.setActiveBody((Body)target.getActiveBody().clone()); 138 139 { 141 Iterator oldUnits = target.getActiveBody().getUnits().iterator(); 142 Iterator newUnits = ct.getActiveBody().getUnits().iterator(); 143 144 while (newUnits.hasNext()) 145 { 146 Stmt oldStmt, newStmt; 147 oldStmt = (Stmt)oldUnits.next(); 148 newStmt = (Stmt)newUnits.next(); 149 150 Iterator edges = cg.edgesOutOf( oldStmt ); 151 while( edges.hasNext() ) { 152 Edge e = (Edge) edges.next(); 153 cg.addEdge( new Edge( 154 ct, newStmt, e.tgt(), e.kind() ) ); 155 cg.removeEdge( e ); 156 } 157 } 158 } 159 160 { 165 Body newBody = ct.getActiveBody(); 166 167 Chain units = newBody.getUnits(); 168 169 Iterator unitsIt = newBody.getUnits().snapshotIterator(); 170 while (unitsIt.hasNext()) 171 { 172 Stmt st = (Stmt)unitsIt.next(); 173 if (st instanceof IdentityStmt) 174 { 175 IdentityStmt is = (IdentityStmt)st; 176 if (is.getRightOp() instanceof ThisRef) 177 { 178 if (targetUsesThis) 179 units.swapWith(st, Jimple.v().newIdentityStmt(is.getLeftOp(), 180 Jimple.v().newParameterRef(is.getRightOp().getType(), 0))); 181 else 182 { units.remove(st); break; } 183 } 184 else if (targetUsesThis) 185 { 186 if (is.getRightOp() instanceof ParameterRef) 187 { 188 ParameterRef ro = (ParameterRef)is.getRightOp(); 189 ro.setIndex(ro.getIndex() + 1); 190 } 191 } 192 } 193 } 194 195 } 196 197 instanceToStaticMap.put(target, ct); 198 } 199 200 SootMethod clonedTarget = (SootMethod)instanceToStaticMap.get(target); 201 Value thisToAdd = ((InstanceInvokeExpr)ie).getBase(); 202 203 if (options.insert_redundant_casts() && targetUsesThis) 205 { 206 SootClass localType, parameterType; 211 localType = ((RefType)((InstanceInvokeExpr)ie).getBase().getType()).getSootClass(); 212 parameterType = target.getDeclaringClass(); 213 214 if (localType.isInterface() || 215 hierarchy.isClassSuperclassOf(localType, parameterType)) 216 { 217 Local castee = Jimple.v().newLocal("__castee", parameterType.getType()); 218 b.getLocals().add(castee); 219 b.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, 220 Jimple.v().newCastExpr(((InstanceInvokeExpr)ie).getBase(), 221 parameterType.getType())), s); 222 thisToAdd = castee; 223 } 224 } 225 226 { 228 List newArgs = new ArrayList(); 229 if (targetUsesThis) 230 newArgs.add(thisToAdd); 231 newArgs.addAll(ie.getArgs()); 232 233 StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr 234 (clonedTarget.makeRef(), newArgs); 235 236 ValueBox ieBox = s.getInvokeExprBox(); 237 ieBox.setValue(sie); 238 239 cg.addEdge( new Edge( container, s, clonedTarget ) ); 240 } 241 242 if (options.insert_null_checks()) 244 { 245 boolean caught = TrapManager.isExceptionCaughtAt 246 (Scene.v().getSootClass("java.lang.NullPointerException"), s, b); 247 248 249 if (caught) 250 { 251 253 Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr)ie).getBase(), 254 NullConstant.v()), s); 255 256 b.getUnits().insertBefore(insertee, s); 257 258 ((IfStmt)insertee).setTarget(s); 260 261 ThrowManager.addThrowAfter(b, insertee); 262 } 263 else 264 { 265 Stmt throwPoint = 266 ThrowManager.getNullPointerExceptionThrower(b); 267 b.getUnits().insertBefore 268 (Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr)ie).getBase(), 269 NullConstant.v()), throwPoint), 270 s); 271 } 272 } 273 274 { 276 if (target.isSynchronized()) 277 { 278 clonedTarget.setModifiers(clonedTarget.getModifiers() & ~Modifier.SYNCHRONIZED); 279 SynchronizerManager.v().synchronizeStmtOn(s, b, (Local)((InstanceInvokeExpr)ie).getBase()); 280 } 281 } 282 283 LocalNameStandardizer.v().transform(b, phaseName + ".lns"); 285 } 286 } 287 } 288 } 289 290 private static boolean methodUsesThis(SootMethod m) 291 { 292 JimpleBody b = (JimpleBody)m.getActiveBody(); 293 ExceptionalUnitGraph g = new ExceptionalUnitGraph(b); 294 LocalDefs ld = new SmartLocalDefs(g, new SimpleLiveLocals(g)); 295 LocalUses lu = new SimpleLocalUses(g, ld); 296 297 { 299 Iterator unitsIt = b.getUnits().iterator(); 300 while (unitsIt.hasNext()) 301 { 302 Stmt s = (Stmt)unitsIt.next(); 303 if (s instanceof IdentityStmt && 304 ((IdentityStmt)s).getRightOp() instanceof ThisRef) 305 return lu.getUsesOf(s).size() != 0; 306 } 307 } 308 309 throw new RuntimeException ("couldn't find identityref!"); 310 } 311 } 312 313 314 | Popular Tags |