diff mbox

[RFA,2/2] : --enable-explicit-exception-frame-registration compatibility option

Message ID 201409042142.s84LgSeO006256@ignucius.se.axis.com
State New
Headers show

Commit Message

Hans-Peter Nilsson Sept. 4, 2014, 9:42 p.m. UTC
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.


brgds, H-P
diff mbox

Patch

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