linker: LoadSegments: Factor out DropPaddingPages()
This is a preparatory patch for 16KiB app compat. No functional change
is introduced.
Bug: 339709616
Test: atest -c linker-unit-tests
Change-Id: Ibd11ef972094fcc8406a1ff93b3adbfb82b7c8ad
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index a842dfd..02c5079 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -897,6 +897,33 @@
}
}
+void ElfReader::DropPaddingPages(const ElfW(Phdr)* phdr, uint64_t seg_file_end) {
+ ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
+ uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
+
+ uint64_t pad_start = page_end(unextended_seg_file_end);
+ uint64_t pad_end = page_end(seg_file_end);
+ CHECK(pad_start <= pad_end);
+
+ uint64_t pad_len = pad_end - pad_start;
+ if (pad_len == 0 || !page_size_migration_supported()) {
+ return;
+ }
+
+ // Pages may be brought in due to readahead.
+ // Drop the padding (zero) pages, to avoid reclaim work later.
+ //
+ // NOTE: The madvise() here is special, as it also serves to hint to the
+ // kernel the portion of the LOAD segment that is padding.
+ //
+ // See: [1] https://android-review.googlesource.com/c/kernel/common/+/3032411
+ // [2] https://android-review.googlesource.com/c/kernel/common/+/3048835
+ if (madvise(reinterpret_cast<void*>(pad_start), pad_len, MADV_DONTNEED)) {
+ DL_WARN("\"%s\": madvise(0x%" PRIx64 ", 0x%" PRIx64 ", MADV_DONTNEED) failed: %m",
+ name_.c_str(), pad_start, pad_len);
+ }
+}
+
bool ElfReader::LoadSegments() {
size_t min_palign = phdr_table_get_minimum_alignment(phdr_table_, phdr_num_);
// Only enforce this on 16 KB systems. Apps may rely on undefined behavior
@@ -971,24 +998,7 @@
ZeroFillSegment(phdr);
- uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
- // Pages may be brought in due to readahead.
- // Drop the padding (zero) pages, to avoid reclaim work later.
- //
- // NOTE: The madvise() here is special, as it also serves to hint to the
- // kernel the portion of the LOAD segment that is padding.
- //
- // See: [1] https://android-review.googlesource.com/c/kernel/common/+/3032411
- // [2] https://android-review.googlesource.com/c/kernel/common/+/3048835
- uint64_t pad_start = page_end(unextended_seg_file_end);
- uint64_t pad_end = page_end(seg_file_end);
- CHECK(pad_start <= pad_end);
- uint64_t pad_len = pad_end - pad_start;
- if (page_size_migration_supported() && pad_len > 0 &&
- madvise(reinterpret_cast<void*>(pad_start), pad_len, MADV_DONTNEED)) {
- DL_WARN("\"%s\": madvise(0x%" PRIx64 ", 0x%" PRIx64 ", MADV_DONTNEED) failed: %m",
- name_.c_str(), pad_start, pad_len);
- }
+ DropPaddingPages(phdr, seg_file_end);
seg_file_end = page_end(seg_file_end);
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 4028062..33e55ac 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -70,6 +70,7 @@
[[nodiscard]] bool ReserveAddressSpace(address_space_params* address_space);
[[nodiscard]] bool MapSegment(size_t seg_idx, size_t len);
void ZeroFillSegment(const ElfW(Phdr)* phdr);
+ void DropPaddingPages(const ElfW(Phdr)* phdr, uint64_t seg_file_end);
[[nodiscard]] bool LoadSegments();
[[nodiscard]] bool FindPhdr();
[[nodiscard]] bool FindGnuPropertySection();