xref: /aosp_15_r20/art/libdexfile/dex/dex_file_loader.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <cstdint>
21*795d594fSAndroid Build Coastguard Worker #include <functional>
22*795d594fSAndroid Build Coastguard Worker #include <memory>
23*795d594fSAndroid Build Coastguard Worker #include <optional>
24*795d594fSAndroid Build Coastguard Worker #include <string>
25*795d594fSAndroid Build Coastguard Worker #include <string_view>
26*795d594fSAndroid Build Coastguard Worker #include <utility>
27*795d594fSAndroid Build Coastguard Worker #include <vector>
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker #include "base/os.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/unix_file/fd_file.h"
31*795d594fSAndroid Build Coastguard Worker #include "dex_file.h"
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker namespace art {
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker class MemMap;
36*795d594fSAndroid Build Coastguard Worker class OatDexFile;
37*795d594fSAndroid Build Coastguard Worker class ZipArchive;
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker enum class DexFileLoaderErrorCode {
40*795d594fSAndroid Build Coastguard Worker   kNoError,
41*795d594fSAndroid Build Coastguard Worker   kEntryNotFound,
42*795d594fSAndroid Build Coastguard Worker   kExtractToMemoryError,
43*795d594fSAndroid Build Coastguard Worker   kDexFileError,
44*795d594fSAndroid Build Coastguard Worker   kMakeReadOnlyError,
45*795d594fSAndroid Build Coastguard Worker   kVerifyError
46*795d594fSAndroid Build Coastguard Worker };
47*795d594fSAndroid Build Coastguard Worker 
48*795d594fSAndroid Build Coastguard Worker // Class that is used to open dex files and deal with corresponding multidex and location logic.
49*795d594fSAndroid Build Coastguard Worker class DexFileLoader {
50*795d594fSAndroid Build Coastguard Worker  public:
51*795d594fSAndroid Build Coastguard Worker   // name of the DexFile entry within a zip archive
52*795d594fSAndroid Build Coastguard Worker   static constexpr const char* kClassesDex = "classes.dex";
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker   // The separator character in MultiDex locations.
55*795d594fSAndroid Build Coastguard Worker   static constexpr char kMultiDexSeparator = '!';
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker   // Return true if the magic is valid for dex or cdex.
58*795d594fSAndroid Build Coastguard Worker   static bool IsMagicValid(uint32_t magic);
59*795d594fSAndroid Build Coastguard Worker   static bool IsMagicValid(const uint8_t* magic);
60*795d594fSAndroid Build Coastguard Worker 
61*795d594fSAndroid Build Coastguard Worker   // Return true if the corresponding version and magic is valid.
62*795d594fSAndroid Build Coastguard Worker   static bool IsVersionAndMagicValid(const uint8_t* magic);
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker   // Check whether a location denotes a multidex dex file. This is a very simple check: returns
65*795d594fSAndroid Build Coastguard Worker   // whether the string contains the separator character.
66*795d594fSAndroid Build Coastguard Worker   static bool IsMultiDexLocation(std::string_view location);
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker   // Return the name of the index-th classes.dex in a multidex zip file. This is classes.dex for
69*795d594fSAndroid Build Coastguard Worker   // index == 0, and classes{index + 1}.dex else.
70*795d594fSAndroid Build Coastguard Worker   static std::string GetMultiDexClassesDexName(size_t index);
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker   // Return the (possibly synthetic) dex location for a multidex entry. This is dex_location for
73*795d594fSAndroid Build Coastguard Worker   // index == 0, and dex_location + multi-dex-separator + GetMultiDexClassesDexName(index) else.
74*795d594fSAndroid Build Coastguard Worker   static std::string GetMultiDexLocation(size_t index, const char* dex_location);
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker   // Returns the multidex location and the checksum for each dex file in a zip or a dex container.
77*795d594fSAndroid Build Coastguard Worker   //
78*795d594fSAndroid Build Coastguard Worker   // This uses the source path provided to DexFileLoader constructor.
79*795d594fSAndroid Build Coastguard Worker   //
80*795d594fSAndroid Build Coastguard Worker   // Returns false on error.
81*795d594fSAndroid Build Coastguard Worker   bool GetMultiDexChecksums(/*out*/ std::vector<std::pair<std::string, uint32_t>>* checksums,
82*795d594fSAndroid Build Coastguard Worker                             /*out*/ std::string* error_msg,
83*795d594fSAndroid Build Coastguard Worker                             /*out*/ bool* only_contains_uncompressed_dex = nullptr);
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   // Returns combined checksum of one or more dex files (one checksum for the whole multidex set).
86*795d594fSAndroid Build Coastguard Worker   //
87*795d594fSAndroid Build Coastguard Worker   // This uses the source path provided to DexFileLoader constructor.
88*795d594fSAndroid Build Coastguard Worker   //
89*795d594fSAndroid Build Coastguard Worker   // Returns false on error.  Sets *checksum to nullopt for an empty set.
90*795d594fSAndroid Build Coastguard Worker   bool GetMultiDexChecksum(/*out*/ std::optional<uint32_t>* checksum,
91*795d594fSAndroid Build Coastguard Worker                            /*out*/ std::string* error_msg,
92*795d594fSAndroid Build Coastguard Worker                            /*out*/ bool* only_contains_uncompressed_dex = nullptr);
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker   // Returns combined checksum of one or more dex files (one checksum for the whole multidex set).
95*795d594fSAndroid Build Coastguard Worker   //
96*795d594fSAndroid Build Coastguard Worker   // This uses already open dex files.
97*795d594fSAndroid Build Coastguard Worker   //
98*795d594fSAndroid Build Coastguard Worker   // It starts iteration at index 'i', which must be a primary dex file,
99*795d594fSAndroid Build Coastguard Worker   // and it sets 'i' to the next primary dex file or to end of the array.
100*795d594fSAndroid Build Coastguard Worker   template <typename DexFilePtrVector>  // array|vector<unique_ptr|DexFile|OatDexFile*>.
GetMultiDexChecksum(const DexFilePtrVector & dex_files,size_t * i)101*795d594fSAndroid Build Coastguard Worker   static uint32_t GetMultiDexChecksum(const DexFilePtrVector& dex_files,
102*795d594fSAndroid Build Coastguard Worker                                       /*inout*/ size_t* i) {
103*795d594fSAndroid Build Coastguard Worker     CHECK_LT(*i, dex_files.size()) << "No dex files";
104*795d594fSAndroid Build Coastguard Worker     std::optional<uint32_t> checksum;
105*795d594fSAndroid Build Coastguard Worker     for (; *i < dex_files.size(); ++(*i)) {
106*795d594fSAndroid Build Coastguard Worker       const auto* dex_file = &*dex_files[*i];
107*795d594fSAndroid Build Coastguard Worker       bool is_primary_dex = !IsMultiDexLocation(dex_file->GetLocation());
108*795d594fSAndroid Build Coastguard Worker       if (!checksum.has_value()) {                         // First dex file.
109*795d594fSAndroid Build Coastguard Worker         CHECK(is_primary_dex) << dex_file->GetLocation();  // Expect primary dex.
110*795d594fSAndroid Build Coastguard Worker       } else if (is_primary_dex) {                         // Later dex file.
111*795d594fSAndroid Build Coastguard Worker         break;  // Found another primary dex file, terminate iteration.
112*795d594fSAndroid Build Coastguard Worker       }
113*795d594fSAndroid Build Coastguard Worker       if (!is_primary_dex && dex_file->GetDexVersion() >= DexFile::kDexContainerVersion) {
114*795d594fSAndroid Build Coastguard Worker         if (dex_file->GetLocationChecksum() == dex_files[*i - 1]->GetLocationChecksum() + 1) {
115*795d594fSAndroid Build Coastguard Worker           continue;
116*795d594fSAndroid Build Coastguard Worker         }
117*795d594fSAndroid Build Coastguard Worker       }
118*795d594fSAndroid Build Coastguard Worker       checksum = checksum.value_or(kEmptyMultiDexChecksum) ^ dex_file->GetLocationChecksum();
119*795d594fSAndroid Build Coastguard Worker     }
120*795d594fSAndroid Build Coastguard Worker     CHECK(checksum.has_value());
121*795d594fSAndroid Build Coastguard Worker     return checksum.value();
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   // Calculate checksum of dex files in a vector, starting at index 0.
125*795d594fSAndroid Build Coastguard Worker   // It will CHECK that the whole vector is consumed (i.e. there is just one primary dex file).
126*795d594fSAndroid Build Coastguard Worker   template <typename DexFilePtrVector>
GetMultiDexChecksum(const DexFilePtrVector & dex_files)127*795d594fSAndroid Build Coastguard Worker   static uint32_t GetMultiDexChecksum(const DexFilePtrVector& dex_files) {
128*795d594fSAndroid Build Coastguard Worker     size_t i = 0;
129*795d594fSAndroid Build Coastguard Worker     uint32_t checksum = GetMultiDexChecksum(dex_files, &i);
130*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(i, dex_files.size());
131*795d594fSAndroid Build Coastguard Worker     return checksum;
132*795d594fSAndroid Build Coastguard Worker   }
133*795d594fSAndroid Build Coastguard Worker 
134*795d594fSAndroid Build Coastguard Worker   // Non-zero initial value for multi-dex to catch bugs if multi-dex checksum is compared
135*795d594fSAndroid Build Coastguard Worker   // directly to DexFile::GetLocationChecksum without going through GetMultiDexChecksum.
136*795d594fSAndroid Build Coastguard Worker   static constexpr uint32_t kEmptyMultiDexChecksum = 1;
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // Returns the canonical form of the given dex location.
139*795d594fSAndroid Build Coastguard Worker   //
140*795d594fSAndroid Build Coastguard Worker   // There are different flavors of "dex locations" as follows:
141*795d594fSAndroid Build Coastguard Worker   // the file name of a dex file:
142*795d594fSAndroid Build Coastguard Worker   //     The actual file path that the dex file has on disk.
143*795d594fSAndroid Build Coastguard Worker   // dex_location:
144*795d594fSAndroid Build Coastguard Worker   //     This acts as a key for the class linker to know which dex file to load.
145*795d594fSAndroid Build Coastguard Worker   //     It may correspond to either an old odex file or a particular dex file
146*795d594fSAndroid Build Coastguard Worker   //     inside an oat file. In the first case it will also match the file name
147*795d594fSAndroid Build Coastguard Worker   //     of the dex file. In the second case (oat) it will include the file name
148*795d594fSAndroid Build Coastguard Worker   //     and possibly some multidex annotation to uniquely identify it.
149*795d594fSAndroid Build Coastguard Worker   // canonical_dex_location:
150*795d594fSAndroid Build Coastguard Worker   //     the dex_location where its file name part has been made canonical.
151*795d594fSAndroid Build Coastguard Worker   static std::string GetDexCanonicalLocation(const char* dex_location);
152*795d594fSAndroid Build Coastguard Worker 
153*795d594fSAndroid Build Coastguard Worker   // For normal dex files, location and base location coincide. If a dex file is part of a multidex
154*795d594fSAndroid Build Coastguard Worker   // archive, the base location is the name of the originating jar/apk, stripped of any internal
155*795d594fSAndroid Build Coastguard Worker   // classes*.dex path.
GetBaseLocation(const char * location)156*795d594fSAndroid Build Coastguard Worker   static std::string GetBaseLocation(const char* location) {
157*795d594fSAndroid Build Coastguard Worker     const char* pos = strrchr(location, kMultiDexSeparator);
158*795d594fSAndroid Build Coastguard Worker     return (pos == nullptr) ? location : std::string(location, pos - location);
159*795d594fSAndroid Build Coastguard Worker   }
160*795d594fSAndroid Build Coastguard Worker 
GetBaseLocation(const std::string & location)161*795d594fSAndroid Build Coastguard Worker   static std::string GetBaseLocation(const std::string& location) {
162*795d594fSAndroid Build Coastguard Worker     return GetBaseLocation(location.c_str());
163*795d594fSAndroid Build Coastguard Worker   }
164*795d594fSAndroid Build Coastguard Worker 
165*795d594fSAndroid Build Coastguard Worker   // Returns the '!classes*.dex' part of the dex location. Returns an empty
166*795d594fSAndroid Build Coastguard Worker   // string if there is no multidex suffix for the given location.
167*795d594fSAndroid Build Coastguard Worker   // The kMultiDexSeparator is included in the returned suffix.
GetMultiDexSuffix(const std::string & location)168*795d594fSAndroid Build Coastguard Worker   static std::string GetMultiDexSuffix(const std::string& location) {
169*795d594fSAndroid Build Coastguard Worker     size_t pos = location.rfind(kMultiDexSeparator);
170*795d594fSAndroid Build Coastguard Worker     return (pos == std::string::npos) ? std::string() : location.substr(pos);
171*795d594fSAndroid Build Coastguard Worker   }
172*795d594fSAndroid Build Coastguard Worker 
DexFileLoader(const char * filename,const File * file,const std::string & location)173*795d594fSAndroid Build Coastguard Worker   DexFileLoader(const char* filename, const File* file, const std::string& location)
174*795d594fSAndroid Build Coastguard Worker       : filename_(filename), file_(file), location_(location) {
175*795d594fSAndroid Build Coastguard Worker     CHECK(file != nullptr);  // Must be non-null, but may be invalid.
176*795d594fSAndroid Build Coastguard Worker   }
177*795d594fSAndroid Build Coastguard Worker 
DexFileLoader(std::shared_ptr<DexFileContainer> container,const std::string & location)178*795d594fSAndroid Build Coastguard Worker   DexFileLoader(std::shared_ptr<DexFileContainer> container, const std::string& location)
179*795d594fSAndroid Build Coastguard Worker       : root_container_(std::move(container)), location_(location) {
180*795d594fSAndroid Build Coastguard Worker     CHECK(root_container_ != nullptr);
181*795d594fSAndroid Build Coastguard Worker   }
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   DexFileLoader(const uint8_t* base, size_t size, const std::string& location);
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker   DexFileLoader(std::vector<uint8_t>&& memory, const std::string& location);
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker   DexFileLoader(MemMap&& mem_map, const std::string& location);
188*795d594fSAndroid Build Coastguard Worker 
DexFileLoader(File * file,const std::string & location)189*795d594fSAndroid Build Coastguard Worker   DexFileLoader(File* file, const std::string& location)
190*795d594fSAndroid Build Coastguard Worker       : DexFileLoader(/*filename=*/location.c_str(), file, location) {}
191*795d594fSAndroid Build Coastguard Worker 
DexFileLoader(const char * filename,const std::string & location)192*795d594fSAndroid Build Coastguard Worker   DexFileLoader(const char* filename, const std::string& location)
193*795d594fSAndroid Build Coastguard Worker       : DexFileLoader(filename, /*file=*/&kInvalidFile, location) {}
194*795d594fSAndroid Build Coastguard Worker 
DexFileLoader(const std::string & location)195*795d594fSAndroid Build Coastguard Worker   explicit DexFileLoader(const std::string& location)
196*795d594fSAndroid Build Coastguard Worker       : DexFileLoader(location.c_str(), /*file=*/&kInvalidFile, location) {}
197*795d594fSAndroid Build Coastguard Worker 
~DexFileLoader()198*795d594fSAndroid Build Coastguard Worker   virtual ~DexFileLoader() {}
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker   // Open singe dex file at the given offset within the container (usually 0).
201*795d594fSAndroid Build Coastguard Worker   // This intentionally ignores all other dex files in the container
202*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> OpenOne(size_t header_offset,
203*795d594fSAndroid Build Coastguard Worker                                          uint32_t location_checksum,
204*795d594fSAndroid Build Coastguard Worker                                          const OatDexFile* oat_dex_file,
205*795d594fSAndroid Build Coastguard Worker                                          bool verify,
206*795d594fSAndroid Build Coastguard Worker                                          bool verify_checksum,
207*795d594fSAndroid Build Coastguard Worker                                          std::string* error_msg);
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker   // Open single dex file (starting at offset 0 of the container).
210*795d594fSAndroid Build Coastguard Worker   // It expects only single dex file to be present and will fail otherwise.
Open(uint32_t location_checksum,const OatDexFile * oat_dex_file,bool verify,bool verify_checksum,std::string * error_msg)211*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> Open(uint32_t location_checksum,
212*795d594fSAndroid Build Coastguard Worker                                       const OatDexFile* oat_dex_file,
213*795d594fSAndroid Build Coastguard Worker                                       bool verify,
214*795d594fSAndroid Build Coastguard Worker                                       bool verify_checksum,
215*795d594fSAndroid Build Coastguard Worker                                       std::string* error_msg) {
216*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<const DexFile> dex_file = OpenOne(
217*795d594fSAndroid Build Coastguard Worker         /*header_offset=*/0, location_checksum, oat_dex_file, verify, verify_checksum, error_msg);
218*795d594fSAndroid Build Coastguard Worker     // This API returns only singe DEX file, so check there is just single dex in the container.
219*795d594fSAndroid Build Coastguard Worker     CHECK(dex_file == nullptr || dex_file->IsDexContainerLastEntry()) << location_;
220*795d594fSAndroid Build Coastguard Worker     return dex_file;
221*795d594fSAndroid Build Coastguard Worker   }
222*795d594fSAndroid Build Coastguard Worker 
Open(uint32_t location_checksum,bool verify,bool verify_checksum,std::string * error_msg)223*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> Open(uint32_t location_checksum,
224*795d594fSAndroid Build Coastguard Worker                                       bool verify,
225*795d594fSAndroid Build Coastguard Worker                                       bool verify_checksum,
226*795d594fSAndroid Build Coastguard Worker                                       std::string* error_msg) {
227*795d594fSAndroid Build Coastguard Worker     return Open(location_checksum,
228*795d594fSAndroid Build Coastguard Worker                 /*oat_dex_file=*/nullptr,
229*795d594fSAndroid Build Coastguard Worker                 verify,
230*795d594fSAndroid Build Coastguard Worker                 verify_checksum,
231*795d594fSAndroid Build Coastguard Worker                 error_msg);
232*795d594fSAndroid Build Coastguard Worker   }
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   // Opens all dex files, guessing the container format based on file magic.
235*795d594fSAndroid Build Coastguard Worker   bool Open(bool verify,
236*795d594fSAndroid Build Coastguard Worker             bool verify_checksum,
237*795d594fSAndroid Build Coastguard Worker             bool allow_no_dex_files,
238*795d594fSAndroid Build Coastguard Worker             DexFileLoaderErrorCode* error_code,
239*795d594fSAndroid Build Coastguard Worker             std::string* error_msg,
240*795d594fSAndroid Build Coastguard Worker             std::vector<std::unique_ptr<const DexFile>>* dex_files);
241*795d594fSAndroid Build Coastguard Worker 
Open(bool verify,bool verify_checksum,DexFileLoaderErrorCode * error_code,std::string * error_msg,std::vector<std::unique_ptr<const DexFile>> * dex_files)242*795d594fSAndroid Build Coastguard Worker   bool Open(bool verify,
243*795d594fSAndroid Build Coastguard Worker             bool verify_checksum,
244*795d594fSAndroid Build Coastguard Worker             DexFileLoaderErrorCode* error_code,
245*795d594fSAndroid Build Coastguard Worker             std::string* error_msg,
246*795d594fSAndroid Build Coastguard Worker             std::vector<std::unique_ptr<const DexFile>>* dex_files) {
247*795d594fSAndroid Build Coastguard Worker     return Open(verify,
248*795d594fSAndroid Build Coastguard Worker                 verify_checksum,
249*795d594fSAndroid Build Coastguard Worker                 /*allow_no_dex_files=*/false,
250*795d594fSAndroid Build Coastguard Worker                 error_code,
251*795d594fSAndroid Build Coastguard Worker                 error_msg,
252*795d594fSAndroid Build Coastguard Worker                 dex_files);
253*795d594fSAndroid Build Coastguard Worker   }
254*795d594fSAndroid Build Coastguard Worker 
Open(bool verify,bool verify_checksum,bool allow_no_dex_files,std::string * error_msg,std::vector<std::unique_ptr<const DexFile>> * dex_files)255*795d594fSAndroid Build Coastguard Worker   bool Open(bool verify,
256*795d594fSAndroid Build Coastguard Worker             bool verify_checksum,
257*795d594fSAndroid Build Coastguard Worker             bool allow_no_dex_files,
258*795d594fSAndroid Build Coastguard Worker             std::string* error_msg,
259*795d594fSAndroid Build Coastguard Worker             std::vector<std::unique_ptr<const DexFile>>* dex_files) {
260*795d594fSAndroid Build Coastguard Worker     DexFileLoaderErrorCode error_code;
261*795d594fSAndroid Build Coastguard Worker     return Open(verify, verify_checksum, allow_no_dex_files, &error_code, error_msg, dex_files);
262*795d594fSAndroid Build Coastguard Worker   }
263*795d594fSAndroid Build Coastguard Worker 
Open(bool verify,bool verify_checksum,std::string * error_msg,std::vector<std::unique_ptr<const DexFile>> * dex_files)264*795d594fSAndroid Build Coastguard Worker   bool Open(bool verify,
265*795d594fSAndroid Build Coastguard Worker             bool verify_checksum,
266*795d594fSAndroid Build Coastguard Worker             std::string* error_msg,
267*795d594fSAndroid Build Coastguard Worker             std::vector<std::unique_ptr<const DexFile>>* dex_files) {
268*795d594fSAndroid Build Coastguard Worker     DexFileLoaderErrorCode error_code;
269*795d594fSAndroid Build Coastguard Worker     return Open(verify,
270*795d594fSAndroid Build Coastguard Worker                 verify_checksum,
271*795d594fSAndroid Build Coastguard Worker                 /*allow_no_dex_files=*/false,
272*795d594fSAndroid Build Coastguard Worker                 &error_code,
273*795d594fSAndroid Build Coastguard Worker                 error_msg,
274*795d594fSAndroid Build Coastguard Worker                 dex_files);
275*795d594fSAndroid Build Coastguard Worker   }
276*795d594fSAndroid Build Coastguard Worker 
277*795d594fSAndroid Build Coastguard Worker  protected:
278*795d594fSAndroid Build Coastguard Worker   static const File kInvalidFile;  // Used for "no file descriptor" (-1).
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker   bool InitAndReadMagic(size_t header_offset, uint32_t* magic, std::string* error_msg);
281*795d594fSAndroid Build Coastguard Worker 
282*795d594fSAndroid Build Coastguard Worker   // Ensure we have root container.  If we are backed by a file, memory-map it.
283*795d594fSAndroid Build Coastguard Worker   // We can only do this for dex files since zip files might be too big to map.
284*795d594fSAndroid Build Coastguard Worker   bool MapRootContainer(std::string* error_msg);
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker   static std::unique_ptr<DexFile> OpenCommon(std::shared_ptr<DexFileContainer> container,
287*795d594fSAndroid Build Coastguard Worker                                              const uint8_t* base,
288*795d594fSAndroid Build Coastguard Worker                                              size_t size,
289*795d594fSAndroid Build Coastguard Worker                                              const std::string& location,
290*795d594fSAndroid Build Coastguard Worker                                              std::optional<uint32_t> location_checksum,
291*795d594fSAndroid Build Coastguard Worker                                              const OatDexFile* oat_dex_file,
292*795d594fSAndroid Build Coastguard Worker                                              bool verify,
293*795d594fSAndroid Build Coastguard Worker                                              bool verify_checksum,
294*795d594fSAndroid Build Coastguard Worker                                              std::string* error_msg,
295*795d594fSAndroid Build Coastguard Worker                                              DexFileLoaderErrorCode* error_code);
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   // Old signature preserved for app-compat.
298*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> Open(const uint8_t* base,
299*795d594fSAndroid Build Coastguard Worker                                       size_t size,
300*795d594fSAndroid Build Coastguard Worker                                       const std::string& location,
301*795d594fSAndroid Build Coastguard Worker                                       uint32_t location_checksum,
302*795d594fSAndroid Build Coastguard Worker                                       const OatDexFile* oat_dex_file,
303*795d594fSAndroid Build Coastguard Worker                                       bool verify,
304*795d594fSAndroid Build Coastguard Worker                                       bool verify_checksum,
305*795d594fSAndroid Build Coastguard Worker                                       std::string* error_msg,
306*795d594fSAndroid Build Coastguard Worker                                       std::unique_ptr<DexFileContainer> container) const;
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker   // Old signature preserved for app-compat.
309*795d594fSAndroid Build Coastguard Worker   enum VerifyResult {};
310*795d594fSAndroid Build Coastguard Worker   static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
311*795d594fSAndroid Build Coastguard Worker                                              size_t size,
312*795d594fSAndroid Build Coastguard Worker                                              const uint8_t* data_base,
313*795d594fSAndroid Build Coastguard Worker                                              size_t data_size,
314*795d594fSAndroid Build Coastguard Worker                                              const std::string& location,
315*795d594fSAndroid Build Coastguard Worker                                              uint32_t location_checksum,
316*795d594fSAndroid Build Coastguard Worker                                              const OatDexFile* oat_dex_file,
317*795d594fSAndroid Build Coastguard Worker                                              bool verify,
318*795d594fSAndroid Build Coastguard Worker                                              bool verify_checksum,
319*795d594fSAndroid Build Coastguard Worker                                              std::string* error_msg,
320*795d594fSAndroid Build Coastguard Worker                                              std::unique_ptr<DexFileContainer> container,
321*795d594fSAndroid Build Coastguard Worker                                              VerifyResult* verify_result);
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker   // Open .dex files from the entry_name in a zip archive.
324*795d594fSAndroid Build Coastguard Worker   bool OpenFromZipEntry(const ZipArchive& zip_archive,
325*795d594fSAndroid Build Coastguard Worker                         const char* entry_name,
326*795d594fSAndroid Build Coastguard Worker                         const std::string& location,
327*795d594fSAndroid Build Coastguard Worker                         bool verify,
328*795d594fSAndroid Build Coastguard Worker                         bool verify_checksum,
329*795d594fSAndroid Build Coastguard Worker                         /*inout*/ size_t* multidex_count,
330*795d594fSAndroid Build Coastguard Worker                         /*out*/ DexFileLoaderErrorCode* error_code,
331*795d594fSAndroid Build Coastguard Worker                         /*out*/ std::string* error_msg,
332*795d594fSAndroid Build Coastguard Worker                         /*out*/ std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
333*795d594fSAndroid Build Coastguard Worker 
334*795d594fSAndroid Build Coastguard Worker   // The DexFileLoader can be backed either by file or by memory (i.e. DexFileContainer).
335*795d594fSAndroid Build Coastguard Worker   // We can not just mmap the file since APKs might be unreasonably large for 32-bit system.
336*795d594fSAndroid Build Coastguard Worker   std::string filename_;
337*795d594fSAndroid Build Coastguard Worker   const File* file_ = &kInvalidFile;
338*795d594fSAndroid Build Coastguard Worker   std::optional<File> owned_file_;  // May be used as backing storage for 'file_'.
339*795d594fSAndroid Build Coastguard Worker   std::shared_ptr<DexFileContainer> root_container_;
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker   // The full absolute path to the dex file, if it was loaded from disk.
342*795d594fSAndroid Build Coastguard Worker   //
343*795d594fSAndroid Build Coastguard Worker   // Can also be a path to a multidex container (typically apk), followed by
344*795d594fSAndroid Build Coastguard Worker   // kMultiDexSeparator and the file inside the container.
345*795d594fSAndroid Build Coastguard Worker   //
346*795d594fSAndroid Build Coastguard Worker   // On host this may not be an absolute path.
347*795d594fSAndroid Build Coastguard Worker   //
348*795d594fSAndroid Build Coastguard Worker   // On device libnativeloader uses this to determine the location of the java
349*795d594fSAndroid Build Coastguard Worker   // package or shared library, which decides where to load native libraries
350*795d594fSAndroid Build Coastguard Worker   // from.
351*795d594fSAndroid Build Coastguard Worker   const std::string location_;
352*795d594fSAndroid Build Coastguard Worker };
353*795d594fSAndroid Build Coastguard Worker 
354*795d594fSAndroid Build Coastguard Worker }  // namespace art
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker #endif  // ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_
357