1 19 20 25 26 27 28 29 30 package soot; 31 32 import soot.tagkit.*; 33 import soot.baf.*; 34 import soot.jimple.*; 35 import soot.toolkits.graph.*; 36 import soot.*; 37 import soot.util.*; 38 import java.util.*; 39 import java.io.*; 40 import soot.toolkits.scalar.*; 41 import soot.toolkits.exceptions.*; 42 import soot.options.*; 43 44 45 56 public abstract class Body extends AbstractHost implements Serializable 57 { 58 59 protected transient SootMethod method = null; 60 61 62 protected Chain localChain = new HashChain(); 63 64 65 protected Chain trapChain = new HashChain(); 66 67 68 protected PatchingChain unitChain = new PatchingChain(new HashChain()); 69 70 71 abstract public Object clone(); 72 73 76 protected Body(SootMethod m) 77 { 78 this.method = m; 79 } 80 81 82 protected Body() 83 { 84 } 85 86 90 public SootMethod getMethod() 91 { 92 if(method == null) 93 throw new RuntimeException ("no method associated w/ body"); 94 return method; 95 } 96 97 98 103 public void setMethod(SootMethod method) 104 { 105 this.method = method; 106 } 107 108 109 public int getLocalCount() 110 { 111 return localChain.size(); 112 } 113 114 115 public Map importBodyContentsFrom(Body b) 116 { 117 HashMap bindings = new HashMap(); 118 119 Iterator it = b.getUnits().iterator(); 120 121 while(it.hasNext()) { 123 Unit original = (Unit) it.next(); 124 Unit copy = (Unit) original.clone(); 125 126 copy.addAllTagsOf(original); 127 128 unitChain.addLast(copy); 130 131 bindings.put(original, copy); 135 } 136 137 it = b.getTraps().iterator(); 139 while(it.hasNext()) { 140 Trap original = (Trap) it.next(); 141 Trap copy = (Trap) original.clone(); 142 143 trapChain.addLast(copy); 145 146 bindings.put(original, copy); 148 } 149 150 151 it = b.getLocals().iterator(); 153 while(it.hasNext()) { 154 Value original = (Value) it.next(); 155 Value copy = (Value) original.clone(); 156 157 localChain.addLast(copy); 159 160 bindings.put(original, copy); 162 } 163 164 165 166 it = getAllUnitBoxes().iterator(); 168 while(it.hasNext()) { 169 UnitBox box = (UnitBox) it.next(); 170 Unit newObject, oldObject = box.getUnit(); 171 172 if( (newObject = (Unit) bindings.get(oldObject)) != null ) 175 box.setUnit(newObject); 176 177 } 178 179 180 181 it = getUseBoxes().iterator(); 183 while(it.hasNext()) { 184 ValueBox vb = (ValueBox) it.next(); 185 if(vb.getValue() instanceof Local) 186 vb.setValue((Value) bindings.get(vb.getValue())); 187 } 188 it = getDefBoxes().iterator(); 189 while(it.hasNext()) { 190 ValueBox vb = (ValueBox) it.next(); 191 if(vb.getValue() instanceof Local) 192 vb.setValue((Value) bindings.get(vb.getValue())); 193 } 194 return bindings; 195 } 196 197 198 public void validate() 199 { 200 validateLocals(); 202 validateTraps(); 203 validateUnitBoxes(); 204 if (Options.v().debug() || Options.v().validate()) { 205 validateUses(); 206 validateValueBoxes(); 207 checkInit(); 208 checkTypes(); 209 checkLocals(); 210 } 211 } 212 213 214 public void validateValueBoxes() 215 { 216 List l = getUseAndDefBoxes(); 217 for( int i = 0; i < l.size(); i++ ) { 218 for( int j = 0; j < l.size(); j++ ) { 219 if( i == j ) continue; 220 if( l.get(i) == l.get(j) ) { 221 System.err.println("Aliased value box : "+l.get(i)+" in "+getMethod()); 222 for( Iterator uIt = getUnits().iterator(); uIt.hasNext(); ) { 223 final Unit u = (Unit) uIt.next(); 224 System.err.println(""+u); 225 } 226 throw new RuntimeException ("Aliased value box : "+l.get(i)+" in "+getMethod()); 227 } 228 } 229 } 230 } 231 232 233 public void validateLocals() 234 { 235 Iterator it; 236 it = getUseBoxes().iterator(); 237 while(it.hasNext()){ 238 validateLocal( (ValueBox) it.next() ); 239 } 240 it = getDefBoxes().iterator(); 241 while(it.hasNext()){ 242 validateLocal( (ValueBox) it.next() ); 243 } 244 } 245 private void validateLocal( ValueBox vb ) { 246 Value value; 247 if( (value = vb.getValue()) instanceof Local) { 248 if(!localChain.contains(value)) 250 throw new RuntimeException ("Local not in chain : "+value+" in "+getMethod()); 251 } 252 } 253 254 255 public void validateTraps() 256 { 257 Iterator it = getTraps().iterator(); 258 while (it.hasNext()) 259 { 260 Trap t = (Trap)it.next(); 261 if (!unitChain.contains(t.getBeginUnit())) 262 throw new RuntimeException ("begin not in chain"+" in "+getMethod()); 263 264 if (!unitChain.contains(t.getEndUnit())) 265 throw new RuntimeException ("end not in chain"+" in "+getMethod()); 266 267 if (!unitChain.contains(t.getHandlerUnit())) 268 throw new RuntimeException ("handler not in chain"+" in "+getMethod()); 269 } 270 } 271 272 273 public void validateUnitBoxes() 274 { 275 Iterator it = getAllUnitBoxes().iterator(); 276 while (it.hasNext()) 277 { 278 UnitBox ub = (UnitBox)it.next(); 279 if (!unitChain.contains(ub.getUnit())) 280 throw new RuntimeException 281 ("Unitbox points outside unitChain! to unit : "+ub.getUnit()+" in "+getMethod()); 282 } 283 } 284 285 286 public void validateUses() 287 { 288 UnitGraph g = new ExceptionalUnitGraph(this); 289 LocalDefs ld = new SmartLocalDefs(g, new SimpleLiveLocals(g)); 290 291 Iterator unitsIt = getUnits().iterator(); 292 while (unitsIt.hasNext()) 293 { 294 Unit u = (Unit) unitsIt.next(); 295 Iterator useBoxIt = u.getUseBoxes().iterator(); 296 while (useBoxIt.hasNext()) 297 { 298 Value v = ((ValueBox)useBoxIt.next()).getValue(); 299 if (v instanceof Local) 300 { 301 List l = ld.getDefsOfAt((Local)v, u); 304 if (l.size() == 0){ 305 for( Iterator uuIt = getUnits().iterator(); uuIt.hasNext(); ) { 306 final Unit uu = (Unit) uuIt.next(); 307 System.err.println(""+uu); 308 } 309 throw new RuntimeException ("no defs for value: "+v+"!"+" in "+getMethod()); 310 } 311 } 312 } 313 } 314 } 315 316 317 public Chain getLocals() {return localChain;} 318 319 320 public Chain getTraps() {return trapChain;} 321 322 323 public Local getThisLocal() 324 { 325 Iterator unitsIt = getUnits().iterator(); 326 327 while (unitsIt.hasNext()) 328 { 329 Stmt s = (Stmt)unitsIt.next(); 330 if (s instanceof IdentityStmt && 331 ((IdentityStmt)s).getRightOp() instanceof ThisRef) 332 return (Local)(((IdentityStmt)s).getLeftOp()); 333 } 334 335 throw new RuntimeException ("couldn't find identityref!"+" in "+getMethod()); 336 } 337 338 339 public Local getParameterLocal(int i) 340 { 341 Iterator unitsIt = getUnits().iterator(); 342 while (unitsIt.hasNext()) 343 { 344 Stmt s = (Stmt)unitsIt.next(); 345 if (s instanceof IdentityStmt && 346 ((IdentityStmt)s).getRightOp() instanceof ParameterRef) 347 { 348 IdentityStmt is = (IdentityStmt)s; 349 ParameterRef pr = (ParameterRef)is.getRightOp(); 350 if (pr.getIndex() == i) 351 return (Local)is.getLeftOp(); 352 } 353 } 354 355 throw new RuntimeException ("couldn't find parameterref!"+" in "+getMethod()); 356 } 357 358 370 public PatchingChain getUnits() 371 { 372 return unitChain; 373 } 374 375 392 public List getAllUnitBoxes() 393 { 394 ArrayList unitBoxList = new ArrayList(); 395 { 396 Iterator it = unitChain.iterator(); 397 while(it.hasNext()) { 398 Unit item = (Unit) it.next(); 399 unitBoxList.addAll(item.getUnitBoxes()); 400 } 401 } 402 403 { 404 Iterator it = trapChain.iterator(); 405 while(it.hasNext()) { 406 Trap item = (Trap) it.next(); 407 unitBoxList.addAll(item.getUnitBoxes()); 408 } 409 } 410 411 { 412 Iterator it = getTags().iterator(); 413 while(it.hasNext()) { 414 Tag t = (Tag) it.next(); 415 if( t instanceof CodeAttribute) 416 unitBoxList.addAll(((CodeAttribute) t).getUnitBoxes()); 417 } 418 } 419 420 return unitBoxList; 421 } 422 423 443 public List getUnitBoxes(boolean branchTarget) 444 { 445 ArrayList unitBoxList = new ArrayList(); 446 { 447 Iterator it = unitChain.iterator(); 448 while(it.hasNext()) { 449 Unit item = (Unit) it.next(); 450 if(branchTarget){ 451 if(item.branches()) 452 unitBoxList.addAll(item.getUnitBoxes()); 453 } 454 else{ 455 if(!item.branches()) 456 unitBoxList.addAll(item.getUnitBoxes()); 457 } 458 } 459 } 460 461 { 462 Iterator it = trapChain.iterator(); 463 while(it.hasNext()) { 464 Trap item = (Trap) it.next(); 465 unitBoxList.addAll(item.getUnitBoxes()); 466 } 467 } 468 469 { 470 Iterator it = getTags().iterator(); 471 while(it.hasNext()) { 472 Tag t = (Tag) it.next(); 473 if( t instanceof CodeAttribute) 474 unitBoxList.addAll(((CodeAttribute) t).getUnitBoxes()); 475 } 476 } 477 478 return unitBoxList; 479 } 480 481 482 495 public List getUseBoxes() 496 { 497 ArrayList useBoxList = new ArrayList(); 498 499 Iterator it = unitChain.iterator(); 500 while(it.hasNext()) { 501 Unit item = (Unit) it.next(); 502 useBoxList.addAll(item.getUseBoxes()); 503 } 504 return useBoxList; 505 } 506 507 508 520 public List getDefBoxes() 521 { 522 ArrayList defBoxList = new ArrayList(); 523 524 Iterator it = unitChain.iterator(); 525 while(it.hasNext()) { 526 Unit item = (Unit) it.next(); 527 defBoxList.addAll(item.getDefBoxes()); 528 } 529 return defBoxList; 530 } 531 532 543 public List getUseAndDefBoxes() 544 { 545 ArrayList useAndDefBoxList = new ArrayList(); 546 547 Iterator it = unitChain.iterator(); 548 while(it.hasNext()) { 549 Unit item = (Unit) it.next(); 550 useAndDefBoxList.addAll(item.getUseBoxes()); 551 useAndDefBoxList.addAll(item.getDefBoxes()); 552 } 553 return useAndDefBoxList; 554 } 555 556 private void checkLocals() { 557 Chain locals=getLocals(); 558 559 Iterator it=locals.iterator(); 560 while(it.hasNext()) { 561 Local l=(Local) it.next(); 562 if(l.getType() instanceof VoidType) 563 throw new RuntimeException ("Local "+l+" in "+method+" defined with void type"); 564 } 565 } 566 567 private void checkTypes() { 568 Chain units=getUnits(); 569 570 Iterator it=units.iterator(); 571 while(it.hasNext()) { 572 Stmt stmt=(Stmt) (it.next()); 573 InvokeExpr iexpr=null; 574 575 String errorSuffix=" at "+stmt+" in "+getMethod(); 576 577 if(stmt instanceof DefinitionStmt) { 578 DefinitionStmt astmt=(DefinitionStmt) stmt; 579 if( !(astmt.getRightOp() instanceof CaughtExceptionRef ) ) { 580 Type leftType=Type.toMachineType(astmt.getLeftOp().getType()); 581 Type rightType=Type.toMachineType(astmt.getRightOp().getType()); 582 583 checkCopy(leftType,rightType,errorSuffix); 584 if(astmt.getRightOp() instanceof InvokeExpr) 585 iexpr=(InvokeExpr) (astmt.getRightOp()); 586 } 587 } 588 589 if(stmt instanceof InvokeStmt) iexpr=((InvokeStmt) stmt).getInvokeExpr(); 590 591 if(iexpr!=null) { 592 SootMethodRef called=iexpr.getMethodRef(); 593 594 if(iexpr instanceof InstanceInvokeExpr) { 595 InstanceInvokeExpr iiexpr=(InstanceInvokeExpr) iexpr; 596 checkCopy(called.declaringClass().getType(), 597 iiexpr.getBase().getType(), 598 " in receiver of call"+errorSuffix); 599 } 600 601 if(called.parameterTypes().size() != iexpr.getArgCount()) 602 throw new RuntimeException ("Warning: Argument count doesn't match up with signature in call"+errorSuffix+" in "+getMethod()); 603 else 604 for(int i=0;i<iexpr.getArgCount();i++) 605 checkCopy(Type.toMachineType(called.parameterType(i)), 606 Type.toMachineType(iexpr.getArg(i).getType()), 607 " in argument "+i+" of call"+errorSuffix); 608 } 609 } 610 } 611 612 private void checkCopy(Type leftType,Type rightType,String errorSuffix) { 613 if(leftType instanceof PrimType || rightType instanceof PrimType) { 614 if(leftType instanceof IntType && rightType instanceof IntType) return; 615 if(leftType instanceof LongType && rightType instanceof LongType) return; 616 if(leftType instanceof FloatType && rightType instanceof FloatType) return; 617 if(leftType instanceof DoubleType && rightType instanceof DoubleType) return; 618 throw new RuntimeException ("Warning: Bad use of primitive type"+errorSuffix+" in "+getMethod()); 619 } 620 621 if(rightType instanceof NullType) return; 622 if(leftType instanceof RefType && 623 ((RefType) leftType).getClassName().equals("java.lang.Object")) return; 624 625 if(leftType instanceof ArrayType || rightType instanceof ArrayType) { 626 if(leftType instanceof ArrayType && rightType instanceof ArrayType) return; 627 628 throw new RuntimeException ("Warning: Bad use of array type"+errorSuffix+" in "+getMethod()); 629 } 630 631 if(leftType instanceof RefType && rightType instanceof RefType) { 632 SootClass leftClass=((RefType) leftType).getSootClass(); 633 SootClass rightClass=((RefType) rightType).getSootClass(); 634 635 if(leftClass.isInterface()) { 636 if(rightClass.isInterface()) { 637 if(!(leftClass.getName().equals(rightClass.getName()) || 638 Scene.v().getActiveHierarchy().isInterfaceSubinterfaceOf(rightClass,leftClass))) 639 throw new RuntimeException ("Warning: Bad use of interface type"+errorSuffix+" in "+getMethod()); 640 } else { 641 } 643 } else { 644 if(rightClass.isInterface()) { 645 throw new RuntimeException ("Warning: trying to use interface type where non-Object class expected" 646 +errorSuffix+" in "+getMethod()); 647 } else { 648 if(!Scene.v().getActiveHierarchy().isClassSubclassOfIncluding(rightClass,leftClass)) 649 throw new RuntimeException ("Warning: Bad use of class type"+errorSuffix+" in "+getMethod()); 650 } 651 } 652 return; 653 } 654 throw new RuntimeException ("Warning: Bad types"+errorSuffix+" in "+getMethod()); 655 } 656 657 public void checkInit() { 658 Chain units=getUnits(); 659 ExceptionalUnitGraph g = new ExceptionalUnitGraph 660 (this, PedanticThrowAnalysis.v(), false); 661 662 Scene.v().releaseActiveHierarchy(); 664 665 InitAnalysis analysis=new InitAnalysis(g); 666 Iterator it=units.iterator(); 667 while(it.hasNext()) { 668 Stmt s=(Stmt) (it.next()); 669 FlowSet init=(FlowSet) analysis.getFlowBefore(s); 670 List uses=s.getUseBoxes(); 671 Iterator usesIt=uses.iterator(); 672 while(usesIt.hasNext()) { 673 Value v=((ValueBox) (usesIt.next())).getValue(); 674 if(v instanceof Local) { 675 Local l=(Local) v; 676 if(!init.contains(l)) 677 throw new RuntimeException ("Warning: Local variable "+l 678 +" not definitely defined at "+s 679 +" in "+method); 680 } 681 } 682 } 683 } 684 } 685 686 687 688 689 690 691 692 693 | Popular Tags |