Hi Mark,
jankratochvil/rdebugbias
this patch does not change anything visible, just for:
[patch] Verify file vs. core build-id, when both available
https://lists.fedorahosted.org/pipermail/elfutils-devel/2013-November/003...
Message-ID: <20131120193234.GA15057(a)host2.jankratochvil.net>
it reduces the number of verifications from 4 (as listed in the mail above)
just to:
+0xf7603000+0x1b0000 0b9bf374699e141e5dfc14757ff42b8c2373b4de@0xf7603184 - - libc.so.6
-0xf75f3fe0+0x1bea7c 50ed3f33e3761eefeeceb120121643f843260b27@0xf75f4164 /lib/libc.so.6 -
libc.so.6
as the other files will create then real memory location which is read,
compared and found as non-matching already when reading link_map.
Maybe it fixes some more cases, not sure. But it is apparently more correct
than it was before. I did not realize first the real fix is pretty easy,
moreover when dynamic_vaddr_get() is available now.
All the test results are sure very dependent on host files version and also
their prelink status.
Thanks,
Jan
commit aac99be184dc2788c678e2e2063b13fa94b497d4
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Wed Nov 20 20:33:20 2013 +0100
link_map: Use proper bias, not l_addr
libdwfl/
2013-11-20 Jan Kratochvil <jan.kratochvil(a)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.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index f9120ca..92745bd 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 0c862b3..b8a64d8 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 b094b9b..b30f2e3 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,