/* Specialized bits of code needed to support construction and
destruction of file-scope objects in C++ code.
Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
This file is part of GCC.
#include "tsystem.h"
#include "unwind-dw2-fde.h"
+#ifndef FORCE_CODE_SECTION_ALIGN
+# define FORCE_CODE_SECTION_ALIGN
+#endif
+
#ifndef CRT_CALL_STATIC_FUNCTION
-# define CRT_CALL_STATIC_FUNCTION(func) func ()
+# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
+static void __attribute__((__used__)) \
+call_ ## FUNC (void) \
+{ \
+ asm (SECTION_OP); \
+ FUNC (); \
+ FORCE_CODE_SECTION_ALIGN \
+ asm (TEXT_SECTION_ASM_OP); \
+}
+#endif
+
+#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
+ && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
+ && defined(__GLIBC__) && __GLIBC__ >= 2
+#include <link.h>
+# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
+ || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
+# define USE_PT_GNU_EH_FRAME
+# endif
+#endif
+#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
+# define USE_EH_FRAME_REGISTRY
#endif
/* We do not want to add the weak attribute to the declarations of these
in one DSO or the main program is not used in another object. The
dynamic linker takes care of this. */
-/* XXX Ideally the following should be implemented using
- __attribute__ ((__visibility__ ("hidden")))
- but the __attribute__ support is not yet there. */
#ifdef HAVE_GAS_HIDDEN
-asm (".hidden\t__dso_handle");
+extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
#endif
-
#ifdef CRTSTUFFS_O
void *__dso_handle = &__dso_handle;
#else
the list we left off processing, and we resume at that point,
should we be re-invoked. */
-static void
+static void __attribute__((used))
__do_global_dtors_aux (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
- static int completed;
+ static _Bool completed;
func_ptr f;
if (__builtin_expect (completed, 0))
f ();
}
-#ifdef EH_FRAME_SECTION_NAME
+#ifdef USE_EH_FRAME_REGISTRY
#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
/* If we used the new __register_frame_info_bases interface,
make sure that we deregister from the same place. */
completed = 1;
}
-
/* Stick a call to __do_global_dtors_aux into the .fini section. */
+CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
-static void __attribute__ ((__unused__))
-fini_dummy (void)
-{
- asm (FINI_SECTION_ASM_OP);
- CRT_CALL_STATIC_FUNCTION (__do_global_dtors_aux);
-#ifdef FORCE_FINI_SECTION_ALIGN
- FORCE_FINI_SECTION_ALIGN;
-#endif
- asm (TEXT_SECTION_ASM_OP);
-}
-
-#if defined(EH_FRAME_SECTION_NAME) || defined(JCR_SECTION_NAME)
+#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
/* Stick a call to __register_frame_info 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
+static void __attribute__((used))
frame_dummy (void)
{
-#ifdef EH_FRAME_SECTION_NAME
+#ifdef USE_EH_FRAME_REGISTRY
static struct object object;
#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
void *tbase, *dbase;
if (__register_frame_info)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
#endif
-#endif /* EH_FRAME_SECTION_NAME */
+#endif /* USE_EH_FRAME_REGISTRY */
#ifdef JCR_SECTION_NAME
if (__JCR_LIST__[0] && _Jv_RegisterClasses)
_Jv_RegisterClasses (__JCR_LIST__);
#endif /* JCR_SECTION_NAME */
}
-static void __attribute__ ((__unused__))
-init_dummy (void)
-{
- asm (INIT_SECTION_ASM_OP);
- CRT_CALL_STATIC_FUNCTION (frame_dummy);
-#ifdef FORCE_INIT_SECTION_ALIGN
- FORCE_INIT_SECTION_ALIGN;
-#endif
- asm (TEXT_SECTION_ASM_OP);
-}
-#endif /* EH_FRAME_SECTION_NAME || JCR_SECTION_NAME */
+CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
+#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
#else /* OBJECT_FORMAT_ELF */
/* A routine to invoke all of the global constructors upon entry to the
program. We put this into the .init section (for systems that have
such a thing) so that we can properly perform the construction of
- file-scope static-storage C++ objects within shared libraries. */
+ file-scope static-storage C++ objects within shared libraries. */
-static void
+static void __attribute__((used))
__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 */
-#endif
+ FORCE_CODE_SECTION_ALIGN /* explicit align before switch to .text */
asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */
DO_GLOBAL_CTORS_BODY;
atexit (__do_global_dtors);
for (p = __DTOR_LIST__ + 1; (f = *p); p++)
f ();
-#ifdef EH_FRAME_SECTION_NAME
+#ifdef USE_EH_FRAME_REGISTRY
if (__deregister_frame_info)
__deregister_frame_info (__EH_FRAME_BEGIN__);
#endif
}
-#if defined(EH_FRAME_SECTION_NAME) || defined(JCR_SECTION_NAME)
+#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
/* A helper function for __do_global_ctors, which is in crtend.o. Here
in crtbegin.o, we can reference a couple of symbols not visible there.
Plus, since we're before libgcc.a, we have no problems referencing
void
__do_global_ctors_1(void)
{
-#ifdef EH_FRAME_SECTION_NAME
+#ifdef USE_EH_FRAME_REGISTRY
static struct object object;
if (__register_frame_info)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
_Jv_RegisterClasses (__JCR_LIST__);
#endif
}
-#endif /* EH_FRAME_SECTION_NAME || JCR_SECTION_NAME */
+#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
#error "What are you doing with crtstuff.c, then?"
__attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
aligned(4)))
= { 0 };
-#endif /* EH_FRAME_SECTION */
+#endif /* EH_FRAME_SECTION_NAME */
#ifdef JCR_SECTION_NAME
/* Null terminate the .jcr section array. */
#ifdef INIT_SECTION_ASM_OP
#ifdef OBJECT_FORMAT_ELF
-
-static void
+static void __attribute__((used))
__do_global_ctors_aux (void)
{
func_ptr *p;
}
/* Stick a call to __do_global_ctors_aux into the .init section. */
-
-static void __attribute__ ((__unused__))
-init_dummy (void)
-{
- asm (INIT_SECTION_ASM_OP);
- CRT_CALL_STATIC_FUNCTION (__do_global_ctors_aux);
-#ifdef FORCE_INIT_SECTION_ALIGN
- FORCE_INIT_SECTION_ALIGN;
-#endif
- asm (TEXT_SECTION_ASM_OP);
-#ifdef CRT_END_INIT_DUMMY
- CRT_END_INIT_DUMMY;
-#endif
-}
-
+CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux)
#else /* OBJECT_FORMAT_ELF */
/* Stick the real initialization code, followed by a normal sort of
atexit (__do_global_dtors);
} /* epilogue and body go in .init section */
-#ifdef FORCE_INIT_SECTION_ALIGN
-FORCE_INIT_SECTION_ALIGN;
-#endif
-
+FORCE_CODE_SECTION_ALIGN
asm (TEXT_SECTION_ASM_OP);
#endif /* OBJECT_FORMAT_ELF */
__do_global_ctors (void)
{
func_ptr *p;
-#if defined(EH_FRAME_SECTION_NAME) || defined(JCR_SECTION_NAME)
+#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
__do_global_ctors_1();
#endif
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)