Daily bump.
[official-gcc.git] / gcc / crtstuff.c
blob1d1d76e7d816a448ca8b989c4ffe053763e03839
1 /* Specialized bits of code needed to support construction and
2 destruction of file-scope objects in C++ code.
3 Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998,
4 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
5 Contributed by Ron Guilmette (rfg@monkeys.com).
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
14 In addition to the permissions in the GNU General Public License, the
15 Free Software Foundation gives you unlimited permission to link the
16 compiled version of this file into combinations with other programs,
17 and to distribute those combinations without any restriction coming
18 from the use of this file. (The General Public License restrictions
19 do apply in other respects; for example, they cover modification of
20 the file, and distribution when not linked into a combine
21 executable.)
23 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
24 WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 for more details.
28 You should have received a copy of the GNU General Public License
29 along with GCC; see the file COPYING. If not, write to the Free
30 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 02111-1307, USA. */
33 /* This file is a bit like libgcc2.c in that it is compiled
34 multiple times and yields multiple .o files.
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.
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.
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.)
52 This file must be compiled with gcc. */
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. */
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"
61 #include "tconfig.h"
62 #include "tsystem.h"
63 #include "unwind-dw2-fde.h"
65 #ifndef FORCE_CODE_SECTION_ALIGN
66 # define FORCE_CODE_SECTION_ALIGN
67 #endif
69 #ifndef CRT_CALL_STATIC_FUNCTION
70 # define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
71 static void __attribute__((__used__)) \
72 call_ ## FUNC (void) \
73 { \
74 asm (SECTION_OP); \
75 FUNC (); \
76 FORCE_CODE_SECTION_ALIGN \
77 asm (TEXT_SECTION_ASM_OP); \
79 #endif
81 #if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
82 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
83 && defined(__GLIBC__) && __GLIBC__ >= 2
84 #include <link.h>
85 # if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
86 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
87 # define USE_PT_GNU_EH_FRAME
88 # endif
89 #endif
90 #if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
91 # define USE_EH_FRAME_REGISTRY
92 #endif
94 /* We do not want to add the weak attribute to the declarations of these
95 routines in unwind-dw2-fde.h because that will cause the definition of
96 these symbols to be weak as well.
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.
104 Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
105 one thinks about scaling to larger problems -- ie, the condition under
106 which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
107 complicated.
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.
112 Neither way is particularly good. */
114 /* References to __register_frame_info and __deregister_frame_info should
115 be weak in this file if at all possible. */
116 extern void __register_frame_info (void *, struct object *)
117 TARGET_ATTRIBUTE_WEAK;
118 extern void __register_frame_info_bases (void *, struct object *,
119 void *, void *)
120 TARGET_ATTRIBUTE_WEAK;
121 extern void *__deregister_frame_info (void *)
122 TARGET_ATTRIBUTE_WEAK;
123 extern void *__deregister_frame_info_bases (void *)
124 TARGET_ATTRIBUTE_WEAK;
126 /* Likewise for _Jv_RegisterClasses. */
127 extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
129 #if !defined (OBJECT_FORMAT_MACHO) \
130 && !(defined (__MINGW32__) || defined (__CYGWIN__))
132 #ifdef OBJECT_FORMAT_ELF
134 /* Declare a pointer to void function type. */
135 typedef void (*func_ptr) (void);
136 #define STATIC static
138 #else /* OBJECT_FORMAT_ELF */
140 #include "gbl-ctors.h"
142 #define STATIC
144 #endif /* OBJECT_FORMAT_ELF */
146 #ifdef CRT_BEGIN
148 /* NOTE: In order to be able to support SVR4 shared libraries, we arrange
149 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
150 __DTOR_END__ } per root executable and also one set of these symbols
151 per shared library. So in any given whole process image, we may have
152 multiple definitions of each of these symbols. In order to prevent
153 these definitions from conflicting with one another, and in order to
154 ensure that the proper lists are used for the initialization/finalization
155 of each individual shared library (respectively), we give these symbols
156 only internal (i.e. `static') linkage, and we also make it a point to
157 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
158 symbol in crtbegin.o, where they are defined. */
160 /* The -1 is a flag to __do_global_[cd]tors indicating that this table
161 does not start with a count of elements. */
162 #ifdef CTOR_LIST_BEGIN
163 CTOR_LIST_BEGIN;
164 #elif defined(CTORS_SECTION_ASM_OP)
165 /* Hack: force cc1 to switch to .data section early, so that assembling
166 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
167 static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
168 asm (CTORS_SECTION_ASM_OP);
169 STATIC func_ptr __CTOR_LIST__[1]
170 __attribute__ ((__unused__, aligned(sizeof(func_ptr))))
171 = { (func_ptr) (-1) };
172 #else
173 STATIC func_ptr __CTOR_LIST__[1]
174 __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr))))
175 = { (func_ptr) (-1) };
176 #endif /* __CTOR_LIST__ alternatives */
178 #ifdef DTOR_LIST_BEGIN
179 DTOR_LIST_BEGIN;
180 #elif defined(DTORS_SECTION_ASM_OP)
181 asm (DTORS_SECTION_ASM_OP);
182 STATIC func_ptr __DTOR_LIST__[1]
183 __attribute__ ((aligned(sizeof(func_ptr))))
184 = { (func_ptr) (-1) };
185 #else
186 STATIC func_ptr __DTOR_LIST__[1]
187 __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
188 = { (func_ptr) (-1) };
189 #endif /* __DTOR_LIST__ alternatives */
191 #ifdef EH_FRAME_SECTION_NAME
192 /* Stick a label at the beginning of the frame unwind info so we can register
193 and deregister it with the exception handling library code. */
194 STATIC char __EH_FRAME_BEGIN__[]
195 __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
196 = { };
197 #endif /* EH_FRAME_SECTION_NAME */
199 #ifdef JCR_SECTION_NAME
200 /* Stick a label at the beginning of the java class registration info
201 so we can register them properly. */
202 STATIC void *__JCR_LIST__[]
203 __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
204 = { };
205 #endif /* JCR_SECTION_NAME */
207 #ifdef INIT_SECTION_ASM_OP
209 #ifdef OBJECT_FORMAT_ELF
211 /* Declare the __dso_handle variable. It should have a unique value
212 in every shared-object; in a main program its value is zero. The
213 object should in any case be protected. This means the instance
214 in one DSO or the main program is not used in another object. The
215 dynamic linker takes care of this. */
217 /* XXX Ideally the following should be implemented using
218 __attribute__ ((__visibility__ ("hidden")))
219 but the __attribute__ support is not yet there. */
220 #ifdef HAVE_GAS_HIDDEN
221 asm (".hidden\t__dso_handle");
222 #endif
224 #ifdef CRTSTUFFS_O
225 void *__dso_handle = &__dso_handle;
226 #else
227 void *__dso_handle = 0;
228 #endif
230 /* The __cxa_finalize function may not be available so we use only a
231 weak declaration. */
232 extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
234 /* Run all the global destructors on exit from the program. */
236 /* Some systems place the number of pointers in the first word of the
237 table. On SVR4 however, that word is -1. In all cases, the table is
238 null-terminated. On SVR4, we start from the beginning of the list and
239 invoke each per-compilation-unit destructor routine in order
240 until we find that null.
242 Note that this function MUST be static. There will be one of these
243 functions in each root executable and one in each shared library, but
244 although they all have the same code, each one is unique in that it
245 refers to one particular associated `__DTOR_LIST__' which belongs to the
246 same particular root executable or shared library file.
248 On some systems, this routine is run more than once from the .fini,
249 when exit is called recursively, so we arrange to remember where in
250 the list we left off processing, and we resume at that point,
251 should we be re-invoked. */
253 static void __attribute__((used))
254 __do_global_dtors_aux (void)
256 static func_ptr *p = __DTOR_LIST__ + 1;
257 static _Bool completed;
258 func_ptr f;
260 if (__builtin_expect (completed, 0))
261 return;
263 #ifdef CRTSTUFFS_O
264 if (__cxa_finalize)
265 __cxa_finalize (__dso_handle);
266 #endif
268 while ((f = *p))
270 p++;
271 f ();
274 #ifdef USE_EH_FRAME_REGISTRY
275 #if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
276 /* If we used the new __register_frame_info_bases interface,
277 make sure that we deregister from the same place. */
278 if (__deregister_frame_info_bases)
279 __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
280 #else
281 if (__deregister_frame_info)
282 __deregister_frame_info (__EH_FRAME_BEGIN__);
283 #endif
284 #endif
286 completed = 1;
289 /* Stick a call to __do_global_dtors_aux into the .fini section. */
290 CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
292 #if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
293 /* Stick a call to __register_frame_info into the .init section. For some
294 reason calls with no arguments work more reliably in .init, so stick the
295 call in another function. */
297 static void __attribute__((used))
298 frame_dummy (void)
300 #ifdef USE_EH_FRAME_REGISTRY
301 static struct object object;
302 #if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
303 void *tbase, *dbase;
304 #ifdef CRT_GET_RFIB_TEXT
305 CRT_GET_RFIB_TEXT (tbase);
306 #else
307 tbase = 0;
308 #endif
309 #ifdef CRT_GET_RFIB_DATA
310 CRT_GET_RFIB_DATA (dbase);
311 #else
312 dbase = 0;
313 #endif
314 if (__register_frame_info_bases)
315 __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
316 #else
317 if (__register_frame_info)
318 __register_frame_info (__EH_FRAME_BEGIN__, &object);
319 #endif
320 #endif /* USE_EH_FRAME_REGISTRY */
321 #ifdef JCR_SECTION_NAME
322 if (__JCR_LIST__[0] && _Jv_RegisterClasses)
323 _Jv_RegisterClasses (__JCR_LIST__);
324 #endif /* JCR_SECTION_NAME */
327 CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
328 #endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
330 #else /* OBJECT_FORMAT_ELF */
332 /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
333 and once in crtend.o). It must be declared static to avoid a link
334 error. Here, we define __do_global_ctors as an externally callable
335 function. It is externally callable so that __main can invoke it when
336 INVOKE__main is defined. This has the additional effect of forcing cc1
337 to switch to the .text section. */
339 static void __do_global_ctors_aux (void);
340 void
341 __do_global_ctors (void)
343 #ifdef INVOKE__main
344 /* If __main won't actually call __do_global_ctors then it doesn't matter
345 what's inside the function. The inside of __do_global_ctors_aux is
346 called automatically in that case. And the Alliant fx2800 linker
347 crashes on this reference. So prevent the crash. */
348 __do_global_ctors_aux ();
349 #endif
352 asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
354 /* On some svr4 systems, the initial .init section preamble code provided in
355 crti.o may do something, such as bump the stack, which we have to
356 undo before we reach the function prologue code for __do_global_ctors
357 (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE
358 to expand into the code needed to undo the actions of the crti.o file. */
360 #ifdef INIT_SECTION_PREAMBLE
361 INIT_SECTION_PREAMBLE;
362 #endif
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
367 file-scope static-storage C++ objects within shared libraries. */
369 static void __attribute__((used))
370 __do_global_ctors_aux (void) /* prologue goes in .init section */
372 FORCE_CODE_SECTION_ALIGN /* explicit align before switch to .text */
373 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */
374 DO_GLOBAL_CTORS_BODY;
375 atexit (__do_global_dtors);
378 #endif /* OBJECT_FORMAT_ELF */
380 #elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
382 /* This case is used by the Irix 6 port, which supports named sections but
383 not an SVR4-style .fini section. __do_global_dtors can be non-static
384 in this case because we protect it with -hidden_symbol. */
386 void
387 __do_global_dtors (void)
389 func_ptr *p, f;
390 for (p = __DTOR_LIST__ + 1; (f = *p); p++)
391 f ();
393 #ifdef USE_EH_FRAME_REGISTRY
394 if (__deregister_frame_info)
395 __deregister_frame_info (__EH_FRAME_BEGIN__);
396 #endif
399 #if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
400 /* A helper function for __do_global_ctors, which is in crtend.o. Here
401 in crtbegin.o, we can reference a couple of symbols not visible there.
402 Plus, since we're before libgcc.a, we have no problems referencing
403 functions from there. */
404 void
405 __do_global_ctors_1(void)
407 #ifdef USE_EH_FRAME_REGISTRY
408 static struct object object;
409 if (__register_frame_info)
410 __register_frame_info (__EH_FRAME_BEGIN__, &object);
411 #endif
412 #ifdef JCR_SECTION_NAME
413 if (__JCR_LIST__[0] && _Jv_RegisterClasses)
414 _Jv_RegisterClasses (__JCR_LIST__);
415 #endif
417 #endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */
419 #else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
420 #error "What are you doing with crtstuff.c, then?"
421 #endif
423 #elif defined(CRT_END) /* ! CRT_BEGIN */
425 /* Put a word containing zero at the end of each of our two lists of function
426 addresses. Note that the words defined here go into the .ctors and .dtors
427 sections of the crtend.o file, and since that file is always linked in
428 last, these words naturally end up at the very ends of the two lists
429 contained in these two sections. */
431 #ifdef CTOR_LIST_END
432 CTOR_LIST_END;
433 #elif defined(CTORS_SECTION_ASM_OP)
434 /* Hack: force cc1 to switch to .data section early, so that assembling
435 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
436 static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { };
437 asm (CTORS_SECTION_ASM_OP);
438 STATIC func_ptr __CTOR_END__[1]
439 __attribute__((aligned(sizeof(func_ptr))))
440 = { (func_ptr) 0 };
441 #else
442 STATIC func_ptr __CTOR_END__[1]
443 __attribute__((section(".ctors"), aligned(sizeof(func_ptr))))
444 = { (func_ptr) 0 };
445 #endif
447 #ifdef DTOR_LIST_END
448 DTOR_LIST_END;
449 #elif defined(DTORS_SECTION_ASM_OP)
450 asm (DTORS_SECTION_ASM_OP);
451 STATIC func_ptr __DTOR_END__[1]
452 __attribute__ ((unused, aligned(sizeof(func_ptr))))
453 = { (func_ptr) 0 };
454 #else
455 STATIC func_ptr __DTOR_END__[1]
456 __attribute__((unused, section(".dtors"), aligned(sizeof(func_ptr))))
457 = { (func_ptr) 0 };
458 #endif
460 #ifdef EH_FRAME_SECTION_NAME
461 /* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
462 this would be the 'length' field in a real FDE. */
463 STATIC int __FRAME_END__[]
464 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
465 aligned(4)))
466 = { 0 };
467 #endif /* EH_FRAME_SECTION_NAME */
469 #ifdef JCR_SECTION_NAME
470 /* Null terminate the .jcr section array. */
471 STATIC void *__JCR_END__[1]
472 __attribute__ ((unused, section(JCR_SECTION_NAME),
473 aligned(sizeof(void *))))
474 = { 0 };
475 #endif /* JCR_SECTION_NAME */
477 #ifdef INIT_SECTION_ASM_OP
479 #ifdef OBJECT_FORMAT_ELF
480 static void __attribute__((used))
481 __do_global_ctors_aux (void)
483 func_ptr *p;
484 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
485 (*p) ();
488 /* Stick a call to __do_global_ctors_aux into the .init section. */
489 CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux)
490 #else /* OBJECT_FORMAT_ELF */
492 /* Stick the real initialization code, followed by a normal sort of
493 function epilogue at the very end of the .init section for this
494 entire root executable file or for this entire shared library file.
496 Note that we use some tricks here to get *just* the body and just
497 a function epilogue (but no function prologue) into the .init
498 section of the crtend.o file. Specifically, we switch to the .text
499 section, start to define a function, and then we switch to the .init
500 section just before the body code.
502 Earlier on, we put the corresponding function prologue into the .init
503 section of the crtbegin.o file (which will be linked in first).
505 Note that we want to invoke all constructors for C++ file-scope static-
506 storage objects AFTER any other possible initialization actions which
507 may be performed by the code in the .init section contributions made by
508 other libraries, etc. That's because those other initializations may
509 include setup operations for very primitive things (e.g. initializing
510 the state of the floating-point coprocessor, etc.) which should be done
511 before we start to execute any of the user's code. */
513 static void
514 __do_global_ctors_aux (void) /* prologue goes in .text section */
516 asm (INIT_SECTION_ASM_OP);
517 DO_GLOBAL_CTORS_BODY;
518 atexit (__do_global_dtors);
519 } /* epilogue and body go in .init section */
521 FORCE_CODE_SECTION_ALIGN
522 asm (TEXT_SECTION_ASM_OP);
524 #endif /* OBJECT_FORMAT_ELF */
526 #elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
528 /* This case is used by the Irix 6 port, which supports named sections but
529 not an SVR4-style .init section. __do_global_ctors can be non-static
530 in this case because we protect it with -hidden_symbol. */
531 extern void __do_global_ctors_1(void);
532 void
533 __do_global_ctors (void)
535 func_ptr *p;
536 #if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
537 __do_global_ctors_1();
538 #endif
539 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
540 (*p) ();
543 #else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */
544 #error "What are you doing with crtstuff.c, then?"
545 #endif
547 #else /* ! CRT_BEGIN && ! CRT_END */
548 #error "One of CRT_BEGIN or CRT_END must be defined."
549 #endif
551 #elif defined OBJECT_FORMAT_MACHO
553 /* For Mach-O format executables, we assume that the system's runtime is
554 smart enough to handle constructors and destructors, but doesn't have
555 an init section (if it can't even handle constructors/destructors
556 you should be using INVOKE__main, not crtstuff). All we need to do
557 is install/deinstall the frame information for exceptions. We do this
558 by putting a constructor in crtbegin.o and a destructor in crtend.o.
560 crtend.o also puts in the terminating zero in the frame information
561 segment. */
563 /* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__
564 to figure out the start of the exception frame, but here we use
565 getsectbynamefromheader to find this value. Either method would work,
566 but this method avoids creating any global symbols, which seems
567 cleaner. */
569 #include <mach-o/ldsyms.h>
570 extern const struct section *
571 getsectbynamefromheader (const struct mach_header *,
572 const char *, const char *);
574 #ifdef CRT_BEGIN
576 static void __reg_frame_ctor (void) __attribute__ ((constructor));
578 static void
579 __reg_frame_ctor (void)
581 static struct object object;
582 const struct section *eh_frame;
584 eh_frame = getsectbynamefromheader (&_mh_execute_header,
585 "__TEXT", "__eh_frame");
586 __register_frame_info ((void *) eh_frame->addr, &object);
589 #elif defined(CRT_END)
591 static void __dereg_frame_dtor (void) __attribute__ ((destructor));
593 static void
594 __dereg_frame_dtor (void)
596 const struct section *eh_frame;
598 eh_frame = getsectbynamefromheader (&_mh_execute_header,
599 "__TEXT", "__eh_frame");
600 __deregister_frame_info ((void *) eh_frame->addr);
603 /* Terminate the frame section with a final zero. */
604 STATIC int __FRAME_END__[]
605 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
606 aligned(4)))
607 = { 0 };
609 #else /* ! CRT_BEGIN && ! CRT_END */
610 #error "One of CRT_BEGIN or CRT_END must be defined."
611 #endif
613 #else /*__MINGW32__ || __CYGWIN__ */
615 /* Use __main to run ctors and dtors. This code generates a
616 label for beginning of .eh_frame section in crtbegin.o and terminates
617 the section in crtend.o. Registration and deregistration is done by
618 installing ctor and dtor functions to do the job. */
621 #ifdef CRT_BEGIN
622 /* Stick a label at the beginning of the frame unwind info so we can
623 register/deregister it with the exception handling library code. */
625 char __EH_FRAME_BEGIN__[]
626 __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4)))
627 = { };
629 static struct object obj;
631 /* These will pull in references from libgcc.a(unwind-dw2-fde.o) */
633 void __do_frame_init (void);
634 void __do_frame_fini (void);
636 void
637 __do_frame_init (void)
639 __register_frame_info (__EH_FRAME_BEGIN__, &obj);
642 void
643 __do_frame_fini (void)
645 __deregister_frame_info (__EH_FRAME_BEGIN__);
649 #elif defined CRT_END
651 /* Terminate the frame unwind info section with a 0 as a sentinel;
652 this would be the 'length' field in a real FDE. */
653 static int __EH_FRAME_END__[]
654 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
655 aligned(4)))
656 = { 0 };
658 /* Register the eh_frame. This has to be the first ctor to
659 be invoked so we put it in last. Since we're last, we can't
660 reference __register_frame_info in libgcc.a directly (if eh_frame
661 code has been referenced than it will have been pulled in but
662 we can't count on it) so we call a stub in crtbegin.o. */
664 extern void __do_frame_init (void);
665 static void __reg_frame_ctor (void) __attribute__ ((constructor));
667 static void
668 __reg_frame_ctor (void)
670 __do_frame_init ();
674 /* Deregister the eh_frame. This has to be the last dtor. The
675 call to __register_frame_info in crtbegin.o will have pulled in
676 libgcc.a(unwind-dw2-fde.o) if libgcc.a is static lib but not if
677 dll, so we use a stub again to be sure. */
679 extern void __do_frame_fini (void);
680 static void __dereg_frame_dtor (void) __attribute__ ((destructor));
682 static void
683 __dereg_frame_dtor (void)
685 __do_frame_fini ();
688 #else /* ! CRT_BEGIN && ! CRT_END */
689 #error "One of CRT_BEGIN or CRT_END must be defined."
690 #endif
692 #endif /* __MINGW32__ || __CYGWIN__ */