Fix run-test after introduction of VDEX

Run-test 119-noimage-patchoat used to fail due to a codepath in
OatFile which allows to create an instance of the class from an
existing ElfFile instance. This patch updates the codepath to require
an existing VdexFile as well.

Test: art/test/run-test 119
Bug: 30937355
Change-Id: I8fd0e47f07921aaee999f73711766ada9c35d214
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index cbc5d3c..76b71a3 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -132,6 +132,10 @@
     end_ = end;
   }
 
+  void SetVdex(VdexFile* vdex) {
+    vdex_.reset(vdex);
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(OatFileBase);
 };
@@ -793,6 +797,7 @@
                                  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 @@
 }
 
 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 @@
     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 @@
 }
 
 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 96e651e..a48791e 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -64,7 +64,9 @@
 
   // 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 ba12d33..d8e8573 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -829,6 +829,8 @@
 
     // 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 @@
     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;