crtstuff.c revision 18334
118334Speter/* Specialized bits of code needed to support construction and 218334Speter destruction of file-scope objects in C++ code. 318334Speter 418334Speter Written by Ron Guilmette (rfg@netcom.com) with help from Richard Stallman. 518334Speter 618334SpeterCopyright (C) 1991, 1994, 1995 Free Software Foundation, Inc. 718334Speter 818334SpeterThis file is part of GNU CC. 918334Speter 1018334SpeterGNU CC is free software; you can redistribute it and/or modify 1118334Speterit under the terms of the GNU General Public License as published by 1218334Speterthe Free Software Foundation; either version 2, or (at your option) 1318334Speterany later version. 1418334Speter 1518334SpeterGNU CC is distributed in the hope that it will be useful, 1618334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1718334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1818334SpeterGNU General Public License for more details. 1918334Speter 2018334SpeterYou should have received a copy of the GNU General Public License 2118334Speteralong with GNU CC; see the file COPYING. If not, write to 2218334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 2318334SpeterBoston, MA 02111-1307, USA. */ 2418334Speter 2518334Speter/* As a special exception, if you link this library with files 2618334Speter compiled with GCC to produce an executable, this does not cause 2718334Speter the resulting executable to be covered by the GNU General Public License. 2818334Speter This exception does not however invalidate any other reasons why 2918334Speter the executable file might be covered by the GNU General Public License. */ 3018334Speter 3118334Speter/* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled 3218334Speter multiple times and yields multiple .o files. 3318334Speter 3418334Speter This file is useful on target machines where the object file format 3518334Speter supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On 3618334Speter such systems, this file allows us to avoid running collect (or any 3718334Speter other such slow and painful kludge). Additionally, if the target 3818334Speter system supports a .init section, this file allows us to support the 3918334Speter linking of C++ code with a non-C++ main program. 4018334Speter 4118334Speter Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then 4218334Speter this file *will* make use of the .init section. If that symbol is 4318334Speter not defined however, then the .init section will not be used. 4418334Speter 4518334Speter Currently, only ELF and COFF are supported. It is likely however that 4618334Speter ROSE could also be supported, if someone was willing to do the work to 4718334Speter make whatever (small?) adaptations are needed. (Some work may be 4818334Speter needed on the ROSE assembler and linker also.) 4918334Speter 5018334Speter This file must be compiled with gcc. */ 5118334Speter 5218334Speter/* It is incorrect to include config.h here, because this file is being 5318334Speter compiled for the target, and hence definitions concerning only the host 5418334Speter do not apply. */ 5518334Speter 5618334Speter#include "tm.h" 5718334Speter 5818334Speter/* Provide default definitions for the pseudo-ops used to switch to the 5918334Speter .ctors and .dtors sections. 6018334Speter 6118334Speter Note that we want to give these sections the SHF_WRITE attribute 6218334Speter because these sections will actually contain data (i.e. tables of 6318334Speter addresses of functions in the current root executable or shared library 6418334Speter file) and, in the case of a shared library, the relocatable addresses 6518334Speter will have to be properly resolved/relocated (and then written into) by 6618334Speter the dynamic linker when it actually attaches the given shared library 6718334Speter to the executing process. (Note that on SVR4, you may wish to use the 6818334Speter `-z text' option to the ELF linker, when building a shared library, as 6918334Speter an additional check that you are doing everything right. But if you do 7018334Speter use the `-z text' option when building a shared library, you will get 7118334Speter errors unless the .ctors and .dtors sections are marked as writable 7218334Speter via the SHF_WRITE attribute.) */ 7318334Speter 7418334Speter#ifndef CTORS_SECTION_ASM_OP 7518334Speter#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" 7618334Speter#endif 7718334Speter#ifndef DTORS_SECTION_ASM_OP 7818334Speter#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\"" 7918334Speter#endif 8018334Speter 8118334Speter#ifdef OBJECT_FORMAT_ELF 8218334Speter 8318334Speter/* Declare a pointer to void function type. */ 8418334Spetertypedef void (*func_ptr) (void); 8518334Speter#define STATIC static 8618334Speter 8718334Speter#else /* OBJECT_FORMAT_ELF */ 8818334Speter 8918334Speter#include "gbl-ctors.h" 9018334Speter 9118334Speter#ifndef ON_EXIT 9218334Speter#define ON_EXIT(a, b) 9318334Speter#endif 9418334Speter#define STATIC 9518334Speter 9618334Speter#endif /* OBJECT_FORMAT_ELF */ 9718334Speter 9818334Speter#ifdef CRT_BEGIN 9918334Speter 10018334Speter#ifdef INIT_SECTION_ASM_OP 10118334Speter 10218334Speter#ifdef OBJECT_FORMAT_ELF 10318334Speter 10418334Speter/* Run all the global destructors on exit from the program. */ 10518334Speter 10618334Speter/* Some systems place the number of pointers in the first word of the 10718334Speter table. On SVR4 however, that word is -1. In all cases, the table is 10818334Speter null-terminated. On SVR4, we start from the beginning of the list and 10918334Speter invoke each per-compilation-unit destructor routine in order 11018334Speter until we find that null. 11118334Speter 11218334Speter Note that this function MUST be static. There will be one of these 11318334Speter functions in each root executable and one in each shared library, but 11418334Speter although they all have the same code, each one is unique in that it 11518334Speter refers to one particular associated `__DTOR_LIST__' which belongs to the 11618334Speter same particular root executable or shared library file. */ 11718334Speter 11818334Speterstatic func_ptr __DTOR_LIST__[]; 11918334Speterstatic void 12018334Speter__do_global_dtors_aux () 12118334Speter{ 12218334Speter func_ptr *p; 12318334Speter for (p = __DTOR_LIST__ + 1; *p; p++) 12418334Speter (*p) (); 12518334Speter} 12618334Speter 12718334Speter/* Stick a call to __do_global_dtors_aux into the .fini section. */ 12818334Speterstatic void 12918334Speterfini_dummy () 13018334Speter{ 13118334Speter asm (FINI_SECTION_ASM_OP); 13218334Speter __do_global_dtors_aux (); 13318334Speter#ifdef FORCE_FINI_SECTION_ALIGN 13418334Speter FORCE_FINI_SECTION_ALIGN; 13518334Speter#endif 13618334Speter asm (TEXT_SECTION_ASM_OP); 13718334Speter} 13818334Speter 13918334Speter#else /* OBJECT_FORMAT_ELF */ 14018334Speter 14118334Speter/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o 14218334Speter and once in crtend.o). It must be declared static to avoid a link 14318334Speter error. Here, we define __do_global_ctors as an externally callable 14418334Speter function. It is externally callable so that __main can invoke it when 14518334Speter INVOKE__main is defined. This has the additional effect of forcing cc1 14618334Speter to switch to the .text section. */ 14718334Speterstatic void __do_global_ctors_aux (); 14818334Spetervoid __do_global_ctors () 14918334Speter{ 15018334Speter#ifdef INVOKE__main /* If __main won't actually call __do_global_ctors 15118334Speter then it doesn't matter what's inside the function. 15218334Speter The inside of __do_global_ctors_aux is called 15318334Speter automatically in that case. 15418334Speter And the Alliant fx2800 linker crashes 15518334Speter on this reference. So prevent the crash. */ 15618334Speter __do_global_ctors_aux (); 15718334Speter#endif 15818334Speter} 15918334Speter 16018334Speterasm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 16118334Speter 16218334Speter/* On some svr4 systems, the initial .init section preamble code provided in 16318334Speter crti.o may do something, such as bump the stack, which we have to 16418334Speter undo before we reach the function prologue code for __do_global_ctors 16518334Speter (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE 16618334Speter to expand into the code needed to undo the actions of the crti.o file. */ 16718334Speter 16818334Speter#ifdef INIT_SECTION_PREAMBLE 16918334Speter INIT_SECTION_PREAMBLE; 17018334Speter#endif 17118334Speter 17218334Speter/* A routine to invoke all of the global constructors upon entry to the 17318334Speter program. We put this into the .init section (for systems that have 17418334Speter such a thing) so that we can properly perform the construction of 17518334Speter file-scope static-storage C++ objects within shared libraries. */ 17618334Speter 17718334Speterstatic void 17818334Speter__do_global_ctors_aux () /* prologue goes in .init section */ 17918334Speter{ 18018334Speter#ifdef FORCE_INIT_SECTION_ALIGN 18118334Speter FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */ 18218334Speter#endif 18318334Speter asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */ 18418334Speter DO_GLOBAL_CTORS_BODY; 18518334Speter ON_EXIT (__do_global_dtors, 0); 18618334Speter} 18718334Speter 18818334Speter#endif /* OBJECT_FORMAT_ELF */ 18918334Speter#endif /* defined(INIT_SECTION_ASM_OP) */ 19018334Speter 19118334Speter/* Force cc1 to switch to .data section. */ 19218334Speterstatic func_ptr force_to_data[0] = { }; 19318334Speter 19418334Speter/* NOTE: In order to be able to support SVR4 shared libraries, we arrange 19518334Speter to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, 19618334Speter __DTOR_END__ } per root executable and also one set of these symbols 19718334Speter per shared library. So in any given whole process image, we may have 19818334Speter multiple definitions of each of these symbols. In order to prevent 19918334Speter these definitions from conflicting with one another, and in order to 20018334Speter ensure that the proper lists are used for the initialization/finalization 20118334Speter of each individual shared library (respectively), we give these symbols 20218334Speter only internal (i.e. `static') linkage, and we also make it a point to 20318334Speter refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ 20418334Speter symbol in crtbegin.o, where they are defined. */ 20518334Speter 20618334Speter/* The -1 is a flag to __do_global_[cd]tors 20718334Speter indicating that this table does not start with a count of elements. */ 20818334Speter#ifdef CTOR_LIST_BEGIN 20918334SpeterCTOR_LIST_BEGIN; 21018334Speter#else 21118334Speterasm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 21218334SpeterSTATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) }; 21318334Speter#endif 21418334Speter 21518334Speter#ifdef DTOR_LIST_BEGIN 21618334SpeterDTOR_LIST_BEGIN; 21718334Speter#else 21818334Speterasm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 21918334SpeterSTATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) }; 22018334Speter#endif 22118334Speter 22218334Speter#endif /* defined(CRT_BEGIN) */ 22318334Speter 22418334Speter#ifdef CRT_END 22518334Speter 22618334Speter#ifdef INIT_SECTION_ASM_OP 22718334Speter 22818334Speter#ifdef OBJECT_FORMAT_ELF 22918334Speter 23018334Speterstatic func_ptr __CTOR_END__[]; 23118334Speterstatic void 23218334Speter__do_global_ctors_aux () 23318334Speter{ 23418334Speter func_ptr *p; 23518334Speter for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 23618334Speter (*p) (); 23718334Speter} 23818334Speter 23918334Speter/* Stick a call to __do_global_ctors_aux into the .init section. */ 24018334Speterstatic void 24118334Speterinit_dummy () 24218334Speter{ 24318334Speter asm (INIT_SECTION_ASM_OP); 24418334Speter __do_global_ctors_aux (); 24518334Speter#ifdef FORCE_INIT_SECTION_ALIGN 24618334Speter FORCE_INIT_SECTION_ALIGN; 24718334Speter#endif 24818334Speter asm (TEXT_SECTION_ASM_OP); 24918334Speter 25018334Speter/* This is a kludge. The Linux dynamic linker needs ___brk_addr, __environ 25118334Speter and atexit (). We have to make sure they are in the .dynsym section. We 25218334Speter accomplish it by making a dummy call here. This 25318334Speter code is never reached. */ 25418334Speter 25518334Speter#if defined(__linux__) && defined(__PIC__) 25618334Speter { 25718334Speter extern void *___brk_addr; 25818334Speter extern char **__environ; 25918334Speter 26018334Speter ___brk_addr = __environ; 26118334Speter atexit (); 26218334Speter } 26318334Speter#endif 26418334Speter} 26518334Speter 26618334Speter#else /* OBJECT_FORMAT_ELF */ 26718334Speter 26818334Speter/* Stick the real initialization code, followed by a normal sort of 26918334Speter function epilogue at the very end of the .init section for this 27018334Speter entire root executable file or for this entire shared library file. 27118334Speter 27218334Speter Note that we use some tricks here to get *just* the body and just 27318334Speter a function epilogue (but no function prologue) into the .init 27418334Speter section of the crtend.o file. Specifically, we switch to the .text 27518334Speter section, start to define a function, and then we switch to the .init 27618334Speter section just before the body code. 27718334Speter 27818334Speter Earlier on, we put the corresponding function prologue into the .init 27918334Speter section of the crtbegin.o file (which will be linked in first). 28018334Speter 28118334Speter Note that we want to invoke all constructors for C++ file-scope static- 28218334Speter storage objects AFTER any other possible initialization actions which 28318334Speter may be performed by the code in the .init section contributions made by 28418334Speter other libraries, etc. That's because those other initializations may 28518334Speter include setup operations for very primitive things (e.g. initializing 28618334Speter the state of the floating-point coprocessor, etc.) which should be done 28718334Speter before we start to execute any of the user's code. */ 28818334Speter 28918334Speterstatic void 29018334Speter__do_global_ctors_aux () /* prologue goes in .text section */ 29118334Speter{ 29218334Speter asm (INIT_SECTION_ASM_OP); 29318334Speter DO_GLOBAL_CTORS_BODY; 29418334Speter ON_EXIT (__do_global_dtors, 0); 29518334Speter} /* epilogue and body go in .init section */ 29618334Speter 29718334Speter#endif /* OBJECT_FORMAT_ELF */ 29818334Speter 29918334Speter#endif /* defined(INIT_SECTION_ASM_OP) */ 30018334Speter 30118334Speter/* Force cc1 to switch to .data section. */ 30218334Speterstatic func_ptr force_to_data[0] = { }; 30318334Speter 30418334Speter/* Put a word containing zero at the end of each of our two lists of function 30518334Speter addresses. Note that the words defined here go into the .ctors and .dtors 30618334Speter sections of the crtend.o file, and since that file is always linked in 30718334Speter last, these words naturally end up at the very ends of the two lists 30818334Speter contained in these two sections. */ 30918334Speter 31018334Speter#ifdef CTOR_LIST_END 31118334SpeterCTOR_LIST_END; 31218334Speter#else 31318334Speterasm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 31418334SpeterSTATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 }; 31518334Speter#endif 31618334Speter 31718334Speter#ifdef DTOR_LIST_END 31818334SpeterDTOR_LIST_END; 31918334Speter#else 32018334Speterasm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 32118334SpeterSTATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 }; 32218334Speter#endif 32318334Speter 32418334Speter#endif /* defined(CRT_END) */ 325