This adds an option to allow programs and libraries built *without* inhibit_libc to stay compatible with system libraries (really: libgcc_s.so.1) built *with* inhibit_libc, at the cost of the registration. As mentioned, that's a one-way compatibility barrier.
While it's nice to avoid the overhead of a function call at DSO/program initialization time, using eh-registry isn't that much of overhead until an exception is thrown: most of the execution-time overhead will come from the additional symbol-table-entries due to the registry calls (typically 2 in all libraries and programs, as weak references) and calls to thread-locking as the (main) part of its work-load. Besides the symbol-table-entries the footprint size is typically the code for if (__register_frame_info) __register_frame_info (__EH_FRAME_BEGIN__, &object); and the corresponding deregistration and the static object struct (6 or 7 pointers). (As mentioned, the library-part of the eh-registry support is present either way.) So, a low-cost compatibility path is to always call __register_frame_info, despite favorable conditions for phdr usage. Here's a patch to optionally do that, controlled by a configure-time option tentatively called --enable-explicit-exception-frame-registration (subject to bikeshedding if only for the length). Note that there is a cost when an exception *is* thrown, the dreaded sorting of FDE:s. There seems to be some obvious room for improvement though, as the same information is available *without* sorting through the PT_GNU_EH_FRAME header entry for the same file. Tested with no regressions after fixing g++.old-deja/g++.eh/badalloc1.C (see <http://gcc.gnu.org/ml/gcc-patches/2014-09/msg00115.html>) for native x86_64-linux before compared to with patch/with patch and --enable-explicit-exception-frame-registration/. Ok to commit? libgcc: * crtstuff.c [EH_FRAME_SECTION_NAME && !USE_PT_GNU_EH_FRAME]: Sanity-check USE_EH_FRAME_REGISTRY_ALWAYS against EH_FRAME_SECTION_NAME, emit error if unsane. (USE_EH_FRAME_REGISTRY): Let USE_EH_FRAME_REGISTRY_ALWAYS override USE_PT_GNU_EH_FRAME. * Makefile.in (FORCE_EXPLICIT_EH_REGISTRY): New variable for substituted force_explicit_eh_registry. (CRTSTUFF_CFLAGS): Add FORCE_EXPLICIT_EH_REGISTRY. * configure.ac (explicit-exception-frame-registration): New AC_ARG_ENABLE. * configure: Regenerate. Index: libgcc/Makefile.in =================================================================== --- libgcc/Makefile.in (revision 214759) +++ libgcc/Makefile.in (working copy) @@ -50,6 +50,8 @@ target_noncanonical = @target_noncanonic # The rules for compiling them should be in the t-* file for the machine. EXTRA_PARTS = @extra_parts@ +FORCE_EXPLICIT_EH_REGISTRY = @force_explicit_eh_registry@ + extra-parts = libgcc-extra-parts # Multilib support variables. @@ -283,7 +285,7 @@ INTERNAL_CFLAGS = $(CFLAGS) $(LIBGCC2_CF CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ -finhibit-size-directive -fno-inline -fno-exceptions \ -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \ - -fno-stack-protector \ + -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \ $(INHIBIT_LIBC_CFLAGS) # Extra flags to use when compiling crt{begin,end}.o. Index: libgcc/configure.ac =================================================================== --- libgcc/configure.ac (revision 214759) +++ libgcc/configure.ac (working copy) @@ -262,6 +262,22 @@ no) ;; esac +AC_ARG_ENABLE([explicit-exception-frame-registration], + [AC_HELP_STRING([--enable-explicit-exception-frame-registration], + [register exception tables explicitly at module start, for use + e.g. for compatibility with installations without PT_GNU_EH_FRAME support])], +[ +force_explicit_eh_registry= +if test "$enable_explicit_exception_frame_registration" = yes; then + if test "$enable_sjlj_exceptions" = yes; then + AC_MSG_ERROR([Can't enable both of --enable-sjlj-exceptions + and --enable-explicit-exception-frame-registration]) + fi + force_explicit_eh_registry=-DUSE_EH_FRAME_REGISTRY_ALWAYS +fi +]) +AC_SUBST([force_explicit_eh_registry]) + AC_LIB_PROG_LD_GNU AC_MSG_CHECKING([for thread model used by GCC]) Index: libgcc/crtstuff.c =================================================================== --- libgcc/crtstuff.c (revision 214709) +++ libgcc/crtstuff.c (working copy) @@ -131,7 +131,12 @@ call_ ## FUNC (void) \ # define USE_PT_GNU_EH_FRAME #endif -#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME) +#ifdef USE_EH_FRAME_REGISTRY_ALWAYS +# ifndef EH_FRAME_SECTION_NAME +# error "Can't use explicit exception-frame-registration without EH_FRAME_SECTION_NAME" +# endif +#endif +#if defined(EH_FRAME_SECTION_NAME) && (!defined(USE_PT_GNU_EH_FRAME) || defined(USE_EH_FRAME_REGISTRY_ALWAYS)) # define USE_EH_FRAME_REGISTRY #endif #if defined(EH_FRAME_SECTION_NAME) && EH_TABLES_CAN_BE_READ_ONLY brgds, H-P