diff mbox series

Darwin: Rework handling for unwinder code in libgcc_s and specs [PR80556].

Message ID FC509680-1681-4DDF-BAEC-DE0D6905E585@sandoe.co.uk
State New
Headers show
Series Darwin: Rework handling for unwinder code in libgcc_s and specs [PR80556]. | expand

Commit Message

Iain Sandoe March 23, 2021, 2:46 p.m. UTC
Hi

I expect this to be my last (substantial) regression fix for GCC-11.

Although this is a Darwin patch, I’d welcome any comments - if none appear
then I plan to apply the patch later in the week.

tested on Darwin8 .20, x86_64-linux-gnu and powerpc-linux-gnu.

thanks
Iain

======


This addresses a long-standing problem where a work-around for an unwinder
issue (also a regression) regresses other functionality.  The patch replaces
the work-arounds.

TL;DR:
  * we provide a bumped libgcc_s.1.1 that contains the routines that were
    previously exported via symbols in libgcc_ext
  * we always use the builtins from the [new] compiler's libgcc.
 
This allows us to clean up a bunch of stuff and back out of the various work-
arounds.  (With 20:20 hindsight, we should have done this in the first place
but the libgcc_ext solution, described below, appeared less invasive at the
time).

====

MacOS system configurations are considered immutable by end-users - there is
no general equivalent of "apt-getting" additions to the system components,
instead updates come from Apple, at least, until an OS version is out of
support.  Additions typically come from one of the macOS OSS 'distributions'
(e.g. macports, homebrew, fink).

OSS distributions install alongside the system rather than into it - and  
policy
(for at least the major distributions) is that they do not modify the Apple-
provided one.  As far as the Darwin maintainers of GCC are concerned, this is
the only realistically supportable policy here too.

The issue here concerns the shared libgcc which not only provides the  
compiler
built-ins but also support for emulated TLS and the language-neutral parts of
the unwinder.

On macOS, there is no user-space equivalent of a completely "static"  
executable
they are all launched via the dynamic loader (dyld) and use the shared libc
(libSystem) which is only available as a dynamic library.  Nevertheless, the
static linker can use convenience libraries - so that (other than  
libSystem) an
executable can be statically-linked.

Until 10.3.9, there was no shared libgcc (or libstdc++) and all exceptions-
handling code was added from convenience libraries by the static linker.

Between 10.3.9 and 10.5.8, there is a shared libgcc_s, which provides the
unwinder and is based on gcc-4.2.1.  This is /usr/lib/libgcc_s.1.dylib.

 From 10.6 onwards the unwinder is provided (via libSystem) by libunwind  
which
is part of the LLVM project.  However, for backwards compatibility, there is
a symlink /usr/lib/libgcc_s.1.dylib => /usr/lib/libSystem.B.dylib.  Note,  
that
this link has (currently) been removed from macOS 11 systems.

We want to be able to install a new version of GCC alongside existing system
compilers, but policy dictates that we are not able to overwrite or replace
the system unwinder with the one in the new libgcc_s (it would be essentially
unworkable on any system after 10.6 anyway).

On Darwin systems /path1/to/library.dylib and /path2/to/library.dylib are
considered to be different libraries (so-called, two-level library  
namespace).

Darwin can also provide 'stub' libraries that simply re-export a sub-set of
the symbols from another library.

These two points allowed us to use two stub libraries; one containing the
symbols from the original /usr/lib/libgcc_s.1.dylib and one containing new
symbols from /path/to/compiler/install/lib/libgcc_s.1.dylib.  Since the two
libraries are distinct by the two-level namespace rules, there was no need to
alter the library build (a complete set of builtins and unwinder components  
are
still present in the /path/to/compiler/install/lib/libgcc_s.1.dylib).
The system SDKs provide the stub libraries that export the symbols present in
/usr/lib/libgcc_s.1.dylib; we added a 'libgcc_ext' stub (describing the new
symbols available with the updated GCC).

NOTE (important) that this means that code referring to
/path/to/compiler/install/lib/libgcc_s.1.dylib via libgcc_ext
will not reference any unwinder symbols in that lib [even though they were
present in the built libraries, they were not exposed via the stub].

Unfortunately the system SDKs do not provide a libgcc_s.10.X for 10.6+ and we
are not able to add our own (since SDKs are considered part of the immutable
content).  Since the systems *do* provide /usr/lib/libgcc_s.1.dylib as a link
to libSystem and /usr/lib is a necessary path for library searches, this
conflicts with any -lgcc_s.1 we add.

A series of workarounds have been used to try and resolve this, but none are
completely satisfactory; hence this patch.

--- dynamic objects

This change removes all the stubs machinery and workarounds and:

  * bumps the SO version for Darwin's libgcc_s => 1.1 avoiding the conflict.
  * the new version does not contain an unwinder, so it can be symlinked as
    libgcc_s.1 [in the compiler install path] and be backward-compatible with
    the symbols exported by libgcc_ext (per NOTE above).
  * builtins will be resolved from the new libgcc_s.  Previously, we have
    used the versions exported from /usr/lib/libgcc_s.1.dylib or libSystem
    where these are present, and from the compiler version where not.  This is
    no longer satisfactory, we need to use the versions from the compiler's
    build to pick up bug fixes (part of this regression is caused by a buggy
    conversion routine, now fixed in libgcc).  This makes sense as a general
    policy anyway - the builtins belong to the compiler, not the system (this
    same policy is already used for other system compilers).

--- static linking (noting that user-space executables are always dynamic
     but the static linker can use convenience libraries for runtimes etc.).

For macOS 10.6+ (Darwin10+), we do not provide an (automatic) ability to link
an unwinder statically - this is because there is no system-provided unwinder
convenience library - and any version we added would conflict with the  
dynamic
one in libSystem.  An end-user can always add -lgcc_eh to override that
decision (but that is not recommended).

For 10.6+ and a "-static-libgcc", we need to provide an implementation of the
emulated TLS routines - and we need to provide it in a non-conflicting  
manner.
This is resolved by linking a weak version of the routines in this case.   
Thus
such an executable can be operated together with a dynamically linked library
that refers to the version in /..../libgcc_s.1.1.dylib, because the version  
in
that is non-weak it will override the one in the exe.  If there is no  
non-weak
version then a weak version will be selected by the dynamic loaded (dyld).

For macOS versions before 10.6, we provide the same pattern as for other GCC
installs (libgcc.a libgcc_eh.a) and these have their usual content.  Of  
course,
it is the user's responsibility to avoid conflicts in that case (i.e ensure
that all or none of the libraries are statically linked; noting that  
libSystem
is fine here since it does not contain the unwinder in these OS revisions).

One final note:

We are not able to add a symlink libgcc_s.1.dylib => libgcc_s.1.1.dylib [in  
the
compiler's install lib dir] at build time, since that breaks testing (because
of the way in which DYLD_LIBRARY_PATH works, ignoring the two-level names).

This needs fixing too but is outside the scope of the current patch.

A distribution that wishes to have multiple GCC versions installed in the  
same
paths should, post-install, replace any existing older libgcc_s.1.dylib  
with a
symlink to the new libgcc_s.1.1.dylib .

gcc/ChangeLog:

	PR target/80556
	* config/darwin.c (darwin_rename_builtins): Remove workaround.
	* config/darwin.h (LINK_GCC_C_SEQUENCE_SPEC): Provide __eprintf via
	libgcc for macOS <= 10.4. (REAL_LIBGCC_SPEC): Adjust for the revised
	library naming.
	* config/i386/darwin.h (REAL_LIBGCC_SPEC): Remove workaround.
	* config/i386/darwin32-biarch.h (REAL_LIBGCC_SPEC): Likewise.
	* config/i386/darwin64-biarch.h (REAL_LIBGCC_SPEC): Likewise.

libgcc/ChangeLog:

	PR target/80556
	* config.host: Adjust target fragments to omit the unwinder from
	Darwin libgcc builds.  Add a weak emutls crt.
	* config/i386/t-darwin: Add X86-specific libgcc symbols.
	* config/t-darwin: Build a crat containing weak definitions for the
	emuTLS routines.
	* config/t-slibgcc-darwin: Bump SO version, remove all the handling
	for stub libraries.
	* emutls.c (EMUTLS_ATTR): New.
	(__emutls_get_address): Allow a target to add a weak
	attribute if provided.
	(__emutls_register_common): Likewise.
	* config/i386/libgcc-darwin.10.4.ver: Removed.
	* config/i386/libgcc-darwin.10.5.ver: Removed.
	* config/libgcc-libsystem.ver: Removed.
	* config/rs6000/libgcc-darwin.10.4.ver: Removed.
	* config/rs6000/libgcc-darwin.10.5.ver: Removed.
	* config/i386/libgcc-darwin.ver: New file.
	* config/t-darwin-noeh: New file.

gcc/testsuite/ChangeLog:

	PR target/80556
	* gcc.dg/torture/fp-int-convert-timode-3.c: Revert XFAIL.
	* gcc.dg/torture/fp-int-convert-timode-4.c: Likewise.


---
  gcc/config/darwin.c                           |  24 ----
  gcc/config/darwin.h                           |  65 ++++++-----
  gcc/config/i386/darwin.h                      |  27 -----
  gcc/config/i386/darwin32-biarch.h             |  26 -----
  gcc/config/i386/darwin64-biarch.h             |  26 -----
  .../gcc.dg/torture/fp-int-convert-timode-3.c  |   1 -
  .../gcc.dg/torture/fp-int-convert-timode-4.c  |   1 -
  libgcc/config.host                            |  11 +-
  libgcc/config/i386/libgcc-darwin.10.4.ver     |  98 ----------------
  libgcc/config/i386/libgcc-darwin.10.5.ver     | 102 -----------------
  libgcc/config/i386/libgcc-darwin.ver          |   2 +
  libgcc/config/i386/t-darwin                   |   2 +
  libgcc/config/libgcc-libsystem.ver            |   1 -
  libgcc/config/rs6000/libgcc-darwin.10.4.ver   |  93 ---------------
  libgcc/config/rs6000/libgcc-darwin.10.5.ver   | 106 ------------------
  libgcc/config/t-darwin                        |  12 ++
  libgcc/config/t-darwin-noeh                   |   4 +
  libgcc/config/t-slibgcc-darwin                |  94 ++++------------
  libgcc/emutls.c                               |  12 +-
  19 files changed, 92 insertions(+), 615 deletions(-)
  delete mode 100644 libgcc/config/i386/libgcc-darwin.10.4.ver
  delete mode 100644 libgcc/config/i386/libgcc-darwin.10.5.ver
  create mode 100644 libgcc/config/i386/libgcc-darwin.ver
  delete mode 100644 libgcc/config/libgcc-libsystem.ver
  delete mode 100644 libgcc/config/rs6000/libgcc-darwin.10.4.ver
  delete mode 100644 libgcc/config/rs6000/libgcc-darwin.10.5.ver
  create mode 100644 libgcc/config/t-darwin-noeh

  #ifdef __GTHREAD_MUTEX_INIT
diff mbox series

Patch

diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index e2e60bbf1b2..f96afcec1f0 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -3605,30 +3605,6 @@  darwin_fold_builtin (tree fndecl, int n_args, tree  
*argp,
  void
  darwin_rename_builtins (void)
  {
-  /* The system ___divdc3 routine in libSystem on darwin10 is not
-     accurate to 1ulp, ours is, so we avoid ever using the system name
-     for this routine and instead install a non-conflicting name that
-     is accurate.
-
-     When -ffast-math or -funsafe-math-optimizations is given, we can
-     use the faster version.  */
-  if (!flag_unsafe_math_optimizations)
-    {
-      enum built_in_function dcode
-	= (enum built_in_function)(BUILT_IN_COMPLEX_DIV_MIN
-				   + DCmode - MIN_MODE_COMPLEX_FLOAT);
-      tree fn = builtin_decl_explicit (dcode);
-      /* Fortran and c call TARGET_INIT_BUILTINS and
-	 TARGET_INIT_LIBFUNCS at different times, so we have to put a
-	 call into each to ensure that at least one of them is called
-	 after build_common_builtin_nodes.  A better fix is to add a
-	 new hook to run after build_common_builtin_nodes runs.  */
-      if (fn)
-	set_user_assembler_name (fn, "___ieee_divdc3");
-      fn = builtin_decl_implicit (dcode);
-      if (fn)
-	set_user_assembler_name (fn, "___ieee_divdc3");
-    }
  }
 
  bool
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index d2b2c141c8e..ed65c8ad868 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -260,14 +260,12 @@  extern GTY(()) int darwin_ms_struct;
  /* Tell collect2 to run dsymutil for us as necessary.  */
  #define COLLECT_RUN_DSYMUTIL 1
 
-/* Fix PR47558 by linking against libSystem ahead of libgcc. See also
-   PR 80556 and the fallout from this.  */
-
+/* We only want one instance of %G, since libSystem (Darwin's -lc) does not
+   depend on libgcc, however Darwin 8 relies on __eprintf from libgcc.a so
+   we append that.  */
  #undef  LINK_GCC_C_SEQUENCE_SPEC
  #define LINK_GCC_C_SEQUENCE_SPEC \
-"%{!static:%{!static-libgcc: \
-    %:version-compare(>= 10.6 mmacosx-version-min= -lSystem) } } \
-  %G %{!nolibc:%L}"
+ "%G %{!nolibc:%L} %:version-compare(!> 10.5 mmacosx-version-min= -lgcc)"
 
  /* ld64 supports a sysroot, it just has a different name and there's no easy
     way to check for it at config time.  */
@@ -375,37 +373,42 @@  extern GTY(()) int darwin_ms_struct;
 
  #define LIB_SPEC "%{!static:-lSystem}"
 
-/* Support -mmacosx-version-min by supplying different (stub) libgcc_s.dylib
-   libraries to link against, and by not linking against libgcc_s on
-   earlier-than-10.3.9.  If we need exceptions, prior to 10.3.9, then we  
have
-   to link the static eh lib, since there's no shared version on the system.
-
-   Note that by default, except as above, -lgcc_eh is not linked against.
+/*
+   Note that by default, -lgcc_eh is not linked against.
     This is because,in general, we need to unwind through system libraries that
     are linked with the shared unwinder in libunwind (or libgcc_s for 10.4/5).
 
-   The static version of the current libgcc unwinder (which differs from the
-   implementation in libunwind.dylib on systems Darwin10 [10.6]+) can be  
used
-   by specifying -static-libgcc.
+   For -static-libgcc: < 10.6, use the unwinder in libgcc_eh (and find
+   the emultls impl. there too).
+
+   For -static-libgcc: >= 10.6, the unwinder *still* comes from libSystem  
and
+   we find the emutls impl from lemutls_w. In either case, the builtins etc.
+   are linked from -lgcc.
 
-   If libgcc_eh is linked against, it has to be before -lgcc, because it  
might
-   need symbols from -lgcc.  */
+   When we have specified shared-libgcc or any case that might require
+   exceptions, we pull the libgcc content (including emulated tls) from
+   -lgcc_s.1 in GCC and the unwinder from /usr/lib/libgcc_s.1 for < 10.6 and
+   libSystem for >= 10.6 respectively.
+   Otherwise, we just link the emutls/builtins from convenience libs.
 
+   If we need exceptions, prior to 10.3.9, then we have to link the static
+   eh lib, since there's no shared version on the system.
+
+   In all cases, libgcc_s.1 will be installed with the compiler, or any app
+   built using it, so we can link the builtins and emutls shared on all.
+*/
  #undef REAL_LIBGCC_SPEC
-#define REAL_LIBGCC_SPEC						   \
-   "%{static-libgcc|static: -lgcc_eh -lgcc;				   \
-      shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime:		   \
-       %:version-compare(!> 10.3.9 mmacosx-version-min= -lgcc_eh)	   \
-       %:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(>< 10.3.9 10.5 mmacosx-version-min=  
-lgcc_ext.10.4) \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc ;								   \
-      :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(>< 10.3.9 10.5 mmacosx-version-min=  
-lgcc_ext.10.4) \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc }"
+#define REAL_LIBGCC_SPEC \
+"%{static-libgcc|static:						  \
+    %:version-compare(!> 10.6 mmacosx-version-min= -lgcc_eh)		  \
+    %:version-compare(>= 10.6 mmacosx-version-min= -lemutls_w) -lgcc;	  \
+   shared-libgcc|fexceptions|fobjc-exceptions|fgnu-runtime:		  \
+    -lgcc_s.1.1								  \
+    %:version-compare(!> 10.3.9 mmacosx-version-min= -lgcc_eh)		  \
+    %:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4)   \
+    %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5);	  \
+   : -lemutls_w	 -lgcc							  \
+  }"
 
  /* We specify crt0.o as -lcrt0.o so that ld will search the library path.  */
 
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index c81db9bf09f..f3947010f15 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -39,33 +39,6 @@  along with GCC; see the file COPYING3.  If not see
  #endif
  #endif
 
-/* WORKAROUND pr80556:
-   For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
-   from libSystem).  This doesn't use the keymgr (see keymgr.c) and  
therefore
-   the calls that libgcc makes to obtain the KEYMGR_GCC3_DW2_OBJ_LIST are  
not
-   updated to include new images, and might not even be valid for a single
-   image.
-   Therefore, for 64b exes at least, we must use the libunwind  
implementation,
-   even when static-libgcc is specified.  We put libSystem first so that
-   unwinder symbols are satisfied from there.
-   We default to 64b for single-arch builds, so apply this  
unconditionally. */
-#undef REAL_LIBGCC_SPEC
-#define REAL_LIBGCC_SPEC						   \
-   "%{static-libgcc|static: 						   \
-       %:version-compare(>= 10.6 mmacosx-version-min= -lSystem)		   \
-       -lgcc_eh -lgcc;							   \
-      shared-libgcc|fexceptions|fgnu-runtime:				   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4)	   \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4)	   \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc ;								   \
-      :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4)	   \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc }"
-
  /* Size of the Obj-C jump buffer.  */
  #define OBJC_JBLEN ((TARGET_64BIT) ? ((9 * 2) + 3 + 16) : (18))
 
diff --git a/gcc/config/i386/darwin32-biarch.h  
b/gcc/config/i386/darwin32-biarch.h
index 73b83eb650c..c0989068fd9 100644
--- a/gcc/config/i386/darwin32-biarch.h
+++ b/gcc/config/i386/darwin32-biarch.h
@@ -21,32 +21,6 @@  along with GCC; see the file COPYING3.  If not see
  #undef DARWIN_ARCH_SPEC
  #define DARWIN_ARCH_SPEC "%{m64:x86_64;:i386}"
 
-/* WORKAROUND pr80556:
-   For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
-   from libSystem).  This doesn't use the keymgr (see keymgr.c) and  
therefore
-   the calls that libgcc makes to obtain the KEYMGR_GCC3_DW2_OBJ_LIST are  
not
-   updated to include new images, and might not even be valid for a single
-   image.
-   Therefore, for 64b exes at least, we must use the libunwind  
implementation,
-   even when static-libgcc is specified.  We put libSystem first so that
-   unwinder symbols are satisfied from there. */
-#undef REAL_LIBGCC_SPEC
-#define REAL_LIBGCC_SPEC						   \
-   "%{static-libgcc|static: 						   \
-      %{m64:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)}	   \
-        -lgcc_eh -lgcc;							   \
-      shared-libgcc|fexceptions|fgnu-runtime:				   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4)	   \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4)	   \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc ;								   \
-      :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4)	   \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc }"
-
  #undef  DARWIN_SUBARCH_SPEC
  #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
 
diff --git a/gcc/config/i386/darwin64-biarch.h  
b/gcc/config/i386/darwin64-biarch.h
index 1ae76b8fb91..e543e635801 100644
--- a/gcc/config/i386/darwin64-biarch.h
+++ b/gcc/config/i386/darwin64-biarch.h
@@ -22,32 +22,6 @@  along with GCC; see the file COPYING3.  If not see
  #undef  DARWIN_ARCH_SPEC
  #define DARWIN_ARCH_SPEC "%{m32:i386;:x86_64}"
 
-/* WORKAROUND pr80556:
-   For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
-   from libSystem).  This doesn't use the keymgr (see keymgr.c) and  
therefore
-   the calls that libgcc makes to obtain the KEYMGR_GCC3_DW2_OBJ_LIST are  
not
-   updated to include new images, and might not even be valid for a single
-   image.
-   Therefore, for 64b exes at least, we must use the libunwind  
implementation,
-   even when static-libgcc is specified.  We put libSystem first so that
-   unwinder symbols are satisfied from there. */
-#undef REAL_LIBGCC_SPEC
-#define REAL_LIBGCC_SPEC						   \
-   "%{static-libgcc|static: 						   \
-      %{!m32:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)}	   \
-        -lgcc_eh -lgcc;							   \
-      shared-libgcc|fexceptions|fgnu-runtime:				   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4)	   \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4)	   \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc ;								   \
-      :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
-       %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5)   \
-       %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4)	   \
-       %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5)	   \
-       -lgcc }"
-
  #undef  DARWIN_SUBARCH_SPEC
  #define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
 
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c  
b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c
index 10702302bf8..707d539335f 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c
@@ -4,7 +4,6 @@ 
  /* { dg-require-effective-target int128 } */
  /* { dg-require-effective-target fenv } */
  /* { dg-options "-frounding-math" } */
-/* { dg-xfail-run-if "see PR80556 c63" { x86_64-*-darwin* i68?-*-darwin* }  
{ "*" } { "" } } */
 
  #include <fenv.h>
  #include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c  
b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c
index 3facf32fb8b..09600f90903 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c
@@ -4,7 +4,6 @@ 
  /* { dg-require-effective-target int128 } */
  /* { dg-require-effective-target fenv } */
  /* { dg-options "-frounding-math" } */
-/* { dg-xfail-run-if "see PR80556 c63" { x86_64-*-darwin* i68?-*-darwin* }  
{ "*" } { "" } } */
 
  #include <fenv.h>
  #include <stdlib.h>
diff --git a/libgcc/config.host b/libgcc/config.host
index f808b61be70..229631dd1b5 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -214,8 +214,11 @@  esac
  case ${host} in
  *-*-darwin*)
    asm_hidden_op=.private_extern
-  tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic  
t-slibgcc-darwin"
-  extra_parts="crt3.o d10-uwfef.o crttms.o crttme.o"
+  tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic"
+  extra_parts="crt3.o d10-uwfef.o crttms.o crttme.o libemutls_w.a"
+  # The unwinder is provided by the system shared libraries, do not add one
+  # to the shared libgcc.
+  tmake_file="$tmake_file t-darwin-noeh t-slibgcc-darwin"
    ;;
  *-*-dragonfly*)
    tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
@@ -678,12 +681,12 @@  hppa*-*-netbsd*)
  	;;
  i[34567]86-*-darwin*)
  	tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
-	tm_file="$tm_file i386/darwin-lib.h"
+	tm_file="$tm_file "
  	extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
  	;;
  x86_64-*-darwin*)
  	tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
-	tm_file="$tm_file i386/darwin-lib.h"
+	tm_file="$tm_file "
  	extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
  	;;
  i[34567]86-*-elfiamcu)
diff --git a/libgcc/config/i386/libgcc-darwin.10.4.ver  
b/libgcc/config/i386/libgcc-darwin.10.4.ver
deleted file mode 100644
index b8a73b1f10f..00000000000
--- a/libgcc/config/i386/libgcc-darwin.10.4.ver
+++ /dev/null
@@ -1,98 +0,0 @@ 
-# Copyright (C) 2005-2021 Free Software Foundation, Inc.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GCC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-__Unwind_Backtrace
-__Unwind_DeleteException
-__Unwind_FindEnclosingFunction
-__Unwind_Find_FDE
-__Unwind_ForcedUnwind
-__Unwind_GetCFA
-__Unwind_GetDataRelBase
-__Unwind_GetGR
-__Unwind_GetIP
-__Unwind_GetLanguageSpecificData
-__Unwind_GetRegionStart
-__Unwind_GetTextRelBase
-__Unwind_RaiseException
-__Unwind_Resume
-__Unwind_Resume_or_Rethrow
-__Unwind_SetGR
-__Unwind_SetIP
-___absvdi2
-___absvsi2
-___addvdi3
-___addvsi3
-___ashldi3
-___ashrdi3
-___clear_cache
-___clzdi2
-___clzsi2
-___cmpdi2
-___ctzdi2
-___ctzsi2
-___deregister_frame
-___deregister_frame_info
-___deregister_frame_info_bases
-___divdc3
-___divdi3
-___divsc3
-___divxc3
-___enable_execute_stack
-___ffsdi2
-___fixdfdi
-___fixsfdi
-___fixunsdfdi
-___fixunsdfsi
-___fixunssfdi
-___fixunssfsi
-___fixunsxfdi
-___fixunsxfsi
-___fixxfdi
-___floatdidf
-___floatdisf
-___floatdixf
-___gcc_personality_v0
-___lshrdi3
-___moddi3
-___muldc3
-___muldi3
-___mulsc3
-___mulvdi3
-___mulvsi3
-___mulxc3
-___negdi2
-___negvdi2
-___negvsi2
-___paritydi2
-___paritysi2
-___popcountdi2
-___popcountsi2
-___powidf2
-___powisf2
-___powixf2
-___register_frame
-___register_frame_info
-___register_frame_info_bases
-___register_frame_info_table
-___register_frame_info_table_bases
-___register_frame_table
-___subvdi3
-___subvsi3
-___ucmpdi2
-___udivdi3
-___udivmoddi4
-___umoddi3
diff --git a/libgcc/config/i386/libgcc-darwin.10.5.ver  
b/libgcc/config/i386/libgcc-darwin.10.5.ver
deleted file mode 100644
index 49fd9279d28..00000000000
--- a/libgcc/config/i386/libgcc-darwin.10.5.ver
+++ /dev/null
@@ -1,102 +0,0 @@ 
-# Copyright (C) 2005-2021 Free Software Foundation, Inc.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GCC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-__Unwind_Backtrace
-__Unwind_DeleteException
-__Unwind_FindEnclosingFunction
-__Unwind_Find_FDE
-__Unwind_ForcedUnwind
-__Unwind_GetCFA
-__Unwind_GetDataRelBase
-__Unwind_GetGR
-__Unwind_GetIP
-__Unwind_GetIPInfo
-__Unwind_GetLanguageSpecificData
-__Unwind_GetRegionStart
-__Unwind_GetTextRelBase
-__Unwind_RaiseException
-__Unwind_Resume
-__Unwind_Resume_or_Rethrow
-__Unwind_SetGR
-__Unwind_SetIP
-___absvdi2
-___absvsi2
-___addvdi3
-___addvsi3
-___ashldi3
-___ashrdi3
-___clear_cache
-___clzdi2
-___clzsi2
-___cmpdi2
-___ctzdi2
-___ctzsi2
-___deregister_frame
-___deregister_frame_info
-___deregister_frame_info_bases
-___divdc3
-___divdi3
-___divsc3
-___divxc3
-___enable_execute_stack
-___ffsdi2
-___fixdfdi
-___fixsfdi
-___fixunsdfdi
-___fixunsdfsi
-___fixunssfdi
-___fixunssfsi
-___fixunsxfdi
-___fixunsxfsi
-___fixxfdi
-___floatdidf
-___floatdisf
-___floatdixf
-___floatundidf
-___floatundisf
-___floatundixf
-___gcc_personality_v0
-___lshrdi3
-___moddi3
-___muldc3
-___muldi3
-___mulsc3
-___mulvdi3
-___mulvsi3
-___mulxc3
-___negdi2
-___negvdi2
-___negvsi2
-___paritydi2
-___paritysi2
-___popcountdi2
-___popcountsi2
-___powidf2
-___powisf2
-___powixf2
-___register_frame
-___register_frame_info
-___register_frame_info_bases
-___register_frame_info_table
-___register_frame_info_table_bases
-___register_frame_table
-___subvdi3
-___subvsi3
-___ucmpdi2
-___udivdi3
-___udivmoddi4
-___umoddi3
diff --git a/libgcc/config/i386/libgcc-darwin.ver  
b/libgcc/config/i386/libgcc-darwin.ver
new file mode 100644
index 00000000000..9a6d26597f0
--- /dev/null
+++ b/libgcc/config/i386/libgcc-darwin.ver
@@ -0,0 +1,2 @@ 
+__cpu_model
+__cpu_indicator_init
diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin
index 5f2c69725d0..64eea1cd5f9 100644
--- a/libgcc/config/i386/t-darwin
+++ b/libgcc/config/i386/t-darwin
@@ -1,3 +1,5 @@ 
  LIB2_SIDITI_CONV_FUNCS = yes
  LIB2ADD = $(srcdir)/config/darwin-64.c
  LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf
+
+SHLIB_MAPFILES += $(srcdir)/config/$(cpu_type)/libgcc-darwin.ver
diff --git a/libgcc/config/libgcc-libsystem.ver  
b/libgcc/config/libgcc-libsystem.ver
deleted file mode 100644
index 47631749dc2..00000000000
--- a/libgcc/config/libgcc-libsystem.ver
+++ /dev/null
@@ -1 +0,0 @@ 
-_darwin10_Unwind_FindEnclosingFunction
diff --git a/libgcc/config/rs6000/libgcc-darwin.10.4.ver  
b/libgcc/config/rs6000/libgcc-darwin.10.4.ver
deleted file mode 100644
index b050cb8e704..00000000000
--- a/libgcc/config/rs6000/libgcc-darwin.10.4.ver
+++ /dev/null
@@ -1,93 +0,0 @@ 
-# Copyright (C) 2005-2021 Free Software Foundation, Inc.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GCC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-__Unwind_Backtrace
-__Unwind_DeleteException
-__Unwind_FindEnclosingFunction
-__Unwind_Find_FDE
-__Unwind_ForcedUnwind
-__Unwind_GetCFA
-__Unwind_GetDataRelBase
-__Unwind_GetGR
-__Unwind_GetIP
-__Unwind_GetLanguageSpecificData
-__Unwind_GetRegionStart
-__Unwind_GetTextRelBase
-__Unwind_RaiseException
-__Unwind_Resume
-__Unwind_Resume_or_Rethrow
-__Unwind_SetGR
-__Unwind_SetIP
-___absvdi2
-___absvsi2
-___addvdi3
-___addvsi3
-___ashldi3
-___ashrdi3
-___clear_cache
-___clzdi2
-___clzsi2
-___cmpdi2
-___ctzdi2
-___ctzsi2
-___deregister_frame
-___deregister_frame_info
-___deregister_frame_info_bases
-___divdi3
-___enable_execute_stack
-___ffsdi2
-___fixdfdi
-___fixsfdi
-___fixtfdi
-___fixunsdfdi
-___fixunsdfsi
-___fixunssfdi
-___fixunssfsi
-___fixunstfdi
-___floatdidf
-___floatdisf
-___floatditf
-___gcc_personality_v0
-___gcc_qadd
-___gcc_qdiv
-___gcc_qmul
-___gcc_qsub
-___lshrdi3
-___moddi3
-___muldi3
-___mulvdi3
-___mulvsi3
-___negdi2
-___negvdi2
-___negvsi2
-___paritydi2
-___paritysi2
-___popcountdi2
-___popcountsi2
-___register_frame
-___register_frame_info
-___register_frame_info_bases
-___register_frame_info_table
-___register_frame_info_table_bases
-___register_frame_table
-___subvdi3
-___subvsi3
-___trampoline_setup
-___ucmpdi2
-___udivdi3
-___udivmoddi4
-___umoddi3
diff --git a/libgcc/config/rs6000/libgcc-darwin.10.5.ver  
b/libgcc/config/rs6000/libgcc-darwin.10.5.ver
deleted file mode 100644
index dcc548f8a52..00000000000
--- a/libgcc/config/rs6000/libgcc-darwin.10.5.ver
+++ /dev/null
@@ -1,106 +0,0 @@ 
-# Copyright (C) 2005-2021 Free Software Foundation, Inc.
-#
-# This file is part of GCC.
-#
-# GCC is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GCC is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-__Unwind_Backtrace
-__Unwind_DeleteException
-__Unwind_FindEnclosingFunction
-__Unwind_Find_FDE
-__Unwind_ForcedUnwind
-__Unwind_GetCFA
-__Unwind_GetDataRelBase
-__Unwind_GetGR
-__Unwind_GetIP
-__Unwind_GetIPInfo
-__Unwind_GetLanguageSpecificData
-__Unwind_GetRegionStart
-__Unwind_GetTextRelBase
-__Unwind_RaiseException
-__Unwind_Resume
-__Unwind_Resume_or_Rethrow
-__Unwind_SetGR
-__Unwind_SetIP
-___absvdi2
-___absvsi2
-___addvdi3
-___addvsi3
-___ashldi3
-___ashrdi3
-___clear_cache
-___clzdi2
-___clzsi2
-___cmpdi2
-___ctzdi2
-___ctzsi2
-___deregister_frame
-___deregister_frame_info
-___deregister_frame_info_bases
-___divdc3
-___divdi3
-___divsc3
-___divtc3
-___enable_execute_stack
-___ffsdi2
-___fixdfdi
-___fixsfdi
-___fixtfdi
-___fixunsdfdi
-___fixunsdfsi
-___fixunssfdi
-___fixunssfsi
-___fixunstfdi
-___floatdidf
-___floatdisf
-___floatditf
-___floatundidf
-___floatundisf
-___floatunditf
-___gcc_personality_v0
-___gcc_qadd
-___gcc_qdiv
-___gcc_qmul
-___gcc_qsub
-___lshrdi3
-___moddi3
-___muldc3
-___muldi3
-___mulsc3
-___multc3
-___mulvdi3
-___mulvsi3
-___negdi2
-___negvdi2
-___negvsi2
-___paritydi2
-___paritysi2
-___popcountdi2
-___popcountsi2
-___powidf2
-___powisf2
-___powitf2
-___register_frame
-___register_frame_info
-___register_frame_info_bases
-___register_frame_info_table
-___register_frame_info_table_bases
-___register_frame_table
-___subvdi3
-___subvsi3
-___trampoline_setup
-___ucmpdi2
-___udivdi3
-___udivmoddi4
-___umoddi3
diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin
index 3b5e3428958..3b348fd2a20 100644
--- a/libgcc/config/t-darwin
+++ b/libgcc/config/t-darwin
@@ -15,6 +15,18 @@  crttme.o: $(srcdir)/config/darwin-crt-tm.c
  LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/config/unwind-dw2-fde-darwin.c \
    $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
 
+# Make a weak version to use in static lib and as a crt.
+emutls.o: HOST_LIBGCC2_CFLAGS += -DEMUTLS_ATTR='__attribute__((__weak__))'
+
+# Make it a convenience lib so that it can be linked optionally.
+libemutls_w.a: emutls.o
+	$(AR_CREATE_FOR_TARGET) $@ $<
+	$(RANLIB_FOR_TARGET) $@
+
  # Patch to __Unwind_Find_Enclosing_Function for Darwin10.
  d10-uwfef.o: $(srcdir)/config/darwin10-unwind-find-enc-func.c
  	$(crt_compile) -mmacosx-version-min=10.6 -c $<
+
+# Start with an empty list and allow the arch-specific t-darwin files to  
add in
+# any extras, with the main set added by t-slibgcc-darwin.
+SHLIB_MAPFILES =
diff --git a/libgcc/config/t-darwin-noeh b/libgcc/config/t-darwin-noeh
new file mode 100644
index 00000000000..08d9c1affd3
--- /dev/null
+++ b/libgcc/config/t-darwin-noeh
@@ -0,0 +1,4 @@ 
+# Most Darwin versions get their unwinder from libSystem.
+# so remove the unwinder from the shared lib.
+# We still need it in the _eh.a for Darwin8/9.
+LIB2ADDEHSHARED =
diff --git a/libgcc/config/t-slibgcc-darwin b/libgcc/config/t-slibgcc-darwin
index 9970d003436..1229cb47e7a 100644
--- a/libgcc/config/t-slibgcc-darwin
+++ b/libgcc/config/t-slibgcc-darwin
@@ -1,44 +1,35 @@ 
  # Build a shared libgcc library with the darwin linker.
-SHLIB_SOVERSION = 1
-SHLIB_VERSTRING = -compatibility_version $(SHLIB_SOVERSION)  
-current_version $(SHLIB_SOVERSION).0
+
+SHLIB_SOVERSION = 1.1
+SHLIB_SO_MINVERSION = 1
+SHLIB_VERSTRING = -compatibility_version $(SHLIB_SO_MINVERSION)  
-current_version $(SHLIB_SOVERSION)
  SHLIB_EXT = .dylib
+SHLIB_LC = -lc
+
+# Shorthand expressions for the LINK below.
  SHLIB_INSTALL_NAME = @shlib_base_name@.$(SHLIB_SOVERSION)$(SHLIB_EXT)
-SHLIB_SONAME = @shlib_base_name@$(SHLIB_EXT)
-SHLIB_SOLINK = @shlib_base_name@.so
  SHLIB_MAP = @shlib_map_file@
-SHLIB_OBJS = @shlib_objs@
  SHLIB_DIR = @multilib_dir@
-SHLIB_LC = -lc
+SHLIB_SONAME = @shlib_base_name@$(SHLIB_EXT)
 
-# Darwin only searches in /usr/lib for shared libraries, not in  
subdirectories,
-# so the libgcc variants have different names not different locations.
-# Note that this version is used for the loader, not the linker; the linker
-# uses the stub versions named by the versioned members of $(INSTALL_FILES).
+# Darwin only searches in shlib_slibdir for shared libraries, not in
+# subdirectories.  The link builds one architecture slice in its designated
+# subdir.  The code under MULTIBUILDTOP combines these into a single FAT
+# library, that is what we eventually install.
 
  SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -dynamiclib -nodefaultlibs \
  	-install_name @shlib_slibdir@/$(SHLIB_INSTALL_NAME) \
  	-single_module -o $(SHLIB_DIR)/$(SHLIB_SONAME) \
  	-Wl,-exported_symbols_list,$(SHLIB_MAP) \
  	$(SHLIB_VERSTRING) \
-	@multilib_flags@ $(SHLIB_OBJS) $(SHLIB_LC)
+	@multilib_flags@ @shlib_objs@ $(SHLIB_LC)
 
  SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
  SHLIB_MKMAP_OPTS = -v leading_underscore=1
-SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/libgcc-libsystem.ver
-SHLIB_VERPFX = $(srcdir)/config/$(cpu_type)/libgcc-darwin
-
-# we're only going to build the stubs if the target slib is /usr/lib
-# there is no other case in which they're useful in a live system.
-ifeq (/usr/lib,$(shlib_slibdir))
-LGCC_STUBS = libgcc_s.10.4.dylib libgcc_s.10.5.dylib
-else
-LGCC_STUBS =
-endif
+SHLIB_MAPFILES += libgcc-std.ver
 
  LGCC_FILES = libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)
-LGCC_FILES += $(LGCC_STUBS)
-LEXT_STUBS = libgcc_ext.10.4$(SHLIB_EXT) libgcc_ext.10.5$(SHLIB_EXT)
-LGCC_FILES += $(LEXT_STUBS)
+
  INSTALL_FILES=$(LGCC_FILES)
 
  # we do our own thing
@@ -52,33 +43,6 @@  all: $(INSTALL_FILES)
  install-leaf: install-darwin-libgcc-stubs
  endif
 
-# In order to support -mmacosx-version-min, you need to have multiple
-# different libgcc_s libraries that actually get linked against, one for
-# each system version supported.  They are 'stub' libraries that
-# contain no code, just a list of exported symbols.
-# The actual use of the libraries is controlled by REAL_LIBGCC_SPEC.
-#
-# This assumes each multilib corresponds to a different architecture.
-libgcc_s.%.dylib : all-multi $(SHLIB_VERPFX).%.ver libgcc_s$(SHLIB_EXT)
-	MLIBS=`$(CC) --print-multi-lib | sed -e 's/;.*$$//'` ; \
-	for mlib in $$MLIBS ; do \
-	  $(STRIP) -o $(@)_T$${mlib} \
-	    -s $(SHLIB_VERPFX).$(*).ver -c -u \
-	    ../$${mlib}/libgcc/$${mlib}/libgcc_s$(SHLIB_EXT)  || exit 1 ; \
-	done
-	$(LIPO) -output $@ -create $(@)_T*
-	rm $(@)_T*
-
-libgcc_ext.%.dylib : all-multi $(SHLIB_VERPFX).%.ver libgcc_s$(SHLIB_EXT)
-	MLIBS=`$(CC) --print-multi-lib | sed -e 's/;.*$$//'` ; \
-	for mlib in $$MLIBS ; do \
-	  $(STRIP) -o $(@)_T$${mlib} \
-	    -R $(SHLIB_VERPFX).$(*).ver -c -urx \
-	    ../$${mlib}/libgcc/$${mlib}/libgcc_s$(SHLIB_EXT) || exit 1 ; \
-	done
-	$(LIPO) -output $@ -create $(@)_T*
-	rm $(@)_T*
-
  libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT): all-multi libgcc_s$(SHLIB_EXT)
  	MLIBS=`$(CC) --print-multi-lib | sed -e 's/;.*$$//'` ; \
  	for mlib in $$MLIBS ; do \
@@ -89,28 +53,20 @@  libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT): all-multi  
libgcc_s$(SHLIB_EXT)
  	  -create libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
  	rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
 
+# Install the shared library.
+
  install-darwin-libgcc-stubs :
  	$(mkinstalldirs) $(DESTDIR)$(slibdir)
  	for d in $(INSTALL_FILES) ; do \
  	  $(INSTALL_DATA) $$d $(DESTDIR)$(slibdir)/$$d || exit 1 ; \
  	done
-	if [ -f $(DESTDIR)$(slibdir)/libgcc_s_ppc64.1.dylib ]; then \
-	  rm -f $(DESTDIR)$(slibdir)/libgcc_s_ppc64.1.dylib; \
-	else true; fi
-	$(LN_S) libgcc_s.1.dylib \
-		$(DESTDIR)$(slibdir)/libgcc_s_ppc64.1.dylib
-	if [ -f $(DESTDIR)$(slibdir)/libgcc_s_x86_64.1.dylib ]; then \
-	  rm -f $(DESTDIR)$(slibdir)/libgcc_s_x86_64.1.dylib; \
-	else true; fi
-	$(LN_S) libgcc_s.1.dylib \
-		$(DESTDIR)$(slibdir)/libgcc_s_x86_64.1.dylib
 
  else
 
-# Do not install shared libraries for any other multilibs.  Unless
-# we're putting them in the gcc directory during a build, for
-# compatibility with the pre-top-level layout.  In that case we
-# need symlinks.
+# Do not install shared libraries for any other multilibs.  Unless we are
+# putting them in the gcc directory during a build, for compatibility with
+# the pre-top-level layout.  In that case we provide symlinks to the FAT lib
+# from the sub-directories.
 
  ifeq ($(enable_shared),yes)
  all: install-darwin-libgcc-links
@@ -123,12 +79,4 @@  install-darwin-libgcc-links:
  	  $(LN_S) ../$$file $(gcc_objdir)$(MULTISUBDIR)/;	\
  	done
 
-	rm -f $(gcc_objdir)$(MULTISUBDIR)/libgcc_s_x86_64.1.dylib
-	$(LN_S) libgcc_s.1.dylib \
-		$(gcc_objdir)$(MULTISUBDIR)/libgcc_s_x86_64.1.dylib
-
-	rm -f $(gcc_objdir)$(MULTISUBDIR)/libgcc_s_ppc64.1.dylib
-	$(LN_S) libgcc_s.1.dylib \
-		$(gcc_objdir)$(MULTISUBDIR)/libgcc_s_ppc64.1.dylib
-
  endif
diff --git a/libgcc/emutls.c b/libgcc/emutls.c
index ed2658170f5..2015da1369e 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 convenience 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