]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Add parameter add_p_vaddr to dwfl_report_elf.
authorJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 30 Apr 2013 12:27:16 +0000 (14:27 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 5 May 2013 17:08:50 +0000 (19:08 +0200)
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@redhat.com>
13 files changed:
ChangeLog
NEWS
libdw/ChangeLog
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/dwfl_report_elf.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h
libdwfl/link_map.c
libdwfl/linux-kernel-modules.c
libdwfl/offline.c
tests/ChangeLog
tests/dwfl-report-elf-align.c

index 1fdcb588e82511513328eb154569bd0209de929b..bffe62d309b12127bab0ed7f939d3d70a9610997 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * NEWS (Version 0.156): New.
+
 2013-04-26  Mark Wielaard  <mjw@redhat.com>
 
        * configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests.
diff --git a/NEWS b/NEWS
index e38e60c1c0af5f18ecac14ffc94a6c0678e909bc..a71a87c8e022d3033a8ded0dbc408bfc8677b36d 100644 (file)
--- 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.
index b4d9dc3111357cd2c24f35decfc3301c7ff63074..ef9b3acdd8379803f761a23f14ceb6e0a505c881 100644 (file)
@@ -1,3 +1,7 @@
+2013-04-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * libdw.map (ELFUTILS_0.156): New.
+
 2013-04-24  Mark Wielaard  <mjw@redhat.com>
 
        * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
index 1f71d03b50a983e5a5825f5936b6e1dfdde12617..d38a8ef6d63719e0772fbb6ab5501da9e4b83b40 100644 (file)
@@ -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;
index 42f720c955359e2bba9f544600bd0527a5fa1f36..74ede01dcff0fdbee640c339f4d76d24f2d9a850 100644 (file)
@@ -1,3 +1,19 @@
+2013-04-30  Jan Kratochvil  <jan.kratochvil@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@redhat.com>
 
        * link_map.c: #include system.h.
index d7061704cbc57f780712a251ec14df1323ccad1e..20d04da1653f57c4bd65c4ff1a7e8c162bbba47b 100644 (file)
@@ -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
index 000d582f5bb63479aec3d19882a6909f84adcf2d..2b70e2845a6071f5773387f4832bf33a4596b88e 100644 (file)
@@ -137,14 +137,21 @@ extern int dwfl_report_segment (Dwfl *dwfl, int ndx,
 extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name,
                                        Dwarf_Addr start, Dwarf_Addr end);
 
-/* Report a module with start and end addresses computed from the ELF
-   program headers in the given file, plus BASE.  For an ET_REL file,
-   does a simple absolute section layout starting at BASE.
+/* Report a module to address BASE with start and end addresses computed
+   from the ELF program headers in the given file - see the table below.
    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  BASE
+   ET_EXEC  ignored      ignored
+   ET_DYN   false        absolute address where to place the file
+           true         start address relative to ELF's phdr p_vaddr
+   ET_REL   ignored      absolute address where to place the file
+   ET_CORE  ignored      ignored
+   ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library
+   has been prelinked by tool prelink(8).  */
 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.
index 5aaa77858c2a6dbb80e3487fdae33c029dae5c9c..37a9dff4e29a27598d867954dec82b6286e076ab 100644 (file)
@@ -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.  */
index c6ec29c9c1105a0a4b58d43756fadb459b054ede..9f1b867e3aa4fd5a692032609158b1f39ed61923 100644 (file)
@@ -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)
index 9bf5f255f4c4af38b03bdc3f71f76f976939f102..dec1a5985f78a75316be133289f1adec879b083c 100644 (file)
@@ -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
index 26a6bd664dd55b1b284018c044ca1dc72f452933..28d2782e8a879a2ef6e18973738aacb3427b25e2 100644 (file)
@@ -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
index f6c004c7aa60be60fca28fef6d56f47f312e4950..4003851f58ffee75d15831e86c03d712e9f90ab2 100644 (file)
@@ -1,3 +1,7 @@
+2013-04-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       * dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
+
 2013-04-29  Mark Wielaard  <mjw@redhat.com>
 
        * test-subr.sh: Don't use pushd, just cd into test-dir.
index 0e8bfe3ee33661b57590f06f9d5f8ccffecf89b3..a4e97d3c5828db98daca0f4e44152bf983ea6c7a 100644 (file)
@@ -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);