blob: 6f1afd636ff90cf2cdb17364d420d199d70c54b3 [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
David Sehr9e734c72018-01-04 17:56:19 -080017#ifndef ART_RUNTIME_DEX_DEX_FILE_LOADER_H_
18#define ART_RUNTIME_DEX_DEX_FILE_LOADER_H_
Mathieu Chartier79c87da2017-10-10 11:54:29 -070019
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
David Sehr013fd802018-01-11 22:55:24 -080049 virtual ~DexFileLoader() { }
50
Mathieu Chartier79c87da2017-10-10 11:54:29 -070051 // Returns the checksums of a file for comparison with GetLocationChecksum().
52 // For .dex files, this is the single header checksum.
53 // For zip files, this is the zip entry CRC32 checksum for classes.dex and
54 // each additional multidex entry classes2.dex, classes3.dex, etc.
Shubham Ajmerac12bf4c2017-10-24 16:59:42 -070055 // If a valid zip_fd is provided the file content will be read directly from
56 // the descriptor and `filename` will be used as alias for error logging. If
57 // zip_fd is -1, the method will try to open the `filename` and read the
58 // content from it.
Mathieu Chartier79c87da2017-10-10 11:54:29 -070059 // Return true if the checksums could be found, false otherwise.
David Sehr013fd802018-01-11 22:55:24 -080060 virtual bool GetMultiDexChecksums(const char* filename,
61 std::vector<uint32_t>* checksums,
62 std::string* error_msg,
63 int zip_fd = -1) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070064
65 // Check whether a location denotes a multidex dex file. This is a very simple check: returns
66 // whether the string contains the separator character.
67 static bool IsMultiDexLocation(const char* location);
68
69 // Opens .dex file, backed by existing memory
David Sehr013fd802018-01-11 22:55:24 -080070 virtual std::unique_ptr<const DexFile> Open(const uint8_t* base,
71 size_t size,
72 const std::string& location,
73 uint32_t location_checksum,
74 const OatDexFile* oat_dex_file,
75 bool verify,
76 bool verify_checksum,
77 std::string* error_msg) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070078
79 // Opens .dex file that has been memory-mapped by the caller.
David Sehr013fd802018-01-11 22:55:24 -080080 virtual std::unique_ptr<const DexFile> Open(const std::string& location,
81 uint32_t location_checkum,
82 std::unique_ptr<MemMap> mem_map,
83 bool verify,
84 bool verify_checksum,
85 std::string* error_msg) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070086
87 // Opens all .dex files found in the file, guessing the container format based on file extension.
David Sehr013fd802018-01-11 22:55:24 -080088 virtual bool Open(const char* filename,
89 const std::string& location,
90 bool verify,
91 bool verify_checksum,
92 std::string* error_msg,
93 std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070094
95 // Open a single dex file from an fd. This function closes the fd.
David Sehr013fd802018-01-11 22:55:24 -080096 virtual std::unique_ptr<const DexFile> OpenDex(int fd,
97 const std::string& location,
98 bool verify,
99 bool verify_checksum,
100 std::string* error_msg) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700101
102 // Opens dex files from within a .jar, .zip, or .apk file
David Sehr013fd802018-01-11 22:55:24 -0800103 virtual bool OpenZip(int fd,
104 const std::string& location,
105 bool verify,
106 bool verify_checksum,
107 std::string* error_msg,
108 std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700109
110 // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for
111 // index == 0, and classes{index + 1}.dex else.
112 static std::string GetMultiDexClassesDexName(size_t index);
113
114 // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for
115 // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else.
116 static std::string GetMultiDexLocation(size_t index, const char* dex_location);
117
118 // Returns the canonical form of the given dex location.
119 //
120 // There are different flavors of "dex locations" as follows:
121 // the file name of a dex file:
122 // The actual file path that the dex file has on disk.
123 // dex_location:
124 // This acts as a key for the class linker to know which dex file to load.
125 // It may correspond to either an old odex file or a particular dex file
126 // inside an oat file. In the first case it will also match the file name
127 // of the dex file. In the second case (oat) it will include the file name
128 // and possibly some multidex annotation to uniquely identify it.
129 // canonical_dex_location:
130 // the dex_location where it's file name part has been made canonical.
131 static std::string GetDexCanonicalLocation(const char* dex_location);
132
133 // For normal dex files, location and base location coincide. If a dex file is part of a multidex
134 // archive, the base location is the name of the originating jar/apk, stripped of any internal
135 // classes*.dex path.
136 static std::string GetBaseLocation(const char* location) {
137 const char* pos = strrchr(location, kMultiDexSeparator);
138 return (pos == nullptr) ? location : std::string(location, pos - location);
139 }
140
141 static std::string GetBaseLocation(const std::string& location) {
142 return GetBaseLocation(location.c_str());
143 }
144
145 // Returns the '!classes*.dex' part of the dex location. Returns an empty
146 // string if there is no multidex suffix for the given location.
147 // The kMultiDexSeparator is included in the returned suffix.
148 static std::string GetMultiDexSuffix(const std::string& location) {
149 size_t pos = location.rfind(kMultiDexSeparator);
150 return (pos == std::string::npos) ? std::string() : location.substr(pos);
151 }
152
David Sehr013fd802018-01-11 22:55:24 -0800153 protected:
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700154 enum class ZipOpenErrorCode {
155 kNoError,
156 kEntryNotFound,
157 kExtractToMemoryError,
158 kDexFileError,
159 kMakeReadOnlyError,
160 kVerifyError
161 };
162
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700163 enum class VerifyResult { // private
164 kVerifyNotAttempted,
165 kVerifySucceeded,
166 kVerifyFailed
167 };
168
169 static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
170 size_t size,
171 const std::string& location,
172 uint32_t location_checksum,
173 const OatDexFile* oat_dex_file,
174 bool verify,
175 bool verify_checksum,
176 std::string* error_msg,
David Sehr733bd4d2017-10-26 10:39:15 -0700177 DexFileContainer* container,
178 VerifyResult* verify_result);
David Sehr013fd802018-01-11 22:55:24 -0800179
180 private:
181 virtual std::unique_ptr<const DexFile> OpenFile(int fd,
182 const std::string& location,
183 bool verify,
184 bool verify_checksum,
185 std::string* error_msg) const;
186
187 // Open all classesXXX.dex files from a zip archive.
188 virtual bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
189 const std::string& location,
190 bool verify,
191 bool verify_checksum,
192 std::string* error_msg,
193 std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
194
195 // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
196 // return.
197 virtual std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
198 const char* entry_name,
199 const std::string& location,
200 bool verify,
201 bool verify_checksum,
202 std::string* error_msg,
203 ZipOpenErrorCode* error_code) const;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700204};
205
206} // namespace art
207
David Sehr9e734c72018-01-04 17:56:19 -0800208#endif // ART_RUNTIME_DEX_DEX_FILE_LOADER_H_