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