944164c5e2
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> |
||
---|---|---|
.. | ||
arch | ||
testdata | ||
Android.bp | ||
dlfcn.cpp | ||
ld.config.format.md | ||
ld_android.cpp | ||
ldd.sh | ||
linked_list.h | ||
linked_list_test.cpp | ||
linker.arm.map | ||
linker.cpp | ||
linker.generic.map | ||
linker.h | ||
linker_auxv.cpp | ||
linker_auxv.h | ||
linker_block_allocator.cpp | ||
linker_block_allocator.h | ||
linker_block_allocator_test.cpp | ||
linker_cfi.cpp | ||
linker_cfi.h | ||
linker_common_types.h | ||
linker_config.cpp | ||
linker_config.h | ||
linker_config_test.cpp | ||
linker_crt_pad_segment_test.cpp | ||
linker_debug.cpp | ||
linker_debug.h | ||
linker_debuggerd.h | ||
linker_debuggerd_android.cpp | ||
linker_debuggerd_stub.cpp | ||
linker_dlwarning.cpp | ||
linker_dlwarning.h | ||
linker_gdb_support.cpp | ||
linker_gdb_support.h | ||
linker_globals.cpp | ||
linker_globals.h | ||
linker_gnu_hash.h | ||
linker_gnu_hash_benchmark.cpp | ||
linker_gnu_hash_test.cpp | ||
linker_libc_support.c | ||
linker_libcxx_support.cpp | ||
linker_logger.cpp | ||
linker_logger.h | ||
linker_main.cpp | ||
linker_main.h | ||
linker_mapped_file_fragment.cpp | ||
linker_mapped_file_fragment.h | ||
linker_memory.cpp | ||
linker_namespaces.cpp | ||
linker_namespaces.h | ||
linker_note_gnu_property.cpp | ||
linker_note_gnu_property.h | ||
linker_note_gnu_property_test.cpp | ||
linker_phdr.cpp | ||
linker_phdr.h | ||
linker_reloc_iterators.h | ||
linker_relocate.cpp | ||
linker_relocate.h | ||
linker_relocs.h | ||
linker_sdk_versions.cpp | ||
linker_sleb128.h | ||
linker_sleb128_test.cpp | ||
linker_soinfo.cpp | ||
linker_soinfo.h | ||
linker_test_globals.cpp | ||
linker_tls.cpp | ||
linker_tls.h | ||
linker_translate_path.cpp | ||
linker_translate_path.h | ||
linker_transparent_hugepage_support.cpp | ||
linker_utils.cpp | ||
linker_utils.h | ||
linker_utils_test.cpp | ||
linker_wrapper.cpp | ||
MODULE_LICENSE_BSD | ||
NOTICE | ||
rt.cpp |