diff options
author | 2025-02-12 20:41:56 +0000 | |
---|---|---|
committer | 2025-02-18 02:37:43 -0800 | |
commit | 39b153dff377f5f13f5d218088d66f5748100f11 (patch) | |
tree | 93cfdb13761976f8c84a62a39ab3d116d0c87f87 | |
parent | 5bcb526ba52f9bef4b85fcc27c497428425be683 (diff) |
Support loading a VDEX file from a zip file at an address.
We cannot use the existing VdexFile::OpenFromDm because loading dm along
with sdm has additional map address, map size, and alignment
requirements.
Bug: 377474232
Test: art/test.py --host -g
Change-Id: I9adf7daf0dad440e181ef324a207b359742e2747
-rw-r--r-- | runtime/oat/oat_file.cc | 1 | ||||
-rw-r--r-- | runtime/vdex_file.cc | 38 | ||||
-rw-r--r-- | runtime/vdex_file.h | 10 |
3 files changed, 47 insertions, 2 deletions
diff --git a/runtime/oat/oat_file.cc b/runtime/oat/oat_file.cc index 1652674de7..772d126651 100644 --- a/runtime/oat/oat_file.cc +++ b/runtime/oat/oat_file.cc @@ -346,6 +346,7 @@ bool OatFileBase::LoadVdex(int vdex_fd, vdex_end_ - vdex_begin_, /*mmap_reuse=*/vdex_begin_ != nullptr, vdex_fd, + /*start=*/0, s.st_size, vdex_filename, low_4gb, diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc index 1767d1f359..1d3a9fbe66 100644 --- a/runtime/vdex_file.cc +++ b/runtime/vdex_file.cc @@ -18,6 +18,7 @@ #include <sys/mman.h> // For the PROT_* and MAP_* constants. #include <sys/stat.h> // for mkdir() +#include <sys/types.h> #include <memory> #include <unordered_set> @@ -92,6 +93,7 @@ std::unique_ptr<VdexFile> VdexFile::OpenAtAddress(uint8_t* mmap_addr, mmap_size, mmap_reuse, vdex_file->Fd(), + /*start=*/0, vdex_length, vdex_filename, low_4gb, @@ -102,6 +104,7 @@ std::unique_ptr<VdexFile> VdexFile::OpenAtAddress(uint8_t* mmap_addr, size_t mmap_size, bool mmap_reuse, int file_fd, + off_t start, size_t vdex_length, const std::string& vdex_filename, bool low_4gb, @@ -119,7 +122,7 @@ std::unique_ptr<VdexFile> VdexFile::OpenAtAddress(uint8_t* mmap_addr, PROT_READ | PROT_WRITE, MAP_PRIVATE, file_fd, - /*start=*/0u, + start, low_4gb, vdex_filename.c_str(), mmap_reuse, @@ -168,6 +171,39 @@ std::unique_ptr<VdexFile> VdexFile::OpenFromDm(const std::string& filename, return vdex_file; } +std::unique_ptr<VdexFile> VdexFile::OpenFromDm(const std::string& filename, + uint8_t* vdex_begin_, + uint8_t* vdex_end_, + std::string* error_msg) { + std::string vdex_filename = filename + OatFile::kZipSeparator + kVdexNameInDmFile; + // This overload of `OpenFromDm` is for loading both odex and vdex. We need to map the vdex at the + // address required by the odex, so the vdex must be uncompressed and page-aligned. + // To load vdex only, use the other overload. + FileWithRange vdex_file_with_range = OS::OpenFileDirectlyOrFromZip( + vdex_filename, OatFile::kZipSeparator, /*alignment=*/MemMap::GetPageSize(), error_msg); + if (vdex_file_with_range.file == nullptr) { + return nullptr; + } + std::unique_ptr<VdexFile> vdex_file = + VdexFile::OpenAtAddress(vdex_begin_, + vdex_end_ - vdex_begin_, + /*mmap_reuse=*/vdex_begin_ != nullptr, + vdex_file_with_range.file->Fd(), + vdex_file_with_range.start, + vdex_file_with_range.length, + vdex_filename, + /*low_4gb=*/false, + error_msg); + if (vdex_file == nullptr) { + return nullptr; + } + if (vdex_file->HasDexSection()) { + *error_msg = "The dex metadata is not allowed to contain dex files"; + return nullptr; + } + return vdex_file; +} + const uint8_t* VdexFile::GetNextDexFileData(const uint8_t* cursor, uint32_t dex_file_index) const { DCHECK(cursor == nullptr || (cursor > Begin() && cursor <= End())); if (cursor == nullptr) { diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h index ab3ea1f3b3..4ccc402b32 100644 --- a/runtime/vdex_file.h +++ b/runtime/vdex_file.h @@ -18,6 +18,8 @@ #define ART_RUNTIME_VDEX_FILE_H_ #include <stdint.h> +#include <sys/types.h> + #include <string> #include "base/array_ref.h" @@ -200,6 +202,7 @@ class VdexFile { size_t mmap_size, bool mmap_reuse, int file_fd, + off_t start, size_t vdex_length, const std::string& vdex_filename, bool low_4gb, @@ -219,13 +222,18 @@ class VdexFile { bool low_4gb, std::string* error_msg) { return OpenAtAddress( - nullptr, 0, false, file_fd, vdex_length, vdex_filename, low_4gb, error_msg); + nullptr, 0, false, file_fd, /*start=*/0, vdex_length, vdex_filename, low_4gb, error_msg); } EXPORT static std::unique_ptr<VdexFile> OpenFromDm(const std::string& filename, const ZipArchive& archive, std::string* error_msg); + static std::unique_ptr<VdexFile> OpenFromDm(const std::string& filename, + uint8_t* vdex_begin_, + uint8_t* vdex_end_, + std::string* error_msg); + const uint8_t* Begin() const { return mmap_.Begin(); } const uint8_t* End() const { return mmap_.End(); } size_t Size() const { return mmap_.Size(); } |