summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2013-11-27 16:45:44 +0100
committerMark Wielaard <mjw@redhat.com>2013-11-27 16:45:44 +0100
commit819c349f6339512d6961a6172c539fdf2c2f1328 (patch)
treec7be311a37ac6ebae7d27b10f401d131d7d8be0d
parent16bc4569a9d4c86aac4de749ccf27fa7b1ae24d5 (diff)
downloadelfutils-819c349f6339512d6961a6172c539fdf2c2f1328.tar.gz
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>
-rw-r--r--libdw/ChangeLog5
-rw-r--r--libdw/libdw.map3
-rw-r--r--libdwfl/ChangeLog22
-rw-r--r--libdwfl/dwfl_module_addrsym.c49
-rw-r--r--libdwfl/dwfl_module_getsym.c33
-rw-r--r--libdwfl/dwfl_module_info.c2
-rw-r--r--libdwfl/libdwfl.h25
-rw-r--r--libdwfl/libdwflP.h24
-rw-r--r--libdwfl/relocate.c2
-rw-r--r--tests/ChangeLog10
-rw-r--r--tests/dwflsyms.c66
-rwxr-xr-xtests/run-dwflsyms.sh110
12 files changed, 243 insertions, 108 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 33885ac3..91e10833 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 060c3df8..0438e24c 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 deb50140..9937bbbb 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 d9eb0a27..320d41f1 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 0f5dd37d..319f9758 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 fdb4202a..df16be41 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 c1a0fb99..3d5bede6 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 b8a64d8e..b73f7b1d 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 bd51ad6d..f8a5fcfa 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 8a6c4d22..6c0ec364 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 55f2653c..10c01f1f 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 2adec5a3..3cd7bf36 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