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