1dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson/*
2dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * Copyright (C) 2011 The Android Open Source Project
3dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson *
4dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * you may not use this file except in compliance with the License.
6dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * You may obtain a copy of the License at
7dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson *
8dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson *
10dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * See the License for the specific language governing permissions and
14dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * limitations under the License.
15dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson */
16dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
17dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilsonpackage com.android.dx.io;
18dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.ClassDef;
20fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.Dex;
21fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.FieldId;
22fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.MethodId;
23fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.ProtoId;
24fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.TableOfContents;
25dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilsonimport java.io.File;
26dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilsonimport java.io.IOException;
27dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
28dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson/**
29dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson * Executable that prints all indices of a dex file.
30dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson */
31dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilsonpublic final class DexIndexPrinter {
32fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson    private final Dex dex;
33dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private final TableOfContents tableOfContents;
34dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
35dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    public DexIndexPrinter(File file) throws IOException {
36fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        this.dex = new Dex(file);
37fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        this.tableOfContents = dex.getTableOfContents();
38dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
39dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
40dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printMap() {
41dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        for (TableOfContents.Section section : tableOfContents.sections) {
42dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            if (section.off != -1) {
43dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson                System.out.println("section " + Integer.toHexString(section.type)
44dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson                        + " off=" + Integer.toHexString(section.off)
45dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson                        + " size=" + Integer.toHexString(section.size)
46dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson                        + " byteCount=" + Integer.toHexString(section.byteCount));
47dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            }
48dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
49dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
50dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
51dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printStrings() throws IOException {
52e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        int index = 0;
53fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        for (String string : dex.strings()) {
54e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            System.out.println("string " + index + ": " + string);
55e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            index++;
56dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
57dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
58dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
59dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printTypeIds() throws IOException {
60e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        int index = 0;
61fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        for (Integer type : dex.typeIds()) {
62fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson            System.out.println("type " + index + ": " + dex.strings().get(type));
63e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            index++;
64dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
65dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
66dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
67dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printProtoIds() throws IOException {
68e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        int index = 0;
69fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        for (ProtoId protoId : dex.protoIds()) {
70e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            System.out.println("proto " + index + ": " + protoId);
71e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            index++;
72dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
73dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
74dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
75dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printFieldIds() throws IOException {
76e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        int index = 0;
77fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        for (FieldId fieldId : dex.fieldIds()) {
78e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            System.out.println("field " + index + ": " + fieldId);
79e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            index++;
80dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
81dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
82dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
83dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printMethodIds() throws IOException {
84e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        int index = 0;
85fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        for (MethodId methodId : dex.methodIds()) {
86e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            System.out.println("methodId " + index + ": " + methodId);
87e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            index++;
88dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
89dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
90dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
91dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printTypeLists() throws IOException {
92dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        if (tableOfContents.typeLists.off == -1) {
93dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            System.out.println("No type lists");
94dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            return;
95dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
96fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        Dex.Section in = dex.open(tableOfContents.typeLists.off);
97dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        for (int i = 0; i < tableOfContents.typeLists.size; i++) {
98dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            int size = in.readInt();
99dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            System.out.print("Type list i=" + i + ", size=" + size + ", elements=");
100dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            for (int t = 0; t < size; t++) {
101fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson                System.out.print(" " + dex.typeNames().get((int) in.readShort()));
102dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            }
103dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            if (size % 2 == 1) {
104dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson                in.readShort(); // retain alignment
105dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            }
106dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson            System.out.println();
107dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
108dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
109dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
110dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    private void printClassDefs() {
111e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson        int index = 0;
112fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilson        for (ClassDef classDef : dex.classDefs()) {
113e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            System.out.println("class def " + index + ": " + classDef);
114e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson            index++;
115dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        }
116dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
117dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson
118dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    public static void main(String[] args) throws IOException {
119dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        DexIndexPrinter indexPrinter = new DexIndexPrinter(new File(args[0]));
120dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printMap();
121dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printStrings();
122dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printTypeIds();
123dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printProtoIds();
124dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printFieldIds();
125dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printMethodIds();
126dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printTypeLists();
127dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson        indexPrinter.printClassDefs();
128dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson    }
129dc8ad6cbf19b62d8c50527a0a38fe82b937370f1Jesse Wilson}
130