summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2019-02-06 14:13:28 +0000
committerVladimir Marko <vmarko@google.com>2019-02-06 14:15:00 +0000
commit1cedb4a2779fd161f781503fd5de08cab0a1c85b (patch)
treea9c0b7082e0d5d2f1b931eac7db3fcf9b0d46862
parent7909e1e4cc741b38b25328e2f9077beb7ecd018b (diff)
downloadart-1cedb4a2779fd161f781503fd5de08cab0a1c85b.tar.gz
art-1cedb4a2779fd161f781503fd5de08cab0a1c85b.tar.bz2
art-1cedb4a2779fd161f781503fd5de08cab0a1c85b.zip
ART: Move .bss mappings check before .bss init.
Previously the check was done before we compared the dex file checksums, so an out of date oat file could have failed the check. Now we're doing the check only if we're initializing the .bss section for use by an executable oat file, i.e. after matching the dex file checksums. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 119601889 Change-Id: Ib79d84c5bc2cf0674fc1f76071c589d49663e13c
-rw-r--r--runtime/class_linker.cc27
-rw-r--r--runtime/oat_file.cc113
-rw-r--r--runtime/oat_file.h3
3 files changed, 82 insertions, 61 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index d29a6b7577..ae6ac9b192 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3727,32 +3727,7 @@ void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file,
}
}
if (initialize_oat_file_data) {
- // Initialize the .data.bimg.rel.ro section.
- if (!oat_file->GetBootImageRelocations().empty()) {
- uint8_t* reloc_begin = const_cast<uint8_t*>(oat_file->DataBimgRelRoBegin());
- CheckedCall(mprotect,
- "un-protect boot image relocations",
- reloc_begin,
- oat_file->DataBimgRelRoSize(),
- PROT_READ | PROT_WRITE);
- uint32_t boot_image_begin = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(
- Runtime::Current()->GetHeap()->GetBootImageSpaces().front()->Begin()));
- for (const uint32_t& relocation : oat_file->GetBootImageRelocations()) {
- const_cast<uint32_t&>(relocation) += boot_image_begin;
- }
- CheckedCall(mprotect,
- "protect boot image relocations",
- reloc_begin,
- oat_file->DataBimgRelRoSize(),
- PROT_READ);
- }
-
- // Initialize the .bss section.
- // TODO: Pre-initialize from boot/app image?
- ArtMethod* resolution_method = Runtime::Current()->GetResolutionMethod();
- for (ArtMethod*& entry : oat_file->GetBssMethods()) {
- entry = resolution_method;
- }
+ oat_file->InitializeRelocations();
}
jweak dex_cache_jweak = vm->AddWeakGlobalRef(self, dex_cache);
dex_cache->SetDexFile(&dex_file);
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 8a0a1e7c9d..67803b6121 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -58,13 +58,14 @@
#include "elf_file.h"
#include "elf_utils.h"
#include "gc_root.h"
+#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "mirror/class.h"
#include "mirror/object-inl.h"
#include "oat.h"
#include "oat_file-inl.h"
#include "oat_file_manager.h"
-#include "runtime.h"
+#include "runtime-inl.h"
#include "vdex_file.h"
namespace art {
@@ -447,34 +448,6 @@ static bool ReadIndexBssMapping(OatFile* oat_file,
return true;
}
-static void DCheckIndexToBssMapping(OatFile* oat_file,
- uint32_t number_of_indexes,
- size_t slot_size,
- const IndexBssMapping* index_bss_mapping) {
- if (kIsDebugBuild && index_bss_mapping != nullptr) {
- size_t index_bits = IndexBssMappingEntry::IndexBits(number_of_indexes);
- const IndexBssMappingEntry* prev_entry = nullptr;
- for (const IndexBssMappingEntry& entry : *index_bss_mapping) {
- CHECK_ALIGNED_PARAM(entry.bss_offset, slot_size);
- // When loading a non-executable ElfOatFile, .bss symbols are not even
- // looked up, so we cannot verify the offset against BssSize().
- if (oat_file->IsExecutable()) {
- CHECK_LT(entry.bss_offset, oat_file->BssSize());
- }
- uint32_t mask = entry.GetMask(index_bits);
- CHECK_LE(POPCOUNT(mask) * slot_size, entry.bss_offset);
- size_t index_mask_span = (mask != 0u) ? 32u - index_bits - CTZ(mask) : 0u;
- CHECK_LE(index_mask_span, entry.GetIndex(index_bits));
- if (prev_entry != nullptr) {
- CHECK_LT(prev_entry->GetIndex(index_bits), entry.GetIndex(index_bits) - index_mask_span);
- }
- prev_entry = &entry;
- }
- CHECK(prev_entry != nullptr);
- CHECK_LT(prev_entry->GetIndex(index_bits), number_of_indexes);
- }
-}
-
bool OatFileBase::Setup(int zip_fd, const char* abs_dex_location, std::string* error_msg) {
if (!GetOatHeader().IsValid()) {
std::string cause = GetOatHeader().GetValidationErrorMessage();
@@ -813,12 +786,6 @@ bool OatFileBase::Setup(int zip_fd, const char* abs_dex_location, std::string* e
this, &oat, i, dex_file_location, "string", &string_bss_mapping, error_msg)) {
return false;
}
- DCheckIndexToBssMapping(
- this, header->method_ids_size_, static_cast<size_t>(pointer_size), method_bss_mapping);
- DCheckIndexToBssMapping(
- this, header->type_ids_size_, sizeof(GcRoot<mirror::Class>), type_bss_mapping);
- DCheckIndexToBssMapping(
- this, header->string_ids_size_, sizeof(GcRoot<mirror::String>), string_bss_mapping);
std::string canonical_location =
DexFileLoader::GetDexCanonicalLocation(dex_file_name.c_str());
@@ -2019,6 +1986,82 @@ OatFile::OatClass OatFile::FindOatClass(const DexFile& dex_file,
return oat_dex_file->GetOatClass(class_def_idx);
}
+static void DCheckIndexToBssMapping(const OatFile* oat_file,
+ uint32_t number_of_indexes,
+ size_t slot_size,
+ const IndexBssMapping* index_bss_mapping) {
+ if (kIsDebugBuild && index_bss_mapping != nullptr) {
+ size_t index_bits = IndexBssMappingEntry::IndexBits(number_of_indexes);
+ const IndexBssMappingEntry* prev_entry = nullptr;
+ for (const IndexBssMappingEntry& entry : *index_bss_mapping) {
+ CHECK_ALIGNED_PARAM(entry.bss_offset, slot_size);
+ CHECK_LT(entry.bss_offset, oat_file->BssSize());
+ uint32_t mask = entry.GetMask(index_bits);
+ CHECK_LE(POPCOUNT(mask) * slot_size, entry.bss_offset);
+ size_t index_mask_span = (mask != 0u) ? 32u - index_bits - CTZ(mask) : 0u;
+ CHECK_LE(index_mask_span, entry.GetIndex(index_bits));
+ if (prev_entry != nullptr) {
+ CHECK_LT(prev_entry->GetIndex(index_bits), entry.GetIndex(index_bits) - index_mask_span);
+ }
+ prev_entry = &entry;
+ }
+ CHECK(prev_entry != nullptr);
+ CHECK_LT(prev_entry->GetIndex(index_bits), number_of_indexes);
+ }
+}
+
+void OatFile::InitializeRelocations() const {
+ DCHECK(IsExecutable());
+
+ // Initialize the .data.bimg.rel.ro section.
+ if (!GetBootImageRelocations().empty()) {
+ uint8_t* reloc_begin = const_cast<uint8_t*>(DataBimgRelRoBegin());
+ CheckedCall(mprotect,
+ "un-protect boot image relocations",
+ reloc_begin,
+ DataBimgRelRoSize(),
+ PROT_READ | PROT_WRITE);
+ uint32_t boot_image_begin = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(
+ Runtime::Current()->GetHeap()->GetBootImageSpaces().front()->Begin()));
+ for (const uint32_t& relocation : GetBootImageRelocations()) {
+ const_cast<uint32_t&>(relocation) += boot_image_begin;
+ }
+ CheckedCall(mprotect,
+ "protect boot image relocations",
+ reloc_begin,
+ DataBimgRelRoSize(),
+ PROT_READ);
+ }
+
+ // Before initializing .bss, check the .bss mappings in debug mode.
+ if (kIsDebugBuild) {
+ PointerSize pointer_size = GetInstructionSetPointerSize(GetOatHeader().GetInstructionSet());
+ for (const OatDexFile* odf : GetOatDexFiles()) {
+ const DexFile::Header* header =
+ reinterpret_cast<const DexFile::Header*>(odf->GetDexFilePointer());
+ DCheckIndexToBssMapping(this,
+ header->method_ids_size_,
+ static_cast<size_t>(pointer_size),
+ odf->GetMethodBssMapping());
+ DCheckIndexToBssMapping(this,
+ header->type_ids_size_,
+ sizeof(GcRoot<mirror::Class>),
+ odf->GetTypeBssMapping());
+ DCheckIndexToBssMapping(this,
+ header->string_ids_size_,
+ sizeof(GcRoot<mirror::String>),
+ odf->GetStringBssMapping());
+ }
+ }
+
+ // Initialize the .bss section.
+ // TODO: Pre-initialize from boot/app image?
+ ArtMethod* resolution_method = Runtime::Current()->GetResolutionMethod();
+ for (ArtMethod*& entry : GetBssMethods()) {
+ entry = resolution_method;
+ }
+}
+
void OatDexFile::AssertAotCompiler() {
CHECK(Runtime::Current()->IsAotCompiler());
}
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 37dbe6a5ab..04b666c507 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -325,6 +325,9 @@ class OatFile {
ArrayRef<ArtMethod*> GetBssMethods() const;
ArrayRef<GcRoot<mirror::Object>> GetBssGcRoots() const;
+ // Initialize relocation sections (.data.bimg.rel.ro and .bss).
+ void InitializeRelocations() const;
+
// Returns the absolute dex location for the encoded relative dex location.
//
// If not null, abs_dex_location is used to resolve the absolute dex