summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2013-11-07 16:47:19 +0100
committerJan Kratochvil <jan.kratochvil@redhat.com>2013-11-07 16:47:19 +0100
commit35d95f378d2f2732055523abcbbfd58f7a404dcd (patch)
tree6bbf5a0c1eb5ba31472f9597d34fc5920945dbb1
parent21783b5e2a284081a9b9c8e451f844565b5f0a66 (diff)
downloadelfutils-35d95f378d2f2732055523abcbbfd58f7a404dcd.tar.gz
dwfl_core_file_report: Fix core files for re-prelink-ed files
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
-rw-r--r--libdwfl/ChangeLog9
-rw-r--r--libdwfl/core-file.c27
-rw-r--r--libdwfl/libdwflP.h2
-rw-r--r--libdwfl/link_map.c1
4 files changed, 36 insertions, 3 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5b445e12..7f36bdf8 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,14 @@
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.
* core-file.c (dwfl_core_file_report): Reindent block of code by
continue keyword.
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 24a3b248..665fcf7a 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -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;
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 1d4899b8..7e46478d 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -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;
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 65e1c3a6..b094b9bc 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -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;