diff options
author | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-13 03:44:54 +0000 |
---|---|---|
committer | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-13 03:44:54 +0000 |
commit | a08b74c8bf89232cd59a439190b786dae8a87a5f (patch) | |
tree | 9d8b83093127fbc3b7a523ef893b097ff59eb9b5 /gcc/crtstuff.c | |
parent | 9f6ef744447d2da6c300f71e8f22802d0064b1f5 (diff) | |
download | gcc-a08b74c8bf89232cd59a439190b786dae8a87a5f.tar.gz |
* target.h (struct gcc_target): New field
terminate_dw2_eh_frame_info.
* target-def.h (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
(TARGET_INITIALIZER): Add it.
* dwarf2out.c (output_call_frame_info): Use target hook.
* dwarf2asm.c (dw2_asm_output_delta): Use macro
ASM_OUTPUT_DWARF_DELTA if defined.
* doc/tm.texi (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Document.
(ASM_OUTPUT_DWARF_DELTA): Ditto.
(ASM_OUTPUT_DWARF_OFFSET): Ditto.
(ASM_OUTPUT_DWARF_PCREL): Ditto.
* config.gcc (i[34567]86-*-darwin*): Define extra_parts.
(powerpc-*-darwin*): Ditto.
* crtstuff.c [OBJECT_FORMAT_MACHO]: Update the Mach-O bits
to work correctly for Darwin.
* config/darwin.h (OBJECT_FORMAT_MACHO): Define.
(STARTFILE_SPEC): Add crtbegin.o.
(ENDFILE_SPEC): Define.
(EXTRA_SECTION_FUNCTIONS): Put gcc_except_tab in data segment.
(ASM_PREFERRED_EH_DATA_FORMAT): Handle more cases.
(ASM_OUTPUT_DWARF_DELTA): Define.
(TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
* config/darwin.c (darwin_asm_output_dwarf_delta): New function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57089 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/crtstuff.c')
-rw-r--r-- | gcc/crtstuff.c | 100 |
1 files changed, 58 insertions, 42 deletions
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c index 041c810f6f4..125e236ee9c 100644 --- a/gcc/crtstuff.c +++ b/gcc/crtstuff.c @@ -545,64 +545,80 @@ __do_global_ctors (void) #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 *); +/* Crt stuff for Mach-O (NeXT and Darwin). + + The theory of this is that each dynamically-loadable module, + including the main program itself, must have been positioned by + dyld before any frame info can be registered. So we set up the + registration functions as dyld hooks, using a "preregistration" + function that is called directly from the system crt1.o. */ #ifdef CRT_BEGIN -static void __reg_frame_ctor (void) __attribute__ ((constructor)); +/* Homemade decls substituting for getsect.h and dyld.h, so cross + compilation works. */ +struct mach_header; +extern char *getsectdatafromheader (struct mach_header *, const char *, + const char *, unsigned long *); +extern void _dyld_register_func_for_add_image + (void (*) (struct mach_header *, unsigned long)); +extern void _dyld_register_func_for_remove_image + (void (*) (struct mach_header *, unsigned long)); + +extern void __darwin_gcc3_preregister_frame_info (void); static void -__reg_frame_ctor (void) +unwind_dyld_add_image_hook (struct mach_header *mh, + unsigned long vm_slide) { - static struct object object; - const struct section *eh_frame; + unsigned long sz; + char *fde; - eh_frame = getsectbynamefromheader (&_mh_execute_header, - "__TEXT", "__eh_frame"); - __register_frame_info ((void *) eh_frame->addr, &object); -} - -#elif defined(CRT_END) + fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz); + if (fde) + { + struct object *ob = (struct object *) malloc (sizeof (struct object)); -static void __dereg_frame_dtor (void) __attribute__ ((destructor)); + __register_frame_info (fde + vm_slide, ob); + } +} static void -__dereg_frame_dtor (void) +unwind_dyld_remove_image_hook (struct mach_header *mh, + unsigned long vm_slide) { - const struct section *eh_frame; + unsigned long sz; + char *fde; + + fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz); - eh_frame = getsectbynamefromheader (&_mh_execute_header, - "__TEXT", "__eh_frame"); - __deregister_frame_info ((void *) eh_frame->addr); + if (fde) + __deregister_frame_info (fde + vm_slide); } -/* Terminate the frame section with a final zero. */ -STATIC int __FRAME_END__[] - __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME), - aligned(4))) - = { 0 }; +/* Call this routine from the system crt1.o. The call is standard in + Darwin 6.x (Mac OS X 10.2) and later; for earlier systems, you + would need to modify crt.c in the Csu project. (This isn't great, + but other alternatives run afoul of linker semantics. This + function is declared as common and tested before being called, so + that programs compiled by older GCCs still link and run.) */ + +void +__darwin_gcc3_preregister_frame_info () +{ + _dyld_register_func_for_add_image (unwind_dyld_add_image_hook); + _dyld_register_func_for_remove_image (unwind_dyld_remove_image_hook); +} + +#elif defined(CRT_END) /* ! CRT_BEGIN */ + +/* Install a single zero word at the end of the __eh_frame section. */ + +asm (".section __TEXT,__eh_frame"); +asm (".long 0"); #else /* ! CRT_BEGIN && ! CRT_END */ #error "One of CRT_BEGIN or CRT_END must be defined." #endif -#endif /* OBJECT_FORMAT_MACHO */ +#endif /* OBJECT_FORMAT_MACHO */ |