[gcc(refs/users/iains/heads/darwin-gcc-8-3r0)] [darwin, emutls] Make emutls into a crt

Iain D Sandoe iains@gcc.gnu.org
Mon Jan 13 20:17:00 GMT 2020


https://gcc.gnu.org/g:ca38d45223e717fe8b700bf5c536cff10ffad46f

commit ca38d45223e717fe8b700bf5c536cff10ffad46f
Author: Iain Sandoe <iain@codesourcery.com>
Date:   Wed Dec 12 16:50:46 2018 +0000

    [darwin, emutls] Make emutls into a crt
    
    EMUTLS requires a single implementation of the handling of thread-local data
    (per exe).  So the obvious solution is to make the symbols for this
    "dynamic lookup" and provide them in the main executable.
    
    However, we might want to build a shared library that could (perhaps) be used
    with an older GCC (or clang) and thus that isn't sufficient.
    
    This version
     * build two crts, one with the symbols "weak".
     * The weak version is linked into shared libraries and bundles.
     * The non-weak version is used in main exes.
    
    Therefore, when a shared library is used "stand-alone" without a GCC-linked exe
    the handling for the shlib will be local (dyld will pick one of the weak instances
    it finds, in the absence of a non-weak).
    
    For this to work, the weak symbols have to be externally-visible on the shared libs.
    Thus we have to add them to the libstdc++ list and ensure that they are not made
    private.
    
    Make the weak version into a convenience lib, so that we don’t end up with a copy in every dylib.

Diff:
---
 gcc/config/darwin.h                                |  2 ++
 libgcc/Makefile.in                                 | 11 +++++++----
 libgcc/config.host                                 |  2 +-
 libgcc/config/t-darwin                             | 15 +++++++++++++++
 libgcc/emutls.c                                    | 12 ++++++++++--
 libstdc++-v3/config/os/bsd/darwin/emutls-extra.ver |  5 +++++
 libstdc++-v3/configure.host                        |  4 ++++
 libstdc++-v3/src/Makefile.am                       | 11 ++++++++++-
 libstdc++-v3/src/Makefile.in                       | 11 ++++++++++-
 libstdc++-v3/src/filesystem/Makefile.in            |  2 +-
 10 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index edf9435..95f04ad 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -194,6 +194,8 @@ extern GTY(()) int darwin_ms_struct;
       %{%:sanitize(undefined): -lubsan } \
       %(link_ssp) \
       " DARWIN_EXPORT_DYNAMIC " %<rdynamic \
+      %{Zdynamiclib|Zbundle: -lemutls_w } \
+      %{!Zdynamiclib:%{!Zbundle: -lemutls_s.o }} \
       %(link_gcc_c_sequence) \
     }}\
     %{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index dd8cee9..560f10c 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -343,6 +343,9 @@ LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
 LIB2ADDEHSTATIC = $(LIB2ADDEH)
 LIB2ADDEHSHARED = $(LIB2ADDEH)
 
+# Additional source for emulated TLS, can be overridden by target.
+LIB2EMUTLS = $(srcdir)/emutls.c
+
 # nm flags to list global symbols in libgcc object files.
 SHLIB_NM_FLAGS = -pg
 
@@ -427,10 +430,10 @@ LIB2ADD += enable-execute-stack.c
 
 # While emutls.c has nothing to do with EH, it is in LIB2ADDEH*
 # instead of LIB2ADD because that's the way to be sure on some targets
-# (e.g. *-*-darwin*) only one copy of it is linked.
-LIB2ADDEH += $(srcdir)/emutls.c
-LIB2ADDEHSTATIC += $(srcdir)/emutls.c
-LIB2ADDEHSHARED += $(srcdir)/emutls.c
+# only one copy of it is linked.
+LIB2ADDEH += $(LIB2EMUTLS)
+LIB2ADDEHSTATIC += $(LIB2EMUTLS)
+LIB2ADDEHSHARED += $(LIB2EMUTLS)
 
 # Library members defined in libgcc2.c.
 lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
diff --git a/libgcc/config.host b/libgcc/config.host
index 451fd62..327e02c 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -205,7 +205,7 @@ case ${host} in
 *-*-darwin*)
   asm_hidden_op=.private_extern
   tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic"
-  extra_parts="crt3.o d10-uwfef.o crttms.o crttme.o"
+  extra_parts="crt3.o d10-uwfef.o crttms.o crttme.o libemutls_w.a emutls_s.o"
   if test "${slibdir}" = "/usr/lib"; then
     # If we're building to install libgcc_s into the system, then proceed to make a
     # libgcc_s and the 10.5/10.5 stubs.
diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin
index 8340ea2..6b215dc 100644
--- a/libgcc/config/t-darwin
+++ b/libgcc/config/t-darwin
@@ -21,6 +21,21 @@ HOST_LIBGCC2_CFLAGS += -pipe
 LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/config/unwind-dw2-fde-darwin.c \
   $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
 
+LIB2EMUTLS =
+
+# Make a weak version for linking into shared libs
+emutls_w.o: $(srcdir)/emutls.c libgcc_tm.h
+	$(gcc_compile) -DEMUTLS_ATTR='__attribute__((__weak__))' -c $<
+
+# Make it a convenience lib so that it can be linked optionally into DSOs.
+libemutls_w.a: emutls_w.o
+	$(AR_CREATE_FOR_TARGET) $@ $<
+	$(RANLIB_FOR_TARGET) $@
+
+# Make a no-dead-strip version for linking into exes.
+emutls_s.o: $(srcdir)/emutls.c libgcc_tm.h
+	$(gcc_compile) -DEMUTLS_ATTR='__attribute__((__used__))' -c $<
+
 # Patch to __Unwind_Find_Enclosing_Function for Darwin10.
 d10-uwfef.o: $(srcdir)/config/darwin10-unwind-find-enc-func.c
 	$(crt_compile) $(DARWIN_EXTRA_CRT_BUILD_CFLAGS) -mmacosx-version-min=10.6 -c $<
diff --git a/libgcc/emutls.c b/libgcc/emutls.c
index e70cf2b..3d42817 100644
--- a/libgcc/emutls.c
+++ b/libgcc/emutls.c
@@ -50,8 +50,16 @@ struct __emutls_array
   void **data[];
 };
 
-void *__emutls_get_address (struct __emutls_object *);
-void __emutls_register_common (struct __emutls_object *, word, word, void *);
+/* EMUTLS_ATTR is provided to allow targets to build the emulated tls
+   routines as weak functions for inclusion in dynamic libraries.  If
+   there is no definition, fall back to the default.  */
+#ifndef EMUTLS_ATTR
+#  define EMUTLS_ATTR
+#endif
+
+void *__emutls_get_address (struct __emutls_object *) EMUTLS_ATTR;
+void __emutls_register_common (struct __emutls_object *,
+			       word, word, void *) EMUTLS_ATTR;
 
 #ifdef __GTHREADS
 #ifdef __GTHREAD_MUTEX_INIT
diff --git a/libstdc++-v3/config/os/bsd/darwin/emutls-extra.ver b/libstdc++-v3/config/os/bsd/darwin/emutls-extra.ver
new file mode 100644
index 0000000..f542ecd
--- /dev/null
+++ b/libstdc++-v3/config/os/bsd/darwin/emutls-extra.ver
@@ -0,0 +1,5 @@
+CXXEMUTLS_DARWIN_1.0.0 {
+  global:
+  __emutls_get_address;
+  __emutls_register_common;
+};
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index 155a3cd..b47a1a1 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -368,6 +368,10 @@ case "${host}" in
      ;;
   powerpc*-*-darwin*)
     port_specific_symbol_files="\$(srcdir)/../config/os/bsd/darwin/ppc-extra.ver"
+    port_specific_symbol_files="${port_specific_symbol_files} \$(srcdir)/../config/os/bsd/darwin/emutls-extra.ver"
+    ;;
+  *darwin*)
+    port_specific_symbol_files="\$(srcdir)/../config/os/bsd/darwin/emutls-extra.ver"
     ;;
   *-*-solaris2.1[0-9])
     # On Solaris 10 with Solaris ld, there's no COMDAT support.  GNU ld always
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index ba30dde..f4d32a1 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -268,14 +268,23 @@ endif
 if ENABLE_SYMVERS_DARWIN
 version_arg = -Wl,-exported_symbols_list,libstdc++-symbols.explist
 version_dep = libstdc++-symbols.explist
+# When building a shared object on Darwin, the support for emulated tls will
+# be included as a weak implementation (with the non-weak provided by the main
+# exe when that is provided by an appropriate version of GCC).
+# We must include the weak symbols in the export list, otherwise they will get
+# hidden and emutls will then fail at runtime since dyld won't see them.
+# To do this, we build a dummy empty shared lib and include that in the list
+# to be scanned; We also make sure that we're looking only at externs.
 libstdc++-symbols.explist : libstdc++-symbols.ver \
 		${glibcxx_srcdir}/scripts/make_exports.pl \
 		$(libstdc___la_OBJECTS) $(libstdc___la_LIBADD)
+	echo " .text" | $(CXXCOMPILE) -shared -x assembler - -o temp.dylib -Wl,-all_load
+	NM_FOR_TARGET = "$(NM_FOR_TARGET) -g" \
 	perl ${glibcxx_srcdir}/scripts/make_exports.pl \
 	  libstdc++-symbols.ver \
 	  $(libstdc___la_OBJECTS:%.lo=.libs/%.o) \
 	 `echo $(libstdc___la_LIBADD) | \
-	    sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
+	    sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` temp.dylib \
 	 > $@ || (rm -f $@ ; exit 1)
 endif
 
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index f0ec7bc..536c22a 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -965,14 +965,23 @@ compatibility-condvar.o: compatibility-condvar.cc
 @ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@	 `echo $(libstdc___la_LIBADD) | \
 @ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@	    sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
 @ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@	 > $@ || (rm -f $@ ; exit 1)
+# When building a shared object on Darwin, the support for emulated tls will
+# be included as a weak implementation (with the non-weak provided by the main
+# exe when that is provided by an appropriate version of GCC).
+# We must include the weak symbols in the export list, otherwise they will get
+# hidden and emutls will then fail at runtime since dyld won't see them.
+# To do this, we build a dummy empty shared lib and include that in the list
+# to be scanned; We also make sure that we're looking only at externs.
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@libstdc++-symbols.explist : libstdc++-symbols.ver \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@		${glibcxx_srcdir}/scripts/make_exports.pl \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@		$(libstdc___la_OBJECTS) $(libstdc___la_LIBADD)
+@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	echo " .text " | $(CXXCOMPILE) -shared -x assembler - -o temp.dylib -Wl,-all_load
+@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	NM_FOR_TARGET="$(NM_FOR_TARGET) -g" \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	perl ${glibcxx_srcdir}/scripts/make_exports.pl \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	  libstdc++-symbols.ver \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	  $(libstdc___la_OBJECTS:%.lo=.libs/%.o) \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	 `echo $(libstdc___la_LIBADD) | \
-@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	    sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
+@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	    sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` temp.dylib \
 @ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@	 > $@ || (rm -f $@ ; exit 1)
 
 # Control additional build primary rules.
diff --git a/libstdc++-v3/src/filesystem/Makefile.in b/libstdc++-v3/src/filesystem/Makefile.in
index 0b43889..ddca014 100644
--- a/libstdc++-v3/src/filesystem/Makefile.in
+++ b/libstdc++-v3/src/filesystem/Makefile.in
@@ -358,7 +358,7 @@ WARN_CXXFLAGS = \
 
 
 # -I/-D flags to pass when compiling.
-AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS)
+AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
 toolexeclib_LTLIBRARIES = libstdc++fs.la
 headers = 
 @ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources =



More information about the Libstdc++-cvs mailing list