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