crtstuff.c revision 50397
118334Speter/* Specialized bits of code needed to support construction and 218334Speter destruction of file-scope objects in C++ code. 350397Sobrien Copyright (C) 1991, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. 450397Sobrien Contributed by Ron Guilmette (rfg@monkeys.com). 518334Speter 618334SpeterThis file is part of GNU CC. 718334Speter 818334SpeterGNU CC is free software; you can redistribute it and/or modify 918334Speterit under the terms of the GNU General Public License as published by 1018334Speterthe Free Software Foundation; either version 2, or (at your option) 1118334Speterany later version. 1218334Speter 1318334SpeterGNU CC is distributed in the hope that it will be useful, 1418334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1518334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1618334SpeterGNU General Public License for more details. 1718334Speter 1818334SpeterYou should have received a copy of the GNU General Public License 1918334Speteralong with GNU CC; see the file COPYING. If not, write to 2018334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 2118334SpeterBoston, MA 02111-1307, USA. */ 2218334Speter 2318334Speter/* As a special exception, if you link this library with files 2418334Speter compiled with GCC to produce an executable, this does not cause 2518334Speter the resulting executable to be covered by the GNU General Public License. 2618334Speter This exception does not however invalidate any other reasons why 2718334Speter the executable file might be covered by the GNU General Public License. */ 2818334Speter 2918334Speter/* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled 3018334Speter multiple times and yields multiple .o files. 3118334Speter 3218334Speter This file is useful on target machines where the object file format 3318334Speter supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On 3418334Speter such systems, this file allows us to avoid running collect (or any 3518334Speter other such slow and painful kludge). Additionally, if the target 3618334Speter system supports a .init section, this file allows us to support the 3718334Speter linking of C++ code with a non-C++ main program. 3818334Speter 3918334Speter Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then 4018334Speter this file *will* make use of the .init section. If that symbol is 4118334Speter not defined however, then the .init section will not be used. 4218334Speter 4318334Speter Currently, only ELF and COFF are supported. It is likely however that 4418334Speter ROSE could also be supported, if someone was willing to do the work to 4518334Speter make whatever (small?) adaptations are needed. (Some work may be 4618334Speter needed on the ROSE assembler and linker also.) 4718334Speter 4818334Speter This file must be compiled with gcc. */ 4918334Speter 5018334Speter/* It is incorrect to include config.h here, because this file is being 5118334Speter compiled for the target, and hence definitions concerning only the host 5218334Speter do not apply. */ 5318334Speter 5418334Speter#include "tm.h" 5550397Sobrien#include "defaults.h" 5650397Sobrien#include <stddef.h> 5750397Sobrien#include "frame.h" 5818334Speter 5950397Sobrien/* This really belongs in gansidecl.h, but for the egcs-1.1.x branch, the 6050397Sobrien only code which uses weak attributes is in this file and this file does 6150397Sobrien not include gansidecl.h. */ 6250397Sobrien#ifndef TARGET_ATTRIBUTE_WEAK 6350397Sobrien# if SUPPORTS_WEAK 6450397Sobrien# define TARGET_ATTRIBUTE_WEAK __attribute__ ((weak)) 6550397Sobrien# else 6650397Sobrien# define TARGET_ATTRIBUTE_WEAK 6750397Sobrien# endif 6850397Sobrien#endif 6950397Sobrien 7050397Sobrien/* We do not want to add the weak attribute to the declarations of these 7150397Sobrien routines in frame.h because that will cause the definition of these 7250397Sobrien symbols to be weak as well. 7350397Sobrien 7450397Sobrien This exposes a core issue, how to handle creating weak references vs 7550397Sobrien how to create weak definitions. Either we have to have the definition 7650397Sobrien of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or 7750397Sobrien have a second declaration if we want a function's references to be weak, 7850397Sobrien but not its definition. 7950397Sobrien 8050397Sobrien Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until 8150397Sobrien one thinks about scaling to larger problems -- ie, the condition under 8250397Sobrien which TARGET_WEAK_ATTRIBUTE is active will eventually get far too 8350397Sobrien complicated. 8450397Sobrien 8550397Sobrien So, we take an approach similar to #pragma weak -- we have a second 8650397Sobrien declaration for functions that we want to have weak references. 8750397Sobrien 8850397Sobrien Neither way is particularly good. */ 8950397Sobrien 9050397Sobrien/* References to __register_frame_info and __deregister_frame_info should 9150397Sobrien be weak in this file if at all possible. */ 9250397Sobrienextern void __register_frame_info (void *, struct object *) 9350397Sobrien TARGET_ATTRIBUTE_WEAK; 9450397Sobrien 9550397Sobrienextern void *__deregister_frame_info (void *) 9650397Sobrien TARGET_ATTRIBUTE_WEAK; 9750397Sobrien 9818334Speter/* Provide default definitions for the pseudo-ops used to switch to the 9918334Speter .ctors and .dtors sections. 10018334Speter 10118334Speter Note that we want to give these sections the SHF_WRITE attribute 10218334Speter because these sections will actually contain data (i.e. tables of 10318334Speter addresses of functions in the current root executable or shared library 10418334Speter file) and, in the case of a shared library, the relocatable addresses 10518334Speter will have to be properly resolved/relocated (and then written into) by 10618334Speter the dynamic linker when it actually attaches the given shared library 10718334Speter to the executing process. (Note that on SVR4, you may wish to use the 10818334Speter `-z text' option to the ELF linker, when building a shared library, as 10918334Speter an additional check that you are doing everything right. But if you do 11018334Speter use the `-z text' option when building a shared library, you will get 11118334Speter errors unless the .ctors and .dtors sections are marked as writable 11218334Speter via the SHF_WRITE attribute.) */ 11318334Speter 11418334Speter#ifndef CTORS_SECTION_ASM_OP 11518334Speter#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" 11618334Speter#endif 11718334Speter#ifndef DTORS_SECTION_ASM_OP 11818334Speter#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\"" 11918334Speter#endif 12050397Sobrien#if !defined (EH_FRAME_SECTION_ASM_OP) && defined (DWARF2_UNWIND_INFO) && defined(ASM_OUTPUT_SECTION_NAME) 12150397Sobrien#define EH_FRAME_SECTION_ASM_OP ".section\t.eh_frame,\"aw\"" 12250397Sobrien#endif 12318334Speter 12418334Speter#ifdef OBJECT_FORMAT_ELF 12518334Speter 12618334Speter/* Declare a pointer to void function type. */ 12718334Spetertypedef void (*func_ptr) (void); 12818334Speter#define STATIC static 12918334Speter 13018334Speter#else /* OBJECT_FORMAT_ELF */ 13118334Speter 13218334Speter#include "gbl-ctors.h" 13318334Speter 13418334Speter#ifndef ON_EXIT 13518334Speter#define ON_EXIT(a, b) 13618334Speter#endif 13718334Speter#define STATIC 13818334Speter 13918334Speter#endif /* OBJECT_FORMAT_ELF */ 14018334Speter 14118334Speter#ifdef CRT_BEGIN 14218334Speter 14318334Speter#ifdef INIT_SECTION_ASM_OP 14418334Speter 14518334Speter#ifdef OBJECT_FORMAT_ELF 14618334Speter 14718334Speter/* Run all the global destructors on exit from the program. */ 14818334Speter 14918334Speter/* Some systems place the number of pointers in the first word of the 15018334Speter table. On SVR4 however, that word is -1. In all cases, the table is 15118334Speter null-terminated. On SVR4, we start from the beginning of the list and 15218334Speter invoke each per-compilation-unit destructor routine in order 15318334Speter until we find that null. 15418334Speter 15518334Speter Note that this function MUST be static. There will be one of these 15618334Speter functions in each root executable and one in each shared library, but 15718334Speter although they all have the same code, each one is unique in that it 15818334Speter refers to one particular associated `__DTOR_LIST__' which belongs to the 15950397Sobrien same particular root executable or shared library file. 16018334Speter 16150397Sobrien On some systems, this routine is run more than once from the .fini, 16250397Sobrien when exit is called recursively, so we arrange to remember where in 16350397Sobrien the list we left off processing, and we resume at that point, 16450397Sobrien should we be re-invoked. */ 16550397Sobrien 16650397Sobrienstatic char __EH_FRAME_BEGIN__[]; 16718334Speterstatic func_ptr __DTOR_LIST__[]; 16818334Speterstatic void 16918334Speter__do_global_dtors_aux () 17018334Speter{ 17150397Sobrien static func_ptr *p = __DTOR_LIST__ + 1; 17250397Sobrien static int completed = 0; 17350397Sobrien 17450397Sobrien if (completed) 17550397Sobrien return; 17650397Sobrien 17750397Sobrien while (*p) 17850397Sobrien { 17950397Sobrien p++; 18050397Sobrien (*(p-1)) (); 18150397Sobrien } 18250397Sobrien 18350397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 18450397Sobrien if (__deregister_frame_info) 18550397Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 18650397Sobrien#endif 18750397Sobrien completed = 1; 18818334Speter} 18918334Speter 19050397Sobrien 19118334Speter/* Stick a call to __do_global_dtors_aux into the .fini section. */ 19250397Sobrien 19350397Sobrienstatic void __attribute__ ((__unused__)) 19418334Speterfini_dummy () 19518334Speter{ 19618334Speter asm (FINI_SECTION_ASM_OP); 19718334Speter __do_global_dtors_aux (); 19818334Speter#ifdef FORCE_FINI_SECTION_ALIGN 19918334Speter FORCE_FINI_SECTION_ALIGN; 20018334Speter#endif 20118334Speter asm (TEXT_SECTION_ASM_OP); 20218334Speter} 20318334Speter 20450397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 20550397Sobrien/* Stick a call to __register_frame_info into the .init section. For some 20650397Sobrien reason calls with no arguments work more reliably in .init, so stick the 20750397Sobrien call in another function. */ 20850397Sobrien 20950397Sobrienstatic void 21050397Sobrienframe_dummy () 21150397Sobrien{ 21250397Sobrien static struct object object; 21350397Sobrien if (__register_frame_info) 21450397Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 21550397Sobrien} 21650397Sobrien 21750397Sobrienstatic void __attribute__ ((__unused__)) 21850397Sobrieninit_dummy () 21950397Sobrien{ 22050397Sobrien asm (INIT_SECTION_ASM_OP); 22150397Sobrien frame_dummy (); 22250397Sobrien#ifdef FORCE_INIT_SECTION_ALIGN 22350397Sobrien FORCE_INIT_SECTION_ALIGN; 22450397Sobrien#endif 22550397Sobrien asm (TEXT_SECTION_ASM_OP); 22650397Sobrien} 22750397Sobrien#endif /* EH_FRAME_SECTION_ASM_OP */ 22850397Sobrien 22918334Speter#else /* OBJECT_FORMAT_ELF */ 23018334Speter 23118334Speter/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o 23218334Speter and once in crtend.o). It must be declared static to avoid a link 23318334Speter error. Here, we define __do_global_ctors as an externally callable 23418334Speter function. It is externally callable so that __main can invoke it when 23518334Speter INVOKE__main is defined. This has the additional effect of forcing cc1 23618334Speter to switch to the .text section. */ 23750397Sobrien 23818334Speterstatic void __do_global_ctors_aux (); 23918334Spetervoid __do_global_ctors () 24018334Speter{ 24118334Speter#ifdef INVOKE__main /* If __main won't actually call __do_global_ctors 24218334Speter then it doesn't matter what's inside the function. 24318334Speter The inside of __do_global_ctors_aux is called 24418334Speter automatically in that case. 24518334Speter And the Alliant fx2800 linker crashes 24618334Speter on this reference. So prevent the crash. */ 24718334Speter __do_global_ctors_aux (); 24818334Speter#endif 24918334Speter} 25018334Speter 25118334Speterasm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 25218334Speter 25318334Speter/* On some svr4 systems, the initial .init section preamble code provided in 25418334Speter crti.o may do something, such as bump the stack, which we have to 25518334Speter undo before we reach the function prologue code for __do_global_ctors 25618334Speter (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE 25750397Sobrien to expand into the code needed to undo the actions of the crti.o file. */ 25818334Speter 25918334Speter#ifdef INIT_SECTION_PREAMBLE 26018334Speter INIT_SECTION_PREAMBLE; 26118334Speter#endif 26218334Speter 26318334Speter/* A routine to invoke all of the global constructors upon entry to the 26418334Speter program. We put this into the .init section (for systems that have 26518334Speter such a thing) so that we can properly perform the construction of 26618334Speter file-scope static-storage C++ objects within shared libraries. */ 26718334Speter 26818334Speterstatic void 26918334Speter__do_global_ctors_aux () /* prologue goes in .init section */ 27018334Speter{ 27118334Speter#ifdef FORCE_INIT_SECTION_ALIGN 27218334Speter FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */ 27318334Speter#endif 27418334Speter asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */ 27518334Speter DO_GLOBAL_CTORS_BODY; 27618334Speter ON_EXIT (__do_global_dtors, 0); 27718334Speter} 27818334Speter 27918334Speter#endif /* OBJECT_FORMAT_ELF */ 28050397Sobrien 28150397Sobrien#else /* defined(INIT_SECTION_ASM_OP) */ 28250397Sobrien 28350397Sobrien#ifdef HAS_INIT_SECTION 28450397Sobrien/* This case is used by the Irix 6 port, which supports named sections but 28550397Sobrien not an SVR4-style .fini section. __do_global_dtors can be non-static 28650397Sobrien in this case because we protect it with -hidden_symbol. */ 28750397Sobrien 28850397Sobrienstatic char __EH_FRAME_BEGIN__[]; 28950397Sobrienstatic func_ptr __DTOR_LIST__[]; 29050397Sobrienvoid 29150397Sobrien__do_global_dtors () 29250397Sobrien{ 29350397Sobrien func_ptr *p; 29450397Sobrien for (p = __DTOR_LIST__ + 1; *p; p++) 29550397Sobrien (*p) (); 29650397Sobrien 29750397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 29850397Sobrien if (__deregister_frame_info) 29950397Sobrien __deregister_frame_info (__EH_FRAME_BEGIN__); 30050397Sobrien#endif 30150397Sobrien} 30250397Sobrien 30350397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 30450397Sobrien/* Define a function here to call __register_frame. crtend.o is linked in 30550397Sobrien after libgcc.a, and hence can't call libgcc.a functions directly. That 30650397Sobrien can lead to unresolved function references. */ 30750397Sobrienvoid 30850397Sobrien__frame_dummy () 30950397Sobrien{ 31050397Sobrien static struct object object; 31150397Sobrien if (__register_frame_info) 31250397Sobrien __register_frame_info (__EH_FRAME_BEGIN__, &object); 31350397Sobrien} 31450397Sobrien#endif 31550397Sobrien#endif 31650397Sobrien 31718334Speter#endif /* defined(INIT_SECTION_ASM_OP) */ 31818334Speter 31918334Speter/* Force cc1 to switch to .data section. */ 32050397Sobrienstatic func_ptr force_to_data[0] __attribute__ ((__unused__)) = { }; 32118334Speter 32218334Speter/* NOTE: In order to be able to support SVR4 shared libraries, we arrange 32318334Speter to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, 32418334Speter __DTOR_END__ } per root executable and also one set of these symbols 32518334Speter per shared library. So in any given whole process image, we may have 32618334Speter multiple definitions of each of these symbols. In order to prevent 32718334Speter these definitions from conflicting with one another, and in order to 32818334Speter ensure that the proper lists are used for the initialization/finalization 32918334Speter of each individual shared library (respectively), we give these symbols 33018334Speter only internal (i.e. `static') linkage, and we also make it a point to 33118334Speter refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ 33218334Speter symbol in crtbegin.o, where they are defined. */ 33318334Speter 33418334Speter/* The -1 is a flag to __do_global_[cd]tors 33518334Speter indicating that this table does not start with a count of elements. */ 33618334Speter#ifdef CTOR_LIST_BEGIN 33718334SpeterCTOR_LIST_BEGIN; 33818334Speter#else 33918334Speterasm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 34050397SobrienSTATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__)) 34150397Sobrien = { (func_ptr) (-1) }; 34218334Speter#endif 34318334Speter 34418334Speter#ifdef DTOR_LIST_BEGIN 34518334SpeterDTOR_LIST_BEGIN; 34618334Speter#else 34718334Speterasm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 34818334SpeterSTATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) }; 34918334Speter#endif 35018334Speter 35150397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 35250397Sobrien/* Stick a label at the beginning of the frame unwind info so we can register 35350397Sobrien and deregister it with the exception handling library code. */ 35450397Sobrien 35550397Sobrienasm (EH_FRAME_SECTION_ASM_OP); 35650397Sobrien#ifdef INIT_SECTION_ASM_OP 35750397SobrienSTATIC 35850397Sobrien#endif 35950397Sobrienchar __EH_FRAME_BEGIN__[] = { }; 36050397Sobrien#endif /* EH_FRAME_SECTION_ASM_OP */ 36150397Sobrien 36218334Speter#endif /* defined(CRT_BEGIN) */ 36318334Speter 36418334Speter#ifdef CRT_END 36518334Speter 36618334Speter#ifdef INIT_SECTION_ASM_OP 36718334Speter 36818334Speter#ifdef OBJECT_FORMAT_ELF 36918334Speter 37018334Speterstatic func_ptr __CTOR_END__[]; 37118334Speterstatic void 37218334Speter__do_global_ctors_aux () 37318334Speter{ 37418334Speter func_ptr *p; 37518334Speter for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 37618334Speter (*p) (); 37718334Speter} 37818334Speter 37918334Speter/* Stick a call to __do_global_ctors_aux into the .init section. */ 38050397Sobrien 38150397Sobrienstatic void __attribute__ ((__unused__)) 38218334Speterinit_dummy () 38318334Speter{ 38418334Speter asm (INIT_SECTION_ASM_OP); 38518334Speter __do_global_ctors_aux (); 38618334Speter#ifdef FORCE_INIT_SECTION_ALIGN 38718334Speter FORCE_INIT_SECTION_ALIGN; 38818334Speter#endif 38918334Speter asm (TEXT_SECTION_ASM_OP); 39018334Speter 39150397Sobrien/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr, 39250397Sobrien __environ and atexit (). We have to make sure they are in the .dynsym 39350397Sobrien section. We accomplish it by making a dummy call here. This 39450397Sobrien code is never reached. */ 39518334Speter 39650397Sobrien#if defined(__linux__) && defined(__PIC__) && defined(__i386__) 39718334Speter { 39818334Speter extern void *___brk_addr; 39918334Speter extern char **__environ; 40018334Speter 40118334Speter ___brk_addr = __environ; 40218334Speter atexit (); 40318334Speter } 40418334Speter#endif 40518334Speter} 40618334Speter 40718334Speter#else /* OBJECT_FORMAT_ELF */ 40818334Speter 40918334Speter/* Stick the real initialization code, followed by a normal sort of 41018334Speter function epilogue at the very end of the .init section for this 41118334Speter entire root executable file or for this entire shared library file. 41218334Speter 41318334Speter Note that we use some tricks here to get *just* the body and just 41418334Speter a function epilogue (but no function prologue) into the .init 41518334Speter section of the crtend.o file. Specifically, we switch to the .text 41618334Speter section, start to define a function, and then we switch to the .init 41718334Speter section just before the body code. 41818334Speter 41918334Speter Earlier on, we put the corresponding function prologue into the .init 42018334Speter section of the crtbegin.o file (which will be linked in first). 42118334Speter 42218334Speter Note that we want to invoke all constructors for C++ file-scope static- 42318334Speter storage objects AFTER any other possible initialization actions which 42418334Speter may be performed by the code in the .init section contributions made by 42518334Speter other libraries, etc. That's because those other initializations may 42618334Speter include setup operations for very primitive things (e.g. initializing 42718334Speter the state of the floating-point coprocessor, etc.) which should be done 42850397Sobrien before we start to execute any of the user's code. */ 42918334Speter 43018334Speterstatic void 43118334Speter__do_global_ctors_aux () /* prologue goes in .text section */ 43218334Speter{ 43318334Speter asm (INIT_SECTION_ASM_OP); 43418334Speter DO_GLOBAL_CTORS_BODY; 43518334Speter ON_EXIT (__do_global_dtors, 0); 43618334Speter} /* epilogue and body go in .init section */ 43718334Speter 43850397Sobrien#ifdef FORCE_INIT_SECTION_ALIGN 43950397SobrienFORCE_INIT_SECTION_ALIGN; 44050397Sobrien#endif 44150397Sobrien 44250397Sobrienasm (TEXT_SECTION_ASM_OP); 44350397Sobrien 44418334Speter#endif /* OBJECT_FORMAT_ELF */ 44518334Speter 44650397Sobrien#else /* defined(INIT_SECTION_ASM_OP) */ 44750397Sobrien 44850397Sobrien#ifdef HAS_INIT_SECTION 44950397Sobrien/* This case is used by the Irix 6 port, which supports named sections but 45050397Sobrien not an SVR4-style .init section. __do_global_ctors can be non-static 45150397Sobrien in this case because we protect it with -hidden_symbol. */ 45250397Sobrienstatic func_ptr __CTOR_END__[]; 45350397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 45450397Sobrienextern void __frame_dummy (void); 45550397Sobrien#endif 45650397Sobrienvoid 45750397Sobrien__do_global_ctors () 45850397Sobrien{ 45950397Sobrien func_ptr *p; 46050397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 46150397Sobrien __frame_dummy (); 46250397Sobrien#endif 46350397Sobrien for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 46450397Sobrien (*p) (); 46550397Sobrien} 46650397Sobrien#endif 46750397Sobrien 46818334Speter#endif /* defined(INIT_SECTION_ASM_OP) */ 46918334Speter 47018334Speter/* Force cc1 to switch to .data section. */ 47150397Sobrienstatic func_ptr force_to_data[0] __attribute__ ((__unused__)) = { }; 47218334Speter 47318334Speter/* Put a word containing zero at the end of each of our two lists of function 47418334Speter addresses. Note that the words defined here go into the .ctors and .dtors 47518334Speter sections of the crtend.o file, and since that file is always linked in 47618334Speter last, these words naturally end up at the very ends of the two lists 47718334Speter contained in these two sections. */ 47818334Speter 47918334Speter#ifdef CTOR_LIST_END 48018334SpeterCTOR_LIST_END; 48118334Speter#else 48218334Speterasm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 48318334SpeterSTATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 }; 48418334Speter#endif 48518334Speter 48618334Speter#ifdef DTOR_LIST_END 48718334SpeterDTOR_LIST_END; 48818334Speter#else 48918334Speterasm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 49050397SobrienSTATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__)) 49150397Sobrien = { (func_ptr) 0 }; 49218334Speter#endif 49318334Speter 49450397Sobrien#ifdef EH_FRAME_SECTION_ASM_OP 49550397Sobrien/* Terminate the frame unwind info section with a 4byte 0 as a sentinel; 49650397Sobrien this would be the 'length' field in a real FDE. */ 49750397Sobrien 49850397Sobrientypedef unsigned int ui32 __attribute__ ((mode (SI))); 49950397Sobrienasm (EH_FRAME_SECTION_ASM_OP); 50050397SobrienSTATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 }; 50150397Sobrien#endif /* EH_FRAME_SECTION */ 50250397Sobrien 50318334Speter#endif /* defined(CRT_END) */ 504