[RFA/RFC] try ignoring bad PLT entries in ELF symbol tables

Joel Brobecker brobecker@adacore.com
Wed Oct 19 00:30:00 GMT 2011


Our testsuite noticed a problem on ia64-hpux when trying to compute
a backtrace inside one of our Ada programs. In one of the frames,
it said that the function name was `uwx_get_reg' instead of the
name of our main subprogram (in our case, `_ada_test_protected').

Exploring further, I found that the code address for the frame was
correct, and that the problem was the reverse lookup of the symbol
at that address. It turns out:

  1. When searching the symtabs, it found the correct symbol;
  2. Regardless of the above, it still searched the minsyms, and
     found a different symbol (uwx_get_reg) whose address is closer
     to our PC;
  3. Based on the above, it decided that the correct answer is
     the latter choice.

Unfortunately, this is not correct in our case, simply because the
entry in the symbol table seems bogus. `uwx_get_reg' is provided
by the libunwind shared library, and the entry in the symbol table
looks like this:

    40000000000182e0       F *UND*  0000000000000000 uwx_get_reg

Normally, such entries either have a null value, or their value
corresponds to an address in the PLT section.  But, in this case,
it actually points to some real (user) code in the .text section,
right in the middle of our main subprogram. This is what we have
in the symbol table for our main subprogram:

    4000000000018060 g     F .text  0000000000000570 _ada_test_protected

The debug info probably says exactly the same thing in terms of
the code boundaries.  I've also verified by visual inspection that
the instructions at those addresses correspond to the instructions
I found in the assembly file.

So the undefined symbol entry for uwx_get_reg seems bogus.  We use
the system linker, so we cannot fix the problem there.  So I tried
to find a way to work around this in GDB. Normally, we ignore entries
with a null value. Here, the value is not null, so we expect it to
be a reference to the corresponding PLT.  The check I am adding is
to verify that it seems plausible by checking the name of the section
we think this address corresponds to.  It bets on the fact that it
usually is ".plt".  And to survive the theoretical situation where
the symbol is a valid reference to a valid PLT which lives in
a section not named ".plt", I added a check that makes sure that
we only discard such symbol if there is a ".plt" section. In other
words, if the symbol points to a section not named ".plt", and
there is no section named ".plt", then we retain it.

gdb/ChangeLog:

        * elfread.c (elf_symtab_read): Ignore undefined symbols with
        nonzero addresses if they do not correspond to a .plt section
        when one is available in the objfile.

Tested on ia64-hpux. No regressions.

Thoughts? Worth a try?

---
 gdb/elfread.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/gdb/elfread.c b/gdb/elfread.c
index a309a2c..866226d 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -303,6 +303,23 @@ elf_symtab_read (struct objfile *objfile, int type,
 	  if (!sect)
 	    continue;
 
+	  /* On ia64-hpux, we have discovered that the system linker
+	     adds undefined symbols with nonzero addresses that cannot
+	     be right (their address points inside the code of another
+	     function in the .text section).  This creates problems
+	     when trying to determine which symbol corresponds to
+	     a given address.
+
+	     We try to detect those buggy symbols by checking which
+	     section we think they correspond to.  Normally, PLT symbols
+	     are stored inside their own section, and the typical name
+	     for that section is ".plt".  So, if there is a ".plt"
+	     section, and yet the section name of our symbol does not
+	     start with ".plt", we ignore that symbol.  */
+	  if (strncmp (sect->name, ".plt", 4) != 0
+	      && bfd_get_section_by_name (abfd, ".plt") != NULL)
+	    continue;
+
 	  symaddr += ANOFFSET (objfile->section_offsets, sect->index);
 
 	  msym = record_minimal_symbol
-- 
1.7.1



More information about the Gdb-patches mailing list