Refactor Dex open methods

Consolidate dex opening around a simpler single interface in DexFile.
Making this change prior to moving all but the simplest interface out of
dex_file.{cc,h}.

Bug: 22322814
Change-Id: I4c55019912a19a1c90f9022c20f5b8b954fc7a47
Test: test-art-{host,target}
diff --git a/profman/profman.cc b/profman/profman.cc
index a5fefa7..7722e80 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -280,18 +280,11 @@
     for (size_t i = 0; i < dex_locations_.size(); ++i) {
       std::string error_msg;
       std::vector<std::unique_ptr<const DexFile>> dex_files_for_location;
-      std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(apks_fd_[i],
-                                                                     dex_locations_[i].c_str(),
-                                                                     &error_msg));
-      if (zip_archive == nullptr) {
-        LOG(WARNING) << "OpenFromFd failed for '" << dex_locations_[i] << "' " << error_msg;
-        continue;
-      }
-      if (DexFile::OpenFromZip(*zip_archive,
-                               dex_locations_[i],
-                               kVerifyChecksum,
-                               &error_msg,
-                               &dex_files_for_location)) {
+      if (DexFile::OpenZip(apks_fd_[i],
+                           dex_locations_[i],
+                           kVerifyChecksum,
+                           &error_msg,
+                           &dex_files_for_location)) {
       } else {
         LOG(WARNING) << "OpenFromZip failed for '" << dex_locations_[i] << "' " << error_msg;
         continue;
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 5e0ee6f..a27a389 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -1269,7 +1269,6 @@
                                                 old_dex_file->Size(),
                                                 location->ToModifiedUtf8(),
                                                 0u,
-                                                nullptr,
                                                 nullptr));
   {
     WriterMutexLock mu(soa.Self(), *class_linker->DexLock());
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 03223b0..70b7f87 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -52,6 +52,10 @@
 
 namespace art {
 
+static constexpr OatDexFile* kNoOatDexFile = nullptr;
+
+const char* DexFile::kClassesDex = "classes.dex";
+
 const uint8_t DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
 const uint8_t DexFile::kDexMagicVersions[DexFile::kNumDexVersions][DexFile::kDexVersionLen] = {
   {'0', '3', '5', '\0'},
@@ -118,64 +122,6 @@
   return false;
 }
 
-bool DexFile::Open(const char* filename,
-                   const char* location,
-                   bool verify_checksum,
-                   std::string* error_msg,
-                   std::vector<std::unique_ptr<const DexFile>>* dex_files) {
-  ScopedTrace trace(std::string("Open dex file ") + location);
-  DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";
-  uint32_t magic;
-  File fd = OpenAndReadMagic(filename, &magic, error_msg);
-  if (fd.Fd() == -1) {
-    DCHECK(!error_msg->empty());
-    return false;
-  }
-  if (IsZipMagic(magic)) {
-    return DexFile::OpenZip(fd.Release(), location, verify_checksum, error_msg, dex_files);
-  }
-  if (IsDexMagic(magic)) {
-    std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.Release(),
-                                                              location,
-                                                              /* verify */ true,
-                                                              verify_checksum,
-                                                              error_msg));
-    if (dex_file.get() != nullptr) {
-      dex_files->push_back(std::move(dex_file));
-      return true;
-    } else {
-      return false;
-    }
-  }
-  *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
-  return false;
-}
-
-static bool ContainsClassesDex(int fd, const char* filename) {
-  std::string error_msg;
-  std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(fd, filename, &error_msg));
-  if (zip_archive.get() == nullptr) {
-    return false;
-  }
-  std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(DexFile::kClassesDex, &error_msg));
-  return (zip_entry.get() != nullptr);
-}
-
-bool DexFile::MaybeDex(const char* filename) {
-  uint32_t magic;
-  std::string error_msg;
-  File fd = OpenAndReadMagic(filename, &magic, &error_msg);
-  if (fd.Fd() == -1) {
-    return false;
-  }
-  if (IsZipMagic(magic)) {
-    return ContainsClassesDex(fd.Release(), filename);
-  } else if (IsDexMagic(magic)) {
-    return true;
-  }
-  return false;
-}
-
 int DexFile::GetPermissions() const {
   if (mem_map_.get() == nullptr) {
     return 0;
@@ -206,7 +152,9 @@
   }
 }
 
-std::unique_ptr<const DexFile> DexFile::Open(const uint8_t* base, size_t size,
+
+std::unique_ptr<const DexFile> DexFile::Open(const uint8_t* base,
+                                             size_t size,
                                              const std::string& location,
                                              uint32_t location_checksum,
                                              const OatDexFile* oat_dex_file,
@@ -214,118 +162,78 @@
                                              bool verify_checksum,
                                              std::string* error_msg) {
   ScopedTrace trace(std::string("Open dex file from RAM ") + location);
-  std::unique_ptr<const DexFile> dex_file = OpenMemory(base,
-                                                       size,
-                                                       location,
-                                                       location_checksum,
-                                                       nullptr,
-                                                       oat_dex_file,
-                                                       error_msg);
-  if (dex_file == nullptr) {
-    return nullptr;
-  }
-
-  if (verify && !DexFileVerifier::Verify(dex_file.get(),
-                                         dex_file->Begin(),
-                                         dex_file->Size(),
-                                         location.c_str(),
-                                         verify_checksum,
-                                         error_msg)) {
-    return nullptr;
-  }
-  return dex_file;
+  return OpenCommon(base,
+                    size,
+                    location,
+                    location_checksum,
+                    oat_dex_file,
+                    verify,
+                    verify_checksum,
+                    error_msg);
 }
 
 std::unique_ptr<const DexFile> DexFile::Open(const std::string& location,
                                              uint32_t location_checksum,
-                                             std::unique_ptr<MemMap> mem_map,
+                                             std::unique_ptr<MemMap> map,
                                              bool verify,
                                              bool verify_checksum,
                                              std::string* error_msg) {
   ScopedTrace trace(std::string("Open dex file from mapped-memory ") + location);
-  std::unique_ptr<const DexFile> dex_file = OpenMemory(location,
-                                                       location_checksum,
-                                                       std::move(mem_map),
-                                                       error_msg);
-  if (dex_file == nullptr) {
-    return nullptr;
-  }
-
-  if (verify && !DexFileVerifier::Verify(dex_file.get(),
-                                         dex_file->Begin(),
-                                         dex_file->Size(),
-                                         location.c_str(),
-                                         verify_checksum,
-                                         error_msg)) {
-    return nullptr;
+  CHECK(map.get() != nullptr);
+  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
+                                                 map->Size(),
+                                                 location,
+                                                 location_checksum,
+                                                 kNoOatDexFile,
+                                                 verify,
+                                                 verify_checksum,
+                                                 error_msg);
+  if (dex_file != nullptr) {
+    dex_file->mem_map_.reset(map.release());
   }
   return dex_file;
 }
 
-std::unique_ptr<const DexFile> DexFile::OpenFile(int fd,
-                                                 const char* location,
-                                                 bool verify,
-                                                 bool verify_checksum,
-                                                 std::string* error_msg) {
-  ScopedTrace trace(std::string("Open dex file ") + location);
-  CHECK(location != nullptr);
-  std::unique_ptr<MemMap> map;
-  {
-    File delayed_close(fd, /* check_usage */ false);
-    struct stat sbuf;
-    memset(&sbuf, 0, sizeof(sbuf));
-    if (fstat(fd, &sbuf) == -1) {
-      *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location, strerror(errno));
-      return nullptr;
-    }
-    if (S_ISDIR(sbuf.st_mode)) {
-      *error_msg = StringPrintf("Attempt to mmap directory '%s'", location);
-      return nullptr;
-    }
-    size_t length = sbuf.st_size;
-    map.reset(MemMap::MapFile(length,
-                              PROT_READ,
-                              MAP_PRIVATE,
-                              fd,
-                              0,
-                              /*low_4gb*/false,
-                              location,
-                              error_msg));
-    if (map == nullptr) {
-      DCHECK(!error_msg->empty());
-      return nullptr;
+bool DexFile::Open(const char* filename,
+                   const std::string& location,
+                   bool verify_checksum,
+                   std::string* error_msg,
+                   std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+  ScopedTrace trace(std::string("Open dex file ") + std::string(location));
+  DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";
+  uint32_t magic;
+  File fd = OpenAndReadMagic(filename, &magic, error_msg);
+  if (fd.Fd() == -1) {
+    DCHECK(!error_msg->empty());
+    return false;
+  }
+  if (IsZipMagic(magic)) {
+    return DexFile::OpenZip(fd.Release(), location, verify_checksum, error_msg, dex_files);
+  }
+  if (IsDexMagic(magic)) {
+    std::unique_ptr<const DexFile> dex_file(DexFile::OpenFile(fd.Release(),
+                                                              location,
+                                                              /* verify */ true,
+                                                              verify_checksum,
+                                                              error_msg));
+    if (dex_file.get() != nullptr) {
+      dex_files->push_back(std::move(dex_file));
+      return true;
+    } else {
+      return false;
     }
   }
-
-  if (map->Size() < sizeof(DexFile::Header)) {
-    *error_msg = StringPrintf(
-        "DexFile: failed to open dex file '%s' that is too short to have a header", location);
-    return nullptr;
-  }
-
-  const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
-
-  std::unique_ptr<const DexFile> dex_file(OpenMemory(location,
-                                                     dex_header->checksum_,
-                                                     std::move(map),
-                                                     error_msg));
-  if (dex_file.get() == nullptr) {
-    *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location,
-                              error_msg->c_str());
-    return nullptr;
-  }
-
-  if (verify && !DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(),
-                                         location,
-                                         verify_checksum,
-                                         error_msg)) {
-    return nullptr;
-  }
-
-  return dex_file;
+  *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
+  return false;
 }
 
-const char* DexFile::kClassesDex = "classes.dex";
+std::unique_ptr<const DexFile> DexFile::OpenDex(int fd,
+                                                const std::string& location,
+                                                bool verify_checksum,
+                                                std::string* error_msg) {
+  ScopedTrace trace("Open dex file " + std::string(location));
+  return OpenFile(fd, location, true /* verify */, verify_checksum, error_msg);
+}
 
 bool DexFile::OpenZip(int fd,
                       const std::string& location,
@@ -339,28 +247,79 @@
     DCHECK(!error_msg->empty());
     return false;
   }
-  return DexFile::OpenFromZip(*zip_archive, location, verify_checksum, error_msg, dex_files);
+  return DexFile::OpenAllDexFilesFromZip(*zip_archive,
+                                         location,
+                                         verify_checksum,
+                                         error_msg,
+                                         dex_files);
 }
 
-std::unique_ptr<const DexFile> DexFile::OpenMemory(const std::string& location,
-                                                   uint32_t location_checksum,
-                                                   std::unique_ptr<MemMap> mem_map,
-                                                   std::string* error_msg) {
-  return OpenMemory(mem_map->Begin(),
-                    mem_map->Size(),
-                    location,
-                    location_checksum,
-                    std::move(mem_map),
-                    nullptr,
-                    error_msg);
+std::unique_ptr<const DexFile> DexFile::OpenFile(int fd,
+                                                 const std::string& location,
+                                                 bool verify,
+                                                 bool verify_checksum,
+                                                 std::string* error_msg) {
+  ScopedTrace trace(std::string("Open dex file ") + std::string(location));
+  CHECK(!location.empty());
+  std::unique_ptr<MemMap> map;
+  {
+    File delayed_close(fd, /* check_usage */ false);
+    struct stat sbuf;
+    memset(&sbuf, 0, sizeof(sbuf));
+    if (fstat(fd, &sbuf) == -1) {
+      *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location.c_str(),
+                                strerror(errno));
+      return nullptr;
+    }
+    if (S_ISDIR(sbuf.st_mode)) {
+      *error_msg = StringPrintf("Attempt to mmap directory '%s'", location.c_str());
+      return nullptr;
+    }
+    size_t length = sbuf.st_size;
+    map.reset(MemMap::MapFile(length,
+                              PROT_READ,
+                              MAP_PRIVATE,
+                              fd,
+                              0,
+                              /*low_4gb*/false,
+                              location.c_str(),
+                              error_msg));
+    if (map == nullptr) {
+      DCHECK(!error_msg->empty());
+      return nullptr;
+    }
+  }
+
+  if (map->Size() < sizeof(DexFile::Header)) {
+    *error_msg = StringPrintf(
+        "DexFile: failed to open dex file '%s' that is too short to have a header",
+        location.c_str());
+    return nullptr;
+  }
+
+  const Header* dex_header = reinterpret_cast<const Header*>(map->Begin());
+
+  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
+                                                 map->Size(),
+                                                 location,
+                                                 dex_header->checksum_,
+                                                 kNoOatDexFile,
+                                                 verify,
+                                                 verify_checksum,
+                                                 error_msg);
+  if (dex_file != nullptr) {
+    dex_file->mem_map_.reset(map.release());
+  }
+
+  return dex_file;
 }
 
-std::unique_ptr<const DexFile> DexFile::Open(const ZipArchive& zip_archive,
-                                             const char* entry_name,
-                                             const std::string& location,
-                                             bool verify_checksum,
-                                             std::string* error_msg,
-                                             ZipOpenErrorCode* error_code) {
+std::unique_ptr<const DexFile> DexFile::OpenOneDexFileFromZip(const ZipArchive& zip_archive,
+                                                              const char* entry_name,
+                                                              const std::string& location,
+                                                              bool verify_checksum,
+                                                              std::string* error_msg,
+                                                              ZipOpenErrorCode* error_code) {
   ScopedTrace trace("Dex file open from Zip Archive " + std::string(location));
   CHECK(!location.empty());
   std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
@@ -380,15 +339,18 @@
     *error_code = ZipOpenErrorCode::kExtractToMemoryError;
     return nullptr;
   }
-  std::unique_ptr<const DexFile> dex_file(OpenMemory(location,
-                                                     zip_entry->GetCrc32(),
-                                                     std::move(map),
-                                                     error_msg));
-  if (dex_file == nullptr) {
-    *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),
-                              error_msg->c_str());
-    *error_code = ZipOpenErrorCode::kDexFileError;
-    return nullptr;
+  VerifyResult verify_result;
+  std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(),
+                                                 map->Size(),
+                                                 location,
+                                                 zip_entry->GetCrc32(),
+                                                 kNoOatDexFile,
+                                                 /* verify */ true,
+                                                 verify_checksum,
+                                                 error_msg,
+                                                 &verify_result);
+  if (dex_file != nullptr) {
+    dex_file->mem_map_.reset(map.release());
   }
   if (!dex_file->DisableWrite()) {
     *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
@@ -396,10 +358,7 @@
     return nullptr;
   }
   CHECK(dex_file->IsReadOnly()) << location;
-  if (!DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(),
-                               location.c_str(),
-                               verify_checksum,
-                               error_msg)) {
+  if (verify_result != VerifyResult::kVerifySucceeded) {
     *error_code = ZipOpenErrorCode::kVerifyError;
     return nullptr;
   }
@@ -413,16 +372,20 @@
 // seems an excessive number.
 static constexpr size_t kWarnOnManyDexFilesThreshold = 100;
 
-bool DexFile::OpenFromZip(const ZipArchive& zip_archive,
-                          const std::string& location,
-                          bool verify_checksum,
-                          std::string* error_msg,
-                          std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+bool DexFile::OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
+                                     const std::string& location,
+                                     bool verify_checksum,
+                                     std::string* error_msg,
+                                     std::vector<std::unique_ptr<const DexFile>>* dex_files) {
   ScopedTrace trace("Dex file open from Zip " + std::string(location));
   DCHECK(dex_files != nullptr) << "DexFile::OpenFromZip: out-param is nullptr";
   ZipOpenErrorCode error_code;
-  std::unique_ptr<const DexFile> dex_file(
-      Open(zip_archive, kClassesDex, location, verify_checksum, error_msg, &error_code));
+  std::unique_ptr<const DexFile> dex_file(OpenOneDexFileFromZip(zip_archive,
+                                                                kClassesDex,
+                                                                location,
+                                                                verify_checksum,
+                                                                error_msg,
+                                                                &error_code));
   if (dex_file.get() == nullptr) {
     return false;
   } else {
@@ -437,8 +400,12 @@
     for (size_t i = 1; ; ++i) {
       std::string name = GetMultiDexClassesDexName(i);
       std::string fake_location = GetMultiDexLocation(i, location.c_str());
-      std::unique_ptr<const DexFile> next_dex_file(
-          Open(zip_archive, name.c_str(), fake_location, verify_checksum, error_msg, &error_code));
+      std::unique_ptr<const DexFile> next_dex_file(OpenOneDexFileFromZip(zip_archive,
+                                                                         name.c_str(),
+                                                                         fake_location,
+                                                                         verify_checksum,
+                                                                         error_msg,
+                                                                         &error_code));
       if (next_dex_file.get() == nullptr) {
         if (error_code != ZipOpenErrorCode::kEntryNotFound) {
           LOG(WARNING) << error_msg;
@@ -464,35 +431,55 @@
   }
 }
 
-
-std::unique_ptr<const DexFile> DexFile::OpenMemory(const uint8_t* base,
-                                                   size_t size,
-                                                   const std::string& location,
-                                                   uint32_t location_checksum,
-                                                   std::unique_ptr<MemMap> mem_map,
-                                                   const OatDexFile* oat_dex_file,
-                                                   std::string* error_msg) {
-  DCHECK(base != nullptr);
-  DCHECK_NE(size, 0U);
-  CHECK_ALIGNED(base, 4);  // various dex file structures must be word aligned
-  std::unique_ptr<DexFile> dex_file(
-      new DexFile(base, size, location, location_checksum, std::move(mem_map), oat_dex_file));
+std::unique_ptr<DexFile> DexFile::OpenCommon(const uint8_t* base,
+                                             size_t size,
+                                             const std::string& location,
+                                             uint32_t location_checksum,
+                                             const OatDexFile* oat_dex_file,
+                                             bool verify,
+                                             bool verify_checksum,
+                                             std::string* error_msg,
+                                             VerifyResult* verify_result) {
+  std::unique_ptr<DexFile> dex_file(new DexFile(base,
+                                                size,
+                                                location,
+                                                location_checksum,
+                                                oat_dex_file));
+  if (dex_file == nullptr) {
+    *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),
+                              error_msg->c_str());
+    return nullptr;
+  }
   if (!dex_file->Init(error_msg)) {
     dex_file.reset();
+    return nullptr;
   }
-  return std::unique_ptr<const DexFile>(dex_file.release());
+  if (verify && !DexFileVerifier::Verify(dex_file.get(),
+                                         dex_file->Begin(),
+                                         dex_file->Size(),
+                                         location.c_str(),
+                                         verify_checksum,
+                                         error_msg)) {
+    if (verify_result != nullptr) {
+      *verify_result = VerifyResult::kVerifyFailed;
+    }
+    return nullptr;
+  }
+  if (verify_result != nullptr) {
+    *verify_result = VerifyResult::kVerifySucceeded;
+  }
+  return dex_file;
 }
 
-DexFile::DexFile(const uint8_t* base, size_t size,
+DexFile::DexFile(const uint8_t* base,
+                 size_t size,
                  const std::string& location,
                  uint32_t location_checksum,
-                 std::unique_ptr<MemMap> mem_map,
                  const OatDexFile* oat_dex_file)
     : begin_(base),
       size_(size),
       location_(location),
       location_checksum_(location_checksum),
-      mem_map_(std::move(mem_map)),
       header_(reinterpret_cast<const Header*>(base)),
       string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)),
       type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)),
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 97c2596..14bde09 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -397,15 +397,9 @@
   // Return true if the checksum could be found, false otherwise.
   static bool GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg);
 
-  // Opens .dex files found in the container, guessing the container format based on file extension.
-  static bool Open(const char* filename,
-                   const char* location,
-                   bool verify_checksum,
-                   std::string* error_msg,
-                   std::vector<std::unique_ptr<const DexFile>>* dex_files);
-
   // Opens .dex file, backed by existing memory
-  static std::unique_ptr<const DexFile> Open(const uint8_t* base, size_t size,
+  static std::unique_ptr<const DexFile> Open(const uint8_t* base,
+                                             size_t size,
                                              const std::string& location,
                                              uint32_t location_checksum,
                                              const OatDexFile* oat_dex_file,
@@ -421,16 +415,25 @@
                                              bool verify_checksum,
                                              std::string* error_msg);
 
-  // Checks whether the given file has the dex magic, or is a zip file with a classes.dex entry.
-  // If this function returns false, Open will not succeed. The inverse is not true, however.
-  static bool MaybeDex(const char* filename);
+  // Opens all .dex files found in the file, guessing the container format based on file extension.
+  static bool Open(const char* filename,
+                   const std::string& location,
+                   bool verify_checksum,
+                   std::string* error_msg,
+                   std::vector<std::unique_ptr<const DexFile>>* dex_files);
 
-  // Open all classesXXX.dex files from a zip archive.
-  static bool OpenFromZip(const ZipArchive& zip_archive,
-                          const std::string& location,
-                          bool verify_checksum,
-                          std::string* error_msg,
-                          std::vector<std::unique_ptr<const DexFile>>* dex_files);
+  // Open a single dex file from an fd.
+  static std::unique_ptr<const DexFile> OpenDex(int fd,
+                                                const std::string& location,
+                                                bool verify_checksum,
+                                                std::string* error_msg);
+
+  // Opens dex files from within a .jar, .zip, or .apk file
+  static bool OpenZip(int fd,
+                      const std::string& location,
+                      bool verify_checksum,
+                      std::string* error_msg,
+                      std::vector<std::unique_ptr<const DexFile>>* dex_files);
 
   // Closes a .dex file.
   virtual ~DexFile();
@@ -1011,20 +1014,12 @@
   static uint64_t ReadUnsignedLong(const uint8_t* ptr, int zwidth, bool fill_on_right);
 
  private:
-  // Opens a .dex file
   static std::unique_ptr<const DexFile> OpenFile(int fd,
-                                                 const char* location,
+                                                 const std::string& location,
                                                  bool verify,
                                                  bool verify_checksum,
                                                  std::string* error_msg);
 
-  // Opens dex files from within a .jar, .zip, or .apk file
-  static bool OpenZip(int fd,
-                      const std::string& location,
-                      bool verify_checksum,
-                      std::string* error_msg,
-                      std::vector<std::unique_ptr<const DexFile>>* dex_files);
-
   enum class ZipOpenErrorCode {  // private
     kNoError,
     kEntryNotFound,
@@ -1034,34 +1029,41 @@
     kVerifyError
   };
 
+  // Open all classesXXX.dex files from a zip archive.
+  static bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
+                                     const std::string& location,
+                                     bool verify_checksum,
+                                     std::string* error_msg,
+                                     std::vector<std::unique_ptr<const DexFile>>* dex_files);
+
   // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
   // return.
-  static std::unique_ptr<const DexFile> Open(const ZipArchive& zip_archive,
-                                             const char* entry_name,
+  static std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
+                                                              const char* entry_name,
+                                                              const std::string& location,
+                                                              bool verify_checksum,
+                                                              std::string* error_msg,
+                                                              ZipOpenErrorCode* error_code);
+
+  enum class VerifyResult {  // private
+    kVerifySucceeded,
+    kVerifyFailed
+  };
+
+  static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base,
+                                             size_t size,
                                              const std::string& location,
+                                             uint32_t location_checksum,
+                                             const OatDexFile* oat_dex_file,
+                                             bool verify,
                                              bool verify_checksum,
                                              std::string* error_msg,
-                                             ZipOpenErrorCode* error_code);
+                                             VerifyResult* verify_result = nullptr);
 
-  // Opens a .dex file at the given address backed by a MemMap
-  static std::unique_ptr<const DexFile> OpenMemory(const std::string& location,
-                                                   uint32_t location_checksum,
-                                                   std::unique_ptr<MemMap> mem_map,
-                                                   std::string* error_msg);
-
-  // Opens a .dex file at the given address, optionally backed by a MemMap
-  static std::unique_ptr<const DexFile> OpenMemory(const uint8_t* dex_file,
-                                                   size_t size,
-                                                   const std::string& location,
-                                                   uint32_t location_checksum,
-                                                   std::unique_ptr<MemMap> mem_map,
-                                                   const OatDexFile* oat_dex_file,
-                                                   std::string* error_msg);
-
-  DexFile(const uint8_t* base, size_t size,
+  DexFile(const uint8_t* base,
+          size_t size,
           const std::string& location,
           uint32_t location_checksum,
-          std::unique_ptr<MemMap> mem_map,
           const OatDexFile* oat_dex_file);
 
   // Top-level initializer that calls other Init methods.
diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc
index 71c0ad9..5939ef3 100644
--- a/runtime/dex_file_verifier_test.cc
+++ b/runtime/dex_file_verifier_test.cc
@@ -123,7 +123,7 @@
 class DexFileVerifierTest : public CommonRuntimeTest {
  protected:
   DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
-    return new DexFile(dex_bytes, length, "tmp", 0, nullptr, nullptr);
+    return new DexFile(dex_bytes, length, "tmp", 0, nullptr);
   }
 
   void VerifyModification(const char* dex_file_base64_content,