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