--with-gnu-ld uses different x- fiile under aix 4.1
[official-gcc.git] / gcc / crtstuff.c
blobce2c9561e64e287f961e8dc813f914f6ab475279
1 /* Specialized bits of code needed to support construction and
2 destruction of file-scope objects in C++ code.
3 Copyright (C) 1991, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
4 Contributed by Ron Guilmette (rfg@monkeys.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* As a special exception, if you link this library with files
24 compiled with GCC to produce an executable, this does not cause
25 the resulting executable to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
29 /* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled
30 multiple times and yields multiple .o files.
32 This file is useful on target machines where the object file format
33 supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On
34 such systems, this file allows us to avoid running collect (or any
35 other such slow and painful kludge). Additionally, if the target
36 system supports a .init section, this file allows us to support the
37 linking of C++ code with a non-C++ main program.
39 Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then
40 this file *will* make use of the .init section. If that symbol is
41 not defined however, then the .init section will not be used.
43 Currently, only ELF and COFF are supported. It is likely however that
44 ROSE could also be supported, if someone was willing to do the work to
45 make whatever (small?) adaptations are needed. (Some work may be
46 needed on the ROSE assembler and linker also.)
48 This file must be compiled with gcc. */
50 /* It is incorrect to include config.h here, because this file is being
51 compiled for the target, and hence definitions concerning only the host
52 do not apply. */
54 #include "tm.h"
55 #include "defaults.h"
56 #include <stddef.h>
57 #include "frame.h"
59 #ifndef OBJECT_FORMAT_MACHO
61 /* Provide default definitions for the pseudo-ops used to switch to the
62 .ctors and .dtors sections.
64 Note that we want to give these sections the SHF_WRITE attribute
65 because these sections will actually contain data (i.e. tables of
66 addresses of functions in the current root executable or shared library
67 file) and, in the case of a shared library, the relocatable addresses
68 will have to be properly resolved/relocated (and then written into) by
69 the dynamic linker when it actually attaches the given shared library
70 to the executing process. (Note that on SVR4, you may wish to use the
71 `-z text' option to the ELF linker, when building a shared library, as
72 an additional check that you are doing everything right. But if you do
73 use the `-z text' option when building a shared library, you will get
74 errors unless the .ctors and .dtors sections are marked as writable
75 via the SHF_WRITE attribute.) */
77 #ifndef CTORS_SECTION_ASM_OP
78 #define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
79 #endif
80 #ifndef DTORS_SECTION_ASM_OP
81 #define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
82 #endif
83 #if !defined (EH_FRAME_SECTION_ASM_OP) && defined (DWARF2_UNWIND_INFO) && defined(ASM_OUTPUT_SECTION_NAME)
84 #define EH_FRAME_SECTION_ASM_OP ".section\t.eh_frame,\"aw\""
85 #endif
87 #ifdef OBJECT_FORMAT_ELF
89 /* Declare a pointer to void function type. */
90 typedef void (*func_ptr) (void);
91 #define STATIC static
93 #else /* OBJECT_FORMAT_ELF */
95 #include "gbl-ctors.h"
97 #ifndef ON_EXIT
98 #define ON_EXIT(a, b)
99 #endif
100 #define STATIC
102 #endif /* OBJECT_FORMAT_ELF */
104 #ifdef CRT_BEGIN
106 #ifdef INIT_SECTION_ASM_OP
108 #ifdef OBJECT_FORMAT_ELF
110 /* Run all the global destructors on exit from the program. */
112 /* Some systems place the number of pointers in the first word of the
113 table. On SVR4 however, that word is -1. In all cases, the table is
114 null-terminated. On SVR4, we start from the beginning of the list and
115 invoke each per-compilation-unit destructor routine in order
116 until we find that null.
118 Note that this function MUST be static. There will be one of these
119 functions in each root executable and one in each shared library, but
120 although they all have the same code, each one is unique in that it
121 refers to one particular associated `__DTOR_LIST__' which belongs to the
122 same particular root executable or shared library file.
124 On some systems, this routine is run more than once from the .fini,
125 when exit is called recursively, so we arrange to remember where in
126 the list we left off processing, and we resume at that point,
127 should we be re-invoked. */
129 static char __EH_FRAME_BEGIN__[];
130 static func_ptr __DTOR_LIST__[];
131 static void
132 __do_global_dtors_aux ()
134 static func_ptr *p = __DTOR_LIST__ + 1;
135 static int completed = 0;
137 if (completed)
138 return;
140 while (*p)
142 p++;
143 (*(p-1)) ();
146 #ifdef EH_FRAME_SECTION_ASM_OP
147 __deregister_frame_info (__EH_FRAME_BEGIN__);
148 #endif
149 completed = 1;
153 /* Stick a call to __do_global_dtors_aux into the .fini section. */
155 static void __attribute__ ((__unused__))
156 fini_dummy ()
158 asm (FINI_SECTION_ASM_OP);
159 __do_global_dtors_aux ();
160 #ifdef FORCE_FINI_SECTION_ALIGN
161 FORCE_FINI_SECTION_ALIGN;
162 #endif
163 asm (TEXT_SECTION_ASM_OP);
166 #ifdef EH_FRAME_SECTION_ASM_OP
167 /* Stick a call to __register_frame_info into the .init section. For some
168 reason calls with no arguments work more reliably in .init, so stick the
169 call in another function. */
171 static void
172 frame_dummy ()
174 static struct object object;
175 __register_frame_info (__EH_FRAME_BEGIN__, &object);
178 static void __attribute__ ((__unused__))
179 init_dummy ()
181 asm (INIT_SECTION_ASM_OP);
182 frame_dummy ();
183 #ifdef FORCE_INIT_SECTION_ALIGN
184 FORCE_INIT_SECTION_ALIGN;
185 #endif
186 asm (TEXT_SECTION_ASM_OP);
188 #endif /* EH_FRAME_SECTION_ASM_OP */
190 #else /* OBJECT_FORMAT_ELF */
192 /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
193 and once in crtend.o). It must be declared static to avoid a link
194 error. Here, we define __do_global_ctors as an externally callable
195 function. It is externally callable so that __main can invoke it when
196 INVOKE__main is defined. This has the additional effect of forcing cc1
197 to switch to the .text section. */
199 static void __do_global_ctors_aux ();
200 void __do_global_ctors ()
202 #ifdef INVOKE__main /* If __main won't actually call __do_global_ctors
203 then it doesn't matter what's inside the function.
204 The inside of __do_global_ctors_aux is called
205 automatically in that case.
206 And the Alliant fx2800 linker crashes
207 on this reference. So prevent the crash. */
208 __do_global_ctors_aux ();
209 #endif
212 asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
214 /* On some svr4 systems, the initial .init section preamble code provided in
215 crti.o may do something, such as bump the stack, which we have to
216 undo before we reach the function prologue code for __do_global_ctors
217 (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE
218 to expand into the code needed to undo the actions of the crti.o file. */
220 #ifdef INIT_SECTION_PREAMBLE
221 INIT_SECTION_PREAMBLE;
222 #endif
224 /* A routine to invoke all of the global constructors upon entry to the
225 program. We put this into the .init section (for systems that have
226 such a thing) so that we can properly perform the construction of
227 file-scope static-storage C++ objects within shared libraries. */
229 static void
230 __do_global_ctors_aux () /* prologue goes in .init section */
232 #ifdef FORCE_INIT_SECTION_ALIGN
233 FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */
234 #endif
235 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */
236 DO_GLOBAL_CTORS_BODY;
237 ON_EXIT (__do_global_dtors, 0);
240 #endif /* OBJECT_FORMAT_ELF */
242 #else /* defined(INIT_SECTION_ASM_OP) */
244 #ifdef HAS_INIT_SECTION
245 /* This case is used by the Irix 6 port, which supports named sections but
246 not an SVR4-style .fini section. __do_global_dtors can be non-static
247 in this case because we protect it with -hidden_symbol. */
249 static char __EH_FRAME_BEGIN__[];
250 static func_ptr __DTOR_LIST__[];
251 void
252 __do_global_dtors ()
254 func_ptr *p;
255 for (p = __DTOR_LIST__ + 1; *p; p++)
256 (*p) ();
258 #ifdef EH_FRAME_SECTION_ASM_OP
259 __deregister_frame_info (__EH_FRAME_BEGIN__);
260 #endif
263 #ifdef EH_FRAME_SECTION_ASM_OP
264 /* Define a function here to call __register_frame. crtend.o is linked in
265 after libgcc.a, and hence can't call libgcc.a functions directly. That
266 can lead to unresolved function references. */
267 void
268 __frame_dummy ()
270 static struct object object;
271 __register_frame_info (__EH_FRAME_BEGIN__, &object);
273 #endif
274 #endif
276 #endif /* defined(INIT_SECTION_ASM_OP) */
278 /* Force cc1 to switch to .data section. */
279 static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { };
281 /* NOTE: In order to be able to support SVR4 shared libraries, we arrange
282 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
283 __DTOR_END__ } per root executable and also one set of these symbols
284 per shared library. So in any given whole process image, we may have
285 multiple definitions of each of these symbols. In order to prevent
286 these definitions from conflicting with one another, and in order to
287 ensure that the proper lists are used for the initialization/finalization
288 of each individual shared library (respectively), we give these symbols
289 only internal (i.e. `static') linkage, and we also make it a point to
290 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
291 symbol in crtbegin.o, where they are defined. */
293 /* The -1 is a flag to __do_global_[cd]tors
294 indicating that this table does not start with a count of elements. */
295 #ifdef CTOR_LIST_BEGIN
296 CTOR_LIST_BEGIN;
297 #else
298 asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
299 STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__))
300 = { (func_ptr) (-1) };
301 #endif
303 #ifdef DTOR_LIST_BEGIN
304 DTOR_LIST_BEGIN;
305 #else
306 asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
307 STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
308 #endif
310 #ifdef EH_FRAME_SECTION_ASM_OP
311 /* Stick a label at the beginning of the frame unwind info so we can register
312 and deregister it with the exception handling library code. */
314 asm (EH_FRAME_SECTION_ASM_OP);
315 #ifdef INIT_SECTION_ASM_OP
316 STATIC
317 #endif
318 char __EH_FRAME_BEGIN__[] = { };
319 #endif /* EH_FRAME_SECTION_ASM_OP */
321 #endif /* defined(CRT_BEGIN) */
323 #ifdef CRT_END
325 #ifdef INIT_SECTION_ASM_OP
327 #ifdef OBJECT_FORMAT_ELF
329 static func_ptr __CTOR_END__[];
330 static void
331 __do_global_ctors_aux ()
333 func_ptr *p;
334 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
335 (*p) ();
338 /* Stick a call to __do_global_ctors_aux into the .init section. */
340 static void __attribute__ ((__unused__))
341 init_dummy ()
343 asm (INIT_SECTION_ASM_OP);
344 __do_global_ctors_aux ();
345 #ifdef FORCE_INIT_SECTION_ALIGN
346 FORCE_INIT_SECTION_ALIGN;
347 #endif
348 asm (TEXT_SECTION_ASM_OP);
350 /* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr,
351 __environ and atexit (). We have to make sure they are in the .dynsym
352 section. We accomplish it by making a dummy call here. This
353 code is never reached. */
355 #if defined(__linux__) && defined(__PIC__) && defined(__i386__)
357 extern void *___brk_addr;
358 extern char **__environ;
360 ___brk_addr = __environ;
361 atexit ();
363 #endif
366 #else /* OBJECT_FORMAT_ELF */
368 /* Stick the real initialization code, followed by a normal sort of
369 function epilogue at the very end of the .init section for this
370 entire root executable file or for this entire shared library file.
372 Note that we use some tricks here to get *just* the body and just
373 a function epilogue (but no function prologue) into the .init
374 section of the crtend.o file. Specifically, we switch to the .text
375 section, start to define a function, and then we switch to the .init
376 section just before the body code.
378 Earlier on, we put the corresponding function prologue into the .init
379 section of the crtbegin.o file (which will be linked in first).
381 Note that we want to invoke all constructors for C++ file-scope static-
382 storage objects AFTER any other possible initialization actions which
383 may be performed by the code in the .init section contributions made by
384 other libraries, etc. That's because those other initializations may
385 include setup operations for very primitive things (e.g. initializing
386 the state of the floating-point coprocessor, etc.) which should be done
387 before we start to execute any of the user's code. */
389 static void
390 __do_global_ctors_aux () /* prologue goes in .text section */
392 asm (INIT_SECTION_ASM_OP);
393 DO_GLOBAL_CTORS_BODY;
394 ON_EXIT (__do_global_dtors, 0);
395 } /* epilogue and body go in .init section */
397 #ifdef FORCE_INIT_SECTION_ALIGN
398 FORCE_INIT_SECTION_ALIGN;
399 #endif
401 asm (TEXT_SECTION_ASM_OP);
403 #endif /* OBJECT_FORMAT_ELF */
405 #else /* defined(INIT_SECTION_ASM_OP) */
407 #ifdef HAS_INIT_SECTION
408 /* This case is used by the Irix 6 port, which supports named sections but
409 not an SVR4-style .init section. __do_global_ctors can be non-static
410 in this case because we protect it with -hidden_symbol. */
411 static func_ptr __CTOR_END__[];
412 #ifdef EH_FRAME_SECTION_ASM_OP
413 extern void __frame_dummy (void);
414 #endif
415 void
416 __do_global_ctors ()
418 func_ptr *p;
419 #ifdef EH_FRAME_SECTION_ASM_OP
420 __frame_dummy ();
421 #endif
422 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
423 (*p) ();
425 #endif
427 #endif /* defined(INIT_SECTION_ASM_OP) */
429 /* Force cc1 to switch to .data section. */
430 static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { };
432 /* Put a word containing zero at the end of each of our two lists of function
433 addresses. Note that the words defined here go into the .ctors and .dtors
434 sections of the crtend.o file, and since that file is always linked in
435 last, these words naturally end up at the very ends of the two lists
436 contained in these two sections. */
438 #ifdef CTOR_LIST_END
439 CTOR_LIST_END;
440 #else
441 asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
442 STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
443 #endif
445 #ifdef DTOR_LIST_END
446 DTOR_LIST_END;
447 #else
448 asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
449 STATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__))
450 = { (func_ptr) 0 };
451 #endif
453 #ifdef EH_FRAME_SECTION_ASM_OP
454 /* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
455 this would be the 'length' field in a real FDE. */
457 typedef unsigned int ui32 __attribute__ ((mode (SI)));
458 asm (EH_FRAME_SECTION_ASM_OP);
459 STATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
460 #endif /* EH_FRAME_SECTION */
462 #endif /* defined(CRT_END) */
464 #else /* OBJECT_FORMAT_MACHO */
466 /* For Mach-O format executables, we assume that the system's runtime is
467 smart enough to handle constructors and destructors, but doesn't have
468 an init section (if it can't even handle constructors/destructors
469 you should be using INVOKE__main, not crtstuff). All we need to do
470 is install/deinstall the frame information for exceptions. We do this
471 by putting a constructor in crtbegin.o and a destructor in crtend.o.
473 crtend.o also puts in the terminating zero in the frame information
474 segment. */
476 /* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__
477 to figure out the start of the exception frame, but here we use
478 getsectbynamefromheader to find this value. Either method would work,
479 but this method avoids creating any global symbols, which seems
480 cleaner. */
482 #include <mach-o/ldsyms.h>
483 extern const struct section *
484 getsectbynamefromheader (const struct mach_header *,
485 const char *, const char *);
487 #ifdef CRT_BEGIN
489 static void __reg_frame_ctor () __attribute__ ((constructor));
491 static void
492 __reg_frame_ctor ()
494 static struct object object;
495 const struct section *eh_frame;
497 eh_frame = getsectbynamefromheader (&_mh_execute_header,
498 "__TEXT", "__eh_frame");
499 __register_frame_info ((void *) eh_frame->addr, &object);
502 #endif /* CRT_BEGIN */
504 #ifdef CRT_END
506 static void __dereg_frame_dtor () __attribute__ ((destructor));
508 static
509 void __dereg_frame_dtor ()
511 const struct section *eh_frame;
513 eh_frame = getsectbynamefromheader (&_mh_execute_header,
514 "__TEXT", "__eh_frame");
515 __deregister_frame_info ((void *) eh_frame->addr);
518 /* Terminate the frame section with a final zero. */
520 /* Force cc1 to switch to .data section. */
521 static void * force_to_data[0] __attribute__ ((__unused__)) = { };
523 typedef unsigned int ui32 __attribute__ ((mode (SI)));
524 asm (EH_FRAME_SECTION_ASM_OP);
525 static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
527 #endif /* CRT_END */
529 #endif /* OBJECT_FORMAT_MACHO */