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

Reply via email to