1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
167cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
187cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden * List all methods in all concrete classes in one or more DEX files.
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/DexFile.h"
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/DexClass.h"
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/DexProto.h"
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/SysUtil.h"
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "libdex/CmdUtils.h"
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h>
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h>
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <fcntl.h>
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stddef.h>
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h>
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h>
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <getopt.h>
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h>
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <assert.h>
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* gProgName = "dexlist";
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
387cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden/* command-line args */
397cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFaddenstatic struct {
407cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    char*       argCopy;
417cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    const char* classToFind;
427cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    const char* methodToFind;
437cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden} gParms;
447cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden
457cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a newly-allocated string for the "dot version" of the class
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name for the given type descriptor. That is, The initial "L" and
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * final ";" (if any) have been removed and all occurrences of '/'
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have been changed to '.'.
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic char* descriptorToDot(const char* str)
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t at = strlen(str);
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* newStr;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (str[0] == 'L') {
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(str[at - 1] == ';');
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at -= 2; /* Two fewer chars to copy. */
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        str++; /* Skip the 'L'. */
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newStr = malloc(at + 1); /* Add one for the '\0'. */
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newStr[at] = '\0';
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (at > 0) {
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at--;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newStr[at] = (str[at] == '/') ? '.' : str[at];
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newStr;
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Position table callback; we just want to catch the number of the
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * first line in the method, which *should* correspond to the first
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entry from the table.  (Could also use "min" here.)
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int positionsCallback(void* cnxt, u4 address, u4 lineNum)
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int* pFirstLine = (int*) cnxt;
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (*pFirstLine == -1)
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pFirstLine = lineNum;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump a method.
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dumpMethod(DexFile* pDexFile, const char* fileName,
927cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    const DexMethod* pDexMethod, int i)
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const DexMethodId* pMethodId;
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const DexCode* pCode;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* classDescriptor;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* methodName;
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int firstLine;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* abstract and native methods don't get listed */
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pDexMethod->codeOff == 0)
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMethodId = dexGetMethodId(pDexFile, pDexMethod->methodIdx);
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    methodName = dexStringById(pDexFile, pMethodId->nameIdx);
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pCode = dexGetCode(pDexFile, pDexMethod);
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pCode != NULL);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If the filename is empty, then set it to something printable
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * so that it is easier to parse.
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * TODO: A method may override its class's default source file by
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * specifying a different one in its debug info. This possibility
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * should be handled here.
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (fileName == NULL || fileName[0] == 0) {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fileName = "(none)";
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    firstLine = -1;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dexDecodeDebugInfo(pDexFile, pCode, classDescriptor, pMethodId->protoIdx,
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pDexMethod->accessFlags, positionsCallback, NULL, &firstLine);
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* className = descriptorToDot(classDescriptor);
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* desc = dexCopyDescriptorFromMethodId(pDexFile, pMethodId);
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4 insnsOff = pDexMethod->codeOff + offsetof(DexCode, insns);
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1327cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    if (gParms.methodToFind != NULL &&
1337cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        (strcmp(gParms.classToFind, className) != 0 ||
1347cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden         strcmp(gParms.methodToFind, methodName) != 0))
1357cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    {
1367cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        goto skip;
1377cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    }
1387cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    printf("0x%08x %d %s %s %s %s %d\n",
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insnsOff, pCode->insnsSize * 2,
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        className, methodName, desc,
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fileName, firstLine);
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1447cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFaddenskip:
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(desc);
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(className);
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through all direct and virtual methods in the class.
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dumpClass(DexFile* pDexFile, int idx)
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const DexClassDef* pClassDef;
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DexClassData* pClassData;
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* pEncodedData;
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* fileName;
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pClassDef = dexGetClassDef(pDexFile, idx);
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pEncodedData = dexGetClassData(pDexFile, pClassDef);
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pClassData = dexReadAndVerifyClassData(&pEncodedData, NULL);
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pClassData == NULL) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fprintf(stderr, "Trouble reading class data\n");
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
168de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pClassDef->sourceFileIdx == 0xffffffff) {
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fileName = NULL;
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fileName = dexStringById(pDexFile, pClassDef->sourceFileIdx);
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
174de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
175de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro    /*
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * TODO: Each class def points at a sourceFile, so maybe that
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * should be printed out. However, this needs to be coordinated
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * with the tools that parse this output.
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
180de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < (int) pClassData->header.directMethodsSize; i++) {
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dumpMethod(pDexFile, fileName, &pClassData->directMethods[i], i);
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < (int) pClassData->header.virtualMethodsSize; i++) {
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dumpMethod(pDexFile, fileName, &pClassData->virtualMethods[i], i);
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(pClassData);
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process a file.
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns 0 on success.
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint process(const char* fileName)
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DexFile* pDexFile = NULL;
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    MemMapping map;
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool mapped = false;
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int result = -1;
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UnzipToFileResult utfr;
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    utfr = dexOpenAndMap(fileName, NULL, &map, true);
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (utfr != kUTFRSuccess) {
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (utfr == kUTFRNoClassesDex) {
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* no classes.dex in the APK; pretend we succeeded */
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = 0;
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto bail;
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fprintf(stderr, "Unable to process '%s'\n", fileName);
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mapped = true;
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pDexFile = dexFileParse(map.addr, map.length, kDexParseDefault);
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pDexFile == NULL) {
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fprintf(stderr, "Warning: DEX parse failed for '%s'\n", fileName);
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto bail;
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    printf("#%s\n", fileName);
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < (int) pDexFile->pHeader->classDefsSize; i++) {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dumpClass(pDexFile, i);
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = 0;
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail:
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (mapped)
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sysReleaseShmem(&map);
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pDexFile != NULL)
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dexFileFree(pDexFile);
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Show usage.
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid usage(void)
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    fprintf(stderr, "Copyright (C) 2007 The Android Open Source Project\n\n");
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    fprintf(stderr, "%s: dexfile [dexfile2 ...]\n", gProgName);
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    fprintf(stderr, "\n");
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse args.
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint main(int argc, char* const argv[])
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int result = 0;
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2597cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    /*
2607cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden     * Find all instances of the fully-qualified method name.  This isn't
2617cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden     * really what dexlist is for, but it's easy to do it here.
2627cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden     */
2637cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    if (argc > 3 && strcmp(argv[1], "--method") == 0) {
2647cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        gParms.argCopy = strdup(argv[2]);
2657cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        char* meth = strrchr(gParms.argCopy, '.');
2667cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        if (meth == NULL) {
2677cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden            fprintf(stderr, "Expected package.Class.method\n");
2687cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden            free(gParms.argCopy);
2697cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden            return 2;
2707cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        }
2717cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        *meth = '\0';
2727cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        gParms.classToFind = gParms.argCopy;
2737cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        gParms.methodToFind = meth+1;
2747cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        argv += 2;
2757cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden        argc -= 2;
2767cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    }
2777cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (argc < 2) {
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fprintf(stderr, "%s: no file specified\n", gProgName);
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        usage();
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 2;
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Run through the list of files.  If one of them fails we contine on,
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * only returning a failure at the end.
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 1; i < argc; i++)
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result |= process(argv[i]);
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2917cbf8b4dabe7590871eb890640cd42f2afe777b6Andy McFadden    free(gParms.argCopy);
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
294