]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Add dwfl_module_addrsym_elf and dwfl_module_getsym_elf.
authorMark Wielaard <mjw@redhat.com>
Wed, 27 Nov 2013 15:45:44 +0000 (16:45 +0100)
committerMark Wielaard <mjw@redhat.com>
Wed, 27 Nov 2013 15:45:44 +0000 (16:45 +0100)
Introduce two new functions that also return the elf associated with a
symbol to make symbol section indexing work for non-special sections.
Simplify code by removing dwfl_file where appropriate and just track Elf
directly. Document limitations of shndx with existing dwfl_module_addrsym
and dwfl_module_getsym. Extend dwflsyms testcase to check some more symbol
and section (index) properties.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
12 files changed:
libdw/ChangeLog
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/dwfl_module_addrsym.c
libdwfl/dwfl_module_getsym.c
libdwfl/dwfl_module_info.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h
libdwfl/relocate.c
tests/ChangeLog
tests/dwflsyms.c
tests/run-dwflsyms.sh

index 33885ac3f844b2f8d125d1d6487747ebc1eb4902..91e10833543a8163d801842464b98f8f30b5a246 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-27  Mark Wielaard  <mjw@redhat.com>
+
+       * libdw.map (ELFUTILS_0.158): Add dwfl_module_addrsym_elf and
+       dwfl_module_getsym_elf.
+
 2013-11-26  Mark Wielaard  <mjw@redhat.com>
 
        * libdw.map (ELFUTILS_0.156): Move dwfl_attach_state, dwfl_pid,
index 060c3df87eba117bc043c4f78a8f6cbf897b6b16..0438e24c82234713631e9a8ab74596c444c3eba4 100644 (file)
@@ -283,4 +283,7 @@ ELFUTILS_0.158 {
     dwfl_getthreads;
     dwfl_thread_getframes;
     dwfl_frame_pc;
+
+    dwfl_module_addrsym_elf;
+    dwfl_module_getsym_elf;
 } ELFUTILS_0.157;
index deb501407488502cdcb3c4145146bfaca6078138..9937bbbb8bb7908483e800dffeaaa6ddb8895c13 100644 (file)
@@ -1,3 +1,25 @@
+2013-11-27  Mark Wielaard  <mjw@redhat.com>
+
+       * dwfl_module_addrsym.c (dwfl_module_addrsym): Rename to and call...
+       (dwfl_module_addrsym_elf): this. Add elfp and biasp arguments,
+       keep track of symelf, addr_symelf, closest_elf and sizeless_elf
+       instead of tracking dwfl_files.
+       * dwfl_module_getsym.c (__libdwfl_module_getsym): Renamed to...
+       (dwfl_module_getsym_elf): ...this. Remove dwfl_file argument, add
+       new elfp and biasp arguments. Track elf instead of file.
+       (dwfl_module_getsym): Call dwfl_module_getsym_elf.
+       dwfl_module_info.c (dwfl_module_info): Pass elf to
+       dwfl_adjusted_st_value.
+       * libdwfl.h (dwfl_module_getsym): Document limitations of shndx.
+       (dwfl_module_getsym_elf): New function declaration.
+       (dwfl_module_addrsym_elf): Likewise.
+       * libdwflP.h (dwfl_module_addrsym_elf): INTDECL.
+       (dwfl_module_getsym_elf): Likewise.
+       (dwfl_adjusted_st_value): Take and check elf not dwfl_file.
+       (dwfl_deadjust_st_value): Likewise.
+       (__libdwfl_module_getsym): Removed.
+       * relocate.c (resolve_symbol): Pass elf to dwfl_adjusted_st_value.
+
 2013-11-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Fix non-build-id core files on build-id system.
index d9eb0a27405d8a4b8f58cca95ab9cf2736726366..320d41f185c59ed8a8df846b4df2fc16d470eab2 100644 (file)
@@ -32,8 +32,9 @@
    Never returns symbols at addresses above ADDR.  */
 
 const char *
-dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
-                    GElf_Sym *closest_sym, GElf_Word *shndxp)
+dwfl_module_addrsym_elf (Dwfl_Module *mod, GElf_Addr addr,
+                        GElf_Sym *closest_sym, GElf_Word *shndxp,
+                        Elf **elfp, Dwarf_Addr *biasp)
 {
   int syments = INTUSE(dwfl_module_getsymtab) (mod);
   if (syments < 0)
@@ -41,22 +42,21 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
 
   /* Return true iff we consider ADDR to lie in the same section as SYM.  */
   GElf_Word addr_shndx = SHN_UNDEF;
-  struct dwfl_file *addr_symfile = NULL;
-  inline bool same_section (const GElf_Sym *sym, struct dwfl_file *symfile,
-                           GElf_Word shndx)
+  Elf *addr_symelf = NULL;
+  inline bool same_section (const GElf_Sym *sym, Elf *symelf, GElf_Word shndx)
     {
       /* For absolute symbols and the like, only match exactly.  */
       if (shndx >= SHN_LORESERVE)
        return sym->st_value == addr;
 
       /* Figure out what section ADDR lies in.  */
-      if (addr_shndx == SHN_UNDEF || addr_symfile != symfile)
+      if (addr_shndx == SHN_UNDEF || addr_symelf != symelf)
        {
-         GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, symfile, addr);
+         GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, symelf, addr);
          Elf_Scn *scn = NULL;
          addr_shndx = SHN_ABS;
-         addr_symfile = symfile;
-         while ((scn = elf_nextscn (symfile->elf, scn)) != NULL)
+         addr_symelf = symelf;
+         while ((scn = elf_nextscn (symelf, scn)) != NULL)
            {
              GElf_Shdr shdr_mem;
              GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
@@ -70,18 +70,20 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
            }
        }
 
-      return shndx == addr_shndx && addr_symfile == symfile;
+      return shndx == addr_shndx && addr_symelf == symelf;
     }
 
   /* Keep track of the closest symbol we have seen so far.
      Here we store only symbols with nonzero st_size.  */
   const char *closest_name = NULL;
   GElf_Word closest_shndx = SHN_UNDEF;
+  Elf *closest_elf = NULL;
 
   /* Keep track of an eligible symbol with st_size == 0 as a fallback.  */
   const char *sizeless_name = NULL;
   GElf_Sym sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF };
   GElf_Word sizeless_shndx = SHN_UNDEF;
+  Elf *sizeless_elf = NULL;
 
   /* Keep track of the lowest address a relevant sizeless symbol could have.  */
   GElf_Addr min_label = 0;
@@ -93,9 +95,10 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
        {
          GElf_Sym sym;
          GElf_Word shndx;
-         struct dwfl_file *file;
-         const char *name = __libdwfl_module_getsym (mod, i, &sym, &shndx,
-                                                     &file);
+         Elf *elf;
+         const char *name = INTUSE(dwfl_module_getsym_elf) (mod, i, &sym,
+                                                            &shndx, &elf,
+                                                            NULL);
          if (name != NULL && name[0] != '\0'
              && sym.st_shndx != SHN_UNDEF
              && sym.st_value <= addr
@@ -136,11 +139,12 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
                        {
                          *closest_sym = sym;
                          closest_shndx = shndx;
+                         closest_elf = elf;
                          closest_name = name;
                        }
                      else if (closest_name == NULL
                               && sym.st_value >= min_label
-                              && same_section (&sym, file, shndx))
+                              && same_section (&sym, elf, shndx))
                        {
                          /* Handwritten assembly symbols sometimes have no
                             st_size.  If no symbol with proper size includes
@@ -148,6 +152,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
                             the same section as ADDR.  */
                          sizeless_sym = sym;
                          sizeless_shndx = shndx;
+                         sizeless_elf = elf;
                          sizeless_name = name;
                        }
                    }
@@ -166,6 +171,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
                    {
                      *closest_sym = sym;
                      closest_shndx = shndx;
+                     closest_elf = elf;
                      closest_name = name;
                    }
                }
@@ -200,11 +206,26 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
     {
       *closest_sym = sizeless_sym;
       closest_shndx = sizeless_shndx;
+      closest_elf = sizeless_elf;
       closest_name = sizeless_name;
     }
 
   if (shndxp != NULL)
     *shndxp = closest_shndx;
+  if (elfp != NULL)
+    *elfp = closest_elf;
+  if (biasp != NULL)
+    *biasp = dwfl_adjusted_st_value (mod, closest_elf, 0);
   return closest_name;
 }
+INTDEF (dwfl_module_addrsym_elf)
+
+
+const char *
+dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
+                    GElf_Sym *closest_sym, GElf_Word *shndxp)
+{
+  return INTUSE(dwfl_module_addrsym_elf) (mod, addr, closest_sym, shndxp,
+                                         NULL, NULL);
+}
 INTDEF (dwfl_module_addrsym)
index 0f5dd37db1085b9d186624960ea9f5c668308a80..319f97586c7e4c154e2ad78aabbfa3af879c95d6 100644 (file)
 #include "libdwflP.h"
 
 const char *
-internal_function
-__libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
-                        GElf_Sym *sym, GElf_Word *shndxp,
-                        struct dwfl_file **filep)
+dwfl_module_getsym_elf (Dwfl_Module *mod, int ndx,
+                       GElf_Sym *sym, GElf_Word *shndxp,
+                       Elf **elfp, Dwarf_Addr *biasp)
 {
   if (unlikely (mod == NULL))
     return NULL;
@@ -51,7 +50,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
   GElf_Word shndx;
   int tndx = ndx;
   int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
-  struct dwfl_file *file;
+  Elf *elf;
   Elf_Data *symdata;
   Elf_Data *symxndxdata;
   Elf_Data *symstrdata;
@@ -60,7 +59,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
     {
       /* main symbol table (locals).  */
       tndx = ndx;
-      file = mod->symfile;
+      elf = mod->symfile->elf;
       symdata = mod->symdata;
       symxndxdata = mod->symxndxdata;
       symstrdata = mod->symstrdata;
@@ -69,7 +68,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
     {
       /* aux symbol table (locals).  */
       tndx = ndx - mod->first_global + skip_aux_zero;
-      file = &mod->aux_sym;
+      elf = mod->aux_sym.elf;
       symdata = mod->aux_symdata;
       symxndxdata = mod->aux_symxndxdata;
       symstrdata = mod->aux_symstrdata;
@@ -78,7 +77,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
     {
       /* main symbol table (globals).  */
       tndx = ndx - mod->aux_first_global + skip_aux_zero;
-      file = mod->symfile;
+      elf = mod->symfile->elf;
       symdata = mod->symdata;
       symxndxdata = mod->symxndxdata;
       symstrdata = mod->symstrdata;
@@ -87,7 +86,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
     {
       /* aux symbol table (globals).  */
       tndx = ndx - mod->syments + skip_aux_zero;
-      file = &mod->aux_sym;
+      elf = mod->aux_sym.elf;
       symdata = mod->aux_symdata;
       symxndxdata = mod->aux_symxndxdata;
       symstrdata = mod->aux_symstrdata;
@@ -110,8 +109,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
          || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF)))
     {
       GElf_Shdr shdr_mem;
-      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (file->elf, shndx),
-                                     &shdr_mem);
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, shndx), &shdr_mem);
       alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC);
     }
 
@@ -132,7 +130,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
          /* In an ET_REL file, the symbol table values are relative
             to the section, not to the module's load base.  */
          size_t symshstrndx = SHN_UNDEF;
-         Dwfl_Error result = __libdwfl_relocate_value (mod, file->elf,
+         Dwfl_Error result = __libdwfl_relocate_value (mod, elf,
                                                        &symshstrndx,
                                                        shndx, &sym->st_value);
          if (unlikely (result != DWFL_E_NOERROR))
@@ -143,7 +141,7 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
        }
       else if (alloc)
        /* Apply the bias to the symbol value.  */
-       sym->st_value = dwfl_adjusted_st_value (mod, file, sym->st_value);
+       sym->st_value = dwfl_adjusted_st_value (mod, elf, sym->st_value);
       break;
     }
 
@@ -152,15 +150,18 @@ __libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
       __libdwfl_seterrno (DWFL_E_BADSTROFF);
       return NULL;
     }
-  if (filep)
-    *filep = file;
+  if (elfp)
+    *elfp = elf;
+  if (biasp)
+    *biasp = dwfl_adjusted_st_value (mod, elf, 0);
   return (const char *) symstrdata->d_buf + sym->st_name;
 }
+INTDEF (dwfl_module_getsym_elf)
 
 const char *
 dwfl_module_getsym (Dwfl_Module *mod, int ndx,
                    GElf_Sym *sym, GElf_Word *shndxp)
 {
-  return __libdwfl_module_getsym (mod, ndx, sym, shndxp, NULL);
+  return dwfl_module_getsym_elf (mod, ndx, sym, shndxp, NULL, NULL);
 }
 INTDEF (dwfl_module_getsym)
index fdb4202af8f5777ae414370ebb91578e0b447fd1..df16be4193ed5d83e11e88a95f7655b923ee5c83 100644 (file)
@@ -49,7 +49,7 @@ dwfl_module_info (Dwfl_Module *mod, void ***userdata,
               : dwfl_adjusted_dwarf_addr (mod, 0));
   if (symbias)
     *symbias = (mod->symfile == NULL ? (Dwarf_Addr) -1
-               : dwfl_adjusted_st_value (mod, mod->symfile, 0));
+               : dwfl_adjusted_st_value (mod, mod->symfile->elf, 0));
 
   if (mainfile)
     *mainfile = mod->main.name;
index c1a0fb996914d7df399296766b92c857c9d70654..3d5bede6a23530c7509d7944863ada99f8a486b0 100644 (file)
@@ -436,11 +436,24 @@ extern int dwfl_module_getsymtab (Dwfl_Module *mod);
    an absolute value based on the module's location, when the symbol is in
    an SHF_ALLOC section.  If SHNDXP is non-null, it's set with the section
    index (whether from st_shndx or extended index table); in case of a
-   symbol in a non-allocated section, *SHNDXP is instead set to -1.  */
+   symbol in a non-allocated section, *SHNDXP is instead set to -1.
+   Note that since symbols can come from either the main, debug or auxiliary
+   ELF symbol file (either dynsym or symtab) the section index can only
+   be reliably used to compare against special section constants like
+   SHN_UNDEF or SHN_ABS.  */
 extern const char *dwfl_module_getsym (Dwfl_Module *mod, int ndx,
                                       GElf_Sym *sym, GElf_Word *shndxp)
   __nonnull_attribute__ (3);
 
+/* Same as dwfl_module_getsym but also returns the ELF file, if not NULL,
+   that the symbol came from so the section index can be reliably used.
+   Fills in *BIAS, if not NULL, with the difference between addresses
+   within the loaded module and those in symbol tables of the ELF file. */
+extern const char *dwfl_module_getsym_elf (Dwfl_Module *mod, int ndx,
+                                          GElf_Sym *sym, GElf_Word *shndxp,
+                                          Elf **elfp, Dwarf_Addr *bias)
+  __nonnull_attribute__ (3);
+
 /* Find the symbol that ADDRESS lies inside, and return its name.  */
 extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address);
 
@@ -450,6 +463,16 @@ extern const char *dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr address,
                                        GElf_Sym *sym, GElf_Word *shndxp)
   __nonnull_attribute__ (3);
 
+/* Same as dwfl_module_addrsym but also returns the ELF file, if not NULL,
+   that the symbol came from so the section index can be reliably used.
+   Fills in *BIAS, if not NULL, with the difference between addresses
+   within the loaded module and those in symbol tables of the ELF file. */
+extern const char *dwfl_module_addrsym_elf (Dwfl_Module *mod,
+                                           GElf_Addr address, GElf_Sym *sym,
+                                           GElf_Word *shndxp, Elf **elfp,
+                                           Dwarf_Addr *bias)
+  __nonnull_attribute__ (3);
+
 /* Find the ELF section that *ADDRESS lies inside and return it.
    On success, adjusts *ADDRESS to be relative to the section,
    and sets *BIAS to the difference between addresses used in
index b8a64d8e8d01f8335c4a07ce9c7ce262180bc1e2..b73f7b1dd840d3624d249f078c968223caa0062b 100644 (file)
@@ -359,23 +359,21 @@ dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
 }
 
 static inline GElf_Addr
-dwfl_adjusted_st_value (Dwfl_Module *mod, struct dwfl_file *symfile,
-                       GElf_Addr addr)
+dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
 {
-  if (symfile == &mod->main)
+  if (symelf == mod->main.elf)
     return dwfl_adjusted_address (mod, addr);
-  if (symfile == &mod->debug)
+  if (symelf == mod->debug.elf)
     return dwfl_adjusted_dwarf_addr (mod, addr);
   return dwfl_adjusted_aux_sym_addr (mod, addr);
 }
 
 static inline GElf_Addr
-dwfl_deadjust_st_value (Dwfl_Module *mod, struct dwfl_file *symfile,
-                       GElf_Addr addr)
+dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
 {
-  if (symfile == &mod->main)
+  if (symelf == mod->main.elf)
     return dwfl_deadjust_address (mod, addr);
-  if (symfile == &mod->debug)
+  if (symelf == mod->debug.elf)
     return dwfl_deadjust_dwarf_addr (mod, addr);
   return dwfl_deadjust_aux_sym_addr (mod, addr);
 }
@@ -421,14 +419,6 @@ extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf,
                                            GElf_Addr *value)
      internal_function;
 
-/* See dwfl_module_getsym.  *FILEP will be set to the file of *SYM.
-   FILEP can be NULL.  */
-extern const char *__libdwfl_module_getsym (Dwfl_Module *mod, int ndx,
-                                           GElf_Sym *sym, GElf_Word *shndxp,
-                                           struct dwfl_file **filep)
-     internal_function;
-
-
 /* Ensure that MOD->ebl is set up.  */
 extern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function;
 
@@ -648,10 +638,12 @@ INTDECL (dwfl_getmodules)
 INTDECL (dwfl_module_addrdie)
 INTDECL (dwfl_module_address_section)
 INTDECL (dwfl_module_addrsym)
+INTDECL (dwfl_module_addrsym_elf)
 INTDECL (dwfl_module_build_id)
 INTDECL (dwfl_module_getdwarf)
 INTDECL (dwfl_module_getelf)
 INTDECL (dwfl_module_getsym)
+INTDECL (dwfl_module_getsym_elf)
 INTDECL (dwfl_module_getsymtab)
 INTDECL (dwfl_module_getsrc)
 INTDECL (dwfl_module_report_build_id)
index bd51ad6d5706fa423c3e9c92516369d9b71b1635..f8a5fcfa6a901524da7ae0a7f1ea55801f0a4dfb 100644 (file)
@@ -252,7 +252,7 @@ resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab,
 
                if (m->e_type != ET_REL)
                  {
-                   sym->st_value = dwfl_adjusted_st_value (m, m->symfile,
+                   sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf,
                                                            sym->st_value);
                    return DWFL_E_NOERROR;
                  }
index 8a6c4d22bd95ce98a298b67a7ebc015014760b18..6c0ec364ecb2d5d733fd2b2414f25e8213657d1c 100644 (file)
@@ -1,3 +1,13 @@
+2013-11-27  Mark Wielaard  <mjw@redhat.com>
+
+       * dwflsyms.c (gelf_bind_order): New function.
+       (elf_section_name): Likewise.
+       (addr_in_section): Likewise.
+       (list_syms): Use dwfl_module_getsym_elf and dwfl_module_addrsym_elf.
+       Refine assert using gelf_bind_order. Print elf_section_name. Check
+       bias with addr_in_section.
+       * run-dwflsyms.sh: Add section names to expected output.
+
 2013-11-26  Mark Wielaard  <mjw@redhat.com>
 
        * Makefile.am (EXTRA_DIST): Add run-funcretval.sh.
index 55f2653c6967ab767be7807e4b6f4c34365b8ae2..10c01f1f02a5228610c4bdf002f1707726db5f80 100644 (file)
@@ -68,6 +68,42 @@ gelf_bind (GElf_Sym *sym)
     }
 }
 
+static int
+gelf_bind_order (GElf_Sym *sym)
+{
+  switch (GELF_ST_BIND (sym->st_info))
+    {
+    case STB_LOCAL:
+      return 1;
+    case STB_WEAK:
+      return 2;
+    case STB_GLOBAL:
+      return 3;
+    default:
+      return 0;
+    }
+}
+
+static const char *
+elf_section_name (Elf *elf, GElf_Word shndx)
+{
+  GElf_Ehdr ehdr;
+  GElf_Shdr shdr;
+  Elf_Scn *scn = elf_getscn (elf, shndx);
+  gelf_getshdr (scn, &shdr);
+  gelf_getehdr (elf, &ehdr);
+  return elf_strptr (elf, ehdr.e_shstrndx, shdr.sh_name);
+}
+
+bool
+addr_in_section (Elf *elf, GElf_Word shndx, GElf_Addr addr)
+{
+  GElf_Shdr shdr;
+  Elf_Scn *scn = elf_getscn (elf, shndx);
+  gelf_getshdr (scn, &shdr);
+  return addr >= shdr.sh_addr && addr < shdr.sh_addr + shdr.sh_size;
+}
+
 static int
 list_syms (struct Dwfl_Module *mod,
           void **user __attribute__ ((unused)),
@@ -82,7 +118,10 @@ list_syms (struct Dwfl_Module *mod,
     {
       GElf_Sym sym;
       GElf_Word shndxp;
-      const char *name = dwfl_module_getsym (mod, ndx, &sym, &shndxp);
+      Elf *elf;
+      Dwarf_Addr bias;
+      const char *name = dwfl_module_getsym_elf (mod, ndx, &sym, &shndxp,
+                                                &elf, &bias);
       printf("%4d: %s\t%s\t%s (%" PRIu64 ") %#" PRIx64,
             ndx, gelf_type (&sym), gelf_bind (&sym), name,
             sym.st_size, sym.st_value);
@@ -92,15 +131,34 @@ list_syms (struct Dwfl_Module *mod,
         dwfl_module_getsym ().  */
       if (GELF_ST_TYPE (sym.st_info) == STT_FUNC && shndxp != SHN_UNDEF)
        {
+         /* Make sure the adjusted value really falls in the elf section. */
+          assert (addr_in_section (elf, shndxp, sym.st_value - bias));
+
          GElf_Addr addr = sym.st_value;
          GElf_Sym asym;
          GElf_Word ashndxp;
-         const char *aname = dwfl_module_addrsym (mod, addr, &asym, &ashndxp);
-         assert (strcmp (name, aname) == 0);
+         Elf *aelf;
+         Dwarf_Addr abias;
+         const char *aname = dwfl_module_addrsym_elf (mod, addr, &asym,
+                                                      &ashndxp, &aelf, &abias);
+
+         /* Make sure the adjusted value really falls in the elf section. */
+          assert (addr_in_section (aelf, ashndxp, asym.st_value - abias));
+
+         /* Either they are the same symbol (name), the binding of
+            asym is "stronger" (or equal) to sym or asym is more specific
+            (has a lower address) than sym.  */
+         assert ((strcmp (name, aname) == 0
+                  || gelf_bind_order (&asym) >= gelf_bind_order (&sym))
+                 && asym.st_value <= sym.st_value);
 
          int res = dwfl_module_relocate_address (mod, &addr);
          assert (res != -1);
-         printf(", rel: %#" PRIx64 "", addr);
+         if (shndxp < SHN_LORESERVE)
+           printf(", rel: %#" PRIx64 " (%s)", addr,
+                  elf_section_name (elf, shndxp));
+         else
+           printf(", rel: %#" PRIx64 "", addr);
        }
       printf ("\n");
     }
index 2adec5a3536debc020ff06b2f9cd72d2d3cbda44..3cd7bf3687a5d5d23b5b6a0753a59895ab51a06e 100755 (executable)
@@ -72,17 +72,17 @@ cat > testfile.symtab.in <<\EOF
   32: SECTION  LOCAL    (0) 0
   33: FILE     LOCAL   crtstuff.c (0) 0
   34: OBJECT   LOCAL   __JCR_LIST__ (0) 0x200de0
-  35: FUNC     LOCAL   deregister_tm_clones (0) 0x710, rel: 0x710
-  36: FUNC     LOCAL   register_tm_clones (0) 0x740, rel: 0x740
-  37: FUNC     LOCAL   __do_global_dtors_aux (0) 0x780, rel: 0x780
+  35: FUNC     LOCAL   deregister_tm_clones (0) 0x710, rel: 0x710 (.text)
+  36: FUNC     LOCAL   register_tm_clones (0) 0x740, rel: 0x740 (.text)
+  37: FUNC     LOCAL   __do_global_dtors_aux (0) 0x780, rel: 0x780 (.text)
   38: OBJECT   LOCAL   completed.6137 (1) 0x20103c
   39: OBJECT   LOCAL   __do_global_dtors_aux_fini_array_entry (0) 0x200dd8
-  40: FUNC     LOCAL   frame_dummy (0) 0x7c0, rel: 0x7c0
+  40: FUNC     LOCAL   frame_dummy (0) 0x7c0, rel: 0x7c0 (.text)
   41: OBJECT   LOCAL   __frame_dummy_init_array_entry (0) 0x200dd0
   42: FILE     LOCAL   foo.c (0) 0
   43: FILE     LOCAL   bar.c (0) 0
   44: OBJECT   LOCAL   b1 (4) 0x201034
-  45: FUNC     LOCAL   foo (20) 0x814, rel: 0x814
+  45: FUNC     LOCAL   foo (20) 0x814, rel: 0x814 (.text)
   46: FILE     LOCAL   crtstuff.c (0) 0
   47: OBJECT   LOCAL   __FRAME_END__ (0) 0xa58
   48: OBJECT   LOCAL   __JCR_END__ (0) 0x200de0
@@ -91,28 +91,28 @@ cat > testfile.symtab.in <<\EOF
   51: OBJECT   LOCAL   _DYNAMIC (0) 0x200df0
   52: NOTYPE   LOCAL   __init_array_start (0) 0x200dd0
   53: OBJECT   LOCAL   _GLOBAL_OFFSET_TABLE_ (0) 0x201000
-  54: FUNC     GLOBAL  __libc_csu_fini (2) 0x8f0, rel: 0x8f0
+  54: FUNC     GLOBAL  __libc_csu_fini (2) 0x8f0, rel: 0x8f0 (.text)
   55: NOTYPE   WEAK    _ITM_deregisterTMCloneTable (0) 0
   56: NOTYPE   WEAK    data_start (0) 0x201030
   57: NOTYPE   GLOBAL  _edata (0) 0x20103c
-  58: FUNC     GLOBAL  bar (44) 0x828, rel: 0x828
-  59: FUNC     GLOBAL  _fini (0) 0x8f4, rel: 0x8f4
+  58: FUNC     GLOBAL  bar (44) 0x828, rel: 0x828 (.text)
+  59: FUNC     GLOBAL  _fini (0) 0x8f4, rel: 0x8f4 (.fini)
   60: FUNC     GLOBAL  __libc_start_main@@GLIBC_2.2.5 (0) 0
   61: NOTYPE   GLOBAL  __data_start (0) 0x201030
   62: NOTYPE   WEAK    __gmon_start__ (0) 0
   63: OBJECT   GLOBAL  __dso_handle (0) 0x200de8
   64: OBJECT   GLOBAL  _IO_stdin_used (4) 0x900
   65: OBJECT   GLOBAL  b2 (4) 0x201038
-  66: FUNC     GLOBAL  __libc_csu_init (137) 0x860, rel: 0x860
+  66: FUNC     GLOBAL  __libc_csu_init (137) 0x860, rel: 0x860 (.text)
   67: NOTYPE   GLOBAL  _end (0) 0x201040
-  68: FUNC     GLOBAL  _start (0) 0x6e0, rel: 0x6e0
+  68: FUNC     GLOBAL  _start (0) 0x6e0, rel: 0x6e0 (.text)
   69: NOTYPE   GLOBAL  __bss_start (0) 0x20103c
-  70: FUNC     GLOBAL  main (35) 0x7f0, rel: 0x7f0
+  70: FUNC     GLOBAL  main (35) 0x7f0, rel: 0x7f0 (.text)
   71: NOTYPE   WEAK    _Jv_RegisterClasses (0) 0
   72: OBJECT   GLOBAL  __TMC_END__ (0) 0x201040
   73: NOTYPE   WEAK    _ITM_registerTMCloneTable (0) 0
   74: FUNC     WEAK    __cxa_finalize@@GLIBC_2.2.5 (0) 0
-  75: FUNC     GLOBAL  _init (0) 0x680, rel: 0x680
+  75: FUNC     GLOBAL  _init (0) 0x680, rel: 0x680 (.init)
 EOF
 
 cat > testfile.symtab_pl.in <<\EOF
@@ -151,17 +151,17 @@ cat > testfile.symtab_pl.in <<\EOF
   32: SECTION  LOCAL    (0) 0
   33: FILE     LOCAL   crtstuff.c (0) 0
   34: OBJECT   LOCAL   __JCR_LIST__ (0) 0x3000200de0
-  35: FUNC     LOCAL   deregister_tm_clones (0) 0x3000000710, rel: 0x710
-  36: FUNC     LOCAL   register_tm_clones (0) 0x3000000740, rel: 0x740
-  37: FUNC     LOCAL   __do_global_dtors_aux (0) 0x3000000780, rel: 0x780
+  35: FUNC     LOCAL   deregister_tm_clones (0) 0x3000000710, rel: 0x710 (.text)
+  36: FUNC     LOCAL   register_tm_clones (0) 0x3000000740, rel: 0x740 (.text)
+  37: FUNC     LOCAL   __do_global_dtors_aux (0) 0x3000000780, rel: 0x780 (.text)
   38: OBJECT   LOCAL   completed.6137 (1) 0x300020103c
   39: OBJECT   LOCAL   __do_global_dtors_aux_fini_array_entry (0) 0x3000200dd8
-  40: FUNC     LOCAL   frame_dummy (0) 0x30000007c0, rel: 0x7c0
+  40: FUNC     LOCAL   frame_dummy (0) 0x30000007c0, rel: 0x7c0 (.text)
   41: OBJECT   LOCAL   __frame_dummy_init_array_entry (0) 0x3000200dd0
   42: FILE     LOCAL   foo.c (0) 0
   43: FILE     LOCAL   bar.c (0) 0
   44: OBJECT   LOCAL   b1 (4) 0x3000201034
-  45: FUNC     LOCAL   foo (20) 0x3000000814, rel: 0x814
+  45: FUNC     LOCAL   foo (20) 0x3000000814, rel: 0x814 (.text)
   46: FILE     LOCAL   crtstuff.c (0) 0
   47: OBJECT   LOCAL   __FRAME_END__ (0) 0x3000000a58
   48: OBJECT   LOCAL   __JCR_END__ (0) 0x3000200de0
@@ -170,28 +170,28 @@ cat > testfile.symtab_pl.in <<\EOF
   51: OBJECT   LOCAL   _DYNAMIC (0) 0x3000200df0
   52: NOTYPE   LOCAL   __init_array_start (0) 0x3000200dd0
   53: OBJECT   LOCAL   _GLOBAL_OFFSET_TABLE_ (0) 0x3000201000
-  54: FUNC     GLOBAL  __libc_csu_fini (2) 0x30000008f0, rel: 0x8f0
+  54: FUNC     GLOBAL  __libc_csu_fini (2) 0x30000008f0, rel: 0x8f0 (.text)
   55: NOTYPE   WEAK    _ITM_deregisterTMCloneTable (0) 0
   56: NOTYPE   WEAK    data_start (0) 0x3000201030
   57: NOTYPE   GLOBAL  _edata (0) 0x300020103c
-  58: FUNC     GLOBAL  bar (44) 0x3000000828, rel: 0x828
-  59: FUNC     GLOBAL  _fini (0) 0x30000008f4, rel: 0x8f4
+  58: FUNC     GLOBAL  bar (44) 0x3000000828, rel: 0x828 (.text)
+  59: FUNC     GLOBAL  _fini (0) 0x30000008f4, rel: 0x8f4 (.fini)
   60: FUNC     GLOBAL  __libc_start_main@@GLIBC_2.2.5 (0) 0
   61: NOTYPE   GLOBAL  __data_start (0) 0x3000201030
   62: NOTYPE   WEAK    __gmon_start__ (0) 0
   63: OBJECT   GLOBAL  __dso_handle (0) 0x3000200de8
   64: OBJECT   GLOBAL  _IO_stdin_used (4) 0x3000000900
   65: OBJECT   GLOBAL  b2 (4) 0x3000201038
-  66: FUNC     GLOBAL  __libc_csu_init (137) 0x3000000860, rel: 0x860
+  66: FUNC     GLOBAL  __libc_csu_init (137) 0x3000000860, rel: 0x860 (.text)
   67: NOTYPE   GLOBAL  _end (0) 0x3000201040
-  68: FUNC     GLOBAL  _start (0) 0x30000006e0, rel: 0x6e0
+  68: FUNC     GLOBAL  _start (0) 0x30000006e0, rel: 0x6e0 (.text)
   69: NOTYPE   GLOBAL  __bss_start (0) 0x300020103c
-  70: FUNC     GLOBAL  main (35) 0x30000007f0, rel: 0x7f0
+  70: FUNC     GLOBAL  main (35) 0x30000007f0, rel: 0x7f0 (.text)
   71: NOTYPE   WEAK    _Jv_RegisterClasses (0) 0
   72: OBJECT   GLOBAL  __TMC_END__ (0) 0x3000201040
   73: NOTYPE   WEAK    _ITM_registerTMCloneTable (0) 0
   74: FUNC     WEAK    __cxa_finalize@@GLIBC_2.2.5 (0) 0
-  75: FUNC     GLOBAL  _init (0) 0x3000000680, rel: 0x680
+  75: FUNC     GLOBAL  _init (0) 0x3000000680, rel: 0x680 (.init)
 EOF
 
 cat > testfile.dynsym.in <<\EOF
@@ -205,22 +205,22 @@ cat > testfile.dynsym.in <<\EOF
    7: FUNC     WEAK    __cxa_finalize (0) 0
    8: NOTYPE   GLOBAL  _edata (0) 0x20103c
    9: NOTYPE   GLOBAL  _end (0) 0x201040
-  10: FUNC     GLOBAL  __libc_csu_init (137) 0x860, rel: 0x860
+  10: FUNC     GLOBAL  __libc_csu_init (137) 0x860, rel: 0x860 (.text)
   11: NOTYPE   GLOBAL  __bss_start (0) 0x20103c
-  12: FUNC     GLOBAL  main (35) 0x7f0, rel: 0x7f0
-  13: FUNC     GLOBAL  __libc_csu_fini (2) 0x8f0, rel: 0x8f0
+  12: FUNC     GLOBAL  main (35) 0x7f0, rel: 0x7f0 (.text)
+  13: FUNC     GLOBAL  __libc_csu_fini (2) 0x8f0, rel: 0x8f0 (.text)
 EOF
 
 cat > testfile.minsym.in <<\EOF
    0: NOTYPE   LOCAL    (0) 0
    1: SECTION  LOCAL    (0) 0x238
-   2: FUNC     LOCAL   deregister_tm_clones (0) 0x710, rel: 0x710
-   3: FUNC     LOCAL   register_tm_clones (0) 0x740, rel: 0x740
-   4: FUNC     LOCAL   __do_global_dtors_aux (0) 0x780, rel: 0x780
+   2: FUNC     LOCAL   deregister_tm_clones (0) 0x710, rel: 0x710 (.text)
+   3: FUNC     LOCAL   register_tm_clones (0) 0x740, rel: 0x740 (.text)
+   4: FUNC     LOCAL   __do_global_dtors_aux (0) 0x780, rel: 0x780 (.text)
    5: OBJECT   LOCAL   __do_global_dtors_aux_fini_array_entry (0) 0x200dd8
-   6: FUNC     LOCAL   frame_dummy (0) 0x7c0, rel: 0x7c0
+   6: FUNC     LOCAL   frame_dummy (0) 0x7c0, rel: 0x7c0 (.text)
    7: OBJECT   LOCAL   __frame_dummy_init_array_entry (0) 0x200dd0
-   8: FUNC     LOCAL   foo (20) 0x814, rel: 0x814
+   8: FUNC     LOCAL   foo (20) 0x814, rel: 0x814 (.text)
    9: NOTYPE   LOCAL   __init_array_end (0) 0x200dd8
   10: NOTYPE   LOCAL   __init_array_start (0) 0x200dd0
   11: SECTION  LOCAL    (0) 0x238
@@ -257,26 +257,26 @@ cat > testfile.minsym.in <<\EOF
   42: FUNC     WEAK    __cxa_finalize (0) 0
   43: NOTYPE   GLOBAL  _edata (0) 0x20103c
   44: NOTYPE   GLOBAL  _end (0) 0x201040
-  45: FUNC     GLOBAL  __libc_csu_init (137) 0x860, rel: 0x860
+  45: FUNC     GLOBAL  __libc_csu_init (137) 0x860, rel: 0x860 (.text)
   46: NOTYPE   GLOBAL  __bss_start (0) 0x20103c
-  47: FUNC     GLOBAL  main (35) 0x7f0, rel: 0x7f0
-  48: FUNC     GLOBAL  __libc_csu_fini (2) 0x8f0, rel: 0x8f0
-  49: FUNC     GLOBAL  bar (44) 0x828, rel: 0x828
-  50: FUNC     GLOBAL  _fini (0) 0x8f4, rel: 0x8f4
-  51: FUNC     GLOBAL  _start (0) 0x6e0, rel: 0x6e0
-  52: FUNC     GLOBAL  _init (0) 0x680, rel: 0x680
+  47: FUNC     GLOBAL  main (35) 0x7f0, rel: 0x7f0 (.text)
+  48: FUNC     GLOBAL  __libc_csu_fini (2) 0x8f0, rel: 0x8f0 (.text)
+  49: FUNC     GLOBAL  bar (44) 0x828, rel: 0x828 (.text)
+  50: FUNC     GLOBAL  _fini (0) 0x8f4, rel: 0x8f4 (.fini)
+  51: FUNC     GLOBAL  _start (0) 0x6e0, rel: 0x6e0 (.text)
+  52: FUNC     GLOBAL  _init (0) 0x680, rel: 0x680 (.init)
 EOF
 
 cat > testfile.minsym_pl.in <<\EOF
    0: NOTYPE   LOCAL    (0) 0
    1: SECTION  LOCAL    (0) 0x3000000238
-   2: FUNC     LOCAL   deregister_tm_clones (0) 0x3000000710, rel: 0x710
-   3: FUNC     LOCAL   register_tm_clones (0) 0x3000000740, rel: 0x740
-   4: FUNC     LOCAL   __do_global_dtors_aux (0) 0x3000000780, rel: 0x780
+   2: FUNC     LOCAL   deregister_tm_clones (0) 0x3000000710, rel: 0x710 (.text)
+   3: FUNC     LOCAL   register_tm_clones (0) 0x3000000740, rel: 0x740 (.text)
+   4: FUNC     LOCAL   __do_global_dtors_aux (0) 0x3000000780, rel: 0x780 (.text)
    5: OBJECT   LOCAL   __do_global_dtors_aux_fini_array_entry (0) 0x3000200dd8
-   6: FUNC     LOCAL   frame_dummy (0) 0x30000007c0, rel: 0x7c0
+   6: FUNC     LOCAL   frame_dummy (0) 0x30000007c0, rel: 0x7c0 (.text)
    7: OBJECT   LOCAL   __frame_dummy_init_array_entry (0) 0x3000200dd0
-   8: FUNC     LOCAL   foo (20) 0x3000000814, rel: 0x814
+   8: FUNC     LOCAL   foo (20) 0x3000000814, rel: 0x814 (.text)
    9: NOTYPE   LOCAL   __init_array_end (0) 0x3000200dd8
   10: NOTYPE   LOCAL   __init_array_start (0) 0x3000200dd0
   11: SECTION  LOCAL    (0) 0x3000000238
@@ -313,14 +313,14 @@ cat > testfile.minsym_pl.in <<\EOF
   42: FUNC     WEAK    __cxa_finalize (0) 0
   43: NOTYPE   GLOBAL  _edata (0) 0x300020103c
   44: NOTYPE   GLOBAL  _end (0) 0x3000201040
-  45: FUNC     GLOBAL  __libc_csu_init (137) 0x3000000860, rel: 0x860
+  45: FUNC     GLOBAL  __libc_csu_init (137) 0x3000000860, rel: 0x860 (.text)
   46: NOTYPE   GLOBAL  __bss_start (0) 0x300020103c
-  47: FUNC     GLOBAL  main (35) 0x30000007f0, rel: 0x7f0
-  48: FUNC     GLOBAL  __libc_csu_fini (2) 0x30000008f0, rel: 0x8f0
-  49: FUNC     GLOBAL  bar (44) 0x3000000828, rel: 0x828
-  50: FUNC     GLOBAL  _fini (0) 0x30000008f4, rel: 0x8f4
-  51: FUNC     GLOBAL  _start (0) 0x30000006e0, rel: 0x6e0
-  52: FUNC     GLOBAL  _init (0) 0x3000000680, rel: 0x680
+  47: FUNC     GLOBAL  main (35) 0x30000007f0, rel: 0x7f0 (.text)
+  48: FUNC     GLOBAL  __libc_csu_fini (2) 0x30000008f0, rel: 0x8f0 (.text)
+  49: FUNC     GLOBAL  bar (44) 0x3000000828, rel: 0x828 (.text)
+  50: FUNC     GLOBAL  _fini (0) 0x30000008f4, rel: 0x8f4 (.fini)
+  51: FUNC     GLOBAL  _start (0) 0x30000006e0, rel: 0x6e0 (.text)
+  52: FUNC     GLOBAL  _init (0) 0x3000000680, rel: 0x680 (.init)
 EOF
 
 cat testfile.symtab.in \
@@ -352,14 +352,14 @@ sed s/0x3000/0x4200/g testfile.minsym_pl.in \
 
 testrun_compare ${abs_builddir}/dwflsyms -e testfilebasmin <<\EOF
    0: NOTYPE   LOCAL    (0) 0
-   1: FUNC     LOCAL   foo (18) 0x400168, rel: 0x400168
+   1: FUNC     LOCAL   foo (18) 0x400168, rel: 0x400168 (.text)
    2: SECTION  LOCAL    (0) 0x400120
    3: SECTION  LOCAL    (0) 0x400144
    4: SECTION  LOCAL    (0) 0x4001c0
    5: SECTION  LOCAL    (0) 0x600258
-   6: FUNC     GLOBAL  _start (21) 0x4001a8, rel: 0x4001a8
-   7: FUNC     GLOBAL  main (33) 0x400144, rel: 0x400144
-   8: FUNC     GLOBAL  bar (44) 0x40017a, rel: 0x40017a
+   6: FUNC     GLOBAL  _start (21) 0x4001a8, rel: 0x4001a8 (.text)
+   7: FUNC     GLOBAL  main (33) 0x400144, rel: 0x400144 (.text)
+   8: FUNC     GLOBAL  bar (44) 0x40017a, rel: 0x40017a (.text)
 EOF
 
 exit 0