Bug 47390

Summary: [4.6 Regression] Linking with -export-dynamic broken
Product: gcc Reporter: Ryan Hill <rhill>
Component: driverAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: jsm28, rwild, zsojka
Priority: P2    
Version: 4.6.0   
Target Milestone: 4.6.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-01-21 11:07:28

Description Ryan Hill 2011-01-21 04:38:15 UTC
When building gawk, -export-dynamic is added to LDFLAGS.  It seems current trunk treats options starting with "-e" differently that previous versions.  With 4.6 I get:

x86_64-unknown-linux-gnu-gcc  -O2 -march=native -g -pipe  -export-dynamic -o gawk array.o awkgram.o builtin.o dfa.o ext.o field.o floatcomp.o gawkmisc.o getopt.o getopt1.o io.o main.o msg.o node.o random.o re.o regex.o replace.o version.o eval.o profile.o    -ldl -lm -lm

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0-pre9999/../../../../x86_64-unknown-linux-gnu/bin/ld: warning: cannot find entry symbol xport-dynamic; defaulting to 00000000004034c0

This leads to a broken gawk:

$ gawk -V
(null): fatal: spec_setup: cp: can't allocate 2109862218 bytes of memory (Success)

It could be that this is intentional and something like -Wl,-export-dynamic should be used, but this mail indicates differently:

  http://osdir.com/ml/bug-gnu-utils-gnu/2010-10/msg00002.html

If it is intentional, it should be documented in release notes so we have something to point upstreams at.


$ gcc-4.6.0-pre9999 -v
Using built-in specs.
COLLECT_GCC=gcc-4.6.0-pre9999
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0-pre9999/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-4.6.0_pre9999/work/gcc-4.6.0-9999/configure --prefix=/usr --bindir=/usr/x86_64-unknown-linux-gnu/gcc-bin/4.6.0-pre9999 --includedir=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0-pre9999/include --datadir=/usr/share/gcc-data/x86_64-unknown-linux-gnu/4.6.0-pre9999 --mandir=/usr/share/gcc-data/x86_64-unknown-linux-gnu/4.6.0-pre9999/man --infodir=/usr/share/gcc-data/x86_64-unknown-linux-gnu/4.6.0-pre9999/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0-pre9999/include/g++-v4 --host=x86_64-unknown-linux-gnu --build=x86_64-unknown-linux-gnu --disable-altivec --disable-fixed-point --with-ppl --with-cloog --disable-ppl-version-check --with-cloog-include=/usr/include/cloog-ppl --enable-lto --disable-nls --with-system-zlib --disable-werror --enable-secureplt --enable-multilib --disable-libmudflap --disable-libssp --enable-libgomp --enable-cld --with-python-dir=/share/gcc-data/x86_64-unknown-linux-gnu/4.6.0-pre9999/python --enable-checking=release --disable-libgcj --enable-languages=c,c++,go --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --with-bugurl=http://bugs.gentoo.org/ --with-pkgversion='Gentoo SVN'
Thread model: posix
gcc version 4.6.0-pre9999 20110121 (experimental) rev. 169076 (Gentoo SVN)

$ ld -v
GNU ld (GNU Binutils) 2.21
Comment 1 Richard Biener 2011-01-21 11:07:28 UTC
-export-dynamic is a linker option, you have to use -Wl,-export-dynamic to
pass it to the linker via the gcc driver.

Joseph - 4.5 handled -export-dynamic by passing it through to the linker
(not exactly sure why).  Can we restore this behavior to avoid regressions?
If not, can we diagnose this invalid option then?  It seems to be passed
as -e xport-dynamic to the linker now, resulting in an undefined symbol
for me with a trivial hello-world.

Currently neither behavior seems to be documented btw.
Comment 2 jsm-csl@polyomino.org.uk 2011-01-24 23:37:39 UTC
On Fri, 21 Jan 2011, rguenth at gcc dot gnu.org wrote:

> Joseph - 4.5 handled -export-dynamic by passing it through to the linker
> (not exactly sure why).  Can we restore this behavior to avoid regressions?
> If not, can we diagnose this invalid option then?  It seems to be passed
> as -e xport-dynamic to the linker now, resulting in an undefined symbol
> for me with a trivial hello-world.

-export-dynamic was passed down by an accident of %{e*} in 
LINK_COMMAND_SPEC.  If you want this to continue to work then add

export-dynamic
Driver

to common.opt, and probably put a comment on LINK_COMMAND_SPEC saying that 
%{e*} deliberately covers -export-dynamic.  (Alternatively, I think using 
%{export-dynamic} %{e}, together with the common.opt change, will make the 
passed options explicit, and successfully pass to the linker (in separate 
argument form) -e options passed to the driver in either joined or 
separate form - but verify this before making that change.)
Comment 3 Ryan Hill 2011-02-08 01:23:27 UTC
looks like some packages also use --export-dynamic, which just flat out fails now. 

x86_64-unknown-linux-gnu-gcc: error: unrecognized option '--export-dynamic'
Comment 4 jsm-csl@polyomino.org.uk 2011-02-08 01:35:49 UTC
On Tue, 8 Feb 2011, dirtyepic at gentoo dot org wrote:

> looks like some packages also use --export-dynamic, which just flat out fails
> now. 
> 
> x86_64-unknown-linux-gnu-gcc: error: unrecognized option '--export-dynamic'

As discussed in PR 46410, the -- versions of linker options were in fact 
quietly ignored before on link-only command lines, or produced errors on 
command lines that would actually have resulted in compilation, so 
--export-dynamic would never have had the intended effect.
Comment 5 Ryan Hill 2011-02-08 02:15:13 UTC
okay, i'll let the upstreams of these packages know.
Comment 6 Richard Biener 2011-02-08 14:36:34 UTC
(In reply to comment #2)
> On Fri, 21 Jan 2011, rguenth at gcc dot gnu.org wrote:
> 
> > Joseph - 4.5 handled -export-dynamic by passing it through to the linker
> > (not exactly sure why).  Can we restore this behavior to avoid regressions?
> > If not, can we diagnose this invalid option then?  It seems to be passed
> > as -e xport-dynamic to the linker now, resulting in an undefined symbol
> > for me with a trivial hello-world.
> 
> -export-dynamic was passed down by an accident of %{e*} in 
> LINK_COMMAND_SPEC.  If you want this to continue to work then add
> 
> export-dynamic
> Driver
> 
> to common.opt, and probably put a comment on LINK_COMMAND_SPEC saying that 
> %{e*} deliberately covers -export-dynamic.  (Alternatively, I think using 
> %{export-dynamic} %{e}, together with the common.opt change, will make the 
> passed options explicit, and successfully pass to the linker (in separate 
> argument form) -e options passed to the driver in either joined or 
> separate form - but verify this before making that change.)

Hm, I see.  The -e LINK_COMMAND_SPEC isn't documented in invoke.texi
"Link Options", do we generally not do this?  It seems to be a spec that
is always enabled.

We document -rdynamic as the way to pass down -export-dynamic, so if
the -e handling is on-purpose ...

Can we force -e options to be passed down in their original joined/non-joined form?  At least for GNU ld -e xport-dynamic is not equal to -export-dynamic,
that a %{e*} spec exchanges a working pass-down variant for an unworking
is unfortunate(?)  We can't seem to easily exclude export-dynamic from
e* as to reject it either.

The situation seems to be a bit weird.  Probably a note in the changes.html
Caveats section regarding the stricter option handling is due.
Comment 7 jsm-csl@polyomino.org.uk 2011-02-08 16:54:19 UTC
On Tue, 8 Feb 2011, rguenth at gcc dot gnu.org wrote:

> Hm, I see.  The -e LINK_COMMAND_SPEC isn't documented in invoke.texi
> "Link Options", do we generally not do this?  It seems to be a spec that
> is always enabled.

What's documented is pretty random - there are lots of undocumented 
options in specs.

> Can we force -e options to be passed down in their original joined/non-joined
> form?  At least for GNU ld -e xport-dynamic is not equal to -export-dynamic,
> that a %{e*} spec exchanges a working pass-down variant for an unworking
> is unfortunate(?)  We can't seem to easily exclude export-dynamic from
> e* as to reject it either.

You can force joined form by adding code like the OPT_L handling
    case OPT_L:
      /* Similarly, canonicalize -L for linkers that may not accept
         separate arguments.  */
      save_switch (concat ("-L", arg, NULL), 0, NULL, validated);
      return true;

although the explicit export-dynamic entry in common.opt for backwards 
compatibility would seem better to me.
Comment 8 Joseph S. Myers 2011-02-17 18:35:44 UTC
Author: jsm28
Date: Thu Feb 17 18:35:41 2011
New Revision: 170253

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170253
Log:
	PR driver/47390
	* common.opt (export-dynamic): New Driver option.
	* gcc.c (LINK_COMMAND_SPEC): Add comment about %{e*}.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/common.opt
    trunk/gcc/gcc.c
Comment 9 Joseph S. Myers 2011-02-17 18:38:18 UTC
Fixed for 4.6, though I advise using -rdynamic or -Wl,-export-dynamic instead of this backwards-compatibility support for a previous accident of the implementation.