1 19 20 package soot.shimple; 21 22 import soot.*; 23 import soot.options.Options; 24 import soot.jimple.*; 25 import soot.shimple.internal.*; 26 import soot.util.*; 27 import soot.toolkits.scalar.ValueUnitPair; 28 import java.util.*; 29 import java.io.*; 30 31 50 public class Shimple 51 { 52 public static final String IFALIAS = "IfAlias"; 53 public static final String MAYMODIFY = "MayModify"; 54 public static final String PHI = "Phi"; 55 public static final String PI = "Pi"; 56 public static final String PHASE = "shimple"; 57 58 public Shimple(Singletons.Global g) {} 59 60 public static Shimple v() 61 { return G.v().soot_shimple_Shimple(); } 62 63 67 public ShimpleBody newBody(SootMethod m) 68 { 69 Map options = PhaseOptions.v().getPhaseOptions(PHASE); 70 return new ShimpleBody(m, options); 71 } 72 73 77 public ShimpleBody newBody(SootMethod m, Map options) 78 { 79 return new ShimpleBody(m, options); 80 } 81 82 86 public ShimpleBody newBody(Body b) 87 { 88 Map options = PhaseOptions.v().getPhaseOptions(PHASE); 89 return new ShimpleBody(b, options); 90 } 91 92 96 public ShimpleBody newBody(Body b, Map options) 97 { 98 return new ShimpleBody(b, options); 99 } 100 101 107 public PhiExpr newPhiExpr(Local leftLocal, List preds) 108 { 109 return new SPhiExpr(leftLocal, preds); 110 } 111 112 public PiExpr newPiExpr(Local local, Unit predicate, Object targetKey) 113 { 114 return new SPiExpr(local, predicate, targetKey); 115 } 116 117 123 public PhiExpr newPhiExpr(List args, List preds) 124 { 125 return new SPhiExpr(args, preds); 126 } 127 128 133 public JimpleBody newJimpleBody(ShimpleBody body) 134 { 135 return body.toJimpleBody(); 136 } 137 138 141 public static boolean isPhiExpr(Value value) 142 { 143 return (value instanceof PhiExpr); 144 } 145 146 149 public static boolean isPhiNode(Unit unit) 150 { 151 return 152 getPhiExpr(unit) == null ? false : true; 153 } 154 155 159 public static PhiExpr getPhiExpr(Unit unit) 160 { 161 if(!(unit instanceof AssignStmt)) 162 return null; 163 164 Value right = ((AssignStmt)unit).getRightOp(); 165 166 if(isPhiExpr(right)) 167 return (PhiExpr) right; 168 169 return null; 170 } 171 172 public static boolean isPiExpr(Value value) 173 { 174 return (value instanceof PiExpr); 175 } 176 177 public static boolean isPiNode(Unit unit) 178 { 179 return getPiExpr(unit) == null ? false : true; 180 } 181 182 public static PiExpr getPiExpr(Unit unit) 183 { 184 if(!(unit instanceof AssignStmt)) 185 return null; 186 187 Value right = ((AssignStmt)unit).getRightOp(); 188 189 if(isPiExpr(right)) 190 return (PiExpr) right; 191 192 return null; 193 } 194 195 199 public static Local getLhsLocal(Unit unit) 200 { 201 if(!(unit instanceof AssignStmt)) 202 return null; 203 204 Value right = ((AssignStmt)unit).getRightOp(); 205 206 if(right instanceof ShimpleExpr){ 207 Value left = ((AssignStmt)unit).getLeftOp(); 208 return (Local) left; 209 } 210 211 return null; 212 } 213 214 225 public static void redirectToPreds(Body body, Unit remove) 226 { 227 boolean debug = Options.v().debug(); 228 if(body instanceof ShimpleBody) 229 debug |= ((ShimpleBody)body).getOptions().debug(); 230 231 Chain units = body.getUnits(); 232 233 234 235 Iterator pointersIt = remove.getBoxesPointingToThis().iterator(); 236 237 if(!pointersIt.hasNext()) 238 return; 239 240 while(pointersIt.hasNext()){ 241 UnitBox pointer = (UnitBox) pointersIt.next(); 242 243 if(!pointer.isBranchTarget()) 247 break; 248 249 if(!pointersIt.hasNext()) 251 return; 252 } 253 254 255 256 Set preds = new HashSet(); 257 Set phis = new HashSet(); 258 259 if(!remove.equals(units.getFirst())){ 261 Unit possiblePred = (Unit) units.getPredOf(remove); 262 if(possiblePred.fallsThrough()) 263 preds.add(possiblePred); 264 } 265 266 Iterator unitsIt = units.iterator(); 268 while(unitsIt.hasNext()){ 269 Unit unit = (Unit) unitsIt.next(); 270 Iterator targetsIt = unit.getUnitBoxes().iterator(); 271 while(targetsIt.hasNext()){ 272 UnitBox targetBox = (UnitBox) targetsIt.next(); 273 274 if(remove.equals(targetBox.getUnit())){ 275 if(targetBox.isBranchTarget()) 276 preds.add(unit); 277 else{ 278 PhiExpr phiExpr = Shimple.getPhiExpr(unit); 279 if(phiExpr != null) 280 phis.add(phiExpr); 281 } 282 } 283 } 284 } 285 286 287 288 if(phis.size() == 0){ 289 if(debug) 290 G.v().out.println("Warning: Orphaned UnitBoxes to " + remove + "? Shimple.redirectToPreds is giving up."); 291 return; 292 } 293 294 if(preds.size() == 0){ 295 if(debug) 296 G.v().out.println("Warning: Shimple.redirectToPreds couldn't find any predecessors for " + remove + " in " + body.getMethod() + "."); 297 298 if(!remove.equals(units.getFirst())){ 299 Unit pred = (Unit) units.getPredOf(remove); 300 if(debug) 301 G.v().out.println("Warning: Falling back to immediate chain predecessor: " + pred + "."); 302 preds.add(pred); 303 } 304 else if(!remove.equals(units.getLast())){ 305 Unit succ = (Unit) units.getSuccOf(remove); 306 if(debug) 307 G.v().out.println("Warning: Falling back to immediate chain successor: " + succ + "."); 308 preds.add(succ); 309 } 310 else 311 throw new RuntimeException ("Assertion failed."); 312 } 313 314 315 316 317 Iterator phiIt = phis.iterator(); 318 while(phiIt.hasNext()){ 319 PhiExpr phiExpr = (PhiExpr) phiIt.next(); 320 ValueUnitPair argBox = phiExpr.getArgBox(remove); 321 322 if(argBox == null) 323 throw new RuntimeException ("Assertion failed."); 324 325 Value arg = argBox.getValue(); 327 phiExpr.removeArg(argBox); 328 329 Iterator predsIt = preds.iterator(); 331 while(predsIt.hasNext()){ 332 Unit pred = (Unit) predsIt.next(); 333 phiExpr.addArg(arg, pred); 334 } 335 } 336 } 337 338 345 public static void redirectPointers(Unit oldLocation, Unit newLocation) 346 { 347 List boxesPointing = oldLocation.getBoxesPointingToThis(); 348 349 Object [] boxes = boxesPointing.toArray(); 351 352 for(int i = 0; i < boxes.length; i++){ 353 UnitBox box = (UnitBox) boxes[i]; 354 355 if(box.getUnit() != oldLocation) 356 throw new RuntimeException ("Something weird's happening"); 357 358 if(!box.isBranchTarget()) 359 box.setUnit(newLocation); 360 } 361 } 362 } 363 | Popular Tags |