Re: [patch] Smaller gdb: -rdynamic -> -Wl,--dynamic-list

Jan Kratochvil
2010-05-16T18:08:49Z

On Thu, 13 May 2010 15:26:47 +0200, H.J. Lu wrote:
> On Thu, May 13, 2010 at 6:18 AM, Jan Kratochvil <jan.kratochvil@redhat.com> wrote:
> > I hope on the build hosts where -rdynamic was supported even
> > -Wl,--dynamic-list must be supported.
>
> FWIW, --dynamic-list was added in Sept., 2006

Oops, thanks, therefore it now still fallbacks to -rdynamic. It is
reproducible on RHEL-4.8 (+derivations).

> and a bug was fixed in Oct., 2006.

You refer probably to:
[PATCH] Fix --dynamic-list
http://sourceware.org/ml/binutils/2006-10/msg00064.html
commit 5bab058dff8c0ff134868cc6fdcbe6afe58d7ebc
Author: Jakub Jelinek <jakub@redhat.com>
Date: Wed Oct 11 14:58:19 2006 +0000

I have tested this fix on ppc64 and it has no effect on the build with binutils
from that GIT hash. lang_append_dynamic_list gets called only once with all
the symbols at once:
Breakpoint 1, lang_append_dynamic_list (dynamic=0x1020a140) at ldlang.c:6961
6961 if (link_info.dynamic)
(gdb) p *dynamic
$1 = {next = 0x1020a0f0, pattern = 0x1020a120 ".ps_ptwrite", symbol = 0x1020a170 ".ps_ptwrite", symver = 0, script = 0, mask = 1}
(gdb) p *dynamic->next
$2 = {next = 0x1020a080, pattern = 0x1020a0d0 "ps_ptwrite", symbol = 0x1020a0d0 "ps_ptwrite", symver = 0, script = 0, mask = 1}
(gdb) p *dynamic->next->next
$3 = {next = 0x1020a030, pattern = 0x1020a060 ".ps_ptread", symbol = 0x1020a0b0 ".ps_ptread", symver = 0, script = 0, mask = 1}

Tested it on:
OpenSolaris 2009.06 snv_111b X86
gcc (GCC) 3.4.3 (csl-sol210-3_4-20050802)
$ gcc -rdynamic
gcc: unrecognized option `-rdynamic'
$ gcc -Wl,-export-dynamic ...
ld: fatal: entry point symbol `xport-dynamic' is undefined
$ gcc -Wl,--export-dynamic ...
usage: ld [-6:abc:d:e:f:h:il:mo:p:rstu:z:B:CD:F:GI:L:M:N:P:Q:R:S:VW:Y:?] file(s)
$ /usr/sfw/libexec/gcc/i386-pc-solaris2.11/3.4.3/collect2 --version
ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.1652
$ ld --help|grep export-dynamic
GNU ld version 2.15
-E, --export-dynamic Export all dynamic symbols

But no special option is needed for threads debugging there; there also isn't
any one available for the Sun-provided gcc build. I can remove the Solaris
host simplification
* configure.ac (solaris*): Replace -Wl,-export-dynamic by $RDYNAMIC.
if there are any concerns. The patch replaces -Wl,-export-dynamic by -rdynamic.
it could also test -Wl,-export-dynamic as a second fallback after current
-rdynamic. -rdynamic was already used directly in linux .mh config/ files.

I do not have sparc solaris available to test the gdbserver change on solaris.
gdbserver is not supported on x86* solaris.

> > I am not sure with the gdbserver/Makefile.in new CDEPS there. Â I have not
> > found it defined anywhere while it is used as the gdbserver target dependency.

No regressions on {x86_64,x86_64-m32,i686}-fedora12-linux-gnu.

Thanks,
Jan

gdb/
2010-05-16 Jan Kratochvil <jan.kratochvil@redhat.com>

* Makefile.in (RDYNAMIC): New.
(SFILES): Add proc-service.list.
* config/alpha/alpha-linux.mh (NAT_CDEPS): New.
(LOADLIBES): Replace -rdynamic by $(RDYNAMIC).
* config/arm/linux.mh: Likewise.
* config/i386/linux.mh: Likewise.
* config/i386/linux64.mh: Likewise.
* config/ia64/linux.mh: Likewise.
* config/m32r/linux.mh: Likewise.
* config/m68k/linux.mh: Likewise.
* config/mips/linux.mh: Likewise.
* config/pa/linux.mh: Likewise.
* config/powerpc/linux.mh: Likewise.
* config/powerpc/ppc64-linux.mh: Likewise.
* config/s390/s390.mh: Likewise.
* config/sparc/linux.mh: Likewise.
* config/sparc/linux64.mh: Likewise.
* config/xtensa/linux.mh: Likewise.
* configure.ac: New RDYNAMIC on native host and GCC.
(solaris*): Replace -Wl,-export-dynamic by $RDYNAMIC.
* configure: Regenerate.
* proc-service.list: New.

gdb/gdbserver/
2010-05-16 Jan Kratochvil <jan.kratochvil@redhat.com>

* Makefile.in (SFILES): Add $(srcdir)/proc-service.list.
(CDEPS): New.
* configure.ac (RDYNAMIC): New AC_MSG_CHECKING wrapping. Test also
-Wl,--dynamic-list.
* configure: Regenerate.
* proc-service.list: New.

--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -157,6 +157,8 @@ GDB_WERROR_CFLAGS = $(WERROR_CFLAGS)

GDB_WARN_CFLAGS_NO_FORMAT = `echo " $(GDB_WARN_CFLAGS) " | sed "s/ -Wformat-nonliteral / /g"`

+RDYNAMIC = @RDYNAMIC@
+
# Where is the INTL library? Typically in ../intl.
INTL = @LIBINTL@
INTL_DEPS = @LIBINTL_DEP@
@@ -683,7 +685,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
objc-exp.y objc-lang.c \
objfiles.c osabi.c observer.c osdata.c \
p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
- progspace.c \
+ proc-service.list progspace.c \
prologue-value.c psymtab.c \
regcache.c reggroups.c remote.c remote-fileio.c reverse.c \
scm-exp.c scm-lang.c scm-valprint.c \
--- a/gdb/config/alpha/alpha-linux.mh
+++ b/gdb/config/alpha/alpha-linux.mh
@@ -3,10 +3,11 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o corelow.o alpha-linux-nat.o \
fork-child.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)

# doublest.c currently assumes some properties of FP arithmetic
# on the host which require this.
--- a/gdb/config/arm/linux.mh
+++ b/gdb/config/arm/linux.mh
@@ -3,5 +3,6 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES= -ldl -rdynamic
+LOADLIBES= -ldl $(RDYNAMIC)
--- a/gdb/config/i386/linux.mh
+++ b/gdb/config/i386/linux.mh
@@ -5,7 +5,8 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o i386-linux-nat.o \
proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/i386/linux64.mh
+++ b/gdb/config/i386/linux64.mh
@@ -3,7 +3,8 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o amd64-nat.o amd64-linux-nat.o linux-nat.o \
proc-service.o linux-thread-db.o linux-fork.o
NAT_FILE= config/nm-linux.h
+NAT_CDEPS = $(srcdir)/proc-service.list

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/ia64/linux.mh
+++ b/gdb/config/ia64/linux.mh
@@ -4,5 +4,6 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
core-regset.o ia64-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/m32r/linux.mh
+++ b/gdb/config/m32r/linux.mh
@@ -4,5 +4,6 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
m32r-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES= -ldl -rdynamic
+LOADLIBES= -ldl $(RDYNAMIC)
--- a/gdb/config/m68k/linux.mh
+++ b/gdb/config/m68k/linux.mh
@@ -4,7 +4,8 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
corelow.o m68klinux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/mips/linux.mh
+++ b/gdb/config/mips/linux.mh
@@ -3,5 +3,6 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
linux-thread-db.o proc-service.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/pa/linux.mh
+++ b/gdb/config/pa/linux.mh
@@ -3,5 +3,6 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
hppa-linux-nat.o proc-service.o linux-thread-db.o linux-nat.o \
linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/powerpc/linux.mh
+++ b/gdb/config/powerpc/linux.mh
@@ -6,5 +6,6 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
ppc-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/powerpc/ppc64-linux.mh
+++ b/gdb/config/powerpc/ppc64-linux.mh
@@ -6,6 +6,7 @@ NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
ppc-linux-nat.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

# The PowerPC has severe limitations on TOC size, and uses them even
# for non-PIC code. GDB overflows those tables when compiling with
@@ -15,4 +16,4 @@ MH_CFLAGS= -mminimal-toc

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES= -ldl -rdynamic
+LOADLIBES= -ldl $(RDYNAMIC)
--- a/gdb/config/s390/s390.mh
+++ b/gdb/config/s390/s390.mh
@@ -2,4 +2,5 @@
NAT_FILE= config/nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o s390-nat.o \
linux-thread-db.o proc-service.o linux-nat.o linux-fork.o
-LOADLIBES = -ldl -rdynamic
+NAT_CDEPS = $(srcdir)/proc-service.list
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/sparc/linux.mh
+++ b/gdb/config/sparc/linux.mh
@@ -4,7 +4,8 @@ NATDEPFILES= sparc-nat.o sparc-linux-nat.o \
corelow.o core-regset.o fork-child.o inf-ptrace.o \
proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/sparc/linux64.mh
+++ b/gdb/config/sparc/linux64.mh
@@ -5,7 +5,8 @@ NATDEPFILES= sparc-nat.o sparc64-nat.o sparc64-linux-nat.o \
fork-child.o inf-ptrace.o \
proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/config/xtensa/linux.mh
+++ b/gdb/config/xtensa/linux.mh
@@ -4,5 +4,6 @@ NAT_FILE= config/nm-linux.h

NATDEPFILES= inf-ptrace.o fork-child.o xtensa-linux-nat.o \
linux-thread-db.o proc-service.o linux-nat.o linux-fork.o
+NAT_CDEPS = $(srcdir)/proc-service.list

-LOADLIBES = -ldl -rdynamic
+LOADLIBES = -ldl $(RDYNAMIC)
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1312,6 +1312,30 @@ dnl Note that we only want this if we are both native (host == target),
dnl and not doing a canadian cross build (build == host).

if test ${build} = ${host} -a ${host} = ${target} ; then
+ if test "$GCC" = "yes" ; then
+ # The dynamically loaded libthread_db needs access to symbols in the gdb
+ # executable. Older GNU ld supports --export-dynamic but --dynamic-list
+ # may not be supported there.
+ AC_MSG_CHECKING(for the dynamic export flag)
+ old_LDFLAGS="$LDFLAGS"
+ # Older GNU ld supports --export-dynamic but --dynamic-list it does not.
+ RDYNAMIC="-Wl,--dynamic-list=${srcdir}/proc-service.list"
+ LDFLAGS="$LDFLAGS $RDYNAMIC"
+ AC_TRY_LINK([], [],
+ [found="-Wl,--dynamic-list"
+ RDYNAMIC='-Wl,--dynamic-list=$(srcdir)/proc-service.list'],
+ [RDYNAMIC="-rdynamic"
+ LDFLAGS="$old_LDFLAGS $RDYNAMIC"
+ AC_TRY_LINK([], [],
+ [found="-rdynamic"],
+ [found="no"
+ # Error on its usage by .mh file.
+ RDYNAMIC="no-rdynamic-available"])])
+ AC_SUBST(RDYNAMIC)
+ LDFLAGS="$old_LDFLAGS"
+ AC_MSG_RESULT($found)
+ fi
+
case ${host_os} in
hpux*)
AC_MSG_CHECKING(for HPUX/OSF thread support)
@@ -1342,19 +1366,7 @@ if test ${build} = ${host} -a ${host} = ${target} ; then
CONFIG_OBS="${CONFIG_OBS} sol-thread.o"
CONFIG_SRCS="${CONFIG_SRCS} sol-thread.c"
AC_CHECK_LIB(dl, dlopen)
- if test "$GCC" = "yes" ; then
- # The GNU linker requires the -export-dynamic option to make
- # all symbols visible in the dynamic symbol table.
- hold_ldflags=$LDFLAGS
- AC_MSG_CHECKING(for the ld -export-dynamic flag)
- LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
- AC_TRY_LINK(, [int i;], found=yes, found=no)
- LDFLAGS=$hold_ldflags
- AC_MSG_RESULT($found)
- if test $found = yes; then
- CONFIG_LDFLAGS="${CONFIG_LDFLAGS} -Wl,-export-dynamic"
- fi
- fi
+ CONFIG_LDFLAGS="${CONFIG_LDFLAGS} $RDYNAMIC"
# Sun randomly tweaked the prototypes in <proc_service.h>
# at one point.
AC_MSG_CHECKING(if <proc_service.h> is old)
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -100,7 +100,8 @@ INTERNAL_LDFLAGS = $(LDFLAGS) @RDYNAMIC@
# All source files that go into linking GDB remote server.

SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \
- $(srcdir)/mem-break.c $(srcdir)/proc-service.c $(srcdir)/regcache.c \
+ $(srcdir)/mem-break.c $(srcdir)/proc-service.c \
+ $(srcdir)/proc-service.list $(srcdir)/regcache.c \
$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
$(srcdir)/thread-db.c $(srcdir)/utils.c \
$(srcdir)/linux-arm-low.c $(srcdir)/linux-cris-low.c \
@@ -133,6 +134,7 @@ OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
GDBREPLAY_OBS = gdbreplay.o version.o
GDBSERVER_LIBS = @GDBSERVER_LIBS@
XM_CLIBS = @LIBS@
+CDEPS = $(srcdir)/proc-service.list

# XML files to compile in to gdbserver, if any.
XML_DIR = $(srcdir)/../features
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -188,11 +188,24 @@ USE_THREAD_DB=
if test "$srv_linux_thread_db" = "yes"; then
if test "$ac_cv_lib_dl_dlopen" = "yes"; then
srv_libs="-ldl"
+ AC_MSG_CHECKING(for the dynamic export flag)
old_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -rdynamic"
- AC_TRY_LINK([], [], [RDYNAMIC=-rdynamic], [RDYNAMIC=])
+ # Older GNU ld supports --export-dynamic but --dynamic-list may not be
+ # supported there.
+ RDYNAMIC="-Wl,--dynamic-list=${srcdir}/proc-service.list"
+ LDFLAGS="$LDFLAGS $RDYNAMIC"
+ AC_TRY_LINK([], [],
+ [found="-Wl,--dynamic-list"
+ RDYNAMIC='-Wl,--dynamic-list=$(srcdir)/proc-service.list'],
+ [RDYNAMIC="-rdynamic"
+ LDFLAGS="$old_LDFLAGS $RDYNAMIC"
+ AC_TRY_LINK([], [],
+ [found="-rdynamic"],
+ [found="no"
+ RDYNAMIC=""])])
AC_SUBST(RDYNAMIC)
LDFLAGS="$old_LDFLAGS"
+ AC_MSG_RESULT($found)
else
srv_libs="-lthread_db"
fi
--- /dev/null
+++ b/gdb/gdbserver/proc-service.list
@@ -0,0 +1,30 @@
+/* -Wl,--dynamic-list symbols exported for libthread_db.
+
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+{
+ ps_get_thread_area;
+ ps_getpid;
+ ps_lgetfpregs;
+ ps_lgetregs;
+ ps_lsetfpregs;
+ ps_lsetregs;
+ ps_pdread;
+ ps_pdwrite;
+ ps_pglobal_lookup;
+};
--- /dev/null
+++ b/gdb/proc-service.list
@@ -0,0 +1,40 @@
+/* -Wl,--dynamic-list symbols exported for libthread_db.
+
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>. */
+
+{
+ ps_get_thread_area;
+ ps_getpid;
+ ps_lcontinue;
+ ps_lgetfpregs;
+ ps_lgetregs;
+ ps_lgetxregs;
+ ps_lgetxregsize;
+ ps_lsetfpregs;
+ ps_lsetregs;
+ ps_lsetxregs;
+ ps_lstop;
+ ps_pcontinue;
+ ps_pdread;
+ ps_pdwrite;
+ ps_pglobal_lookup;
+ ps_plog;
+ ps_pstop;
+ ps_ptread;
+ ps_ptwrite;
+};