summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2013-11-21 15:28:02 +0100
committerJan Kratochvil <jan.kratochvil@redhat.com>2013-11-21 15:28:02 +0100
commit463e983e20fdb945b11bb175ca71e23b31146d8e (patch)
tree7d1b57348fe1ed0a22fef24bd4fd434631ef75a9
parent10d7a39aa2a509c16edd205c94b365ff1696f4fb (diff)
downloadelfutils-463e983e20fdb945b11bb175ca71e23b31146d8e.tar.gz
link_map: Use proper bias, not l_addr
Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>
-rw-r--r--libdwfl/ChangeLog12
-rw-r--r--libdwfl/core-file.c7
-rw-r--r--libdwfl/libdwflP.h5
-rw-r--r--libdwfl/link_map.c12
4 files changed, 27 insertions, 9 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 67ae84ad..c0fbc831 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,15 @@
+2013-11-21 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ link_map: Use proper bias, not l_addr.
+ * core-file.c (dynamic_vaddr_get): Rename to ...
+ (__libdwfl_dynamic_vaddr_get): ... here, make it global,
+ internal_function.
+ (dwfl_core_file_report): Update name in the caller.
+ * libdwflP.h (__libdwfl_dynamic_vaddr_get): New declaration.
+ * link_map.c (report_r_debug): New variable elf_dynamic_vaddr. Call
+ __libdwfl_dynamic_vaddr_get for it. Remove L_ADDR FIXME comment.
+ Use ELF_DYNAMIC_VADDR instead of L_ADDR.
+
2013-11-19 Jan Kratochvil <jan.kratochvil@redhat.com>
Compatibility with older kernels such as RHEL-6.
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index f9120ca9..92745bd6 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -397,8 +397,9 @@ clear_r_debug_info (struct r_debug_info *r_debug_info)
}
}
-static bool
-dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
+bool
+internal_function
+__libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
{
size_t phnum;
if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
@@ -525,7 +526,7 @@ 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))
+ if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
continue;
Dwfl_Module *mod;
mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 0c862b38..b8a64d8e 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -558,6 +558,11 @@ extern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp,
bool close_on_fail, bool archive_ok)
internal_function;
+/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP. Return success.
+ *VADDRP is not modified if the function fails. */
+extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
+ internal_function;
+
/* These are working nicely for --core, but are not ready to be
exported interfaces quite yet. */
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index b094b9bc..b30f2e37 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -388,17 +388,15 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
{
Elf *elf;
Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
- if (error == DWFL_E_NOERROR)
+ GElf_Addr elf_dynamic_vaddr;
+ if (error == DWFL_E_NOERROR
+ && __libdwfl_dynamic_vaddr_get (elf, &elf_dynamic_vaddr))
{
const void *build_id_bits;
GElf_Addr build_id_elfaddr;
int build_id_len;
bool valid = true;
- /* FIXME: Bias L_ADDR should be computed from the prelink
- state in memory (when the file got loaded), not against
- the current on-disk file state as is computed below. */
-
if (__libdwfl_find_elf_build_id (NULL, elf, &build_id_bits,
&build_id_elfaddr,
&build_id_len) > 0
@@ -406,7 +404,9 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
{
if (r_debug_info_module != NULL)
r_debug_info_module->disk_file_has_build_id = true;
- GElf_Addr build_id_vaddr = build_id_elfaddr + l_addr;
+ GElf_Addr build_id_vaddr = (build_id_elfaddr
+ - elf_dynamic_vaddr + l_ld);
+
release_buffer (0);
int segndx = INTUSE(dwfl_addrsegment) (dwfl,
build_id_vaddr,