Browse Source

[Pal] db_rtld.c: Fix GDB on PIE executables by fixing mapstart/mapend

Previously, there was a latent bug in db_rtld.c: add_elf_object() --
the mapstart variable was incorrectly initialized to zero. This led to
PIE executables (which typically have two LOAD segments, the code
segment starting with 0x0 and the GOT/PLT/dynamic segment starting with
e.g. 0x200000) to incorrectly set mapstart to the higher-LOAD-segment
address (and not the code address). This in turn confused GDB which
tried to add executable symbols from the wrong offset.

This commit fixes this bug by initializing mapstart to the highest
possible value ("~0") and removing the check for zero. This is similar
to what the Glibc code does. Also, mapend is fixed in a similar way.
Dmitrii Kuvaiskii 6 years ago
parent
commit
b0b29c54c8
1 changed files with 4 additions and 3 deletions
  1. 4 3
      Pal/src/db_rtld.c

+ 4 - 3
Pal/src/db_rtld.c

@@ -521,7 +521,8 @@ int add_elf_object(void * addr, PAL_HANDLE handle, int type)
     map->l_phdr  = (void *) header->e_phoff;
     map->l_phnum = header->e_phnum;
 
-    ElfW(Addr) mapstart = 0, mapend = 0;
+    ElfW(Addr) mapstart = ~0;  /* start with the highest possible address */
+    ElfW(Addr) mapend = 0;     /* start with the lowest possible address */
 
     for (ph = phdr; ph < &phdr[map->l_phnum]; ++ph)
         switch (ph->p_type) {
@@ -534,9 +535,9 @@ int add_elf_object(void * addr, PAL_HANDLE handle, int type)
                         ALLOC_ALIGNDOWN(map->l_addr + ph->p_vaddr);
                 ElfW(Addr) end = (ElfW(Addr))
                         ALLOC_ALIGNUP(map->l_addr + ph->p_vaddr + ph->p_memsz);
-                if (!mapstart || start < mapstart)
+                if (start < mapstart)
                     mapstart = start;
-                if (!mapend || end > mapend)
+                if (end > mapend)
                     mapend = end;
             }
         }