diff options
author | Roland McGrath <roland@redhat.com> | 2009-04-24 01:53:27 -0700 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2009-04-24 01:53:27 -0700 |
commit | 15fd5e3f4479a926839d64a902d489ebbd9bd488 (patch) | |
tree | cdae239d5f4c7a17f5a5342a8ad046b3947871bd | |
parent | 2e5fff4c6c28cba5107436c10810d98d902ccb88 (diff) | |
parent | 300f3a41d5e22f4e6c634ed652ebc2c90303f89f (diff) | |
download | elfutils-15fd5e3f4479a926839d64a902d489ebbd9bd488.tar.gz |
Merge branch 'master' of ssh://git.fedorahosted.org/git/elfutils into roland/unwind
Conflicts:
tests/ChangeLog
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | config/elfutils.spec.in | 9 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | libdwfl/ChangeLog | 26 | ||||
-rw-r--r-- | libdwfl/derelocate.c | 5 | ||||
-rw-r--r-- | libdwfl/dwfl_module_build_id.c | 14 | ||||
-rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 1 | ||||
-rw-r--r-- | libdwfl/dwfl_module_getsym.c | 30 | ||||
-rw-r--r-- | libdwfl/relocate.c | 10 | ||||
-rw-r--r-- | src/ChangeLog | 14 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/addr2line.c | 128 | ||||
-rw-r--r-- | tests/ChangeLog | 11 | ||||
-rw-r--r-- | tests/Makefile.am | 10 | ||||
-rwxr-xr-x | tests/run-dwfl-addr-sect.sh | 8 | ||||
-rw-r--r-- | tests/testfile50.bz2 | bin | 0 -> 229 bytes |
16 files changed, 199 insertions, 76 deletions
@@ -2,11 +2,16 @@ Version 0.141: libebl: sparc backend fixes; some more arm backend support + libdwfl: fix dwfl_module_build_id for prelinked DSO case; fixes in core file support; dwfl_module_getsym interface improved for non-address symbols + strip: fix infinite loop on strange inputs with -f +addr2line: take -j/--section=NAME option for binutils compatibility + (same effect as '(NAME)0x123' syntax already supported) + Version 0.140: libelf: Fix regression in creation of section header diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in index f67d4590..04fc34b3 100644 --- a/config/elfutils.spec.in +++ b/config/elfutils.spec.in @@ -183,6 +183,15 @@ rm -rf ${RPM_BUILD_ROOT} %{_libdir}/libelf.a %changelog +* Thu Apr 23 2009 Ulrich Drepper <drepper@redhat.com> 0.141-1 +- libebl: sparc backend fixes; some more arm backend support +- libdwfl: fix dwfl_module_build_id for prelinked DSO case; + fixes in core file support; dwfl_module_getsym interface + improved for non-address symbols +- strip: fix infinite loop on strange inputs with -f +- addr2line: take -j/--section=NAME option for binutils compatibility + (same effect as '(NAME)0x123' syntax already supported) + * Mon Feb 16 2009 Ulrich Drepper <drepper@redhat.com> 0.140-1 - libelf: Fix regression in creation of section header - libdwfl: Less strict behavior if DWARF reader ist just used to diff --git a/configure.ac b/configure.ac index aeb40d11..4931530c 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software Foundation, dnl Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. dnl -AC_INIT([Red Hat elfutils],[0.140.90],[http://bugzilla.redhat.com/bugzilla/], +AC_INIT([Red Hat elfutils],[0.141],[http://bugzilla.redhat.com/bugzilla/], [elfutils]) AC_CONFIG_AUX_DIR([config]) diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 9115b299..c73b7686 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,29 @@ +2009-04-23 Ulrich Drepper <drepper@redhat.com> + + * dwfl_module_build_id.c: Define versioned symbols only if SHARED is + defined. Otherwise just define the latest version. + +2009-04-22 Roland McGrath <roland@redhat.com> + + * relocate.c (resolve_symbol): Apply correct bias to st_value found in + a non-ET_REL module. + + * dwfl_module_build_id.c (__libdwfl_find_build_id): Fix last change to + adjust properly for non-ET_REL. + +2009-04-21 Roland McGrath <roland@redhat.com> + + * dwfl_module_getsym.c: Apply non-ET_REL bias only if SHF_ALLOC. + + * relocate.c (__libdwfl_relocate_value): Assert that MOD is ET_REL. + * derelocate.c (cache_sections): Call __libdwfl_relocate_value only + for ET_REL. + * dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise. + +2009-04-20 Roland McGrath <roland@redhat.com> + + * dwfl_module_getdwarf.c (__libdwfl_getelf): Add internal_function. + 2009-04-19 Roland McGrath <roland@redhat.com> * dwfl_module_dwarf_cfi.c: New file. diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c index f2a64675..c300f84b 100644 --- a/libdwfl/derelocate.c +++ b/libdwfl/derelocate.c @@ -1,5 +1,5 @@ /* Recover relocatibility for addresses computed from debug information. - Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc. + Copyright (C) 2005-2009 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -110,7 +110,8 @@ cache_sections (Dwfl_Module *mod) if (shdr == NULL) goto elf_error; - if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0) + if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0 + && mod->e_type == ET_REL) { /* This section might not yet have been looked at. */ if (__libdwfl_relocate_value (mod, mod->main.elf, &shstrndx, diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c index f3fcc190..d7bbb3ca 100644 --- a/libdwfl/dwfl_module_build_id.c +++ b/libdwfl/dwfl_module_build_id.c @@ -134,9 +134,12 @@ __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf) { /* Determine the right sh_addr in this module. */ GElf_Addr vaddr = 0; - if (!(shdr->sh_flags & SHF_ALLOC) - || __libdwfl_relocate_value (mod, elf, &shstrndx, - elf_ndxscn (scn), &vaddr)) + if (!(shdr->sh_flags & SHF_ALLOC)) + vaddr = NO_VADDR; + else if (mod->e_type != ET_REL) + vaddr = shdr->sh_addr + mod->main.bias; + else if (__libdwfl_relocate_value (mod, elf, &shstrndx, + elf_ndxscn (scn), &vaddr)) vaddr = NO_VADDR; result = check_notes (mod, set, elf_getdata (scn, NULL), vaddr); } @@ -171,6 +174,7 @@ __dwfl_module_build_id (Dwfl_Module *mod, *vaddr = mod->build_id_vaddr; return mod->build_id_len; } +#ifdef SHARED extern __typeof__ (dwfl_module_build_id) INTUSE(dwfl_module_build_id) __attribute__ ((alias ("__dwfl_module_build_id"))); asm (".symver " @@ -187,3 +191,7 @@ _BUG_COMPAT_dwfl_module_build_id (Dwfl_Module *mod, } asm (".symver " "_BUG_COMPAT_dwfl_module_build_id, dwfl_module_build_id@ELFUTILS_0.130"); +#else +extern __typeof__ (dwfl_module_build_id) dwfl_module_build_id + __attribute__ ((alias ("__dwfl_module_build_id"))); +#endif diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index 0441eb31..06cb4917 100644 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@ -121,6 +121,7 @@ open_elf (Dwfl_Module *mod, struct dwfl_file *file) /* Find the main ELF file for this module and open libelf on it. When we return success, MOD->main.elf and MOD->main.bias are set up. */ void +internal_function __libdwfl_getelf (Dwfl_Module *mod) { if (mod->main.elf != NULL /* Already done. */ diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c index 816d2143..f78e6ec0 100644 --- a/libdwfl/dwfl_module_getsym.c +++ b/libdwfl/dwfl_module_getsym.c @@ -74,25 +74,25 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx, if (sym->st_shndx != SHN_XINDEX) shndx = sym->st_shndx; - if (shndxp != NULL) + /* Figure out whether this symbol points into an SHF_ALLOC section. */ + bool alloc = true; + if ((shndxp != NULL || mod->e_type != ET_REL) + && (sym->st_shndx == SHN_XINDEX + || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF))) { - *shndxp = shndx; - - /* Yield -1 in case of a non-SHF_ALLOC section. */ - if (sym->st_shndx == SHN_XINDEX - || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF)) - { - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = gelf_getshdr (elf_getscn (mod->symfile->elf, shndx), - &shdr_mem); - if (unlikely (shdr == NULL) || !(shdr->sh_flags & SHF_ALLOC)) - *shndxp = (GElf_Word) -1; - } + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (elf_getscn (mod->symfile->elf, shndx), + &shdr_mem); + alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC); } + if (shndxp != NULL) + /* Yield -1 in case of a non-SHF_ALLOC section. */ + *shndxp = alloc ? shndx : (GElf_Word) -1; + switch (sym->st_shndx) { - case SHN_ABS: + case SHN_ABS: /* XXX sometimes should use bias?? */ case SHN_UNDEF: case SHN_COMMON: break; @@ -112,7 +112,7 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx, return NULL; } } - else + else if (alloc) /* Apply the bias to the symbol value. */ sym->st_value += mod->symfile->bias; break; diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c index e809a979..2c0f3010 100644 --- a/libdwfl/relocate.c +++ b/libdwfl/relocate.c @@ -59,6 +59,8 @@ internal_function __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx, Elf32_Word shndx, GElf_Addr *value) { + assert (mod->e_type == ET_REL); + Elf_Scn *refscn = elf_getscn (elf, shndx); GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem); if (refshdr == NULL) @@ -265,9 +267,15 @@ resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab, continue; /* We found it! */ - if (shndx == SHN_ABS) + if (shndx == SHN_ABS) /* XXX maybe should apply bias? */ return DWFL_E_NOERROR; + if (m->e_type != ET_REL) + { + sym->st_value += m->symfile->bias; + return DWFL_E_NOERROR; + } + /* 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; diff --git a/src/ChangeLog b/src/ChangeLog index fe8b0362..49b72037 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2009-04-23 Ulrich Drepper <drepper@redhat.com> + + * Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS). + +2009-04-20 Roland McGrath <roland@redhat.com> + + * addr2line.c (print_dwarf_function): Honor -s and -A for file names + of inline call sites. + + * addr2line.c (just_section): New variable. + (adjust_to_section): New function, broken out of ... + (handle_address): ... here. + (options, parse_opt): Add -j/--section=NAME to set it. + 2009-04-15 Roland McGrath <roland@redhat.com> * readelf.c (print_debug_frame_section): Check for DW_CIE_ID_64 in diff --git a/src/Makefile.am b/src/Makefile.am index 64e4478b..c644a062 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,7 +95,7 @@ endif if BUILD_STATIC libasm = ../libasm/libasm.a -libdw = ../libdw/libdw.a $(libelf) $(libebl) -ldl +libdw = ../libdw/libdw.a $(zip_LIBS) $(libelf) $(libebl) -ldl libelf = ../libelf/libelf.a else libasm = ../libasm/libasm.so diff --git a/src/addr2line.c b/src/addr2line.c index 5a7b0456..99264b01 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -69,6 +69,8 @@ static const struct argp_option options[] = N_("Show absolute file names using compilation directory"), 0 }, { "functions", 'f', NULL, 0, N_("Also show function names"), 0 }, { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 }, + { "section", 'j', "NAME", 0, + N_("Treat addresses as offsets relative to NAME section."), 0 }, { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, /* Unsupported options. */ @@ -113,6 +115,9 @@ static bool show_functions; /* True if ELF symbol or section info should be shown. */ static bool show_symbols; +/* If non-null, take address parameters as relative to named section. */ +static const char *just_section; + int main (int argc, char *argv[]) @@ -188,8 +193,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ /* Handle program arguments. */ static error_t -parse_opt (int key, char *arg __attribute__ ((unused)), - struct argp_state *state) +parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { @@ -219,6 +223,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), show_symbols = true; break; + case 'j': + just_section = arg; + break; + default: return ARGP_ERR_UNKNOWN; } @@ -276,15 +284,35 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) DW_AT_call_column, &attr_mem), &val) == 0) colno = val; - if (lineno == 0) + + const char *comp_dir = ""; + const char *comp_dir_sep = ""; + + if (file == NULL) + file = "???"; + else if (only_basenames) + file = basename (file); + else if (use_comp_dir && file[0] != '/') { - if (file != NULL) - printf (" from %s", file); + const char *const *dirs; + size_t ndirs; + if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 + && dirs[0] != NULL) + { + comp_dir = dirs[0]; + comp_dir_sep = "/"; + } } + + if (lineno == 0) + printf (" from %s%s%s", + comp_dir, comp_dir_sep, file); else if (colno == 0) - printf (" at %s:%u", file, lineno); + printf (" at %s%s%s:%u", + comp_dir, comp_dir_sep, file, lineno); else - printf (" at %s:%u:%u", file, lineno, colno); + printf (" at %s%s%s:%u:%u", + comp_dir, comp_dir_sep, file, lineno, colno); } } printf (" in "); @@ -366,6 +394,49 @@ find_symbol (Dwfl_Module *mod, return DWARF_CB_OK; } +static bool +adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl) +{ + /* It was (section)+offset. This makes sense if there is + only one module to look in for a section. */ + Dwfl_Module *mod = NULL; + if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 + || mod == NULL) + error (EXIT_FAILURE, 0, gettext ("Section syntax requires" + " exactly one module")); + + int nscn = dwfl_module_relocations (mod); + for (int i = 0; i < nscn; ++i) + { + GElf_Word shndx; + const char *scn = dwfl_module_relocation_info (mod, i, &shndx); + if (unlikely (scn == NULL)) + break; + if (!strcmp (scn, name)) + { + /* Found the section. */ + GElf_Shdr shdr_mem; + GElf_Addr shdr_bias; + GElf_Shdr *shdr = gelf_getshdr + (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), + &shdr_mem); + if (unlikely (shdr == NULL)) + break; + + if (*addr >= shdr->sh_size) + error (0, 0, + gettext ("offset %#" PRIxMAX " lies outside" + " section '%s'"), + *addr, scn); + + *addr += shdr->sh_addr + shdr_bias; + return true; + } + } + + return false; +} + static int handle_address (const char *string, Dwfl *dwfl) { @@ -378,45 +449,7 @@ handle_address (const char *string, Dwfl *dwfl) char *name = NULL; if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &n) == 2 && string[n] == '\0') - { - /* It was (section)+offset. This makes sense if there is - only one module to look in for a section. */ - Dwfl_Module *mod = NULL; - if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 - || mod == NULL) - error (EXIT_FAILURE, 0, gettext ("Section syntax requires" - " exactly one module")); - - int nscn = dwfl_module_relocations (mod); - for (int i = 0; i < nscn; ++i) - { - GElf_Word shndx; - const char *scn = dwfl_module_relocation_info (mod, i, &shndx); - if (unlikely (scn == NULL)) - break; - if (!strcmp (scn, name)) - { - /* Found the section. */ - GElf_Shdr shdr_mem; - GElf_Addr shdr_bias; - GElf_Shdr *shdr = gelf_getshdr - (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), - &shdr_mem); - if (unlikely (shdr == NULL)) - break; - - if (addr >= shdr->sh_size) - error (0, 0, - gettext ("offset %#" PRIxMAX " lies outside" - " section '%s'"), - addr, scn); - - addr += shdr->sh_addr + shdr_bias; - parsed = true; - break; - } - } - } + parsed = adjust_to_section (name, &addr, dwfl); else if (sscanf (string, "%m[^-+]%" PRIiMAX "%n", &name, &addr, &n) == 2 && string[n] == '\0') { @@ -442,6 +475,9 @@ handle_address (const char *string, Dwfl *dwfl) if (!parsed) return 1; } + else if (just_section != NULL + && !adjust_to_section (just_section, &addr, dwfl)) + return 1; Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); diff --git a/tests/ChangeLog b/tests/ChangeLog index 151dcabf..e8bb53ae 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -4,6 +4,17 @@ * Makefile.am (noinst_PROGRAMS): Add it. (addrcfi_LDADD): New variable. +2009-04-23 Ulrich Drepper <drepper@redhat.com> + + * Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS). + (rdwrmmap_LDADD): Add $(libmudflap). + +2009-04-21 Roland McGrath <roland@redhat.com> + + * testfile50.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + * run-dwfl-addr-sect.sh: Add a case using it. + 2008-12-31 Ulrich Drepper <drepper@redhat.com> * testfile44.S.bz2: Add tests for dppd, dpps, insertps, movntdqa, diff --git a/tests/Makefile.am b/tests/Makefile.am index 90b593d3..25553795 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 1996-2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. +## Copyright (C) 1996-2009 Red Hat, Inc. ## This file is part of Red Hat elfutils. ## ## Red Hat elfutils is free software; you can redistribute it and/or modify @@ -141,7 +141,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ testfile44.S.bz2 testfile44.expect.bz2 run-disasm-x86.sh \ testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \ testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \ - testfile49.bz2 + testfile49.bz2 testfile50.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ @@ -160,7 +160,7 @@ installcheck-local: endif !STANDALONE if MUDFLAP -static_build=yes +static_build = yes libmudflap = -lmudflap endif @@ -171,7 +171,7 @@ libasm = -lasm libebl = -lebl else !STANDALONE if BUILD_STATIC -libdw = ../libdw/libdw.a $(libelf) $(libebl) -ldl +libdw = ../libdw/libdw.a $(zip_LIBS) $(libelf) $(libebl) -ldl libelf = ../libelf/libelf.a libasm = ../libasm/libasm.a else @@ -225,7 +225,7 @@ asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libmudflap) -ldl dwflmodtest_LDADD = $(libdw) $(libebl) $(libelf) $(libmudflap) -ldl -rdwrmmap_LDADD = $(libelf) +rdwrmmap_LDADD = $(libelf) $(libmudflap) dwfl_bug_addr_overflow_LDADD = $(libdw) $(libebl) $(libelf) $(libmudflap) -ldl arls_LDADD = $(libelf) $(libmudflap) dwfl_bug_fd_leak_LDADD = $(libdw) $(libebl) $(libelf) $(libmudflap) -ldl diff --git a/tests/run-dwfl-addr-sect.sh b/tests/run-dwfl-addr-sect.sh index 98666f37..f33a6e42 100755 --- a/tests/run-dwfl-addr-sect.sh +++ b/tests/run-dwfl-addr-sect.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2007, 2008 Red Hat, Inc. +# Copyright (C) 2007-2009 Red Hat, Inc. # This file is part of Red Hat elfutils. # # Red Hat elfutils is free software; you can redistribute it and/or modify @@ -25,7 +25,7 @@ . $srcdir/test-subr.sh -testfiles testfile43 +testfiles testfile43 testfile50 testrun_compare ./dwfl-addr-sect -e testfile43 0x64 0x8 0x98 <<\EOF address 0x64 => module "" section 4 + 0 @@ -33,4 +33,8 @@ address 0x8 => module "" section 1 + 0x8 address 0x98 => module "" section 7 + 0 EOF +testrun_compare ./dwfl-addr-sect -e testfile50 0x1 <<\EOF +address 0x1 => module "" section 1 + 0x1 +EOF + exit 0 diff --git a/tests/testfile50.bz2 b/tests/testfile50.bz2 Binary files differnew file mode 100644 index 00000000..fce43321 --- /dev/null +++ b/tests/testfile50.bz2 |