summaryrefslogtreecommitdiffstats
path: root/runtime/oat_file.cc
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 /runtime/oat_file.cc
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
Diffstat (limited to 'runtime/oat_file.cc')
-rw-r--r--runtime/oat_file.cc113
1 files changed, 78 insertions, 35 deletions
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());
}