summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2024-11-18 18:12:53 +0000
committer Jiakai Zhang <jiakaiz@google.com> 2024-11-18 19:32:40 +0000
commitfcb5c3a0cc8776cfedf8d289c5de19b605afe7ae (patch)
tree5bdd3d877491acc38ea644065882ebd8c4423a2e
parent7a97baeb4f553cdf6c9b4db2f9bae39cb0b74e6d (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.cc1
-rw-r--r--libartbase/base/globals.h4
-rw-r--r--runtime/gc/space/image_space.cc11
-rw-r--r--runtime/oat/oat.h4
-rw-r--r--runtime/oat/oat_file_assistant.cc14
-rw-r--r--runtime/runtime.cc6
-rw-r--r--runtime/runtime.h3
-rw-r--r--runtime/runtime_image.cc5
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";