Merge "linker: Set VMA name for bss sections"
am: a40a1442a8

Change-Id: I0f4c3458f6e8d76311b3e691581755191011822b
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();