blob: 17631234b31fb18292ec0a29d791a2a008758482 [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.
Shubham Ajmerac12bf4c2017-10-24 16:59:42 -070053 // If a valid zip_fd is provided the file content will be read directly from
54 // the descriptor and `filename` will be used as alias for error logging. If
55 // zip_fd is -1, the method will try to open the `filename` and read the
56 // content from it.
Mathieu Chartier79c87da2017-10-10 11:54:29 -070057 // Return true if the checksums could be found, false otherwise.
58 static bool GetMultiDexChecksums(const char* filename,
59 std::vector<uint32_t>* checksums,
Shubham Ajmerac12bf4c2017-10-24 16:59:42 -070060 std::string* error_msg,
61 int zip_fd = -1);
Mathieu Chartier79c87da2017-10-10 11:54:29 -070062
63 // Check whether a location denotes a multidex dex file. This is a very simple check: returns
64 // whether the string contains the separator character.
65 static bool IsMultiDexLocation(const char* location);
66
67 // Opens .dex file, backed by existing memory
68 static std::unique_ptr<const DexFile> Open(const uint8_t* base,
69 size_t size,
70 const std::string& location,
71 uint32_t location_checksum,
72 const OatDexFile* oat_dex_file,
73 bool verify,
74 bool verify_checksum,
75 std::string* error_msg);
76
77 // Opens .dex file that has been memory-mapped by the caller.
78 static std::unique_ptr<const DexFile> Open(const std::string& location,
79 uint32_t location_checkum,
80 std::unique_ptr<MemMap> mem_map,
81 bool verify,
82 bool verify_checksum,
83 std::string* error_msg);
84
85 // Opens all .dex files found in the file, guessing the container format based on file extension.
86 static bool Open(const char* filename,
87 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +010088 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -070089 bool verify_checksum,
90 std::string* error_msg,
91 std::vector<std::unique_ptr<const DexFile>>* dex_files);
92
93 // Open a single dex file from an fd. This function closes the fd.
94 static std::unique_ptr<const DexFile> OpenDex(int fd,
95 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +010096 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -070097 bool verify_checksum,
98 std::string* error_msg);
99
100 // Opens dex files from within a .jar, .zip, or .apk file
101 static bool OpenZip(int fd,
102 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100103 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700104 bool verify_checksum,
105 std::string* error_msg,
106 std::vector<std::unique_ptr<const DexFile>>* dex_files);
107
108 // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for
109 // index == 0, and classes{index + 1}.dex else.
110 static std::string GetMultiDexClassesDexName(size_t index);
111
112 // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for
113 // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else.
114 static std::string GetMultiDexLocation(size_t index, const char* dex_location);
115
116 // Returns the canonical form of the given dex location.
117 //
118 // There are different flavors of "dex locations" as follows:
119 // the file name of a dex file:
120 // The actual file path that the dex file has on disk.
121 // dex_location:
122 // This acts as a key for the class linker to know which dex file to load.
123 // It may correspond to either an old odex file or a particular dex file
124 // inside an oat file. In the first case it will also match the file name
125 // of the dex file. In the second case (oat) it will include the file name
126 // and possibly some multidex annotation to uniquely identify it.
127 // canonical_dex_location:
128 // the dex_location where it's file name part has been made canonical.
129 static std::string GetDexCanonicalLocation(const char* dex_location);
130
131 // For normal dex files, location and base location coincide. If a dex file is part of a multidex
132 // archive, the base location is the name of the originating jar/apk, stripped of any internal
133 // classes*.dex path.
134 static std::string GetBaseLocation(const char* location) {
135 const char* pos = strrchr(location, kMultiDexSeparator);
136 return (pos == nullptr) ? location : std::string(location, pos - location);
137 }
138
139 static std::string GetBaseLocation(const std::string& location) {
140 return GetBaseLocation(location.c_str());
141 }
142
143 // Returns the '!classes*.dex' part of the dex location. Returns an empty
144 // string if there is no multidex suffix for the given location.
145 // The kMultiDexSeparator is included in the returned suffix.
146 static std::string GetMultiDexSuffix(const std::string& location) {
147 size_t pos = location.rfind(kMultiDexSeparator);
148 return (pos == std::string::npos) ? std::string() : location.substr(pos);
149 }
150
151 private:
152 static std::unique_ptr<const DexFile> OpenFile(int fd,
153 const std::string& location,
154 bool verify,
155 bool verify_checksum,
156 std::string* error_msg);
157
158 enum class ZipOpenErrorCode {
159 kNoError,
160 kEntryNotFound,
161 kExtractToMemoryError,
162 kDexFileError,
163 kMakeReadOnlyError,
164 kVerifyError
165 };
166
167 // Open all classesXXX.dex files from a zip archive.
168 static bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
169 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100170 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700171 bool verify_checksum,
172 std::string* error_msg,
173 std::vector<std::unique_ptr<const DexFile>>* dex_files);
174
175 // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
176 // return.
177 static std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
178 const char* entry_name,
179 const std::string& location,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100180 bool verify,
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700181 bool verify_checksum,
182 std::string* error_msg,
183 ZipOpenErrorCode* error_code);
184
185 enum class VerifyResult { // private
186 kVerifyNotAttempted,
187 kVerifySucceeded,
188 kVerifyFailed
189 };
190
191 static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
192 size_t size,
193 const std::string& location,
194 uint32_t location_checksum,
195 const OatDexFile* oat_dex_file,
196 bool verify,
197 bool verify_checksum,
198 std::string* error_msg,
David Sehr733bd4d2017-10-26 10:39:15 -0700199 DexFileContainer* container,
200 VerifyResult* verify_result);
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700201};
202
203} // namespace art
204
205#endif // ART_RUNTIME_DEX_FILE_LOADER_H_