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