diff options
author | Mark Wielaard <mjw@redhat.com> | 2013-11-27 16:45:44 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2013-11-27 16:45:44 +0100 |
commit | 819c349f6339512d6961a6172c539fdf2c2f1328 (patch) | |
tree | c7be311a37ac6ebae7d27b10f401d131d7d8be0d | |
parent | 16bc4569a9d4c86aac4de749ccf27fa7b1ae24d5 (diff) | |
download | elfutils-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/ChangeLog | 5 | ||||
-rw-r--r-- | libdw/libdw.map | 3 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 22 | ||||
-rw-r--r-- | libdwfl/dwfl_module_addrsym.c | 49 | ||||
-rw-r--r-- | libdwfl/dwfl_module_getsym.c | 33 | ||||
-rw-r--r-- | libdwfl/dwfl_module_info.c | 2 | ||||
-rw-r--r-- | libdwfl/libdwfl.h | 25 | ||||
-rw-r--r-- | libdwfl/libdwflP.h | 24 | ||||
-rw-r--r-- | libdwfl/relocate.c | 2 | ||||
-rw-r--r-- | tests/ChangeLog | 10 | ||||
-rw-r--r-- | tests/dwflsyms.c | 66 | ||||
-rwxr-xr-x | tests/run-dwflsyms.sh | 110 |
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 |