summaryrefslogtreecommitdiff
path: root/elf/soinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/soinit.c')
-rw-r--r--elf/soinit.c69
1 files changed, 65 insertions, 4 deletions
diff --git a/elf/soinit.c b/elf/soinit.c
index c0a881ef5d..2015ea2d66 100644
--- a/elf/soinit.c
+++ b/elf/soinit.c
@@ -6,6 +6,10 @@
#include <libc-internal.h>
#include <stdlib.h>
+#ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
+# include <gccframe.h>
+#endif
+
static void (*const __CTOR_LIST__[1]) (void)
__attribute__ ((section (".ctors")))
= { (void (*) (void)) -1 };
@@ -20,9 +24,21 @@ run_hooks (void (*const list[]) (void))
(**list) ();
}
-static const char __EH_FRAME_BEGIN__[]
- __attribute__ ((used, section (".eh_frame")))
- = { };
+#ifdef HAVE_DWARF2_UNWIND_INFO
+static char __EH_FRAME_BEGIN__[]
+ __attribute__ ((section (".eh_frame")))
+ = { };
+# 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 *,
+ void *, void *);
+extern void __deregister_frame_info (const void *);
+extern void __deregister_frame_info_bases (const void *);
+# else
+extern void __register_frame (const void *);
+extern void __deregister_frame (const void *);
+# endif
+#endif
/* This function will be called from _init in init-first.c. */
void
@@ -30,17 +46,62 @@ __libc_global_ctors (void)
{
/* Call constructor functions. */
run_hooks (__CTOR_LIST__);
+
+#ifdef HAVE_DWARF2_UNWIND_INFO
+# ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
+ {
+ static struct object ob;
+# if defined CRT_GET_RFIB_TEXT || defined CRT_GET_RFIB_DATA
+ void *tbase, *dbase;
+
+# ifdef CRT_GET_RFIB_TEXT
+ CRT_GET_RFIB_TEXT (tbase);
+# else
+ tbase = NULL;
+# endif
+# ifdef CRT_GET_RFIB_DATA
+ CRT_GET_RFIB_DATA (dbase);
+# else
+ dbase = NULL;
+# endif
+ __register_frame_info_bases (__EH_FRAME_BEGIN__, &ob, tbase, dbase);
+# else
+ __register_frame_info (__EH_FRAME_BEGIN__, &ob);
+# endif
+ }
+# else
+ __register_frame (__EH_FRAME_BEGIN__);
+# endif
+#endif
}
/* This function becomes the DT_FINI termination function
for the C library. */
+#ifndef HAVE_INITFINI_ARRAY
+void _fini (void) __attribute__ ((section (".fini"))); /* Just for kicks. */
+void
+_fini (void)
+#else
void
__libc_fini (void)
+#endif
{
/* Call destructor functions. */
run_hooks (__DTOR_LIST__);
+#ifdef HAVE_DWARF2_UNWIND_INFO
+# ifdef HAVE_DWARF2_UNWIND_INFO_STATIC
+# if defined CRT_GET_RFIB_TEXT || defined CRT_GET_RFIB_DATA
+ __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
+# else
+ __deregister_frame_info (__EH_FRAME_BEGIN__);
+# endif
+# else
+ __deregister_frame (__EH_FRAME_BEGIN__);
+# endif
+#endif
}
-
+#ifdef HAVE_INITFINI_ARRAY
void (*_fini_ptr) (void) __attribute__ ((section (".fini_array")))
= &__libc_fini;
+#endif