/* Specialized bits of code needed to support construction and
destruction of file-scope objects in C++ code.
- Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
This file is part of GNU CC.
do not apply. */
#include "tm.h"
+#include "defaults.h"
+#include <stddef.h>
+#include "frame.h"
/* Provide default definitions for the pseudo-ops used to switch to the
.ctors and .dtors sections.
#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
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 ()
{
static func_ptr *p = __DTOR_LIST__ + 1;
+ static int completed = 0;
+
+ if (completed)
+ return;
+
while (*p)
{
p++;
(*(p-1)) ();
}
+
+#ifdef EH_FRAME_SECTION_ASM_OP
+ __deregister_frame (__EH_FRAME_BEGIN__);
+#endif
+ completed = 1;
}
+
/* Stick a call to __do_global_dtors_aux into the .fini section. */
static void
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 ()
+{
+ static struct object object;
+ __register_frame (__EH_FRAME_BEGIN__, &object);
+}
+
+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
#else /* defined(INIT_SECTION_ASM_OP) */
+#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 ()
func_ptr *p;
for (p = __DTOR_LIST__ + 1; *p; p++)
(*p) ();
+
+#ifdef EH_FRAME_SECTION_ASM_OP
+ __deregister_frame (__EH_FRAME_BEGIN__);
+#endif
}
+#endif
#endif /* defined(INIT_SECTION_ASM_OP) */
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
#endif
asm (TEXT_SECTION_ASM_OP);
-/* This is a kludge. The i386 Linux dynamic linker needs ___brk_addr,
+/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr,
__environ and atexit (). We have to make sure they are in the .dynsym
section. We accomplish it by making a dummy call here. This
code is never reached. */
#else /* defined(INIT_SECTION_ASM_OP) */
+#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
+ static struct oobject object;
+ __register_frame (__EH_FRAME_BEGIN__, &object);
+#endif
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p) ();
}
+#endif
#endif /* defined(INIT_SECTION_ASM_OP) */
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) */