Make image oat checksum depend on secondary images.

Rather than explicitly having to load and combine the checksums from
secondary images in the case of multi-image, have the image oat
checksum for the primary image depend on the contents of all the
images.

Bug: 35659889
Bug: 34385298
Bug: 35992406

Test: test-art-host
Test: Manually add field to ZygoteInit, update boot image, verify image
      is properly relocated and used on device.
Change-Id: I38bd957d165682edabd0fd1874e8ef7acf923deb
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 3fa30fa..92a12c8 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1486,7 +1486,7 @@
         TimingLogger::ScopedTiming t3("Loading image checksum", timings_);
         std::vector<gc::space::ImageSpace*> image_spaces =
             Runtime::Current()->GetHeap()->GetBootImageSpaces();
-        image_file_location_oat_checksum_ = OatFileAssistant::CalculateCombinedImageChecksum();
+        image_file_location_oat_checksum_ = image_spaces[0]->GetImageHeader().GetOatChecksum();
         image_file_location_oat_data_begin_ =
             reinterpret_cast<uintptr_t>(image_spaces[0]->GetImageHeader().GetOatDataBegin());
         image_patch_delta_ = image_spaces[0]->GetImageHeader().GetPatchDelta();
@@ -1907,6 +1907,14 @@
                                              oat_writer->GetOatDataOffset(),
                                              oat_writer->GetOatSize());
         }
+
+        if (IsBootImage()) {
+          // Have the image_file_location_oat_checksum_ for boot oat files
+          // depend on the contents of all the boot oat files. This way only
+          // the primary image checksum needs to be checked to determine
+          // whether any of the images are out of date.
+          image_file_location_oat_checksum_ ^= oat_writer->GetOatHeader().GetChecksum();
+        }
       }
 
       for (size_t i = 0, size = oat_files_.size(); i != size; ++i) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b611aa2..4e4ecdb 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -906,7 +906,6 @@
       runtime->GetOatFileManager().RegisterImageOatFiles(spaces);
   DCHECK(!oat_files.empty());
   const OatHeader& default_oat_header = oat_files[0]->GetOatHeader();
-  CHECK_EQ(default_oat_header.GetImageFileLocationOatChecksum(), 0U);
   CHECK_EQ(default_oat_header.GetImageFileLocationOatDataBegin(), 0U);
   const char* image_file_location = oat_files[0]->GetOatHeader().
       GetStoreValueByKey(OatHeader::kImageLocationKey);
diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc
index 5167869..db65e40 100644
--- a/runtime/dexopt_test.cc
+++ b/runtime/dexopt_test.cc
@@ -111,7 +111,7 @@
                                                  &error_msg));
   ASSERT_TRUE(image_header != nullptr) << error_msg;
   const OatHeader& oat_header = odex_file->GetOatHeader();
-  uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum();
+  uint32_t combined_checksum = image_header->GetOatChecksum();
 
   if (CompilerFilter::DependsOnImageChecksum(filter)) {
     if (with_alternate_image) {
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 48bf1e7..1735045 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -750,32 +750,18 @@
   // same as kRuntimeISA, so this behavior is suspect (b/35659889).
   if (isa == kRuntimeISA) {
     const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
+    info->oat_checksum = image_header.GetOatChecksum();
     info->oat_data_begin = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin());
     info->patch_delta = image_header.GetPatchDelta();
-
-    info->oat_checksum = 0;
-    for (gc::space::ImageSpace* image_space : image_spaces) {
-      info->oat_checksum ^= image_space->GetImageHeader().GetOatChecksum();
-    }
   } else {
     std::unique_ptr<ImageHeader> image_header(
         gc::space::ImageSpace::ReadImageHeader(info->location.c_str(), isa, error_msg));
     if (image_header == nullptr) {
       return nullptr;
     }
+    info->oat_checksum = image_header->GetOatChecksum();
     info->oat_data_begin = reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin());
     info->patch_delta = image_header->GetPatchDelta();
-
-    info->oat_checksum = 0;
-    for (gc::space::ImageSpace* image_space : image_spaces) {
-      std::string location = image_space->GetImageLocation();
-      image_header.reset(
-          gc::space::ImageSpace::ReadImageHeader(location.c_str(), isa, error_msg));
-      if (image_header == nullptr) {
-        return nullptr;
-      }
-      info->oat_checksum ^= image_header->GetOatChecksum();
-    }
   }
   return info;
 }
@@ -792,16 +778,6 @@
   return cached_image_info_.get();
 }
 
-uint32_t OatFileAssistant::CalculateCombinedImageChecksum(InstructionSet isa) {
-  std::string error_msg;
-  std::unique_ptr<ImageInfo> info = ImageInfo::GetRuntimeImageInfo(isa, &error_msg);
-  if (info == nullptr) {
-    LOG(WARNING) << "Unable to get runtime image info for checksum: " << error_msg;
-    return 0;
-  }
-  return info->oat_checksum;
-}
-
 OatFileAssistant::OatFileInfo& OatFileAssistant::GetBestInfo() {
   bool use_oat = oat_.IsUseable() || odex_.Status() == kOatCannotOpen;
   return use_oat ? oat_ : odex_;
diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h
index eec87f0..d61e994 100644
--- a/runtime/oat_file_assistant.h
+++ b/runtime/oat_file_assistant.h
@@ -276,8 +276,6 @@
                                        std::string* oat_filename,
                                        std::string* error_msg);
 
-  static uint32_t CalculateCombinedImageChecksum(InstructionSet isa = kRuntimeISA);
-
  private:
   struct ImageInfo {
     uint32_t oat_checksum = 0;