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