diff options
Diffstat (limited to 'contrib/gcc/crtstuff.c')
-rw-r--r-- | contrib/gcc/crtstuff.c | 107 |
1 files changed, 84 insertions, 23 deletions
diff --git a/contrib/gcc/crtstuff.c b/contrib/gcc/crtstuff.c index a1b9ef8..ccebde1 100644 --- a/contrib/gcc/crtstuff.c +++ b/contrib/gcc/crtstuff.c @@ -56,17 +56,6 @@ Boston, MA 02111-1307, USA. */ #include <stddef.h> #include "frame.h" -/* This really belongs in gansidecl.h, but for the egcs-1.1.x branch, the - only code which uses weak attributes is in this file and this file does - not include gansidecl.h. */ -#ifndef TARGET_ATTRIBUTE_WEAK -# if SUPPORTS_WEAK -# define TARGET_ATTRIBUTE_WEAK __attribute__ ((weak)) -# else -# define TARGET_ATTRIBUTE_WEAK -# endif -#endif - /* We do not want to add the weak attribute to the declarations of these routines in frame.h because that will cause the definition of these symbols to be weak as well. @@ -95,6 +84,8 @@ extern void __register_frame_info (void *, struct object *) extern void *__deregister_frame_info (void *) TARGET_ATTRIBUTE_WEAK; +#ifndef OBJECT_FORMAT_MACHO + /* Provide default definitions for the pseudo-ops used to switch to the .ctors and .dtors sections. @@ -166,7 +157,7 @@ typedef void (*func_ptr) (void); static char __EH_FRAME_BEGIN__[]; static func_ptr __DTOR_LIST__[]; static void -__do_global_dtors_aux () +__do_global_dtors_aux (void) { static func_ptr *p = __DTOR_LIST__ + 1; static int completed = 0; @@ -191,7 +182,7 @@ __do_global_dtors_aux () /* Stick a call to __do_global_dtors_aux into the .fini section. */ static void __attribute__ ((__unused__)) -fini_dummy () +fini_dummy (void) { asm (FINI_SECTION_ASM_OP); __do_global_dtors_aux (); @@ -207,7 +198,7 @@ fini_dummy () call in another function. */ static void -frame_dummy () +frame_dummy (void) { static struct object object; if (__register_frame_info) @@ -215,7 +206,7 @@ frame_dummy () } static void __attribute__ ((__unused__)) -init_dummy () +init_dummy (void) { asm (INIT_SECTION_ASM_OP); frame_dummy (); @@ -236,7 +227,8 @@ init_dummy () to switch to the .text section. */ static void __do_global_ctors_aux (); -void __do_global_ctors () +void +__do_global_ctors (void) { #ifdef INVOKE__main /* If __main won't actually call __do_global_ctors then it doesn't matter what's inside the function. @@ -266,7 +258,7 @@ asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ file-scope static-storage C++ objects within shared libraries. */ static void -__do_global_ctors_aux () /* prologue goes in .init section */ +__do_global_ctors_aux (void) /* prologue goes in .init section */ { #ifdef FORCE_INIT_SECTION_ALIGN FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */ @@ -288,7 +280,7 @@ __do_global_ctors_aux () /* prologue goes in .init section */ static char __EH_FRAME_BEGIN__[]; static func_ptr __DTOR_LIST__[]; void -__do_global_dtors () +__do_global_dtors (void) { func_ptr *p; for (p = __DTOR_LIST__ + 1; *p; p++) @@ -305,7 +297,7 @@ __do_global_dtors () after libgcc.a, and hence can't call libgcc.a functions directly. That can lead to unresolved function references. */ void -__frame_dummy () +__frame_dummy (void) { static struct object object; if (__register_frame_info) @@ -369,7 +361,7 @@ char __EH_FRAME_BEGIN__[] = { }; static func_ptr __CTOR_END__[]; static void -__do_global_ctors_aux () +__do_global_ctors_aux (void) { func_ptr *p; for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) @@ -379,7 +371,7 @@ __do_global_ctors_aux () /* Stick a call to __do_global_ctors_aux into the .init section. */ static void __attribute__ ((__unused__)) -init_dummy () +init_dummy (void) { asm (INIT_SECTION_ASM_OP); __do_global_ctors_aux (); @@ -428,7 +420,7 @@ init_dummy () before we start to execute any of the user's code. */ static void -__do_global_ctors_aux () /* prologue goes in .text section */ +__do_global_ctors_aux (void) /* prologue goes in .text section */ { asm (INIT_SECTION_ASM_OP); DO_GLOBAL_CTORS_BODY; @@ -454,7 +446,7 @@ static func_ptr __CTOR_END__[]; extern void __frame_dummy (void); #endif void -__do_global_ctors () +__do_global_ctors (void) { func_ptr *p; #ifdef EH_FRAME_SECTION_ASM_OP @@ -501,3 +493,72 @@ STATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 }; #endif /* EH_FRAME_SECTION */ #endif /* defined(CRT_END) */ + +#else /* OBJECT_FORMAT_MACHO */ + +/* For Mach-O format executables, we assume that the system's runtime is + smart enough to handle constructors and destructors, but doesn't have + an init section (if it can't even handle constructors/destructors + you should be using INVOKE__main, not crtstuff). All we need to do + is install/deinstall the frame information for exceptions. We do this + by putting a constructor in crtbegin.o and a destructor in crtend.o. + + crtend.o also puts in the terminating zero in the frame information + segment. */ + +/* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__ + to figure out the start of the exception frame, but here we use + getsectbynamefromheader to find this value. Either method would work, + but this method avoids creating any global symbols, which seems + cleaner. */ + +#include <mach-o/ldsyms.h> +extern const struct section * + getsectbynamefromheader (const struct mach_header *, + const char *, const char *); + +#ifdef CRT_BEGIN + +static void __reg_frame_ctor () __attribute__ ((constructor)); + +static void +__reg_frame_ctor (void) +{ + static struct object object; + const struct section *eh_frame; + + eh_frame = getsectbynamefromheader (&_mh_execute_header, + "__TEXT", "__eh_frame"); + __register_frame_info ((void *) eh_frame->addr, &object); +} + +#endif /* CRT_BEGIN */ + +#ifdef CRT_END + +static void __dereg_frame_dtor () __attribute__ ((destructor)); + +static +void +__dereg_frame_dtor (void) +{ + const struct section *eh_frame; + + eh_frame = getsectbynamefromheader (&_mh_execute_header, + "__TEXT", "__eh_frame"); + __deregister_frame_info ((void *) eh_frame->addr); +} + +/* Terminate the frame section with a final zero. */ + +/* Force cc1 to switch to .data section. */ +static void * force_to_data[0] __attribute__ ((__unused__)) = { }; + +typedef unsigned int ui32 __attribute__ ((mode (SI))); +asm (EH_FRAME_SECTION_ASM_OP); +static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 }; + +#endif /* CRT_END */ + +#endif /* OBJECT_FORMAT_MACHO */ + |