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.
}
}