]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
2007-08-09 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Thu, 9 Aug 2007 07:54:22 +0000 (07:54 +0000)
committerRoland McGrath <roland@redhat.com>
Thu, 9 Aug 2007 07:54:22 +0000 (07:54 +0000)
* dwfl-bug-report.c: Fix header inclusion.

config/ChangeLog
config/elfutils.spec.in
libdwfl/ChangeLog
libdwfl/dwfl_module_addrsym.c
tests/ChangeLog
tests/Makefile.am
tests/dwfl-bug-report.c
tests/run-addrname-test.sh
tests/testfile38.bz2 [new file with mode: 0644]

index 5f712829df9982d9106f3d8b3d13623c208fadbd..e61bac2c67a49df440f9ac18caba654145d1ade8 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-08  Roland McGrath  <roland@redhat.com>
+
+       * elfutils.spec.in (License): Canonicalize.
+
 2007-04-23  Roland McGrath  <roland@redhat.com>
 
        * elfutils.spec.in: Distribute eu-unstrip.
index 9dc436ade81d78b03b595f13fb7999613eaca06a..cb7ddd62ef108da85117dc355e9cad88225e68c3 100644 (file)
@@ -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
index 9df78876ea7129314f0c1dc45c14e84b5600f6f4..38f86a7d5de1a9008874ec2b24f036e2312afdda 100644 (file)
@@ -1,3 +1,9 @@
+2007-08-08  Roland McGrath  <roland@redhat.com>
+
+       * 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  <roland@redhat.com>
 
        * dwfl_module.c (dwfl_report_module): Increment DWFL->nmodules when
index 98ab15a0104073524d1a0cfc6fff997572b9bbd1..e78e292a94d484a4fb07f04aa6767fbbcf4e27b7 100644 (file)
@@ -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;
index 9d082c879a1e071fe5c3df748450e3e030d06497..6ac600776b85986284214f12ab5e9cabea926ac2 100644 (file)
@@ -1,3 +1,13 @@
+2007-08-09  Roland McGrath  <roland@redhat.com>
+
+       * dwfl-bug-report.c: Fix header inclusion.
+
+2007-08-08  Roland McGrath  <roland@redhat.com>
+
+       * 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  <roland@redhat.com>
 
        * dwfl-bug-report.c: New file.
index 86638768bb036e2384b8942eb3eedca8c76a3829..040351f914ccb213ab449dba6512a834c37f1093 100644 (file)
@@ -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) \
index 5f8699ddcc072a797fecccbc68cb0ae0709de5d8..459a41aeaef28dafd49dc11074c8711886cc928e 100644 (file)
@@ -26,7 +26,6 @@
 #include <config.h>
 #include ELFUTILS_HEADER(dwfl)
 
-#include <elfutils/libdwfl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
index 6469646c142aa54ec2a56d44e0c429665244eb2c..59290b393ace1ab1c6d43277c0dcf36b07152a81 100755 (executable)
@@ -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 (file)
index 0000000..42adb77
Binary files /dev/null and b/tests/testfile38.bz2 differ