Brian Carlstrom | b7bbba4 | 2011-10-13 14:58:47 -0700 | [diff] [blame] | 1 | // Copyright 2011 Google Inc. All Rights Reserved. |
| 2 | |
| 3 | #include <stdio.h> |
| 4 | #include <stdlib.h> |
| 5 | |
| 6 | #include "dex_file.h" |
| 7 | #include "file.h" |
| 8 | #include "logging.h" |
| 9 | #include "oat_file.h" |
| 10 | #include "os.h" |
| 11 | #include "UniquePtr.h" |
| 12 | #include "zip_archive.h" |
| 13 | |
| 14 | namespace art { |
| 15 | |
| 16 | int ProcessZipFile(int zip_fd, int cache_fd, const char* zip_name, const char *flags) { |
| 17 | // TODO: need to read/write to installd opened file descriptors |
| 18 | if (false) { |
| 19 | UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(zip_fd)); |
| 20 | if (zip_archive.get() == NULL) { |
| 21 | LOG(ERROR) << "Failed to open " << zip_name << " when looking for classes.dex"; |
| 22 | return -1; |
| 23 | } |
| 24 | |
| 25 | UniquePtr<ZipEntry> zip_entry(zip_archive->Find(DexFile::kClassesDex)); |
| 26 | if (zip_entry.get() == NULL) { |
| 27 | LOG(ERROR) << "Failed to find classes.dex within " << zip_name; |
| 28 | return -1; |
| 29 | } |
| 30 | |
| 31 | UniquePtr<File> file(OS::FileFromFd("oatopt cache file descriptor", cache_fd)); |
| 32 | bool success = zip_entry->Extract(*file); |
| 33 | if (!success) { |
| 34 | LOG(ERROR) << "Failed to extract classes.dex from " << zip_name; |
| 35 | return -1; |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | // Opening a zip file for a dex will extract to art-cache |
| 40 | UniquePtr<const DexFile> dex_file(DexFile::Open(zip_name, "")); |
| 41 | if (dex_file.get() == NULL) { |
| 42 | LOG(ERROR) << "Failed to open " << zip_name; |
| 43 | return -1; |
| 44 | } |
| 45 | |
| 46 | std::string dex_file_option("--dex-file="); |
| 47 | dex_file_option += zip_name; |
| 48 | |
| 49 | std::string oat_file_option("--oat="); |
jeffhao | 262bf46 | 2011-10-20 18:36:32 -0700 | [diff] [blame] | 50 | oat_file_option += GetArtCacheFilenameOrDie(OatFile::DexFilenameToOatFilename(dex_file.get()->GetLocation())); |
Brian Carlstrom | b7bbba4 | 2011-10-13 14:58:47 -0700 | [diff] [blame] | 51 | |
| 52 | execl("/system/bin/dex2oatd", |
| 53 | "/system/bin/dex2oatd", |
jeffhao | 5d84040 | 2011-10-24 17:09:45 -0700 | [diff] [blame] | 54 | "--runtime-arg", "-Xms64m", |
| 55 | "--runtime-arg", "-Xmx64m", |
Brian Carlstrom | b7bbba4 | 2011-10-13 14:58:47 -0700 | [diff] [blame] | 56 | "--boot-image=/data/art-cache/boot.art", |
| 57 | dex_file_option.c_str(), |
| 58 | oat_file_option.c_str(), |
| 59 | NULL); |
| 60 | PLOG(FATAL) << "execl(dex2oatd) failed"; |
| 61 | return -1; |
| 62 | } |
| 63 | |
| 64 | // Parse arguments. We want: |
| 65 | // 0. (name of command -- ignored) |
| 66 | // 1. "--zip" |
| 67 | // 2. zip fd (input, read-only) |
| 68 | // 3. cache fd (output, read-write, locked with flock) |
| 69 | // 4. filename of zipfile |
| 70 | // 5. flags |
| 71 | int FromZip(const int argc, const char* const argv[]) { |
| 72 | if (argc != 6) { |
| 73 | LOG(ERROR) << "Wrong number of args for --zip (found " << argc << ")"; |
| 74 | return -1; |
| 75 | } |
| 76 | |
| 77 | // ignore program name |
| 78 | |
| 79 | // verify --zip |
| 80 | CHECK_STREQ(argv[1], "--zip"); |
| 81 | |
| 82 | char* zip_end; |
| 83 | int zip_fd = strtol(argv[2], &zip_end, 0); |
| 84 | if (*zip_end != '\0') { |
| 85 | LOG(ERROR) << "bad zip fd: " << argv[2]; |
| 86 | return -1; |
| 87 | } |
| 88 | #ifndef NDEBUG |
| 89 | LOG(INFO) << "zip_fd=" << zip_fd; |
| 90 | #endif |
| 91 | |
| 92 | char* cache_end; |
| 93 | int cache_fd = strtol(argv[3], &cache_end, 0); |
| 94 | if (*cache_end != '\0') { |
| 95 | LOG(ERROR) << "bad cache fd: " << argv[3]; |
| 96 | return -1; |
| 97 | } |
| 98 | #ifndef NDEBUG |
| 99 | LOG(INFO) << "cache_fd=" << cache_fd; |
| 100 | #endif |
| 101 | |
| 102 | const char* zip_name = argv[4]; |
| 103 | #ifndef NDEBUG |
| 104 | LOG(INFO) << "zip_name=" << zip_name; |
| 105 | #endif |
| 106 | |
| 107 | const char* flags = argv[5]; |
| 108 | #ifndef NDEBUG |
| 109 | LOG(INFO) << "flags=" << flags; |
| 110 | #endif |
| 111 | |
| 112 | return ProcessZipFile(zip_fd, cache_fd, zip_name, flags); |
| 113 | } |
| 114 | |
| 115 | int oatopt(int argc, char** argv) { |
Brian Carlstrom | b7bbba4 | 2011-10-13 14:58:47 -0700 | [diff] [blame] | 116 | setvbuf(stdout, NULL, _IONBF, 0); |
| 117 | |
| 118 | if (true) { |
| 119 | for (int i = 0; i < argc; ++i) { |
| 120 | LOG(INFO) << "oatopt: option[" << i << "]=" << argv[i]; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | if (argc > 1) { |
| 125 | if (strcmp(argv[1], "--zip") == 0) { |
| 126 | return FromZip(argc, argv); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | fprintf(stderr, |
| 131 | "Usage:\n\n" |
| 132 | "Short version: Don't use this.\n\n" |
| 133 | "Slightly longer version: This system-internal tool is used to extract\n" |
| 134 | "dex files and produce oat files. See the source code for details.\n"); |
| 135 | |
| 136 | return 1; |
| 137 | } |
| 138 | |
| 139 | } // namespace art |
| 140 | |
| 141 | int main(int argc, char** argv) { |
| 142 | return art::oatopt(argc, argv); |
| 143 | } |