118334Speter/* Specialized bits of code needed to support construction and 218334Speter destruction of file-scope objects in C++ code. 390075Sobrien Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 4169689Skan 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 550397Sobrien Contributed by Ron Guilmette (rfg@monkeys.com). 618334Speter 790075SobrienThis file is part of GCC. 818334Speter 990075SobrienGCC is free software; you can redistribute it and/or modify it under 1090075Sobrienthe terms of the GNU General Public License as published by the Free 1190075SobrienSoftware Foundation; either version 2, or (at your option) any later 1290075Sobrienversion. 1318334Speter 1490075SobrienIn addition to the permissions in the GNU General Public License, the 1590075SobrienFree Software Foundation gives you unlimited permission to link the 1690075Sobriencompiled version of this file into combinations with other programs, 1790075Sobrienand to distribute those combinations without any restriction coming 1890075Sobrienfrom the use of this file. (The General Public License restrictions 1990075Sobriendo apply in other respects; for example, they cover modification of 2090075Sobrienthe file, and distribution when not linked into a combine 2190075Sobrienexecutable.) 2218334Speter 2390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 2490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 2590075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2690075Sobrienfor more details. 2790075Sobrien 2818334SpeterYou should have received a copy of the GNU General Public License 2990075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 30169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 31169689Skan02110-1301, USA. */ 3218334Speter 3390075Sobrien/* This file is a bit like libgcc2.c in that it is compiled 3418334Speter multiple times and yields multiple .o files. 3518334Speter 3618334Speter This file is useful on target machines where the object file format 3718334Speter supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On 3818334Speter such systems, this file allows us to avoid running collect (or any 3918334Speter other such slow and painful kludge). Additionally, if the target 4018334Speter system supports a .init section, this file allows us to support the 4118334Speter linking of C++ code with a non-C++ main program. 4218334Speter 4318334Speter Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then 4418334Speter this file *will* make use of the .init section. If that symbol is 4518334Speter not defined however, then the .init section will not be used. 4618334Speter 4718334Speter Currently, only ELF and COFF are supported. It is likely however that 4818334Speter ROSE could also be supported, if someone was willing to do the work to 4918334Speter make whatever (small?) adaptations are needed. (Some work may be 5018334Speter needed on the ROSE assembler and linker also.) 5118334Speter 5218334Speter This file must be compiled with gcc. */ 5318334Speter 54169689Skan/* Target machine header files require this define. */ 55169689Skan#define IN_LIBGCC2 5618334Speter 57169689Skan/* FIXME: Including auto-host is incorrect, but until we have 58169689Skan identified the set of defines that need to go into auto-target.h, 59169689Skan this will have to do. */ 6090075Sobrien#include "auto-host.h" 61169689Skan#undef gid_t 62169689Skan#undef pid_t 63169689Skan#undef rlim_t 64169689Skan#undef ssize_t 65169689Skan#undef uid_t 66169689Skan#undef vfork 6790075Sobrien#include "tconfig.h" 6890075Sobrien#include "tsystem.h" 69132718Skan#include "coretypes.h" 70132718Skan#include "tm.h" 7190075Sobrien#include "unwind-dw2-fde.h" 7218334Speter 7390075Sobrien#ifndef FORCE_CODE_SECTION_ALIGN 7490075Sobrien# define FORCE_CODE_SECTION_ALIGN 7590075Sobrien#endif 7690075Sobrien 7790075Sobrien#ifndef CRT_CALL_STATIC_FUNCTION 7890075Sobrien# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ 7990075Sobrienstatic void __attribute__((__used__)) \ 8090075Sobriencall_ ## FUNC (void) \ 8190075Sobrien{ \ 8290075Sobrien asm (SECTION_OP); \ 8390075Sobrien FUNC (); \ 8490075Sobrien FORCE_CODE_SECTION_ALIGN \ 8590075Sobrien asm (TEXT_SECTION_ASM_OP); \ 8690075Sobrien} 8790075Sobrien#endif 8890075Sobrien 8990075Sobrien#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \ 9090075Sobrien && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ 9190075Sobrien && defined(__GLIBC__) && __GLIBC__ >= 2 9290075Sobrien#include <link.h> 9390075Sobrien# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ 9490075Sobrien || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) 9590075Sobrien# define USE_PT_GNU_EH_FRAME 9690075Sobrien# endif 9790075Sobrien#endif 9890075Sobrien#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME) 9990075Sobrien# define USE_EH_FRAME_REGISTRY 10090075Sobrien#endif 101169689Skan#if defined(EH_FRAME_SECTION_NAME) && EH_TABLES_CAN_BE_READ_ONLY 102117395Skan# define EH_FRAME_SECTION_CONST const 103117395Skan#else 104117395Skan# define EH_FRAME_SECTION_CONST 105117395Skan#endif 10690075Sobrien 10750397Sobrien/* We do not want to add the weak attribute to the declarations of these 10890075Sobrien routines in unwind-dw2-fde.h because that will cause the definition of 10990075Sobrien these symbols to be weak as well. 11050397Sobrien 11150397Sobrien This exposes a core issue, how to handle creating weak references vs 11250397Sobrien how to create weak definitions. Either we have to have the definition 11350397Sobrien of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or 11450397Sobrien have a second declaration if we want a function's references to be weak, 11550397Sobrien but not its definition. 11650397Sobrien 11750397Sobrien Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until 118169689Skan one thinks about scaling to larger problems -- i.e., the condition under 11950397Sobrien which TARGET_WEAK_ATTRIBUTE is active will eventually get far too 12050397Sobrien complicated. 12150397Sobrien 12250397Sobrien So, we take an approach similar to #pragma weak -- we have a second 12350397Sobrien declaration for functions that we want to have weak references. 12450397Sobrien 12550397Sobrien Neither way is particularly good. */ 12650397Sobrien 12750397Sobrien/* References to __register_frame_info and __deregister_frame_info should 12850397Sobrien be weak in this file if at all possible. */ 129132718Skanextern void __register_frame_info (const void *, struct object *) 13050397Sobrien TARGET_ATTRIBUTE_WEAK; 131132718Skanextern void __register_frame_info_bases (const void *, struct object *, 13290075Sobrien void *, void *) 13390075Sobrien TARGET_ATTRIBUTE_WEAK; 134132718Skanextern void *__deregister_frame_info (const void *) 13550397Sobrien TARGET_ATTRIBUTE_WEAK; 136132718Skanextern void *__deregister_frame_info_bases (const void *) 13790075Sobrien TARGET_ATTRIBUTE_WEAK; 138132718Skanextern void __do_global_ctors_1 (void); 13950397Sobrien 14090075Sobrien/* Likewise for _Jv_RegisterClasses. */ 14190075Sobrienextern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK; 14290075Sobrien 14318334Speter#ifdef OBJECT_FORMAT_ELF 14418334Speter 14518334Speter/* Declare a pointer to void function type. */ 14618334Spetertypedef void (*func_ptr) (void); 14718334Speter#define STATIC static 14818334Speter 14918334Speter#else /* OBJECT_FORMAT_ELF */ 15018334Speter 15118334Speter#include "gbl-ctors.h" 15218334Speter 15318334Speter#define STATIC 15418334Speter 15518334Speter#endif /* OBJECT_FORMAT_ELF */ 15618334Speter 15718334Speter#ifdef CRT_BEGIN 15818334Speter 15990075Sobrien/* NOTE: In order to be able to support SVR4 shared libraries, we arrange 16090075Sobrien to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, 16190075Sobrien __DTOR_END__ } per root executable and also one set of these symbols 16290075Sobrien per shared library. So in any given whole process image, we may have 16390075Sobrien multiple definitions of each of these symbols. In order to prevent 16490075Sobrien these definitions from conflicting with one another, and in order to 16590075Sobrien ensure that the proper lists are used for the initialization/finalization 16690075Sobrien of each individual shared library (respectively), we give these symbols 16790075Sobrien only internal (i.e. `static') linkage, and we also make it a point to 16890075Sobrien refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ 16990075Sobrien symbol in crtbegin.o, where they are defined. */ 17090075Sobrien 17190075Sobrien/* The -1 is a flag to __do_global_[cd]tors indicating that this table 17290075Sobrien does not start with a count of elements. */ 17390075Sobrien#ifdef CTOR_LIST_BEGIN 17490075SobrienCTOR_LIST_BEGIN; 17590075Sobrien#elif defined(CTORS_SECTION_ASM_OP) 17690075Sobrien/* Hack: force cc1 to switch to .data section early, so that assembling 17790075Sobrien __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */ 178211729Srpaulostatic func_ptr force_to_data[1] __attribute__ ((__used__)) = { }; 17990075Sobrienasm (CTORS_SECTION_ASM_OP); 18090075SobrienSTATIC func_ptr __CTOR_LIST__[1] 181211729Srpaulo __attribute__ ((__used__, aligned(sizeof(func_ptr)))) 18290075Sobrien = { (func_ptr) (-1) }; 18390075Sobrien#else 18490075SobrienSTATIC func_ptr __CTOR_LIST__[1] 185211729Srpaulo __attribute__ ((__used__, section(".ctors"), aligned(sizeof(func_ptr)))) 18690075Sobrien = { (func_ptr) (-1) }; 18790075Sobrien#endif /* __CTOR_LIST__ alternatives */ 18890075Sobrien 18990075Sobrien#ifdef DTOR_LIST_BEGIN 19090075SobrienDTOR_LIST_BEGIN; 19190075Sobrien#elif defined(DTORS_SECTION_ASM_OP) 19290075Sobrienasm (DTORS_SECTION_ASM_OP); 19390075SobrienSTATIC func_ptr __DTOR_LIST__[1] 194211844Srpaulo __attribute__ ((used, aligned(sizeof(func_ptr)))) 19590075Sobrien = { (func_ptr) (-1) }; 19690075Sobrien#else 19790075SobrienSTATIC func_ptr __DTOR_LIST__[1] 198211844Srpaulo __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr)))) 19990075Sobrien = { (func_ptr) (-1) }; 20090075Sobrien#endif /* __DTOR_LIST__ alternatives */ 20190075Sobrien 202117395Skan#ifdef USE_EH_FRAME_REGISTRY 20390075Sobrien/* Stick a label at the beginning of the frame unwind info so we can register 20490075Sobrien and deregister it with the exception handling library code. */ 205117395SkanSTATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[] 206211844Srpaulo __attribute__((used, section(EH_FRAME_SECTION_NAME), aligned(4))) 20790075Sobrien = { }; 208117395Skan#endif /* USE_EH_FRAME_REGISTRY */ 20990075Sobrien 21090075Sobrien#ifdef JCR_SECTION_NAME 21190075Sobrien/* Stick a label at the beginning of the java class registration info 21290075Sobrien so we can register them properly. */ 21390075SobrienSTATIC void *__JCR_LIST__[] 214211843Srpaulo __attribute__ ((used, section(JCR_SECTION_NAME), aligned(sizeof(void*)))) 21590075Sobrien = { }; 21690075Sobrien#endif /* JCR_SECTION_NAME */ 21790075Sobrien 218169689Skan#if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP) 21918334Speter 22018334Speter#ifdef OBJECT_FORMAT_ELF 22118334Speter 22290075Sobrien/* Declare the __dso_handle variable. It should have a unique value 22390075Sobrien in every shared-object; in a main program its value is zero. The 22490075Sobrien object should in any case be protected. This means the instance 22590075Sobrien in one DSO or the main program is not used in another object. The 22690075Sobrien dynamic linker takes care of this. */ 22790075Sobrien 228169689Skan#ifdef TARGET_LIBGCC_SDATA_SECTION 229169689Skanextern void *__dso_handle __attribute__ ((__section__ (TARGET_LIBGCC_SDATA_SECTION))); 230169689Skan#endif 23190075Sobrien#ifdef HAVE_GAS_HIDDEN 232117395Skanextern void *__dso_handle __attribute__ ((__visibility__ ("hidden"))); 23390075Sobrien#endif 23490075Sobrien#ifdef CRTSTUFFS_O 23590075Sobrienvoid *__dso_handle = &__dso_handle; 23690075Sobrien#else 23790075Sobrienvoid *__dso_handle = 0; 23890075Sobrien#endif 23990075Sobrien 24090075Sobrien/* The __cxa_finalize function may not be available so we use only a 24190075Sobrien weak declaration. */ 24290075Sobrienextern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK; 24390075Sobrien 24418334Speter/* Run all the global destructors on exit from the program. */ 24518334Speter 24618334Speter/* Some systems place the number of pointers in the first word of the 24718334Speter table. On SVR4 however, that word is -1. In all cases, the table is 24818334Speter null-terminated. On SVR4, we start from the beginning of the list and 24918334Speter invoke each per-compilation-unit destructor routine in order 25018334Speter until we find that null. 25118334Speter 25218334Speter Note that this function MUST be static. There will be one of these 25318334Speter functions in each root executable and one in each shared library, but 25418334Speter although they all have the same code, each one is unique in that it 25518334Speter refers to one particular associated `__DTOR_LIST__' which belongs to the 25650397Sobrien same particular root executable or shared library file. 25718334Speter 25850397Sobrien On some systems, this routine is run more than once from the .fini, 25950397Sobrien when exit is called recursively, so we arrange to remember where in 26050397Sobrien the list we left off processing, and we resume at that point, 26150397Sobrien should we be re-invoked. */ 26250397Sobrien 26390075Sobrienstatic void __attribute__((used)) 26452284Sobrien__do_global_dtors_aux (void) 26518334Speter{ 266169689Skan#ifndef FINI_ARRAY_SECTION_ASM_OP 26750397Sobrien static func_ptr *p = __DTOR_LIST__ + 1; 268169689Skan func_ptr f; 269169689Skan#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */ 27090075Sobrien static _Bool completed; 27150397Sobrien 27290075Sobrien if (__builtin_expect (completed, 0)) 27350397Sobrien return; 27450397Sobrien 27590075Sobrien#ifdef CRTSTUFFS_O 27690075Sobrien if (__cxa_finalize) 27790075Sobrien __cxa_finalize (__dso_handle); 27890075Sobrien#endif 27990075Sobrien 280169689Skan#ifdef FINI_ARRAY_SECTION_ASM_OP 281169689Skan /* If we are using .fini_array then destructors will be run via that 282169689Skan mechanism. */ 283169689Skan#else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */ 28490075Sobrien while ((f = *p)) 28550397Sobrien { 28650397Sobrien p++; 28790075Sobrien f (); 28850397Sobrien } 289169689Skan#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */ 29050397Sobrien 29190075Sobrien#ifdef USE_EH_FRAME_REGISTRY 292132718Skan#ifdef CRT_GET_RFIB_DATA 29390075Sobrien /* If we used the new __register_frame_info_bases interface, 29490075Sobrien make sure that we deregister from the same place. */ 29590075Sobrien if (__deregister_frame_info_bases) 29690075Sobrien __deregister_frame_info_bases (__EH_FRAME_BEGIN__); 29790075Sobrien#else 29850397Sobrien if (__deregister_frame_info) 29950397Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 30050397Sobrien#endif 30190075Sobrien#endif 30290075Sobrien 30350397Sobrien completed = 1; 30418334Speter} 30518334Speter 30618334Speter/* Stick a call to __do_global_dtors_aux into the .fini section. */ 307169689Skan#ifdef FINI_SECTION_ASM_OP 30890075SobrienCRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux) 309169689Skan#else /* !defined(FINI_SECTION_ASM_OP) */ 310169689Skanstatic func_ptr __do_global_dtors_aux_fini_array_entry[] 311211729Srpaulo __attribute__ ((__used__, section(".fini_array"))) 312169689Skan = { __do_global_dtors_aux }; 313169689Skan#endif /* !defined(FINI_SECTION_ASM_OP) */ 31450397Sobrien 31590075Sobrien#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) 31650397Sobrien/* Stick a call to __register_frame_info into the .init section. For some 31750397Sobrien reason calls with no arguments work more reliably in .init, so stick the 31850397Sobrien call in another function. */ 31950397Sobrien 32090075Sobrienstatic void __attribute__((used)) 32152284Sobrienframe_dummy (void) 32250397Sobrien{ 32390075Sobrien#ifdef USE_EH_FRAME_REGISTRY 32450397Sobrien static struct object object; 325132718Skan#ifdef CRT_GET_RFIB_DATA 32690075Sobrien void *tbase, *dbase; 32790075Sobrien tbase = 0; 32890075Sobrien CRT_GET_RFIB_DATA (dbase); 32990075Sobrien if (__register_frame_info_bases) 33090075Sobrien __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase); 33190075Sobrien#else 33250397Sobrien if (__register_frame_info) 33350397Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 334132718Skan#endif /* CRT_GET_RFIB_DATA */ 33596263Sobrien#endif /* USE_EH_FRAME_REGISTRY */ 33690075Sobrien#ifdef JCR_SECTION_NAME 337169689Skan if (__JCR_LIST__[0]) 338169689Skan { 339169689Skan void (*register_classes) (void *) = _Jv_RegisterClasses; 340169689Skan __asm ("" : "+r" (register_classes)); 341169689Skan if (register_classes) 342169689Skan register_classes (__JCR_LIST__); 343169689Skan } 34490075Sobrien#endif /* JCR_SECTION_NAME */ 34550397Sobrien} 34650397Sobrien 347169689Skan#ifdef INIT_SECTION_ASM_OP 34890075SobrienCRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy) 349169689Skan#else /* defined(INIT_SECTION_ASM_OP) */ 350169689Skanstatic func_ptr __frame_dummy_init_array_entry[] 351211729Srpaulo __attribute__ ((__used__, section(".init_array"))) 352169689Skan = { frame_dummy }; 353169689Skan#endif /* !defined(INIT_SECTION_ASM_OP) */ 35496263Sobrien#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */ 35590075Sobrien 35618334Speter#else /* OBJECT_FORMAT_ELF */ 35718334Speter 35818334Speter/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o 35918334Speter and once in crtend.o). It must be declared static to avoid a link 36018334Speter error. Here, we define __do_global_ctors as an externally callable 36118334Speter function. It is externally callable so that __main can invoke it when 36218334Speter INVOKE__main is defined. This has the additional effect of forcing cc1 36318334Speter to switch to the .text section. */ 36450397Sobrien 36590075Sobrienstatic void __do_global_ctors_aux (void); 36652284Sobrienvoid 36752284Sobrien__do_global_ctors (void) 36818334Speter{ 36990075Sobrien#ifdef INVOKE__main 37090075Sobrien /* If __main won't actually call __do_global_ctors then it doesn't matter 37190075Sobrien what's inside the function. The inside of __do_global_ctors_aux is 37290075Sobrien called automatically in that case. And the Alliant fx2800 linker 37390075Sobrien crashes on this reference. So prevent the crash. */ 37418334Speter __do_global_ctors_aux (); 37518334Speter#endif 37618334Speter} 37718334Speter 37818334Speterasm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 37918334Speter 38018334Speter/* A routine to invoke all of the global constructors upon entry to the 38118334Speter program. We put this into the .init section (for systems that have 38218334Speter such a thing) so that we can properly perform the construction of 38390075Sobrien file-scope static-storage C++ objects within shared libraries. */ 38418334Speter 38590075Sobrienstatic void __attribute__((used)) 38652284Sobrien__do_global_ctors_aux (void) /* prologue goes in .init section */ 38718334Speter{ 38890075Sobrien FORCE_CODE_SECTION_ALIGN /* explicit align before switch to .text */ 38918334Speter asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */ 39018334Speter DO_GLOBAL_CTORS_BODY; 39190075Sobrien atexit (__do_global_dtors); 39218334Speter} 39318334Speter 39418334Speter#endif /* OBJECT_FORMAT_ELF */ 39550397Sobrien 39690075Sobrien#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */ 39750397Sobrien 398132718Skanextern void __do_global_dtors (void); 399132718Skan 40050397Sobrien/* This case is used by the Irix 6 port, which supports named sections but 40150397Sobrien not an SVR4-style .fini section. __do_global_dtors can be non-static 40250397Sobrien in this case because we protect it with -hidden_symbol. */ 40350397Sobrien 40450397Sobrienvoid 40552284Sobrien__do_global_dtors (void) 40650397Sobrien{ 40790075Sobrien func_ptr *p, f; 40890075Sobrien for (p = __DTOR_LIST__ + 1; (f = *p); p++) 40990075Sobrien f (); 41050397Sobrien 41190075Sobrien#ifdef USE_EH_FRAME_REGISTRY 41250397Sobrien if (__deregister_frame_info) 41350397Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 41450397Sobrien#endif 41550397Sobrien} 41650397Sobrien 41790075Sobrien#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) 41890075Sobrien/* A helper function for __do_global_ctors, which is in crtend.o. Here 41990075Sobrien in crtbegin.o, we can reference a couple of symbols not visible there. 42090075Sobrien Plus, since we're before libgcc.a, we have no problems referencing 42190075Sobrien functions from there. */ 42250397Sobrienvoid 42390075Sobrien__do_global_ctors_1(void) 42450397Sobrien{ 42590075Sobrien#ifdef USE_EH_FRAME_REGISTRY 42650397Sobrien static struct object object; 42750397Sobrien if (__register_frame_info) 42850397Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 42950397Sobrien#endif 43090075Sobrien#ifdef JCR_SECTION_NAME 431169689Skan if (__JCR_LIST__[0]) 432169689Skan { 433169689Skan void (*register_classes) (void *) = _Jv_RegisterClasses; 434169689Skan __asm ("" : "+r" (register_classes)); 435169689Skan if (register_classes) 436169689Skan register_classes (__JCR_LIST__); 437169689Skan } 43850397Sobrien#endif 43990075Sobrien} 44096263Sobrien#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */ 44150397Sobrien 44290075Sobrien#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ 44390075Sobrien#error "What are you doing with crtstuff.c, then?" 44490075Sobrien#endif 44518334Speter 44690075Sobrien#elif defined(CRT_END) /* ! CRT_BEGIN */ 44718334Speter 44890075Sobrien/* Put a word containing zero at the end of each of our two lists of function 44990075Sobrien addresses. Note that the words defined here go into the .ctors and .dtors 45090075Sobrien sections of the crtend.o file, and since that file is always linked in 45190075Sobrien last, these words naturally end up at the very ends of the two lists 45290075Sobrien contained in these two sections. */ 45318334Speter 45490075Sobrien#ifdef CTOR_LIST_END 45590075SobrienCTOR_LIST_END; 45690075Sobrien#elif defined(CTORS_SECTION_ASM_OP) 45790075Sobrien/* Hack: force cc1 to switch to .data section early, so that assembling 45890075Sobrien __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */ 459211729Srpaulostatic func_ptr force_to_data[1] __attribute__ ((__used__)) = { }; 46090075Sobrienasm (CTORS_SECTION_ASM_OP); 46190075SobrienSTATIC func_ptr __CTOR_END__[1] 462211844Srpaulo __attribute__((used, aligned(sizeof(func_ptr)))) 46390075Sobrien = { (func_ptr) 0 }; 46418334Speter#else 46590075SobrienSTATIC func_ptr __CTOR_END__[1] 466211844Srpaulo __attribute__((used, section(".ctors"), aligned(sizeof(func_ptr)))) 46790075Sobrien = { (func_ptr) 0 }; 46818334Speter#endif 46918334Speter 47090075Sobrien#ifdef DTOR_LIST_END 47190075SobrienDTOR_LIST_END; 47290075Sobrien#elif defined(DTORS_SECTION_ASM_OP) 47390075Sobrienasm (DTORS_SECTION_ASM_OP); 47490075SobrienSTATIC func_ptr __DTOR_END__[1] 475211843Srpaulo __attribute__ ((used, aligned(sizeof(func_ptr)))) 47690075Sobrien = { (func_ptr) 0 }; 47718334Speter#else 47890075SobrienSTATIC func_ptr __DTOR_END__[1] 479211843Srpaulo __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr)))) 48090075Sobrien = { (func_ptr) 0 }; 48118334Speter#endif 48218334Speter 48390075Sobrien#ifdef EH_FRAME_SECTION_NAME 48490075Sobrien/* Terminate the frame unwind info section with a 4byte 0 as a sentinel; 48590075Sobrien this would be the 'length' field in a real FDE. */ 486146895Skan# if __INT_MAX__ == 2147483647 487146895Skantypedef int int32; 488146895Skan# elif __LONG_MAX__ == 2147483647 489146895Skantypedef long int32; 490146895Skan# elif __SHRT_MAX__ == 2147483647 491146895Skantypedef short int32; 492146895Skan# else 493146895Skan# error "Missing a 4 byte integer" 494146895Skan# endif 495146895SkanSTATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[] 496211843Srpaulo __attribute__ ((used, section(EH_FRAME_SECTION_NAME), 497146895Skan aligned(sizeof(int32)))) 49890075Sobrien = { 0 }; 49990075Sobrien#endif /* EH_FRAME_SECTION_NAME */ 50050397Sobrien 50190075Sobrien#ifdef JCR_SECTION_NAME 50290075Sobrien/* Null terminate the .jcr section array. */ 50390075SobrienSTATIC void *__JCR_END__[1] 504211843Srpaulo __attribute__ ((used, section(JCR_SECTION_NAME), 50590075Sobrien aligned(sizeof(void *)))) 50690075Sobrien = { 0 }; 50790075Sobrien#endif /* JCR_SECTION_NAME */ 50850397Sobrien 509169689Skan#ifdef INIT_ARRAY_SECTION_ASM_OP 51018334Speter 511169689Skan/* If we are using .init_array, there is nothing to do. */ 512169689Skan 513169689Skan#elif defined(INIT_SECTION_ASM_OP) 514169689Skan 51518334Speter#ifdef OBJECT_FORMAT_ELF 51690075Sobrienstatic void __attribute__((used)) 51752284Sobrien__do_global_ctors_aux (void) 51818334Speter{ 51918334Speter func_ptr *p; 52018334Speter for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 52118334Speter (*p) (); 52218334Speter} 52318334Speter 52418334Speter/* Stick a call to __do_global_ctors_aux into the .init section. */ 52590075SobrienCRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux) 52618334Speter#else /* OBJECT_FORMAT_ELF */ 52718334Speter 52818334Speter/* Stick the real initialization code, followed by a normal sort of 52918334Speter function epilogue at the very end of the .init section for this 53018334Speter entire root executable file or for this entire shared library file. 53118334Speter 53218334Speter Note that we use some tricks here to get *just* the body and just 53318334Speter a function epilogue (but no function prologue) into the .init 53418334Speter section of the crtend.o file. Specifically, we switch to the .text 53518334Speter section, start to define a function, and then we switch to the .init 53618334Speter section just before the body code. 53718334Speter 53818334Speter Earlier on, we put the corresponding function prologue into the .init 53918334Speter section of the crtbegin.o file (which will be linked in first). 54018334Speter 54118334Speter Note that we want to invoke all constructors for C++ file-scope static- 54218334Speter storage objects AFTER any other possible initialization actions which 54318334Speter may be performed by the code in the .init section contributions made by 54418334Speter other libraries, etc. That's because those other initializations may 54518334Speter include setup operations for very primitive things (e.g. initializing 54618334Speter the state of the floating-point coprocessor, etc.) which should be done 54750397Sobrien before we start to execute any of the user's code. */ 54818334Speter 54918334Speterstatic void 55052284Sobrien__do_global_ctors_aux (void) /* prologue goes in .text section */ 55118334Speter{ 55218334Speter asm (INIT_SECTION_ASM_OP); 55318334Speter DO_GLOBAL_CTORS_BODY; 55490075Sobrien atexit (__do_global_dtors); 55518334Speter} /* epilogue and body go in .init section */ 55618334Speter 55790075SobrienFORCE_CODE_SECTION_ALIGN 55850397Sobrienasm (TEXT_SECTION_ASM_OP); 55950397Sobrien 56018334Speter#endif /* OBJECT_FORMAT_ELF */ 56118334Speter 56290075Sobrien#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */ 56350397Sobrien 564132718Skanextern void __do_global_ctors (void); 565132718Skan 56650397Sobrien/* This case is used by the Irix 6 port, which supports named sections but 56750397Sobrien not an SVR4-style .init section. __do_global_ctors can be non-static 56850397Sobrien in this case because we protect it with -hidden_symbol. */ 56950397Sobrienvoid 57052284Sobrien__do_global_ctors (void) 57150397Sobrien{ 57250397Sobrien func_ptr *p; 57390075Sobrien#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) 57490075Sobrien __do_global_ctors_1(); 57550397Sobrien#endif 57650397Sobrien for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 57750397Sobrien (*p) (); 57850397Sobrien} 57950397Sobrien 58090075Sobrien#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ 58190075Sobrien#error "What are you doing with crtstuff.c, then?" 58218334Speter#endif 58318334Speter 58490075Sobrien#else /* ! CRT_BEGIN && ! CRT_END */ 58590075Sobrien#error "One of CRT_BEGIN or CRT_END must be defined." 58618334Speter#endif 587