Improve TLS link test for cross-compiling

View: New views
12 Messages — Rating Filter:   Alert me  

Improve TLS link test for cross-compiling

by Joseph S. Myers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

When cross-compiling, GCC_CHECK_TLS uses a link-time test for TLS
support.  However, code built for an executable, or linked into an
executable, can link OK when libc in fact lacks TLS support, even if
code linked into a shared library would not, because of the different
TLS access models and linker optimizations used in the different
cases.

This patch adds an additional link-time test for linking with -shared
-Wl,--no-undefined in this case: if linking a non-TLS file with those
options succeeds (so, in particular, they are appropriate options for the
target in question), but linking TLS code with them fails, then TLS is not
supported.  Tested with no regressions with cross to i686-pc-linux-gnu
using a sysroot with pre-TLS libc.  OK to commit?

config:
2009-07-02  Joseph Myers  <joseph@...>

        * tls.m4 (GCC_CHECK_TLS): Also test TLS in a shared library when
        cross-compiling.

libgomp:
2009-07-02  Joseph Myers  <joseph@...>

        * configure: Regenerate.

libjava:
2009-07-02  Joseph Myers  <joseph@...>

        * configure: Regenerate.

libmudflap:
2009-07-02  Joseph Myers  <joseph@...>

        * configure: Regenerate.

libstdc++-v3:
2009-07-02  Joseph Myers  <joseph@...>

        * configure: Regenerate.

Index: config/tls.m4
===================================================================
--- config/tls.m4 (revision 149177)
+++ config/tls.m4 (working copy)
@@ -66,7 +66,18 @@
       [dnl This is the cross-compiling case. Assume libc supports TLS if the
        dnl binutils and the compiler do.
        AC_LINK_IFELSE([__thread int a; int b; int main() { return a = b; }],
-      [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no])
+ [chktls_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
+  chktls_save_CFLAGS="$CFLAGS"
+  CFLAGS="-fPIC $CFLAGS"
+  dnl If -shared works, test if TLS works in a shared library.
+  AC_LINK_IFELSE([int f() { return 0; }],
+    AC_LINK_IFELSE([__thread int a; int b; int f() { return a = b; }],
+      [gcc_cv_have_tls=yes],
+      [gcc_cv_have_tls=no]),
+    [gcc_cv_have_tls=yes])
+  CFLAGS="$chktls_save_CFLAGS"
+  LDFLAGS="$chktls_save_LDFLAGS"], [gcc_cv_have_tls=no])
       ]
     )])
   if test "$enable_tls $gcc_cv_have_tls" = "yes yes"; then

--
Joseph S. Myers
joseph@...

Re: Improve TLS link test for cross-compiling

by Andrew Pinski-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 2, 2009 at 12:44 PM, Joseph S. Myers<joseph@...> wrote:

> When cross-compiling, GCC_CHECK_TLS uses a link-time test for TLS
> support.  However, code built for an executable, or linked into an
> executable, can link OK when libc in fact lacks TLS support, even if
> code linked into a shared library would not, because of the different
> TLS access models and linker optimizations used in the different
> cases.
>
> This patch adds an additional link-time test for linking with -shared
> -Wl,--no-undefined in this case: if linking a non-TLS file with those
> options succeeds (so, in particular, they are appropriate options for the
> target in question), but linking TLS code with them fails, then TLS is not
> supported.  Tested with no regressions with cross to i686-pc-linux-gnu
> using a sysroot with pre-TLS libc.  OK to commit?

What about the case when TLS enum is used and -shared does not exist
for the target (I am thinking of darwin or windows)?
Does it check for that case too?

Thanks,
Andrew Pinski

Re: Improve TLS link test for cross-compiling

by Joseph S. Myers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 2 Jul 2009, Andrew Pinski wrote:

> > This patch adds an additional link-time test for linking with -shared
> > -Wl,--no-undefined in this case: if linking a non-TLS file with those
> > options succeeds (so, in particular, they are appropriate options for the
> > target in question), but linking TLS code with them fails, then TLS is not
> > supported.  Tested with no regressions with cross to i686-pc-linux-gnu
> > using a sysroot with pre-TLS libc.  OK to commit?
>
> What about the case when TLS enum is used and -shared does not exist
> for the target (I am thinking of darwin or windows)?
> Does it check for that case too?
If the non-TLS -shared link fails (because -shared does not exist for the
target or --no-undefined is not a valid linker option for the target) then
it will rely on the result of the non-shared link test and report TLS as
available.  The only case changed by the patch is where linking an
executable with TLS succeeds, linking -shared without TLS succeeds, and
linking -shared with TLS fails, in which case TLS will be reported as not
available.  This is similar to the non-cross-compiling check that TLS
works with -static that only applies if a previous non-TLS -static test
passes, because some targets lack -static.

--
Joseph S. Myers
joseph@...

Re: Improve TLS link test for cross-compiling

by Dave Korn-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andrew Pinski wrote:
>  -shared does not exist for [ ... ] windows)?

  It doesn't?  AFAIK it does.  It means "compile a DLL".

    cheers,
      DaveK


Ping Re: Improve TLS link test for cross-compiling

by Joseph S. Myers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ping.  This patch
<http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00139.html> is pending
review.

--
Joseph S. Myers
joseph@...

Re: Ping Re: Improve TLS link test for cross-compiling

by Paolo Bonzini-6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 07/14/2009 05:41 PM, Joseph S. Myers wrote:
> Ping.  This patch
> <http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00139.html>  is pending
> review.

Are there any targets that support TLS but use anything but -shared to
link a shared library, or that do not have -Wl,--no-undefined?  I'm
thinking of Solaris with Sun as and ld especially.

Okay if you conditionalize setting the LDFLAGS on $host being *-*-linux*
(don't know about uclinux?) and require AC_CANONICAL_HOST at the top of
the file.

Paolo

Re: Ping Re: Improve TLS link test for cross-compiling

by Joseph S. Myers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 14 Jul 2009, Paolo Bonzini wrote:

> On 07/14/2009 05:41 PM, Joseph S. Myers wrote:
> > Ping.  This patch
> > <http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00139.html>  is pending
> > review.
>
> Are there any targets that support TLS but use anything but -shared to link a
> shared library, or that do not have -Wl,--no-undefined?  I'm thinking of
> Solaris with Sun as and ld especially.

If -shared -Wl,--no-undefined fails on a target, this patch does not
change the existing result that TLS is treated as available.  It only
changes the result if those options succeed when linking code not using
TLS but fail when linking code using TLS, while linking TLS code without
using those options succeeds.  Any other combination of results for
(linking TLS code without those options, linking non-TLS code with those
options, linking TLS code with those options) should be unaffected.

--
Joseph S. Myers
joseph@...

Re: Ping Re: Improve TLS link test for cross-compiling

by Joseph S. Myers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 14 Jul 2009, Paolo Bonzini wrote:

> On 07/14/2009 05:41 PM, Joseph S. Myers wrote:
> > Ping.  This patch
> > <http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00139.html>  is pending
> > review.
>
> Are there any targets that support TLS but use anything but -shared to link a
> shared library, or that do not have -Wl,--no-undefined?  I'm thinking of
> Solaris with Sun as and ld especially.
>
> Okay if you conditionalize setting the LDFLAGS on $host being *-*-linux*
> (don't know about uclinux?) and require AC_CANONICAL_HOST at the top of the
> file.

I have applied this patch with that condition added.

config:
2009-07-16  Joseph Myers  <joseph@...>

        * tls.m4 (GCC_CHECK_TLS): Also test TLS in a shared library when
        cross-compiling.

libgomp:
2009-07-16  Joseph Myers  <joseph@...>

        * configure: Regenerate.

libjava:
2009-07-16  Joseph Myers  <joseph@...>

        * configure: Regenerate.

libmudflap:
2009-07-16  Joseph Myers  <joseph@...>

        * configure: Regenerate.

libstdc++-v3:
2009-07-16  Joseph Myers  <joseph@...>

        * configure: Regenerate.

Index: config/tls.m4
===================================================================
--- config/tls.m4 (revision 149722)
+++ config/tls.m4 (working copy)
@@ -1,5 +1,6 @@
 dnl Check whether the target supports TLS.
 AC_DEFUN([GCC_CHECK_TLS], [
+  AC_REQUIRE([AC_CANONICAL_HOST])
   GCC_ENABLE(tls, yes, [], [Use thread-local storage])
   AC_CACHE_CHECK([whether the target supports thread-local storage],
  gcc_cv_have_tls, [
@@ -66,7 +67,24 @@
       [dnl This is the cross-compiling case. Assume libc supports TLS if the
        dnl binutils and the compiler do.
        AC_LINK_IFELSE([__thread int a; int b; int main() { return a = b; }],
-      [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no])
+ [chktls_save_LDFLAGS="$LDFLAGS"
+  dnl Shared library options may depend on the host; this check
+  dnl is only known to be needed for GNU/Linux.
+  case $host in
+    *-*-linux*)
+      LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
+      ;;
+  esac
+  chktls_save_CFLAGS="$CFLAGS"
+  CFLAGS="-fPIC $CFLAGS"
+  dnl If -shared works, test if TLS works in a shared library.
+  AC_LINK_IFELSE([int f() { return 0; }],
+    AC_LINK_IFELSE([__thread int a; int b; int f() { return a = b; }],
+      [gcc_cv_have_tls=yes],
+      [gcc_cv_have_tls=no]),
+    [gcc_cv_have_tls=yes])
+  CFLAGS="$chktls_save_CFLAGS"
+  LDFLAGS="$chktls_save_LDFLAGS"], [gcc_cv_have_tls=no])
       ]
     )])
   if test "$enable_tls $gcc_cv_have_tls" = "yes yes"; then

--
Joseph S. Myers
joseph@...

Re: Ping Re: Improve TLS link test for cross-compiling

by H.J. Lu-30 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 16, 2009 at 4:19 PM, Joseph S. Myers<joseph@...> wrote:

> On Tue, 14 Jul 2009, Paolo Bonzini wrote:
>
>> On 07/14/2009 05:41 PM, Joseph S. Myers wrote:
>> > Ping.  This patch
>> > <http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00139.html>  is pending
>> > review.
>>
>> Are there any targets that support TLS but use anything but -shared to link a
>> shared library, or that do not have -Wl,--no-undefined?  I'm thinking of
>> Solaris with Sun as and ld especially.
>>
>> Okay if you conditionalize setting the LDFLAGS on $host being *-*-linux*
>> (don't know about uclinux?) and require AC_CANONICAL_HOST at the top of the
>> file.
>
> I have applied this patch with that condition added.
>
> config:
> 2009-07-16  Joseph Myers  <joseph@...>
>
>        * tls.m4 (GCC_CHECK_TLS): Also test TLS in a shared library when
>        cross-compiling.
>
> libgomp:
> 2009-07-16  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>
> libjava:
> 2009-07-16  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>
> libmudflap:
> 2009-07-16  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>
> libstdc++-v3:
> 2009-07-16  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>

I got

[hjl@gnu-6 libstdc++-v3]$ autoconf-2.59
configure.ac:178: warning: GCC_NO_EXECUTABLES invoked multiple times
/export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:2213:
AC_LINK_IFELSE is expanded from...
/export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:2271:
AC_RUN_IFELSE is expanded from...
/export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:1792:
AC_CACHE_VAL is expanded from...
/export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:1805:
AC_CACHE_CHECK is expanded from...
../config/tls.m4:2: GCC_CHECK_TLS is expanded from...
configure.ac:178: the top level
configure.ac:247: warning: GCC_NO_EXECUTABLES invoked multiple times
crossconfig.m4:5: GLIBCXX_CROSSCONFIG is expanded from...
configure.ac:247: the top level
[hjl@gnu-6 libstdc++-v3]$

in libstdc++-v3. Did you see it?

Thanks.


--
H.J.

Re: Improve TLS link test for cross-compiling

by H.J. Lu-30 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 2, 2009 at 12:44 PM, Joseph S. Myers<joseph@...> wrote:

> When cross-compiling, GCC_CHECK_TLS uses a link-time test for TLS
> support.  However, code built for an executable, or linked into an
> executable, can link OK when libc in fact lacks TLS support, even if
> code linked into a shared library would not, because of the different
> TLS access models and linker optimizations used in the different
> cases.
>
> This patch adds an additional link-time test for linking with -shared
> -Wl,--no-undefined in this case: if linking a non-TLS file with those
> options succeeds (so, in particular, they are appropriate options for the
> target in question), but linking TLS code with them fails, then TLS is not
> supported.  Tested with no regressions with cross to i686-pc-linux-gnu
> using a sysroot with pre-TLS libc.  OK to commit?
>
> config:
> 2009-07-02  Joseph Myers  <joseph@...>
>
>        * tls.m4 (GCC_CHECK_TLS): Also test TLS in a shared library when
>        cross-compiling.
>
> libgomp:
> 2009-07-02  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>
> libjava:
> 2009-07-02  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>
> libmudflap:
> 2009-07-02  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>
> libstdc++-v3:
> 2009-07-02  Joseph Myers  <joseph@...>
>
>        * configure: Regenerate.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40784


--
H.J.

Re: Ping Re: Improve TLS link test for cross-compiling

by Joseph S. Myers :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, 17 Jul 2009, H.J. Lu wrote:

> [hjl@gnu-6 libstdc++-v3]$ autoconf-2.59
> configure.ac:178: warning: GCC_NO_EXECUTABLES invoked multiple times
> /export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:2213:
> AC_LINK_IFELSE is expanded from...
> /export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:2271:
> AC_RUN_IFELSE is expanded from...
> /export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:1792:
> AC_CACHE_VAL is expanded from...
> /export/redhat/rpms/BUILD/autoconf-2.59/tests/../lib/autoconf/general.m4:1805:
> AC_CACHE_CHECK is expanded from...
> ../config/tls.m4:2: GCC_CHECK_TLS is expanded from...
> configure.ac:178: the top level
> configure.ac:247: warning: GCC_NO_EXECUTABLES invoked multiple times
> crossconfig.m4:5: GLIBCXX_CROSSCONFIG is expanded from...
> configure.ac:247: the top level
> [hjl@gnu-6 libstdc++-v3]$
>
> in libstdc++-v3. Did you see it?

This appears to be describing a condition (GCC_NO_EXECUTABLES called under
various possible conditions, via GCC_CHECK_TLS being called under those
conditions) that is neither new after my patch, nor in any way a problem,
so I'm not sure of the point of this warning or why my patch should have
caused it.  I have however applied this followup patch to fix a quoting
issue in my patch that perturbs things sufficiently to avoid this warning,
although I do not believe the pre-existing code in this macro is correctly
quoted either (I'd expect the static linking call of AC_RUN_IFELSE to need
to be quoted as an argument to AC_LINK_IFELSE).

Index: libstdc++-v3/configure
===================================================================
--- libstdc++-v3/configure (revision 149747)
+++ libstdc++-v3/configure (working copy)
@@ -40770,8 +40770,8 @@
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   if test x$gcc_no_link = xyes; then
-  { { echo "$as_me:$LINENO: error: Link tests are not allowed after ." >&5
-echo "$as_me: error: Link tests are not allowed after ." >&2;}
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
    { (exit 1); exit 1; }; }
 fi
 cat >conftest.$ac_ext <<_ACEOF
@@ -94505,8 +94505,8 @@
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   if test x$gcc_no_link = xyes; then
-  { { echo "$as_me:$LINENO: error: Link tests are not allowed after ." >&5
-echo "$as_me: error: Link tests are not allowed after ." >&2;}
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
    { (exit 1); exit 1; }; }
 fi
 cat >conftest.$ac_ext <<_ACEOF
@@ -112207,8 +112207,8 @@
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   if test x$gcc_no_link = xyes; then
-  { { echo "$as_me:$LINENO: error: Link tests are not allowed after ." >&5
-echo "$as_me: error: Link tests are not allowed after ." >&2;}
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
    { (exit 1); exit 1; }; }
 fi
 cat >conftest.$ac_ext <<_ACEOF
Index: libstdc++-v3/ChangeLog
===================================================================
--- libstdc++-v3/ChangeLog (revision 149747)
+++ libstdc++-v3/ChangeLog (working copy)
@@ -1,3 +1,8 @@
+2009-07-17  Joseph Myers  <joseph@...>
+
+ PR other/40784
+ * configure: Regenerate.
+
 2009-07-16  Benjamin Kosnik  <bkoz@...>
 
  * testsuite/util/testsuite_common_types.h (standard_layout): Activate.
Index: config/ChangeLog
===================================================================
--- config/ChangeLog (revision 149747)
+++ config/ChangeLog (working copy)
@@ -1,3 +1,9 @@
+2009-07-17  Joseph Myers  <joseph@...>
+
+ PR other/40784
+ * tls.m4 (GCC_CHECK_TLS): Add extra quoting around argument to
+ AC_LINK_IFELSE.
+
 2009-07-16  Joseph Myers  <joseph@...>
 
  * tls.m4 (GCC_CHECK_TLS): Also test TLS in a shared library when
Index: config/tls.m4
===================================================================
--- config/tls.m4 (revision 149747)
+++ config/tls.m4 (working copy)
@@ -79,9 +79,9 @@
   CFLAGS="-fPIC $CFLAGS"
   dnl If -shared works, test if TLS works in a shared library.
   AC_LINK_IFELSE([int f() { return 0; }],
-    AC_LINK_IFELSE([__thread int a; int b; int f() { return a = b; }],
+    [AC_LINK_IFELSE([__thread int a; int b; int f() { return a = b; }],
       [gcc_cv_have_tls=yes],
-      [gcc_cv_have_tls=no]),
+      [gcc_cv_have_tls=no])],
     [gcc_cv_have_tls=yes])
   CFLAGS="$chktls_save_CFLAGS"
   LDFLAGS="$chktls_save_LDFLAGS"], [gcc_cv_have_tls=no])
Index: libjava/ChangeLog
===================================================================
--- libjava/ChangeLog (revision 149747)
+++ libjava/ChangeLog (working copy)
@@ -1,3 +1,8 @@
+2009-07-17  Joseph Myers  <joseph@...>
+
+ PR other/40784
+ * configure: Regenerate.
+
 2009-07-16  Joseph Myers  <joseph@...>
 
  * configure: Regenerate.
Index: libjava/configure
===================================================================
--- libjava/configure (revision 149747)
+++ libjava/configure (working copy)
@@ -27702,8 +27702,8 @@
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   if test x$gcc_no_link = xyes; then
-  { { echo "$as_me:$LINENO: error: Link tests are not allowed after ." >&5
-echo "$as_me: error: Link tests are not allowed after ." >&2;}
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
    { (exit 1); exit 1; }; }
 fi
 cat >conftest.$ac_ext <<_ACEOF

--
Joseph S. Myers
joseph@...

Re: Ping Re: Improve TLS link test for cross-compiling

by Paolo Bonzini-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> This appears to be describing a condition (GCC_NO_EXECUTABLES called under
> various possible conditions, via GCC_CHECK_TLS being called under those
> conditions) that is neither new after my patch, nor in any way a problem,
> so I'm not sure of the point of this warning or why my patch should have
> caused it.  I have however applied this followup patch to fix a quoting
> issue in my patch that perturbs things sufficiently to avoid this warning,
> although I do not believe the pre-existing code in this macro is correctly
> quoted either (I'd expect the static linking call of AC_RUN_IFELSE to need
> to be quoted as an argument to AC_LINK_IFELSE).

Yes.

Paolo