OSDN Git Service

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