This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix linking C executables/shared libraries which use __attribute__((cleanup ()))
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Alan Modra <amodra at bigpond dot net dot au>
- Cc: mark at codesourcery dot com, Gabriel Dos Reis <gdr at integrable-solutions dot net>, gcc-patches at gcc dot gnu dot org
- Date: Sat, 27 Mar 2004 14:50:02 +0100
- Subject: [PATCH] Fix linking C executables/shared libraries which use __attribute__((cleanup ()))
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Alan recently implemented support for conditional linking of shared
libraries. The follwoing patch is the GCC side of the needed changes.
Without it for example gcc 3.4+ compiled NPTL C programs using
pthread_cleanup_{push,pop} will not handle cancellation properly.
This patch just changes the default behaviour, when neither -static-libgcc
nor -shared-libgcc is specified. The program or shared library will be
linked against libgcc_s if EH is used and just against libgcc.a if not.
Ok to commit?
For 3.4/3.3 as well (bootstrapped/regtested in 3.4 on x86_64-redhat-linux
so far)?
2004-03-27 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.
--- gcc/gcc.c.jj 2004-03-08 18:49:01.000000000 +0100
+++ gcc/gcc.c 2004-03-27 10:20:10.651163833 +0100
@@ -1531,6 +1531,12 @@ init_gcc_specs (struct obstack *obstack,
buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
"}%{!static:%{!static-libgcc:",
+#ifdef HAVE_LD_AS_NEEDED
+ "%{!shared-libgcc:", static_name,
+ " --as-needed ", shared_name, " --no-as-needed}"
+ "%{shared-libgcc:", shared_name, "%{!shared: ", static_name,
+ "}",
+#else
"%{!shared:%{!shared-libgcc:", static_name, " ",
eh_name, "}%{shared-libgcc:", shared_name, " ",
static_name, "}}%{shared:",
@@ -1540,6 +1546,7 @@ init_gcc_specs (struct obstack *obstack,
#else
shared_name,
#endif
+#endif
"}}}", NULL);
obstack_grow (obstack, buf, strlen (buf));
--- gcc/configure.ac.jj 2004-03-08 18:49:00.000000000 +0100
+++ gcc/configure.ac 2004-03-27 09:53:42.912708012 +0100
@@ -2627,6 +2627,25 @@ if test x"$gcc_cv_ld_pie" = xyes; then
fi
AC_MSG_RESULT($gcc_cv_ld_pie)
+AC_MSG_CHECKING(linker --as-needed support)
+gcc_cv_ld_as_needed=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_as_needed=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --as-needed and --no-as-needed options
+ if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; then
+ gcc_cv_ld_as_needed=yes
+ fi
+fi
+if test x"$gcc_cv_ld_as_needed" = xyes; then
+ AC_DEFINE(HAVE_LD_AS_NEEDED, 1,
+[Define if your linker supports --as-needed and --no-as-needed options.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_as_needed)
+
if test x$with_sysroot = x && test x$host = x$target \
&& test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
--- gcc/configure.jj 2004-03-16 16:24:42.000000000 +0100
+++ gcc/configure 2004-03-27 09:56:51.886841295 +0100
@@ -11311,6 +11311,30 @@ fi
echo "$as_me:$LINENO: result: $gcc_cv_ld_pie" >&5
echo "${ECHO_T}$gcc_cv_ld_pie" >&6
+echo "$as_me:$LINENO: checking linker --as-needed support" >&5
+echo $ECHO_N "checking linker --as-needed support... $ECHO_C" >&6
+gcc_cv_ld_as_needed=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_as_needed=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --as-needed and --no-as-needed options
+ if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; then
+ gcc_cv_ld_as_needed=yes
+ fi
+fi
+if test x"$gcc_cv_ld_as_needed" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LD_AS_NEEDED 1
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_as_needed" >&5
+echo "${ECHO_T}$gcc_cv_ld_as_needed" >&6
+
if test x$with_sysroot = x && test x$host = x$target \
&& test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
--- gcc/config.in.jj 2004-03-16 16:24:41.000000000 +0100
+++ gcc/config.in 2004-03-27 09:55:54.922050155 +0100
@@ -306,6 +306,9 @@
/* Define to 1 if you have the <ldfcn.h> header file. */
#undef HAVE_LDFCN_H
+/* Define if your linker supports --as-needed and --no-as-needed options. */
+#undef HAVE_LD_AS_NEEDED
+
/* Define if your linker supports --eh-frame-hdr option. */
#undef HAVE_LD_EH_FRAME_HDR
Jakub