diff options
| -rw-r--r-- | runtime/oat_file.cc | 10 | ||||
| -rw-r--r-- | runtime/oat_file.h | 4 | ||||
| -rw-r--r-- | runtime/runtime.cc | 24 |
3 files changed, 31 insertions, 7 deletions
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index cbc5d3c209..76b71a3271 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -132,6 +132,10 @@ class OatFileBase : public OatFile { end_ = end; } + void SetVdex(VdexFile* vdex) { + vdex_.reset(vdex); + } + private: DISALLOW_COPY_AND_ASSIGN(OatFileBase); }; @@ -793,6 +797,7 @@ class ElfOatFile FINAL : public OatFileBase { std::string* error_msg); bool InitializeFromElfFile(ElfFile* elf_file, + VdexFile* vdex_file, const char* abs_dex_location, std::string* error_msg); @@ -869,6 +874,7 @@ ElfOatFile* ElfOatFile::OpenElfFile(File* file, } bool ElfOatFile::InitializeFromElfFile(ElfFile* elf_file, + VdexFile* vdex_file, const char* abs_dex_location, std::string* error_msg) { ScopedTrace trace(__PRETTY_FUNCTION__); @@ -877,6 +883,7 @@ bool ElfOatFile::InitializeFromElfFile(ElfFile* elf_file, return false; } elf_file_.reset(elf_file); + SetVdex(vdex_file); uint64_t offset, size; bool has_section = elf_file->GetSectionOffsetAndSize(".rodata", &offset, &size); CHECK(has_section); @@ -958,11 +965,12 @@ static void CheckLocation(const std::string& location) { } OatFile* OatFile::OpenWithElfFile(ElfFile* elf_file, + VdexFile* vdex_file, const std::string& location, const char* abs_dex_location, std::string* error_msg) { std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, false /* executable */)); - return oat_file->InitializeFromElfFile(elf_file, abs_dex_location, error_msg) + return oat_file->InitializeFromElfFile(elf_file, vdex_file, abs_dex_location, error_msg) ? oat_file.release() : nullptr; } diff --git a/runtime/oat_file.h b/runtime/oat_file.h index 96e651e446..a48791ee73 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -64,7 +64,9 @@ class OatFile { // Opens an oat file contained within the given elf file. This is always opened as // non-executable at the moment. - static OatFile* OpenWithElfFile(ElfFile* elf_file, const std::string& location, + static OatFile* OpenWithElfFile(ElfFile* elf_file, + VdexFile* vdex_file, + const std::string& location, const char* abs_dex_location, std::string* error_msg); // Open an oat file. Returns null on failure. Requested base can diff --git a/runtime/runtime.cc b/runtime/runtime.cc index ba12d33ca2..d8e857354e 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -829,6 +829,8 @@ static bool OpenDexFilesFromImage(const std::string& image_location, // We are falling back to non-executable use of the oat file because patching failed, presumably // due to lack of space. + std::string vdex_filename = + ImageHeader::GetVdexLocationFromImageLocation(system_filename.c_str()); std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(system_filename.c_str()); std::string oat_location = @@ -838,22 +840,34 @@ static bool OpenDexFilesFromImage(const std::string& image_location, if (EndsWith(oat_location, ".jar")) { oat_location.replace(oat_location.length() - 3, 3, "oat"); } + std::string error_msg; + + std::unique_ptr<VdexFile> vdex_file(VdexFile::Open(vdex_filename, + false /* writable */, + false /* low_4gb */, + &error_msg)); + if (vdex_file.get() == nullptr) { + return false; + } std::unique_ptr<File> file(OS::OpenFileForReading(oat_filename.c_str())); if (file.get() == nullptr) { return false; } - std::string error_msg; std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file.release(), - false, - false, - /*low_4gb*/false, + false /* writable */, + false /* program_header_only */, + false /* low_4gb */, &error_msg)); if (elf_file.get() == nullptr) { return false; } std::unique_ptr<const OatFile> oat_file( - OatFile::OpenWithElfFile(elf_file.release(), oat_location, nullptr, &error_msg)); + OatFile::OpenWithElfFile(elf_file.release(), + vdex_file.release(), + oat_location, + nullptr, + &error_msg)); if (oat_file == nullptr) { LOG(WARNING) << "Unable to use '" << oat_filename << "' because " << error_msg; return false; |