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