From 7add7f7bb3d35726a0c45322ffdbbab2bbf6a348 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 21 Nov 2021 17:19:24 +0000 Subject: [PATCH] libgcc, Darwin: Build a libgcc_s.1 for backwards compatibility. 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) 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 | 134 ++++++++++++++++++++++++++---- 9 files changed, 188 insertions(+), 27 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 --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 - -LGCC_FILES = libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) - -INSTALL_FILES=$(LGCC_FILES) - # we do our own thing SHLIB_INSTALL = -# For the toplevel multilib, build a fat archive including all the multilibs. +LGCC_FILES = libgcc_s.$(SHLIB_SOVERSION)$(SHLIB_EXT) + +ifeq ($(BUILD_LIBGCCS1),YES) + +# 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 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