This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] link_map: Use proper bias, not l_addr


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/003489.html
	Message-ID: <20131120193234.GA15057@host2.jankratochvil.net>

it reduces the number of verifications from 4 (as listed in the mail above)
just to:
+0xf7603000+0x1b0000 0b9bf374699e141e5dfc14757ff42b8c2373b4de(a)0xf7603184 - - libc.so.6
-0xf75f3fe0+0x1bea7c 50ed3f33e3761eefeeceb120121643f843260b27(a)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@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@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@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,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]