This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Unterminated .eh_frame when using --eh-frame-hdr


HAVE_DWARF2_UNWIND_INFO currently guards two things:

  (a) the calls to __register_frame_info(), etc.
  (b) the __EH_FRAME_BEGIN__ and __FRAME_END__ definitions, including
      (in the latter case) .eh_frame's null terminator.

Both are omitted when --eh-frame-hdr is in use.

The current set-up works fine when .eh_frame_hdr has a binary-sorted
table of FDEs.  The problem is that this sorted table is optional, and
isn't created if an FDE uses an absolute encoding for the initial PC.
Quoting from bfd/elf-eh-frame.c:

		  /* If a shared library uses absolute pointers
		     which we cannot turn into PC relative,
		     don't create the binary search table,
		     since it is affected by runtime relocations.  */

On targets like x86, gcc will generate PC-relative FDEs when generating
PIC, so we do indeed get the sorted table.  Unfortunately, the MIPS ABIs
don't define a suitable relocation for PC-relative encodings, so gcc uses
an absolute encoding instead.

At the moment, the linker doesn't convert these absolute MIPS FDEs into
PC-relative form (although it probably should) and so .eh_frame_hdr has
no sorted table.  The unwinder must therefore create the table itself,
just as it would if there were no .eh_frame_hdr, and to do that it needs
to know where the end of .eh_frame is.  Omitting (b) for --eh-frame-hdr
prevents this and can lead to a segfault when unwinding through libc.

The patch below introduces a new macro, HAVE_DWARF2_UNWIND_INFO_REGISTRY,
to control (a), and enables (b) when --eh-frame-hdr is being used.
Tested on MIPS (all three ABIs).  It fixes various g++ failures like
eh/terminate1.C.  Please install if OK.

Richard

PS. I've included the autogenerated change to configure since it's likely
    to apply cleanly.  Let me know if that's not the done thing ;)


2004-11-08  Richard Sandiford  <rsandifo@redhat.com>

	* configure.in (HAVE_DWARF2_UNWIND_INFO): Define even when no
	registry calls are needed.
	(HAVE_DWARF2_UNWIND_INFO_REGISTRY): New macro.
	* configure: Regenerate.
	* config.h.in (HAVE_DWARF2_UNWIND_INFO_REGISTRY): Add placeholder.
	* elf/soinit.c: Use HAVE_DWARF2_UNWIND_INFO_REGISTRY rather than
	HAVE_DWARF2_UNWIND_INFO to guard the registry code.

Index: configure.in
===================================================================
RCS file: /cvs/glibc/libc/configure.in,v
retrieving revision 1.430
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.430 configure.in
--- configure.in	26 Oct 2004 01:35:54 -0000	1.430
+++ configure.in	8 Nov 2004 14:20:38 -0000
@@ -1778,12 +1778,17 @@ if test $libc_cv_gcc_dwarf2_unwind_info 
 fi
 rm -f conftest*])
 case $libc_cv_gcc_dwarf2_unwind_info in
+no_registry_needed)
+  AC_DEFINE(HAVE_DWARF2_UNWIND_INFO)
+  ;;
 yes)
   AC_DEFINE(HAVE_DWARF2_UNWIND_INFO)
+  AC_DEFINE(HAVE_DWARF2_UNWIND_INFO_REGISTRY)
   ;;
 static)
   AC_DEFINE(HAVE_DWARF2_UNWIND_INFO)
   AC_DEFINE(HAVE_DWARF2_UNWIND_INFO_STATIC)
+  AC_DEFINE(HAVE_DWARF2_UNWIND_INFO_REGISTRY)
   ;;
 esac
 
Index: configure
===================================================================
RCS file: /cvs/glibc/libc/configure,v
retrieving revision 1.423
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.423 configure
--- configure	26 Oct 2004 01:35:53 -0000	1.423
+++ configure	8 Nov 2004 14:20:48 -0000
@@ -6378,11 +6378,21 @@ fi
 echo "$as_me:$LINENO: result: $libc_cv_gcc_dwarf2_unwind_info" >&5
 echo "${ECHO_T}$libc_cv_gcc_dwarf2_unwind_info" >&6
 case $libc_cv_gcc_dwarf2_unwind_info in
+no_registry_needed)
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_DWARF2_UNWIND_INFO 1
+_ACEOF
+
+  ;;
 yes)
   cat >>confdefs.h <<\_ACEOF
 #define HAVE_DWARF2_UNWIND_INFO 1
 _ACEOF
 
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_DWARF2_UNWIND_INFO_REGISTRY 1
+_ACEOF
+
   ;;
 static)
   cat >>confdefs.h <<\_ACEOF
@@ -6393,6 +6403,10 @@ _ACEOF
 #define HAVE_DWARF2_UNWIND_INFO_STATIC 1
 _ACEOF
 
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_DWARF2_UNWIND_INFO_REGISTRY 1
+_ACEOF
+
   ;;
 esac
 
Index: config.h.in
===================================================================
RCS file: /cvs/glibc/libc/config.h.in,v
retrieving revision 1.70
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.70 config.h.in
--- config.h.in	16 Sep 2004 23:55:55 -0000	1.70
+++ config.h.in	8 Nov 2004 14:20:51 -0000
@@ -98,6 +98,10 @@
 #undef	HAVE_DWARF2_UNWIND_INFO
 
 /* Define if gcc uses DWARF2 unwind information for exception support
+   and requires explicit calls to register the unwind tables.  */
+#undef	HAVE_DWARF2_UNWIND_INFO_REGISTRY
+
+/* Define if gcc uses DWARF2 unwind information for exception support
    with static variable. */
 #undef	HAVE_DWARF2_UNWIND_INFO_STATIC
 
Index: elf/soinit.c
===================================================================
RCS file: /cvs/glibc/libc/elf/soinit.c,v
retrieving revision 1.11
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.11 soinit.c
--- elf/soinit.c	26 Nov 2003 07:14:31 -0000	1.11
+++ elf/soinit.c	8 Nov 2004 14:20:51 -0000
@@ -28,6 +28,8 @@ run_hooks (void (*const list[]) (void))
 static char __EH_FRAME_BEGIN__[]
      __attribute__ ((section (".eh_frame")))
      = { };
+#endif
+#ifdef HAVE_DWARF2_UNWIND_INFO_REGISTRY
 # ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
 extern void __register_frame_info (const void *, struct object *);
 extern void __register_frame_info_bases (const void *, struct object *,
@@ -47,7 +49,7 @@ __libc_global_ctors (void)
   /* Call constructor functions.  */
   run_hooks (__CTOR_LIST__);
 
-#ifdef HAVE_DWARF2_UNWIND_INFO
+#ifdef HAVE_DWARF2_UNWIND_INFO_REGISTRY
 # ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
   {
     static struct object ob;
@@ -89,7 +91,7 @@ __libc_fini (void)
 {
   /* Call destructor functions.  */
   run_hooks (__DTOR_LIST__);
-#ifdef HAVE_DWARF2_UNWIND_INFO
+#ifdef HAVE_DWARF2_UNWIND_INFO_REGISTRY
 # ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
 #  if defined CRT_GET_RFIB_TEXT || defined CRT_GET_RFIB_DATA
   __deregister_frame_info_bases (__EH_FRAME_BEGIN__);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]