aboutsummaryrefslogtreecommitdiff
path: root/gcc/crtstuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/crtstuff.c')
-rw-r--r--gcc/crtstuff.c91
1 files changed, 83 insertions, 8 deletions
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index e6238de5e9b..ce2c9561e64 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -56,6 +56,8 @@ Boston, MA 02111-1307, USA. */
#include <stddef.h>
#include "frame.h"
+#ifndef OBJECT_FORMAT_MACHO
+
/* Provide default definitions for the pseudo-ops used to switch to the
.ctors and .dtors sections.
@@ -150,7 +152,7 @@ __do_global_dtors_aux ()
/* Stick a call to __do_global_dtors_aux into the .fini section. */
-static void
+static void __attribute__ ((__unused__))
fini_dummy ()
{
asm (FINI_SECTION_ASM_OP);
@@ -173,7 +175,7 @@ frame_dummy ()
__register_frame_info (__EH_FRAME_BEGIN__, &object);
}
-static void
+static void __attribute__ ((__unused__))
init_dummy ()
{
asm (INIT_SECTION_ASM_OP);
@@ -274,7 +276,7 @@ __frame_dummy ()
#endif /* defined(INIT_SECTION_ASM_OP) */
/* Force cc1 to switch to .data section. */
-static func_ptr force_to_data[0] = { };
+static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { };
/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
@@ -294,7 +296,8 @@ static func_ptr force_to_data[0] = { };
CTOR_LIST_BEGIN;
#else
asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-STATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) };
+STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__))
+ = { (func_ptr) (-1) };
#endif
#ifdef DTOR_LIST_BEGIN
@@ -334,7 +337,7 @@ __do_global_ctors_aux ()
/* Stick a call to __do_global_ctors_aux into the .init section. */
-static void
+static void __attribute__ ((__unused__))
init_dummy ()
{
asm (INIT_SECTION_ASM_OP);
@@ -406,6 +409,9 @@ asm (TEXT_SECTION_ASM_OP);
not an SVR4-style .init section. __do_global_ctors can be non-static
in this case because we protect it with -hidden_symbol. */
static func_ptr __CTOR_END__[];
+#ifdef EH_FRAME_SECTION_ASM_OP
+extern void __frame_dummy (void);
+#endif
void
__do_global_ctors ()
{
@@ -421,7 +427,7 @@ __do_global_ctors ()
#endif /* defined(INIT_SECTION_ASM_OP) */
/* Force cc1 to switch to .data section. */
-static func_ptr force_to_data[0] = { };
+static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { };
/* Put a word containing zero at the end of each of our two lists of function
addresses. Note that the words defined here go into the .ctors and .dtors
@@ -440,7 +446,8 @@ STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
DTOR_LIST_END;
#else
asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+STATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__))
+ = { (func_ptr) 0 };
#endif
#ifdef EH_FRAME_SECTION_ASM_OP
@@ -449,7 +456,75 @@ STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
typedef unsigned int ui32 __attribute__ ((mode (SI)));
asm (EH_FRAME_SECTION_ASM_OP);
-STATIC ui32 __FRAME_END__[] = { 0 };
+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 ()
+{
+ 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 ()
+{
+ 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 */
+