]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/crtstuff.c
2009-04-09 Richard Guenther <rguenther@suse.de>
[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.
f2397fc4 3 Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
4 2002, 2003, 2004, 2005, 2006, 2007, 2009 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
67ce556b 30Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
3102110-1301, 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
fece7655 54/* Target machine header files require this define. */
55#define IN_LIBGCC2
56
dd41a27b 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"
9ed5ef25 61#undef pid_t
62#undef rlim_t
63#undef ssize_t
9ed5ef25 64#undef vfork
d826737c 65#include "tconfig.h"
069631e1 66#include "tsystem.h"
805e22b2 67#include "coretypes.h"
68#include "tm.h"
df4b504c 69#include "unwind-dw2-fde.h"
9d13f5c4 70
e1ff7102 71#ifndef FORCE_CODE_SECTION_ALIGN
72# define FORCE_CODE_SECTION_ALIGN
73#endif
74
a815e00c 75#ifndef CRT_CALL_STATIC_FUNCTION
e1ff7102 76# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
77static void __attribute__((__used__)) \
78call_ ## FUNC (void) \
79{ \
80 asm (SECTION_OP); \
81 FUNC (); \
82 FORCE_CODE_SECTION_ALIGN \
83 asm (TEXT_SECTION_ASM_OP); \
84}
a815e00c 85#endif
86
f8200b2a 87#if defined(OBJECT_FORMAT_ELF) \
88 && !defined(OBJECT_FORMAT_FLAT) \
89 && defined(HAVE_LD_EH_FRAME_HDR) \
3cfa3aba 90 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
0d6378a9 91 && defined(__GLIBC__) && __GLIBC__ >= 2
92#include <link.h>
b0c091c8 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) \
0d6378a9 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
51601538 104#if defined(EH_FRAME_SECTION_NAME) && EH_TABLES_CAN_BE_READ_ONLY
d5720b0c 105# define EH_FRAME_SECTION_CONST const
106#else
107# define EH_FRAME_SECTION_CONST
108#endif
0d6378a9 109
f9e6c0d4 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
ee055d40 115/* We do not want to add the weak attribute to the declarations of these
df4b504c 116 routines in unwind-dw2-fde.h because that will cause the definition of
117 these symbols to be weak as well.
ee055d40 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
0c6d8c36 126 one thinks about scaling to larger problems -- i.e., the condition under
ee055d40 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. */
49856054 137extern void __register_frame_info (const void *, struct object *)
ee055d40 138 TARGET_ATTRIBUTE_WEAK;
49856054 139extern void __register_frame_info_bases (const void *, struct object *,
f6338f42 140 void *, void *)
141 TARGET_ATTRIBUTE_WEAK;
49856054 142extern void *__deregister_frame_info (const void *)
ee055d40 143 TARGET_ATTRIBUTE_WEAK;
49856054 144extern void *__deregister_frame_info_bases (const void *)
ce32d35f 145 TARGET_ATTRIBUTE_WEAK;
db0f4f32 146extern void __do_global_ctors_1 (void);
ee055d40 147
f313c0e1 148/* Likewise for _Jv_RegisterClasses. */
149extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
150
b7c87ff2 151#ifdef OBJECT_FORMAT_ELF
152
153/* Declare a pointer to void function type. */
154typedef void (*func_ptr) (void);
155#define STATIC static
156
157#else /* OBJECT_FORMAT_ELF */
158
9d13f5c4 159#include "gbl-ctors.h"
160
b7c87ff2 161#define STATIC
162
163#endif /* OBJECT_FORMAT_ELF */
9d13f5c4 164
165#ifdef CRT_BEGIN
166
f313c0e1 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
182CTOR_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. */
186static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
187asm (CTORS_SECTION_ASM_OP);
188STATIC func_ptr __CTOR_LIST__[1]
189 __attribute__ ((__unused__, aligned(sizeof(func_ptr))))
190 = { (func_ptr) (-1) };
191#else
192STATIC 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
198DTOR_LIST_BEGIN;
199#elif defined(DTORS_SECTION_ASM_OP)
200asm (DTORS_SECTION_ASM_OP);
201STATIC func_ptr __DTOR_LIST__[1]
202 __attribute__ ((aligned(sizeof(func_ptr))))
203 = { (func_ptr) (-1) };
204#else
205STATIC func_ptr __DTOR_LIST__[1]
206 __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
207 = { (func_ptr) (-1) };
208#endif /* __DTOR_LIST__ alternatives */
209
fabbeb08 210#ifdef USE_EH_FRAME_REGISTRY
f313c0e1 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. */
d5720b0c 213STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
f313c0e1 214 __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
215 = { };
fabbeb08 216#endif /* USE_EH_FRAME_REGISTRY */
f313c0e1 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. */
f313c0e1 221STATIC void *__JCR_LIST__[]
222 __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
223 = { };
224#endif /* JCR_SECTION_NAME */
225
d24bc145 226#if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
584907e7 227
b7c87ff2 228#ifdef OBJECT_FORMAT_ELF
229
39b6af4b 230/* Declare the __dso_handle variable. It should have a unique value
5be729c9 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
91e8ab5c 236#ifdef TARGET_LIBGCC_SDATA_SECTION
237extern void *__dso_handle __attribute__ ((__section__ (TARGET_LIBGCC_SDATA_SECTION)));
238#endif
5be729c9 239#ifdef HAVE_GAS_HIDDEN
b4cf9ec1 240extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
5be729c9 241#endif
39b6af4b 242#ifdef CRTSTUFFS_O
243void *__dso_handle = &__dso_handle;
244#else
245void *__dso_handle = 0;
246#endif
247
248/* The __cxa_finalize function may not be available so we use only a
249 weak declaration. */
250extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
251
b7c87ff2 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
113f9ca7 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. */
b7c87ff2 270
e1ff7102 271static void __attribute__((used))
aedb00bf 272__do_global_dtors_aux (void)
b7c87ff2 273{
d24bc145 274 static _Bool completed;
dade0711 275
f6338f42 276 if (__builtin_expect (completed, 0))
dade0711 277 return;
278
f4513b3d 279#ifdef CRTSTUFFS_O
280 if (__cxa_finalize)
39b6af4b 281 __cxa_finalize (__dso_handle);
f4513b3d 282#endif
39b6af4b 283
d24bc145 284#ifdef FINI_ARRAY_SECTION_ASM_OP
285 /* If we are using .fini_array then destructors will be run via that
286 mechanism. */
f9e6c0d4 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 }
d24bc145 302#else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
f9e6c0d4 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 }
d24bc145 313#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
d757b8c9 314
0d6378a9 315#ifdef USE_EH_FRAME_REGISTRY
6fa2a5a8 316#ifdef CRT_GET_RFIB_DATA
ce32d35f 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
ee055d40 322 if (__deregister_frame_info)
323 __deregister_frame_info (__EH_FRAME_BEGIN__);
d757b8c9 324#endif
ce32d35f 325#endif
326
dade0711 327 completed = 1;
b7c87ff2 328}
329
330/* Stick a call to __do_global_dtors_aux into the .fini section. */
d24bc145 331#ifdef FINI_SECTION_ASM_OP
e1ff7102 332CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
d24bc145 333#else /* !defined(FINI_SECTION_ASM_OP) */
334static 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) */
b7c87ff2 338
0d6378a9 339#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
c4fa4c4d 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. */
d757b8c9 343
e1ff7102 344static void __attribute__((used))
aedb00bf 345frame_dummy (void)
d757b8c9 346{
0d6378a9 347#ifdef USE_EH_FRAME_REGISTRY
ad87de1e 348 static struct object object;
6fa2a5a8 349#ifdef CRT_GET_RFIB_DATA
f6338f42 350 void *tbase, *dbase;
f6338f42 351 tbase = 0;
f6338f42 352 CRT_GET_RFIB_DATA (dbase);
f6338f42 353 if (__register_frame_info_bases)
354 __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
355#else
ee055d40 356 if (__register_frame_info)
357 __register_frame_info (__EH_FRAME_BEGIN__, &object);
6fa2a5a8 358#endif /* CRT_GET_RFIB_DATA */
71fcebb2 359#endif /* USE_EH_FRAME_REGISTRY */
f313c0e1 360#ifdef JCR_SECTION_NAME
69c4cf50 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 }
f313c0e1 368#endif /* JCR_SECTION_NAME */
d757b8c9 369}
370
d24bc145 371#ifdef INIT_SECTION_ASM_OP
e1ff7102 372CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
d24bc145 373#else /* defined(INIT_SECTION_ASM_OP) */
374static func_ptr __frame_dummy_init_array_entry[]
375 __attribute__ ((__unused__, section(".init_array")))
376 = { frame_dummy };
377#endif /* !defined(INIT_SECTION_ASM_OP) */
71fcebb2 378#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
d757b8c9 379
b7c87ff2 380#else /* OBJECT_FORMAT_ELF */
381
b13ae905 382/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
d8fa92ab 383 and once in crtend.o). It must be declared static to avoid a link
b13ae905 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. */
a92771b8 388
205b5771 389static void __do_global_ctors_aux (void);
aedb00bf 390void
391__do_global_ctors (void)
84b64a19 392{
584907e7 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. */
84b64a19 398 __do_global_ctors_aux ();
399#endif
400}
9d13f5c4 401
402asm (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
1e625a2e 407 file-scope static-storage C++ objects within shared libraries. */
9d13f5c4 408
e1ff7102 409static void __attribute__((used))
aedb00bf 410__do_global_ctors_aux (void) /* prologue goes in .init section */
9d13f5c4 411{
e1ff7102 412 FORCE_CODE_SECTION_ALIGN /* explicit align before switch to .text */
9d13f5c4 413 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */
414 DO_GLOBAL_CTORS_BODY;
75d3a87b 415 atexit (__do_global_dtors);
9d13f5c4 416}
417
b7c87ff2 418#endif /* OBJECT_FORMAT_ELF */
8313a782 419
584907e7 420#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
8313a782 421
eb7ed20c 422extern void __do_global_dtors (void);
423
8313a782 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
d757b8c9 426 in this case because we protect it with -hidden_symbol. */
427
8313a782 428void
aedb00bf 429__do_global_dtors (void)
8313a782 430{
f6338f42 431 func_ptr *p, f;
432 for (p = __DTOR_LIST__ + 1; (f = *p); p++)
433 f ();
d757b8c9 434
0d6378a9 435#ifdef USE_EH_FRAME_REGISTRY
ee055d40 436 if (__deregister_frame_info)
437 __deregister_frame_info (__EH_FRAME_BEGIN__);
d757b8c9 438#endif
8313a782 439}
72ac783d 440
0d6378a9 441#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
584907e7 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. */
72ac783d 446void
584907e7 447__do_global_ctors_1(void)
72ac783d 448{
0d6378a9 449#ifdef USE_EH_FRAME_REGISTRY
72ac783d 450 static struct object object;
ee055d40 451 if (__register_frame_info)
452 __register_frame_info (__EH_FRAME_BEGIN__, &object);
b13ae905 453#endif
2cee371f 454#ifdef JCR_SECTION_NAME
69c4cf50 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 }
f313c0e1 462#endif
463}
71fcebb2 464#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
2cee371f 465
584907e7 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
479CTOR_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. */
483static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
484asm (CTORS_SECTION_ASM_OP);
485STATIC func_ptr __CTOR_END__[1]
486 __attribute__((aligned(sizeof(func_ptr))))
487 = { (func_ptr) 0 };
488#else
489STATIC 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
495DTOR_LIST_END;
f9e6c0d4 496#elif defined(HIDDEN_DTOR_LIST_END)
497#ifdef DTORS_SECTION_ASM_OP
498asm (DTORS_SECTION_ASM_OP);
499#endif
500func_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 };
584907e7 507#elif defined(DTORS_SECTION_ASM_OP)
508asm (DTORS_SECTION_ASM_OP);
509STATIC func_ptr __DTOR_END__[1]
510 __attribute__ ((unused, aligned(sizeof(func_ptr))))
511 = { (func_ptr) 0 };
512#else
513STATIC func_ptr __DTOR_END__[1]
514 __attribute__((unused, section(".dtors"), aligned(sizeof(func_ptr))))
515 = { (func_ptr) 0 };
516#endif
9d13f5c4 517
584907e7 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. */
743a6f47 521# if __INT_MAX__ == 2147483647
522typedef int int32;
523# elif __LONG_MAX__ == 2147483647
524typedef long int32;
525# elif __SHRT_MAX__ == 2147483647
526typedef short int32;
527# else
528# error "Missing a 4 byte integer"
529# endif
530STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[]
531 __attribute__ ((unused, section(EH_FRAME_SECTION_NAME),
532 aligned(sizeof(int32))))
584907e7 533 = { 0 };
13c14f1c 534#endif /* EH_FRAME_SECTION_NAME */
584907e7 535
536#ifdef JCR_SECTION_NAME
537/* Null terminate the .jcr section array. */
538STATIC void *__JCR_END__[1]
539 __attribute__ ((unused, section(JCR_SECTION_NAME),
540 aligned(sizeof(void *))))
541 = { 0 };
542#endif /* JCR_SECTION_NAME */
9d13f5c4 543
d24bc145 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)
9d13f5c4 549
b7c87ff2 550#ifdef OBJECT_FORMAT_ELF
e1ff7102 551static void __attribute__((used))
aedb00bf 552__do_global_ctors_aux (void)
b7c87ff2 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. */
e1ff7102 560CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux)
b7c87ff2 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
c3418f42 569 section of the crtend.o file. Specifically, we switch to the .text
b7c87ff2 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
a92771b8 582 before we start to execute any of the user's code. */
9d13f5c4 583
584static void
aedb00bf 585__do_global_ctors_aux (void) /* prologue goes in .text section */
9d13f5c4 586{
587 asm (INIT_SECTION_ASM_OP);
588 DO_GLOBAL_CTORS_BODY;
75d3a87b 589 atexit (__do_global_dtors);
997d68fe 590} /* epilogue and body go in .init section */
591
e1ff7102 592FORCE_CODE_SECTION_ALIGN
997d68fe 593asm (TEXT_SECTION_ASM_OP);
9d13f5c4 594
b7c87ff2 595#endif /* OBJECT_FORMAT_ELF */
596
584907e7 597#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
8313a782 598
eb7ed20c 599extern void __do_global_ctors (void);
600
8313a782 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
d757b8c9 603 in this case because we protect it with -hidden_symbol. */
8313a782 604void
aedb00bf 605__do_global_ctors (void)
8313a782 606{
607 func_ptr *p;
0d6378a9 608#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
584907e7 609 __do_global_ctors_1();
d757b8c9 610#endif
8313a782 611 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
612 (*p) ();
613}
b7c87ff2 614
584907e7 615#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
616#error "What are you doing with crtstuff.c, then?"
b13ae905 617#endif
9d13f5c4 618
584907e7 619#else /* ! CRT_BEGIN && ! CRT_END */
620#error "One of CRT_BEGIN or CRT_END must be defined."
b13ae905 621#endif