Add DEX SHA1 to oat files.

Add SHA1 since it is much more reliable then CRC32/Adler.

CHECK that it matches with location checksum comparison.

We sill rely on the location checksum, this just ensures
that in the very unlikely case of CRC collision we crash,
rather than accept the DEX and later mysteriously fail.

Test: ./art/test.py -b --host --64
Change-Id: I51af02f63c9ce8b858e4e8b4363bb75f8774d477
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index 41e9cdb..67d2003 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -278,6 +278,7 @@
 
   // The checksum of the dex file.
   const uint32_t dex_file_location_checksum_;
+  const DexFile::Sha1 dex_file_sha1_;
 
   // Offset of the dex file in the vdex file. Set when writing dex files in
   // SeekToDexFile.
@@ -2640,6 +2641,7 @@
     DO_STAT(size_oat_dex_file_location_size_);
     DO_STAT(size_oat_dex_file_location_data_);
     DO_STAT(size_oat_dex_file_location_checksum_);
+    DO_STAT(size_oat_dex_file_sha1_);
     DO_STAT(size_oat_dex_file_offset_);
     DO_STAT(size_oat_dex_file_class_offsets_offset_);
     DO_STAT(size_oat_dex_file_lookup_table_offset_);
@@ -3421,6 +3423,7 @@
     }
   }
   CHECK_EQ(oat_dex_file->dex_file_location_checksum_, dex_file->GetLocationChecksum());
+  CHECK(oat_dex_file->dex_file_sha1_ == dex_file->GetSha1());
   return true;
 }
 
@@ -3799,6 +3802,7 @@
       dex_file_location_size_(strlen(dex_file_location_->c_str())),
       dex_file_location_data_(dex_file_location_->c_str()),
       dex_file_location_checksum_(dex_file_->GetLocationChecksum()),
+      dex_file_sha1_(dex_file_->GetSha1()),
       dex_file_offset_(0u),
       lookup_table_offset_(0u),
       class_offsets_offset_(0u),
@@ -3811,18 +3815,12 @@
       class_offsets_() {}
 
 size_t OatWriter::OatDexFile::SizeOf() const {
-  return sizeof(dex_file_location_size_)
-          + dex_file_location_size_
-          + sizeof(dex_file_location_checksum_)
-          + sizeof(dex_file_offset_)
-          + sizeof(class_offsets_offset_)
-          + sizeof(lookup_table_offset_)
-          + sizeof(method_bss_mapping_offset_)
-          + sizeof(type_bss_mapping_offset_)
-          + sizeof(public_type_bss_mapping_offset_)
-          + sizeof(package_type_bss_mapping_offset_)
-          + sizeof(string_bss_mapping_offset_)
-          + sizeof(dex_sections_layout_offset_);
+  return sizeof(dex_file_location_size_) + dex_file_location_size_ +
+         sizeof(dex_file_location_checksum_) + sizeof(dex_file_sha1_) + sizeof(dex_file_offset_) +
+         sizeof(class_offsets_offset_) + sizeof(lookup_table_offset_) +
+         sizeof(method_bss_mapping_offset_) + sizeof(type_bss_mapping_offset_) +
+         sizeof(public_type_bss_mapping_offset_) + sizeof(package_type_bss_mapping_offset_) +
+         sizeof(string_bss_mapping_offset_) + sizeof(dex_sections_layout_offset_);
 }
 
 bool OatWriter::OatDexFile::Write(OatWriter* oat_writer, OutputStream* out) const {
@@ -3847,6 +3845,12 @@
   }
   oat_writer->size_oat_dex_file_location_checksum_ += sizeof(dex_file_location_checksum_);
 
+  if (!out->WriteFully(&dex_file_sha1_, sizeof(dex_file_sha1_))) {
+    PLOG(ERROR) << "Failed to write dex file sha1 to " << out->GetLocation();
+    return false;
+  }
+  oat_writer->size_oat_dex_file_sha1_ += sizeof(dex_file_sha1_);
+
   if (!out->WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) {
     PLOG(ERROR) << "Failed to write dex file offset to " << out->GetLocation();
     return false;
diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h
index a10572a..623c4db 100644
--- a/dex2oat/linker/oat_writer.h
+++ b/dex2oat/linker/oat_writer.h
@@ -526,6 +526,7 @@
   uint32_t size_oat_dex_file_location_size_;
   uint32_t size_oat_dex_file_location_data_;
   uint32_t size_oat_dex_file_location_checksum_;
+  uint32_t size_oat_dex_file_sha1_ = 0;
   uint32_t size_oat_dex_file_offset_;
   uint32_t size_oat_dex_file_class_offsets_offset_;
   uint32_t size_oat_dex_file_lookup_table_offset_;
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index 6742cf77..6ec15e2 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -463,9 +463,7 @@
 
   ASSERT_TRUE(java_lang_dex_file_ != nullptr);
   const DexFile& dex_file = *java_lang_dex_file_;
-  uint32_t dex_file_checksum = dex_file.GetLocationChecksum();
-  const OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation().c_str(),
-                                                           &dex_file_checksum);
+  const OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation().c_str());
   ASSERT_TRUE(oat_dex_file != nullptr);
   CHECK_EQ(dex_file.GetLocationChecksum(), oat_dex_file->GetDexFileLocationChecksum());
   ScopedObjectAccess soa(Thread::Current());
diff --git a/dexlayout/compact_dex_writer.cc b/dexlayout/compact_dex_writer.cc
index b8c6ebe2..b07a956 100644
--- a/dexlayout/compact_dex_writer.cc
+++ b/dexlayout/compact_dex_writer.cc
@@ -270,7 +270,7 @@
   CompactDexFile::WriteMagic(&header.magic_[0]);
   CompactDexFile::WriteCurrentVersion(&header.magic_[0]);
   header.checksum_ = header_->Checksum();
-  std::copy_n(header_->Signature(), DexFile::kSha1DigestSize, header.signature_);
+  header.signature_ = header_->Signature();
   header.file_size_ = header_->FileSize();
   // Since we are not necessarily outputting the same format as the input, avoid using the stored
   // header size.
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index c819c67..2471aae 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -359,7 +359,7 @@
  public:
   Header(const uint8_t* magic,
          uint32_t checksum,
-         const uint8_t* signature,
+         DexFile::Sha1 signature,
          uint32_t endian_tag,
          uint32_t file_size,
          uint32_t header_size,
@@ -383,7 +383,7 @@
 
   Header(const uint8_t* magic,
          uint32_t checksum,
-         const uint8_t* signature,
+         DexFile::Sha1 signature,
          uint32_t endian_tag,
          uint32_t file_size,
          uint32_t header_size,
@@ -423,7 +423,7 @@
 
   const uint8_t* Magic() const { return magic_; }
   uint32_t Checksum() const { return checksum_; }
-  const uint8_t* Signature() const { return signature_; }
+  DexFile::Sha1 Signature() const { return signature_; }
   uint32_t EndianTag() const { return endian_tag_; }
   uint32_t FileSize() const { return file_size_; }
   uint32_t HeaderSize() const { return header_size_; }
@@ -433,9 +433,7 @@
   uint32_t DataOffset() const { return data_offset_; }
 
   void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
-  void SetSignature(const uint8_t* new_signature) {
-    memcpy(signature_, new_signature, sizeof(signature_));
-  }
+  void SetSignature(DexFile::Sha1 new_signature) { signature_ = new_signature; }
   void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
   void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
   void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
@@ -522,7 +520,7 @@
  private:
   uint8_t magic_[8];
   uint32_t checksum_;
-  uint8_t signature_[DexFile::kSha1DigestSize];
+  DexFile::Sha1 signature_;
   uint32_t endian_tag_;
   uint32_t file_size_;
   uint32_t header_size_;
@@ -534,7 +532,7 @@
 
   void ConstructorHelper(const uint8_t* magic,
                          uint32_t checksum,
-                         const uint8_t* signature,
+                         DexFile::Sha1 signature,
                          uint32_t endian_tag,
                          uint32_t file_size,
                          uint32_t header_size,
@@ -551,7 +549,7 @@
     data_size_ = data_size;
     data_offset_ = data_offset;
     memcpy(magic_, magic, sizeof(magic_));
-    memcpy(signature_, signature, sizeof(signature_));
+    signature_ = signature;
   }
 
   // Collection vectors own the IR data.
diff --git a/dexlayout/dex_writer.cc b/dexlayout/dex_writer.cc
index e7473c0..3966753 100644
--- a/dexlayout/dex_writer.cc
+++ b/dexlayout/dex_writer.cc
@@ -804,7 +804,7 @@
     std::copy_n(header_->Magic(), kMagicAndVersionLen, header.magic_);
   }
   header.checksum_ = header_->Checksum();
-  std::copy_n(header_->Signature(), DexFile::kSha1DigestSize, header.signature_);
+  header.signature_ = header_->Signature();
   header.file_size_ = header_->FileSize();
   header.header_size_ = GetHeaderSize();
   header.endian_tag_ = header_->EndianTag();
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index 8179559..55a9c08 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -61,6 +61,13 @@
 static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong");
 static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial");
 
+// Print the SHA1 as 20-byte hexadecimal string.
+std::string DexFile::Sha1::ToString() const {
+  auto data = this->data();
+  auto part = [d = data](int i) { return d[i] << 24 | d[i + 1] << 16 | d[i + 2] << 8 | d[i + 3]; };
+  return StringPrintf("%08x%08x%08x%08x%08x", part(0), part(4), part(8), part(12), part(16));
+}
+
 uint32_t DexFile::CalculateChecksum() const {
   return CalculateChecksum(Begin(), Size());
 }
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 1d1b016..af2bb74 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -19,6 +19,7 @@
 
 #include <android-base/logging.h>
 
+#include <array>
 #include <memory>
 #include <optional>
 #include <string>
@@ -124,11 +125,17 @@
   static constexpr uint16_t kDexNoIndex16 = 0xFFFF;
   static constexpr uint32_t kDexNoIndex32 = 0xFFFFFFFF;
 
+  struct Sha1 : public std::array<uint8_t, kSha1DigestSize> {
+    std::string ToString() const;
+  };
+
+  static_assert(std::is_standard_layout_v<Sha1>);
+
   // Raw header_item.
   struct Header {
     uint8_t magic_[8] = {};
     uint32_t checksum_ = 0;  // See also location_checksum_
-    uint8_t signature_[kSha1DigestSize] = {};
+    Sha1 signature_ = {};
     uint32_t file_size_ = 0;  // size of entire file
     uint32_t header_size_ = 0;  // offset to start of next section
     uint32_t endian_tag_ = 0;
@@ -245,6 +252,8 @@
     return location_checksum_;
   }
 
+  Sha1 GetSha1() const { return header_->signature_; }
+
   const Header& GetHeader() const {
     DCHECK(header_ != nullptr) << GetLocation();
     return *header_;
diff --git a/libdexfile/dex/dex_file_loader_test.cc b/libdexfile/dex/dex_file_loader_test.cc
index 8abe9a4..515ec1a 100644
--- a/libdexfile/dex/dex_file_loader_test.cc
+++ b/libdexfile/dex/dex_file_loader_test.cc
@@ -358,16 +358,15 @@
     /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
     /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
   };
-  static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
-    0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
-    0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
-    0x2e, 0xf2, 0x8c, 0x3d,
+  static const DexFile::Sha1 kExpectedSha1 = {
+      0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5, 0x89, 0xe8,
+      0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18, 0x2e, 0xf2, 0x8c, 0x3d,
   };
 
   const DexFile::Header& header = dex_file->GetHeader();
   EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
   EXPECT_EQ(0x00d87910U, header.checksum_);
-  EXPECT_EQ(*kExpectedSha1, *header.signature_);
+  EXPECT_EQ(kExpectedSha1, header.signature_);
   EXPECT_EQ(904U, header.file_size_);
   EXPECT_EQ(112U, header.header_size_);
   EXPECT_EQ(0U, header.link_size_);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index eb75c6b..f307d71 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1824,7 +1824,7 @@
     REQUIRES_SHARED(Locks::mutator_lock_) {
   DCHECK(error_msg != nullptr);
   std::unique_ptr<const DexFile> dex_file;
-  const OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, nullptr, error_msg);
+  const OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, error_msg);
   if (oat_dex_file == nullptr) {
     return std::unique_ptr<const DexFile>();
   }
@@ -1839,12 +1839,14 @@
   }
 
   if (dex_file->GetLocationChecksum() != oat_dex_file->GetDexFileLocationChecksum()) {
+    CHECK(dex_file->GetSha1() != oat_dex_file->GetSha1());
     *error_msg = StringPrintf("Checksums do not match for %s: %x vs %x",
                               location,
                               dex_file->GetLocationChecksum(),
                               oat_dex_file->GetDexFileLocationChecksum());
     return std::unique_ptr<const DexFile>();
   }
+  CHECK(dex_file->GetSha1() == oat_dex_file->GetSha1());
   return dex_file;
 }
 
diff --git a/runtime/oat.h b/runtime/oat.h
index d65f19a..65d3a5e 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -44,8 +44,8 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr std::array<uint8_t, 4> kOatMagic { { 'o', 'a', 't', '\n' } };
-  // Last oat version changed reason: Reduce multidex checksum to single scalar value.
-  static constexpr std::array<uint8_t, 4> kOatVersion{{'2', '3', '1', '\0'}};
+  // Last oat version changed reason: Add DEX SHA1 to oat files.
+  static constexpr std::array<uint8_t, 4> kOatVersion{{'2', '3', '2', '\0'}};
 
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
   static constexpr const char* kDebuggableKey = "debuggable";
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index c75a9ec..1d8a76a 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -547,13 +547,13 @@
       return false;
     }
     // Create an OatDexFile and add it to the owning container.
-    OatDexFile* oat_dex_file = new OatDexFile(
-        this,
-        dex_file->Begin(),
-        dex_file->GetLocationChecksum(),
-        dex_location,
-        canonical_location,
-        type_lookup_table_data);
+    OatDexFile* oat_dex_file = new OatDexFile(this,
+                                              dex_file->Begin(),
+                                              dex_file->GetLocationChecksum(),
+                                              dex_file->GetSha1(),
+                                              dex_location,
+                                              canonical_location,
+                                              type_lookup_table_data);
     oat_dex_files_storage_.push_back(oat_dex_file);
 
     // Add the location and canonical location (if different) to the oat_dex_files_ table.
@@ -753,6 +753,16 @@
       return false;
     }
 
+    DexFile::Sha1 dex_file_sha1;
+    if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_sha1))) {
+      *error_msg = StringPrintf(
+          "In oat file '%s' found OatDexFile #%zu for '%s' truncated after dex file sha1",
+          GetLocation().c_str(),
+          i,
+          dex_file_location.c_str());
+      return false;
+    }
+
     uint32_t dex_file_offset;
     if (UNLIKELY(!ReadOatDexFileData(*this, &oat, &dex_file_offset))) {
       *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' truncated "
@@ -848,6 +858,7 @@
       // expects this check to happen during oat file setup when the oat file
       // does not contain dex code.
       if (dex_file_checksum != external_dex_files_[i]->GetLocationChecksum()) {
+        CHECK(dex_file_sha1 != external_dex_files_[i]->GetSha1());
         *error_msg = StringPrintf("In oat file '%s', dex file checksum 0x%08x does not match"
                                       " checksum 0x%08x of external dex file '%s'",
                                   GetLocation().c_str(),
@@ -856,6 +867,7 @@
                                   external_dex_files_[i]->GetLocation().c_str());
         return false;
       }
+      CHECK(dex_file_sha1 == external_dex_files_[i]->GetSha1());
       dex_file_pointer = external_dex_files_[i]->Begin();
     } else {
       // Do not support mixed-mode oat files.
@@ -1001,20 +1013,21 @@
     }
 
     // Create the OatDexFile and add it to the owning container.
-    OatDexFile* oat_dex_file = new OatDexFile(
-        this,
-        dex_file_location,
-        DexFileLoader::GetDexCanonicalLocation(dex_file_name.c_str()),
-        dex_file_checksum,
-        dex_file_pointer,
-        lookup_table_data,
-        method_bss_mapping,
-        type_bss_mapping,
-        public_type_bss_mapping,
-        package_type_bss_mapping,
-        string_bss_mapping,
-        class_offsets_pointer,
-        dex_layout_sections);
+    OatDexFile* oat_dex_file =
+        new OatDexFile(this,
+                       dex_file_location,
+                       DexFileLoader::GetDexCanonicalLocation(dex_file_name.c_str()),
+                       dex_file_checksum,
+                       dex_file_sha1,
+                       dex_file_pointer,
+                       lookup_table_data,
+                       method_bss_mapping,
+                       type_bss_mapping,
+                       public_type_bss_mapping,
+                       package_type_bss_mapping,
+                       string_bss_mapping,
+                       class_offsets_pointer,
+                       dex_layout_sections);
     oat_dex_files_storage_.push_back(oat_dex_file);
 
     // Add the location and canonical location (if different) to the oat_dex_files_ table.
@@ -1783,6 +1796,7 @@
         OatDexFile* oat_dex_file = new OatDexFile(oat_file.get(),
                                                   dex_file_start,
                                                   vdex_file->GetLocationChecksum(i),
+                                                  header->signature_,
                                                   location,
                                                   canonical_location,
                                                   type_lookup_table_data);
@@ -2084,9 +2098,7 @@
   }
 }
 
-const OatDexFile* OatFile::GetOatDexFile(const char* dex_location,
-                                         const uint32_t* dex_location_checksum,
-                                         std::string* error_msg) const {
+const OatDexFile* OatFile::GetOatDexFile(const char* dex_location, std::string* error_msg) const {
   // NOTE: We assume here that the canonical location for a given dex_location never
   // changes. If it does (i.e. some symlink used by the filename changes) we may return
   // an incorrect OatDexFile. As long as we have a checksum to check, we shall return
@@ -2138,18 +2150,6 @@
     return nullptr;
   }
 
-  if (dex_location_checksum != nullptr &&
-      oat_dex_file->GetDexFileLocationChecksum() != *dex_location_checksum) {
-    if (error_msg != nullptr) {
-      std::string dex_canonical_location = DexFileLoader::GetDexCanonicalLocation(dex_location);
-      std::string checksum = StringPrintf("0x%08x", oat_dex_file->GetDexFileLocationChecksum());
-      std::string required_checksum = StringPrintf("0x%08x", *dex_location_checksum);
-      *error_msg = "OatDexFile for DexFile " + std::string(dex_location)
-          + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation()
-          + " has checksum " + checksum + " but " + required_checksum + " was required";
-    }
-    return nullptr;
-  }
   return oat_dex_file;
 }
 
@@ -2157,6 +2157,7 @@
                        const std::string& dex_file_location,
                        const std::string& canonical_dex_file_location,
                        uint32_t dex_file_location_checksum,
+                       DexFile::Sha1 dex_file_sha1,
                        const uint8_t* dex_file_pointer,
                        const uint8_t* lookup_table_data,
                        const IndexBssMapping* method_bss_mapping_data,
@@ -2170,6 +2171,7 @@
       dex_file_location_(dex_file_location),
       canonical_dex_file_location_(canonical_dex_file_location),
       dex_file_location_checksum_(dex_file_location_checksum),
+      dex_file_sha1_(dex_file_sha1),
       dex_file_pointer_(dex_file_pointer),
       lookup_table_data_(lookup_table_data),
       method_bss_mapping_(method_bss_mapping_data),
@@ -2207,6 +2209,7 @@
 OatDexFile::OatDexFile(const OatFile* oat_file,
                        const uint8_t* dex_file_pointer,
                        uint32_t dex_file_location_checksum,
+                       DexFile::Sha1 dex_file_sha1,
                        const std::string& dex_file_location,
                        const std::string& canonical_dex_file_location,
                        const uint8_t* lookup_table_data)
@@ -2214,6 +2217,7 @@
       dex_file_location_(dex_file_location),
       canonical_dex_file_location_(canonical_dex_file_location),
       dex_file_location_checksum_(dex_file_location_checksum),
+      dex_file_sha1_(dex_file_sha1),
       dex_file_pointer_(dex_file_pointer),
       lookup_table_data_(lookup_table_data) {
   InitializeTypeLookupTable();
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 4fdbb75..7ceafac 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -29,6 +29,7 @@
 #include "base/safe_map.h"
 #include "base/tracking_safe_map.h"
 #include "class_status.h"
+#include "dex/dex_file.h"
 #include "dex/dex_file_layout.h"
 #include "dex/type_lookup_table.h"
 #include "dex/utf.h"
@@ -38,7 +39,6 @@
 namespace art {
 
 class BitVector;
-class DexFile;
 class ClassLoaderContext;
 class ElfFile;
 class DexLayoutSections;
@@ -302,8 +302,7 @@
   // If error_msg is non-null and no OatDexFile is returned, error_msg will
   // be updated with a description of why no OatDexFile was returned.
   const OatDexFile* GetOatDexFile(const char* dex_location,
-                                  const uint32_t* const dex_location_checksum,
-                                  /*out*/std::string* error_msg = nullptr) const
+                                  /*out*/ std::string* error_msg = nullptr) const
       REQUIRES(!secondary_lookup_lock_);
 
   const std::vector<const OatDexFile*>& GetOatDexFiles() const {
@@ -530,6 +529,8 @@
   // Returns checksum of original DexFile that was the source of this OatDexFile;
   uint32_t GetLocationChecksum() const { return dex_file_location_checksum_; }
 
+  DexFile::Sha1 GetSha1() const { return dex_file_sha1_; }
+
   // Returns the OatClass for the class specified by the given DexFile class_def_index.
   OatFile::OatClass GetOatClass(uint16_t class_def_index) const;
 
@@ -589,6 +590,7 @@
              const std::string& dex_file_location,
              const std::string& canonical_dex_file_location,
              uint32_t dex_file_checksum,
+             DexFile::Sha1 dex_file_sha1,
              const uint8_t* dex_file_pointer,
              const uint8_t* lookup_table_data,
              const IndexBssMapping* method_bss_mapping,
@@ -604,6 +606,7 @@
   OatDexFile(const OatFile* oat_file,
              const uint8_t* dex_file_pointer,
              uint32_t dex_file_checksum,
+             DexFile::Sha1 dex_file_sha1,
              const std::string& dex_file_location,
              const std::string& canonical_dex_file_location,
              const uint8_t* lookup_table_data);
@@ -617,6 +620,7 @@
   const std::string dex_file_location_;
   const std::string canonical_dex_file_location_;
   const uint32_t dex_file_location_checksum_ = 0u;
+  const DexFile::Sha1 dex_file_sha1_ = {};
   const uint8_t* const dex_file_pointer_ = nullptr;
   const uint8_t* const lookup_table_data_ = nullptr;
   const IndexBssMapping* const method_bss_mapping_ = nullptr;
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 5024335..5d035f5 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -418,8 +418,7 @@
                                     std::vector<std::unique_ptr<const DexFile>>* out_dex_files) {
   // Load the main dex file.
   std::string error_msg;
-  const OatDexFile* oat_dex_file =
-      oat_file.GetOatDexFile(dex_location.c_str(), nullptr, &error_msg);
+  const OatDexFile* oat_dex_file = oat_file.GetOatDexFile(dex_location.c_str(), &error_msg);
   if (oat_dex_file == nullptr) {
     LOG(WARNING) << error_msg;
     return false;
@@ -435,7 +434,7 @@
   // Load the rest of the multidex entries
   for (size_t i = 1;; i++) {
     std::string multidex_dex_location = DexFileLoader::GetMultiDexLocation(i, dex_location.c_str());
-    oat_dex_file = oat_file.GetOatDexFile(multidex_dex_location.c_str(), nullptr);
+    oat_dex_file = oat_file.GetOatDexFile(multidex_dex_location.c_str());
     if (oat_dex_file == nullptr) {
       // There are no more multidex entries to load.
       break;
@@ -484,7 +483,7 @@
   uint32_t number_of_dex_files = file.GetOatHeader().GetDexFileCount();
   for (uint32_t i = 0; i < number_of_dex_files; i++) {
     std::string dex = DexFileLoader::GetMultiDexLocation(i, dex_location_.c_str());
-    const OatDexFile* oat_dex_file = file.GetOatDexFile(dex.c_str(), nullptr);
+    const OatDexFile* oat_dex_file = file.GetOatDexFile(dex.c_str());
     if (oat_dex_file == nullptr) {
       *error_msg = StringPrintf("failed to find %s in %s", dex.c_str(), file.GetLocation().c_str());
       return false;