diff options
author | 2024-11-18 18:12:53 +0000 | |
---|---|---|
committer | 2024-11-18 19:32:40 +0000 | |
commit | fcb5c3a0cc8776cfedf8d289c5de19b605afe7ae (patch) | |
tree | 5bdd3d877491acc38ea644065882ebd8c4423a2e | |
parent | 7a97baeb4f553cdf6c9b4db2f9bae39cb0b74e6d (diff) |
Force 4K ELF alignment on art/odex files.
Bug: 376814207
Test: atest art_standalone_dexpreopt_tests (on 4K page size)
Test: atest CtsCompilationTestCases (on 4K page size)
Test: adb shell pm art dump (on 4K page size, see "speed-profile" on
some apps, meaning odex files are accepted)
Test: adb shell pm art dump (on 16K page size, see "[reason=vdex]" on
all apps, meaning odex files are rejected)
Change-Id: Ie71b8910fd9662db01f860441bc50967ce31cd0c
-rw-r--r-- | artd/artd.cc | 1 | ||||
-rw-r--r-- | libartbase/base/globals.h | 4 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 11 | ||||
-rw-r--r-- | runtime/oat/oat.h | 4 | ||||
-rw-r--r-- | runtime/oat/oat_file_assistant.cc | 14 | ||||
-rw-r--r-- | runtime/runtime.cc | 6 | ||||
-rw-r--r-- | runtime/runtime.h | 3 | ||||
-rw-r--r-- | runtime/runtime_image.cc | 5 |
8 files changed, 45 insertions, 3 deletions
diff --git a/artd/artd.cc b/artd/artd.cc index ee4f5588aa..c8a1b6cdab 100644 --- a/artd/artd.cc +++ b/artd/artd.cc @@ -1500,6 +1500,7 @@ ScopedAStatus Artd::checkPreRebootSystemRequirements(const std::string& in_chroo Result<void> Artd::Start() { OR_RETURN(SetLogVerbosity()); MemMap::Init(); + Runtime::AllowPageSizeAccess(); ScopedAStatus status = ScopedAStatus::fromStatus(AServiceManager_registerLazyService( this->asBinder().get(), options_.is_pre_reboot ? kPreRebootServiceName : kServiceName)); diff --git a/libartbase/base/globals.h b/libartbase/base/globals.h index cab7fab63d..7348444e1c 100644 --- a/libartbase/base/globals.h +++ b/libartbase/base/globals.h @@ -53,7 +53,9 @@ static constexpr size_t kMaxPageSize = kMinPageSize; // to be able to generate OAT (ELF) and other image files with alignment other than the host page // size. kElfSegmentAlignment needs to be equal to the largest page size supported. Effectively, // this is the value to be used in images files for aligning contents to page size. -static constexpr size_t kElfSegmentAlignment = kMaxPageSize; +// However, it's temporarily set to 4096 now, to prevent dex2oat from creating sparse files. +// TODO(b/378794327): Fix this. +static constexpr size_t kElfSegmentAlignment = kMinPageSize; // Clion, clang analyzer, etc can falsely believe that "if (kIsDebugBuild)" always // returns the same value. By wrapping into a call to another constexpr function, we force it diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index d28a534440..18f4c4205a 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -65,6 +65,7 @@ #include "oat/oat_file.h" #include "profile/profile_compilation_info.h" #include "runtime.h" +#include "runtime_globals.h" #include "space-inl.h" namespace art HIDDEN { @@ -564,6 +565,11 @@ class ImageSpace::Loader { REQUIRES(!Locks::mutator_lock_) { TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image)); + if (gPageSize != kMinPageSize) { + *error_msg = "Loading app image is only supported on devices with 4K page size"; + return nullptr; + } + std::unique_ptr<ImageSpace> space = Init(image_filename, image_location, &logger, @@ -3243,6 +3249,11 @@ bool ImageSpace::BootImageLoader::LoadFromSystem( /*out*/std::string* error_msg) { TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image)); + if (gPageSize != kMinPageSize) { + *error_msg = "Loading boot image is only supported on devices with 4K page size"; + return false; + } + BootImageLayout layout(image_locations_, boot_class_path_, boot_class_path_locations_, diff --git a/runtime/oat/oat.h b/runtime/oat/oat.h index fbd83974f0..f9bb57cd72 100644 --- a/runtime/oat/oat.h +++ b/runtime/oat/oat.h @@ -44,8 +44,8 @@ std::ostream& operator<<(std::ostream& stream, StubType stub_type); class EXPORT PACKED(4) OatHeader { public: static constexpr std::array<uint8_t, 4> kOatMagic { { 'o', 'a', 't', '\n' } }; - // Last oat version changed reason: Store resolved MethodType-s in .bss. - static constexpr std::array<uint8_t, 4> kOatVersion{{'2', '4', '9', '\0'}}; + // Last oat version changed reason: Force 4K ELF alignment on art/odex files. + static constexpr std::array<uint8_t, 4> kOatVersion{{'2', '5', '2', '\0'}}; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; static constexpr const char* kDebuggableKey = "debuggable"; diff --git a/runtime/oat/oat_file_assistant.cc b/runtime/oat/oat_file_assistant.cc index 151c3a6ca9..7ee65db1a5 100644 --- a/runtime/oat/oat_file_assistant.cc +++ b/runtime/oat/oat_file_assistant.cc @@ -51,6 +51,7 @@ #include "oat.h" #include "oat_file_assistant_context.h" #include "runtime.h" +#include "runtime_globals.h" #include "scoped_thread_state_change-inl.h" #include "vdex_file.h" #include "zlib.h" @@ -1106,6 +1107,12 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { executable = LocationIsTrusted(filename_, /*trust_art_apex_data_files=*/true); } VLOG(oat) << "Loading " << filename_ << " with executable: " << executable; + + if (gPageSize != kMinPageSize) { + LOG(WARNING) << "Loading odex files is only supported on devices with 4K page size"; + return nullptr; + } + if (use_fd_) { if (oat_fd_ >= 0 && vdex_fd_ >= 0) { ArrayRef<const std::string> dex_locations(&oat_file_assistant_->dex_location_, @@ -1144,6 +1151,13 @@ bool OatFileAssistant::OatFileInfo::ShouldRecompileForFilter(CompilerFilter::Fil const OatFile* file = GetFile(); DCHECK(file != nullptr); + if (CompilerFilter::IsBetter(target, CompilerFilter::kVerify) && gPageSize != kMinPageSize) { + // Prevent infinite recompilations during background dexopt on 16K page devices. + VLOG(oat) << "Adjusting target filter to 'verify' because loading odex files is only supported " + "on devices with 4K page size"; + target = CompilerFilter::kVerify; + } + CompilerFilter::Filter current = file->GetCompilerFilter(); if (dexopt_trigger.targetFilterIsBetter && CompilerFilter::IsBetter(target, current)) { VLOG(oat) << ART_FORMAT("Should recompile: targetFilterIsBetter (current: {}, target: {})", diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 4ceb2bb72e..4db65e5ace 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -3501,4 +3501,10 @@ void Runtime::DCheckNoTransactionCheckAllowed() { } } +NO_INLINE void Runtime::AllowPageSizeAccess() { +#ifdef ART_PAGE_SIZE_AGNOSTIC + gPageSize.AllowAccess(); +#endif +} + } // namespace art diff --git a/runtime/runtime.h b/runtime/runtime.h index e43d1d3432..97eac64fa1 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -1134,6 +1134,9 @@ class Runtime { bool AreMetricsInitialized() const { return metrics_reporter_ != nullptr; } + // For `artd` only. + EXPORT static void AllowPageSizeAccess(); + private: static void InitPlatformSignalHandlers(); diff --git a/runtime/runtime_image.cc b/runtime/runtime_image.cc index 77548ee27e..c73810de59 100644 --- a/runtime/runtime_image.cc +++ b/runtime/runtime_image.cc @@ -1872,6 +1872,11 @@ static bool EnsureDirectoryExists(const std::string& directory, std::string* err } bool RuntimeImage::WriteImageToDisk(std::string* error_msg) { + if (gPageSize != kMinPageSize) { + *error_msg = "Writing runtime image is only supported on devices with 4K page size"; + return false; + } + gc::Heap* heap = Runtime::Current()->GetHeap(); if (!heap->HasBootImageSpace()) { *error_msg = "Cannot generate an app image without a boot image"; |