Home | History | Annotate | Download | only in dump
      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 
     17 package com.android.dx.command.dump;
     18 
     19 import com.android.dex.util.FileUtils;
     20 import com.android.dx.cf.iface.ParseException;
     21 import com.android.dx.util.HexParser;
     22 import java.io.UnsupportedEncodingException;
     23 
     24 /**
     25  * Main class for the class file dumper.
     26  */
     27 public class Main {
     28 
     29     private final Args parsedArgs = new Args();
     30 
     31     /**
     32      * This class is uninstantiable.
     33      */
     34     private Main() {
     35         // This space intentionally left blank.
     36     }
     37 
     38     public static void main(String[] args) {
     39         new Main().run(args);
     40     }
     41 
     42     /**
     43      * Run!
     44      */
     45     private void run(String[] args) {
     46         int at = 0;
     47 
     48         for (/*at*/; at < args.length; at++) {
     49             String arg = args[at];
     50             if (arg.equals("--") || !arg.startsWith("--")) {
     51                 break;
     52             } else if (arg.equals("--bytes")) {
     53                 parsedArgs.rawBytes = true;
     54             } else if (arg.equals("--basic-blocks")) {
     55                 parsedArgs.basicBlocks = true;
     56             } else if (arg.equals("--rop-blocks")) {
     57                 parsedArgs.ropBlocks = true;
     58             } else if (arg.equals("--optimize")) {
     59                 parsedArgs.optimize = true;
     60             } else if (arg.equals("--ssa-blocks")) {
     61                 parsedArgs.ssaBlocks = true;
     62             } else if (arg.startsWith("--ssa-step=")) {
     63                 parsedArgs.ssaStep = arg.substring(arg.indexOf('=') + 1);
     64             } else if (arg.equals("--debug")) {
     65                 parsedArgs.debug = true;
     66             } else if (arg.equals("--dot")) {
     67                 parsedArgs.dotDump = true;
     68             } else if (arg.equals("--strict")) {
     69                 parsedArgs.strictParse = true;
     70             } else if (arg.startsWith("--width=")) {
     71                 arg = arg.substring(arg.indexOf('=') + 1);
     72                 parsedArgs.width = Integer.parseInt(arg);
     73             } else if (arg.startsWith("--method=")) {
     74                 arg = arg.substring(arg.indexOf('=') + 1);
     75                 parsedArgs.method = arg;
     76             } else {
     77                 System.err.println("unknown option: " + arg);
     78                 throw new RuntimeException("usage");
     79             }
     80         }
     81 
     82         if (at == args.length) {
     83             System.err.println("no input files specified");
     84             throw new RuntimeException("usage");
     85         }
     86 
     87         for (/*at*/; at < args.length; at++) {
     88             try {
     89                 String name = args[at];
     90                 System.out.println("reading " + name + "...");
     91                 byte[] bytes = FileUtils.readFile(name);
     92                 if (!name.endsWith(".class")) {
     93                     String src;
     94                     try {
     95                         src = new String(bytes, "utf-8");
     96                     } catch (UnsupportedEncodingException ex) {
     97                         throw new RuntimeException("shouldn't happen", ex);
     98                     }
     99                     bytes = HexParser.parse(src);
    100                 }
    101                 processOne(name, bytes);
    102             } catch (ParseException ex) {
    103                 System.err.println("\ntrouble parsing:");
    104                 if (parsedArgs.debug) {
    105                     ex.printStackTrace();
    106                 } else {
    107                     ex.printContext(System.err);
    108                 }
    109             }
    110         }
    111     }
    112 
    113     /**
    114      * Processes one file.
    115      *
    116      * @param name {@code non-null;} name of the file
    117      * @param bytes {@code non-null;} contents of the file
    118      */
    119     private void processOne(String name, byte[] bytes) {
    120         if (parsedArgs.dotDump) {
    121             DotDumper.dump(bytes, name, parsedArgs);
    122         } else if (parsedArgs.basicBlocks) {
    123             BlockDumper.dump(bytes, System.out, name, false, parsedArgs);
    124         } else if (parsedArgs.ropBlocks) {
    125             BlockDumper.dump(bytes, System.out, name, true, parsedArgs);
    126         } else if (parsedArgs.ssaBlocks) {
    127             // --optimize ignored with --ssa-blocks
    128             parsedArgs.optimize = false;
    129             SsaDumper.dump(bytes, System.out, name, parsedArgs);
    130         } else {
    131             ClassDumper.dump(bytes, System.out, name, parsedArgs);
    132         }
    133     }
    134 }
    135