loader: Only extend segments if kernel supports page size migration am: c5c1d19ebb

Original change: https://android-review.googlesource.com/c/platform/bionic/+/3035335

Change-Id: Ie2eec54ba3c7307ae138787cf7f12a7e7992e941
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Kalesh Singh 2024-05-02 19:54:51 +00:00 committed by Automerger Merge Worker
commit e560bde675
3 changed files with 33 additions and 0 deletions

View file

@ -72,13 +72,22 @@ bool GetPadSegment(const std::string& elf_path) {
}; // anonymous namespace
TEST(crt_pad_segment, note_absent) {
if (!page_size_migration_supported()) {
GTEST_SKIP() << "Kernel does not support page size migration";
}
ASSERT_FALSE(GetPadSegment("no_crt_pad_segment.so"));
}
TEST(crt_pad_segment, note_present_and_enabled) {
if (!page_size_migration_supported()) {
GTEST_SKIP() << "Kernel does not support page size migration";
}
ASSERT_TRUE(GetPadSegment("crt_pad_segment_enabled.so"));
}
TEST(crt_pad_segment, note_present_and_disabled) {
if (!page_size_migration_supported()) {
GTEST_SKIP() << "Kernel does not support page size migration";
}
ASSERT_FALSE(GetPadSegment("crt_pad_segment_disabled.so"));
}

View file

@ -46,6 +46,8 @@
#include "private/CFIShadow.h" // For kLibraryAlignment
#include "private/elf_note.h"
#include <android-base/file.h>
static int GetTargetElfMachine() {
#if defined(__arm__)
return EM_ARM;
@ -707,8 +709,28 @@ bool ElfReader::ReserveAddressSpace(address_space_params* address_space) {
return true;
}
/*
* Returns true if the kernel supports page size migration, else false.
*/
bool page_size_migration_supported() {
static bool pgsize_migration_enabled = []() {
std::string enabled;
if (!android::base::ReadFileToString("/sys/kernel/mm/pgsize_migration/enabled", &enabled)) {
return false;
}
return enabled.find("1") != std::string::npos;
}();
return pgsize_migration_enabled;
}
// Find the ELF note of type NT_ANDROID_TYPE_PAD_SEGMENT and check that the desc value is 1.
bool ElfReader::ReadPadSegmentNote() {
if (!page_size_migration_supported()) {
// Don't attempt to read the note, since segment extension isn't
// supported; but return true so that loading can continue normally.
return true;
}
// The ELF can have multiple PT_NOTE's, check them all
for (size_t i = 0; i < phdr_num_; ++i) {
const ElfW(Phdr)* phdr = &phdr_table_[i];

View file

@ -154,3 +154,5 @@ void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_co
const char* phdr_table_get_interpreter_name(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias);
bool page_size_migration_supported();