crtstuff.c revision 267654
155714Skris/* Specialized bits of code needed to support construction and
255714Skris   destruction of file-scope objects in C++ code.
355714Skris   Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998,
455714Skris   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
555714Skris   Contributed by Ron Guilmette (rfg@monkeys.com).
655714Skris
755714SkrisThis file is part of GCC.
855714Skris
955714SkrisGCC is free software; you can redistribute it and/or modify it under
1055714Skristhe terms of the GNU General Public License as published by the Free
1159191SkrisSoftware Foundation; either version 2, or (at your option) any later
1255714Skrisversion.
1355714Skris
1455714SkrisIn addition to the permissions in the GNU General Public License, the
1555714SkrisFree Software Foundation gives you unlimited permission to link the
1655714Skriscompiled version of this file into combinations with other programs,
1755714Skrisand to distribute those combinations without any restriction coming
1855714Skrisfrom the use of this file.  (The General Public License restrictions
1955714Skrisdo apply in other respects; for example, they cover modification of
2055714Skristhe file, and distribution when not linked into a combine
2155714Skrisexecutable.)
2255714Skris
2355714SkrisGCC is distributed in the hope that it will be useful, but WITHOUT ANY
2455714SkrisWARRANTY; without even the implied warranty of MERCHANTABILITY or
2555714SkrisFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
2655714Skrisfor more details.
2755714Skris
2855714SkrisYou should have received a copy of the GNU General Public License
2955714Skrisalong with GCC; see the file COPYING.  If not, write to the Free
3055714SkrisSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
3155714Skris02110-1301, USA.  */
3255714Skris
3355714Skris/* This file is a bit like libgcc2.c in that it is compiled
3455714Skris   multiple times and yields multiple .o files.
3555714Skris
3655714Skris   This file is useful on target machines where the object file format
3755714Skris   supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE).  On
3855714Skris   such systems, this file allows us to avoid running collect (or any
3955714Skris   other such slow and painful kludge).  Additionally, if the target
4055714Skris   system supports a .init section, this file allows us to support the
4155714Skris   linking of C++ code with a non-C++ main program.
4255714Skris
4355714Skris   Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then
4455714Skris   this file *will* make use of the .init section.  If that symbol is
4555714Skris   not defined however, then the .init section will not be used.
4655714Skris
4755714Skris   Currently, only ELF and COFF are supported.  It is likely however that
4855714Skris   ROSE could also be supported, if someone was willing to do the work to
4955714Skris   make whatever (small?) adaptations are needed.  (Some work may be
5055714Skris   needed on the ROSE assembler and linker also.)
5155714Skris
5255714Skris   This file must be compiled with gcc.  */
5355714Skris
5455714Skris/* Target machine header files require this define. */
5568651Skris#define IN_LIBGCC2
5668651Skris
5755714Skris/* FIXME: Including auto-host is incorrect, but until we have
5855714Skris   identified the set of defines that need to go into auto-target.h,
5955714Skris   this will have to do.  */
6055714Skris#include "auto-host.h"
6155714Skris#undef gid_t
6255714Skris#undef pid_t
6355714Skris#undef rlim_t
6459191Skris#undef ssize_t
6555714Skris#undef uid_t
6655714Skris#undef vfork
6755714Skris#include "tconfig.h"
6855714Skris#include "tsystem.h"
6968651Skris#include "coretypes.h"
7055714Skris#include "tm.h"
7155714Skris#include "unwind-dw2-fde.h"
7255714Skris
7355714Skris#ifndef FORCE_CODE_SECTION_ALIGN
7455714Skris# define FORCE_CODE_SECTION_ALIGN
7555714Skris#endif
7655714Skris
7755714Skris#ifndef CRT_CALL_STATIC_FUNCTION
7855714Skris# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
7955714Skrisstatic void __attribute__((__used__))			\
8055714Skriscall_ ## FUNC (void)					\
8155714Skris{							\
8255714Skris  asm (SECTION_OP);					\
8355714Skris  FUNC ();						\
8455714Skris  FORCE_CODE_SECTION_ALIGN				\
8555714Skris  asm (TEXT_SECTION_ASM_OP);				\
8655714Skris}
8755714Skris#endif
8855714Skris
8955714Skris#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
9055714Skris    && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
9155714Skris    && defined(__GLIBC__) && __GLIBC__ >= 2
9255714Skris#include <link.h>
9355714Skris# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
9455714Skris     || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
9555714Skris#  define USE_PT_GNU_EH_FRAME
9655714Skris# endif
9755714Skris#endif
9855714Skris#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
9955714Skris# define USE_EH_FRAME_REGISTRY
10055714Skris#endif
101100936Snectar#if defined(EH_FRAME_SECTION_NAME) && EH_TABLES_CAN_BE_READ_ONLY
10255714Skris# define EH_FRAME_SECTION_CONST const
10355714Skris#else
10455714Skris# define EH_FRAME_SECTION_CONST
10555714Skris#endif
10655714Skris
10755714Skris/* We do not want to add the weak attribute to the declarations of these
10855714Skris   routines in unwind-dw2-fde.h because that will cause the definition of
10955714Skris   these symbols to be weak as well.
11055714Skris
11155714Skris   This exposes a core issue, how to handle creating weak references vs
11255714Skris   how to create weak definitions.  Either we have to have the definition
11355714Skris   of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or
11455714Skris   have a second declaration if we want a function's references to be weak,
11555714Skris   but not its definition.
11655714Skris
11755714Skris   Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
11855714Skris   one thinks about scaling to larger problems -- i.e., the condition under
11955714Skris   which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
12055714Skris   complicated.
12155714Skris
12255714Skris   So, we take an approach similar to #pragma weak -- we have a second
12355714Skris   declaration for functions that we want to have weak references.
12455714Skris
12555714Skris   Neither way is particularly good.  */
12655714Skris
12755714Skris/* References to __register_frame_info and __deregister_frame_info should
12855714Skris   be weak in this file if at all possible.  */
12955714Skrisextern void __register_frame_info (const void *, struct object *)
13055714Skris				  TARGET_ATTRIBUTE_WEAK;
13155714Skrisextern void __register_frame_info_bases (const void *, struct object *,
13255714Skris					 void *, void *)
13355714Skris				  TARGET_ATTRIBUTE_WEAK;
13455714Skrisextern void *__deregister_frame_info (const void *)
13555714Skris				     TARGET_ATTRIBUTE_WEAK;
13655714Skrisextern void *__deregister_frame_info_bases (const void *)
13755714Skris				     TARGET_ATTRIBUTE_WEAK;
13855714Skrisextern void __do_global_ctors_1 (void);
13955714Skris
14055714Skris/* Likewise for _Jv_RegisterClasses.  */
14155714Skrisextern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
14255714Skris
14355714Skris#ifdef OBJECT_FORMAT_ELF
14455714Skris
14555714Skris/*  Declare a pointer to void function type.  */
14655714Skristypedef void (*func_ptr) (void);
14755714Skris#define STATIC static
14855714Skris
14955714Skris#else  /* OBJECT_FORMAT_ELF */
15055714Skris
15155714Skris#include "gbl-ctors.h"
15255714Skris
15355714Skris#define STATIC
15455714Skris
15555714Skris#endif /* OBJECT_FORMAT_ELF */
15655714Skris
15755714Skris#ifdef CRT_BEGIN
15855714Skris
15955714Skris/* NOTE:  In order to be able to support SVR4 shared libraries, we arrange
16055714Skris   to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
16155714Skris   __DTOR_END__ } per root executable and also one set of these symbols
16255714Skris   per shared library.  So in any given whole process image, we may have
16355714Skris   multiple definitions of each of these symbols.  In order to prevent
16455714Skris   these definitions from conflicting with one another, and in order to
16555714Skris   ensure that the proper lists are used for the initialization/finalization
16655714Skris   of each individual shared library (respectively), we give these symbols
16755714Skris   only internal (i.e. `static') linkage, and we also make it a point to
16855714Skris   refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
16955714Skris   symbol in crtbegin.o, where they are defined.  */
17055714Skris
17155714Skris/* The -1 is a flag to __do_global_[cd]tors indicating that this table
17255714Skris   does not start with a count of elements.  */
17355714Skris#ifdef CTOR_LIST_BEGIN
17455714SkrisCTOR_LIST_BEGIN;
17555714Skris#elif defined(CTORS_SECTION_ASM_OP)
17655714Skris/* Hack: force cc1 to switch to .data section early, so that assembling
17755714Skris   __CTOR_LIST__ does not undo our behind-the-back change to .ctors.  */
17855714Skrisstatic func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
17955714Skrisasm (CTORS_SECTION_ASM_OP);
18055714SkrisSTATIC func_ptr __CTOR_LIST__[1]
18155714Skris  __attribute__ ((__used__, aligned(sizeof(func_ptr))))
18255714Skris  = { (func_ptr) (-1) };
18355714Skris#else
18455714SkrisSTATIC func_ptr __CTOR_LIST__[1]
18555714Skris  __attribute__ ((__used__, section(".ctors"), aligned(sizeof(func_ptr))))
18655714Skris  = { (func_ptr) (-1) };
18755714Skris#endif /* __CTOR_LIST__ alternatives */
18855714Skris
18955714Skris#ifdef DTOR_LIST_BEGIN
19055714SkrisDTOR_LIST_BEGIN;
19155714Skris#elif defined(DTORS_SECTION_ASM_OP)
19255714Skrisasm (DTORS_SECTION_ASM_OP);
19355714SkrisSTATIC func_ptr __DTOR_LIST__[1]
19455714Skris  __attribute__ ((used, aligned(sizeof(func_ptr))))
19555714Skris  = { (func_ptr) (-1) };
19655714Skris#else
19755714SkrisSTATIC func_ptr __DTOR_LIST__[1]
19855714Skris  __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr))))
19955714Skris  = { (func_ptr) (-1) };
20055714Skris#endif /* __DTOR_LIST__ alternatives */
20155714Skris
20255714Skris#ifdef USE_EH_FRAME_REGISTRY
20355714Skris/* Stick a label at the beginning of the frame unwind info so we can register
20455714Skris   and deregister it with the exception handling library code.  */
20568651SkrisSTATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
20655714Skris     __attribute__((used, section(EH_FRAME_SECTION_NAME), aligned(4)))
20755714Skris     = { };
20855714Skris#endif /* USE_EH_FRAME_REGISTRY */
20955714Skris
21055714Skris#ifdef JCR_SECTION_NAME
21155714Skris/* Stick a label at the beginning of the java class registration info
21255714Skris   so we can register them properly.  */
21355714SkrisSTATIC void *__JCR_LIST__[]
21455714Skris  __attribute__ ((used, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
21555714Skris  = { };
21655714Skris#endif /* JCR_SECTION_NAME */
21755714Skris
21855714Skris#if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
21955714Skris
22055714Skris#ifdef OBJECT_FORMAT_ELF
22155714Skris
22255714Skris/* Declare the __dso_handle variable.  It should have a unique value
22368651Skris   in every shared-object; in a main program its value is zero.  The
22468651Skris   object should in any case be protected.  This means the instance
22568651Skris   in one DSO or the main program is not used in another object.  The
22668651Skris   dynamic linker takes care of this.  */
22755714Skris
22855714Skris#ifdef TARGET_LIBGCC_SDATA_SECTION
22955714Skrisextern void *__dso_handle __attribute__ ((__section__ (TARGET_LIBGCC_SDATA_SECTION)));
23055714Skris#endif
23155714Skris#ifdef HAVE_GAS_HIDDEN
23255714Skrisextern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
23355714Skris#endif
23455714Skris#ifdef CRTSTUFFS_O
23555714Skrisvoid *__dso_handle = &__dso_handle;
23655714Skris#else
23755714Skrisvoid *__dso_handle = 0;
23855714Skris#endif
23955714Skris
24055714Skris/* The __cxa_finalize function may not be available so we use only a
24155714Skris   weak declaration.  */
24255714Skrisextern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
24355714Skris
24455714Skris/* Run all the global destructors on exit from the program.  */
24555714Skris
24655714Skris/* Some systems place the number of pointers in the first word of the
24755714Skris   table.  On SVR4 however, that word is -1.  In all cases, the table is
24855714Skris   null-terminated.  On SVR4, we start from the beginning of the list and
24955714Skris   invoke each per-compilation-unit destructor routine in order
25055714Skris   until we find that null.
25155714Skris
25255714Skris   Note that this function MUST be static.  There will be one of these
25355714Skris   functions in each root executable and one in each shared library, but
25455714Skris   although they all have the same code, each one is unique in that it
25555714Skris   refers to one particular associated `__DTOR_LIST__' which belongs to the
25655714Skris   same particular root executable or shared library file.
25755714Skris
25855714Skris   On some systems, this routine is run more than once from the .fini,
25955714Skris   when exit is called recursively, so we arrange to remember where in
26055714Skris   the list we left off processing, and we resume at that point,
26155714Skris   should we be re-invoked.  */
26255714Skris
26355714Skrisstatic void __attribute__((used))
26455714Skris__do_global_dtors_aux (void)
26555714Skris{
26655714Skris#ifndef FINI_ARRAY_SECTION_ASM_OP
26755714Skris  static func_ptr *p = __DTOR_LIST__ + 1;
26855714Skris  func_ptr f;
26955714Skris#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP)  */
27055714Skris  static _Bool completed;
27155714Skris
27255714Skris  if (__builtin_expect (completed, 0))
27355714Skris    return;
27455714Skris
27555714Skris#ifdef CRTSTUFFS_O
27655714Skris  if (__cxa_finalize)
27755714Skris    __cxa_finalize (__dso_handle);
27855714Skris#endif
27955714Skris
28068651Skris#ifdef FINI_ARRAY_SECTION_ASM_OP
28168651Skris  /* If we are using .fini_array then destructors will be run via that
28255714Skris     mechanism.  */
28355714Skris#else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
28455714Skris  while ((f = *p))
28555714Skris    {
28655714Skris      p++;
28755714Skris      f ();
28855714Skris    }
28955714Skris#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
29055714Skris
29155714Skris#ifdef USE_EH_FRAME_REGISTRY
29255714Skris#ifdef CRT_GET_RFIB_DATA
29355714Skris  /* If we used the new __register_frame_info_bases interface,
29455714Skris     make sure that we deregister from the same place.  */
29555714Skris  if (__deregister_frame_info_bases)
29655714Skris    __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
29755714Skris#else
29855714Skris  if (__deregister_frame_info)
29955714Skris    __deregister_frame_info (__EH_FRAME_BEGIN__);
30055714Skris#endif
30155714Skris#endif
30255714Skris
30355714Skris  completed = 1;
30455714Skris}
30555714Skris
30655714Skris/* Stick a call to __do_global_dtors_aux into the .fini section.  */
30755714Skris#ifdef FINI_SECTION_ASM_OP
30855714SkrisCRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
30955714Skris#else /* !defined(FINI_SECTION_ASM_OP) */
31055714Skrisstatic func_ptr __do_global_dtors_aux_fini_array_entry[]
31155714Skris  __attribute__ ((__used__, section(".fini_array")))
31255714Skris  = { __do_global_dtors_aux };
31355714Skris#endif /* !defined(FINI_SECTION_ASM_OP) */
31455714Skris
31555714Skris#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
31655714Skris/* Stick a call to __register_frame_info into the .init section.  For some
31755714Skris   reason calls with no arguments work more reliably in .init, so stick the
31855714Skris   call in another function.  */
31955714Skris
32055714Skrisstatic void __attribute__((used))
32155714Skrisframe_dummy (void)
32255714Skris{
32355714Skris#ifdef USE_EH_FRAME_REGISTRY
32455714Skris  static struct object object;
32555714Skris#ifdef CRT_GET_RFIB_DATA
32655714Skris  void *tbase, *dbase;
32755714Skris  tbase = 0;
32855714Skris  CRT_GET_RFIB_DATA (dbase);
32955714Skris  if (__register_frame_info_bases)
33055714Skris    __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
33155714Skris#else
33255714Skris  if (__register_frame_info)
33355714Skris    __register_frame_info (__EH_FRAME_BEGIN__, &object);
33455714Skris#endif /* CRT_GET_RFIB_DATA */
33555714Skris#endif /* USE_EH_FRAME_REGISTRY */
33655714Skris#ifdef JCR_SECTION_NAME
33755714Skris  if (__JCR_LIST__[0])
33855714Skris    {
33955714Skris      void (*register_classes) (void *) = _Jv_RegisterClasses;
34055714Skris      __asm ("" : "+r" (register_classes));
34155714Skris      if (register_classes)
34255714Skris	register_classes (__JCR_LIST__);
34355714Skris    }
34455714Skris#endif /* JCR_SECTION_NAME */
34555714Skris}
34655714Skris
34755714Skris#ifdef INIT_SECTION_ASM_OP
34855714SkrisCRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
34955714Skris#else /* defined(INIT_SECTION_ASM_OP) */
35055714Skrisstatic func_ptr __frame_dummy_init_array_entry[]
35155714Skris  __attribute__ ((__used__, section(".init_array")))
35255714Skris  = { frame_dummy };
35355714Skris#endif /* !defined(INIT_SECTION_ASM_OP) */
35455714Skris#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
35555714Skris
35655714Skris#else  /* OBJECT_FORMAT_ELF */
35755714Skris
35855714Skris/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
35955714Skris   and once in crtend.o).  It must be declared static to avoid a link
36055714Skris   error.  Here, we define __do_global_ctors as an externally callable
36155714Skris   function.  It is externally callable so that __main can invoke it when
36255714Skris   INVOKE__main is defined.  This has the additional effect of forcing cc1
36355714Skris   to switch to the .text section.  */
36455714Skris
36555714Skrisstatic void __do_global_ctors_aux (void);
36655714Skrisvoid
36755714Skris__do_global_ctors (void)
36855714Skris{
36955714Skris#ifdef INVOKE__main
37055714Skris  /* If __main won't actually call __do_global_ctors then it doesn't matter
37155714Skris     what's inside the function.  The inside of __do_global_ctors_aux is
37255714Skris     called automatically in that case.  And the Alliant fx2800 linker
37355714Skris     crashes on this reference.  So prevent the crash.  */
37455714Skris  __do_global_ctors_aux ();
37555714Skris#endif
37655714Skris}
37755714Skris
37855714Skrisasm (INIT_SECTION_ASM_OP);	/* cc1 doesn't know that we are switching! */
37955714Skris
38055714Skris/* A routine to invoke all of the global constructors upon entry to the
38155714Skris   program.  We put this into the .init section (for systems that have
38255714Skris   such a thing) so that we can properly perform the construction of
38355714Skris   file-scope static-storage C++ objects within shared libraries.  */
38455714Skris
38555714Skrisstatic void __attribute__((used))
38655714Skris__do_global_ctors_aux (void)	/* prologue goes in .init section */
38755714Skris{
38868651Skris  FORCE_CODE_SECTION_ALIGN	/* explicit align before switch to .text */
38955714Skris  asm (TEXT_SECTION_ASM_OP);	/* don't put epilogue and body in .init */
39055714Skris  DO_GLOBAL_CTORS_BODY;
39155714Skris  atexit (__do_global_dtors);
39255714Skris}
39355714Skris
39455714Skris#endif /* OBJECT_FORMAT_ELF */
39555714Skris
39655714Skris#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
39755714Skris
39855714Skrisextern void __do_global_dtors (void);
39955714Skris
40055714Skris/* This case is used by the Irix 6 port, which supports named sections but
40155714Skris   not an SVR4-style .fini section.  __do_global_dtors can be non-static
40255714Skris   in this case because we protect it with -hidden_symbol.  */
40355714Skris
40455714Skrisvoid
40555714Skris__do_global_dtors (void)
40655714Skris{
40755714Skris  func_ptr *p, f;
40855714Skris  for (p = __DTOR_LIST__ + 1; (f = *p); p++)
40955714Skris    f ();
41055714Skris
41155714Skris#ifdef USE_EH_FRAME_REGISTRY
41255714Skris  if (__deregister_frame_info)
41355714Skris    __deregister_frame_info (__EH_FRAME_BEGIN__);
41455714Skris#endif
41555714Skris}
41655714Skris
41755714Skris#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
41855714Skris/* A helper function for __do_global_ctors, which is in crtend.o.  Here
41955714Skris   in crtbegin.o, we can reference a couple of symbols not visible there.
42055714Skris   Plus, since we're before libgcc.a, we have no problems referencing
42155714Skris   functions from there.  */
42255714Skrisvoid
42355714Skris__do_global_ctors_1(void)
42455714Skris{
42555714Skris#ifdef USE_EH_FRAME_REGISTRY
42655714Skris  static struct object object;
42755714Skris  if (__register_frame_info)
42855714Skris    __register_frame_info (__EH_FRAME_BEGIN__, &object);
42955714Skris#endif
43055714Skris#ifdef JCR_SECTION_NAME
43155714Skris  if (__JCR_LIST__[0])
43255714Skris    {
43355714Skris      void (*register_classes) (void *) = _Jv_RegisterClasses;
43455714Skris      __asm ("" : "+r" (register_classes));
43555714Skris      if (register_classes)
43655714Skris	register_classes (__JCR_LIST__);
43755714Skris    }
43855714Skris#endif
43955714Skris}
44055714Skris#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
44155714Skris
44255714Skris#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
44355714Skris#error "What are you doing with crtstuff.c, then?"
44455714Skris#endif
44555714Skris
44655714Skris#elif defined(CRT_END) /* ! CRT_BEGIN */
44755714Skris
44855714Skris/* Put a word containing zero at the end of each of our two lists of function
44955714Skris   addresses.  Note that the words defined here go into the .ctors and .dtors
45055714Skris   sections of the crtend.o file, and since that file is always linked in
45155714Skris   last, these words naturally end up at the very ends of the two lists
45255714Skris   contained in these two sections.  */
45355714Skris
45455714Skris#ifdef CTOR_LIST_END
45555714SkrisCTOR_LIST_END;
45655714Skris#elif defined(CTORS_SECTION_ASM_OP)
45755714Skris/* Hack: force cc1 to switch to .data section early, so that assembling
45855714Skris   __CTOR_LIST__ does not undo our behind-the-back change to .ctors.  */
45955714Skrisstatic func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
46055714Skrisasm (CTORS_SECTION_ASM_OP);
46155714SkrisSTATIC func_ptr __CTOR_END__[1]
46255714Skris  __attribute__((used, aligned(sizeof(func_ptr))))
46355714Skris  = { (func_ptr) 0 };
46455714Skris#else
46555714SkrisSTATIC func_ptr __CTOR_END__[1]
46655714Skris  __attribute__((used, section(".ctors"), aligned(sizeof(func_ptr))))
46755714Skris  = { (func_ptr) 0 };
46855714Skris#endif
46955714Skris
47055714Skris#ifdef DTOR_LIST_END
47155714SkrisDTOR_LIST_END;
47255714Skris#elif defined(DTORS_SECTION_ASM_OP)
47355714Skrisasm (DTORS_SECTION_ASM_OP);
47455714SkrisSTATIC func_ptr __DTOR_END__[1]
47555714Skris  __attribute__ ((used, aligned(sizeof(func_ptr))))
47655714Skris  = { (func_ptr) 0 };
47755714Skris#else
47855714SkrisSTATIC func_ptr __DTOR_END__[1]
47955714Skris  __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr))))
48055714Skris  = { (func_ptr) 0 };
48155714Skris#endif
48255714Skris
48355714Skris#ifdef EH_FRAME_SECTION_NAME
48455714Skris/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
48555714Skris   this would be the 'length' field in a real FDE.  */
48655714Skris# if __INT_MAX__ == 2147483647
48755714Skristypedef int int32;
48855714Skris# elif __LONG_MAX__ == 2147483647
48955714Skristypedef long int32;
49055714Skris# elif __SHRT_MAX__ == 2147483647
49155714Skristypedef short int32;
49255714Skris# else
49355714Skris#  error "Missing a 4 byte integer"
49455714Skris# endif
49555714SkrisSTATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[]
49655714Skris     __attribute__ ((used, section(EH_FRAME_SECTION_NAME),
49755714Skris		     aligned(sizeof(int32))))
49855714Skris     = { 0 };
49955714Skris#endif /* EH_FRAME_SECTION_NAME */
50055714Skris
50155714Skris#ifdef JCR_SECTION_NAME
50255714Skris/* Null terminate the .jcr section array.  */
50355714SkrisSTATIC void *__JCR_END__[1]
50455714Skris   __attribute__ ((used, section(JCR_SECTION_NAME),
50555714Skris		   aligned(sizeof(void *))))
50655714Skris   = { 0 };
50755714Skris#endif /* JCR_SECTION_NAME */
50855714Skris
50955714Skris#ifdef INIT_ARRAY_SECTION_ASM_OP
51055714Skris
51155714Skris/* If we are using .init_array, there is nothing to do.  */
51255714Skris
51355714Skris#elif defined(INIT_SECTION_ASM_OP)
51455714Skris
51555714Skris#ifdef OBJECT_FORMAT_ELF
51655714Skrisstatic void __attribute__((used))
51755714Skris__do_global_ctors_aux (void)
51855714Skris{
51955714Skris  func_ptr *p;
52055714Skris  for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
52155714Skris    (*p) ();
52255714Skris}
52355714Skris
52455714Skris/* Stick a call to __do_global_ctors_aux into the .init section.  */
52555714SkrisCRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux)
52655714Skris#else  /* OBJECT_FORMAT_ELF */
52755714Skris
52855714Skris/* Stick the real initialization code, followed by a normal sort of
52955714Skris   function epilogue at the very end of the .init section for this
53055714Skris   entire root executable file or for this entire shared library file.
53155714Skris
53255714Skris   Note that we use some tricks here to get *just* the body and just
53355714Skris   a function epilogue (but no function prologue) into the .init
53455714Skris   section of the crtend.o file.  Specifically, we switch to the .text
53555714Skris   section, start to define a function, and then we switch to the .init
53655714Skris   section just before the body code.
53755714Skris
53855714Skris   Earlier on, we put the corresponding function prologue into the .init
53955714Skris   section of the crtbegin.o file (which will be linked in first).
54055714Skris
54155714Skris   Note that we want to invoke all constructors for C++ file-scope static-
54255714Skris   storage objects AFTER any other possible initialization actions which
54355714Skris   may be performed by the code in the .init section contributions made by
54455714Skris   other libraries, etc.  That's because those other initializations may
54555714Skris   include setup operations for very primitive things (e.g. initializing
54655714Skris   the state of the floating-point coprocessor, etc.) which should be done
54755714Skris   before we start to execute any of the user's code.  */
54855714Skris
54968651Skrisstatic void
55068651Skris__do_global_ctors_aux (void)	/* prologue goes in .text section */
55168651Skris{
55268651Skris  asm (INIT_SECTION_ASM_OP);
55368651Skris  DO_GLOBAL_CTORS_BODY;
55455714Skris  atexit (__do_global_dtors);
55555714Skris}				/* epilogue and body go in .init section */
55655714Skris
55755714SkrisFORCE_CODE_SECTION_ALIGN
55855714Skrisasm (TEXT_SECTION_ASM_OP);
55955714Skris
56055714Skris#endif /* OBJECT_FORMAT_ELF */
56155714Skris
56255714Skris#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
56355714Skris
56455714Skrisextern void __do_global_ctors (void);
56555714Skris
56655714Skris/* This case is used by the Irix 6 port, which supports named sections but
56755714Skris   not an SVR4-style .init section.  __do_global_ctors can be non-static
56855714Skris   in this case because we protect it with -hidden_symbol.  */
56955714Skrisvoid
57055714Skris__do_global_ctors (void)
57155714Skris{
57255714Skris  func_ptr *p;
57355714Skris#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
57455714Skris  __do_global_ctors_1();
57555714Skris#endif
57655714Skris  for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
57755714Skris    (*p) ();
57855714Skris}
57955714Skris
58055714Skris#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
58155714Skris#error "What are you doing with crtstuff.c, then?"
58255714Skris#endif
58355714Skris
58455714Skris#else /* ! CRT_BEGIN && ! CRT_END */
58555714Skris#error "One of CRT_BEGIN or CRT_END must be defined."
58655714Skris#endif
58755714Skris