This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug bootstrap/14992] New: --as-needed patch makes -shared-libgcc the default on some systems
- From: "rsandifo at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 17 Apr 2004 15:19:13 -0000
- Subject: [Bug bootstrap/14992] New: --as-needed patch makes -shared-libgcc the default on some systems
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
Summary
-------
The following 3.4 patch:
2004-04-01 Alan Modra <amodra@bigpond.net.au>
Jakub Jelinek <jakub@redhat.com>
* gcc.c (init_gcc_specs): If HAVE_LD_AS_NEEDED, link with
-lgcc --as-needed -lgcc_s --no-as-needed by default.
* configure.ac (HAVE_LD_AS_NEEDED): Check for ld --as-needed.
* configure: Rebuilt.
* config.in: Rebuilt.
* Makefile.in (stage1-start): Copy also libgcc_s*$(SHLIB_EXT).
(stage2-start, stage3-start, stage4-start): Likewise.
(stageprofile-start, stagefeedback-start): Likewise.
effectively makes -shared-libgcc the default for mips-sgi-irix6.5 when
using binutils 2.15. This seems undesirable for its own sake, and breaks
bootstrap unless you take elaborate countermeasures. It also wasn't the
intended effect of the patch.
Although the problem only seems to have been reported for IRIX so far,
I believe it could occur on most hosted, non-glibc ELF systems if
binutils 2.15 is used.
Detail
------
The rationale for the patch can be found here:
http://gcc.gnu.org/ml/gcc-patches/2004-03/msg02210.html
As I understand it, the problem described in the message above can be
solved simply by linking with -shared-libgcc. The purpose of the patch
is to make this extra option unnecessary.
It seems that, on glibc systems, symbols in libgcc_s.so are only
referenced by code that needs to use the EH routines. The default
behaviour can therefore be to link against libgcc_s.so "as needed".
Unfortunately, the patch seems to be very invasive. It changes the
default link line for all targets whose binutils support --as-needed
linking of shared libraries. And not all targets follow the glibc model
wrt EH routines.
An initial posting about the problem can be found here:
http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00855.html
It boils down to target-specific variations in crtbegin.o.
In particular, crtstuff.c contains:
--------------------------------------------------------------------
#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
&& !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
&& defined(__GLIBC__) && __GLIBC__ >= 2
#include <link.h>
# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
# define USE_PT_GNU_EH_FRAME
# endif
#endif
#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
# define USE_EH_FRAME_REGISTRY
#endif
--------------------------------------------------------------------
....
--------------------------------------------------------------------
#ifdef USE_EH_FRAME_REGISTRY
static struct object object;
if (__register_frame_info)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
#endif
--------------------------------------------------------------------
Thus, if a system doesn't satisfy the __GLIBC__ check above, and uses a
.eh_frame section, then crtbegin.o will include a call to the weak function
__register_frame_info. Since this function is provided by libgcc_s.so,
any program linked with crtbegin.o will end up requiring libgcc_s.so
when linked with --as-needed -lgcc_s.
As I said above, this effectively makes --shared-libgcc the default
on IRIX, and probably other ELF systems that don't satisfy the __GLIBC__
check. This is an unannounced (and IMO undesirable) change in behaviour.
It also causes bootstrap problems because LD_LIBRARY_PATH (or whatever)
doesn't typically include the gcc/ and gcc/stage* directories that are
necessary for finding the new libgcc_s.so. Anything built by the stage1
compiler will therefore fail to run.
I'm not sure how much to read into the fact that the problem has only been
reported for IRIX so far. However, I suspect folks probably haven't had
that much opportunity to trip over it. They'll only have noticed if:
(1) They tested a 3.4 snapshot from the last two weeks. (The patch
was only applied at the beginning of April.)
(2) They tested with a recent CVS version of binutils (cvs HEAD since
18th March, or 2.15 branch since 8th April.)
(3) Not only do they test with CVS versions of binutils, but they
build binutils separately from gcc itself. If you use a combined
tree instead, ./configure will look for binutils 2.16 or above,
and not even CVS mainline has a version number that high. The
only way the ./configure check can pass is if you have a
preinstalled linker that supports --as-needed.
As Jakub says here:
http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00857.html:
the proper fix is probably to tighten the check in gcc.c:
---------------------------------------------------------------------
So probably the #if conditional in init_gcc_specs needs to be
#if defined HAVE_LD_AS_NEEDED &&
test_whether_USE_EH_FRAME_REGISTRY_will_not_be_defined
The question is how to find that out, since in crtstuff.c it uses target
headers to find that out, but we don't have such luxury in gcc.c.
Ideas?
---------------------------------------------------------------------
Unfortunately, no-one has yet suggested a viable way of doing this.
FWIW, a band-aid fix for IRIX is:
http://gcc.gnu.org/ml/gcc-patches/2004-04/msg00931.html
However, if I'm not completely overegging the potential fallout,
I wonder if would be better to revert the patch for now, and perhaps
revisit it for 3.4.1?
Richard
--
Summary: --as-needed patch makes -shared-libgcc the default on
some systems
Product: gcc
Version: 3.4.0
Status: UNCONFIRMED
Severity: critical
Priority: P2
Component: bootstrap
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: rsandifo at gcc dot gnu dot org
CC: gcc-bugs at gcc dot gnu dot org,mmitchel at gcc dot gnu
dot org
GCC build triplet: mips-sgi-irix6.5
GCC host triplet: mips-sgi-irix6.5
GCC target triplet: mips-sgi-irix6.5
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992