Home | History | Annotate | Line # | Download | only in libgcc
crtstuff.c revision 1.1.1.9
      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.9  mrg    Copyright (C) 1991-2020 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.2  mrg      __attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4)))
    265      1.1  mrg      = { };
    266      1.1  mrg #endif /* USE_EH_FRAME_REGISTRY */
    267      1.1  mrg 
    268      1.1  mrg #if USE_TM_CLONE_REGISTRY
    269      1.1  mrg STATIC func_ptr __TMC_LIST__[]
    270  1.1.1.9  mrg   __attribute__((used, section(".tm_clone_table"), aligned(__alignof__(void*))))
    271      1.1  mrg   = { };
    272      1.1  mrg # ifdef HAVE_GAS_HIDDEN
    273      1.1  mrg extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden")));
    274      1.1  mrg # endif
    275      1.1  mrg 
    276      1.1  mrg static inline void
    277      1.1  mrg deregister_tm_clones (void)
    278      1.1  mrg {
    279      1.1  mrg   void (*fn) (void *);
    280      1.1  mrg 
    281      1.1  mrg #ifdef HAVE_GAS_HIDDEN
    282  1.1.1.4  mrg   func_ptr *end = __TMC_END__;
    283  1.1.1.4  mrg   // Do not optimize the comparison to false.
    284  1.1.1.4  mrg   __asm ("" : "+g" (end));
    285  1.1.1.4  mrg   if (__TMC_LIST__ == end)
    286      1.1  mrg     return;
    287      1.1  mrg #else
    288      1.1  mrg   if (__TMC_LIST__[0] == NULL)
    289      1.1  mrg     return;
    290      1.1  mrg #endif
    291      1.1  mrg 
    292      1.1  mrg   fn = _ITM_deregisterTMCloneTable;
    293      1.1  mrg   __asm ("" : "+r" (fn));
    294      1.1  mrg   if (fn)
    295      1.1  mrg     fn (__TMC_LIST__);
    296      1.1  mrg }
    297      1.1  mrg 
    298      1.1  mrg static inline void
    299      1.1  mrg register_tm_clones (void)
    300      1.1  mrg {
    301      1.1  mrg   void (*fn) (void *, size_t);
    302      1.1  mrg   size_t size;
    303      1.1  mrg 
    304      1.1  mrg #ifdef HAVE_GAS_HIDDEN
    305  1.1.1.4  mrg   func_ptr *end = __TMC_END__;
    306  1.1.1.4  mrg   // Do not optimize the comparison to false.
    307  1.1.1.4  mrg   __asm ("" : "+g" (end));
    308  1.1.1.4  mrg   size = (end - __TMC_LIST__) / 2;
    309      1.1  mrg #else
    310      1.1  mrg   for (size = 0; __TMC_LIST__[size * 2] != NULL; size++)
    311      1.1  mrg     continue;
    312      1.1  mrg #endif
    313      1.1  mrg   if (size == 0)
    314      1.1  mrg     return;
    315      1.1  mrg 
    316      1.1  mrg   fn = _ITM_registerTMCloneTable;
    317      1.1  mrg   __asm ("" : "+r" (fn));
    318      1.1  mrg   if (fn)
    319      1.1  mrg     fn (__TMC_LIST__, size);
    320      1.1  mrg }
    321      1.1  mrg #endif /* USE_TM_CLONE_REGISTRY */
    322      1.1  mrg 
    323  1.1.1.2  mrg #if defined(__LIBGCC_INIT_SECTION_ASM_OP__) \
    324  1.1.1.2  mrg     || defined(__LIBGCC_INIT_ARRAY_SECTION_ASM_OP__)
    325      1.1  mrg 
    326      1.1  mrg #ifdef OBJECT_FORMAT_ELF
    327      1.1  mrg 
    328  1.1.1.9  mrg #if DEFAULT_USE_CXA_ATEXIT
    329      1.1  mrg /* Declare the __dso_handle variable.  It should have a unique value
    330      1.1  mrg    in every shared-object; in a main program its value is zero.  The
    331      1.1  mrg    object should in any case be protected.  This means the instance
    332      1.1  mrg    in one DSO or the main program is not used in another object.  The
    333  1.1.1.9  mrg    dynamic linker takes care of this.
    334  1.1.1.9  mrg    If __cxa_atexit is not being used, __dso_handle will not be used and
    335  1.1.1.9  mrg    doesn't need to be defined.  */
    336      1.1  mrg 
    337      1.1  mrg #ifdef TARGET_LIBGCC_SDATA_SECTION
    338      1.1  mrg extern void *__dso_handle __attribute__ ((__section__ (TARGET_LIBGCC_SDATA_SECTION)));
    339      1.1  mrg #endif
    340      1.1  mrg #ifdef HAVE_GAS_HIDDEN
    341      1.1  mrg extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
    342      1.1  mrg #endif
    343      1.1  mrg #ifdef CRTSTUFFS_O
    344      1.1  mrg void *__dso_handle = &__dso_handle;
    345      1.1  mrg #else
    346      1.1  mrg void *__dso_handle = 0;
    347      1.1  mrg #endif
    348  1.1.1.9  mrg #endif /* DEFAULT_USE_CXA_ATEXIT */
    349      1.1  mrg 
    350      1.1  mrg /* The __cxa_finalize function may not be available so we use only a
    351      1.1  mrg    weak declaration.  */
    352      1.1  mrg extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
    353      1.1  mrg 
    354      1.1  mrg /* Run all the global destructors on exit from the program.  */
    355      1.1  mrg 
    356      1.1  mrg /* Some systems place the number of pointers in the first word of the
    357      1.1  mrg    table.  On SVR4 however, that word is -1.  In all cases, the table is
    358      1.1  mrg    null-terminated.  On SVR4, we start from the beginning of the list and
    359      1.1  mrg    invoke each per-compilation-unit destructor routine in order
    360      1.1  mrg    until we find that null.
    361      1.1  mrg 
    362      1.1  mrg    Note that this function MUST be static.  There will be one of these
    363      1.1  mrg    functions in each root executable and one in each shared library, but
    364      1.1  mrg    although they all have the same code, each one is unique in that it
    365      1.1  mrg    refers to one particular associated `__DTOR_LIST__' which belongs to the
    366      1.1  mrg    same particular root executable or shared library file.
    367      1.1  mrg 
    368      1.1  mrg    On some systems, this routine is run more than once from the .fini,
    369      1.1  mrg    when exit is called recursively, so we arrange to remember where in
    370      1.1  mrg    the list we left off processing, and we resume at that point,
    371  1.1.1.9  mrg    should we be re-invoked.
    372      1.1  mrg 
    373  1.1.1.9  mrg    This routine does not need to be run if none of the following clauses are
    374  1.1.1.9  mrg    true, as it will not do anything, so can be removed.  */
    375  1.1.1.9  mrg #if defined(CRTSTUFFS_O) || !defined(FINI_ARRAY_SECTION_ASM_OP) \
    376  1.1.1.9  mrg   || USE_TM_CLONE_REGISTRY || defined(USE_EH_FRAME_REGISTRY)
    377      1.1  mrg static void __attribute__((used))
    378      1.1  mrg __do_global_dtors_aux (void)
    379      1.1  mrg {
    380      1.1  mrg   static _Bool completed;
    381      1.1  mrg 
    382      1.1  mrg   if (__builtin_expect (completed, 0))
    383      1.1  mrg     return;
    384      1.1  mrg 
    385  1.1.1.9  mrg #if DEFAULT_USE_CXA_ATEXIT
    386      1.1  mrg #ifdef CRTSTUFFS_O
    387      1.1  mrg   if (__cxa_finalize)
    388      1.1  mrg     __cxa_finalize (__dso_handle);
    389      1.1  mrg #endif
    390  1.1.1.9  mrg #endif
    391      1.1  mrg 
    392      1.1  mrg #ifdef FINI_ARRAY_SECTION_ASM_OP
    393      1.1  mrg   /* If we are using .fini_array then destructors will be run via that
    394      1.1  mrg      mechanism.  */
    395      1.1  mrg #elif defined(HIDDEN_DTOR_LIST_END)
    396      1.1  mrg   {
    397      1.1  mrg     /* Safer version that makes sure only .dtors function pointers are
    398      1.1  mrg        called even if the static variable is maliciously changed.  */
    399      1.1  mrg     extern func_ptr __DTOR_END__[] __attribute__((visibility ("hidden")));
    400      1.1  mrg     static size_t dtor_idx;
    401      1.1  mrg     const size_t max_idx = __DTOR_END__ - __DTOR_LIST__ - 1;
    402  1.1.1.2  mrg     func_ptr *dtor_list;
    403      1.1  mrg 
    404  1.1.1.2  mrg     __asm ("" : "=g" (dtor_list) : "0" (__DTOR_LIST__));
    405      1.1  mrg     while (dtor_idx < max_idx)
    406  1.1.1.2  mrg       dtor_list[++dtor_idx] ();
    407      1.1  mrg   }
    408      1.1  mrg #else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
    409      1.1  mrg   {
    410      1.1  mrg     static func_ptr *p = __DTOR_LIST__ + 1;
    411      1.1  mrg     func_ptr f;
    412      1.1  mrg 
    413      1.1  mrg     while ((f = *p))
    414      1.1  mrg       {
    415      1.1  mrg 	p++;
    416      1.1  mrg 	f ();
    417      1.1  mrg       }
    418      1.1  mrg   }
    419      1.1  mrg #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
    420      1.1  mrg 
    421      1.1  mrg #if USE_TM_CLONE_REGISTRY
    422      1.1  mrg   deregister_tm_clones ();
    423      1.1  mrg #endif /* USE_TM_CLONE_REGISTRY */
    424      1.1  mrg 
    425      1.1  mrg #ifdef USE_EH_FRAME_REGISTRY
    426      1.1  mrg #ifdef CRT_GET_RFIB_DATA
    427      1.1  mrg   /* If we used the new __register_frame_info_bases interface,
    428      1.1  mrg      make sure that we deregister from the same place.  */
    429      1.1  mrg   if (__deregister_frame_info_bases)
    430      1.1  mrg     __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
    431      1.1  mrg #else
    432      1.1  mrg   if (__deregister_frame_info)
    433      1.1  mrg     __deregister_frame_info (__EH_FRAME_BEGIN__);
    434      1.1  mrg #endif
    435      1.1  mrg #endif
    436      1.1  mrg 
    437      1.1  mrg   completed = 1;
    438      1.1  mrg }
    439      1.1  mrg 
    440      1.1  mrg /* Stick a call to __do_global_dtors_aux into the .fini section.  */
    441      1.1  mrg #ifdef FINI_SECTION_ASM_OP
    442      1.1  mrg CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
    443      1.1  mrg #elif defined (FINI_ARRAY_SECTION_ASM_OP)
    444  1.1.1.9  mrg #if defined(__FDPIC__)
    445  1.1.1.9  mrg __asm__("\t.equ\t__do_global_dtors_aux_alias, __do_global_dtors_aux\n");
    446  1.1.1.9  mrg extern char __do_global_dtors_aux_alias;
    447  1.1.1.9  mrg static void *__do_global_dtors_aux_fini_array_entry[]
    448  1.1.1.9  mrg __attribute__ ((__used__, section(".fini_array"), aligned(sizeof(void *))))
    449  1.1.1.9  mrg      = { &__do_global_dtors_aux_alias };
    450  1.1.1.9  mrg #else /* defined(__FDPIC__) */
    451      1.1  mrg static func_ptr __do_global_dtors_aux_fini_array_entry[]
    452  1.1.1.9  mrg   __attribute__ ((__used__, section(".fini_array"),
    453  1.1.1.9  mrg 		  aligned(__alignof__(func_ptr)))) = { __do_global_dtors_aux };
    454  1.1.1.9  mrg #endif /* defined(__FDPIC__) */
    455      1.1  mrg #else /* !FINI_SECTION_ASM_OP && !FINI_ARRAY_SECTION_ASM_OP */
    456      1.1  mrg static void __attribute__((used))
    457      1.1  mrg __do_global_dtors_aux_1 (void)
    458      1.1  mrg {
    459      1.1  mrg   atexit (__do_global_dtors_aux);
    460      1.1  mrg }
    461  1.1.1.2  mrg CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__,
    462  1.1.1.2  mrg 			  __do_global_dtors_aux_1)
    463      1.1  mrg #endif
    464  1.1.1.9  mrg #endif /* defined(CRTSTUFFS_O) || !defined(FINI_ARRAY_SECTION_ASM_OP)
    465  1.1.1.9  mrg   || USE_TM_CLONE_REGISTRY || defined(USE_EH_FRAME_REGISTRY) */
    466      1.1  mrg 
    467  1.1.1.9  mrg #if defined(USE_EH_FRAME_REGISTRY) || USE_TM_CLONE_REGISTRY
    468      1.1  mrg /* Stick a call to __register_frame_info into the .init section.  For some
    469      1.1  mrg    reason calls with no arguments work more reliably in .init, so stick the
    470      1.1  mrg    call in another function.  */
    471      1.1  mrg 
    472      1.1  mrg static void __attribute__((used))
    473      1.1  mrg frame_dummy (void)
    474      1.1  mrg {
    475      1.1  mrg #ifdef USE_EH_FRAME_REGISTRY
    476      1.1  mrg   static struct object object;
    477      1.1  mrg #ifdef CRT_GET_RFIB_DATA
    478      1.1  mrg   void *tbase, *dbase;
    479      1.1  mrg   tbase = 0;
    480      1.1  mrg   CRT_GET_RFIB_DATA (dbase);
    481      1.1  mrg   if (__register_frame_info_bases)
    482      1.1  mrg     __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
    483      1.1  mrg #else
    484      1.1  mrg   if (__register_frame_info)
    485      1.1  mrg     __register_frame_info (__EH_FRAME_BEGIN__, &object);
    486      1.1  mrg #endif /* CRT_GET_RFIB_DATA */
    487      1.1  mrg #endif /* USE_EH_FRAME_REGISTRY */
    488      1.1  mrg 
    489      1.1  mrg #if USE_TM_CLONE_REGISTRY
    490      1.1  mrg   register_tm_clones ();
    491      1.1  mrg #endif /* USE_TM_CLONE_REGISTRY */
    492      1.1  mrg }
    493      1.1  mrg 
    494  1.1.1.2  mrg #ifdef __LIBGCC_INIT_SECTION_ASM_OP__
    495  1.1.1.2  mrg CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, frame_dummy)
    496  1.1.1.2  mrg #else /* defined(__LIBGCC_INIT_SECTION_ASM_OP__) */
    497  1.1.1.9  mrg #if defined(__FDPIC__)
    498  1.1.1.9  mrg __asm__("\t.equ\t__frame_dummy_alias, frame_dummy\n");
    499  1.1.1.9  mrg extern char __frame_dummy_alias;
    500  1.1.1.9  mrg static void *__frame_dummy_init_array_entry[]
    501  1.1.1.9  mrg __attribute__ ((__used__, section(".init_array"), aligned(sizeof(void *))))
    502  1.1.1.9  mrg      = { &__frame_dummy_alias };
    503  1.1.1.9  mrg #else /* defined(__FDPIC__) */
    504      1.1  mrg static func_ptr __frame_dummy_init_array_entry[]
    505  1.1.1.9  mrg   __attribute__ ((__used__, section(".init_array"),
    506  1.1.1.9  mrg 		  aligned(__alignof__(func_ptr)))) = { frame_dummy };
    507  1.1.1.9  mrg #endif /* defined(__FDPIC__) */
    508  1.1.1.2  mrg #endif /* !defined(__LIBGCC_INIT_SECTION_ASM_OP__) */
    509  1.1.1.4  mrg #endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */
    510      1.1  mrg 
    511      1.1  mrg #else  /* OBJECT_FORMAT_ELF */
    512      1.1  mrg 
    513      1.1  mrg /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
    514      1.1  mrg    and once in crtend.o).  It must be declared static to avoid a link
    515      1.1  mrg    error.  Here, we define __do_global_ctors as an externally callable
    516      1.1  mrg    function.  It is externally callable so that __main can invoke it when
    517      1.1  mrg    INVOKE__main is defined.  This has the additional effect of forcing cc1
    518      1.1  mrg    to switch to the .text section.  */
    519      1.1  mrg 
    520      1.1  mrg static void __do_global_ctors_aux (void);
    521      1.1  mrg void
    522      1.1  mrg __do_global_ctors (void)
    523      1.1  mrg {
    524      1.1  mrg #ifdef INVOKE__main
    525      1.1  mrg   /* If __main won't actually call __do_global_ctors then it doesn't matter
    526      1.1  mrg      what's inside the function.  The inside of __do_global_ctors_aux is
    527      1.1  mrg      called automatically in that case.  And the Alliant fx2800 linker
    528      1.1  mrg      crashes on this reference.  So prevent the crash.  */
    529      1.1  mrg   __do_global_ctors_aux ();
    530      1.1  mrg #endif
    531      1.1  mrg }
    532      1.1  mrg 
    533  1.1.1.2  mrg asm (__LIBGCC_INIT_SECTION_ASM_OP__);	/* cc1 doesn't know that we are switching! */
    534      1.1  mrg 
    535      1.1  mrg /* A routine to invoke all of the global constructors upon entry to the
    536      1.1  mrg    program.  We put this into the .init section (for systems that have
    537      1.1  mrg    such a thing) so that we can properly perform the construction of
    538      1.1  mrg    file-scope static-storage C++ objects within shared libraries.  */
    539      1.1  mrg 
    540      1.1  mrg static void __attribute__((used))
    541      1.1  mrg __do_global_ctors_aux (void)	/* prologue goes in .init section */
    542      1.1  mrg {
    543      1.1  mrg   FORCE_CODE_SECTION_ALIGN	/* explicit align before switch to .text */
    544  1.1.1.2  mrg   asm (__LIBGCC_TEXT_SECTION_ASM_OP__);	/* don't put epilogue and body in .init */
    545      1.1  mrg   DO_GLOBAL_CTORS_BODY;
    546      1.1  mrg   atexit (__do_global_dtors);
    547      1.1  mrg }
    548      1.1  mrg 
    549      1.1  mrg #endif /* OBJECT_FORMAT_ELF */
    550      1.1  mrg 
    551  1.1.1.2  mrg #elif defined(HAS_INIT_SECTION) /* ! __LIBGCC_INIT_SECTION_ASM_OP__ */
    552      1.1  mrg 
    553      1.1  mrg extern void __do_global_dtors (void);
    554      1.1  mrg 
    555      1.1  mrg /* This case is used by the Irix 6 port, which supports named sections but
    556      1.1  mrg    not an SVR4-style .fini section.  __do_global_dtors can be non-static
    557      1.1  mrg    in this case because we protect it with -hidden_symbol.  */
    558      1.1  mrg 
    559      1.1  mrg void
    560      1.1  mrg __do_global_dtors (void)
    561      1.1  mrg {
    562      1.1  mrg   func_ptr *p, f;
    563      1.1  mrg   for (p = __DTOR_LIST__ + 1; (f = *p); p++)
    564      1.1  mrg     f ();
    565      1.1  mrg 
    566      1.1  mrg #if USE_TM_CLONE_REGISTRY
    567      1.1  mrg   deregister_tm_clones ();
    568      1.1  mrg #endif /* USE_TM_CLONE_REGISTRY */
    569      1.1  mrg 
    570      1.1  mrg #ifdef USE_EH_FRAME_REGISTRY
    571      1.1  mrg   if (__deregister_frame_info)
    572      1.1  mrg     __deregister_frame_info (__EH_FRAME_BEGIN__);
    573      1.1  mrg #endif
    574      1.1  mrg }
    575      1.1  mrg 
    576  1.1.1.9  mrg #if defined(USE_EH_FRAME_REGISTRY) || USE_TM_CLONE_REGISTRY
    577      1.1  mrg /* A helper function for __do_global_ctors, which is in crtend.o.  Here
    578      1.1  mrg    in crtbegin.o, we can reference a couple of symbols not visible there.
    579      1.1  mrg    Plus, since we're before libgcc.a, we have no problems referencing
    580      1.1  mrg    functions from there.  */
    581      1.1  mrg void
    582      1.1  mrg __do_global_ctors_1(void)
    583      1.1  mrg {
    584      1.1  mrg #ifdef USE_EH_FRAME_REGISTRY
    585      1.1  mrg   static struct object object;
    586      1.1  mrg   if (__register_frame_info)
    587      1.1  mrg     __register_frame_info (__EH_FRAME_BEGIN__, &object);
    588      1.1  mrg #endif
    589      1.1  mrg 
    590      1.1  mrg #if USE_TM_CLONE_REGISTRY
    591      1.1  mrg   register_tm_clones ();
    592      1.1  mrg #endif /* USE_TM_CLONE_REGISTRY */
    593      1.1  mrg }
    594  1.1.1.4  mrg #endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */
    595      1.1  mrg 
    596  1.1.1.2  mrg #else /* ! __LIBGCC_INIT_SECTION_ASM_OP__ && ! HAS_INIT_SECTION */
    597      1.1  mrg #error "What are you doing with crtstuff.c, then?"
    598      1.1  mrg #endif
    599      1.1  mrg 
    600      1.1  mrg #elif defined(CRT_END) /* ! CRT_BEGIN */
    601      1.1  mrg 
    602      1.1  mrg /* No need for .ctors/.dtors section if linker can place them in
    603      1.1  mrg    .init_array/.fini_array section.  */
    604      1.1  mrg #ifndef USE_INITFINI_ARRAY
    605      1.1  mrg /* Put a word containing zero at the end of each of our two lists of function
    606      1.1  mrg    addresses.  Note that the words defined here go into the .ctors and .dtors
    607      1.1  mrg    sections of the crtend.o file, and since that file is always linked in
    608      1.1  mrg    last, these words naturally end up at the very ends of the two lists
    609      1.1  mrg    contained in these two sections.  */
    610      1.1  mrg 
    611      1.1  mrg #ifdef CTOR_LIST_END
    612      1.1  mrg CTOR_LIST_END;
    613  1.1.1.2  mrg #elif defined(__LIBGCC_CTORS_SECTION_ASM_OP__)
    614      1.1  mrg /* Hack: force cc1 to switch to .data section early, so that assembling
    615      1.1  mrg    __CTOR_LIST__ does not undo our behind-the-back change to .ctors.  */
    616      1.1  mrg static func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
    617  1.1.1.2  mrg asm (__LIBGCC_CTORS_SECTION_ASM_OP__);
    618      1.1  mrg STATIC func_ptr __CTOR_END__[1]
    619  1.1.1.9  mrg   __attribute__((aligned(__alignof__(func_ptr))))
    620      1.1  mrg   = { (func_ptr) 0 };
    621      1.1  mrg #else
    622      1.1  mrg STATIC func_ptr __CTOR_END__[1]
    623  1.1.1.9  mrg   __attribute__((section(".ctors"), aligned(__alignof__(func_ptr))))
    624      1.1  mrg   = { (func_ptr) 0 };
    625      1.1  mrg #endif
    626      1.1  mrg 
    627      1.1  mrg #ifdef DTOR_LIST_END
    628      1.1  mrg DTOR_LIST_END;
    629      1.1  mrg #elif defined(HIDDEN_DTOR_LIST_END)
    630  1.1.1.2  mrg #ifdef __LIBGCC_DTORS_SECTION_ASM_OP__
    631  1.1.1.2  mrg asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
    632      1.1  mrg #endif
    633      1.1  mrg func_ptr __DTOR_END__[1]
    634      1.1  mrg   __attribute__ ((used,
    635  1.1.1.2  mrg #ifndef __LIBGCC_DTORS_SECTION_ASM_OP__
    636      1.1  mrg 		  section(".dtors"),
    637      1.1  mrg #endif
    638  1.1.1.9  mrg 		  aligned(__alignof__(func_ptr)), visibility ("hidden")))
    639      1.1  mrg   = { (func_ptr) 0 };
    640  1.1.1.2  mrg #elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__)
    641  1.1.1.2  mrg asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
    642      1.1  mrg STATIC func_ptr __DTOR_END__[1]
    643  1.1.1.9  mrg   __attribute__ ((used, aligned(__alignof__(func_ptr))))
    644      1.1  mrg   = { (func_ptr) 0 };
    645      1.1  mrg #else
    646      1.1  mrg STATIC func_ptr __DTOR_END__[1]
    647  1.1.1.9  mrg   __attribute__((used, section(".dtors"), aligned(__alignof__(func_ptr))))
    648      1.1  mrg   = { (func_ptr) 0 };
    649      1.1  mrg #endif
    650      1.1  mrg #endif /* USE_INITFINI_ARRAY */
    651      1.1  mrg 
    652  1.1.1.2  mrg #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
    653      1.1  mrg /* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
    654      1.1  mrg    this would be the 'length' field in a real FDE.  */
    655      1.1  mrg # if __INT_MAX__ == 2147483647
    656      1.1  mrg typedef int int32;
    657      1.1  mrg # elif __LONG_MAX__ == 2147483647
    658      1.1  mrg typedef long int32;
    659      1.1  mrg # elif __SHRT_MAX__ == 2147483647
    660      1.1  mrg typedef short int32;
    661      1.1  mrg # else
    662      1.1  mrg #  error "Missing a 4 byte integer"
    663      1.1  mrg # endif
    664      1.1  mrg STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[]
    665  1.1.1.2  mrg      __attribute__ ((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__),
    666  1.1.1.9  mrg 		     aligned(__alignof__(int32))))
    667      1.1  mrg      = { 0 };
    668  1.1.1.2  mrg #endif /* __LIBGCC_EH_FRAME_SECTION_NAME__ */
    669      1.1  mrg 
    670      1.1  mrg #if USE_TM_CLONE_REGISTRY
    671      1.1  mrg # ifndef HAVE_GAS_HIDDEN
    672      1.1  mrg static
    673      1.1  mrg # endif
    674      1.1  mrg func_ptr __TMC_END__[]
    675  1.1.1.9  mrg   __attribute__((used, section(".tm_clone_table"),
    676  1.1.1.9  mrg 		 aligned(__alignof__(void *))))
    677      1.1  mrg # ifdef HAVE_GAS_HIDDEN
    678      1.1  mrg   __attribute__((__visibility__ ("hidden"))) = { };
    679      1.1  mrg # else
    680      1.1  mrg   = { 0, 0 };
    681      1.1  mrg # endif
    682      1.1  mrg #endif /* USE_TM_CLONE_REGISTRY */
    683      1.1  mrg 
    684  1.1.1.2  mrg #ifdef __LIBGCC_INIT_ARRAY_SECTION_ASM_OP__
    685      1.1  mrg 
    686      1.1  mrg /* If we are using .init_array, there is nothing to do.  */
    687      1.1  mrg 
    688  1.1.1.2  mrg #elif defined(__LIBGCC_INIT_SECTION_ASM_OP__)
    689      1.1  mrg 
    690      1.1  mrg #ifdef OBJECT_FORMAT_ELF
    691      1.1  mrg static void __attribute__((used))
    692      1.1  mrg __do_global_ctors_aux (void)
    693      1.1  mrg {
    694      1.1  mrg   func_ptr *p;
    695      1.1  mrg   for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
    696      1.1  mrg     (*p) ();
    697      1.1  mrg }
    698      1.1  mrg 
    699      1.1  mrg /* Stick a call to __do_global_ctors_aux into the .init section.  */
    700  1.1.1.2  mrg CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, __do_global_ctors_aux)
    701      1.1  mrg #else  /* OBJECT_FORMAT_ELF */
    702      1.1  mrg 
    703      1.1  mrg /* Stick the real initialization code, followed by a normal sort of
    704      1.1  mrg    function epilogue at the very end of the .init section for this
    705      1.1  mrg    entire root executable file or for this entire shared library file.
    706      1.1  mrg 
    707      1.1  mrg    Note that we use some tricks here to get *just* the body and just
    708      1.1  mrg    a function epilogue (but no function prologue) into the .init
    709      1.1  mrg    section of the crtend.o file.  Specifically, we switch to the .text
    710      1.1  mrg    section, start to define a function, and then we switch to the .init
    711      1.1  mrg    section just before the body code.
    712      1.1  mrg 
    713      1.1  mrg    Earlier on, we put the corresponding function prologue into the .init
    714      1.1  mrg    section of the crtbegin.o file (which will be linked in first).
    715      1.1  mrg 
    716      1.1  mrg    Note that we want to invoke all constructors for C++ file-scope static-
    717      1.1  mrg    storage objects AFTER any other possible initialization actions which
    718      1.1  mrg    may be performed by the code in the .init section contributions made by
    719      1.1  mrg    other libraries, etc.  That's because those other initializations may
    720      1.1  mrg    include setup operations for very primitive things (e.g. initializing
    721      1.1  mrg    the state of the floating-point coprocessor, etc.) which should be done
    722      1.1  mrg    before we start to execute any of the user's code.  */
    723      1.1  mrg 
    724      1.1  mrg static void
    725      1.1  mrg __do_global_ctors_aux (void)	/* prologue goes in .text section */
    726      1.1  mrg {
    727  1.1.1.2  mrg   asm (__LIBGCC_INIT_SECTION_ASM_OP__);
    728      1.1  mrg   DO_GLOBAL_CTORS_BODY;
    729      1.1  mrg   atexit (__do_global_dtors);
    730      1.1  mrg }				/* epilogue and body go in .init section */
    731      1.1  mrg 
    732      1.1  mrg FORCE_CODE_SECTION_ALIGN
    733  1.1.1.2  mrg asm (__LIBGCC_TEXT_SECTION_ASM_OP__);
    734      1.1  mrg 
    735      1.1  mrg #endif /* OBJECT_FORMAT_ELF */
    736      1.1  mrg 
    737  1.1.1.2  mrg #elif defined(HAS_INIT_SECTION) /* ! __LIBGCC_INIT_SECTION_ASM_OP__ */
    738      1.1  mrg 
    739      1.1  mrg extern void __do_global_ctors (void);
    740      1.1  mrg 
    741      1.1  mrg /* This case is used by the Irix 6 port, which supports named sections but
    742      1.1  mrg    not an SVR4-style .init section.  __do_global_ctors can be non-static
    743      1.1  mrg    in this case because we protect it with -hidden_symbol.  */
    744      1.1  mrg void
    745      1.1  mrg __do_global_ctors (void)
    746      1.1  mrg {
    747      1.1  mrg   func_ptr *p;
    748  1.1.1.9  mrg #if defined(USE_EH_FRAME_REGISTRY) || USE_TM_CLONE_REGISTRY
    749      1.1  mrg   __do_global_ctors_1();
    750      1.1  mrg #endif
    751      1.1  mrg   for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
    752      1.1  mrg     (*p) ();
    753      1.1  mrg }
    754      1.1  mrg 
    755  1.1.1.2  mrg #else /* ! __LIBGCC_INIT_SECTION_ASM_OP__ && ! HAS_INIT_SECTION */
    756      1.1  mrg #error "What are you doing with crtstuff.c, then?"
    757      1.1  mrg #endif
    758      1.1  mrg 
    759      1.1  mrg #else /* ! CRT_BEGIN && ! CRT_END */
    760      1.1  mrg #error "One of CRT_BEGIN or CRT_END must be defined."
    761      1.1  mrg #endif
    762