OSDN Git Service

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