Merge changes I05871a8a,I8baec836
* changes:
Refactor loading boot image.
Remove boot image begin/size from image header.
diff --git a/dex2oat/linker/image_test.cc b/dex2oat/linker/image_test.cc
index 69dac19..64b98cd 100644
--- a/dex2oat/linker/image_test.cc
+++ b/dex2oat/linker/image_test.cc
@@ -74,13 +74,11 @@
oat_data_begin,
oat_data_end,
oat_file_end,
- /*boot_image_begin*/0U,
- /*boot_image_size*/0U,
- /*boot_oat_begin*/0U,
- /*boot_oat_size_*/0U,
+ /*boot_image_begin=*/ 0u,
+ /*boot_image_size=*/ 0u,
sizeof(void*),
ImageHeader::kDefaultStorageMode,
- /*data_size*/0u);
+ /*data_size=*/ 0u);
ASSERT_TRUE(image_header.IsValid());
ASSERT_TRUE(!image_header.IsAppImage());
@@ -110,7 +108,7 @@
// Test the pointer to quick code is the same in origin method
// and in the copied method form the same oat file.
ObjPtr<mirror::Class> iface_klass =
- class_linker_->LookupClass(self, "LIface;", /* class_loader */ nullptr);
+ class_linker_->LookupClass(self, "LIface;", /*class_loader=*/ nullptr);
ASSERT_NE(nullptr, iface_klass);
ArtMethod* origin = iface_klass->FindInterfaceMethod("defaultMethod", "()V", pointer_size);
ASSERT_NE(nullptr, origin);
@@ -120,7 +118,7 @@
ASSERT_NE(nullptr, code);
ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code));
ObjPtr<mirror::Class> impl_klass =
- class_linker_->LookupClass(self, "LImpl;", /* class_loader */ nullptr);
+ class_linker_->LookupClass(self, "LImpl;", /*class_loader=*/ nullptr);
ASSERT_NE(nullptr, impl_klass);
ArtMethod* copied = FindCopiedMethod(origin, impl_klass);
ASSERT_NE(nullptr, copied);
@@ -131,7 +129,7 @@
// but the copied method has pointer to interpreter
// because these methods are in different oat files.
ObjPtr<mirror::Class> iterable_klass =
- class_linker_->LookupClass(self, "Ljava/lang/Iterable;", /* class_loader */ nullptr);
+ class_linker_->LookupClass(self, "Ljava/lang/Iterable;", /*class_loader=*/ nullptr);
ASSERT_NE(nullptr, iterable_klass);
origin = iterable_klass->FindClassMethod(
"forEach", "(Ljava/util/function/Consumer;)V", pointer_size);
@@ -143,7 +141,7 @@
ASSERT_NE(nullptr, code);
ASSERT_FALSE(class_linker_->IsQuickToInterpreterBridge(code));
ObjPtr<mirror::Class> iterablebase_klass =
- class_linker_->LookupClass(self, "LIterableBase;", /* class_loader */ nullptr);
+ class_linker_->LookupClass(self, "LIterableBase;", /*class_loader=*/ nullptr);
ASSERT_NE(nullptr, iterablebase_klass);
copied = FindCopiedMethod(origin, iterablebase_klass);
ASSERT_NE(nullptr, copied);
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index e59faf1..75b3555 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -2573,9 +2573,7 @@
PointerToLowMemUInt32(oat_data_end),
PointerToLowMemUInt32(oat_file_end),
boot_image_begin,
- boot_image_end - boot_image_begin,
- boot_oat_begin,
- boot_oat_end - boot_oat_begin,
+ boot_oat_end - boot_image_begin,
static_cast<uint32_t>(target_ptr_size_),
image_storage_mode_,
/*data_size*/0u);
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index dd1ff2a..51f6008 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1783,9 +1783,7 @@
os << "BOOT IMAGE BEGIN: " << reinterpret_cast<void*>(image_header_.GetBootImageBegin())
<< "\n";
- os << "BOOT IMAGE SIZE: " << image_header_.GetBootImageSize() << "\n";
- os << "BOOT OAT BEGIN: " << reinterpret_cast<void*>(image_header_.GetBootOatBegin()) << "\n";
- os << "BOOT OAT SIZE: " << image_header_.GetBootOatSize() << "\n\n";
+ os << "BOOT IMAGE SIZE: " << image_header_.GetBootImageSize() << "\n\n";
for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) {
auto section = static_cast<ImageHeader::ImageSections>(i);
diff --git a/runtime/gc/collector/immune_spaces_test.cc b/runtime/gc/collector/immune_spaces_test.cc
index c2a67bf..9f98f6c 100644
--- a/runtime/gc/collector/immune_spaces_test.cc
+++ b/runtime/gc/collector/immune_spaces_test.cc
@@ -113,22 +113,20 @@
ImageSection sections[ImageHeader::kSectionCount];
new (image_map.Begin()) ImageHeader(
/*image_begin=*/ PointerToLowMemUInt32(image_map.Begin()),
- /*image_size=*/ image_map.Size(),
+ /*image_size=*/ image_size,
sections,
/*image_roots=*/ PointerToLowMemUInt32(image_map.Begin()) + 1,
/*oat_checksum=*/ 0u,
// The oat file data in the header is always right after the image space.
/*oat_file_begin=*/ PointerToLowMemUInt32(oat_map.Begin()),
- /*oat_data_begin=*/PointerToLowMemUInt32(oat_map.Begin()),
- /*oat_data_end=*/PointerToLowMemUInt32(oat_map.Begin() + oat_size),
- /*oat_file_end=*/PointerToLowMemUInt32(oat_map.Begin() + oat_size),
- /*boot_image_begin=*/0u,
- /*boot_image_size=*/0u,
- /*boot_oat_begin=*/0u,
- /*boot_oat_size=*/0u,
- /*pointer_size=*/sizeof(void*),
+ /*oat_data_begin=*/ PointerToLowMemUInt32(oat_map.Begin()),
+ /*oat_data_end=*/ PointerToLowMemUInt32(oat_map.Begin() + oat_size),
+ /*oat_file_end=*/ PointerToLowMemUInt32(oat_map.Begin() + oat_size),
+ /*boot_image_begin=*/ 0u,
+ /*boot_image_size=*/ 0u,
+ /*pointer_size=*/ sizeof(void*),
ImageHeader::kStorageModeUncompressed,
- /*data_size=*/0u);
+ /*data_size=*/ 0u);
return new DummyImageSpace(std::move(image_map),
std::move(live_bitmap),
std::move(oat_file),
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 0766999..bfb3746 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -383,20 +383,16 @@
public:
static std::unique_ptr<ImageSpace> InitAppImage(const char* image_filename,
const char* image_location,
- bool validate_oat_file,
const OatFile* oat_file,
/*inout*/MemMap* image_reservation,
- /*inout*/MemMap* oat_reservation,
/*out*/std::string* error_msg)
REQUIRES_SHARED(Locks::mutator_lock_) {
TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image));
std::unique_ptr<ImageSpace> space = Init(image_filename,
image_location,
- validate_oat_file,
oat_file,
&logger,
image_reservation,
- oat_reservation,
error_msg);
if (space != nullptr) {
TimingLogger::ScopedTiming timing("RelocateImage", &logger);
@@ -438,11 +434,9 @@
static std::unique_ptr<ImageSpace> Init(const char* image_filename,
const char* image_location,
- bool validate_oat_file,
const OatFile* oat_file,
TimingLogger* logger,
/*inout*/MemMap* image_reservation,
- /*inout*/MemMap* oat_reservation,
/*out*/std::string* error_msg)
REQUIRES_SHARED(Locks::mutator_lock_) {
CHECK(image_filename != nullptr);
@@ -479,8 +473,8 @@
}
if (oat_file != nullptr) {
- // If we have an oat file, check the oat file checksum. The oat file is only non-null for the
- // app image case. Otherwise, we open the oat file after the image and check the checksum there.
+ // If we have an oat file (i.e. for app image), check the oat file checksum.
+ // Otherwise, we open the oat file after the image and check the checksum there.
const uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
const uint32_t image_oat_checksum = image_header->GetOatChecksum();
if (oat_checksum != image_oat_checksum) {
@@ -517,15 +511,13 @@
return nullptr;
}
- MemMap map;
-
// GetImageBegin is the preferred address to map the image. If we manage to map the
// image at the image begin, the amount of fixup work required is minimized.
// If it is pic we will retry with error_msg for the failure case. Pass a null error_msg to
// avoid reading proc maps for a mapping failure and slowing everything down.
// For the boot image, we have already reserved the memory and we load the image
// into the `image_reservation`.
- map = LoadImageFile(
+ MemMap map = LoadImageFile(
image_filename,
image_location,
*image_header,
@@ -583,33 +575,7 @@
std::move(map),
std::move(bitmap),
image_end));
-
- // VerifyImageAllocations() will be called later in Runtime::Init()
- // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_
- // and ArtField::java_lang_reflect_ArtField_, which are used from
- // Object::SizeOf() which VerifyImageAllocations() calls, are not
- // set yet at this point.
- if (oat_file == nullptr) {
- TimingLogger::ScopedTiming timing("OpenOatFile", logger);
- space->oat_file_ = OpenOatFile(*space, image_filename, oat_reservation, error_msg);
- if (space->oat_file_ == nullptr) {
- DCHECK(!error_msg->empty());
- return nullptr;
- }
- space->oat_file_non_owned_ = space->oat_file_.get();
- } else {
- space->oat_file_non_owned_ = oat_file;
- }
-
- if (validate_oat_file) {
- TimingLogger::ScopedTiming timing("ValidateOatFile", logger);
- CHECK(space->oat_file_ != nullptr);
- if (!ImageSpace::ValidateOatFile(*space->oat_file_, error_msg)) {
- DCHECK(!error_msg->empty());
- return nullptr;
- }
- }
-
+ space->oat_file_non_owned_ = oat_file;
return space;
}
@@ -700,11 +666,9 @@
class FixupVisitor : public ValueObject {
public:
FixupVisitor(const RelocationRange& boot_image,
- const RelocationRange& boot_oat,
const RelocationRange& app_image,
const RelocationRange& app_oat)
: boot_image_(boot_image),
- boot_oat_(boot_oat),
app_image_(app_image),
app_oat_(app_oat) {}
@@ -727,8 +691,8 @@
// Return the relocated address of a code pointer (contained by an oat file).
ALWAYS_INLINE const void* ForwardCode(const void* src) const {
const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src);
- if (boot_oat_.InSource(uint_src)) {
- return reinterpret_cast<const void*>(boot_oat_.ToDest(uint_src));
+ if (boot_image_.InSource(uint_src)) {
+ return reinterpret_cast<const void*>(boot_image_.ToDest(uint_src));
}
if (app_oat_.InSource(uint_src)) {
return reinterpret_cast<const void*>(app_oat_.ToDest(uint_src));
@@ -745,7 +709,6 @@
protected:
// Source section.
const RelocationRange boot_image_;
- const RelocationRange boot_oat_;
const RelocationRange app_image_;
const RelocationRange app_oat_;
};
@@ -893,7 +856,7 @@
// We want to use our own class loader and not the one in the image.
if (obj->IsClass<kVerifyNone>()) {
mirror::Class* as_klass = obj->AsClass<kVerifyNone>();
- FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_);
+ FixupObjectAdapter visitor(boot_image_, app_image_, app_oat_);
as_klass->FixupNativePointers<kVerifyNone>(as_klass, pointer_size_, visitor);
// Deal with the pointer arrays. Use the helper function since multiple classes can reference
// the same arrays.
@@ -1025,10 +988,8 @@
*error_msg = "Can not relocate app image without boot oat file";
return false;
}
- const uint32_t boot_image_size = boot_image_end - boot_image_begin;
- const uint32_t boot_oat_size = boot_oat_end - boot_oat_begin;
+ const uint32_t boot_image_size = boot_oat_end - boot_image_begin;
const uint32_t image_header_boot_image_size = image_header.GetBootImageSize();
- const uint32_t image_header_boot_oat_size = image_header.GetBootOatSize();
if (boot_image_size != image_header_boot_image_size) {
*error_msg = StringPrintf("Boot image size %" PRIu64 " does not match expected size %"
PRIu64,
@@ -1036,20 +997,10 @@
static_cast<uint64_t>(image_header_boot_image_size));
return false;
}
- if (boot_oat_size != image_header_boot_oat_size) {
- *error_msg = StringPrintf("Boot oat size %" PRIu64 " does not match expected size %"
- PRIu64,
- static_cast<uint64_t>(boot_oat_size),
- static_cast<uint64_t>(image_header_boot_oat_size));
- return false;
- }
TimingLogger logger(__FUNCTION__, true, false);
RelocationRange boot_image(image_header.GetBootImageBegin(),
boot_image_begin,
boot_image_size);
- RelocationRange boot_oat(image_header.GetBootOatBegin(),
- boot_oat_begin,
- boot_oat_size);
RelocationRange app_image(reinterpret_cast<uintptr_t>(image_header.GetImageBegin()),
reinterpret_cast<uintptr_t>(target_base),
image_header.GetImageSize());
@@ -1061,11 +1012,9 @@
VLOG(image) << "App image " << app_image;
VLOG(image) << "App oat " << app_oat;
VLOG(image) << "Boot image " << boot_image;
- VLOG(image) << "Boot oat " << boot_oat;
- // True if we need to fixup any heap pointers, otherwise only code pointers.
+ // True if we need to fixup any heap pointers.
const bool fixup_image = boot_image.Delta() != 0 || app_image.Delta() != 0;
- const bool fixup_code = boot_oat.Delta() != 0 || app_oat.Delta() != 0;
- if (!fixup_image && !fixup_code) {
+ if (!fixup_image) {
// Nothing to fix up.
return true;
}
@@ -1074,7 +1023,7 @@
const ImageSection& objects_section = image_header.GetObjectsSection();
uintptr_t objects_begin = reinterpret_cast<uintptr_t>(target_base + objects_section.Offset());
uintptr_t objects_end = reinterpret_cast<uintptr_t>(target_base + objects_section.End());
- FixupObjectAdapter fixup_adapter(boot_image, boot_oat, app_image, app_oat);
+ FixupObjectAdapter fixup_adapter(boot_image, app_image, app_oat);
if (fixup_image) {
// Two pass approach, fix up all classes first, then fix up non class-objects.
// The visited bitmap is used to ensure that pointer arrays are not forwarded twice.
@@ -1085,7 +1034,6 @@
FixupObjectVisitor fixup_object_visitor(visited_bitmap.get(),
pointer_size,
boot_image,
- boot_oat,
app_image,
app_oat);
TimingLogger::ScopedTiming timing("Fixup classes", &logger);
@@ -1191,7 +1139,6 @@
FixupArtMethodVisitor method_visitor(fixup_image,
pointer_size,
boot_image,
- boot_oat,
app_image,
app_oat);
image_header.VisitPackedArtMethods(&method_visitor, target_base, pointer_size);
@@ -1200,7 +1147,7 @@
{
// Only touches objects in the app image, no need for mutator lock.
TimingLogger::ScopedTiming timing("Fixup fields", &logger);
- FixupArtFieldVisitor field_visitor(boot_image, boot_oat, app_image, app_oat);
+ FixupArtFieldVisitor field_visitor(boot_image, app_image, app_oat);
image_header.VisitPackedArtFields(&field_visitor, target_base);
}
{
@@ -1222,7 +1169,7 @@
WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
ClassTable temp_table;
temp_table.ReadFromMemory(target_base + class_table_section.Offset());
- FixupRootVisitor root_visitor(boot_image, boot_oat, app_image, app_oat);
+ FixupRootVisitor root_visitor(boot_image, app_image, app_oat);
temp_table.VisitRoots(root_visitor);
}
// Fix up the intern table.
@@ -1234,7 +1181,7 @@
InternTable temp_intern_table;
// Note that we require that ReadFromMemory does not make an internal copy of the elements
// so that the VisitRoots() will update the memory directly rather than the copies.
- FixupRootVisitor root_visitor(boot_image, boot_oat, app_image, app_oat);
+ FixupRootVisitor root_visitor(boot_image, app_image, app_oat);
temp_intern_table.AddTableFromMemory(target_base + intern_table_section.Offset(),
[&](InternTable::UnorderedSet& strings)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1249,49 +1196,6 @@
}
return true;
}
-
- static std::unique_ptr<OatFile> OpenOatFile(const ImageSpace& image,
- const char* image_path,
- /*inout*/MemMap* oat_reservation,
- std::string* error_msg) {
- const ImageHeader& image_header = image.GetImageHeader();
- std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_path);
-
- CHECK(image_header.GetOatDataBegin() != nullptr);
-
- uint8_t* oat_data_begin = image_header.GetOatDataBegin();
- if (oat_reservation != nullptr) {
- oat_data_begin += oat_reservation->Begin() - image_header.GetOatFileBegin();
- }
- std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1,
- oat_filename,
- oat_filename,
- !Runtime::Current()->IsAotCompiler(),
- /*low_4gb=*/ false,
- /*abs_dex_location=*/ nullptr,
- oat_reservation,
- error_msg));
- if (oat_file == nullptr) {
- *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s",
- oat_filename.c_str(),
- image.GetName(),
- error_msg->c_str());
- return nullptr;
- }
- CHECK(oat_data_begin == oat_file->Begin());
- uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
- uint32_t image_oat_checksum = image_header.GetOatChecksum();
- if (oat_checksum != image_oat_checksum) {
- *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum 0x%x"
- " in image %s",
- oat_checksum,
- image_oat_checksum,
- image.GetName());
- return nullptr;
- }
-
- return oat_file;
- }
};
class ImageSpace::BootImageLoader {
@@ -1351,26 +1255,22 @@
}
uint32_t image_start;
uint32_t image_end;
- uint32_t oat_end;
- if (!GetBootImageAddressRange(filename, &image_start, &image_end, &oat_end, error_msg)) {
+ if (!GetBootImageAddressRange(filename, &image_start, &image_end, error_msg)) {
return false;
}
if (locations.size() > 1u) {
std::string last_filename = GetSystemImageFilename(locations.back().c_str(), image_isa_);
uint32_t dummy;
- if (!GetBootImageAddressRange(last_filename, &dummy, &image_end, &oat_end, error_msg)) {
+ if (!GetBootImageAddressRange(last_filename, &dummy, &image_end, error_msg)) {
return false;
}
}
MemMap image_reservation;
- MemMap oat_reservation;
MemMap local_extra_reservation;
- if (!ReserveBootImageMemory(image_start,
- image_end,
- oat_end,
+ if (!ReserveBootImageMemory(/*reservation_size=*/ image_end - image_start,
+ image_start,
extra_reservation_size,
&image_reservation,
- &oat_reservation,
&local_extra_reservation,
error_msg)) {
return false;
@@ -1380,28 +1280,29 @@
spaces.reserve(locations.size());
for (const std::string& location : locations) {
filename = GetSystemImageFilename(location.c_str(), image_isa_);
- spaces.push_back(Load(location,
- filename,
- /*validate_oat_file=*/ false,
- &logger,
- &image_reservation,
- &oat_reservation,
- error_msg));
+ spaces.push_back(Load(location, filename, &logger, &image_reservation, error_msg));
if (spaces.back() == nullptr) {
return false;
}
}
- if (!CheckReservationsExhausted(image_reservation, oat_reservation, error_msg)) {
+ for (std::unique_ptr<ImageSpace>& space : spaces) {
+ static constexpr bool kValidateOatFile = false;
+ if (!OpenOatFile(space.get(), kValidateOatFile, &logger, &image_reservation, error_msg)) {
+ return false;
+ }
+ }
+ if (!CheckReservationExhausted(image_reservation, error_msg)) {
return false;
}
MaybeRelocateSpaces(spaces, &logger);
InitRuntimeMethods(spaces);
- *extra_reservation = std::move(local_extra_reservation);
- VLOG(image) << "ImageSpace::BootImageLoader::InitFromDalvikCache exiting " << *spaces.front();
boot_image_spaces->swap(spaces);
+ *extra_reservation = std::move(local_extra_reservation);
if (VLOG_IS_ON(image)) {
+ LOG(INFO) << "ImageSpace::BootImageLoader::LoadFromSystem exiting "
+ << boot_image_spaces->front();
logger.Dump(LOG_STREAM(INFO));
}
return true;
@@ -1421,8 +1322,7 @@
}
uint32_t image_start;
uint32_t image_end;
- uint32_t oat_end;
- if (!GetBootImageAddressRange(cache_filename_, &image_start, &image_end, &oat_end, error_msg)) {
+ if (!GetBootImageAddressRange(cache_filename_, &image_start, &image_end, error_msg)) {
return false;
}
if (locations.size() > 1u) {
@@ -1434,19 +1334,16 @@
return false;
}
uint32_t dummy;
- if (!GetBootImageAddressRange(last_filename, &dummy, &image_end, &oat_end, error_msg)) {
+ if (!GetBootImageAddressRange(last_filename, &dummy, &image_end, error_msg)) {
return false;
}
}
MemMap image_reservation;
- MemMap oat_reservation;
MemMap local_extra_reservation;
- if (!ReserveBootImageMemory(image_start,
- image_end,
- oat_end,
+ if (!ReserveBootImageMemory(/*reservation_size=*/ image_end - image_start,
+ image_start,
extra_reservation_size,
&image_reservation,
- &oat_reservation,
&local_extra_reservation,
error_msg)) {
return false;
@@ -1459,28 +1356,28 @@
if (!GetDalvikCacheFilename(location.c_str(), dalvik_cache_.c_str(), &filename, error_msg)) {
return false;
}
- spaces.push_back(Load(location,
- filename,
- validate_oat_file,
- &logger,
- &image_reservation,
- &oat_reservation,
- error_msg));
+ spaces.push_back(Load(location, filename, &logger, &image_reservation, error_msg));
if (spaces.back() == nullptr) {
return false;
}
}
- if (!CheckReservationsExhausted(image_reservation, oat_reservation, error_msg)) {
+ for (std::unique_ptr<ImageSpace>& space : spaces) {
+ if (!OpenOatFile(space.get(), validate_oat_file, &logger, &image_reservation, error_msg)) {
+ return false;
+ }
+ }
+ if (!CheckReservationExhausted(image_reservation, error_msg)) {
return false;
}
MaybeRelocateSpaces(spaces, &logger);
InitRuntimeMethods(spaces);
- *extra_reservation = std::move(local_extra_reservation);
boot_image_spaces->swap(spaces);
+ *extra_reservation = std::move(local_extra_reservation);
- VLOG(image) << "ImageSpace::BootImageLoader::InitFromDalvikCache exiting " << *spaces.front();
if (VLOG_IS_ON(image)) {
+ LOG(INFO) << "ImageSpace::BootImageLoader::LoadFromDalvikCache exiting "
+ << boot_image_spaces->front();
logger.Dump(LOG_STREAM(INFO));
}
return true;
@@ -2013,10 +1910,8 @@
std::unique_ptr<ImageSpace> Load(const std::string& image_location,
const std::string& image_filename,
- bool validate_oat_file,
TimingLogger* logger,
/*inout*/MemMap* image_reservation,
- /*inout*/MemMap* oat_reservation,
/*out*/std::string* error_msg)
REQUIRES_SHARED(Locks::mutator_lock_) {
// Should this be a RDWR lock? This is only a defensive measure, as at
@@ -2045,14 +1940,80 @@
// file name.
return Loader::Init(image_filename.c_str(),
image_location.c_str(),
- validate_oat_file,
/*oat_file=*/ nullptr,
logger,
image_reservation,
- oat_reservation,
error_msg);
}
+ bool OpenOatFile(ImageSpace* space,
+ bool validate_oat_file,
+ TimingLogger* logger,
+ /*inout*/MemMap* image_reservation,
+ /*out*/std::string* error_msg) {
+ // VerifyImageAllocations() will be called later in Runtime::Init()
+ // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_
+ // and ArtField::java_lang_reflect_ArtField_, which are used from
+ // Object::SizeOf() which VerifyImageAllocations() calls, are not
+ // set yet at this point.
+ DCHECK(image_reservation != nullptr);
+ std::unique_ptr<OatFile> oat_file;
+ {
+ TimingLogger::ScopedTiming timing("OpenOatFile", logger);
+ std::string oat_filename =
+ ImageHeader::GetOatLocationFromImageLocation(space->GetImageFilename());
+
+ oat_file.reset(OatFile::Open(/*zip_fd=*/ -1,
+ oat_filename,
+ oat_filename,
+ !Runtime::Current()->IsAotCompiler(),
+ /*low_4gb=*/ false,
+ /*abs_dex_location=*/ nullptr,
+ image_reservation,
+ error_msg));
+ if (oat_file == nullptr) {
+ *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s",
+ oat_filename.c_str(),
+ space->GetName(),
+ error_msg->c_str());
+ return false;
+ }
+ const ImageHeader& image_header = space->GetImageHeader();
+ uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
+ uint32_t image_oat_checksum = image_header.GetOatChecksum();
+ if (oat_checksum != image_oat_checksum) {
+ *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum"
+ " 0x%x in image %s",
+ oat_checksum,
+ image_oat_checksum,
+ space->GetName());
+ return false;
+ }
+ ptrdiff_t relocation_diff = space->Begin() - image_header.GetImageBegin();
+ CHECK(image_header.GetOatDataBegin() != nullptr);
+ uint8_t* oat_data_begin = image_header.GetOatDataBegin() + relocation_diff;
+ if (oat_file->Begin() != oat_data_begin) {
+ *error_msg = StringPrintf("Oat file '%s' referenced from image %s has unexpected begin"
+ " %p v. %p",
+ oat_filename.c_str(),
+ space->GetName(),
+ oat_file->Begin(),
+ oat_data_begin);
+ return false;
+ }
+ }
+ if (validate_oat_file) {
+ TimingLogger::ScopedTiming timing("ValidateOatFile", logger);
+ if (!ImageSpace::ValidateOatFile(*oat_file, error_msg)) {
+ DCHECK(!error_msg->empty());
+ return false;
+ }
+ }
+ space->oat_file_ = std::move(oat_file);
+ space->oat_file_non_owned_ = space->oat_file_.get();
+ return true;
+ }
+
// Extract boot class path from oat file associated with `image_filename`
// and list all associated image locations.
static bool GetBootClassPathImageLocations(const std::string& image_location,
@@ -2087,7 +2048,6 @@
bool GetBootImageAddressRange(const std::string& filename,
/*out*/uint32_t* start,
/*out*/uint32_t* end,
- /*out*/uint32_t* oat_end,
/*out*/std::string* error_msg) {
ImageHeader system_hdr;
if (!ReadSpecificImageHeader(filename.c_str(), &system_hdr)) {
@@ -2096,22 +2056,19 @@
}
*start = reinterpret_cast32<uint32_t>(system_hdr.GetImageBegin());
CHECK_ALIGNED(*start, kPageSize);
- *end = RoundUp(*start + system_hdr.GetImageSize(), kPageSize);
- *oat_end = RoundUp(reinterpret_cast32<uint32_t>(system_hdr.GetOatFileEnd()), kPageSize);
+ *end = RoundUp(reinterpret_cast32<uint32_t>(system_hdr.GetOatFileEnd()), kPageSize);
return true;
}
- bool ReserveBootImageMemory(uint32_t image_start,
- uint32_t image_end,
- uint32_t oat_end,
+ bool ReserveBootImageMemory(uint32_t reservation_size,
+ uint32_t image_start,
size_t extra_reservation_size,
/*out*/MemMap* image_reservation,
- /*out*/MemMap* oat_reservation,
/*out*/MemMap* extra_reservation,
/*out*/std::string* error_msg) {
DCHECK(!image_reservation->IsValid());
- size_t total_size =
- dchecked_integral_cast<size_t>(oat_end - image_start) + extra_reservation_size;
+ DCHECK_LT(extra_reservation_size, std::numeric_limits<uint32_t>::max() - reservation_size);
+ size_t total_size = reservation_size + extra_reservation_size;
bool relocate = Runtime::Current()->ShouldRelocate();
// If relocating, choose a random address for ALSR.
uint32_t addr = relocate ? ART_BASE_ADDRESS + ChooseRelocationOffsetDelta() : image_start;
@@ -2140,37 +2097,17 @@
return false;
}
}
- uint32_t diff = reinterpret_cast32<uint32_t>(image_reservation->Begin()) - image_start;
- image_start += diff;
- image_end += diff;
- oat_end += diff;
- DCHECK(!oat_reservation->IsValid());
- *oat_reservation = image_reservation->RemapAtEnd(reinterpret_cast32<uint8_t*>(image_end),
- "Boot image oat reservation",
- PROT_NONE,
- error_msg);
- if (!oat_reservation->IsValid()) {
- return false;
- }
return true;
}
- bool CheckReservationsExhausted(const MemMap& image_reservation,
- const MemMap& oat_reservation,
- /*out*/std::string* error_msg) {
+ bool CheckReservationExhausted(const MemMap& image_reservation, /*out*/std::string* error_msg) {
if (image_reservation.IsValid()) {
*error_msg = StringPrintf("Excessive image reservation after loading boot image: %p-%p",
image_reservation.Begin(),
image_reservation.End());
return false;
}
- if (oat_reservation.IsValid()) {
- *error_msg = StringPrintf("Excessive oat reservation after loading boot image: %p-%p",
- image_reservation.Begin(),
- image_reservation.End());
- return false;
- }
return true;
}
@@ -2374,12 +2311,11 @@
std::unique_ptr<ImageSpace> ImageSpace::CreateFromAppImage(const char* image,
const OatFile* oat_file,
std::string* error_msg) {
+ // Note: The oat file has already been validated.
return Loader::InitAppImage(image,
image,
- /*validate_oat_file=*/ false,
oat_file,
/*image_reservation=*/ nullptr,
- /*oat_reservation=*/ nullptr,
error_msg);
}
diff --git a/runtime/image.cc b/runtime/image.cc
index f4c3fea..3023cef 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -26,7 +26,7 @@
namespace art {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '6', '8', '\0' }; // Image checksums.
+const uint8_t ImageHeader::kImageVersion[] = { '0', '6', '9', '\0' }; // Remove boot oat extents.
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_size,
@@ -39,8 +39,6 @@
uint32_t oat_file_end,
uint32_t boot_image_begin,
uint32_t boot_image_size,
- uint32_t boot_oat_begin,
- uint32_t boot_oat_size,
uint32_t pointer_size,
StorageMode storage_mode,
size_t data_size)
@@ -54,8 +52,6 @@
oat_file_end_(oat_file_end),
boot_image_begin_(boot_image_begin),
boot_image_size_(boot_image_size),
- boot_oat_begin_(boot_oat_begin),
- boot_oat_size_(boot_oat_size),
image_roots_(image_roots),
pointer_size_(pointer_size),
storage_mode_(storage_mode),
diff --git a/runtime/image.h b/runtime/image.h
index 5245cea..f33b9b2 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -93,23 +93,7 @@
};
static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
- ImageHeader()
- : image_begin_(0U),
- image_size_(0U),
- image_checksum_(0u),
- oat_checksum_(0U),
- oat_file_begin_(0U),
- oat_data_begin_(0U),
- oat_data_end_(0U),
- oat_file_end_(0U),
- boot_image_begin_(0U),
- boot_image_size_(0U),
- boot_oat_begin_(0U),
- boot_oat_size_(0U),
- image_roots_(0U),
- pointer_size_(0U),
- storage_mode_(kDefaultStorageMode),
- data_size_(0) {}
+ ImageHeader() {}
ImageHeader(uint32_t image_begin,
uint32_t image_size,
@@ -122,8 +106,6 @@
uint32_t oat_file_end,
uint32_t boot_image_begin,
uint32_t boot_image_size,
- uint32_t boot_oat_begin,
- uint32_t boot_oat_size,
uint32_t pointer_size,
StorageMode storage_mode,
size_t data_size);
@@ -322,14 +304,6 @@
return boot_image_size_;
}
- uint32_t GetBootOatBegin() const {
- return boot_oat_begin_;
- }
-
- uint32_t GetBootOatSize() const {
- return boot_oat_size_;
- }
-
StorageMode GetStorageMode() const {
return storage_mode_;
}
@@ -390,43 +364,39 @@
uint8_t version_[4];
// Required base address for mapping the image.
- uint32_t image_begin_;
+ uint32_t image_begin_ = 0u;
// Image size, not page aligned.
- uint32_t image_size_;
+ uint32_t image_size_ = 0u;
// Image file checksum (calculated with the checksum field set to 0).
- uint32_t image_checksum_;
+ uint32_t image_checksum_ = 0u;
// Checksum of the oat file we link to for load time sanity check.
- uint32_t oat_checksum_;
+ uint32_t oat_checksum_ = 0u;
// Start address for oat file. Will be before oat_data_begin_ for .so files.
- uint32_t oat_file_begin_;
+ uint32_t oat_file_begin_ = 0u;
// Required oat address expected by image Method::GetCode() pointers.
- uint32_t oat_data_begin_;
+ uint32_t oat_data_begin_ = 0u;
// End of oat data address range for this image file.
- uint32_t oat_data_end_;
+ uint32_t oat_data_end_ = 0u;
// End of oat file address range. will be after oat_data_end_ for
// .so files. Used for positioning a following alloc spaces.
- uint32_t oat_file_end_;
+ uint32_t oat_file_end_ = 0u;
// Boot image begin and end (app image headers only).
- uint32_t boot_image_begin_;
- uint32_t boot_image_size_;
-
- // Boot oat begin and end (app image headers only).
- uint32_t boot_oat_begin_;
- uint32_t boot_oat_size_;
+ uint32_t boot_image_begin_ = 0u;
+ uint32_t boot_image_size_ = 0u; // Includes heap (*.art) and code (.oat).
// Absolute address of an Object[] of objects needed to reinitialize from an image.
- uint32_t image_roots_;
+ uint32_t image_roots_ = 0u;
// Pointer size, this affects the size of the ArtMethods.
- uint32_t pointer_size_;
+ uint32_t pointer_size_ = 0u;
// Image section sizes/offsets correspond to the uncompressed form.
ImageSection sections_[kSectionCount];
@@ -435,11 +405,11 @@
uint64_t image_methods_[kImageMethodsCount];
// Storage method for the image, the image may be compressed.
- StorageMode storage_mode_;
+ StorageMode storage_mode_ = kDefaultStorageMode;
// Data size for the image data excluding the bitmap and the header. For compressed images, this
// is the compressed size in the file.
- uint32_t data_size_;
+ uint32_t data_size_ = 0u;
friend class linker::ImageWriter;
};