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