diff mbox series

[pushed] libgcc, Darwin: Build a libgcc_s.1 for backwards compatibility.

Message ID 20211208200214.62427-1-iain@sandoe.co.uk
State New
Headers show
Series [pushed] libgcc, Darwin: Build a libgcc_s.1 for backwards compatibility. | expand

Commit Message

Iain Sandoe Dec. 8, 2021, 8:02 p.m. UTC
In order to reslve a long-standing issue with inter-operation
with libSystem, we have bumped the SO name for libgcc_s.

Distributions might wish to install this new version into a
structure where exisiting code is already linked with the
compiler-local libgcc_s.1 (providing symbols exported by the
now-retired libgcc_ext.10.x shims).

The replacement libgcc_s.1 forwards the symbols from the new SO.
In order to support DYLD_LIBRARY_PATH on systems (where it works)
we forward the libSystem unwinder symbols from 10.7+ and a
compiler-local version of the libgcc unwinder on earlier.

For macOS 10.4 to 10.6 this is 'bug-compatible' with existing uses.
For 10.7+ the behaviour will now actually be correct.

This should be squashed with the initial libgcc changes for PR80556
in any backport (r12-5418-gd4943ce939d).

tested on powerpc, i686, x86_64 and aarch64 (where this will be a NOP
since there are no historical uses to cater for).
pushed to master, thanks
Iain

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
 
libgcc/ChangeLog:

	* config.host (*-*-darwin*): Add logic to build a shared
	unwinder library for Darwin8-10.
	* config/i386/t-darwin: Build legacy libgcc_s.1.
	* config/rs6000/t-darwin: Likewise.
	* config/t-darwin: Reorganise the EH fragments to place
	them for inclusion in a shared EH lib.
	* config/t-slibgcc-darwin: Build a legacy libgcc_s.1 and
	the supporting pieces (all FAT libs).
	* config/t-darwin-noeh: Removed.
	* config/darwin-unwind.ver: New file.
	* config/rs6000/t-darwin-ehs: New file.
	* config/t-darwin-ehs: New file.
---
 libgcc/config.host                |  13 ++-
 libgcc/config/darwin-unwind.ver   |  30 +++++++
 libgcc/config/i386/t-darwin       |   3 +
 libgcc/config/rs6000/t-darwin     |   3 +
 libgcc/config/rs6000/t-darwin-ehs |   5 ++
 libgcc/config/t-darwin            |  19 ++++-
 libgcc/config/t-darwin-ehs        |   4 +
 libgcc/config/t-darwin-noeh       |   4 -
 libgcc/config/t-slibgcc-darwin    | 130 ++++++++++++++++++++++++++----
 9 files changed, 186 insertions(+), 25 deletions(-)
 create mode 100644 libgcc/config/darwin-unwind.ver
 create mode 100644 libgcc/config/rs6000/t-darwin-ehs
 create mode 100644 libgcc/config/t-darwin-ehs
 delete mode 100644 libgcc/config/t-darwin-noeh
diff mbox series

Patch

diff --git a/libgcc/config.host b/libgcc/config.host
index 9475246593b..d4c035c7188 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -215,10 +215,17 @@  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 libd10-uwfef.a 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"
+  # to the shared libgcc but, for older systems, we build a shared unwinder
+  # separately so that we can construct a libgcc_s.1 to use for binaries
+  # linked against the old libgcc_ext.10.x stubs.
+  case ${host} in
+    *-*-darwin[89]* | *-*-darwin10*)
+      tmake_file="$tmake_file t-darwin-ehs ${cpu_type}/t-darwin-ehs"
+      ;;
+  esac
+  tmake_file="$tmake_file t-slibgcc-darwin"
+  extra_parts="crt3.o libd10-uwfef.a crttms.o crttme.o libemutls_w.a"
   ;;
 *-*-dragonfly*)
   tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
diff --git a/libgcc/config/darwin-unwind.ver b/libgcc/config/darwin-unwind.ver
new file mode 100644
index 00000000000..fb74cb2c5d2
--- /dev/null
+++ b/libgcc/config/darwin-unwind.ver
@@ -0,0 +1,30 @@ 
+# unwinder
+__Unwind_DeleteException
+__Unwind_Find_FDE
+__Unwind_ForcedUnwind
+__Unwind_GetGR
+__Unwind_GetIP
+__Unwind_GetLanguageSpecificData
+__Unwind_GetRegionStart
+__Unwind_GetTextRelBase
+__Unwind_GetDataRelBase
+__Unwind_RaiseException
+__Unwind_Resume
+__Unwind_SetGR
+__Unwind_SetIP
+__Unwind_FindEnclosingFunction
+__Unwind_GetCFA
+__Unwind_Backtrace
+__Unwind_Resume_or_Rethrow
+__Unwind_GetIPInfo
+
+___register_frame
+___register_frame_table
+___register_frame_info
+___register_frame_info_bases
+___register_frame_info_table
+___register_frame_info_table_bases
+
+___deregister_frame
+___deregister_frame_info
+___deregister_frame_info_bases
diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin
index c6b3acaaca2..4c18da1efbf 100644
--- a/libgcc/config/i386/t-darwin
+++ b/libgcc/config/i386/t-darwin
@@ -4,3 +4,6 @@  LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf
 
 # Extra symbols for this port.
 SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-darwin.ver
+
+# Build a legacy libgcc_s.1
+BUILD_LIBGCCS1 = YES
diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin
index 8b513bdb1d7..183d0df92ce 100644
--- a/libgcc/config/rs6000/t-darwin
+++ b/libgcc/config/rs6000/t-darwin
@@ -56,3 +56,6 @@  unwind-dw2_s.o: HOST_LIBGCC2_CFLAGS += -maltivec
 unwind-dw2.o: HOST_LIBGCC2_CFLAGS += -maltivec
 
 LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c
+
+# Build a legacy libgcc_s.1
+BUILD_LIBGCCS1 = YES
diff --git a/libgcc/config/rs6000/t-darwin-ehs b/libgcc/config/rs6000/t-darwin-ehs
new file mode 100644
index 00000000000..3047f53cb70
--- /dev/null
+++ b/libgcc/config/rs6000/t-darwin-ehs
@@ -0,0 +1,5 @@ 
+# We need the save_world code for the EH library.
+
+LIBEHSOBJS +=  darwin-world_s.o
+
+$(LIBEHSOBJS): libef_ppc.a
diff --git a/libgcc/config/t-darwin b/libgcc/config/t-darwin
index d6f688d66d5..a855ecfd526 100644
--- a/libgcc/config/t-darwin
+++ b/libgcc/config/t-darwin
@@ -11,10 +11,6 @@  crttms.o: $(srcdir)/config/darwin-crt-tm.c
 crttme.o: $(srcdir)/config/darwin-crt-tm.c
 	$(crt_compile) -mmacosx-version-min=10.4 -DEND -c $<
 
-# Use unwind-dw2-fde-darwin
-LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/config/unwind-dw2-fde-darwin.c \
-  $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
-
 # Make emutls weak so that we can deal with -static-libgcc, override the
 # hidden visibility when this is present in libgcc_eh.
 emutls.o: HOST_LIBGCC2_CFLAGS += \
@@ -38,5 +34,20 @@  libd10-uwfef.a: d10-uwfef.o
 	$(AR_CREATE_FOR_TARGET) $@ d10-uwfef.o
 	$(RANLIB_FOR_TARGET) $@
 
+###### Unwinder #######
+# Most Darwin versions get their unwinder from libSystem; older versions
+# have an installed /usr/lib/libgcc_s.1.dylib.
+# So do not add the unwinder to the shared libgcc.
+LIB2ADDEHSHARED =
+
+# We still need it in the _eh.a for earlier platform versions.
+# Use unwind-dw2-fde-darwin
+LIB2ADDEH = $(srcdir)/unwind-dw2.c \
+	    $(srcdir)/config/unwind-dw2-fde-darwin.c \
+	    $(srcdir)/unwind-c.c
+
+# Do not build a shared unwind lib by default.
+LIBEHSOBJS=
+
 # Symbols for all the sub-ports.
 SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/libgcc-libsystem.ver
diff --git a/libgcc/config/t-darwin-ehs b/libgcc/config/t-darwin-ehs
new file mode 100644
index 00000000000..8481898d98a
--- /dev/null
+++ b/libgcc/config/t-darwin-ehs
@@ -0,0 +1,4 @@ 
+# Build the unwinder separately so that we can construct a replacement for
+# libgcc_s.1 on systems that used the unwinder in libgcc_s.
+
+LIBEHSOBJS = unwind-dw2_s.o unwind-dw2-fde-darwin_s.o unwind-c_s.o
diff --git a/libgcc/config/t-darwin-noeh b/libgcc/config/t-darwin-noeh
deleted file mode 100644
index 08d9c1affd3..00000000000
--- a/libgcc/config/t-darwin-noeh
+++ /dev/null
@@ -1,4 +0,0 @@ 
-# 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 1512267b5aa..7349b87468a 100644
--- a/libgcc/config/t-slibgcc-darwin
+++ b/libgcc/config/t-slibgcc-darwin
@@ -2,11 +2,17 @@ 
 
 SHLIB_SOVERSION = 1.1
 SHLIB_SO_MINVERSION = 1
-SHLIB_VERSTRING = -compatibility_version $(SHLIB_SO_MINVERSION) -current_version $(SHLIB_SOVERSION)
+SHLIB_VERSTRING = -compatibility_version $(SHLIB_SO_MINVERSION) \
+		  -current_version $(SHLIB_SOVERSION)
 SHLIB_EXT = .dylib
 SHLIB_LC = -lSystem
+SHLIB_INSTALL_DIR = $(slibdir)
 
-# Shorthand expressions for the LINK below.
+SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
+SHLIB_MKMAP_OPTS = -v leading_underscore=1
+
+# Shorthand expressions for the LINK below, these are substituted in the
+# link expression.
 SHLIB_INSTALL_NAME = @shlib_base_name@.$(SHLIB_SOVERSION)$(SHLIB_EXT)
 SHLIB_MAP = @shlib_map_file@
 SHLIB_DIR = @multilib_dir@
@@ -18,23 +24,64 @@  SHLIB_SONAME = @shlib_base_name@$(SHLIB_EXT)
 # library, that is what we eventually install.
 
 SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \
-	-install_name @shlib_slibdir@/$(SHLIB_INSTALL_NAME) \
+	-install_name $(SHLIB_INSTALL_DIR)/$(SHLIB_INSTALL_NAME) \
 	-single_module -o $(SHLIB_DIR)/$(SHLIB_SONAME) \
 	-Wl,-exported_symbols_list,$(SHLIB_MAP) \
 	$(SHLIB_VERSTRING) \
 	@multilib_flags@ @shlib_objs@ $(SHLIB_LC)
 
-SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
-SHLIB_MKMAP_OPTS = -v leading_underscore=1
+# we do our own thing
+SHLIB_INSTALL =
 
 LGCC_FILES = libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)
 
-INSTALL_FILES=$(LGCC_FILES)
+ifeq ($(BUILD_LIBGCCS1),YES)
 
-# we do our own thing
-SHLIB_INSTALL =
+# We are going to build a libgcc_s.1.dylib so that distributions can
+# install it for compatibility with binaries linked against the old
+# libgcc_ext.10.x.dylib stubs.
+
+# For systems after macOS 10.7 we can forward the correct unwinder symbols
+# from libSystem.
+
+# For older systems we have to forward an entire library (since they cannot
+# selectively forward symbols, which means that we cannot forward the unwinder
+# in /usr/lib/libgcc_s.1.dylib).  We also cannot forward the entire library
+# since that creates a self-referencing loop when DYLD_LIBRARY_PATH is used.
+# To provide the unwinder symbols in this case, we build the unwinder into a
+# separate shared lib (libgcc_ehs) and forward that.
+
+# These targets are local to this make fragment, which means that they do not
+# get the substitutions seen in SHLIB_LINK.
+
+ifneq ($(LIBEHSOBJS),)
+
+EHS_INSTNAME = libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)
+
+# multilib build for a shared EH lib.
+$(LIBEHSOBJS): libgcc_tm.h
+
+libgcc_ehs$(SHLIB_EXT): $(LIBEHSOBJS)
+	mkdir -p $(MULTIDIR)
+	$(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -dynamiclib -nodefaultlibs \
+	-install_name $(SHLIB_INSTALL_DIR)/$(EHS_INSTNAME) \
+	-o $(MULTIDIR)/libgcc_ehs$(SHLIB_EXT) $(SHLIB_VERSTRING) \
+	$(LIBEHSOBJS) $(SHLIB_LC)
+
+all: libgcc_ehs$(SHLIB_EXT)
+
+LGCC_FILES += libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)
+
+endif
+
+# Provide libgcc_s.1 for backwards compatibility.
+LGCC_FILES += libgcc_s.1.dylib
+
+endif
+
+INSTALL_FILES=$(LGCC_FILES)
 
-# For the toplevel multilib, build a fat archive including all the multilibs.
+# For the toplevel multilib, build FAT dylibs including all the multilibs.
 ifeq ($(MULTIBUILDTOP),)
 
 ifeq ($(enable_shared),yes)
@@ -52,7 +99,62 @@  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.
+ifeq ($(BUILD_LIBGCCS1),YES)
+ifneq ($(LIBEHSOBJS),)
+
+libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT): all-multi libgcc_ehs$(SHLIB_EXT)
+	MLIBS=`$(CC) --print-multi-lib | sed -e 's/;.*$$//'` ; \
+	for mlib in $$MLIBS ; do \
+	  cp ../$${mlib}/libgcc/$${mlib}/libgcc_ehs$(SHLIB_EXT)  \
+	    ./libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \
+	done
+	$(LIPO) -output libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT) \
+	  -create libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
+	rm libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
+
+
+libgcc_s.1.dylib: libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)
+	MLIBS=`$(CC) --print-multi-lib | sed -e 's/;.*$$//'` ; \
+	for mlib in $$MLIBS ; do \
+	  cp ../$${mlib}/libgcc/$${mlib}/libgcc_s$(SHLIB_EXT)  \
+	    ./libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \
+	  cp ../$${mlib}/libgcc/$${mlib}/libgcc_ehs$(SHLIB_EXT)  \
+	    ./libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \
+	  arch=`$(LIPO) -info libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} | sed -e 's/.*:\ //'` ; \
+	  $(CC) -arch $${arch} -nodefaultlibs -dynamiclib \
+	    -o libgcc_s.1$(SHLIB_EXT)_T_$${mlib} \
+	    -Wl,-reexport_library,libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \
+	    -Wl,-reexport_library,libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \
+	    -install_name $(SHLIB_INSTALL_DIR)/libgcc_s.1.dylib \
+	    -compatibility_version 1 -current_version 1 ; \
+	done
+	$(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T*
+	rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
+	rm libgcc_ehs.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
+
+else
+
+libgcc_s.1.dylib: libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)
+	MLIBS=`$(CC) --print-multi-lib | sed -e 's/;.*$$//'` ; \
+	for mlib in $$MLIBS ; do \
+	  cp ../$${mlib}/libgcc/$${mlib}/libgcc_s$(SHLIB_EXT)  \
+	    ./libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} || exit 1 ; \
+	  arch=`$(LIPO) -info libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} | sed -e 's/.*:\ //'` ; \
+	  $(CC) -arch $${arch} -nodefaultlibs -dynamiclib \
+	    -o libgcc_s.1$(SHLIB_EXT)_T_$${mlib} \
+	    -Wl,-reexport_library,libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T_$${mlib} \
+	    -lSystem \
+	    -Wl,-reexported_symbols_list,$(srcdir)/config/darwin-unwind.ver \
+	    -install_name $(SHLIB_INSTALL_DIR)/libgcc_s.1.dylib \
+	    -compatibility_version 1 -current_version 1 ; \
+	done
+	$(LIPO) -output libgcc_s.1$(SHLIB_EXT) -create libgcc_s.1$(SHLIB_EXT)_T*
+	rm libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT)_T*
+
+endif
+endif
+
+# Install the shared libraries.
 
 install-darwin-libgcc-stubs :
 	$(mkinstalldirs) $(DESTDIR)$(slibdir)
@@ -62,10 +164,10 @@  install-darwin-libgcc-stubs :
 
 else
 
-# 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.
+# Do not install shared libraries for 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
+# multilib sub-directories.
 
 ifeq ($(enable_shared),yes)
 all: install-darwin-libgcc-links