]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/crtstuff.c
Update copyright.
[thirdparty/gcc.git] / gcc / crtstuff.c
CommitLineData
dc17e9e9
RS
1/* Specialized bits of code needed to support construction and
2 destruction of file-scope objects in C++ code.
5e7b4e25 3 Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998,
c913b6f1 4 1999, 2000, 2001 Free Software Foundation, Inc.
d0f8fcea 5 Contributed by Ron Guilmette (rfg@monkeys.com).
dc17e9e9 6
1322177d 7This file is part of GCC.
dc17e9e9 8
1322177d
LB
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.
dc17e9e9 13
f7af368f
JL
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
1322177d
LB
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.
dc17e9e9
RS
27
28You should have received a copy of the GNU General Public License
1322177d
LB
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. */
dc17e9e9 32
7857f134 33/* This file is a bit like libgcc2.c in that it is compiled
dc17e9e9
RS
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
37ce5b86
CH
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.)
dc17e9e9
RS
51
52 This file must be compiled with gcc. */
53
54/* It is incorrect to include config.h here, because this file is being
55 compiled for the target, and hence definitions concerning only the host
56 do not apply. */
57
1b5640cd
KG
58/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
59 supposedly valid even though this is a "target" file. */
60#include "auto-host.h"
eaf4e618 61#include "tconfig.h"
2e39bdbe 62#include "tsystem.h"
52a11cbf 63#include "unwind-dw2-fde.h"
dc17e9e9 64
036cfb36
AO
65#ifndef CRT_CALL_STATIC_FUNCTION
66# define CRT_CALL_STATIC_FUNCTION(func) func ()
67#endif
68
275b60d6 69#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
72c7c913 70 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
275b60d6
JJ
71 && defined(__GLIBC__) && __GLIBC__ >= 2
72#include <link.h>
73# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
74 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
75# define USE_PT_GNU_EH_FRAME
76# endif
77#endif
78#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
79# define USE_EH_FRAME_REGISTRY
80#endif
81
8f08ea1e 82/* We do not want to add the weak attribute to the declarations of these
52a11cbf
RH
83 routines in unwind-dw2-fde.h because that will cause the definition of
84 these symbols to be weak as well.
8f08ea1e
L
85
86 This exposes a core issue, how to handle creating weak references vs
87 how to create weak definitions. Either we have to have the definition
88 of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or
89 have a second declaration if we want a function's references to be weak,
90 but not its definition.
91
92 Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
93 one thinks about scaling to larger problems -- ie, the condition under
94 which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
95 complicated.
96
97 So, we take an approach similar to #pragma weak -- we have a second
98 declaration for functions that we want to have weak references.
99
100 Neither way is particularly good. */
101
102/* References to __register_frame_info and __deregister_frame_info should
103 be weak in this file if at all possible. */
104extern void __register_frame_info (void *, struct object *)
105 TARGET_ATTRIBUTE_WEAK;
1066e2b5
RH
106extern void __register_frame_info_bases (void *, struct object *,
107 void *, void *)
108 TARGET_ATTRIBUTE_WEAK;
8f08ea1e
L
109extern void *__deregister_frame_info (void *)
110 TARGET_ATTRIBUTE_WEAK;
101fa48c
RH
111extern void *__deregister_frame_info_bases (void *)
112 TARGET_ATTRIBUTE_WEAK;
8f08ea1e 113
213f974a
RH
114/* Likewise for _Jv_RegisterClasses. */
115extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
116
750930c1
MN
117#ifndef OBJECT_FORMAT_MACHO
118
68d69835
JM
119#ifdef OBJECT_FORMAT_ELF
120
121/* Declare a pointer to void function type. */
122typedef void (*func_ptr) (void);
123#define STATIC static
124
125#else /* OBJECT_FORMAT_ELF */
126
dc17e9e9
RS
127#include "gbl-ctors.h"
128
68d69835
JM
129#define STATIC
130
131#endif /* OBJECT_FORMAT_ELF */
dc17e9e9
RS
132
133#ifdef CRT_BEGIN
134
213f974a
RH
135/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
136 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
137 __DTOR_END__ } per root executable and also one set of these symbols
138 per shared library. So in any given whole process image, we may have
139 multiple definitions of each of these symbols. In order to prevent
140 these definitions from conflicting with one another, and in order to
141 ensure that the proper lists are used for the initialization/finalization
142 of each individual shared library (respectively), we give these symbols
143 only internal (i.e. `static') linkage, and we also make it a point to
144 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
145 symbol in crtbegin.o, where they are defined. */
146
147/* The -1 is a flag to __do_global_[cd]tors indicating that this table
148 does not start with a count of elements. */
149#ifdef CTOR_LIST_BEGIN
150CTOR_LIST_BEGIN;
151#elif defined(CTORS_SECTION_ASM_OP)
152/* Hack: force cc1 to switch to .data section early, so that assembling
153 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
154static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
155asm (CTORS_SECTION_ASM_OP);
156STATIC func_ptr __CTOR_LIST__[1]
157 __attribute__ ((__unused__, aligned(sizeof(func_ptr))))
158 = { (func_ptr) (-1) };
159#else
160STATIC func_ptr __CTOR_LIST__[1]
161 __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr))))
162 = { (func_ptr) (-1) };
163#endif /* __CTOR_LIST__ alternatives */
164
165#ifdef DTOR_LIST_BEGIN
166DTOR_LIST_BEGIN;
167#elif defined(DTORS_SECTION_ASM_OP)
168asm (DTORS_SECTION_ASM_OP);
169STATIC func_ptr __DTOR_LIST__[1]
170 __attribute__ ((aligned(sizeof(func_ptr))))
171 = { (func_ptr) (-1) };
172#else
173STATIC func_ptr __DTOR_LIST__[1]
174 __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
175 = { (func_ptr) (-1) };
176#endif /* __DTOR_LIST__ alternatives */
177
178#ifdef EH_FRAME_SECTION_NAME
179/* Stick a label at the beginning of the frame unwind info so we can register
180 and deregister it with the exception handling library code. */
29d2c7a5 181STATIC char __EH_FRAME_BEGIN__[]
213f974a
RH
182 __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
183 = { };
184#endif /* EH_FRAME_SECTION_NAME */
185
186#ifdef JCR_SECTION_NAME
187/* Stick a label at the beginning of the java class registration info
188 so we can register them properly. */
213f974a
RH
189STATIC void *__JCR_LIST__[]
190 __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
191 = { };
192#endif /* JCR_SECTION_NAME */
193
29d2c7a5
RH
194#ifdef INIT_SECTION_ASM_OP
195
68d69835
JM
196#ifdef OBJECT_FORMAT_ELF
197
fc693822 198/* Declare the __dso_handle variable. It should have a unique value
6a9c5260
UD
199 in every shared-object; in a main program its value is zero. The
200 object should in any case be protected. This means the instance
201 in one DSO or the main program is not used in another object. The
202 dynamic linker takes care of this. */
203
204/* XXX Ideally the following should be implemented using
205 __attribute__ ((__visibility__ ("hidden")))
206 but the __attribute__ support is not yet there. */
207#ifdef HAVE_GAS_HIDDEN
208asm (".hidden\t__dso_handle");
209#endif
fc693822
MM
210
211#ifdef CRTSTUFFS_O
212void *__dso_handle = &__dso_handle;
213#else
214void *__dso_handle = 0;
215#endif
216
217/* The __cxa_finalize function may not be available so we use only a
218 weak declaration. */
219extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
220
68d69835
JM
221/* Run all the global destructors on exit from the program. */
222
223/* Some systems place the number of pointers in the first word of the
224 table. On SVR4 however, that word is -1. In all cases, the table is
225 null-terminated. On SVR4, we start from the beginning of the list and
226 invoke each per-compilation-unit destructor routine in order
227 until we find that null.
228
229 Note that this function MUST be static. There will be one of these
230 functions in each root executable and one in each shared library, but
231 although they all have the same code, each one is unique in that it
232 refers to one particular associated `__DTOR_LIST__' which belongs to the
b40b9d93
MS
233 same particular root executable or shared library file.
234
235 On some systems, this routine is run more than once from the .fini,
236 when exit is called recursively, so we arrange to remember where in
237 the list we left off processing, and we resume at that point,
238 should we be re-invoked. */
68d69835 239
68d69835 240static void
3cc22c31 241__do_global_dtors_aux (void)
68d69835 242{
b40b9d93 243 static func_ptr *p = __DTOR_LIST__ + 1;
1066e2b5
RH
244 static int completed;
245 func_ptr f;
5041a61c 246
1066e2b5 247 if (__builtin_expect (completed, 0))
5041a61c
JL
248 return;
249
2a14e214
MM
250#ifdef CRTSTUFFS_O
251 if (__cxa_finalize)
fc693822 252 __cxa_finalize (__dso_handle);
2a14e214 253#endif
fc693822 254
1066e2b5 255 while ((f = *p))
b40b9d93
MS
256 {
257 p++;
1066e2b5 258 f ();
b40b9d93 259 }
0021b564 260
275b60d6 261#ifdef USE_EH_FRAME_REGISTRY
101fa48c
RH
262#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
263 /* If we used the new __register_frame_info_bases interface,
264 make sure that we deregister from the same place. */
265 if (__deregister_frame_info_bases)
266 __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
267#else
8f08ea1e
L
268 if (__deregister_frame_info)
269 __deregister_frame_info (__EH_FRAME_BEGIN__);
0021b564 270#endif
101fa48c
RH
271#endif
272
5041a61c 273 completed = 1;
68d69835
JM
274}
275
5041a61c 276
68d69835 277/* Stick a call to __do_global_dtors_aux into the .fini section. */
0f41302f 278
50b2596f 279static void __attribute__ ((__unused__))
3cc22c31 280fini_dummy (void)
68d69835
JM
281{
282 asm (FINI_SECTION_ASM_OP);
036cfb36 283 CRT_CALL_STATIC_FUNCTION (__do_global_dtors_aux);
68d69835
JM
284#ifdef FORCE_FINI_SECTION_ALIGN
285 FORCE_FINI_SECTION_ALIGN;
286#endif
287 asm (TEXT_SECTION_ASM_OP);
288}
289
275b60d6 290#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
6d8ccdbb
JL
291/* Stick a call to __register_frame_info into the .init section. For some
292 reason calls with no arguments work more reliably in .init, so stick the
293 call in another function. */
0021b564
JM
294
295static void
3cc22c31 296frame_dummy (void)
0021b564 297{
275b60d6 298#ifdef USE_EH_FRAME_REGISTRY
956d6950 299 static struct object object;
1066e2b5
RH
300#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
301 void *tbase, *dbase;
302#ifdef CRT_GET_RFIB_TEXT
303 CRT_GET_RFIB_TEXT (tbase);
304#else
305 tbase = 0;
306#endif
307#ifdef CRT_GET_RFIB_DATA
308 CRT_GET_RFIB_DATA (dbase);
309#else
310 dbase = 0;
311#endif
312 if (__register_frame_info_bases)
313 __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
314#else
8f08ea1e
L
315 if (__register_frame_info)
316 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1066e2b5 317#endif
213f974a
RH
318#endif /* EH_FRAME_SECTION_NAME */
319#ifdef JCR_SECTION_NAME
320 if (__JCR_LIST__[0] && _Jv_RegisterClasses)
321 _Jv_RegisterClasses (__JCR_LIST__);
322#endif /* JCR_SECTION_NAME */
0021b564
JM
323}
324
50b2596f 325static void __attribute__ ((__unused__))
3cc22c31 326init_dummy (void)
0021b564
JM
327{
328 asm (INIT_SECTION_ASM_OP);
036cfb36 329 CRT_CALL_STATIC_FUNCTION (frame_dummy);
0021b564
JM
330#ifdef FORCE_INIT_SECTION_ALIGN
331 FORCE_INIT_SECTION_ALIGN;
332#endif
333 asm (TEXT_SECTION_ASM_OP);
334}
213f974a 335#endif /* EH_FRAME_SECTION_NAME || JCR_SECTION_NAME */
0021b564 336
68d69835
JM
337#else /* OBJECT_FORMAT_ELF */
338
b335c2cc 339/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
b71a4aa9 340 and once in crtend.o). It must be declared static to avoid a link
b335c2cc
TW
341 error. Here, we define __do_global_ctors as an externally callable
342 function. It is externally callable so that __main can invoke it when
343 INVOKE__main is defined. This has the additional effect of forcing cc1
344 to switch to the .text section. */
0f41302f 345
d1e51320 346static void __do_global_ctors_aux (void);
3cc22c31
JL
347void
348__do_global_ctors (void)
329d2160 349{
29d2c7a5
RH
350#ifdef INVOKE__main
351 /* If __main won't actually call __do_global_ctors then it doesn't matter
352 what's inside the function. The inside of __do_global_ctors_aux is
353 called automatically in that case. And the Alliant fx2800 linker
354 crashes on this reference. So prevent the crash. */
329d2160
RS
355 __do_global_ctors_aux ();
356#endif
357}
dc17e9e9
RS
358
359asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
360
5378943d
RK
361/* On some svr4 systems, the initial .init section preamble code provided in
362 crti.o may do something, such as bump the stack, which we have to
363 undo before we reach the function prologue code for __do_global_ctors
364 (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE
0f41302f 365 to expand into the code needed to undo the actions of the crti.o file. */
5378943d
RK
366
367#ifdef INIT_SECTION_PREAMBLE
368 INIT_SECTION_PREAMBLE;
369#endif
370
dc17e9e9
RS
371/* A routine to invoke all of the global constructors upon entry to the
372 program. We put this into the .init section (for systems that have
373 such a thing) so that we can properly perform the construction of
6d2f8887 374 file-scope static-storage C++ objects within shared libraries. */
dc17e9e9
RS
375
376static void
3cc22c31 377__do_global_ctors_aux (void) /* prologue goes in .init section */
dc17e9e9 378{
5868ca20
JW
379#ifdef FORCE_INIT_SECTION_ALIGN
380 FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */
381#endif
dc17e9e9
RS
382 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */
383 DO_GLOBAL_CTORS_BODY;
451fbdf2 384 atexit (__do_global_dtors);
dc17e9e9
RS
385}
386
68d69835 387#endif /* OBJECT_FORMAT_ELF */
fe1fd353 388
29d2c7a5 389#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
fe1fd353
JM
390
391/* This case is used by the Irix 6 port, which supports named sections but
392 not an SVR4-style .fini section. __do_global_dtors can be non-static
0021b564
JM
393 in this case because we protect it with -hidden_symbol. */
394
fe1fd353 395void
3cc22c31 396__do_global_dtors (void)
fe1fd353 397{
1066e2b5
RH
398 func_ptr *p, f;
399 for (p = __DTOR_LIST__ + 1; (f = *p); p++)
400 f ();
0021b564 401
275b60d6 402#ifdef USE_EH_FRAME_REGISTRY
8f08ea1e
L
403 if (__deregister_frame_info)
404 __deregister_frame_info (__EH_FRAME_BEGIN__);
0021b564 405#endif
fe1fd353 406}
35a42f5f 407
275b60d6 408#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
29d2c7a5
RH
409/* A helper function for __do_global_ctors, which is in crtend.o. Here
410 in crtbegin.o, we can reference a couple of symbols not visible there.
411 Plus, since we're before libgcc.a, we have no problems referencing
412 functions from there. */
35a42f5f 413void
29d2c7a5 414__do_global_ctors_1(void)
35a42f5f 415{
275b60d6 416#ifdef USE_EH_FRAME_REGISTRY
35a42f5f 417 static struct object object;
8f08ea1e
L
418 if (__register_frame_info)
419 __register_frame_info (__EH_FRAME_BEGIN__, &object);
b335c2cc 420#endif
6351543d 421#ifdef JCR_SECTION_NAME
213f974a
RH
422 if (__JCR_LIST__[0] && _Jv_RegisterClasses)
423 _Jv_RegisterClasses (__JCR_LIST__);
424#endif
425}
426#endif /* EH_FRAME_SECTION_NAME || JCR_SECTION_NAME */
6351543d 427
29d2c7a5
RH
428#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
429#error "What are you doing with crtstuff.c, then?"
430#endif
431
432#elif defined(CRT_END) /* ! CRT_BEGIN */
433
434/* Put a word containing zero at the end of each of our two lists of function
435 addresses. Note that the words defined here go into the .ctors and .dtors
436 sections of the crtend.o file, and since that file is always linked in
437 last, these words naturally end up at the very ends of the two lists
438 contained in these two sections. */
439
440#ifdef CTOR_LIST_END
441CTOR_LIST_END;
442#elif defined(CTORS_SECTION_ASM_OP)
443/* Hack: force cc1 to switch to .data section early, so that assembling
444 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
445static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
446asm (CTORS_SECTION_ASM_OP);
447STATIC func_ptr __CTOR_END__[1]
448 __attribute__((aligned(sizeof(func_ptr))))
449 = { (func_ptr) 0 };
450#else
451STATIC func_ptr __CTOR_END__[1]
452 __attribute__((section(".ctors"), aligned(sizeof(func_ptr))))
453 = { (func_ptr) 0 };
454#endif
455
456#ifdef DTOR_LIST_END
457DTOR_LIST_END;
458#elif defined(DTORS_SECTION_ASM_OP)
459asm (DTORS_SECTION_ASM_OP);
460STATIC func_ptr __DTOR_END__[1]
461 __attribute__ ((unused, aligned(sizeof(func_ptr))))
462 = { (func_ptr) 0 };
463#else
464STATIC func_ptr __DTOR_END__[1]
465 __attribute__((unused, section(".dtors"), aligned(sizeof(func_ptr))))
466 = { (func_ptr) 0 };
467#endif
dc17e9e9 468
29d2c7a5
RH
469#ifdef EH_FRAME_SECTION_NAME
470/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
471 this would be the 'length' field in a real FDE. */
472STATIC int __FRAME_END__[]
473 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
474 aligned(4)))
475 = { 0 };
f3a8e4f5 476#endif /* EH_FRAME_SECTION_NAME */
29d2c7a5
RH
477
478#ifdef JCR_SECTION_NAME
479/* Null terminate the .jcr section array. */
480STATIC void *__JCR_END__[1]
481 __attribute__ ((unused, section(JCR_SECTION_NAME),
482 aligned(sizeof(void *))))
483 = { 0 };
484#endif /* JCR_SECTION_NAME */
dc17e9e9
RS
485
486#ifdef INIT_SECTION_ASM_OP
487
68d69835 488#ifdef OBJECT_FORMAT_ELF
dc17e9e9 489
68d69835 490static void
3cc22c31 491__do_global_ctors_aux (void)
68d69835
JM
492{
493 func_ptr *p;
494 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
495 (*p) ();
496}
497
498/* Stick a call to __do_global_ctors_aux into the .init section. */
0f41302f 499
50b2596f 500static void __attribute__ ((__unused__))
3cc22c31 501init_dummy (void)
68d69835
JM
502{
503 asm (INIT_SECTION_ASM_OP);
036cfb36 504 CRT_CALL_STATIC_FUNCTION (__do_global_ctors_aux);
68d69835
JM
505#ifdef FORCE_INIT_SECTION_ALIGN
506 FORCE_INIT_SECTION_ALIGN;
507#endif
508 asm (TEXT_SECTION_ASM_OP);
373368fd
JJ
509#ifdef CRT_END_INIT_DUMMY
510 CRT_END_INIT_DUMMY;
bced43dd 511#endif
68d69835
JM
512}
513
514#else /* OBJECT_FORMAT_ELF */
515
516/* Stick the real initialization code, followed by a normal sort of
517 function epilogue at the very end of the .init section for this
518 entire root executable file or for this entire shared library file.
519
520 Note that we use some tricks here to get *just* the body and just
521 a function epilogue (but no function prologue) into the .init
9faa82d8 522 section of the crtend.o file. Specifically, we switch to the .text
68d69835
JM
523 section, start to define a function, and then we switch to the .init
524 section just before the body code.
525
526 Earlier on, we put the corresponding function prologue into the .init
527 section of the crtbegin.o file (which will be linked in first).
528
529 Note that we want to invoke all constructors for C++ file-scope static-
530 storage objects AFTER any other possible initialization actions which
531 may be performed by the code in the .init section contributions made by
532 other libraries, etc. That's because those other initializations may
533 include setup operations for very primitive things (e.g. initializing
534 the state of the floating-point coprocessor, etc.) which should be done
0f41302f 535 before we start to execute any of the user's code. */
dc17e9e9
RS
536
537static void
3cc22c31 538__do_global_ctors_aux (void) /* prologue goes in .text section */
dc17e9e9
RS
539{
540 asm (INIT_SECTION_ASM_OP);
541 DO_GLOBAL_CTORS_BODY;
451fbdf2 542 atexit (__do_global_dtors);
e5e809f4
JL
543} /* epilogue and body go in .init section */
544
c85f7c16 545#ifdef FORCE_INIT_SECTION_ALIGN
e5e809f4 546FORCE_INIT_SECTION_ALIGN;
c85f7c16 547#endif
e5e809f4
JL
548
549asm (TEXT_SECTION_ASM_OP);
dc17e9e9 550
68d69835
JM
551#endif /* OBJECT_FORMAT_ELF */
552
29d2c7a5 553#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
fe1fd353
JM
554
555/* This case is used by the Irix 6 port, which supports named sections but
556 not an SVR4-style .init section. __do_global_ctors can be non-static
0021b564 557 in this case because we protect it with -hidden_symbol. */
29d2c7a5 558extern void __do_global_ctors_1(void);
fe1fd353 559void
3cc22c31 560__do_global_ctors (void)
fe1fd353
JM
561{
562 func_ptr *p;
275b60d6 563#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
29d2c7a5 564 __do_global_ctors_1();
0021b564 565#endif
fe1fd353
JM
566 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
567 (*p) ();
568}
68d69835 569
29d2c7a5
RH
570#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
571#error "What are you doing with crtstuff.c, then?"
b335c2cc 572#endif
dc17e9e9 573
29d2c7a5
RH
574#else /* ! CRT_BEGIN && ! CRT_END */
575#error "One of CRT_BEGIN or CRT_END must be defined."
b335c2cc 576#endif
dc17e9e9 577
750930c1
MN
578#else /* OBJECT_FORMAT_MACHO */
579
580/* For Mach-O format executables, we assume that the system's runtime is
581 smart enough to handle constructors and destructors, but doesn't have
582 an init section (if it can't even handle constructors/destructors
583 you should be using INVOKE__main, not crtstuff). All we need to do
584 is install/deinstall the frame information for exceptions. We do this
585 by putting a constructor in crtbegin.o and a destructor in crtend.o.
586
587 crtend.o also puts in the terminating zero in the frame information
ec5c56db 588 segment. */
750930c1
MN
589
590/* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__
591 to figure out the start of the exception frame, but here we use
592 getsectbynamefromheader to find this value. Either method would work,
593 but this method avoids creating any global symbols, which seems
ec5c56db 594 cleaner. */
750930c1
MN
595
596#include <mach-o/ldsyms.h>
597extern const struct section *
598 getsectbynamefromheader (const struct mach_header *,
599 const char *, const char *);
600
601#ifdef CRT_BEGIN
602
d1e51320 603static void __reg_frame_ctor (void) __attribute__ ((constructor));
750930c1
MN
604
605static void
3cc22c31 606__reg_frame_ctor (void)
750930c1
MN
607{
608 static struct object object;
609 const struct section *eh_frame;
610
611 eh_frame = getsectbynamefromheader (&_mh_execute_header,
612 "__TEXT", "__eh_frame");
613 __register_frame_info ((void *) eh_frame->addr, &object);
614}
615
29d2c7a5 616#elif defined(CRT_END)
750930c1 617
d1e51320 618static void __dereg_frame_dtor (void) __attribute__ ((destructor));
750930c1 619
d1e51320 620static void
3cc22c31 621__dereg_frame_dtor (void)
750930c1
MN
622{
623 const struct section *eh_frame;
624
625 eh_frame = getsectbynamefromheader (&_mh_execute_header,
626 "__TEXT", "__eh_frame");
627 __deregister_frame_info ((void *) eh_frame->addr);
628}
629
ec5c56db 630/* Terminate the frame section with a final zero. */
7c262518 631STATIC int __FRAME_END__[]
51084e13
RH
632 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
633 aligned(4)))
7c262518 634 = { 0 };
29d2c7a5
RH
635
636#else /* ! CRT_BEGIN && ! CRT_END */
637#error "One of CRT_BEGIN or CRT_END must be defined."
638#endif
750930c1
MN
639
640#endif /* OBJECT_FORMAT_MACHO */