linker: Set VMA name for bss sections
The linker currently sets VMA name ".bss" for bss sections in DSOs
loaded by the linker. With this change, the linker now also sets VMA
name for bss sections in the linker itself and the main executable, so
that they don't get left out in various accounting.
Test: Run 'dd' and check its /proc/<pid>/maps.
Change-Id: I62d9996ab256f46e2d82cac581c17fa94836a228
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 11d3d29..fd1592d 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -63,6 +63,8 @@
static void get_elf_base_from_phdr(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr)* base, ElfW(Addr)* load_bias);
+static void set_bss_vma_name(soinfo* si);
+
// These should be preserved static to avoid emitting
// RELATIVE relocations for the part of the code running
// before linker links itself.
@@ -366,6 +368,8 @@
si->set_main_executable();
init_link_map_head(*si);
+ set_bss_vma_name(si);
+
// Use the executable's PT_INTERP string as the solinker filename in the
// dynamic linker's module list. gdb reads both PT_INTERP and the module list,
// and if the paths for the linker are different, gdb will report that the
@@ -570,6 +574,31 @@
async_safe_fatal("Could not find a PHDR: broken executable?");
}
+/*
+ * Set anonymous VMA name for .bss section. For DSOs loaded by the linker, this
+ * is done by ElfReader. This function is here for DSOs loaded by the kernel,
+ * namely the linker itself and the main executable.
+ */
+static void set_bss_vma_name(soinfo* si) {
+ for (size_t i = 0; i < si->phnum; ++i) {
+ auto phdr = &si->phdr[i];
+
+ if (phdr->p_type != PT_LOAD) {
+ continue;
+ }
+
+ ElfW(Addr) seg_start = phdr->p_vaddr + si->load_bias;
+ ElfW(Addr) seg_page_end = PAGE_END(seg_start + phdr->p_memsz);
+ ElfW(Addr) seg_file_end = PAGE_END(seg_start + phdr->p_filesz);
+
+ if (seg_page_end > seg_file_end) {
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME,
+ reinterpret_cast<void*>(seg_file_end), seg_page_end - seg_file_end,
+ ".bss");
+ }
+ }
+}
+
// Detect an attempt to run the linker on itself. e.g.:
// /system/bin/linker64 /system/bin/linker64
// Use priority-1 to run this constructor before other constructors.
@@ -660,6 +689,9 @@
// couldn't make system calls on x86 at that point, but we can now...
if (!tmp_linker_so.protect_relro()) __linker_cannot_link(args.argv[0]);
+ // And we can set VMA name for the bss section now
+ set_bss_vma_name(&tmp_linker_so);
+
// Initialize the linker's static libc's globals
__libc_init_globals();