1 19 20 package soot; 21 import java.util.*; 22 import java.io.*; 23 import java.util.zip.*; 24 import soot.util.*; 25 import soot.util.queue.*; 26 import soot.jimple.*; 27 import soot.shimple.*; 28 import soot.grimp.*; 29 import soot.baf.*; 30 import soot.jimple.toolkits.invoke.*; 31 import soot.jimple.toolkits.base.*; 32 import soot.shimple.toolkits.scalar.*; 33 import soot.grimp.toolkits.base.*; 34 import soot.baf.toolkits.base.*; 35 import soot.jimple.toolkits.typing.*; 36 import soot.jimple.toolkits.scalar.*; 37 import soot.jimple.toolkits.scalar.pre.*; 38 import soot.jimple.toolkits.annotation.arraycheck.*; 39 import soot.jimple.toolkits.annotation.profiling.*; 40 import soot.jimple.toolkits.annotation.callgraph.*; 41 import soot.jimple.toolkits.annotation.parity.*; 42 import soot.jimple.toolkits.annotation.methods.*; 43 import soot.jimple.toolkits.annotation.fields.*; 44 import soot.jimple.toolkits.annotation.qualifiers.*; 45 import soot.jimple.toolkits.annotation.nullcheck.*; 46 import soot.jimple.toolkits.annotation.tags.*; 47 import soot.jimple.toolkits.annotation.defs.*; 48 import soot.jimple.toolkits.annotation.liveness.*; 49 import soot.jimple.toolkits.annotation.logic.*; 50 import soot.jimple.toolkits.annotation.purity.*; import soot.jimple.toolkits.annotation.*; 53 import soot.jimple.toolkits.pointer.*; 54 import soot.jimple.toolkits.callgraph.*; 55 import soot.tagkit.*; 56 import soot.options.Options; 57 import soot.toolkits.scalar.*; 58 import soot.jimple.spark.SparkTransformer; 59 import soot.jimple.paddle.PaddleHook; 60 import soot.jimple.toolkits.callgraph.CHATransformer; 61 import soot.jimple.spark.fieldrw.*; 62 import soot.dava.*; 63 import soot.dava.toolkits.base.AST.interProcedural.InterProceduralAnalyses; 64 import soot.dava.toolkits.base.misc.*; 65 import soot.xml.*; 66 import soot.toolkits.graph.interaction.*; 67 68 69 public class PackManager { 70 public PackManager( Singletons.Global g ) { PhaseOptions.v().setPackManager(this); init(); } 71 72 public boolean onlyStandardPacks() { return onlyStandardPacks; } 73 private boolean onlyStandardPacks = false; 74 void notifyAddPack() { 75 onlyStandardPacks = false; 76 } 77 78 private void init() 79 { 80 Pack p; 81 82 addPack(p = new JimpleBodyPack()); 84 { 85 p.add(new Transform("jb.tt", soot.toolkits.exceptions.TrapTightener.v())); 86 p.add(new Transform("jb.ls", LocalSplitter.v())); 87 p.add(new Transform("jb.a", Aggregator.v())); 88 p.add(new Transform("jb.ule", UnusedLocalEliminator.v())); 89 p.add(new Transform("jb.tr", TypeAssigner.v())); 90 p.add(new Transform("jb.ulp", LocalPacker.v())); 91 p.add(new Transform("jb.lns", LocalNameStandardizer.v())); 92 p.add(new Transform("jb.cp", CopyPropagator.v())); 93 p.add(new Transform("jb.dae", DeadAssignmentEliminator.v())); 94 p.add(new Transform("jb.cp-ule", UnusedLocalEliminator.v())); 95 p.add(new Transform("jb.lp", LocalPacker.v())); 96 p.add(new Transform("jb.ne", NopEliminator.v())); 97 p.add(new Transform("jb.uce", UnreachableCodeEliminator.v())); 98 } 99 100 addPack(p = new JavaToJimpleBodyPack()); 102 { 103 p.add(new Transform("jj.ls", LocalSplitter.v())); 104 p.add(new Transform("jj.a", Aggregator.v())); 105 p.add(new Transform("jj.ule", UnusedLocalEliminator.v())); 106 p.add(new Transform("jj.ne", NopEliminator.v())); 107 p.add(new Transform("jj.tr", TypeAssigner.v())); 108 p.add(new Transform("jj.ulp", LocalPacker.v())); 110 p.add(new Transform("jj.lns", LocalNameStandardizer.v())); 111 p.add(new Transform("jj.cp", CopyPropagator.v())); 112 p.add(new Transform("jj.dae", DeadAssignmentEliminator.v())); 113 p.add(new Transform("jj.cp-ule", UnusedLocalEliminator.v())); 114 p.add(new Transform("jj.lp", LocalPacker.v())); 115 p.add(new Transform("jj.uce", UnreachableCodeEliminator.v())); 116 117 } 118 119 addPack(p = new CallGraphPack("cg")); 121 { 122 p.add(new Transform("cg.cha", CHATransformer.v())); 123 p.add(new Transform("cg.spark", SparkTransformer.v())); 124 p.add(new Transform("cg.paddle", PaddleHook.v())); 125 } 126 127 addPack(p = new ScenePack("wstp")); 129 130 addPack(p = new ScenePack("wsop")); 132 133 addPack(p = new ScenePack("wjtp")); 135 { 136 } 137 138 addPack(p = new ScenePack("wjop")); 140 { 141 p.add(new Transform("wjop.smb", StaticMethodBinder.v())); 142 p.add(new Transform("wjop.si", StaticInliner.v())); 143 } 144 145 addPack(p = new ScenePack("wjap")); 148 { 149 p.add(new Transform("wjap.ra", RectangularArrayFinder.v())); 150 p.add(new Transform("wjap.umt", UnreachableMethodsTagger.v())); 151 p.add(new Transform("wjap.uft", UnreachableFieldsTagger.v())); 152 p.add(new Transform("wjap.tqt", TightestQualifiersTagger.v())); 153 p.add(new Transform("wjap.cgg", CallGraphGrapher.v())); 154 p.add(new Transform("wjap.purity", PurityAnalysis.v())); } 156 157 addPack(p = new BodyPack(Shimple.PHASE)); 159 160 addPack(p = new BodyPack("stp")); 162 163 addPack(p = new BodyPack("sop")); 165 { 166 p.add(new Transform("sop.cpf", SConstantPropagatorAndFolder.v())); 167 } 168 169 addPack(p = new BodyPack("jtp")); 171 172 addPack(p = new BodyPack("jop")); 174 { 175 p.add(new Transform("jop.cse", CommonSubexpressionEliminator.v())); 176 p.add(new Transform("jop.bcm", BusyCodeMotion.v())); 177 p.add(new Transform("jop.lcm", LazyCodeMotion.v())); 178 p.add(new Transform("jop.cp", CopyPropagator.v())); 179 p.add(new Transform("jop.cpf", ConstantPropagatorAndFolder.v())); 180 p.add(new Transform("jop.cbf", ConditionalBranchFolder.v())); 181 p.add(new Transform("jop.dae", DeadAssignmentEliminator.v())); 182 p.add(new Transform("jop.uce1", UnreachableCodeEliminator.v())); 183 p.add(new Transform("jop.ubf1", UnconditionalBranchFolder.v())); 184 p.add(new Transform("jop.uce2", UnreachableCodeEliminator.v())); 185 p.add(new Transform("jop.ubf2", UnconditionalBranchFolder.v())); 186 p.add(new Transform("jop.ule", UnusedLocalEliminator.v())); 187 } 188 189 addPack(p = new BodyPack("jap")); 191 { 192 p.add(new Transform("jap.npc", NullPointerChecker.v())); 193 p.add(new Transform("jap.npcolorer", NullPointerColorer.v())); 194 p.add(new Transform("jap.abc", ArrayBoundsChecker.v())); 195 p.add(new Transform("jap.profiling", ProfilingGenerator.v())); 196 p.add(new Transform("jap.sea", SideEffectTagger.v())); 197 p.add(new Transform("jap.fieldrw", FieldTagger.v())); 198 p.add(new Transform("jap.cgtagger", CallGraphTagger.v())); 199 p.add(new Transform("jap.parity", ParityTagger.v())); 200 p.add(new Transform("jap.pat", ParameterAliasTagger.v())); 201 p.add(new Transform("jap.rdtagger", ReachingDefsTagger.v())); 202 p.add(new Transform("jap.lvtagger", LiveVarsTagger.v())); 203 p.add(new Transform("jap.che", CastCheckEliminatorDumper.v())); 204 p.add(new Transform("jap.umt", new UnreachableMethodTransformer())); 205 p.add(new Transform("jap.lit", LoopInvariantFinder.v())); 206 p.add(new Transform("jap.aet", AvailExprTagger.v())); 207 p.add(new Transform("jap.dmt", DominatorsTagger.v())); 208 209 } 210 211 216 217 addPack(p = new BodyPack("gb")); 219 { 220 p.add(new Transform("gb.a1", Aggregator.v())); 221 p.add(new Transform("gb.cf", ConstructorFolder.v())); 222 p.add(new Transform("gb.a2", Aggregator.v())); 223 p.add(new Transform("gb.ule", UnusedLocalEliminator.v())); 224 } 225 226 addPack(p = new BodyPack("gop")); 228 229 addPack(p = new BodyPack("bb")); 231 { 232 p.add(new Transform("bb.lso", LoadStoreOptimizer.v())); 233 p.add(new Transform("bb.pho", PeepholeOptimizer.v())); 234 p.add(new Transform("bb.ule", UnusedLocalEliminator.v())); 235 p.add(new Transform("bb.lp", LocalPacker.v())); 236 } 237 238 addPack(p = new BodyPack("bop")); 240 241 addPack(p = new BodyPack("tag")); 243 { 244 p.add(new Transform("tag.ln", LineNumberTagAggregator.v())); 245 p.add(new Transform("tag.an", ArrayNullTagAggregator.v())); 246 p.add(new Transform("tag.dep", DependenceTagAggregator.v())); 247 p.add(new Transform("tag.fieldrw", FieldTagAggregator.v())); 248 } 249 250 257 addPack(p = new BodyPack("db")); 258 { 259 p.add(new Transform("db.transformations", null)); 260 p.add(new Transform("db.renamer", null)); 261 p.add(new Transform("db.deobfuscate", null)); 262 p.add(new Transform("db.force-recompile", null)); 263 } 264 265 266 267 onlyStandardPacks = true; 268 } 269 270 public static PackManager v() { 271 return G.v().soot_PackManager(); 272 } 273 274 private Map packNameToPack = new HashMap(); 275 private List packList = new LinkedList(); 276 277 private void addPack( Pack p ) { 278 if( packNameToPack.containsKey( p.getPhaseName() ) ) 279 throw new RuntimeException ( "Duplicate pack "+p.getPhaseName() ); 280 packNameToPack.put( p.getPhaseName(), p ); 281 packList.add( p ); 282 } 283 284 public boolean hasPack(String phaseName) { 285 return getPhase( phaseName ) != null; 286 } 287 288 public Pack getPack(String phaseName) { 289 Pack p = (Pack) packNameToPack.get(phaseName); 290 return p; 291 } 292 293 public boolean hasPhase(String phaseName) { 294 return getPhase(phaseName) != null; 295 } 296 297 public HasPhaseOptions getPhase(String phaseName) { 298 int index = phaseName.indexOf( "." ); 299 if( index < 0 ) return getPack( phaseName ); 300 String packName = phaseName.substring(0,index); 301 if( !hasPack( packName ) ) return null; 302 return getPack( packName ).get( phaseName ); 303 } 304 305 public Transform getTransform(String phaseName) { 306 return (Transform) getPhase( phaseName ); 307 } 308 309 310 public Collection allPacks() { 311 return Collections.unmodifiableList( packList ); 312 } 313 314 public void runPacks() { 315 if (Options.v().src_prec() == Options.src_prec_class && Options.v().keep_line_number()){ 316 LineNumberAdder lineNumAdder = LineNumberAdder.v(); 317 lineNumAdder.internalTransform("", null); 318 } 319 320 if (Options.v().whole_program() || Options.v().whole_shimple()) { 321 runWholeProgramPacks(); 322 } 323 retrieveAllBodies(); 324 preProcessDAVA(); 325 if (Options.v().interactive_mode()){ 326 if (InteractionHandler.v().getInteractionListener() == null){ 327 G.v().out.println("Cannot run in interactive mode. No listeners available. Continuing in regular mode."); 328 Options.v().set_interactive_mode(false); 329 } 330 else { 331 G.v().out.println("Running in interactive mode."); 332 } 333 } 334 335 runBodyPacks(); 336 handleInnerClasses(); 337 } 338 339 public void runBodyPacks() { 340 runBodyPacks( reachableClasses() ); 341 } 342 343 private ZipOutputStream jarFile = null; 344 public void writeOutput() { 345 if( Options.v().output_jar() ) { 346 String outFileName = SourceLocator.v().getOutputDir(); 347 try { 348 jarFile = new ZipOutputStream(new FileOutputStream(outFileName)); 349 } catch( FileNotFoundException e ) { 350 throw new CompilationDeathException("Cannot open output Jar file " + outFileName); 351 } 352 } else { 353 jarFile = null; 354 } 355 if(Options.v().verbose()) 356 PhaseDumper.v().dumpBefore("output"); 357 if( Options.v().output_format() == Options.output_format_dava ) { 358 postProcessDAVA(); 359 } else { 360 writeOutput( reachableClasses() ); 361 } 362 postProcessXML( reachableClasses() ); 363 releaseBodies( reachableClasses() ); 364 if(Options.v().verbose()) 365 PhaseDumper.v().dumpAfter("output"); 366 } 367 368 private void runWholeProgramPacks() { 369 if (Options.v().whole_shimple()) { 370 ShimpleTransformer.v().transform(); 371 getPack("cg").apply(); 372 getPack("wstp").apply(); 373 getPack("wsop").apply(); 374 } else { 375 getPack("cg").apply(); 376 getPack("wjtp").apply(); 377 getPack("wjop").apply(); 378 getPack("wjap").apply(); 379 } 380 PaddleHook.v().finishPhases(); 381 } 382 383 384 private void preProcessDAVA() { 385 if (Options.v().output_format() == Options.output_format_dava) { 386 ThrowFinder.v().find(); 387 PackageNamer.v().fixNames(); 388 389 G.v().out.println(); 390 } 391 } 392 393 private void runBodyPacks( Iterator classes ) { 394 while( classes.hasNext() ) { 395 SootClass cl = (SootClass) classes.next(); 396 runBodyPacks( cl ); 397 } 398 } 399 400 private void handleInnerClasses(){ 401 InnerClassTagAggregator agg = InnerClassTagAggregator.v(); 402 agg.internalTransform("", null); 403 } 404 405 private void writeOutput( Iterator classes ) { 406 while( classes.hasNext() ) { 407 SootClass cl = (SootClass) classes.next(); 408 writeClass( cl ); 409 } 410 try { 411 if(jarFile != null) jarFile.close(); 412 } catch( IOException e ) { 413 throw new CompilationDeathException( "Error closing output jar: "+e ); 414 } 415 } 416 417 private void releaseBodies( Iterator classes ) { 418 while( classes.hasNext() ) { 419 SootClass cl = (SootClass) classes.next(); 420 releaseBodies( cl ); 421 } 422 } 423 424 private Iterator reachableClasses() { 425 if( false && (Options.v().whole_program() || 426 Options.v().whole_shimple())) { 427 QueueReader methods = Scene.v().getReachableMethods().listener(); 428 HashSet reachableClasses = new HashSet(); 429 430 while(true) { 431 SootMethod m = (SootMethod) methods.next(); 432 if(m == null) break; 433 SootClass c = m.getDeclaringClass(); 434 if( !c.isApplicationClass() ) continue; 435 reachableClasses.add( c ); 436 } 437 return reachableClasses.iterator(); 438 } else { 439 return Scene.v().getApplicationClasses().iterator(); 440 } 441 } 442 443 444 private void postProcessDAVA() { 445 G.v().out.println(); 446 447 Chain appClasses = Scene.v().getApplicationClasses(); 448 449 Map options = PhaseOptions.v().getPhaseOptions("db.transformations"); 450 boolean transformations = PhaseOptions.getBoolean(options, "enabled"); 451 454 Iterator classIt = appClasses.iterator(); 455 while (classIt.hasNext()) { 456 SootClass s = (SootClass) classIt.next(); 457 String fileName = SourceLocator.v().getFileNameFor(s, Options.v().output_format()); 458 459 463 DavaStaticBlockCleaner.v().staticBlockInlining(s); 464 465 466 471 if(transformations){ 472 474 G.v().out.println("Analyzing " + fileName + "... "); 475 476 481 Iterator methodIt = s.methodIterator(); 482 while (methodIt.hasNext()) { 483 484 SootMethod m = (SootMethod) methodIt.next(); 485 DavaBody body = (DavaBody)m.getActiveBody(); 487 body.analyzeAST(); 489 } 490 } } 493 494 495 496 502 if(transformations){ 503 InterProceduralAnalyses.applyInterProceduralAnalyses(); 504 } 505 506 507 508 509 510 511 514 String pathForBuild=null; 515 ArrayList decompiledClasses = new ArrayList(); 516 classIt = appClasses.iterator(); 517 while (classIt.hasNext()) { 518 SootClass s = (SootClass) classIt.next(); 519 520 OutputStream streamOut = null; 521 PrintWriter writerOut = null; 522 String fileName = SourceLocator.v().getFileNameFor(s, Options.v().output_format()); 523 decompiledClasses.add(fileName.substring(fileName.lastIndexOf('/')+1)); 524 if(pathForBuild == null){ 525 pathForBuild =fileName.substring(0,fileName.lastIndexOf('/')+1); 526 } 528 if( Options.v().gzip() ) 529 fileName = fileName+".gz"; 530 531 try { 532 if( jarFile != null ) { 533 ZipEntry entry = new ZipEntry(soot.util.StringTools.replaceAll(fileName,"\\","/")); 534 jarFile.putNextEntry(entry); 535 streamOut = jarFile; 536 } else { 537 streamOut = new FileOutputStream(fileName); 538 } 539 if( Options.v().gzip() ) 540 streamOut = new GZIPOutputStream(streamOut); 541 writerOut = 542 new PrintWriter(new OutputStreamWriter(streamOut)); 543 } catch (IOException e) { 544 throw new CompilationDeathException("Cannot output file " + fileName); 545 } 546 547 548 549 G.v().out.print("Generating " + fileName + "... "); 550 551 G.v().out.flush(); 552 553 DavaPrinter.v().printTo(s, writerOut); 554 555 G.v().out.println(); 556 G.v().out.flush(); 557 558 { 559 try { 560 writerOut.flush(); 561 if(jarFile == null) streamOut.close(); 562 } catch (IOException e) { 563 throw new CompilationDeathException("Cannot close output file " + fileName); 564 } 565 } 566 } G.v().out.println(); 568 569 570 573 { 574 if(pathForBuild.endsWith("src/")) 577 pathForBuild=pathForBuild.substring(0,pathForBuild.length()-4); 578 579 String fileName = pathForBuild +"build.xml"; 580 581 try{ 582 OutputStream streamOut = new FileOutputStream(fileName); 583 PrintWriter writerOut = new PrintWriter(new OutputStreamWriter(streamOut)); 584 DavaBuildFile.generate(writerOut,decompiledClasses); 585 writerOut.flush(); 586 streamOut.close(); 587 } catch (IOException e) { 588 throw new CompilationDeathException("Cannot output file " + fileName); 589 } 590 } 591 592 593 594 } 595 596 private void runBodyPacks(SootClass c) { 597 final int format = Options.v().output_format(); 598 if (format == Options.output_format_dava) { 599 G.v().out.print("Decompiling "); 600 601 G.v().SootMethodAddedByDava=false; 603 } else { 604 G.v().out.print("Transforming "); 605 } 606 G.v().out.println(c.getName() + "... "); 607 608 boolean produceBaf = false, produceGrimp = false, produceDava = false, 609 produceJimple = true, produceShimple = false; 610 611 switch (format) { 612 case Options.output_format_none : 613 case Options.output_format_xml : 614 case Options.output_format_jimple : 615 case Options.output_format_jimp : 616 break; 617 case Options.output_format_shimp: 618 case Options.output_format_shimple: 619 produceShimple = true; 620 produceJimple = false; 622 break; 623 case Options.output_format_dava : 624 produceDava = true; 625 case Options.output_format_grimp : 627 case Options.output_format_grimple : 628 produceGrimp = true; 629 break; 630 case Options.output_format_baf : 631 case Options.output_format_b : 632 produceBaf = true; 633 break; 634 case Options.output_format_jasmin : 635 case Options.output_format_class : 636 produceGrimp = Options.v().via_grimp(); 637 produceBaf = !produceGrimp; 638 break; 639 default : 640 throw new RuntimeException (); 641 } 642 643 soot.xml.TagCollector tc = new soot.xml.TagCollector(); 644 645 boolean wholeShimple = Options.v().whole_shimple(); 646 if( Options.v().via_shimple() ) produceShimple = true; 647 648 Iterator methodIt = c.methodIterator(); 649 while (methodIt.hasNext()) { 650 SootMethod m = (SootMethod) methodIt.next(); 651 652 if (!m.isConcrete()) continue; 653 654 if (produceShimple || wholeShimple) { 655 ShimpleBody sBody = null; 656 657 { 659 Body body = m.retrieveActiveBody(); 660 661 if(body instanceof ShimpleBody){ 662 sBody = (ShimpleBody) body; 663 if(!sBody.isSSA()) 664 sBody.rebuild(); 665 } 666 else{ 667 sBody = Shimple.v().newBody(body); 668 } 669 } 670 671 m.setActiveBody(sBody); 672 PackManager.v().getPack("stp").apply(sBody); 673 PackManager.v().getPack("sop").apply(sBody); 674 675 if( produceJimple || (wholeShimple && !produceShimple) ) 676 m.setActiveBody(sBody.toJimpleBody()); 677 } 678 679 if (produceJimple) { 680 JimpleBody body =(JimpleBody) m.retrieveActiveBody(); 681 PackManager.v().getPack("jtp").apply(body); 682 if( Options.v().validate() ) { 683 body.validate(); 684 } 685 PackManager.v().getPack("jop").apply(body); 686 PackManager.v().getPack("jap").apply(body); 687 if (Options.v().xml_attributes() && Options.v().output_format() != Options.output_format_jimple) { 688 tc.collectBodyTags(body); 690 } 691 } 692 693 695 if (produceGrimp) { 696 m.setActiveBody(Grimp.v().newBody(m.getActiveBody(), "gb")); 697 PackManager.v().getPack("gop").apply(m.getActiveBody()); 698 } else if (produceBaf) { 699 m.setActiveBody(Baf.v().newBody 700 ((JimpleBody) m.getActiveBody())); 701 PackManager.v().getPack("bop").apply(m.getActiveBody()); 702 PackManager.v().getPack("tag").apply(m.getActiveBody()); 703 } 704 } 705 706 if (Options.v().xml_attributes() && Options.v().output_format() != Options.output_format_jimple) { 707 processXMLForClass(c, tc); 708 } 710 711 if (produceDava) { 712 methodIt = c.methodIterator(); 713 while (methodIt.hasNext()) { 714 SootMethod m = (SootMethod) methodIt.next(); 715 if (!m.isConcrete()) 716 continue; 717 m.setActiveBody(Dava.v().newBody(m.getActiveBody())); 719 } 720 721 726 if(G.v().SootMethodAddedByDava){ 728 ArrayList sootMethodsAdded = G.v().SootMethodsAdded; 730 Iterator it = sootMethodsAdded.iterator(); 731 while(it.hasNext()){ 732 c.addMethod((SootMethod)it.next()); 733 } 734 G.v().SootMethodsAdded = new ArrayList(); 735 G.v().SootMethodAddedByDava=false; 736 } 737 738 } } 740 741 private void writeClass(SootClass c) { 742 final int format = Options.v().output_format(); 743 if( format == Options.output_format_none ) return; 744 if( format == Options.output_format_dava ) return; 745 746 OutputStream streamOut = null; 747 PrintWriter writerOut = null; 748 boolean noOutputFile = false; 749 750 String fileName = SourceLocator.v().getFileNameFor(c, format); 751 if( Options.v().gzip() ) fileName = fileName+".gz"; 752 753 try { 754 if( jarFile != null ) { 755 ZipEntry entry = new ZipEntry(fileName); 756 jarFile.putNextEntry(entry); 757 streamOut = jarFile; 758 } else { 759 new File(fileName).getParentFile().mkdirs(); 760 streamOut = new FileOutputStream(fileName); 761 } 762 if( Options.v().gzip() ) { 763 streamOut = new GZIPOutputStream(streamOut); 764 } 765 if(format == Options.output_format_class) { 766 streamOut = new JasminOutputStream(streamOut); 767 } 768 writerOut = new PrintWriter(new OutputStreamWriter(streamOut)); 769 G.v().out.println( "Writing to "+fileName ); 770 } catch (IOException e) { 771 throw new CompilationDeathException("Cannot output file " + fileName); 772 } 773 774 if (Options.v().xml_attributes()) { 775 Printer.v().setOption(Printer.ADD_JIMPLE_LN); 776 } 777 switch (format) { 778 case Options.output_format_class : 779 case Options.output_format_jasmin : 780 if (c.containsBafBody()) 781 new soot.baf.JasminClass(c).print(writerOut); 782 else 783 new soot.jimple.JasminClass(c).print(writerOut); 784 break; 785 case Options.output_format_jimp : 786 case Options.output_format_shimp : 787 case Options.output_format_b : 788 case Options.output_format_grimp : 789 Printer.v().setOption(Printer.USE_ABBREVIATIONS); 790 Printer.v().printTo(c, writerOut); 791 break; 792 case Options.output_format_baf : 793 case Options.output_format_jimple : 794 case Options.output_format_shimple : 795 case Options.output_format_grimple : 796 writerOut = 797 new PrintWriter( 798 new EscapedWriter(new OutputStreamWriter(streamOut))); 799 Printer.v().printTo(c, writerOut); 800 break; 801 case Options.output_format_xml : 802 writerOut = 803 new PrintWriter( 804 new EscapedWriter(new OutputStreamWriter(streamOut))); 805 XMLPrinter.v().printJimpleStyleTo(c, writerOut); 806 break; 807 default : 808 throw new RuntimeException (); 809 } 810 811 try { 812 writerOut.flush(); 813 streamOut.close(); 814 } catch (IOException e) { 815 throw new CompilationDeathException("Cannot close output file " + fileName); 816 } 817 } 818 819 private void postProcessXML( Iterator classes ) { 820 if (!Options.v().xml_attributes()) return; 821 if (Options.v().output_format() != Options.output_format_jimple) return; 822 while( classes.hasNext() ) { 823 SootClass c = (SootClass) classes.next(); 824 processXMLForClass(c); 825 } 826 } 827 828 private void processXMLForClass(SootClass c, TagCollector tc){ 829 final int format = Options.v().output_format(); 830 String fileName = SourceLocator.v().getFileNameFor(c, format); 831 XMLAttributesPrinter xap = new XMLAttributesPrinter(fileName, 832 SourceLocator.v().getOutputDir()); 833 xap.printAttrs(c, tc); 834 } 835 836 private void processXMLForClass(SootClass c){ 837 final int format = Options.v().output_format(); 838 String fileName = SourceLocator.v().getFileNameFor(c, format); 839 XMLAttributesPrinter xap = new XMLAttributesPrinter(fileName, 840 SourceLocator.v().getOutputDir()); 841 xap.printAttrs(c); 842 } 843 844 private void releaseBodies( SootClass cl ) { 845 Iterator methodIt = cl.methodIterator(); 846 while (methodIt.hasNext()) { 847 SootMethod m = (SootMethod) methodIt.next(); 848 849 if (m.hasActiveBody()) 850 m.releaseActiveBody(); 851 } 852 } 853 854 private void retrieveAllBodies() { 855 Iterator clIt = reachableClasses(); 856 while( clIt.hasNext() ) { 857 SootClass cl = (SootClass) clIt.next(); 858 Iterator methodIt = cl.methodIterator(); 859 while (methodIt.hasNext()) { 860 SootMethod m = (SootMethod) methodIt.next(); 861 862 if( m.isConcrete() ) { 863 m.retrieveActiveBody(); 864 } 865 } 866 } 867 } 868 } 869 | Popular Tags |