[patch 2/2] Add add_p_vaddr to dwfl_report_elf

Jan Kratochvil jan.kratochvil at redhat.com
Tue Apr 30 12:38:39 UTC 2013


Hi,

jankratochvil/compatversion-baseaddpvaddr

patch rebase.


Jan


commit 2ecbc7f264d2956e5f93f49dba2b8aba482b989f
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Tue Apr 30 14:27:16 2013 +0200

    Add parameter add_p_vaddr to dwfl_report_elf.
    
    libdwfl/
    	* dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr.
    	Set it to true for ET_EXEC and ET_CORE.  Provide alternative
    	setup of START and BIAS if !ADD_P_VADDR.  Set END from BIAS, not BASE.
    	(dwfl_report_elf): Add parameter add_p_vaddr.  Pass it down.  Add
    	NEW_VERSION.
    	(_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with
    	COMPAT_VERSION.
    	* libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr.  Describe it.
    	* libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr.
    	* link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf.
    	* linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for
    	dwfl_report_elf.
    	* offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
    
    tests/
    	* dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
    
    Signed-off-by: Jan Kratochvil <jan.kratochvil at redhat.com>

diff --git a/ChangeLog b/ChangeLog
index 1fdcb58..bffe62d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-28  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* NEWS (Version 0.156): New.
+
 2013-04-26  Mark Wielaard  <mjw at redhat.com>
 
 	* configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests.
diff --git a/NEWS b/NEWS
index e38e60c..a71a87c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Version 0.156
+
+libdwfl: dwfl_report_elf has new parameter add_p_vaddr.
+
 Version 0.155
 
 libelf: elf*_xlatetomd now works for cross-endian ELF note data.
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index b4d9dc3..ef9b3ac 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-28  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* libdw.map (ELFUTILS_0.156): New.
+
 2013-04-24  Mark Wielaard  <mjw at redhat.com>
 
 	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 1f71d03..d38a8ef 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -254,3 +254,9 @@ ELFUTILS_0.149 {
 
     dwfl_dwarf_line;
 } ELFUTILS_0.148;
+
+ELFUTILS_0.156 {
+  global:
+    # Replaced ELFUTILS_0.122 version, which has a wrapper without add_p_vaddr.
+    dwfl_report_elf;
+} ELFUTILS_0.149;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 42f720c..74ede01 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,19 @@
+2013-04-30  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr.
+	Set it to true for ET_EXEC and ET_CORE.  Provide alternative
+	setup of START and BIAS if !ADD_P_VADDR.  Set END from BIAS, not BASE.
+	(dwfl_report_elf): Add parameter add_p_vaddr.  Pass it down.  Add
+	NEW_VERSION.
+	(_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with
+	COMPAT_VERSION.
+	* libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr.  Describe it.
+	* libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr.
+	* link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf.
+	* linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for
+	dwfl_report_elf.
+	* offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
+
 2013-04-27  Mark Wielaard  <mjw at redhat.com>
 
 	* link_map.c: #include system.h.
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index d706170..20d04da 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -41,7 +41,8 @@
 Dwfl_Module *
 internal_function
 __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
-		      int fd, Elf *elf, GElf_Addr base, bool sanity)
+		      int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr,
+		      bool sanity)
 {
   GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
   if (ehdr == NULL)
@@ -166,6 +167,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
     case ET_CORE:
       /* An assigned base address is meaningless for these.  */
       base = 0;
+      add_p_vaddr = true;
 
     case ET_DYN:
     default:;
@@ -181,11 +183,19 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
 	    {
 	      vaddr = ph->p_vaddr & -ph->p_align;
 	      address_sync = ph->p_vaddr + ph->p_memsz;
-	      start = base + vaddr;
 	      break;
 	    }
 	}
-      bias = base;
+      if (add_p_vaddr)
+	{
+	  start = base + vaddr;
+	  bias = base;
+	}
+      else
+	{
+	  start = base;
+	  bias = base - vaddr;
+	}
 
       for (size_t i = phnum; i-- > 0;)
 	{
@@ -195,7 +205,7 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
 	  if (ph->p_type == PT_LOAD
 	      && ph->p_vaddr + ph->p_memsz > 0)
 	    {
-	      end = base + (ph->p_vaddr + ph->p_memsz);
+	      end = bias + (ph->p_vaddr + ph->p_memsz);
 	      break;
 	    }
 	}
@@ -246,8 +256,8 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
 }
 
 Dwfl_Module *
-dwfl_report_elf (Dwfl *dwfl, const char *name,
-		 const char *file_name, int fd, GElf_Addr base)
+dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
+		 GElf_Addr base, bool add_p_vaddr)
 {
   bool closefd = false;
   if (fd < 0)
@@ -270,7 +280,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name,
     }
 
   Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name,
-					   fd, elf, base, true);
+					   fd, elf, base, add_p_vaddr, true);
   if (mod == NULL)
     {
       elf_end (elf);
@@ -281,3 +291,20 @@ dwfl_report_elf (Dwfl *dwfl, const char *name,
   return mod;
 }
 INTDEF (dwfl_report_elf)
+NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
+
+#ifdef SHARED
+Dwfl_Module *
+  _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
+					       const char *file_name, int fd,
+					       GElf_Addr base);
+COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr)
+
+Dwfl_Module *
+_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
+					     const char *file_name, int fd,
+					     GElf_Addr base)
+{
+  return dwfl_report_elf (dwfl, name, file_name, fd, base, true);
+}
+#endif
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index 000d582..572520d 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -141,10 +141,14 @@ extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name,
    program headers in the given file, plus BASE.  For an ET_REL file,
    does a simple absolute section layout starting at BASE.
    FD may be -1 to open FILE_NAME.  On success, FD is consumed by the
-   library, and the `find_elf' callback will not be used for this module.  */
+   library, and the `find_elf' callback will not be used for this module.
+   ADD_P_VADDR has meaning only for ET_DYN files.  With ADD_P_VADDR true BASE
+   then specifies in-memory address with subtracted on-disk file prelinked base
+   address (such as the GNU C library l_addr field).  With ADD_P_VADDR false
+   BASE is in-memory absolute address start for any relocatable ELF type.  */
 extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name,
 				     const char *file_name, int fd,
-				     GElf_Addr base);
+				     GElf_Addr base, bool add_p_vaddr);
 
 /* Similar, but report the module for offline use.  All ET_EXEC files
    being reported must be reported before any relocatable objects.
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 5aaa778..37a9dff 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -382,7 +382,8 @@ extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden;
    Consumes ELF on success, not on failure.  */
 extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name,
 					  const char *file_name, int fd,
-					  Elf *elf, GElf_Addr base, bool sanity)
+					  Elf *elf, GElf_Addr base,
+					  bool add_p_vaddr, bool sanity)
   internal_function;
 
 /* Meat of dwfl_report_offline.  */
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index c6ec29c..9f1b867 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -384,7 +384,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
 
 	  // XXX hook for sysroot
 	  mod = INTUSE(dwfl_report_elf) (dwfl, basename (name),
-					 name, -1, l_addr);
+					 name, -1, l_addr, true);
 	}
 
       if (mod != NULL)
diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 9bf5f25..dec1a59 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -217,7 +217,7 @@ report_kernel (Dwfl *dwfl, const char **release,
       if (report)
 	{
 	  Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME,
-						      fname, fd, 0);
+						      fname, fd, 0, false);
 	  if (mod == NULL)
 	    result = -1;
 	  else
diff --git a/libdwfl/offline.c b/libdwfl/offline.c
index 26a6bd6..28d2782 100644
--- a/libdwfl/offline.c
+++ b/libdwfl/offline.c
@@ -127,7 +127,8 @@ process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
 	     Elf *elf)
 {
   Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf,
-					   dwfl->offline_next_address, false);
+					   dwfl->offline_next_address, true,
+					   false);
   if (mod != NULL)
     {
       /* If this is an ET_EXEC file with fixed addresses, the address range
diff --git a/tests/ChangeLog b/tests/ChangeLog
index f6c004c..4003851 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-30  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
+
 2013-04-29  Mark Wielaard  <mjw at redhat.com>
 
 	* test-subr.sh: Don't use pushd, just cd into test-dir.
diff --git a/tests/dwfl-report-elf-align.c b/tests/dwfl-report-elf-align.c
index 0e8bfe3..a4e97d3 100644
--- a/tests/dwfl-report-elf-align.c
+++ b/tests/dwfl-report-elf-align.c
@@ -53,7 +53,7 @@ main (int argc, char **argv)
   uintptr_t base = strtoull (argv[2], &endptr, 0);
   assert (endptr && !*endptr);
 
-  Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base);
+  Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base, false);
   assert (mod != NULL);
 
   uintptr_t funcaddr = strtoull (argv[3], &endptr, 0);


More information about the elfutils-devel mailing list