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