(root)/
gcc-13.2.0/
libgcc/
crtstuff.c
       1  /* Specialized bits of code needed to support construction and
       2     destruction of file-scope objects in C++ code.
       3     Copyright (C) 1991-2023 Free Software Foundation, Inc.
       4     Contributed by Ron Guilmette (rfg@monkeys.com).
       5  
       6  This file is part of GCC.
       7  
       8  GCC is free software; you can redistribute it and/or modify it under
       9  the terms of the GNU General Public License as published by the Free
      10  Software Foundation; either version 3, or (at your option) any later
      11  version.
      12  
      13  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16  for more details.
      17  
      18  Under Section 7 of GPL version 3, you are granted additional
      19  permissions described in the GCC Runtime Library Exception, version
      20  3.1, as published by the Free Software Foundation.
      21  
      22  You should have received a copy of the GNU General Public License and
      23  a copy of the GCC Runtime Library Exception along with this program;
      24  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      25  <http://www.gnu.org/licenses/>.  */
      26  
      27  /* This file is a bit like libgcc2.c in that it is compiled
      28     multiple times and yields multiple .o files.
      29  
      30     This file is useful on target machines where the object file format
      31     supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE).  On
      32     such systems, this file allows us to avoid running collect (or any
      33     other such slow and painful kludge).  Additionally, if the target
      34     system supports a .init section, this file allows us to support the
      35     linking of C++ code with a non-C++ main program.
      36  
      37     Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then
      38     this file *will* make use of the .init section.  If that symbol is
      39     not defined however, then the .init section will not be used.
      40  
      41     Currently, only ELF and COFF are supported.  It is likely however that
      42     ROSE could also be supported, if someone was willing to do the work to
      43     make whatever (small?) adaptations are needed.  (Some work may be
      44     needed on the ROSE assembler and linker also.)
      45  
      46     This file must be compiled with gcc.  */
      47  
      48  /* Target machine header files require this define. */
      49  #define IN_LIBGCC2
      50  
      51  /* FIXME: Including auto-host is incorrect, but until we have
      52     identified the set of defines that need to go into auto-target.h,
      53     this will have to do.  */
      54  #include "auto-host.h"
      55  #undef caddr_t
      56  #undef pid_t
      57  #undef rlim_t
      58  #undef ssize_t
      59  #undef vfork
      60  #include "tconfig.h"
      61  #include "tsystem.h"
      62  #include "coretypes.h"
      63  #include "tm.h"
      64  #include "libgcc_tm.h"
      65  #include "unwind-dw2-fde.h"
      66  
      67  #ifndef FORCE_CODE_SECTION_ALIGN
      68  # define FORCE_CODE_SECTION_ALIGN
      69  #endif
      70  
      71  #ifndef CRT_CALL_STATIC_FUNCTION
      72  # define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)	\
      73  static void __attribute__((__used__))			\
      74  call_ ## FUNC (void)					\
      75  {							\
      76    asm (SECTION_OP);					\
      77    FUNC ();						\
      78    FORCE_CODE_SECTION_ALIGN				\
      79    asm (__LIBGCC_TEXT_SECTION_ASM_OP__);				\
      80  }
      81  #endif
      82  
      83  #if defined(TARGET_DL_ITERATE_PHDR) && \
      84     (defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__))
      85  #define BSD_DL_ITERATE_PHDR_AVAILABLE
      86  #endif
      87   
      88  #if defined(OBJECT_FORMAT_ELF) \
      89      && !defined(OBJECT_FORMAT_FLAT) \
      90      && defined(HAVE_LD_EH_FRAME_HDR) \
      91      && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
      92      && defined(BSD_DL_ITERATE_PHDR_AVAILABLE)
      93  #include <link.h>
      94  # define USE_PT_GNU_EH_FRAME
      95  #endif
      96  
      97  #if defined(OBJECT_FORMAT_ELF) \
      98      && !defined(OBJECT_FORMAT_FLAT) \
      99      && defined(HAVE_LD_EH_FRAME_HDR) && defined(TARGET_DL_ITERATE_PHDR) \
     100      && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
     101      && defined(__sun__) && defined(__svr4__)
     102  #include <link.h>
     103  # define USE_PT_GNU_EH_FRAME
     104  #endif
     105  
     106  #if defined(OBJECT_FORMAT_ELF) \
     107      && !defined(OBJECT_FORMAT_FLAT) \
     108      && defined(HAVE_LD_EH_FRAME_HDR) \
     109      && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
     110      && defined(__GLIBC__) && __GLIBC__ >= 2
     111  #include <link.h>
     112  /* uClibc pretends to be glibc 2.2 and DT_CONFIG is defined in its link.h.
     113     But it doesn't use PT_GNU_EH_FRAME ELF segment currently.  */
     114  # if !defined(__UCLIBC__) \
     115       && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
     116       || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
     117  #  define USE_PT_GNU_EH_FRAME
     118  # endif
     119  #endif
     120  
     121  #if defined(OBJECT_FORMAT_ELF) \
     122      && !defined(OBJECT_FORMAT_FLAT) \
     123      && defined(HAVE_LD_EH_FRAME_HDR) \
     124      && !defined(CRTSTUFFT_O) \
     125      && defined(inhibit_libc) \
     126      && (defined(__GLIBC__) || defined(__gnu_linux__) || defined(__GNU__))
     127  /* On systems using glibc, an inhibit_libc build of libgcc is only
     128     part of a bootstrap process.  Build the same crt*.o as would be
     129     built with headers present, so that it is not necessary to build
     130     glibc more than once for the bootstrap to converge.  */
     131  # define USE_PT_GNU_EH_FRAME
     132  #endif
     133  
     134  #ifdef USE_EH_FRAME_REGISTRY_ALWAYS
     135  # ifndef __LIBGCC_EH_FRAME_SECTION_NAME__
     136  #  error "Can't use explicit exception-frame-registration without __LIBGCC_EH_FRAME_SECTION_NAME__"
     137  # endif
     138  #endif
     139  #if defined(__LIBGCC_EH_FRAME_SECTION_NAME__) && (!defined(USE_PT_GNU_EH_FRAME) || defined(USE_EH_FRAME_REGISTRY_ALWAYS))
     140  # define USE_EH_FRAME_REGISTRY
     141  #endif
     142  #if defined(__LIBGCC_EH_FRAME_SECTION_NAME__) \
     143      && __LIBGCC_EH_TABLES_CAN_BE_READ_ONLY__
     144  # define EH_FRAME_SECTION_CONST const
     145  #else
     146  # define EH_FRAME_SECTION_CONST
     147  #endif
     148  
     149  #if !defined(DTOR_LIST_END) && defined(OBJECT_FORMAT_ELF) \
     150      && defined(HAVE_GAS_HIDDEN) && !defined(FINI_ARRAY_SECTION_ASM_OP)
     151  # define HIDDEN_DTOR_LIST_END
     152  #endif
     153  
     154  #if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF)
     155  # define USE_TM_CLONE_REGISTRY 1
     156  #elif !defined(USE_TM_CLONE_REGISTRY)
     157  # define USE_TM_CLONE_REGISTRY 0
     158  #endif
     159  
     160  /* We do not want to add the weak attribute to the declarations of these
     161     routines in unwind-dw2-fde.h because that will cause the definition of
     162     these symbols to be weak as well.
     163  
     164     This exposes a core issue, how to handle creating weak references vs
     165     how to create weak definitions.  Either we have to have the definition
     166     of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or
     167     have a second declaration if we want a function's references to be weak,
     168     but not its definition.
     169  
     170     Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
     171     one thinks about scaling to larger problems -- i.e., the condition under
     172     which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
     173     complicated.
     174  
     175     So, we take an approach similar to #pragma weak -- we have a second
     176     declaration for functions that we want to have weak references.
     177  
     178     Neither way is particularly good.  */
     179  
     180  /* References to __register_frame_info and __deregister_frame_info should
     181     be weak in this file if at all possible.  */
     182  extern void __register_frame_info (const void *, struct object *)
     183  				  TARGET_ATTRIBUTE_WEAK;
     184  extern void __register_frame_info_bases (const void *, struct object *,
     185  					 void *, void *)
     186  				  TARGET_ATTRIBUTE_WEAK;
     187  extern void *__deregister_frame_info (const void *)
     188  				     TARGET_ATTRIBUTE_WEAK;
     189  extern void *__deregister_frame_info_bases (const void *)
     190  				     TARGET_ATTRIBUTE_WEAK;
     191  extern void __do_global_ctors_1 (void);
     192  
     193  /* Likewise for transactional memory clone tables.  */
     194  extern void _ITM_registerTMCloneTable (void *, size_t) TARGET_ATTRIBUTE_WEAK;
     195  extern void _ITM_deregisterTMCloneTable (void *) TARGET_ATTRIBUTE_WEAK;
     196  
     197  #ifdef OBJECT_FORMAT_ELF
     198  
     199  /*  Declare a pointer to void function type.  */
     200  typedef void (*func_ptr) (void);
     201  #define STATIC static
     202  
     203  #else  /* OBJECT_FORMAT_ELF */
     204  
     205  #include "gbl-ctors.h"
     206  
     207  #define STATIC
     208  
     209  #endif /* OBJECT_FORMAT_ELF */
     210  
     211  #ifdef CRT_BEGIN
     212  
     213  /* NOTE:  In order to be able to support SVR4 shared libraries, we arrange
     214     to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
     215     __DTOR_END__ } per root executable and also one set of these symbols
     216     per shared library.  So in any given whole process image, we may have
     217     multiple definitions of each of these symbols.  In order to prevent
     218     these definitions from conflicting with one another, and in order to
     219     ensure that the proper lists are used for the initialization/finalization
     220     of each individual shared library (respectively), we give these symbols
     221     only internal (i.e. `static') linkage, and we also make it a point to
     222     refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
     223     symbol in crtbegin.o, where they are defined.  */
     224  
     225  /* No need for .ctors/.dtors section if linker can place them in
     226     .init_array/.fini_array section.  */
     227  #ifndef USE_INITFINI_ARRAY
     228  /* The -1 is a flag to __do_global_[cd]tors indicating that this table
     229     does not start with a count of elements.  */
     230  #ifdef CTOR_LIST_BEGIN
     231  CTOR_LIST_BEGIN;
     232  #elif defined(__LIBGCC_CTORS_SECTION_ASM_OP__)
     233  /* Hack: force cc1 to switch to .data section early, so that assembling
     234     __CTOR_LIST__ does not undo our behind-the-back change to .ctors.  */
     235  static func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
     236  asm (__LIBGCC_CTORS_SECTION_ASM_OP__);
     237  STATIC func_ptr __CTOR_LIST__[1]
     238    __attribute__ ((__used__, aligned(__alignof__(func_ptr))))
     239    = { (func_ptr) (-1) };
     240  #else
     241  STATIC func_ptr __CTOR_LIST__[1]
     242    __attribute__ ((__used__, section(".ctors"), aligned(__alignof__(func_ptr))))
     243    = { (func_ptr) (-1) };
     244  #endif /* __CTOR_LIST__ alternatives */
     245  
     246  #ifdef DTOR_LIST_BEGIN
     247  DTOR_LIST_BEGIN;
     248  #elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__)
     249  asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
     250  STATIC func_ptr __DTOR_LIST__[1]
     251    __attribute__ ((aligned(__alignof__(func_ptr))))
     252    = { (func_ptr) (-1) };
     253  #else
     254  STATIC func_ptr __DTOR_LIST__[1]
     255    __attribute__((section(".dtors"), aligned(__alignof__(func_ptr))))
     256    = { (func_ptr) (-1) };
     257  #endif /* __DTOR_LIST__ alternatives */
     258  #endif /* USE_INITFINI_ARRAY */
     259  
     260  #ifdef USE_EH_FRAME_REGISTRY
     261  /* Stick a label at the beginning of the frame unwind info so we can register
     262     and deregister it with the exception handling library code.  */
     263  STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
     264       __attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__),
     265  		    aligned(__alignof__ (void *))))
     266       = { };
     267  #endif /* USE_EH_FRAME_REGISTRY */
     268  
     269  #if USE_TM_CLONE_REGISTRY
     270  STATIC func_ptr __TMC_LIST__[]
     271    __attribute__((used, section(".tm_clone_table"), aligned(__alignof__(void*))))
     272    = { };
     273  # ifdef HAVE_GAS_HIDDEN
     274  extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden")));
     275  # endif
     276  
     277  static inline void
     278  deregister_tm_clones (void)
     279  {
     280    void (*fn) (void *);
     281  
     282  #ifdef HAVE_GAS_HIDDEN
     283    func_ptr *end = __TMC_END__;
     284    // Do not optimize the comparison to false.
     285    __asm ("" : "+g" (end));
     286    if (__TMC_LIST__ == end)
     287      return;
     288  #else
     289    if (__TMC_LIST__[0] == NULL)
     290      return;
     291  #endif
     292  
     293    fn = _ITM_deregisterTMCloneTable;
     294    __asm ("" : "+r" (fn));
     295    if (fn)
     296      fn (__TMC_LIST__);
     297  }
     298  
     299  static inline void
     300  register_tm_clones (void)
     301  {
     302    void (*fn) (void *, size_t);
     303    size_t size;
     304  
     305  #ifdef HAVE_GAS_HIDDEN
     306    func_ptr *end = __TMC_END__;
     307    // Do not optimize the comparison to false.
     308    __asm ("" : "+g" (end));
     309    size = (end - __TMC_LIST__) / 2;
     310  #else
     311    for (size = 0; __TMC_LIST__[size * 2] != NULL; size++)
     312      continue;
     313  #endif
     314    if (size == 0)
     315      return;
     316  
     317    fn = _ITM_registerTMCloneTable;
     318    __asm ("" : "+r" (fn));
     319    if (fn)
     320      fn (__TMC_LIST__, size);
     321  }
     322  #endif /* USE_TM_CLONE_REGISTRY */
     323  
     324  #if defined(__LIBGCC_INIT_SECTION_ASM_OP__) \
     325      || defined(__LIBGCC_INIT_ARRAY_SECTION_ASM_OP__)
     326  
     327  #ifdef OBJECT_FORMAT_ELF
     328  
     329  #if DEFAULT_USE_CXA_ATEXIT
     330  /* Declare the __dso_handle variable.  It should have a unique value
     331     in every shared-object; in a main program its value is zero.  The
     332     object should in any case be protected.  This means the instance
     333     in one DSO or the main program is not used in another object.  The
     334     dynamic linker takes care of this.
     335     If __cxa_atexit is not being used, __dso_handle will not be used and
     336     doesn't need to be defined.  */
     337  
     338  #ifdef TARGET_LIBGCC_SDATA_SECTION
     339  extern void *__dso_handle __attribute__ ((__section__ (TARGET_LIBGCC_SDATA_SECTION)));
     340  #endif
     341  #ifdef HAVE_GAS_HIDDEN
     342  extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
     343  #endif
     344  #ifdef CRTSTUFFS_O
     345  void *__dso_handle = &__dso_handle;
     346  #else
     347  void *__dso_handle = 0;
     348  #endif
     349  #endif /* DEFAULT_USE_CXA_ATEXIT */
     350  
     351  /* The __cxa_finalize function may not be available so we use only a
     352     weak declaration.  */
     353  extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
     354  
     355  /* Run all the global destructors on exit from the program.  */
     356  
     357  /* Some systems place the number of pointers in the first word of the
     358     table.  On SVR4 however, that word is -1.  In all cases, the table is
     359     null-terminated.  On SVR4, we start from the beginning of the list and
     360     invoke each per-compilation-unit destructor routine in order
     361     until we find that null.
     362  
     363     Note that this function MUST be static.  There will be one of these
     364     functions in each root executable and one in each shared library, but
     365     although they all have the same code, each one is unique in that it
     366     refers to one particular associated `__DTOR_LIST__' which belongs to the
     367     same particular root executable or shared library file.
     368  
     369     On some systems, this routine is run more than once from the .fini,
     370     when exit is called recursively, so we arrange to remember where in
     371     the list we left off processing, and we resume at that point,
     372     should we be re-invoked.
     373  
     374     This routine does not need to be run if none of the following clauses are
     375     true, as it will not do anything, so can be removed.  */
     376  #if defined(CRTSTUFFS_O) || !defined(FINI_ARRAY_SECTION_ASM_OP) \
     377    || USE_TM_CLONE_REGISTRY || defined(USE_EH_FRAME_REGISTRY)
     378  static void __attribute__((used))
     379  __do_global_dtors_aux (void)
     380  {
     381    static _Bool completed;
     382  
     383    if (__builtin_expect (completed, 0))
     384      return;
     385  
     386  #if DEFAULT_USE_CXA_ATEXIT
     387  #ifdef CRTSTUFFS_O
     388    if (__cxa_finalize)
     389      __cxa_finalize (__dso_handle);
     390  #endif
     391  #endif
     392  
     393  #ifdef FINI_ARRAY_SECTION_ASM_OP
     394    /* If we are using .fini_array then destructors will be run via that
     395       mechanism.  */
     396  #elif defined(HIDDEN_DTOR_LIST_END)
     397    {
     398      /* Safer version that makes sure only .dtors function pointers are
     399         called even if the static variable is maliciously changed.  */
     400      extern func_ptr __DTOR_END__[] __attribute__((visibility ("hidden")));
     401      static size_t dtor_idx;
     402      const size_t max_idx = __DTOR_END__ - __DTOR_LIST__ - 1;
     403      func_ptr *dtor_list;
     404  
     405      __asm ("" : "=g" (dtor_list) : "0" (__DTOR_LIST__));
     406      while (dtor_idx < max_idx)
     407        dtor_list[++dtor_idx] ();
     408    }
     409  #else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
     410    {
     411      static func_ptr *p = __DTOR_LIST__ + 1;
     412      func_ptr f;
     413  
     414      while ((f = *p))
     415        {
     416  	p++;
     417  	f ();
     418        }
     419    }
     420  #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
     421  
     422  #if USE_TM_CLONE_REGISTRY
     423    deregister_tm_clones ();
     424  #endif /* USE_TM_CLONE_REGISTRY */
     425  
     426  #ifdef USE_EH_FRAME_REGISTRY
     427  #ifdef CRT_GET_RFIB_DATA
     428    /* If we used the new __register_frame_info_bases interface,
     429       make sure that we deregister from the same place.  */
     430    if (__deregister_frame_info_bases)
     431      __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
     432  #else
     433    if (__deregister_frame_info)
     434      __deregister_frame_info (__EH_FRAME_BEGIN__);
     435  #endif
     436  #endif
     437  
     438    completed = 1;
     439  }
     440  
     441  /* Stick a call to __do_global_dtors_aux into the .fini section.  */
     442  #ifdef FINI_SECTION_ASM_OP
     443  CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
     444  #elif defined (FINI_ARRAY_SECTION_ASM_OP)
     445  #if defined(__FDPIC__)
     446  __asm__("\t.equ\t__do_global_dtors_aux_alias, __do_global_dtors_aux\n");
     447  extern char __do_global_dtors_aux_alias;
     448  static void *__do_global_dtors_aux_fini_array_entry[]
     449  __attribute__ ((__used__, section(".fini_array"), aligned(sizeof(void *))))
     450       = { &__do_global_dtors_aux_alias };
     451  #else /* defined(__FDPIC__) */
     452  static func_ptr __do_global_dtors_aux_fini_array_entry[]
     453    __attribute__ ((__used__, section(".fini_array"),
     454  		  aligned(__alignof__(func_ptr)))) = { __do_global_dtors_aux };
     455  #endif /* defined(__FDPIC__) */
     456  #else /* !FINI_SECTION_ASM_OP && !FINI_ARRAY_SECTION_ASM_OP */
     457  static void __attribute__((used))
     458  __do_global_dtors_aux_1 (void)
     459  {
     460    atexit (__do_global_dtors_aux);
     461  }
     462  CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__,
     463  			  __do_global_dtors_aux_1)
     464  #endif
     465  #endif /* defined(CRTSTUFFS_O) || !defined(FINI_ARRAY_SECTION_ASM_OP)
     466    || USE_TM_CLONE_REGISTRY || defined(USE_EH_FRAME_REGISTRY) */
     467  
     468  #if defined(USE_EH_FRAME_REGISTRY) || USE_TM_CLONE_REGISTRY
     469  /* Stick a call to __register_frame_info into the .init section.  For some
     470     reason calls with no arguments work more reliably in .init, so stick the
     471     call in another function.  */
     472  
     473  static void __attribute__((used))
     474  frame_dummy (void)
     475  {
     476  #ifdef USE_EH_FRAME_REGISTRY
     477    static struct object object;
     478  #ifdef CRT_GET_RFIB_DATA
     479    void *tbase, *dbase;
     480    tbase = 0;
     481    CRT_GET_RFIB_DATA (dbase);
     482    if (__register_frame_info_bases)
     483      __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
     484  #else
     485    if (__register_frame_info)
     486      __register_frame_info (__EH_FRAME_BEGIN__, &object);
     487  #endif /* CRT_GET_RFIB_DATA */
     488  #endif /* USE_EH_FRAME_REGISTRY */
     489  
     490  #if USE_TM_CLONE_REGISTRY
     491    register_tm_clones ();
     492  #endif /* USE_TM_CLONE_REGISTRY */
     493  }
     494  
     495  #ifdef __LIBGCC_INIT_SECTION_ASM_OP__
     496  CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, frame_dummy)
     497  #else /* defined(__LIBGCC_INIT_SECTION_ASM_OP__) */
     498  #if defined(__FDPIC__)
     499  __asm__("\t.equ\t__frame_dummy_alias, frame_dummy\n");
     500  extern char __frame_dummy_alias;
     501  static void *__frame_dummy_init_array_entry[]
     502  __attribute__ ((__used__, section(".init_array"), aligned(sizeof(void *))))
     503       = { &__frame_dummy_alias };
     504  #else /* defined(__FDPIC__) */
     505  static func_ptr __frame_dummy_init_array_entry[]
     506    __attribute__ ((__used__, section(".init_array"),
     507  		  aligned(__alignof__(func_ptr)))) = { frame_dummy };
     508  #endif /* defined(__FDPIC__) */
     509  #endif /* !defined(__LIBGCC_INIT_SECTION_ASM_OP__) */
     510  #endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */
     511  
     512  #else  /* OBJECT_FORMAT_ELF */
     513  
     514  /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
     515     and once in crtend.o).  It must be declared static to avoid a link
     516     error.  Here, we define __do_global_ctors as an externally callable
     517     function.  It is externally callable so that __main can invoke it when
     518     INVOKE__main is defined.  This has the additional effect of forcing cc1
     519     to switch to the .text section.  */
     520  
     521  static void __do_global_ctors_aux (void);
     522  void
     523  __do_global_ctors (void)
     524  {
     525  #ifdef INVOKE__main
     526    /* If __main won't actually call __do_global_ctors then it doesn't matter
     527       what's inside the function.  The inside of __do_global_ctors_aux is
     528       called automatically in that case.  And the Alliant fx2800 linker
     529       crashes on this reference.  So prevent the crash.  */
     530    __do_global_ctors_aux ();
     531  #endif
     532  }
     533  
     534  asm (__LIBGCC_INIT_SECTION_ASM_OP__);	/* cc1 doesn't know that we are switching! */
     535  
     536  /* A routine to invoke all of the global constructors upon entry to the
     537     program.  We put this into the .init section (for systems that have
     538     such a thing) so that we can properly perform the construction of
     539     file-scope static-storage C++ objects within shared libraries.  */
     540  
     541  static void __attribute__((used))
     542  __do_global_ctors_aux (void)	/* prologue goes in .init section */
     543  {
     544    FORCE_CODE_SECTION_ALIGN	/* explicit align before switch to .text */
     545    asm (__LIBGCC_TEXT_SECTION_ASM_OP__);	/* don't put epilogue and body in .init */
     546    DO_GLOBAL_CTORS_BODY;
     547    atexit (__do_global_dtors);
     548  }
     549  
     550  #endif /* OBJECT_FORMAT_ELF */
     551  
     552  #elif defined(HAS_INIT_SECTION) /* ! __LIBGCC_INIT_SECTION_ASM_OP__ */
     553  
     554  extern void __do_global_dtors (void);
     555  
     556  /* This case is used by the Irix 6 port, which supports named sections but
     557     not an SVR4-style .fini section.  __do_global_dtors can be non-static
     558     in this case because we protect it with -hidden_symbol.  */
     559  
     560  void
     561  __do_global_dtors (void)
     562  {
     563    func_ptr *p, f;
     564    for (p = __DTOR_LIST__ + 1; (f = *p); p++)
     565      f ();
     566  
     567  #if USE_TM_CLONE_REGISTRY
     568    deregister_tm_clones ();
     569  #endif /* USE_TM_CLONE_REGISTRY */
     570  
     571  #ifdef USE_EH_FRAME_REGISTRY
     572    if (__deregister_frame_info)
     573      __deregister_frame_info (__EH_FRAME_BEGIN__);
     574  #endif
     575  }
     576  
     577  #if defined(USE_EH_FRAME_REGISTRY) || USE_TM_CLONE_REGISTRY
     578  /* A helper function for __do_global_ctors, which is in crtend.o.  Here
     579     in crtbegin.o, we can reference a couple of symbols not visible there.
     580     Plus, since we're before libgcc.a, we have no problems referencing
     581     functions from there.  */
     582  void
     583  __do_global_ctors_1(void)
     584  {
     585  #ifdef USE_EH_FRAME_REGISTRY
     586    static struct object object;
     587    if (__register_frame_info)
     588      __register_frame_info (__EH_FRAME_BEGIN__, &object);
     589  #endif
     590  
     591  #if USE_TM_CLONE_REGISTRY
     592    register_tm_clones ();
     593  #endif /* USE_TM_CLONE_REGISTRY */
     594  }
     595  #endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */
     596  
     597  #else /* ! __LIBGCC_INIT_SECTION_ASM_OP__ && ! HAS_INIT_SECTION */
     598  #error "What are you doing with crtstuff.c, then?"
     599  #endif
     600  
     601  #elif defined(CRT_END) /* ! CRT_BEGIN */
     602  
     603  /* No need for .ctors/.dtors section if linker can place them in
     604     .init_array/.fini_array section.  */
     605  #ifndef USE_INITFINI_ARRAY
     606  /* Put a word containing zero at the end of each of our two lists of function
     607     addresses.  Note that the words defined here go into the .ctors and .dtors
     608     sections of the crtend.o file, and since that file is always linked in
     609     last, these words naturally end up at the very ends of the two lists
     610     contained in these two sections.  */
     611  
     612  #ifdef CTOR_LIST_END
     613  CTOR_LIST_END;
     614  #elif defined(__LIBGCC_CTORS_SECTION_ASM_OP__)
     615  /* Hack: force cc1 to switch to .data section early, so that assembling
     616     __CTOR_LIST__ does not undo our behind-the-back change to .ctors.  */
     617  static func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
     618  asm (__LIBGCC_CTORS_SECTION_ASM_OP__);
     619  STATIC func_ptr __CTOR_END__[1]
     620    __attribute__((aligned(__alignof__(func_ptr))))
     621    = { (func_ptr) 0 };
     622  #else
     623  STATIC func_ptr __CTOR_END__[1]
     624    __attribute__((section(".ctors"), aligned(__alignof__(func_ptr))))
     625    = { (func_ptr) 0 };
     626  #endif
     627  
     628  #ifdef DTOR_LIST_END
     629  DTOR_LIST_END;
     630  #elif defined(HIDDEN_DTOR_LIST_END)
     631  #ifdef __LIBGCC_DTORS_SECTION_ASM_OP__
     632  asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
     633  #endif
     634  func_ptr __DTOR_END__[1]
     635    __attribute__ ((used,
     636  #ifndef __LIBGCC_DTORS_SECTION_ASM_OP__
     637  		  section(".dtors"),
     638  #endif
     639  		  aligned(__alignof__(func_ptr)), visibility ("hidden")))
     640    = { (func_ptr) 0 };
     641  #elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__)
     642  asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
     643  STATIC func_ptr __DTOR_END__[1]
     644    __attribute__ ((used, aligned(__alignof__(func_ptr))))
     645    = { (func_ptr) 0 };
     646  #else
     647  STATIC func_ptr __DTOR_END__[1]
     648    __attribute__((used, section(".dtors"), aligned(__alignof__(func_ptr))))
     649    = { (func_ptr) 0 };
     650  #endif
     651  #endif /* USE_INITFINI_ARRAY */
     652  
     653  #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
     654  /* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
     655     this would be the 'length' field in a real FDE.  */
     656  # if __INT_MAX__ == 2147483647
     657  typedef int int32;
     658  # elif __LONG_MAX__ == 2147483647
     659  typedef long int32;
     660  # elif __SHRT_MAX__ == 2147483647
     661  typedef short int32;
     662  # else
     663  #  error "Missing a 4 byte integer"
     664  # endif
     665  STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[]
     666       __attribute__ ((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__),
     667  		     aligned(__alignof__(int32))))
     668       = { 0 };
     669  #endif /* __LIBGCC_EH_FRAME_SECTION_NAME__ */
     670  
     671  #if USE_TM_CLONE_REGISTRY
     672  # ifndef HAVE_GAS_HIDDEN
     673  static
     674  # endif
     675  func_ptr __TMC_END__[]
     676    __attribute__((used, section(".tm_clone_table"),
     677  		 aligned(__alignof__(void *))))
     678  # ifdef HAVE_GAS_HIDDEN
     679    __attribute__((__visibility__ ("hidden"))) = { };
     680  # else
     681    = { 0, 0 };
     682  # endif
     683  #endif /* USE_TM_CLONE_REGISTRY */
     684  
     685  #ifdef __LIBGCC_INIT_ARRAY_SECTION_ASM_OP__
     686  
     687  /* If we are using .init_array, there is nothing to do.  */
     688  
     689  #elif defined(__LIBGCC_INIT_SECTION_ASM_OP__)
     690  
     691  #ifdef OBJECT_FORMAT_ELF
     692  static void __attribute__((used))
     693  __do_global_ctors_aux (void)
     694  {
     695    func_ptr *p;
     696    for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
     697      (*p) ();
     698  }
     699  
     700  /* Stick a call to __do_global_ctors_aux into the .init section.  */
     701  CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, __do_global_ctors_aux)
     702  #else  /* OBJECT_FORMAT_ELF */
     703  
     704  /* Stick the real initialization code, followed by a normal sort of
     705     function epilogue at the very end of the .init section for this
     706     entire root executable file or for this entire shared library file.
     707  
     708     Note that we use some tricks here to get *just* the body and just
     709     a function epilogue (but no function prologue) into the .init
     710     section of the crtend.o file.  Specifically, we switch to the .text
     711     section, start to define a function, and then we switch to the .init
     712     section just before the body code.
     713  
     714     Earlier on, we put the corresponding function prologue into the .init
     715     section of the crtbegin.o file (which will be linked in first).
     716  
     717     Note that we want to invoke all constructors for C++ file-scope static-
     718     storage objects AFTER any other possible initialization actions which
     719     may be performed by the code in the .init section contributions made by
     720     other libraries, etc.  That's because those other initializations may
     721     include setup operations for very primitive things (e.g. initializing
     722     the state of the floating-point coprocessor, etc.) which should be done
     723     before we start to execute any of the user's code.  */
     724  
     725  static void
     726  __do_global_ctors_aux (void)	/* prologue goes in .text section */
     727  {
     728    asm (__LIBGCC_INIT_SECTION_ASM_OP__);
     729    DO_GLOBAL_CTORS_BODY;
     730    atexit (__do_global_dtors);
     731  }				/* epilogue and body go in .init section */
     732  
     733  FORCE_CODE_SECTION_ALIGN
     734  asm (__LIBGCC_TEXT_SECTION_ASM_OP__);
     735  
     736  #endif /* OBJECT_FORMAT_ELF */
     737  
     738  #elif defined(HAS_INIT_SECTION) /* ! __LIBGCC_INIT_SECTION_ASM_OP__ */
     739  
     740  extern void __do_global_ctors (void);
     741  
     742  /* This case is used by the Irix 6 port, which supports named sections but
     743     not an SVR4-style .init section.  __do_global_ctors can be non-static
     744     in this case because we protect it with -hidden_symbol.  */
     745  void
     746  __do_global_ctors (void)
     747  {
     748    func_ptr *p;
     749  #if defined(USE_EH_FRAME_REGISTRY) || USE_TM_CLONE_REGISTRY
     750    __do_global_ctors_1();
     751  #endif
     752    for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
     753      (*p) ();
     754  }
     755  
     756  #else /* ! __LIBGCC_INIT_SECTION_ASM_OP__ && ! HAS_INIT_SECTION */
     757  #error "What are you doing with crtstuff.c, then?"
     758  #endif
     759  
     760  #else /* ! CRT_BEGIN && ! CRT_END */
     761  #error "One of CRT_BEGIN or CRT_END must be defined."
     762  #endif