summaryrefslogtreecommitdiff
path: root/gcc/crtstuff.c
diff options
context:
space:
mode:
authorshebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-13 03:44:54 +0000
committershebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-13 03:44:54 +0000
commita08b74c8bf89232cd59a439190b786dae8a87a5f (patch)
tree9d8b83093127fbc3b7a523ef893b097ff59eb9b5 /gcc/crtstuff.c
parent9f6ef744447d2da6c300f71e8f22802d0064b1f5 (diff)
downloadgcc-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.c100
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 */