ART: Use .bss section for dex cache arrays.
Change-Id: I5fd507973b56f6a662a02a8c1dd9ac4493fb7b36
diff --git a/runtime/arch/instruction_set.h b/runtime/arch/instruction_set.h
index 9cfd2eb..ff9c0b3 100644
--- a/runtime/arch/instruction_set.h
+++ b/runtime/arch/instruction_set.h
@@ -107,6 +107,22 @@
}
}
+static inline bool IsValidInstructionSet(InstructionSet isa) {
+ switch (isa) {
+ case kArm:
+ case kThumb2:
+ case kArm64:
+ case kX86:
+ case kX86_64:
+ case kMips:
+ case kMips64:
+ return true;
+ case kNone:
+ default:
+ return false;
+ }
+}
+
size_t GetInstructionSetAlignment(InstructionSet isa);
static inline bool Is64BitInstructionSet(InstructionSet isa) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 02f2e0b..c91577a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1204,7 +1204,10 @@
}
DexCacheArraysLayout layout(image_pointer_size_, &dex_file);
uint8_t* raw_arrays = nullptr;
- if (dex_file.NumStringIds() != 0u || dex_file.NumTypeIds() != 0u ||
+ if (dex_file.GetOatDexFile() != nullptr &&
+ dex_file.GetOatDexFile()->GetDexCacheArrays() != nullptr) {
+ raw_arrays = const_cast<uint8_t*>(dex_file.GetOatDexFile()->GetDexCacheArrays());
+ } else if (dex_file.NumStringIds() != 0u || dex_file.NumTypeIds() != 0u ||
dex_file.NumMethodIds() != 0u || dex_file.NumFieldIds() != 0u) {
// NOTE: We "leak" the raw_arrays because we never destroy the dex cache.
DCHECK(image_pointer_size_ == 4u || image_pointer_size_ == 8u);
diff --git a/runtime/image.cc b/runtime/image.cc
index 42b348a..192371f 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -24,7 +24,7 @@
namespace art {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '2', '1', '\0' };
+const uint8_t ImageHeader::kImageVersion[] = { '0', '2', '2', '\0' };
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_size,
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 5725b6f..5625499 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -134,6 +134,9 @@
if (!IsAligned<kPageSize>(image_patch_delta_)) {
return false;
}
+ if (!IsValidInstructionSet(instruction_set_)) {
+ return false;
+ }
return true;
}
@@ -156,6 +159,9 @@
if (!IsAligned<kPageSize>(image_patch_delta_)) {
return "Image patch delta not page-aligned.";
}
+ if (!IsValidInstructionSet(instruction_set_)) {
+ return StringPrintf("Invalid instruction set, %d.", static_cast<int>(instruction_set_));
+ }
return "";
}
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 6cbbce9..d931777 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -46,6 +46,7 @@
#include "os.h"
#include "runtime.h"
#include "utils.h"
+#include "utils/dex_cache_arrays_layout-inl.h"
#include "vmap_table.h"
namespace art {
@@ -432,6 +433,8 @@
return false;
}
+ size_t pointer_size = GetInstructionSetPointerSize(GetOatHeader().GetInstructionSet());
+ const uint8_t* dex_cache_arrays = bss_begin_;
uint32_t dex_file_count = GetOatHeader().GetDexFileCount();
oat_dex_files_storage_.reserve(dex_file_count);
for (size_t i = 0; i < dex_file_count; i++) {
@@ -513,6 +516,22 @@
return false;
}
+ const uint8_t* current_dex_cache_arrays = nullptr;
+ if (dex_cache_arrays != nullptr) {
+ DexCacheArraysLayout layout(pointer_size, *header);
+ if (layout.Size() != 0u) {
+ if (static_cast<size_t>(bss_end_ - dex_cache_arrays) < layout.Size()) {
+ *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zd for '%s' with "
+ "truncated dex cache arrays, %zd < %zd.",
+ GetLocation().c_str(), i, dex_file_location.c_str(),
+ static_cast<size_t>(bss_end_ - dex_cache_arrays), layout.Size());
+ return false;
+ }
+ current_dex_cache_arrays = dex_cache_arrays;
+ dex_cache_arrays += layout.Size();
+ }
+ }
+
std::string canonical_location = DexFile::GetDexCanonicalLocation(dex_file_location.c_str());
// Create the OatDexFile and add it to the owning container.
@@ -521,7 +540,8 @@
canonical_location,
dex_file_checksum,
dex_file_pointer,
- methods_offsets_pointer);
+ methods_offsets_pointer,
+ current_dex_cache_arrays);
oat_dex_files_storage_.push_back(oat_dex_file);
// Add the location and canonical location (if different) to the oat_dex_files_ table.
@@ -532,6 +552,15 @@
oat_dex_files_.Put(canonical_key, oat_dex_file);
}
}
+
+ if (dex_cache_arrays != bss_end_) {
+ // We expect the bss section to be either empty (dex_cache_arrays and bss_end_
+ // both null) or contain just the dex cache arrays and nothing else.
+ *error_msg = StringPrintf("In oat file '%s' found unexpected bss size bigger by %zd bytes.",
+ GetLocation().c_str(),
+ static_cast<size_t>(bss_end_ - dex_cache_arrays));
+ return false;
+ }
return true;
}
@@ -634,13 +663,15 @@
const std::string& canonical_dex_file_location,
uint32_t dex_file_location_checksum,
const uint8_t* dex_file_pointer,
- const uint32_t* oat_class_offsets_pointer)
+ const uint32_t* oat_class_offsets_pointer,
+ const uint8_t* dex_cache_arrays)
: oat_file_(oat_file),
dex_file_location_(dex_file_location),
canonical_dex_file_location_(canonical_dex_file_location),
dex_file_location_checksum_(dex_file_location_checksum),
dex_file_pointer_(dex_file_pointer),
- oat_class_offsets_pointer_(oat_class_offsets_pointer) {}
+ oat_class_offsets_pointer_(oat_class_offsets_pointer),
+ dex_cache_arrays_(dex_cache_arrays) {}
OatFile::OatDexFile::~OatDexFile() {}
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 364b734..34f0141 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -396,6 +396,10 @@
// Returns the offset to the OatClass information. Most callers should use GetOatClass.
uint32_t GetOatClassOffset(uint16_t class_def_index) const;
+ const uint8_t* GetDexCacheArrays() const {
+ return dex_cache_arrays_;
+ }
+
~OatDexFile();
private:
@@ -404,7 +408,8 @@
const std::string& canonical_dex_file_location,
uint32_t dex_file_checksum,
const uint8_t* dex_file_pointer,
- const uint32_t* oat_class_offsets_pointer);
+ const uint32_t* oat_class_offsets_pointer,
+ const uint8_t* dex_cache_arrays);
const OatFile* const oat_file_;
const std::string dex_file_location_;
@@ -412,6 +417,7 @@
const uint32_t dex_file_location_checksum_;
const uint8_t* const dex_file_pointer_;
const uint32_t* const oat_class_offsets_pointer_;
+ const uint8_t* const dex_cache_arrays_;
friend class OatFile;
DISALLOW_COPY_AND_ASSIGN(OatDexFile);
diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h
index 4f662d5..90e24b9 100644
--- a/runtime/utils/dex_cache_arrays_layout-inl.h
+++ b/runtime/utils/dex_cache_arrays_layout-inl.h
@@ -27,20 +27,25 @@
namespace art {
-inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file)
+inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size,
+ const DexFile::Header& header)
: pointer_size_(pointer_size),
/* types_offset_ is always 0u, so it's constexpr */
methods_offset_(types_offset_ +
- RoundUp(TypesSize(dex_file->NumTypeIds()), MethodsAlignment())),
+ RoundUp(TypesSize(header.type_ids_size_), MethodsAlignment())),
strings_offset_(methods_offset_ +
- RoundUp(MethodsSize(dex_file->NumMethodIds()), StringsAlignment())),
+ RoundUp(MethodsSize(header.method_ids_size_), StringsAlignment())),
fields_offset_(strings_offset_ +
- RoundUp(StringsSize(dex_file->NumStringIds()), FieldsAlignment())),
+ RoundUp(StringsSize(header.string_ids_size_), FieldsAlignment())),
size_(fields_offset_ +
- RoundUp(FieldsSize(dex_file->NumFieldIds()), Alignment())) {
+ RoundUp(FieldsSize(header.field_ids_size_), Alignment())) {
DCHECK(ValidPointerSize(pointer_size)) << pointer_size;
}
+inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file)
+ : DexCacheArraysLayout(pointer_size, dex_file->GetHeader()) {
+}
+
inline size_t DexCacheArraysLayout::Alignment() const {
// GcRoot<> alignment is 4, i.e. lower than or equal to the pointer alignment.
static_assert(alignof(GcRoot<mirror::Class>) == 4, "Expecting alignof(GcRoot<>) == 4");
diff --git a/runtime/utils/dex_cache_arrays_layout.h b/runtime/utils/dex_cache_arrays_layout.h
index d50be5a..cd84460 100644
--- a/runtime/utils/dex_cache_arrays_layout.h
+++ b/runtime/utils/dex_cache_arrays_layout.h
@@ -17,6 +17,8 @@
#ifndef ART_RUNTIME_UTILS_DEX_CACHE_ARRAYS_LAYOUT_H_
#define ART_RUNTIME_UTILS_DEX_CACHE_ARRAYS_LAYOUT_H_
+#include "dex_file.h"
+
namespace art {
/**
@@ -36,6 +38,9 @@
size_(0u) {
}
+ // Construct a layout for a particular dex file header.
+ DexCacheArraysLayout(size_t pointer_size, const DexFile::Header& header);
+
// Construct a layout for a particular dex file.
DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file);