Rewrite the .data.bimg.rel.ro check in OatFile::Setup().

In preparation for loading boot image extensions before
Runtime::Current()->GetClassLinker() has been initialized,
change the check to not rely on Runtime::Current() at all.

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: Ica37c294a19e36e615186a0331d4d18c40c7fe2e
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 8cee20c..c1b5a81 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -132,6 +132,11 @@
                                 bool* has_data,
                                 bool *is_global_cache);
 
+  // The leading character in an image checksum part of boot class path checkums.
+  static constexpr char kImageChecksumPrefix = 'i';
+  // The leading character in a dex file checksum part of boot class path checkums.
+  static constexpr char kDexFileChecksumPrefix = 'd';
+
   // Returns the checksums for the boot image and extra boot class path dex files,
   // based on the boot class path, image location and ISA (may differ from the ISA of an
   // initialized Runtime). The boot image and dex files do not need to be loaded in memory.
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 92c8cb5..5067237 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -847,25 +847,22 @@
     }
   }
 
-  Runtime* runtime = Runtime::Current();
-
   if (DataBimgRelRoBegin() != nullptr) {
-    // Make .data.bimg.rel.ro read only. ClassLinker shall make it writable for relocation.
+    // Make .data.bimg.rel.ro read only. ClassLinker shall temporarily make it writable for
+    // relocation when we register a dex file from this oat file. We do not do the relocation
+    // here to avoid dirtying the pages if the code is never actually ready to be executed.
     uint8_t* reloc_begin = const_cast<uint8_t*>(DataBimgRelRoBegin());
     CheckedCall(mprotect, "protect relocations", reloc_begin, DataBimgRelRoSize(), PROT_READ);
-    if (UNLIKELY(runtime == nullptr)) {
-      // This must be oatdump without boot image.
-    } else if (!IsExecutable()) {
-      // Do not check whether we have a boot image if the oat file is not executable.
-    } else if (UNLIKELY(runtime->GetHeap()->GetBootImageSpaces().empty())) {
-      *error_msg = StringPrintf("Cannot load oat file '%s' with .data.bimg.rel.ro as executable "
-                                    "without boot image.",
+    // Make sure the file lists a boot image dependency, otherwise the .data.bimg.rel.ro
+    // section is bogus. The full dependency is checked before the code is executed.
+    const char* boot_class_path_checksum =
+        GetOatHeader().GetStoreValueByKey(OatHeader::kBootClassPathChecksumsKey);
+    if (boot_class_path_checksum == nullptr ||
+        boot_class_path_checksum[0] != gc::space::ImageSpace::kImageChecksumPrefix) {
+      *error_msg = StringPrintf("Oat file '%s' contains .data.bimg.rel.ro section "
+                                    "without boot image dependency.",
                                 GetLocation().c_str());
       return false;
-    } else {
-      // ClassLinker shall perform the relocation when we register a dex file from
-      // this oat file. We do not do the relocation here to avoid dirtying the pages
-      // if the code is never actually ready to be executed.
     }
   }