This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: dwfl_module_get|addrsym_elf (Was: [commit] [patch 2/4] Provide __libdwfl_module_getsym to get dwfl_file *)
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Wed, 27 Nov 2013 16:48:16 +0100
- Subject: 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