summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2025-02-12 20:41:56 +0000
committer Jiakai Zhang <jiakaiz@google.com> 2025-02-18 02:37:43 -0800
commit39b153dff377f5f13f5d218088d66f5748100f11 (patch)
tree93cfdb13761976f8c84a62a39ab3d116d0c87f87
parent5bcb526ba52f9bef4b85fcc27c497428425be683 (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.cc1
-rw-r--r--runtime/vdex_file.cc38
-rw-r--r--runtime/vdex_file.h10
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(); }