xref: /aosp_15_r20/art/dexdump/dexdump_main.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  *
16*795d594fSAndroid Build Coastguard Worker  * Main driver of the dexdump utility.
17*795d594fSAndroid Build Coastguard Worker  *
18*795d594fSAndroid Build Coastguard Worker  * This is a re-implementation of the original dexdump utility that was
19*795d594fSAndroid Build Coastguard Worker  * based on Dalvik functions in libdex into a new dexdump that is now
20*795d594fSAndroid Build Coastguard Worker  * based on Art functions in libart instead. The output is very similar to
21*795d594fSAndroid Build Coastguard Worker  * to the original for correct DEX files. Error messages may differ, however.
22*795d594fSAndroid Build Coastguard Worker  * Also, ODEX files are no longer supported.
23*795d594fSAndroid Build Coastguard Worker  */
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
26*795d594fSAndroid Build Coastguard Worker #include <base/mem_map.h>
27*795d594fSAndroid Build Coastguard Worker #include <stdio.h>
28*795d594fSAndroid Build Coastguard Worker #include <string.h>
29*795d594fSAndroid Build Coastguard Worker #include <unistd.h>
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker #include "dexdump.h"
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker namespace art {
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker static const char* gProgName = "dexdump";
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker /*
38*795d594fSAndroid Build Coastguard Worker  * Shows usage.
39*795d594fSAndroid Build Coastguard Worker  */
usage()40*795d594fSAndroid Build Coastguard Worker static void usage() {
41*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << "Copyright (C) 2007 The Android Open Source Project\n";
42*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << gProgName
43*795d594fSAndroid Build Coastguard Worker              << ": [-a] [-c] [-d] [-e] [-f] [-h] [-i] [-j] [-l layout] [-n]"
44*795d594fSAndroid Build Coastguard Worker                 "  [-s] [-o outfile] dexfile...\n";
45*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -a : display annotations";
46*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -c : verify checksum and exit";
47*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -d : disassemble code sections";
48*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -e : display exported items only";
49*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -f : display dex file header";
50*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -g : display CFG for dex";
51*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -h : display all sections header";
52*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -i : ignore checksum failures";
53*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -j : disable dex file verification";
54*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -l : output layout, either 'plain' or 'xml'";
55*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -n : don't display debug information";
56*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -o : output file name (defaults to stdout)";
57*795d594fSAndroid Build Coastguard Worker   LOG(ERROR) << " -s : display all strings from string_ids header section";
58*795d594fSAndroid Build Coastguard Worker }
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker /*
61*795d594fSAndroid Build Coastguard Worker  * Main driver of the dexdump utility.
62*795d594fSAndroid Build Coastguard Worker  */
dexdumpDriver(int argc,char ** argv)63*795d594fSAndroid Build Coastguard Worker int dexdumpDriver(int argc, char** argv) {
64*795d594fSAndroid Build Coastguard Worker   // Reset options.
65*795d594fSAndroid Build Coastguard Worker   bool wantUsage = false;
66*795d594fSAndroid Build Coastguard Worker   memset(&gOptions, 0, sizeof(gOptions));
67*795d594fSAndroid Build Coastguard Worker   gOptions.verbose = true;
68*795d594fSAndroid Build Coastguard Worker   gOptions.showDebugInfo = true;
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker   // Parse all arguments.
71*795d594fSAndroid Build Coastguard Worker   while (true) {
72*795d594fSAndroid Build Coastguard Worker     const int ic = getopt(argc, argv, "acdefghijl:no:s");
73*795d594fSAndroid Build Coastguard Worker     if (ic < 0) {
74*795d594fSAndroid Build Coastguard Worker       break;  // done
75*795d594fSAndroid Build Coastguard Worker     }
76*795d594fSAndroid Build Coastguard Worker     switch (ic) {
77*795d594fSAndroid Build Coastguard Worker       case 'a':  // display annotations
78*795d594fSAndroid Build Coastguard Worker         gOptions.showAnnotations = true;
79*795d594fSAndroid Build Coastguard Worker         break;
80*795d594fSAndroid Build Coastguard Worker       case 'c':  // verify the checksum then exit
81*795d594fSAndroid Build Coastguard Worker         gOptions.checksumOnly = true;
82*795d594fSAndroid Build Coastguard Worker         break;
83*795d594fSAndroid Build Coastguard Worker       case 'd':  // disassemble Dalvik instructions
84*795d594fSAndroid Build Coastguard Worker         gOptions.disassemble = true;
85*795d594fSAndroid Build Coastguard Worker         break;
86*795d594fSAndroid Build Coastguard Worker       case 'e':  // exported items only
87*795d594fSAndroid Build Coastguard Worker         gOptions.exportsOnly = true;
88*795d594fSAndroid Build Coastguard Worker         break;
89*795d594fSAndroid Build Coastguard Worker       case 'f':  // display dex file header
90*795d594fSAndroid Build Coastguard Worker         gOptions.showFileHeaders = true;
91*795d594fSAndroid Build Coastguard Worker         break;
92*795d594fSAndroid Build Coastguard Worker       case 'g':  // display cfg
93*795d594fSAndroid Build Coastguard Worker         gOptions.showCfg = true;
94*795d594fSAndroid Build Coastguard Worker         break;
95*795d594fSAndroid Build Coastguard Worker       case 'h':  // display section headers, i.e. all meta-data
96*795d594fSAndroid Build Coastguard Worker         gOptions.showSectionHeaders = true;
97*795d594fSAndroid Build Coastguard Worker         break;
98*795d594fSAndroid Build Coastguard Worker       case 'i':  // continue even if checksum is bad
99*795d594fSAndroid Build Coastguard Worker         gOptions.ignoreBadChecksum = true;
100*795d594fSAndroid Build Coastguard Worker         break;
101*795d594fSAndroid Build Coastguard Worker       case 'j':  // disable dex file verification
102*795d594fSAndroid Build Coastguard Worker         gOptions.disableVerifier = true;
103*795d594fSAndroid Build Coastguard Worker         break;
104*795d594fSAndroid Build Coastguard Worker       case 'l':  // layout
105*795d594fSAndroid Build Coastguard Worker         if (strcmp(optarg, "plain") == 0) {
106*795d594fSAndroid Build Coastguard Worker           gOptions.outputFormat = OUTPUT_PLAIN;
107*795d594fSAndroid Build Coastguard Worker         } else if (strcmp(optarg, "xml") == 0) {
108*795d594fSAndroid Build Coastguard Worker           gOptions.outputFormat = OUTPUT_XML;
109*795d594fSAndroid Build Coastguard Worker           gOptions.verbose = false;
110*795d594fSAndroid Build Coastguard Worker         } else {
111*795d594fSAndroid Build Coastguard Worker           wantUsage = true;
112*795d594fSAndroid Build Coastguard Worker         }
113*795d594fSAndroid Build Coastguard Worker         break;
114*795d594fSAndroid Build Coastguard Worker       case 'n':  // don't display debug information
115*795d594fSAndroid Build Coastguard Worker         gOptions.showDebugInfo = false;
116*795d594fSAndroid Build Coastguard Worker         break;
117*795d594fSAndroid Build Coastguard Worker       case 'o':  // output file
118*795d594fSAndroid Build Coastguard Worker         gOptions.outputFileName = optarg;
119*795d594fSAndroid Build Coastguard Worker         break;
120*795d594fSAndroid Build Coastguard Worker       case 's':  // display all strings
121*795d594fSAndroid Build Coastguard Worker         gOptions.showAllStrings = true;
122*795d594fSAndroid Build Coastguard Worker         break;
123*795d594fSAndroid Build Coastguard Worker       default:
124*795d594fSAndroid Build Coastguard Worker         wantUsage = true;
125*795d594fSAndroid Build Coastguard Worker         break;
126*795d594fSAndroid Build Coastguard Worker     }  // switch
127*795d594fSAndroid Build Coastguard Worker   }  // while
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker   // Detect early problems.
130*795d594fSAndroid Build Coastguard Worker   if (optind == argc) {
131*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "No file specified";
132*795d594fSAndroid Build Coastguard Worker     wantUsage = true;
133*795d594fSAndroid Build Coastguard Worker   }
134*795d594fSAndroid Build Coastguard Worker   if (gOptions.checksumOnly && gOptions.ignoreBadChecksum) {
135*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Can't specify both -c and -i";
136*795d594fSAndroid Build Coastguard Worker     wantUsage = true;
137*795d594fSAndroid Build Coastguard Worker   }
138*795d594fSAndroid Build Coastguard Worker   if (wantUsage) {
139*795d594fSAndroid Build Coastguard Worker     usage();
140*795d594fSAndroid Build Coastguard Worker     return 2;
141*795d594fSAndroid Build Coastguard Worker   }
142*795d594fSAndroid Build Coastguard Worker 
143*795d594fSAndroid Build Coastguard Worker   // Open alternative output file.
144*795d594fSAndroid Build Coastguard Worker   if (gOptions.outputFileName) {
145*795d594fSAndroid Build Coastguard Worker     gOutFile = fopen(gOptions.outputFileName, "we");
146*795d594fSAndroid Build Coastguard Worker     if (!gOutFile) {
147*795d594fSAndroid Build Coastguard Worker       PLOG(ERROR) << "Can't open " << gOptions.outputFileName;
148*795d594fSAndroid Build Coastguard Worker       return 1;
149*795d594fSAndroid Build Coastguard Worker     }
150*795d594fSAndroid Build Coastguard Worker   }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker   // Process all files supplied on command line.
153*795d594fSAndroid Build Coastguard Worker   int result = 0;
154*795d594fSAndroid Build Coastguard Worker   while (optind < argc) {
155*795d594fSAndroid Build Coastguard Worker     result |= processFile(argv[optind++]);
156*795d594fSAndroid Build Coastguard Worker   }  // while
157*795d594fSAndroid Build Coastguard Worker   return result != 0 ? 1 : 0;
158*795d594fSAndroid Build Coastguard Worker }
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker }  // namespace art
161*795d594fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)162*795d594fSAndroid Build Coastguard Worker int main(int argc, char** argv) {
163*795d594fSAndroid Build Coastguard Worker   // Output all logging to stderr.
164*795d594fSAndroid Build Coastguard Worker   android::base::SetLogger(android::base::StderrLogger);
165*795d594fSAndroid Build Coastguard Worker   art::MemMap::Init();
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   return art::dexdumpDriver(argc, argv);
168*795d594fSAndroid Build Coastguard Worker }
169