From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6435 invoked by alias); 19 Oct 2011 00:24:00 -0000 Received: (qmail 6425 invoked by uid 22791); 19 Oct 2011 00:23:58 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,TW_BJ,TW_UW X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 19 Oct 2011 00:23:44 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id C00262BB346; Tue, 18 Oct 2011 20:23:43 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id zVnPjB-43LsY; Tue, 18 Oct 2011 20:23:43 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 92DF92BB344; Tue, 18 Oct 2011 20:23:43 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id BB1DE145615; Tue, 18 Oct 2011 20:23:38 -0400 (EDT) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [RFA/RFC] try ignoring bad PLT entries in ELF symbol tables Date: Wed, 19 Oct 2011 00:30:00 -0000 Message-Id: <1318983817-29454-1-git-send-email-brobecker@adacore.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-10/txt/msg00518.txt.bz2 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