1 19 20 package soot.dava.toolkits.base.AST.transformations; 21 22 import soot.*; 23 import soot.dava.*; 24 import soot.jimple.*; 25 import soot.jimple.internal.*; 26 import soot.grimp.internal.*; 27 import soot.dava.internal.AST.*; 28 import soot.dava.internal.asg.*; 29 import soot.dava.internal.javaRep.*; 30 import soot.dava.toolkits.base.AST.analysis.*; 31 import soot.dava.toolkits.base.AST.traversals.*; 32 import soot.dava.toolkits.base.AST.structuredAnalysis.*; 33 34 import java.util.*; 35 36 39 40 47 48 53 public class FinalFieldDefinition { SootClass sootClass; 55 56 SootMethod sootMethod; 57 58 DavaBody davaBody; 59 60 List cancelFinalModifier; 61 62 public FinalFieldDefinition(ASTMethodNode node) { 63 davaBody = node.getDavaBody(); 64 sootMethod = davaBody.getMethod(); 65 sootClass = sootMethod.getDeclaringClass(); 66 67 String subSignature = sootMethod.getName(); 68 if (!(subSignature.compareTo("<clinit>") == 0 || subSignature 69 .compareTo("<init>") == 0)) { 70 return; 75 } 76 77 ArrayList interesting = findFinalFields(); 79 if (interesting.size() == 0) { 80 return; 82 } 83 84 cancelFinalModifier = new ArrayList(); 85 analyzeMethod(node, interesting); 86 87 Iterator it = cancelFinalModifier.iterator(); 88 while (it.hasNext()) { 89 SootField field = (SootField) it.next(); 90 field.setModifiers((soot.Modifier.FINAL ^ 0xFFFF) 91 & field.getModifiers()); 92 } 93 } 94 95 103 public ArrayList findFinalFields() { 104 105 ArrayList interestingFinalFields = new ArrayList(); 107 108 Iterator fieldIt = sootClass.getFields().iterator(); 109 while (fieldIt.hasNext()) { 110 SootField tempField = (SootField) fieldIt.next(); 111 if (tempField.isFinal()) { 112 113 if (tempField.isStatic() 115 && sootMethod.getName().compareTo("<clinit>") == 0) { 116 interestingFinalFields.add(tempField); 117 } 118 119 if ((!tempField.isStatic()) 121 && sootMethod.getName().compareTo("<init>") == 0) { 122 interestingFinalFields.add(tempField); 123 } 124 } 125 } 126 return interestingFinalFields; 127 } 128 129 public void analyzeMethod(ASTMethodNode node, List varsOfInterest) { 130 MustMayInitialize must = new MustMayInitialize(node, 131 MustMayInitialize.MUST); 132 133 Iterator it = varsOfInterest.iterator(); 134 while (it.hasNext()) { 135 SootField interest = (SootField) it.next(); 136 137 Type fieldType = interest.getType(); 139 if (fieldType instanceof DoubleType 140 && interest.hasTag("DoubleConstantValueTag")) { 141 continue; 142 } else if (fieldType instanceof FloatType 143 && interest.hasTag("FloatConstantValueTag")) { 144 continue; 145 } else if (fieldType instanceof LongType 146 && interest.hasTag("LongConstantValueTag")) { 147 continue; 148 } else if (fieldType instanceof CharType 149 && interest.hasTag("IntegerConstantValueTag")) { 150 continue; 151 } else if (fieldType instanceof BooleanType 152 && interest.hasTag("IntegerConstantValueTag")) { 153 continue; 154 } else if ((fieldType instanceof IntType 155 || fieldType instanceof ByteType || fieldType instanceof ShortType) 156 && interest.hasTag("IntegerConstantValueTag")) { 157 continue; 158 } else if (interest.hasTag("StringConstantValueTag")) { 159 continue; 160 } 161 162 if (must.isMustInitialized(interest)) { 163 continue; 165 } 166 167 MustMayInitialize may = new MustMayInitialize(node, 170 MustMayInitialize.MAY); 171 if (may.isMayInitialized(interest)) { 172 List defs = must.getDefs(interest); 175 if (defs == null) 176 throw new RuntimeException ("Sootfield: " + interest 177 + " is mayInitialized but the defs is null"); 178 179 handleAssignOnSomePaths(node, interest, defs); 180 } else { 181 assignDefault(node, interest); 185 } 186 } 187 } 188 189 197 public void assignDefault(ASTMethodNode node, SootField f) { 198 199 AugmentedStmt defaultStmt = createDefaultStmt(f); 201 202 if (defaultStmt == null) 203 return; 204 205 List subBodies = (List) node.get_SubBodies(); 206 if (subBodies.size() != 1) 207 throw new RuntimeException ( 208 "SubBodies size of method node not equal to 1"); 209 210 List body = (List) subBodies.get(0); 211 212 215 boolean done = false; 216 if (body.size() != 0) { 217 ASTNode lastNode = (ASTNode) body.get(body.size() - 1); 218 if (lastNode instanceof ASTStatementSequenceNode) { 219 List stmts = ((ASTStatementSequenceNode) lastNode) 220 .getStatements(); 221 if (stmts.size() != 0) { 222 Stmt s = ((AugmentedStmt) stmts.get(0)).get_Stmt(); 223 if (!(s instanceof DVariableDeclarationStmt)) { 224 stmts.add(defaultStmt); 226 227 ASTStatementSequenceNode newNode = new ASTStatementSequenceNode( 228 stmts); 229 231 body.remove(body.size() - 1); 232 body.add(newNode); 233 234 node.replaceBody(body); 235 done = true; 236 } 237 } 238 } 239 } 240 if (!done) { 241 List newBody = new ArrayList(); 242 newBody.add(defaultStmt); 243 244 ASTStatementSequenceNode newNode = new ASTStatementSequenceNode( 245 newBody); 246 body.add(newNode); 247 248 node.replaceBody(body); 249 } 250 251 } 252 253 public AugmentedStmt createDefaultStmt(Object field) { 254 255 Value ref = null; 256 Type fieldType = null; 257 if (field instanceof SootField) { 258 SootFieldRef tempFieldRef = ((SootField) field).makeRef(); 260 261 fieldType = ((SootField) field).getType(); 262 if (((SootField) field).isStatic()) 263 ref = new DStaticFieldRef(tempFieldRef, true); 264 else 265 ref = new DInstanceFieldRef(new JimpleLocal("this", fieldType), 266 tempFieldRef, new HashSet()); 267 268 } else if (field instanceof Local) { 269 ref = (Local) field; 270 fieldType = ((Local) field).getType(); 271 } 272 273 GAssignStmt assignStmt = null; 274 275 if (fieldType instanceof RefType) { 276 assignStmt = new GAssignStmt(ref, NullConstant.v()); 277 } else if (fieldType instanceof DoubleType) { 278 assignStmt = new GAssignStmt(ref, DoubleConstant.v(0)); 279 } else if (fieldType instanceof FloatType) { 280 assignStmt = new GAssignStmt(ref, FloatConstant.v(0)); 281 } else if (fieldType instanceof LongType) { 282 assignStmt = new GAssignStmt(ref, LongConstant.v(0)); 283 } else if (fieldType instanceof IntType 284 || fieldType instanceof ByteType 285 || fieldType instanceof ShortType 286 || fieldType instanceof CharType 287 || fieldType instanceof BooleanType) { 288 289 assignStmt = new GAssignStmt(ref, DIntConstant.v(0, fieldType)); 290 } 291 292 if (assignStmt != null) { 293 AugmentedStmt as = new AugmentedStmt(assignStmt); 295 return as; 296 } else 297 return null; 298 299 } 300 301 309 310 public void handleAssignOnSomePaths(ASTMethodNode node, SootField field, 311 List defs) { 312 313 if (defs.size() != 1) { 314 cancelFinalModifier.add(field); 316 } else { 317 319 AllVariableUses varUses = new AllVariableUses(node); 321 node.apply(varUses); 322 323 List allUses = varUses.getUsesForField(field); 324 325 if (allUses != null && allUses.size() != 0) { 326 331 cancelFinalModifier.add(field); 332 } 333 else { 334 376 377 378 379 Type localType = field.getType(); 381 Local newLocal = new JimpleLocal("DavaTemp_" + field.getName(),localType); 382 383 DVariableDeclarationStmt varStmt = new DVariableDeclarationStmt(localType,davaBody); 384 385 varStmt.addLocal(newLocal); 386 AugmentedStmt as = new AugmentedStmt(varStmt); 387 388 390 ASTStatementSequenceNode declNode = node.getDeclarations(); 392 List stmts = declNode.getStatements(); 393 stmts.add(as); 394 395 declNode = new ASTStatementSequenceNode(stmts); 396 397 List subBodies = (List) node.get_SubBodies(); 398 if (subBodies.size() != 1) 399 throw new DecompilationException("ASTMethodNode does not have one subBody"); 400 401 List body = (List) subBodies.get(0); 402 403 body.remove(0); 404 body.add(0, declNode); 405 406 node.replaceBody(body); 407 408 node.setDeclarations(declNode); 409 410 411 AugmentedStmt initialization = createDefaultStmt(newLocal); 413 418 if (body.size() < 2) 419 throw new RuntimeException ("Size of body is less than 1"); 420 421 425 426 ASTNode nodeSecond = (ASTNode) body.get(1); 427 if (nodeSecond instanceof ASTStatementSequenceNode) { 428 List stmts1 = ((ASTStatementSequenceNode) nodeSecond).getStatements(); 430 stmts1.add(initialization); 431 nodeSecond = new ASTStatementSequenceNode(stmts1); 432 body.remove(1); 434 } else { 435 List tempList = new ArrayList(); 437 tempList.add(initialization); 438 nodeSecond = new ASTStatementSequenceNode(tempList); 439 } 440 body.add(1, nodeSecond); 441 node.replaceBody(body); 442 443 444 445 ((GAssignStmt) defs.get(0)).setLeftOp(newLocal); 448 449 450 451 453 SootFieldRef tempFieldRef = ((SootField) field).makeRef(); 455 456 Value ref; 457 if (field.isStatic()) 458 ref = new DStaticFieldRef(tempFieldRef, true); 459 else { 460 ref = new DInstanceFieldRef(new JimpleLocal("this", field 461 .getType()), tempFieldRef, new HashSet()); 462 } 464 465 GAssignStmt assignStmt = new GAssignStmt(ref, newLocal); 466 AugmentedStmt assignStmt1 = new AugmentedStmt(assignStmt); 467 468 469 470 475 476 ASTParentNodeFinder parentFinder = new ASTParentNodeFinder(); 479 node.apply(parentFinder); 480 481 Object parent = parentFinder.getParentOf(defs.get(0)); 482 if(!(parent instanceof ASTStatementSequenceNode)){ 483 throw new DecompilationException("Parent of stmt was not a stmt seq node"); 484 } 485 486 Object grandParent = parentFinder.getParentOf(parent); 487 if( !(parent instanceof ASTMethodNode) && grandParent == null){ 488 throw new DecompilationException("Parent of stmt seq node was null"); 489 } 490 491 495 496 MustMayInitialize must = new MustMayInitialize(node,MustMayInitialize.MUST); 497 while(!must.isMustInitialized(field)) { 498 499 Object parentOfGrandParent = parentFinder.getParentOf(grandParent); 501 if( !(grandParent instanceof ASTMethodNode) && parentOfGrandParent == null){ 502 throw new DecompilationException("Parent of non method node was null"); 503 } 504 boolean notResolved=false; 505 ASTNode ancestor = (ASTNode)parentOfGrandParent; 507 List ancestorBodies = ancestor.get_SubBodies(); 508 Iterator it = ancestorBodies.iterator(); 509 while(it.hasNext()){ 510 List ancestorSubBody = null; 511 512 if (ancestor instanceof ASTTryNode) 513 ancestorSubBody = (List) ((ASTTryNode.container) it.next()).o; 514 else 515 ancestorSubBody = (List) it.next(); 516 517 if(ancestorSubBody.indexOf(grandParent) > -1) { 518 int index = ancestorSubBody.indexOf(grandParent); 520 522 if(index+1 < ancestorSubBody.size() && ancestorSubBody.get(index+1) instanceof ASTStatementSequenceNode ){ 523 ASTStatementSequenceNode someNode = (ASTStatementSequenceNode)ancestorSubBody.get(index+1); 525 526 528 List stmtsLast = ((ASTStatementSequenceNode) someNode).getStatements(); 529 List newStmts = new ArrayList(); 530 newStmts.add(assignStmt1); 531 newStmts.addAll(stmtsLast); 532 someNode.setStatements(newStmts); 533 System.out.println("here1"); 534 must = new MustMayInitialize(node,MustMayInitialize.MUST); 536 if(!must.isMustInitialized(field)){ 537 someNode.setStatements(stmtsLast); 539 notResolved=true; 540 } 541 } 542 else{ 543 List tempList = new ArrayList(); 545 tempList.add(assignStmt1); 546 ASTStatementSequenceNode lastNode = new ASTStatementSequenceNode(tempList); 547 ancestorSubBody.add(index+1,lastNode); 548 System.out.println("here2"); 550 must = new MustMayInitialize(node,MustMayInitialize.MUST); 552 if(!must.isMustInitialized(field)){ 553 ancestorSubBody.remove(index+1); 555 notResolved=true; 556 } 557 } 558 break; } 561 } if(notResolved){ 563 grandParent = parentFinder.getParentOf(grandParent); 566 } 568 } } 570 } 571 } 572 } 573 574 575 576 580 581 class MethodCallFinder extends DepthFirstAdapter { 582 583 GAssignStmt def; 584 585 boolean foundIt = false; 586 587 boolean anyMethodCalls = false; 588 589 public MethodCallFinder(GAssignStmt def) { 590 this.def = def; 591 } 592 593 public MethodCallFinder(boolean verbose, GAssignStmt def) { 594 super(verbose); 595 this.def = def; 596 } 597 598 public void outDefinitionStmt(DefinitionStmt s) { 599 if (s instanceof GAssignStmt) { 600 if (((GAssignStmt) s).equals(def)) { 601 foundIt = true; 602 } 604 } 605 } 606 607 public void inInvokeExpr(InvokeExpr ie) { 608 if (foundIt) { 610 anyMethodCalls = true; 612 } 613 } 614 615 619 public boolean anyMethodCalls() { 620 return anyMethodCalls; 621 } 623 624 } | Popular Tags |