1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.dx.command.dump; 18 19import com.android.dx.cf.iface.ParseException; 20import com.android.dx.util.FileUtils; 21import com.android.dx.util.HexParser; 22 23import java.io.UnsupportedEncodingException; 24 25/** 26 * Main class for the class file dumper. 27 */ 28public class Main { 29 30 static Args parsedArgs = new Args(); 31 32 /** 33 * This class is uninstantiable. 34 */ 35 private Main() { 36 // This space intentionally left blank. 37 } 38 39 /** 40 * Run! 41 */ 42 public static void main(String[] args) { 43 int at = 0; 44 45 for (/*at*/; at < args.length; at++) { 46 String arg = args[at]; 47 if (arg.equals("--") || !arg.startsWith("--")) { 48 break; 49 } else if (arg.equals("--bytes")) { 50 parsedArgs.rawBytes = true; 51 } else if (arg.equals("--basic-blocks")) { 52 parsedArgs.basicBlocks = true; 53 } else if (arg.equals("--rop-blocks")) { 54 parsedArgs.ropBlocks = true; 55 } else if (arg.equals("--optimize")) { 56 parsedArgs.optimize = true; 57 } else if (arg.equals("--ssa-blocks")) { 58 parsedArgs.ssaBlocks = true; 59 } else if (arg.startsWith("--ssa-step=")) { 60 parsedArgs.ssaStep = arg.substring(arg.indexOf('=') + 1); 61 } else if (arg.equals("--debug")) { 62 parsedArgs.debug = true; 63 } else if (arg.equals("--dot")) { 64 parsedArgs.dotDump = true; 65 } else if (arg.equals("--strict")) { 66 parsedArgs.strictParse = true; 67 } else if (arg.startsWith("--width=")) { 68 arg = arg.substring(arg.indexOf('=') + 1); 69 parsedArgs.width = Integer.parseInt(arg); 70 } else if (arg.startsWith("--method=")) { 71 arg = arg.substring(arg.indexOf('=') + 1); 72 parsedArgs.method = arg; 73 } else { 74 System.err.println("unknown option: " + arg); 75 throw new RuntimeException("usage"); 76 } 77 } 78 79 if (at == args.length) { 80 System.err.println("no input files specified"); 81 throw new RuntimeException("usage"); 82 } 83 84 for (/*at*/; at < args.length; at++) { 85 try { 86 String name = args[at]; 87 System.out.println("reading " + name + "..."); 88 byte[] bytes = FileUtils.readFile(name); 89 if (!name.endsWith(".class")) { 90 String src; 91 try { 92 src = new String(bytes, "utf-8"); 93 } catch (UnsupportedEncodingException ex) { 94 throw new RuntimeException("shouldn't happen", ex); 95 } 96 bytes = HexParser.parse(src); 97 } 98 processOne(name, bytes); 99 } catch (ParseException ex) { 100 System.err.println("\ntrouble parsing:"); 101 if (parsedArgs.debug) { 102 ex.printStackTrace(); 103 } else { 104 ex.printContext(System.err); 105 } 106 } 107 } 108 } 109 110 /** 111 * Processes one file. 112 * 113 * @param name {@code non-null;} name of the file 114 * @param bytes {@code non-null;} contents of the file 115 */ 116 private static void processOne(String name, byte[] bytes) { 117 if (parsedArgs.dotDump) { 118 DotDumper.dump(bytes, name, parsedArgs); 119 } else if (parsedArgs.basicBlocks) { 120 BlockDumper.dump(bytes, System.out, name, false, parsedArgs); 121 } else if (parsedArgs.ropBlocks) { 122 BlockDumper.dump(bytes, System.out, name, true, parsedArgs); 123 } else if (parsedArgs.ssaBlocks) { 124 // --optimize ignored with --ssa-blocks 125 parsedArgs.optimize = false; 126 SsaDumper.dump(bytes, System.out, name, parsedArgs); 127 } else { 128 ClassDumper.dump(bytes, System.out, name, parsedArgs); 129 } 130 } 131} 132