1 19 20 25 26 package soot; 27 import soot.options.*; 28 import java.io.*; 29 import soot.tagkit.*; 30 import java.util.*; 31 import soot.util.*; 32 import soot.toolkits.graph.*; 33 34 37 public class Printer { 38 public Printer(Singletons.Global g) { 39 } 40 public static Printer v() { 41 return G.v().soot_Printer(); 42 } 43 44 final private static char fileSeparator = 45 System.getProperty("file.separator").charAt(0); 46 47 public static final int USE_ABBREVIATIONS = 0x0001, ADD_JIMPLE_LN = 0x0010; 48 49 public boolean useAbbreviations() { 50 return (options & USE_ABBREVIATIONS) != 0; 51 } 52 53 public boolean addJimpleLn() { 54 return (options & ADD_JIMPLE_LN) != 0; 55 } 56 57 int options = 0; 58 public void setOption(int opt) { 59 options |= opt; 60 } 61 public void clearOption(int opt) { 62 options &= ~opt; 63 } 64 65 int jimpleLnNum = 0; 67 public int getJimpleLnNum() { 68 return jimpleLnNum; 69 } 70 public void setJimpleLnNum(int newVal) { 71 jimpleLnNum = newVal; 72 } 73 public void incJimpleLnNum() { 74 jimpleLnNum++; 75 } 77 78 public void printTo(SootClass cl, PrintWriter out) { 79 setJimpleLnNum(1); 81 82 { 84 StringTokenizer st = 85 new StringTokenizer(Modifier.toString(cl.getModifiers())); 86 while (st.hasMoreTokens()) { 87 String tok = (String ) st.nextToken(); 88 if( cl.isInterface() && tok.equals("abstract") ) continue; 89 out.print(tok + " "); 90 } 91 92 String classPrefix = ""; 93 94 if (!cl.isInterface()) { 95 classPrefix = classPrefix + " class"; 96 classPrefix = classPrefix.trim(); 97 } 98 99 out.print( 100 classPrefix + " " + Scene.v().quotedNameOf(cl.getName()) + ""); 101 } 102 103 { 105 if (cl.hasSuperclass()) 106 out.print( 107 " extends " 108 + Scene.v().quotedNameOf(cl.getSuperclass().getName()) 109 + ""); 110 } 111 112 { 114 Iterator interfaceIt = cl.getInterfaces().iterator(); 115 116 if (interfaceIt.hasNext()) { 117 out.print(" implements "); 118 119 out.print( 120 "" 121 + Scene.v().quotedNameOf( 122 ((SootClass) interfaceIt.next()).getName()) 123 + ""); 124 125 while (interfaceIt.hasNext()) { 126 out.print(","); 127 out.print( 128 " " 129 + Scene.v().quotedNameOf( 130 ((SootClass) interfaceIt.next()).getName()) 131 + ""); 132 } 133 } 134 } 135 136 out.println(); 137 incJimpleLnNum(); 138 145 out.println("{"); 146 incJimpleLnNum(); 147 if (Options.v().print_tags_in_output()){ 148 Iterator cTagIterator = cl.getTags().iterator(); 149 while (cTagIterator.hasNext()) { 150 Tag t = (Tag) cTagIterator.next(); 151 out.print("/*"); 152 out.print(t.toString()); 153 out.println("*/"); 154 } 155 } 156 157 { 159 Iterator fieldIt = cl.getFields().iterator(); 160 161 if (fieldIt.hasNext()) { 162 while (fieldIt.hasNext()) { 163 SootField f = (SootField) fieldIt.next(); 164 165 if (f.isPhantom()) 166 continue; 167 168 if (Options.v().print_tags_in_output()){ 169 Iterator fTagIterator = f.getTags().iterator(); 170 while (fTagIterator.hasNext()) { 171 Tag t = (Tag) fTagIterator.next(); 172 out.print("/*"); 173 out.print(t.toString()); 174 out.println("*/"); 175 } 176 } 177 out.println(" " + f.getDeclaration() + ";"); 178 if (addJimpleLn()) { 179 setJimpleLnNum(addJimpleLnTags(getJimpleLnNum(), f)); 180 } 181 182 } 184 } 185 } 186 187 { 189 Iterator methodIt = cl.methodIterator(); 190 191 if (methodIt.hasNext()) { 192 if (cl.getMethodCount() != 0) { 193 out.println(); 194 incJimpleLnNum(); 195 } 196 197 while (methodIt.hasNext()) { 198 SootMethod method = (SootMethod) methodIt.next(); 199 200 if (method.isPhantom()) 201 continue; 202 203 if (!Modifier.isAbstract(method.getModifiers()) 204 && !Modifier.isNative(method.getModifiers())) { 205 if (!method.hasActiveBody()) 206 throw new RuntimeException ( 207 "method " 208 + method.getName() 209 + " has no active body!"); 210 else 211 if (Options.v().print_tags_in_output()){ 212 Iterator mTagIterator = method.getTags().iterator(); 213 while (mTagIterator.hasNext()) { 214 Tag t = (Tag) mTagIterator.next(); 215 out.print("/*"); 216 out.print(t.toString()); 217 out.println("*/"); 218 } 219 } 220 printTo(method.getActiveBody(), out); 221 222 if (methodIt.hasNext()) { 223 out.println(); 224 incJimpleLnNum(); 225 } 226 } else { 227 228 if (Options.v().print_tags_in_output()){ 229 Iterator mTagIterator = method.getTags().iterator(); 230 while (mTagIterator.hasNext()) { 231 Tag t = (Tag) mTagIterator.next(); 232 out.print("/*"); 233 out.print(t.toString()); 234 out.println("*/"); 235 } 236 } 237 238 out.print(" "); 239 out.print(method.getDeclaration()); 240 out.println(";"); 241 incJimpleLnNum(); 242 if (methodIt.hasNext()) { 243 out.println(); 244 incJimpleLnNum(); 245 } 246 } 247 } 248 } 249 } 250 out.println("}"); 251 incJimpleLnNum(); 252 } 253 254 257 public void writeXXXDeprecated(SootClass cl, String outputDir) { 259 String outputDirWithSep = ""; 260 261 if (!outputDir.equals("")) 262 outputDirWithSep = outputDir + fileSeparator; 263 264 try { 265 File tempFile = 266 new File(outputDirWithSep + cl.getName() + ".jasmin"); 267 268 FileOutputStream streamOut = new FileOutputStream(tempFile); 269 270 PrintWriter writerOut = 271 new PrintWriter( 272 new EscapedWriter(new OutputStreamWriter(streamOut))); 273 274 if (cl.containsBafBody()) 275 new soot.baf.JasminClass(cl).print(writerOut); 276 else 277 new soot.jimple.JasminClass(cl).print(writerOut); 278 279 writerOut.close(); 280 281 if (Options.v().time()) 282 Timers.v().assembleJasminTimer.start(); 283 284 { 286 String [] args; 287 288 if (outputDir.equals("")) { 289 args = new String [1]; 290 291 args[0] = cl.getName() + ".jasmin"; 292 } else { 293 args = new String [3]; 294 295 args[0] = "-d"; 296 args[1] = outputDir; 297 args[2] = outputDirWithSep + cl.getName() + ".jasmin"; 298 } 299 300 jasmin.Main.main(args); 301 } 302 303 tempFile.delete(); 304 305 if (Options.v().time()) 306 Timers.v().assembleJasminTimer.end(); 307 308 } catch (IOException e) { 309 throw new RuntimeException ( 310 "Could not produce new classfile! (" + e + ")"); 311 } 312 } 313 314 320 public void printTo(Body b, PrintWriter out) { 321 b.validate(); 322 323 boolean isPrecise = !useAbbreviations(); 324 325 String decl = b.getMethod().getDeclaration(); 326 327 out.println(" " + decl); 328 330 if (!addJimpleLn()) { 332 337 } 338 339 if (addJimpleLn()) { 340 setJimpleLnNum(addJimpleLnTags(getJimpleLnNum(), b.getMethod())); 341 } 343 344 out.println(" {"); 345 incJimpleLnNum(); 346 347 UnitGraph unitGraph = new soot.toolkits.graph.BriefUnitGraph(b); 348 349 LabeledUnitPrinter up; 350 if( isPrecise ) up = new NormalUnitPrinter(b); 351 else up = new BriefUnitPrinter(b); 352 353 if (addJimpleLn()) { 354 up.setPositionTagger( new AttributesUnitPrinter(getJimpleLnNum()) ); 355 } 356 357 printLocalsInBody(b, up); 358 359 printStatementsInBody(b, out, up, unitGraph); 360 361 out.println(" }"); 362 incJimpleLnNum(); 363 364 } 365 366 367 private void printStatementsInBody(Body body, java.io.PrintWriter out, LabeledUnitPrinter up, UnitGraph unitGraph ) { 368 Chain units = body.getUnits(); 369 Iterator unitIt = units.iterator(); 370 Unit currentStmt = null, previousStmt; 371 372 while (unitIt.hasNext()) { 373 374 previousStmt = currentStmt; 375 currentStmt = (Unit) unitIt.next(); 376 377 { 379 383 if (currentStmt != units.getFirst()) { 384 if (unitGraph.getSuccsOf(previousStmt).size() != 1 385 || unitGraph.getPredsOf(currentStmt).size() != 1 386 || up.labels().containsKey(currentStmt)) { 387 up.newline(); 388 } else { 389 391 List succs = unitGraph.getSuccsOf(previousStmt); 392 393 if (succs.get(0) != currentStmt) { 394 up.newline(); 395 } 396 } 397 } 398 399 if (up.labels().containsKey(currentStmt)) { 400 up.unitRef( currentStmt, true ); 401 up.literal(":"); 402 up.newline(); 403 } 404 405 if (up.references().containsKey(currentStmt)) { 406 up.unitRef( currentStmt, false ); 407 } 408 } 409 410 up.startUnit(currentStmt); 411 currentStmt.toString(up); 412 up.endUnit(currentStmt); 413 414 up.literal(";"); 415 up.newline(); 416 417 if (Options.v().print_tags_in_output()){ 421 Iterator tagIterator = currentStmt.getTags().iterator(); 422 while (tagIterator.hasNext()) { 423 Tag t = (Tag) tagIterator.next(); 424 up.noIndent(); 425 up.literal("/*"); 426 up.literal(t.toString()); 427 up.literal("*/"); 428 up.newline(); 429 } 430 441 } 442 } 443 444 out.print(up.toString()); 445 if (addJimpleLn()){ 446 setJimpleLnNum(up.getPositionTagger().getEndLn()); 447 } 448 449 450 { 452 Iterator trapIt = body.getTraps().iterator(); 453 454 if (trapIt.hasNext()) { 455 out.println(); 456 incJimpleLnNum(); 457 } 458 459 while (trapIt.hasNext()) { 460 Trap trap = (Trap) trapIt.next(); 461 462 out.println( 463 " catch " 464 + Scene.v().quotedNameOf(trap.getException().getName()) 465 + " from " 466 + up.labels().get(trap.getBeginUnit()) 467 + " to " 468 + up.labels().get(trap.getEndUnit()) 469 + " with " 470 + up.labels().get(trap.getHandlerUnit()) 471 + ";"); 472 473 incJimpleLnNum(); 474 475 } 476 } 477 478 } 479 480 private int addJimpleLnTags(int lnNum, Unit stmt, int endLn) { 481 482 if (endLn-lnNum <= 1) { 483 stmt.addTag(new JimpleLineNumberTag(lnNum)); 484 lnNum++; 486 return lnNum; 487 } 488 else { 489 stmt.addTag(new JimpleLineNumberTag(lnNum, endLn)); 490 endLn++; 492 return endLn; 493 } 494 } 495 496 private int addJimpleLnTags(int lnNum, SootMethod meth) { 497 meth.addTag(new JimpleLineNumberTag(lnNum)); 498 lnNum++; 499 return lnNum; 500 } 501 502 private int addJimpleLnTags(int lnNum, SootField f) { 503 f.addTag(new JimpleLineNumberTag(lnNum)); 504 lnNum++; 505 return lnNum; 506 } 507 508 509 private void printLocalsInBody( 510 Body body, 511 UnitPrinter up) { 512 { 514 Map typeToLocals = 515 new DeterministicHashMap(body.getLocalCount() * 2 + 1, 0.7f); 516 517 { 519 Iterator localIt = body.getLocals().iterator(); 520 521 while (localIt.hasNext()) { 522 Local local = (Local) localIt.next(); 523 524 List localList; 525 526 Type t = local.getType(); 527 528 if (typeToLocals.containsKey(t)) 529 localList = (List) typeToLocals.get(t); 530 else { 531 localList = new ArrayList(); 532 typeToLocals.put(t, localList); 533 } 534 535 localList.add(local); 536 } 537 } 538 539 { 541 Iterator typeIt = typeToLocals.keySet().iterator(); 542 543 while (typeIt.hasNext()) { 544 Type type = (Type) typeIt.next(); 545 546 List localList = (List) typeToLocals.get(type); 547 Object [] locals = localList.toArray(); 548 up.type( type ); 549 up.literal( " " ); 550 551 for (int k = 0; k < locals.length; k++) { 552 if (k != 0) 553 up.literal( ", " ); 554 555 up.local( (Local) locals[k] ); 556 } 557 558 up.literal(";"); 559 up.newline(); 560 } 561 } 562 563 if (!typeToLocals.isEmpty()) { 564 up.newline(); 565 } 566 } 567 } 568 } 569 | Popular Tags |