From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19688 invoked by alias); 1 Dec 2006 18:15:27 -0000 Received: (qmail 19671 invoked by uid 22791); 1 Dec 2006 18:15:25 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Fri, 01 Dec 2006 18:15:11 +0000 Received: from drow by nevyn.them.org with local (Exim 4.63) (envelope-from ) id 1GqCui-0000gt-VL for gdb-patches@sources.redhat.com; Fri, 01 Dec 2006 13:15:09 -0500 Date: Fri, 01 Dec 2006 18:15:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: Re: [RFA/symtab] Handle weak functions as global Message-ID: <20061201181508.GA1786@nevyn.them.org> Mail-Followup-To: gdb-patches@sources.redhat.com References: <20041101173014.GA20449@nevyn.them.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20041101173014.GA20449@nevyn.them.org> User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes 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: 2006-12/txt/msg00004.txt.bz2 I was reminded about this patch, two years old now, earlier in the week. I've updated it and applied it; patch and testcase below. On Mon, Nov 01, 2004 at 12:30:15PM -0500, Daniel Jacobowitz wrote: > This patch is a one liner, but requires a bit of explanation. If you have a > version of glibc available with debugging symbols (in both ld.so and > libc.so), you can see the problem like this: > > - Compile a program which calls open (). > - Run to main. > - Set a breakpoint on open. > - Continue - the breakpoint will not be hit. > > [Separate debug files will show the bug if you point GDB at the right > directory; on Debian this is /usr/lib/debug, not sure where it is on RH > systems.] > > What happens, in my setup at least, is that gdb searches first the > executable, then libc.so.6, then ld.so for "open". It either finds a > trampoline in the executable or nothing at all (depending on your version of > binutils). Then, it finds open in libc.so.6, which has type mst_file_text. > Then it finds open in ld.so, which also has a symbol named open, which also > has type mst_file_text. We did not find any mst_text symbol, so we settle > for returning the most recent mst_file_text symbol - which is the wrong one. > > There's two strange things here. The first is that we return the second > file symbol instead of the first; it doesn't much matter, since we'll be > wrong half the time anyway. The second is that the symbol in libc.so is > marked as mst_file_text. This turned out to be because BSF_WEAK handling > was added to elfread for non-code symbols, but not for code symbols; and > open is a weak entry point to libc.so.6 for historical reasons. If we treat > it as global, paralleling the non-code symbol handling, then GDB will > resolve breakpoints on "open" reliably to libc.so.6 (assuming no other > shared library defines it). This gives the debugger much better chances of > finding the right symbol - any situation more complicated would require > setting breakpoints at all functions named "open", which is a To-Do-Later > issue. -- Daniel Jacobowitz CodeSourcery 2006-12-01 Daniel Jacobowitz * elfread.c (elf_symtab_read): Treat weak functions as global. 2006-12-01 Daniel Jacobowitz * gdb.base/solib-weak.c, gdb.base/solib-weak.exp, gdb.base/weaklib1.c, gdb.base/weaklib2.c: New files. Index: elfread.c =================================================================== RCS file: /cvs/src/src/gdb/elfread.c,v retrieving revision 1.55 diff -u -p -r1.55 elfread.c --- elfread.c 21 Feb 2006 20:38:48 -0000 1.55 +++ elfread.c 1 Dec 2006 18:10:05 -0000 @@ -284,7 +284,7 @@ elf_symtab_read (struct objfile *objfile } else if (sym->section->flags & SEC_CODE) { - if (sym->flags & BSF_GLOBAL) + if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) { ms_type = mst_text; } Index: testsuite/gdb.base/solib-weak.c =================================================================== RCS file: testsuite/gdb.base/solib-weak.c diff -N testsuite/gdb.base/solib-weak.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-weak.c 1 Dec 2006 18:10:05 -0000 @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +int +main() +{ + foo (); + return 0; +} Index: testsuite/gdb.base/solib-weak.exp =================================================================== RCS file: testsuite/gdb.base/solib-weak.exp diff -N testsuite/gdb.base/solib-weak.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-weak.exp 1 Dec 2006 18:10:05 -0000 @@ -0,0 +1,109 @@ +# Copyright 2006 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test setting breakpoints on shared library functions provided by more +# than one shared library, when one of the implementations is a "weak" +# symbol. GDB should set a breakpoint at the first copy it finds. + +# Don't try to run shared library test cases on a remote target for now. +if ![isnative] then { + return 0 +} + +# This test uses GCC-specific syntax. +if [get_compiler_info not-used] { + return -1 +} + +if {![test_compiler_info "gcc-*"]} { + return 0 +} + +proc do_test { lib1opts lib2opts lib1first } { + global objdir srcdir subdir + + set testopts "" + if {$lib1opts == ""} { + append testopts "lib1 nodebug, " + } else { + append testopts "lib1 debug, " + } + if {$lib2opts == ""} { + append testopts "lib2 nodebug, " + } else { + append testopts "lib2 debug, " + } + if {$lib1first} { + append testopts "lib1 first" + } else { + append testopts "lib2 first" + } + + set testfile "solib-weak" + set srcfile ${testfile}.c + set binfile ${objdir}/${subdir}/${testfile} + + set libfile1 "weaklib1" + set libfile2 "weaklib2" + set lib1src ${srcdir}/${subdir}/${libfile1}.c + set lib2src ${srcdir}/${subdir}/${libfile2}.c + set lib1 ${objdir}/${subdir}/${libfile1}.sl + set lib2 ${objdir}/${subdir}/${libfile2}.sl + + if $lib1first { + set exec_opts [list debug shlib=${lib1} shlib=${lib2}] + set expected_file ${libfile1} + } else { + set exec_opts [list debug shlib=${lib2} shlib=${lib1}] + set expected_file ${libfile2} + } + + if { [gdb_compile_shlib ${lib1src} ${lib1} ${lib1opts}] != "" + || [gdb_compile_shlib ${lib2src} ${lib2} ${lib2opts}] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcfile}" ${binfile} executable $exec_opts] != ""} { + return -1 + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + runto_main + + gdb_breakpoint "bar" + + # If the library which will be used is compiled without debugging + # information, GDB will pick the wrong copy of "bar", i.e. the one + # with debugging information. + + if {(${lib1opts} == "" && ${lib2opts} != "" && ${lib1first} == 1) + || (${lib1opts} != "" && ${lib2opts} == "" && ${lib1first} == 0)} { + setup_kfail *-*-* gdb/1824 + } + + gdb_test "continue" "Breakpoint .* bar .*${expected_file}\\..*" \ + "run to breakpoint - $testopts" +} + +foreach lib1opts {{} {debug}} { + foreach lib2opts {{} {debug}} { + foreach lib1first {1 0} { + do_test $lib1opts $lib2opts $lib1first + } + } +} Index: testsuite/gdb.base/weaklib1.c =================================================================== RCS file: testsuite/gdb.base/weaklib1.c diff -N testsuite/gdb.base/weaklib1.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/weaklib1.c 1 Dec 2006 18:10:05 -0000 @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +void __attribute__((weak)) +bar (void) +{ + puts ("bar in u1"); +} Index: testsuite/gdb.base/weaklib2.c =================================================================== RCS file: testsuite/gdb.base/weaklib2.c diff -N testsuite/gdb.base/weaklib2.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/weaklib2.c 1 Dec 2006 18:10:05 -0000 @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +void bar (void); +void +foo (void) +{ + bar (); +} + +void +bar (void) +{ + puts ("bar in u2"); +}