blob: 97c886ac7d244176188f8402b0cd6a4cfec3ed41 [file] [log] [blame]
Mathieu Chartier79c87da2017-10-10 11:54:29 -07001/*
2 * Copyright (C) 2017 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
17#ifndef ART_RUNTIME_DEX_FILE_LOADER_H_
18#define ART_RUNTIME_DEX_FILE_LOADER_H_
19
20#include <cstdint>
21#include <memory>
22#include <string>
23#include <vector>
24
25namespace art {
26
27class DexFile;
David Sehr733bd4d2017-10-26 10:39:15 -070028class DexFileContainer;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070029class MemMap;
30class OatDexFile;
31class ZipArchive;
32
33// Class that is used to open dex files and deal with corresponding multidex and location logic.
34class DexFileLoader {
35 public:
36 // name of the DexFile entry within a zip archive
37 static constexpr const char* kClassesDex = "classes.dex";
38
39 // The separator character in MultiDex locations.
40 static constexpr char kMultiDexSeparator = '!';
41
42 // Return true if the magic is valid for dex or cdex.
Mathieu Chartiercf76bf82017-09-25 16:22:36 -070043 static bool IsMagicValid(uint32_t magic);
44 static bool IsMagicValid(const uint8_t* magic);
45
46 // Return true if the corresponding version and magic is valid.
47 static bool IsVersionAndMagicValid(const uint8_t* magic);
Mathieu Chartier79c87da2017-10-10 11:54:29 -070048
49 // Returns the checksums of a file for comparison with GetLocationChecksum().
50 // For .dex files, this is the single header checksum.
51 // For zip files, this is the zip entry CRC32 checksum for classes.dex and
52 // each additional multidex entry classes2.dex, classes3.dex, etc.
53 // Return true if the checksums could be found, false otherwise.
54 static bool GetMultiDexChecksums(const char* filename,
55 std::vector<uint32_t>* checksums,
56 std::string* error_msg);
57
58 // Check whether a location denotes a multidex dex file. This is a very simple check: returns
59 // whether the string contains the separator character.
60 static bool IsMultiDexLocation(const char* location);
61
62 // Opens .dex file, backed by existing memory
63 static std::unique_ptr<const DexFile> Open(const uint8_t* base,
64 size_t size,
65 const std::string& location,
66 uint32_t location_checksum,
67 const OatDexFile* oat_dex_file,
68 bool verify,
69 bool verify_checksum,
70 std::string* error_msg);
71
72 // Opens .dex file that has been memory-mapped by the caller.
73 static std::unique_ptr<const DexFile> Open(const std::string& location,
74 uint32_t location_checkum,
75 std::unique_ptr<MemMap> mem_map,
76 bool verify,
77 bool verify_checksum,
78 std::string* error_msg);
79
80 // Opens all .dex files found in the file, guessing the container format based on file extension.
81 static bool Open(const char* filename,
82 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +010083 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -070084 bool verify_checksum,
85 std::string* error_msg,
86 std::vector<std::unique_ptr<const DexFile>>* dex_files);
87
88 // Open a single dex file from an fd. This function closes the fd.
89 static std::unique_ptr<const DexFile> OpenDex(int fd,
90 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +010091 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -070092 bool verify_checksum,
93 std::string* error_msg);
94
95 // Opens dex files from within a .jar, .zip, or .apk file
96 static bool OpenZip(int fd,
97 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +010098 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -070099 bool verify_checksum,
100 std::string* error_msg,
101 std::vector<std::unique_ptr<const DexFile>>* dex_files);
102
103 // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for
104 // index == 0, and classes{index + 1}.dex else.
105 static std::string GetMultiDexClassesDexName(size_t index);
106
107 // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for
108 // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else.
109 static std::string GetMultiDexLocation(size_t index, const char* dex_location);
110
111 // Returns the canonical form of the given dex location.
112 //
113 // There are different flavors of "dex locations" as follows:
114 // the file name of a dex file:
115 // The actual file path that the dex file has on disk.
116 // dex_location:
117 // This acts as a key for the class linker to know which dex file to load.
118 // It may correspond to either an old odex file or a particular dex file
119 // inside an oat file. In the first case it will also match the file name
120 // of the dex file. In the second case (oat) it will include the file name
121 // and possibly some multidex annotation to uniquely identify it.
122 // canonical_dex_location:
123 // the dex_location where it's file name part has been made canonical.
124 static std::string GetDexCanonicalLocation(const char* dex_location);
125
126 // For normal dex files, location and base location coincide. If a dex file is part of a multidex
127 // archive, the base location is the name of the originating jar/apk, stripped of any internal
128 // classes*.dex path.
129 static std::string GetBaseLocation(const char* location) {
130 const char* pos = strrchr(location, kMultiDexSeparator);
131 return (pos == nullptr) ? location : std::string(location, pos - location);
132 }
133
134 static std::string GetBaseLocation(const std::string& location) {
135 return GetBaseLocation(location.c_str());
136 }
137
138 // Returns the '!classes*.dex' part of the dex location. Returns an empty
139 // string if there is no multidex suffix for the given location.
140 // The kMultiDexSeparator is included in the returned suffix.
141 static std::string GetMultiDexSuffix(const std::string& location) {
142 size_t pos = location.rfind(kMultiDexSeparator);
143 return (pos == std::string::npos) ? std::string() : location.substr(pos);
144 }
145
146 private:
147 static std::unique_ptr<const DexFile> OpenFile(int fd,
148 const std::string& location,
149 bool verify,
150 bool verify_checksum,
151 std::string* error_msg);
152
153 enum class ZipOpenErrorCode {
154 kNoError,
155 kEntryNotFound,
156 kExtractToMemoryError,
157 kDexFileError,
158 kMakeReadOnlyError,
159 kVerifyError
160 };
161
162 // Open all classesXXX.dex files from a zip archive.
163 static bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
164 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100165 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700166 bool verify_checksum,
167 std::string* error_msg,
168 std::vector<std::unique_ptr<const DexFile>>* dex_files);
169
170 // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
171 // return.
172 static std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
173 const char* entry_name,
174 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100175 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700176 bool verify_checksum,
177 std::string* error_msg,
178 ZipOpenErrorCode* error_code);
179
180 enum class VerifyResult { // private
181 kVerifyNotAttempted,
182 kVerifySucceeded,
183 kVerifyFailed
184 };
185
186 static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
187 size_t size,
188 const std::string& location,
189 uint32_t location_checksum,
190 const OatDexFile* oat_dex_file,
191 bool verify,
192 bool verify_checksum,
193 std::string* error_msg,
David Sehr733bd4d2017-10-26 10:39:15 -0700194 DexFileContainer* container,
195 VerifyResult* verify_result);
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700196};
197
198} // namespace art
199
200#endif // ART_RUNTIME_DEX_FILE_LOADER_H_