platform_bionic/linker
Kalesh Singh 944164c5e2 RELAND: bionic: loader: Extend LOAD segment VMAs
When the page_size < p_align of the ELF load segment, the loader
will end up creating extra PROT_NONE gap VMA mappings between the
LOAD segments. This problem is exacerbated by Android's zygote
model, where the number of loaded .so's can lead to ~30MB increase
in vm_area_struct unreclaimable slab memory.

Extend the LOAD segment VMA's to cover the range between the
segment's end and the start of the next segment, being careful
to avoid touching regions of the extended mapping where the offset
would overrun the size of the file. This avoids the loader
creating an additional gap VMA for each LOAD segment.

Consider a system with 4KB page size and the ELF files with 64K
alignment. e.g:

$ readelf -Wl /system/lib64/bootstrap/libc.so | grep 'Type\|LOAD'

Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0441a8 0x0441a8 R   0x10000
LOAD           0x0441b0 0x00000000000541b0 0x00000000000541b0 0x091860 0x091860 R E 0x10000
LOAD           0x0d5a10 0x00000000000f5a10 0x00000000000f5a10 0x003d40 0x003d40 RW  0x10000
LOAD           0x0d9760 0x0000000000109760 0x0000000000109760 0x0005c0 0x459844 RW  0x10000

Before this patch:

$ cat /proc/1/maps | grep -A1 libc.so

7fa1d4a90000-7fa1d4ad5000 r--p 00000000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7fa1d4ad5000-7fa1d4ae4000 ---p 00000000 00:00 0
7fa1d4ae4000-7fa1d4b76000 r-xp 00044000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7fa1d4b76000-7fa1d4b85000 ---p 00000000 00:00 0
7fa1d4b85000-7fa1d4b8a000 r--p 000d5000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7fa1d4b8a000-7fa1d4b99000 ---p 00000000 00:00 0
7fa1d4b99000-7fa1d4b9a000 rw-p 000d9000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7fa1d4b9a000-7fa1d4feb000 rw-p 00000000 00:00 0                          [anon:.bss]

3 additional PROT_NONE (---p) VMAs for gap mappings.

After this patch:

$ cat /proc/1/maps | grep -A1 libc.so

7f468f069000-7f468f0bd000 r--p 00000000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7f468f0bd000-7f468f15e000 r-xp 00044000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7f468f15e000-7f468f163000 r--p 000d5000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7f468f163000-7f468f172000 rw-p 000da000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7f468f172000-7f468f173000 rw-p 000d9000 fe:09 20635520                   /system/lib64/bootstrap/libc.so
7f468f173000-7f468f5c4000 rw-p 00000000 00:00 0                          [anon:.bss]

No additional gap VMAs. However notice there is an extra RW VMA at
offset 0x000da000. This is caused by the RO protection of the
GNU_RELRO segment, which causes the extended RW VMA to split.
The GNU_RELRO protection extension is handled in the subsequent
patch in this series.

Bug: 316403210
Bug: 300367402
Bug: 307803052
Bug: 312550202
Test: atest -c linker-unit-tests
Test: atest -c bionic-unit-tests
Change-Id: I7150ed22af0723cc0b2d326c046e4e4a8b56ad09
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
2024-02-27 06:13:11 +00:00
..
arch riscv64: don't use jalr when we can just say call. 2023-05-12 12:56:54 -07:00
testdata bionic: linker-unit-tests: Add crt_pad_segment tests 2024-02-07 16:20:48 -08:00
Android.bp RELAND: bionic: loader: Extend LOAD segment VMAs 2024-02-27 06:13:11 +00:00
dlfcn.cpp Revert "Linker support for MTE globals." 2023-12-06 19:01:46 +00:00
ld.config.format.md linker: Cleanup for Android's inclusive language guidance 2020-07-31 11:37:28 +08:00
ld_android.cpp Add the recoverable GWP-ASan feature. 2023-02-02 15:35:25 -08:00
ldd.sh Ignore LD_LIBRARY_PATH when determining file type in ldd. 2021-03-02 16:56:39 +00:00
linked_list.h Keep allocation of tail_ outside of LinkedList 2022-02-01 21:32:30 -08:00
linked_list_test.cpp Switch linker tests to Android.bp. 2019-02-15 14:40:08 -08:00
linker.arm.map Add the recoverable GWP-ASan feature. 2023-02-02 15:35:25 -08:00
linker.cpp RELAND: bionic: loader: Extend LOAD segment VMAs 2024-02-27 06:13:11 +00:00
linker.generic.map Add the recoverable GWP-ASan feature. 2023-02-02 15:35:25 -08:00
linker.h Merge "Remove unused declarations." into main 2023-10-05 23:28:52 +00:00
linker_auxv.cpp linker: add the L3 cache auxv constants. 2023-10-23 18:42:00 -07:00
linker_auxv.h linker: add LD_SHOW_AUXV support. 2023-08-22 14:25:01 -07:00
linker_block_allocator.cpp linker_block_alloctor: Remove 4k page size assumption 2023-08-04 23:08:34 +00:00
linker_block_allocator.h Change default block size alignment to be 4 for memory saving on 32-bit arch 2022-02-03 16:55:37 -08:00
linker_block_allocator_test.cpp Change default block size alignment to be 4 for memory saving on 32-bit arch 2022-02-03 16:55:37 -08:00
linker_cfi.cpp Remove PAGE_SIZE call sites. 2023-06-12 10:59:39 -07:00
linker_cfi.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_common_types.h Remove unused mips/mips64 code from the linker. 2020-02-13 15:58:48 -08:00
linker_config.cpp Introduce hwasan mode for linker 2023-04-14 01:33:30 -07:00
linker_config.h Introduce hwasan mode for linker 2023-04-14 01:33:30 -07:00
linker_config_test.cpp Introduce hwasan mode for linker 2023-04-14 01:33:30 -07:00
linker_crt_pad_segment_test.cpp bionic: linker-unit-tests: Add crt_pad_segment tests 2024-02-07 16:20:48 -08:00
linker_debug.cpp Create linker_log[_va_list] functions 2020-01-06 16:06:37 -08:00
linker_debug.h Fix bugprone-macro-parentheses warnings 2020-03-04 13:22:05 -08:00
linker_debuggerd.h Add the recoverable GWP-ASan feature. 2023-02-02 15:35:25 -08:00
linker_debuggerd_android.cpp Add API to allow apps to attach extra information to tombstones. 2024-02-13 13:41:12 -08:00
linker_debuggerd_stub.cpp Add the recoverable GWP-ASan feature. 2023-02-02 15:35:25 -08:00
linker_dlwarning.cpp Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_dlwarning.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_gdb_support.cpp Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_gdb_support.h Switch the rest of our internal headers to #pragma once. 2018-02-13 14:27:17 -08:00
linker_globals.cpp Enable BTI in bionic linker 2020-09-23 17:53:28 -07:00
linker_globals.h Hold the loader mutex in linker_main once constructors are running 2023-07-21 23:14:46 -07:00
linker_gnu_hash.h Neon-optimized version of the GNU symbol calculation 2020-01-13 13:29:25 -08:00
linker_gnu_hash_benchmark.cpp Neon-optimized version of the GNU symbol calculation 2020-01-13 13:29:25 -08:00
linker_gnu_hash_test.cpp Neon-optimized version of the GNU symbol calculation 2020-01-13 13:29:25 -08:00
linker_libc_support.c Unify linker files under one license (BSD) 2017-02-15 15:35:33 -08:00
linker_libcxx_support.cpp Adapt to the new libc++/libc++abi update. 2018-01-08 14:44:42 -08:00
linker_logger.cpp Remove debug.ld.greylist_disabled property 2020-07-30 19:29:17 -07:00
linker_logger.h Remove debug.ld.greylist_disabled property 2020-07-30 19:29:17 -07:00
linker_main.cpp RELAND: bionic: loader: Extend LOAD segment VMAs 2024-02-27 06:13:11 +00:00
linker_main.h Revert "Linker support for MTE globals." 2023-12-06 19:01:46 +00:00
linker_mapped_file_fragment.cpp Remove PAGE_SIZE call sites. 2023-06-12 10:59:39 -07:00
linker_mapped_file_fragment.h Clean up bionic_macros.h a bit. 2018-10-25 11:00:00 -07:00
linker_memory.cpp Add aligned_alloc to linker_memory.cpp 2023-07-24 13:08:34 -07:00
linker_namespaces.cpp linker: Cleanup for Android's inclusive language guidance 2020-07-31 11:37:28 +08:00
linker_namespaces.h linker_namespace: move sonames instead of copying 2022-12-01 16:23:03 +09:00
linker_note_gnu_property.cpp Enable BTI in bionic linker 2020-09-23 17:53:28 -07:00
linker_note_gnu_property.h Enable BTI in bionic linker 2020-09-23 17:53:28 -07:00
linker_note_gnu_property_test.cpp Enable BTI in bionic linker 2020-09-23 17:53:28 -07:00
linker_phdr.cpp RELAND: bionic: loader: Extend LOAD segment VMAs 2024-02-27 06:13:11 +00:00
linker_phdr.h RELAND: bionic: loader: Extend LOAD segment VMAs 2024-02-27 06:13:11 +00:00
linker_reloc_iterators.h Optimize GNU hash linking for large inputs 2020-01-13 13:29:25 -08:00
linker_relocate.cpp RELAND: bionic: loader: Extend LOAD segment VMAs 2024-02-27 06:13:11 +00:00
linker_relocate.h Optimize GNU hash linking for large inputs 2020-01-13 13:29:25 -08:00
linker_relocs.h Use the R_RISCV_TLSDESC constant in the linker. 2023-10-18 14:12:31 -07:00
linker_sdk_versions.cpp Add some slack at the end of large allocations when target SDK level < S. 2021-03-05 14:29:17 -08:00
linker_sleb128.h Revert "Linker support for MTE globals." 2023-12-06 19:01:46 +00:00
linker_sleb128_test.cpp Switch linker tests to Android.bp. 2019-02-15 14:40:08 -08:00
linker_soinfo.cpp Don't memset() in the soinfo constructor. 2023-09-29 17:09:02 +00:00
linker_soinfo.h bionic: Introduce ElfReader::ReadPadSegmentNote() 2024-02-06 17:59:01 -08:00
linker_test_globals.cpp bionic: linker-unit-tests: Add crt_pad_segment tests 2024-02-07 16:20:48 -08:00
linker_tls.cpp Add a thread-properties API 2020-08-11 16:51:43 +00:00
linker_tls.h Implement arm64 TLSDESC 2019-01-29 08:33:09 +00:00
linker_translate_path.cpp Refactor translateSystemPathToApexPath 2020-05-19 02:32:07 +02:00
linker_translate_path.h Copy translateSystemPathToApexPath to linker_translate_path.cpp 2020-05-14 22:17:45 +02:00
linker_transparent_hugepage_support.cpp Fix it to call the lambda function 2022-05-19 02:13:39 +00:00
linker_utils.cpp Remove PAGE_SIZE call sites. 2023-06-12 10:59:39 -07:00
linker_utils.h Remove PAGE_SIZE call sites. 2023-06-12 10:59:39 -07:00
linker_utils_test.cpp 16k: Fix linker_utils_test to support 4kb and 16kb page sizes 2023-12-08 00:01:04 +00:00
linker_wrapper.cpp Remove host_bionic_inject 2021-06-14 12:25:05 -07:00
MODULE_LICENSE_BSD Fix/update notices. 2021-02-16 15:06:50 -08:00
NOTICE Update linker/NOTICE. 2024-02-09 09:27:33 -08:00
rt.cpp More dynamic linker cleanup. 2012-10-30 16:35:38 -07:00