aboutsummaryrefslogtreecommitdiff
path: root/gcc/crtstuff.c
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>1997-09-10 14:00:28 -0400
committerJason Merrill <jason@gcc.gnu.org>1997-09-10 14:00:28 -0400
commit0021b564f4ce0b648a8d6ec49b29afe609370788 (patch)
tree0928096722cf7e87c6973bd7bb029f787ab959db /gcc/crtstuff.c
parent0680d170431a1a44f958ca97a9ce01ea12b676b6 (diff)
downloadgcc-0021b564f4ce0b648a8d6ec49b29afe609370788.zip
gcc-0021b564f4ce0b648a8d6ec49b29afe609370788.tar.gz
gcc-0021b564f4ce0b648a8d6ec49b29afe609370788.tar.bz2
dwarf2 EH support
From-SVN: r15255
Diffstat (limited to 'gcc/crtstuff.c')
-rw-r--r--gcc/crtstuff.c66
1 files changed, 64 insertions, 2 deletions
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index 2c68243..bcb5cc5 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -52,6 +52,7 @@ Boston, MA 02111-1307, USA. */
do not apply. */
#include "tm.h"
+#include "defaults.h"
/* Provide default definitions for the pseudo-ops used to switch to the
.ctors and .dtors sections.
@@ -75,6 +76,9 @@ Boston, MA 02111-1307, USA. */
#ifndef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
#endif
+#if !defined (EH_FRAME_SECTION_ASM_OP) && defined (DWARF2_UNWIND_INFO) && defined(ASM_OUTPUT_SECTION_NAME)
+#define EH_FRAME_SECTION_ASM_OP ".section\t.eh_frame,\"aw\""
+#endif
#ifdef OBJECT_FORMAT_ELF
@@ -118,6 +122,7 @@ typedef void (*func_ptr) (void);
the list we left off processing, and we resume at that point,
should we be re-invoked. */
+static char __EH_FRAME_BEGIN__[];
static func_ptr __DTOR_LIST__[];
static void
__do_global_dtors_aux ()
@@ -128,6 +133,10 @@ __do_global_dtors_aux ()
p++;
(*(p-1)) ();
}
+
+#ifdef EH_FRAME_SECTION_ASM_OP
+ __deregister_frame (__EH_FRAME_BEGIN__);
+#endif
}
/* Stick a call to __do_global_dtors_aux into the .fini section. */
@@ -143,6 +152,29 @@ fini_dummy ()
asm (TEXT_SECTION_ASM_OP);
}
+#ifdef EH_FRAME_SECTION_ASM_OP
+/* Stick a call to __register_frame into the .init section. For some reason
+ calls with no arguments work more reliably in .init, so stick the call
+ in another function. */
+
+static void
+frame_dummy ()
+{
+ __register_frame (__EH_FRAME_BEGIN__);
+}
+
+static void
+init_dummy ()
+{
+ asm (INIT_SECTION_ASM_OP);
+ frame_dummy ();
+#ifdef FORCE_INIT_SECTION_ALIGN
+ FORCE_INIT_SECTION_ALIGN;
+#endif
+ asm (TEXT_SECTION_ASM_OP);
+}
+#endif /* EH_FRAME_SECTION_ASM_OP */
+
#else /* OBJECT_FORMAT_ELF */
/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
@@ -200,7 +232,9 @@ __do_global_ctors_aux () /* prologue goes in .init section */
#ifdef HAS_INIT_SECTION
/* This case is used by the Irix 6 port, which supports named sections but
not an SVR4-style .fini section. __do_global_dtors can be non-static
- in this case because the -fini switch to ld binds strongly. */
+ in this case because we protect it with -hidden_symbol. */
+
+static char __EH_FRAME_BEGIN__[];
static func_ptr __DTOR_LIST__[];
void
__do_global_dtors ()
@@ -208,6 +242,10 @@ __do_global_dtors ()
func_ptr *p;
for (p = __DTOR_LIST__ + 1; *p; p++)
(*p) ();
+
+#ifdef EH_FRAME_SECTION_ASM_OP
+ __deregister_frame (__EH_FRAME_BEGIN__);
+#endif
}
#endif
@@ -244,6 +282,17 @@ asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
#endif
+#ifdef EH_FRAME_SECTION_ASM_OP
+/* Stick a label at the beginning of the frame unwind info so we can register
+ and deregister it with the exception handling library code. */
+
+asm (EH_FRAME_SECTION_ASM_OP);
+#ifdef INIT_SECTION_ASM_OP
+STATIC
+#endif
+char __EH_FRAME_BEGIN__[] = { };
+#endif /* EH_FRAME_SECTION_ASM_OP */
+
#endif /* defined(CRT_BEGIN) */
#ifdef CRT_END
@@ -327,12 +376,16 @@ __do_global_ctors_aux () /* prologue goes in .text section */
#ifdef HAS_INIT_SECTION
/* This case is used by the Irix 6 port, which supports named sections but
not an SVR4-style .init section. __do_global_ctors can be non-static
- in this case because the -init switch to ld binds strongly. */
+ in this case because we protect it with -hidden_symbol. */
+extern char __EH_FRAME_BEGIN__[];
static func_ptr __CTOR_END__[];
void
__do_global_ctors ()
{
func_ptr *p;
+#ifdef EH_FRAME_SECTION_ASM_OP
+ __register_frame (__EH_FRAME_BEGIN__);
+#endif
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p) ();
}
@@ -363,4 +416,13 @@ asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
#endif
+#ifdef EH_FRAME_SECTION_ASM_OP
+/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
+ this would be the 'length' field in a real FDE. */
+
+typedef unsigned int ui32 __attribute__ ((mode (SI)));
+asm (EH_FRAME_SECTION_ASM_OP);
+STATIC ui32 __FRAME_END__[] = { 0 };
+#endif /* EH_FRAME_SECTION */
+
#endif /* defined(CRT_END) */