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]

Re: dwfl_module_get|addrsym_elf (Was: [commit] [patch 2/4] Provide __libdwfl_module_getsym to get dwfl_file *)


On Tue, 2013-11-26 at 15:23 +0100, Jan Kratochvil wrote:
> Maybe you had a reason for it but we could also just replace
> __libdwfl_module_getsym by dwfl_module_getsym_elf now.  It would just require
> changing
> 
> static inline GElf_Addr
> dwfl_deadjust_st_value (Dwfl_Module *mod, struct dwfl_file *symfile,
>                         GElf_Addr addr)
> 
> so that it accepts Elf * instead of struct dwfl_file * .

I admit I hadn't thought of that. Now I realize returning the Elf
without the bias is not as useful. For that the dwfl_file is also
useful. But we can still make the simplification you suggest. It does
cause a lot of small changes all over the place, hope that doesn't clash
too much with your pending patches. See attached. Also added one more
test to dwflsyms to make sure the returned bias is sane wrt the elf and
shndx.

Thanks,

Mark
>From 819c349f6339512d6961a6172c539fdf2c2f1328 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Wed, 27 Nov 2013 16:45:44 +0100
Subject: [PATCH] libdwfl: Add dwfl_module_addrsym_elf and dwfl_module_getsym_elf.

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>
---
 libdw/ChangeLog               |    5 ++
 libdw/libdw.map               |    3 +
 libdwfl/ChangeLog             |   22 ++++++++
 libdwfl/dwfl_module_addrsym.c |   49 +++++++++++++-----
 libdwfl/dwfl_module_getsym.c  |   33 ++++++------
 libdwfl/dwfl_module_info.c    |    2 +-
 libdwfl/libdwfl.h             |   25 +++++++++-
 libdwfl/libdwflP.h            |   24 +++------
 libdwfl/relocate.c            |    2 +-
 tests/ChangeLog               |   10 ++++
 tests/dwflsyms.c              |   66 +++++++++++++++++++++++--
 tests/run-dwflsyms.sh         |  110 ++++++++++++++++++++--------------------
 12 files changed, 243 insertions(+), 108 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 33885ac..91e1083 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -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,
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 060c3df..0438e24 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -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;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index deb5014..9937bbb 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -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.
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index d9eb0a2..320d41f 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -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)
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
index 0f5dd37..319f975 100644
--- a/libdwfl/dwfl_module_getsym.c
+++ b/libdwfl/dwfl_module_getsym.c
@@ -29,10 +29,9 @@
 #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)
diff --git a/libdwfl/dwfl_module_info.c b/libdwfl/dwfl_module_info.c
index fdb4202..df16be4 100644
--- a/libdwfl/dwfl_module_info.c
+++ b/libdwfl/dwfl_module_info.c
@@ -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;
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index c1a0fb9..3d5bede 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -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
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index b8a64d8..b73f7b1 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -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)
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index bd51ad6..f8a5fcf 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -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;
 		  }
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 8a6c4d2..6c0ec36 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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.
diff --git a/tests/dwflsyms.c b/tests/dwflsyms.c
index 55f2653..10c01f1 100644
--- a/tests/dwflsyms.c
+++ b/tests/dwflsyms.c
@@ -69,6 +69,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)),
 	   const char *mod_name __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");
     }
diff --git a/tests/run-dwflsyms.sh b/tests/run-dwflsyms.sh
index 2adec5a..3cd7bf3 100755
--- a/tests/run-dwflsyms.sh
+++ b/tests/run-dwflsyms.sh
@@ -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
-- 
1.7.1


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