1 /* 2 * Copyright (C) 2016 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 * Main driver of the dexlayout utility. 17 * 18 * This is a tool to read dex files into an internal representation, 19 * reorganize the representation, and emit dex files with a better 20 * file layout. 21 */ 22 23#include "dexlayout.h" 24 25#include <stdio.h> 26#include <string.h> 27#include <unistd.h> 28#include <sys/types.h> 29#include <sys/stat.h> 30#include <fcntl.h> 31 32#include "base/logging.h" 33#include "jit/profile_compilation_info.h" 34#include "runtime.h" 35#include "mem_map.h" 36 37namespace art { 38 39static const char* kProgramName = "dexlayout"; 40 41/* 42 * Shows usage. 43 */ 44static void Usage(void) { 45 fprintf(stderr, "Copyright (C) 2016 The Android Open Source Project\n\n"); 46 fprintf(stderr, "%s: [-a] [-c] [-d] [-e] [-f] [-h] [-i] [-l layout] [-o outfile] [-p profile]" 47 " [-s] [-t] [-v] [-w directory] dexfile...\n\n", kProgramName); 48 fprintf(stderr, " -a : display annotations\n"); 49 fprintf(stderr, " -b : build dex_ir\n"); 50 fprintf(stderr, " -c : verify checksum and exit\n"); 51 fprintf(stderr, " -d : disassemble code sections\n"); 52 fprintf(stderr, " -e : display exported items only\n"); 53 fprintf(stderr, " -f : display summary information from file header\n"); 54 fprintf(stderr, " -h : display file header details\n"); 55 fprintf(stderr, " -i : ignore checksum failures\n"); 56 fprintf(stderr, " -l : output layout, either 'plain' or 'xml'\n"); 57 fprintf(stderr, " -o : output file name (defaults to stdout)\n"); 58 fprintf(stderr, " -p : profile file name (defaults to no profile)\n"); 59 fprintf(stderr, " -s : visualize reference pattern\n"); 60 fprintf(stderr, " -t : display file section sizes\n"); 61 fprintf(stderr, " -v : verify output file is canonical to input (IR level comparison)\n"); 62 fprintf(stderr, " -w : output dex directory \n"); 63} 64 65/* 66 * Main driver of the dexlayout utility. 67 */ 68int DexlayoutDriver(int argc, char** argv) { 69 // Art specific set up. 70 InitLogging(argv, Runtime::Aborter); 71 MemMap::Init(); 72 73 Options options; 74 options.dump_ = true; 75 options.verbose_ = true; 76 bool want_usage = false; 77 78 // Parse all arguments. 79 while (1) { 80 const int ic = getopt(argc, argv, "abcdefghil:mo:p:stvw:"); 81 if (ic < 0) { 82 break; // done 83 } 84 switch (ic) { 85 case 'a': // display annotations 86 options.show_annotations_ = true; 87 break; 88 case 'b': // build dex_ir 89 options.build_dex_ir_ = true; 90 break; 91 case 'c': // verify the checksum then exit 92 options.checksum_only_ = true; 93 break; 94 case 'd': // disassemble Dalvik instructions 95 options.disassemble_ = true; 96 break; 97 case 'e': // exported items only 98 options.exports_only_ = true; 99 break; 100 case 'f': // display outer file header 101 options.show_file_headers_ = true; 102 break; 103 case 'h': // display section headers, i.e. all meta-data 104 options.show_section_headers_ = true; 105 break; 106 case 'i': // continue even if checksum is bad 107 options.ignore_bad_checksum_ = true; 108 break; 109 case 'l': // layout 110 if (strcmp(optarg, "plain") == 0) { 111 options.output_format_ = kOutputPlain; 112 } else if (strcmp(optarg, "xml") == 0) { 113 options.output_format_ = kOutputXml; 114 options.verbose_ = false; 115 } else { 116 want_usage = true; 117 } 118 break; 119 case 'm': // output dex files to a memmap 120 options.output_to_memmap_ = true; 121 break; 122 case 'o': // output file 123 options.output_file_name_ = optarg; 124 break; 125 case 'p': // profile file 126 options.profile_file_name_ = optarg; 127 break; 128 case 's': // visualize access pattern 129 options.visualize_pattern_ = true; 130 options.verbose_ = false; 131 break; 132 case 't': // display section statistics 133 options.show_section_statistics_ = true; 134 options.verbose_ = false; 135 break; 136 case 'v': // verify output 137 options.verify_output_ = true; 138 break; 139 case 'w': // output dex files directory 140 options.output_dex_directory_ = optarg; 141 break; 142 default: 143 want_usage = true; 144 break; 145 } // switch 146 } // while 147 148 // Detect early problems. 149 if (optind == argc) { 150 fprintf(stderr, "%s: no file specified\n", kProgramName); 151 want_usage = true; 152 } 153 if (options.checksum_only_ && options.ignore_bad_checksum_) { 154 fprintf(stderr, "Can't specify both -c and -i\n"); 155 want_usage = true; 156 } 157 if (want_usage) { 158 Usage(); 159 return 2; 160 } 161 162 // Open alternative output file. 163 FILE* out_file = stdout; 164 if (options.output_file_name_) { 165 out_file = fopen(options.output_file_name_, "w"); 166 if (!out_file) { 167 fprintf(stderr, "Can't open %s\n", options.output_file_name_); 168 return 1; 169 } 170 } 171 172 // Open profile file. 173 ProfileCompilationInfo* profile_info = nullptr; 174 if (options.profile_file_name_) { 175 int profile_fd = open(options.profile_file_name_, O_RDONLY); 176 if (profile_fd < 0) { 177 fprintf(stderr, "Can't open %s\n", options.profile_file_name_); 178 return 1; 179 } 180 profile_info = new ProfileCompilationInfo(); 181 if (!profile_info->Load(profile_fd)) { 182 fprintf(stderr, "Can't read profile info from %s\n", options.profile_file_name_); 183 return 1; 184 } 185 } 186 187 // Create DexLayout instance. 188 DexLayout dex_layout(options, profile_info, out_file); 189 190 // Process all files supplied on command line. 191 int result = 0; 192 while (optind < argc) { 193 result |= dex_layout.ProcessFile(argv[optind++]); 194 } // while 195 return result != 0; 196} 197 198} // namespace art 199 200int main(int argc, char** argv) { 201 return art::DexlayoutDriver(argc, argv); 202} 203