From 42f686820a19806da629990bf7ae69a6a2fcfb1f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 9 Aug 2007 07:54:22 +0000 Subject: [PATCH] 2007-08-09 Roland McGrath * dwfl-bug-report.c: Fix header inclusion. --- config/ChangeLog | 4 ++ config/elfutils.spec.in | 2 +- libdwfl/ChangeLog | 6 +++ libdwfl/dwfl_module_addrsym.c | 75 +++++++++++++++++++++++++--------- tests/ChangeLog | 10 +++++ tests/Makefile.am | 3 +- tests/dwfl-bug-report.c | 1 - tests/run-addrname-test.sh | 13 +++++- tests/testfile38.bz2 | Bin 0 -> 457 bytes 9 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 tests/testfile38.bz2 diff --git a/config/ChangeLog b/config/ChangeLog index 5f712829d..e61bac2c6 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,7 @@ +2007-08-08 Roland McGrath + + * elfutils.spec.in (License): Canonicalize. + 2007-04-23 Roland McGrath * elfutils.spec.in: Distribute eu-unstrip. diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in index 9dc436ade..cb7ddd62e 100644 --- a/config/elfutils.spec.in +++ b/config/elfutils.spec.in @@ -3,7 +3,7 @@ Summary: A collection of utilities and DSOs to handle compiled objects Name: elfutils Version: @PACKAGE_VERSION@ Release: 1 -License: GPL +License: GPLv2 with exceptions Group: Development/Tools Source: elfutils-%{version}.tar.gz Obsoletes: libelf libelf-devel diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 9df78876e..38f86a7d5 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,9 @@ +2007-08-08 Roland McGrath + + * dwfl_module_addrsym.c: Don't use STT_SECTION, STT_FILE symbols and + those with no names. Rewrite best symbol algorithm not to assume a + sorted table and to be smarter handling sizeless symbols. + 2007-07-16 Roland McGrath * dwfl_module.c (dwfl_report_module): Increment DWFL->nmodules when diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c index 98ab15a01..e78e292a9 100644 --- a/libdwfl/dwfl_module_addrsym.c +++ b/libdwfl/dwfl_module_addrsym.c @@ -97,39 +97,76 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, return shndx == addr_shndx; } - /* Look through the symbol table for a matching symbol. */ + /* 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; - closest_sym->st_value = 0; GElf_Word closest_shndx = SHN_UNDEF; + + /* Keep track of an eligible symbol with st_size == 0 as a fallback. */ + const char *sizeless_name = NULL; + GElf_Sym sizeless_sym; + GElf_Word sizeless_shndx = SHN_UNDEF; + + /* Keep track of the lowest address a relevant sizeless symbol could have. */ + GElf_Addr min_label = addr; + + /* Look through the symbol table for a matching symbol. */ for (int i = 1; i < syments; ++i) { GElf_Sym sym; GElf_Word shndx; const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx); - if (name != NULL && sym.st_value <= addr) + if (name != NULL + && sym.st_value <= addr + && (sym.st_size == 0 || addr - sym.st_value < sym.st_size)) { - inline void closest (void) - { - *closest_sym = sym; - closest_shndx = shndx; - closest_name = name; - } + /* Even if we don't choose this symbol, its existence + excludes any sizeless symbol (assembly label) that + is inside its bounds. */ + if (sym.st_value + sym.st_size > addr) + min_label = sym.st_value + sym.st_size; - if (addr < sym.st_value + sym.st_size) + /* This symbol is a better candidate than the current one + if it's a named symbol, not a section or file symbol, + and is closer to ADDR or is global when it was local. */ + if (name[0] != '\0' + && GELF_ST_TYPE (sym.st_info) != STT_SECTION + && GELF_ST_TYPE (sym.st_info) != STT_FILE + && (closest_name == NULL + || closest_sym->st_value < sym.st_value + || (GELF_ST_BIND (closest_sym->st_info) + < GELF_ST_BIND (sym.st_info)))) { - closest (); - break; + if (sym.st_size != 0) + { + *closest_sym = sym; + closest_shndx = shndx; + closest_name = name; + } + else if (same_section (&sym, shndx)) + { + /* Handwritten assembly symbols sometimes have no st_size. + If no symbol with proper size includes the address, + we'll use the closest one that is in the same section + as ADDR. */ + sizeless_sym = sym; + sizeless_shndx = shndx; + sizeless_name = name; + } } - - /* Handwritten assembly symbols sometimes have no st_size. - If no symbol with proper size includes the address, we'll - use the closest one that is in the same section as ADDR. */ - if (sym.st_size == 0 && sym.st_value >= closest_sym->st_value - && same_section (&sym, shndx)) - closest (); } } + /* If we found no proper sized symbol to use, fall back to the best + candidate sizeless symbol we found, if any. */ + if (closest_name == NULL + && sizeless_name != NULL && sizeless_sym.st_value >= min_label) + { + *closest_sym = sizeless_sym; + closest_shndx = sizeless_shndx; + closest_name = sizeless_name; + } + if (shndxp != NULL) *shndxp = closest_shndx; return closest_name; diff --git a/tests/ChangeLog b/tests/ChangeLog index 9d082c879..6ac600776 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,13 @@ +2007-08-09 Roland McGrath + + * dwfl-bug-report.c: Fix header inclusion. + +2007-08-08 Roland McGrath + + * run-addrname-test.sh: Add a new case using addr2line -S. + * testfile38.bz2: New data file. + * Makefile.am (EXTRA_DIST): Add it. + 2007-07-16 Roland McGrath * dwfl-bug-report.c: New file. diff --git a/tests/Makefile.am b/tests/Makefile.am index 86638768b..040351f91 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -125,7 +125,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 \ testfile36.bz2 testfile36.debug.bz2 \ - testfile37.bz2 testfile37.debug.bz2 + testfile37.bz2 testfile37.debug.bz2 \ + testfile38.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ diff --git a/tests/dwfl-bug-report.c b/tests/dwfl-bug-report.c index 5f8699ddc..459a41aea 100644 --- a/tests/dwfl-bug-report.c +++ b/tests/dwfl-bug-report.c @@ -26,7 +26,6 @@ #include #include ELFUTILS_HEADER(dwfl) -#include #include #include #include diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh index 6469646c1..59290b393 100755 --- a/tests/run-addrname-test.sh +++ b/tests/run-addrname-test.sh @@ -25,7 +25,7 @@ . $srcdir/test-subr.sh -testfiles testfile34 +testfiles testfile34 testfile38 testrun_compare ../src/addr2line -f -e testfile34 \ 0x08048074 0x08048075 0x08048076 \ @@ -44,4 +44,15 @@ _end ??:0 EOF +testrun_compare ../src/addr2line -S -e testfile38 0x02 0x10a 0x211 0x31a <<\EOF +t1_global_outer+0x2 +??:0 +t2_global_symbol+0x2 +??:0 +t3_global_after_0+0x1 +??:0 +(.text)+0x31a +??:0 +EOF + exit 0 diff --git a/tests/testfile38.bz2 b/tests/testfile38.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..42adb77459b99a64b24da3f14bbb266755a812a8 GIT binary patch literal 457 zc-jHU0XF_ZT4*^jL0KkKS$uyrsQ>}RfB*mf^n9Vkd{IXPfCT^N-*A9HKu|yg00aO6 z004j>00=MvhHa>ZLWYEDVW=@YkPSUS>H|a683s)>0ihKA6x0TWfHVLA0000001_lA zs(KAiNZU!EG>sSlCPpR%3{NJWrgfHV6yeFA;+pbSDx%t1w)^;JmK%s8bMc5n1qiFb z{PgjNt~fJR#?HH0oE~IFT(^wWZz+fo0Fgi|CH=RFG&M)^xw$!rFfWJ z)L`eoF-b5`zzoQPIf_qKq689RuxKRPOlM!8YMj)*Ii11;FlM5r2%^0EDRx*jT|^@Q zEJgqTIAsZ8Ze?Jvu|thOGn zxQ4Ir1+lir`qEgE#pR47isfN@FiakuptqWrgGrF2@aVuAIFhLr84|n-L7vfQy29a` zDU_f=ERhyk3#W?_1ig2MI`2K5BymiIU literal 0 Hc-jL100001 -- 2.47.2