diff options
author | Jason Merrill <jason@gcc.gnu.org> | 1997-09-10 14:00:28 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1997-09-10 14:00:28 -0400 |
commit | 0021b564f4ce0b648a8d6ec49b29afe609370788 (patch) | |
tree | 0928096722cf7e87c6973bd7bb029f787ab959db /gcc/crtstuff.c | |
parent | 0680d170431a1a44f958ca97a9ce01ea12b676b6 (diff) | |
download | gcc-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.c | 66 |
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) */ |