]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwfl_core_file_report: Fix core files for re-prelink-ed files
authorJan Kratochvil <jan.kratochvil@redhat.com>
Thu, 7 Nov 2013 15:47:19 +0000 (16:47 +0100)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Thu, 7 Nov 2013 15:47:19 +0000 (16:47 +0100)
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
libdwfl/ChangeLog
libdwfl/core-file.c
libdwfl/libdwflP.h
libdwfl/link_map.c

index 5b445e120e1b24892561000b66ac510228046781..7f36bdf8ac7ce82094ce7a7316e725ec72f3391d 100644 (file)
@@ -1,3 +1,12 @@
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix core files for re-prelink-ed files.
+       * core-file.c (dynamic_vaddr_get): New function.
+       (dwfl_core_file_report): New variable file_dynamic_vaddr.  Call
+       dynamic_vaddr_get instead of using L_ADDR.
+       * libdwflP.h (struct r_debug_info_module): Remove field l_addr.
+       * link_map.c (report_r_debug): Do not initialize l_addr.
+
 2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Code cleanup.
index 24a3b2482da36ae4d376a9677ba003e7869f8ff4..665fcf7a4e664e9c5707bccd7208b30212e82d3b 100644 (file)
@@ -397,6 +397,27 @@ clear_r_debug_info (struct r_debug_info *r_debug_info)
     }
 }
 
+static bool
+dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
+{
+  size_t phnum;
+  if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+    return false;
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+      if (unlikely (phdr == NULL))
+       return false;
+      if (phdr->p_type == PT_DYNAMIC)
+       {
+         *vaddrp = phdr->p_vaddr;
+         return true;
+       }
+    }
+  return false;
+}
+
 int
 dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
 {
@@ -503,9 +524,13 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
     {
       if (module->elf == NULL)
        continue;
+      GElf_Addr file_dynamic_vaddr;
+      if (! dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
+       continue;
       Dwfl_Module *mod;
       mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
-                                 module->fd, module->elf, module->l_addr,
+                                 module->fd, module->elf,
+                                 module->l_ld - file_dynamic_vaddr,
                                  true, true);
       if (mod == NULL)
        continue;
index 1d4899b83e6d63a7f2d87719f568bb319cfd4beb..7e46478d42b46a70de98ef77e998562c21208bbc 100644 (file)
@@ -467,7 +467,7 @@ struct r_debug_info_module
   /* FD is -1 iff ELF is NULL.  */
   int fd;
   Elf *elf;
-  GElf_Addr l_addr, l_ld;
+  GElf_Addr l_ld;
   /* START and END are both zero if not valid.  */
   GElf_Addr start, end;
   bool disk_file_has_build_id;
index 65e1c3a6ed51a32d3bc52c0785a9ec7e2397a1b4..b094b9bc99f43d9b5680d463ea9d73bc3d258879 100644 (file)
@@ -369,7 +369,6 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
            return release_buffer (result);
          r_debug_info_module->fd = -1;
          r_debug_info_module->elf = NULL;
-         r_debug_info_module->l_addr = l_addr;
          r_debug_info_module->l_ld = l_ld;
          r_debug_info_module->start = 0;
          r_debug_info_module->end = 0;