]> gcc.gnu.org Git - gcc.git/blob - gcc/crtstuff.c
tsystem.h: New file.
[gcc.git] / gcc / crtstuff.c
1 /* Specialized bits of code needed to support construction and
2 destruction of file-scope objects in C++ code.
3 Copyright (C) 1991, 1994-1999, 2000 Free Software Foundation, Inc.
4 Contributed by Ron Guilmette (rfg@monkeys.com).
5
6 This file is part of GNU CC.
7
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.
12
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.
17
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. */
22
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. */
28
29 /* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled
30 multiple times and yields multiple .o files.
31
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.
38
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.
42
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.)
47
48 This file must be compiled with gcc. */
49
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. */
53
54 #include "tm.h"
55 #include "tsystem.h"
56
57 #include "defaults.h"
58 #include "frame.h"
59
60 /* We do not want to add the weak attribute to the declarations of these
61 routines in frame.h because that will cause the definition of these
62 symbols to be weak as well.
63
64 This exposes a core issue, how to handle creating weak references vs
65 how to create weak definitions. Either we have to have the definition
66 of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or
67 have a second declaration if we want a function's references to be weak,
68 but not its definition.
69
70 Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
71 one thinks about scaling to larger problems -- ie, the condition under
72 which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
73 complicated.
74
75 So, we take an approach similar to #pragma weak -- we have a second
76 declaration for functions that we want to have weak references.
77
78 Neither way is particularly good. */
79
80 /* References to __register_frame_info and __deregister_frame_info should
81 be weak in this file if at all possible. */
82 extern void __register_frame_info (void *, struct object *)
83 TARGET_ATTRIBUTE_WEAK;
84
85 extern void *__deregister_frame_info (void *)
86 TARGET_ATTRIBUTE_WEAK;
87
88 #ifndef OBJECT_FORMAT_MACHO
89
90 /* Provide default definitions for the pseudo-ops used to switch to the
91 .ctors and .dtors sections.
92
93 Note that we want to give these sections the SHF_WRITE attribute
94 because these sections will actually contain data (i.e. tables of
95 addresses of functions in the current root executable or shared library
96 file) and, in the case of a shared library, the relocatable addresses
97 will have to be properly resolved/relocated (and then written into) by
98 the dynamic linker when it actually attaches the given shared library
99 to the executing process. (Note that on SVR4, you may wish to use the
100 `-z text' option to the ELF linker, when building a shared library, as
101 an additional check that you are doing everything right. But if you do
102 use the `-z text' option when building a shared library, you will get
103 errors unless the .ctors and .dtors sections are marked as writable
104 via the SHF_WRITE attribute.) */
105
106 #ifndef CTORS_SECTION_ASM_OP
107 #define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
108 #endif
109 #ifndef DTORS_SECTION_ASM_OP
110 #define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
111 #endif
112
113 #ifdef OBJECT_FORMAT_ELF
114
115 /* Declare a pointer to void function type. */
116 typedef void (*func_ptr) (void);
117 #define STATIC static
118
119 #else /* OBJECT_FORMAT_ELF */
120
121 #include "gbl-ctors.h"
122
123 #define STATIC
124
125 #endif /* OBJECT_FORMAT_ELF */
126
127 #ifdef CRT_BEGIN
128
129 #ifdef INIT_SECTION_ASM_OP
130
131 #ifdef OBJECT_FORMAT_ELF
132
133 /* Declare the __dso_handle variable. It should have a unique value
134 in every shared-object; in a main program its value is zero. */
135
136 #ifdef CRTSTUFFS_O
137 void *__dso_handle = &__dso_handle;
138 #else
139 void *__dso_handle = 0;
140 #endif
141
142 /* The __cxa_finalize function may not be available so we use only a
143 weak declaration. */
144 extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
145
146 /* Run all the global destructors on exit from the program. */
147
148 /* Some systems place the number of pointers in the first word of the
149 table. On SVR4 however, that word is -1. In all cases, the table is
150 null-terminated. On SVR4, we start from the beginning of the list and
151 invoke each per-compilation-unit destructor routine in order
152 until we find that null.
153
154 Note that this function MUST be static. There will be one of these
155 functions in each root executable and one in each shared library, but
156 although they all have the same code, each one is unique in that it
157 refers to one particular associated `__DTOR_LIST__' which belongs to the
158 same particular root executable or shared library file.
159
160 On some systems, this routine is run more than once from the .fini,
161 when exit is called recursively, so we arrange to remember where in
162 the list we left off processing, and we resume at that point,
163 should we be re-invoked. */
164
165 static char __EH_FRAME_BEGIN__[];
166 static func_ptr __DTOR_LIST__[];
167 static void
168 __do_global_dtors_aux (void)
169 {
170 static func_ptr *p = __DTOR_LIST__ + 1;
171 static int completed = 0;
172
173 if (completed)
174 return;
175
176 #ifdef CRTSTUFFS_O
177 if (__cxa_finalize)
178 __cxa_finalize (__dso_handle);
179 #endif
180
181 while (*p)
182 {
183 p++;
184 (*(p-1)) ();
185 }
186
187 #ifdef EH_FRAME_SECTION_ASM_OP
188 if (__deregister_frame_info)
189 __deregister_frame_info (__EH_FRAME_BEGIN__);
190 #endif
191 completed = 1;
192 }
193
194
195 /* Stick a call to __do_global_dtors_aux into the .fini section. */
196
197 static void __attribute__ ((__unused__))
198 fini_dummy (void)
199 {
200 asm (FINI_SECTION_ASM_OP);
201 __do_global_dtors_aux ();
202 #ifdef FORCE_FINI_SECTION_ALIGN
203 FORCE_FINI_SECTION_ALIGN;
204 #endif
205 asm (TEXT_SECTION_ASM_OP);
206 }
207
208 #ifdef EH_FRAME_SECTION_ASM_OP
209 /* Stick a call to __register_frame_info into the .init section. For some
210 reason calls with no arguments work more reliably in .init, so stick the
211 call in another function. */
212
213 static void
214 frame_dummy (void)
215 {
216 static struct object object;
217 if (__register_frame_info)
218 __register_frame_info (__EH_FRAME_BEGIN__, &object);
219 }
220
221 static void __attribute__ ((__unused__))
222 init_dummy (void)
223 {
224 asm (INIT_SECTION_ASM_OP);
225 frame_dummy ();
226 #ifdef FORCE_INIT_SECTION_ALIGN
227 FORCE_INIT_SECTION_ALIGN;
228 #endif
229 asm (TEXT_SECTION_ASM_OP);
230 }
231 #endif /* EH_FRAME_SECTION_ASM_OP */
232
233 #else /* OBJECT_FORMAT_ELF */
234
235 /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
236 and once in crtend.o). It must be declared static to avoid a link
237 error. Here, we define __do_global_ctors as an externally callable
238 function. It is externally callable so that __main can invoke it when
239 INVOKE__main is defined. This has the additional effect of forcing cc1
240 to switch to the .text section. */
241
242 static void __do_global_ctors_aux ();
243 void
244 __do_global_ctors (void)
245 {
246 #ifdef INVOKE__main /* If __main won't actually call __do_global_ctors
247 then it doesn't matter what's inside the function.
248 The inside of __do_global_ctors_aux is called
249 automatically in that case.
250 And the Alliant fx2800 linker crashes
251 on this reference. So prevent the crash. */
252 __do_global_ctors_aux ();
253 #endif
254 }
255
256 asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
257
258 /* On some svr4 systems, the initial .init section preamble code provided in
259 crti.o may do something, such as bump the stack, which we have to
260 undo before we reach the function prologue code for __do_global_ctors
261 (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE
262 to expand into the code needed to undo the actions of the crti.o file. */
263
264 #ifdef INIT_SECTION_PREAMBLE
265 INIT_SECTION_PREAMBLE;
266 #endif
267
268 /* A routine to invoke all of the global constructors upon entry to the
269 program. We put this into the .init section (for systems that have
270 such a thing) so that we can properly perform the construction of
271 file-scope static-storage C++ objects within shared libraries. */
272
273 static void
274 __do_global_ctors_aux (void) /* prologue goes in .init section */
275 {
276 #ifdef FORCE_INIT_SECTION_ALIGN
277 FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */
278 #endif
279 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */
280 DO_GLOBAL_CTORS_BODY;
281 atexit (__do_global_dtors);
282 }
283
284 #endif /* OBJECT_FORMAT_ELF */
285
286 #else /* defined(INIT_SECTION_ASM_OP) */
287
288 #ifdef HAS_INIT_SECTION
289 /* This case is used by the Irix 6 port, which supports named sections but
290 not an SVR4-style .fini section. __do_global_dtors can be non-static
291 in this case because we protect it with -hidden_symbol. */
292
293 static char __EH_FRAME_BEGIN__[];
294 static func_ptr __DTOR_LIST__[];
295 void
296 __do_global_dtors (void)
297 {
298 func_ptr *p;
299 for (p = __DTOR_LIST__ + 1; *p; p++)
300 (*p) ();
301
302 #ifdef EH_FRAME_SECTION_ASM_OP
303 if (__deregister_frame_info)
304 __deregister_frame_info (__EH_FRAME_BEGIN__);
305 #endif
306 }
307
308 #ifdef EH_FRAME_SECTION_ASM_OP
309 /* Define a function here to call __register_frame. crtend.o is linked in
310 after libgcc.a, and hence can't call libgcc.a functions directly. That
311 can lead to unresolved function references. */
312 void
313 __frame_dummy (void)
314 {
315 static struct object object;
316 if (__register_frame_info)
317 __register_frame_info (__EH_FRAME_BEGIN__, &object);
318 }
319 #endif
320 #endif
321
322 #endif /* defined(INIT_SECTION_ASM_OP) */
323
324 /* Force cc1 to switch to .data section. */
325 static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { };
326
327 /* NOTE: In order to be able to support SVR4 shared libraries, we arrange
328 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
329 __DTOR_END__ } per root executable and also one set of these symbols
330 per shared library. So in any given whole process image, we may have
331 multiple definitions of each of these symbols. In order to prevent
332 these definitions from conflicting with one another, and in order to
333 ensure that the proper lists are used for the initialization/finalization
334 of each individual shared library (respectively), we give these symbols
335 only internal (i.e. `static') linkage, and we also make it a point to
336 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
337 symbol in crtbegin.o, where they are defined. */
338
339 /* The -1 is a flag to __do_global_[cd]tors
340 indicating that this table does not start with a count of elements. */
341 #ifdef CTOR_LIST_BEGIN
342 CTOR_LIST_BEGIN;
343 #else
344 asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
345 STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__))
346 = { (func_ptr) (-1) };
347 #endif
348
349 #ifdef DTOR_LIST_BEGIN
350 DTOR_LIST_BEGIN;
351 #else
352 asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
353 STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
354 #endif
355
356 #ifdef EH_FRAME_SECTION_ASM_OP
357 /* Stick a label at the beginning of the frame unwind info so we can register
358 and deregister it with the exception handling library code. */
359
360 asm (EH_FRAME_SECTION_ASM_OP);
361 #ifdef INIT_SECTION_ASM_OP
362 STATIC
363 #endif
364 char __EH_FRAME_BEGIN__[] = { };
365 #endif /* EH_FRAME_SECTION_ASM_OP */
366
367 #endif /* defined(CRT_BEGIN) */
368
369 #ifdef CRT_END
370
371 #ifdef INIT_SECTION_ASM_OP
372
373 #ifdef OBJECT_FORMAT_ELF
374
375 static func_ptr __CTOR_END__[];
376 static void
377 __do_global_ctors_aux (void)
378 {
379 func_ptr *p;
380 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
381 (*p) ();
382 }
383
384 /* Stick a call to __do_global_ctors_aux into the .init section. */
385
386 static void __attribute__ ((__unused__))
387 init_dummy (void)
388 {
389 asm (INIT_SECTION_ASM_OP);
390 __do_global_ctors_aux ();
391 #ifdef FORCE_INIT_SECTION_ALIGN
392 FORCE_INIT_SECTION_ALIGN;
393 #endif
394 asm (TEXT_SECTION_ASM_OP);
395
396 /* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr,
397 __environ and atexit (). We have to make sure they are in the .dynsym
398 section. We accomplish it by making a dummy call here. This
399 code is never reached. */
400
401 #if defined(__linux__) && defined(__PIC__) && defined(__i386__)
402 {
403 extern void *___brk_addr;
404 extern char **__environ;
405
406 ___brk_addr = __environ;
407 atexit (0);
408 }
409 #endif
410 }
411
412 #else /* OBJECT_FORMAT_ELF */
413
414 /* Stick the real initialization code, followed by a normal sort of
415 function epilogue at the very end of the .init section for this
416 entire root executable file or for this entire shared library file.
417
418 Note that we use some tricks here to get *just* the body and just
419 a function epilogue (but no function prologue) into the .init
420 section of the crtend.o file. Specifically, we switch to the .text
421 section, start to define a function, and then we switch to the .init
422 section just before the body code.
423
424 Earlier on, we put the corresponding function prologue into the .init
425 section of the crtbegin.o file (which will be linked in first).
426
427 Note that we want to invoke all constructors for C++ file-scope static-
428 storage objects AFTER any other possible initialization actions which
429 may be performed by the code in the .init section contributions made by
430 other libraries, etc. That's because those other initializations may
431 include setup operations for very primitive things (e.g. initializing
432 the state of the floating-point coprocessor, etc.) which should be done
433 before we start to execute any of the user's code. */
434
435 static void
436 __do_global_ctors_aux (void) /* prologue goes in .text section */
437 {
438 asm (INIT_SECTION_ASM_OP);
439 DO_GLOBAL_CTORS_BODY;
440 atexit (__do_global_dtors);
441 } /* epilogue and body go in .init section */
442
443 #ifdef FORCE_INIT_SECTION_ALIGN
444 FORCE_INIT_SECTION_ALIGN;
445 #endif
446
447 asm (TEXT_SECTION_ASM_OP);
448
449 #endif /* OBJECT_FORMAT_ELF */
450
451 #else /* defined(INIT_SECTION_ASM_OP) */
452
453 #ifdef HAS_INIT_SECTION
454 /* This case is used by the Irix 6 port, which supports named sections but
455 not an SVR4-style .init section. __do_global_ctors can be non-static
456 in this case because we protect it with -hidden_symbol. */
457 static func_ptr __CTOR_END__[];
458 #ifdef EH_FRAME_SECTION_ASM_OP
459 extern void __frame_dummy (void);
460 #endif
461 void
462 __do_global_ctors (void)
463 {
464 func_ptr *p;
465 #ifdef EH_FRAME_SECTION_ASM_OP
466 __frame_dummy ();
467 #endif
468 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
469 (*p) ();
470 }
471 #endif
472
473 #endif /* defined(INIT_SECTION_ASM_OP) */
474
475 /* Force cc1 to switch to .data section. */
476 static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { };
477
478 /* Put a word containing zero at the end of each of our two lists of function
479 addresses. Note that the words defined here go into the .ctors and .dtors
480 sections of the crtend.o file, and since that file is always linked in
481 last, these words naturally end up at the very ends of the two lists
482 contained in these two sections. */
483
484 #ifdef CTOR_LIST_END
485 CTOR_LIST_END;
486 #else
487 asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
488 STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
489 #endif
490
491 #ifdef DTOR_LIST_END
492 DTOR_LIST_END;
493 #else
494 asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
495 STATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__))
496 = { (func_ptr) 0 };
497 #endif
498
499 #ifdef EH_FRAME_SECTION_ASM_OP
500 /* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
501 this would be the 'length' field in a real FDE. */
502
503 typedef unsigned int ui32 __attribute__ ((mode (SI)));
504 asm (EH_FRAME_SECTION_ASM_OP);
505 STATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
506 #endif /* EH_FRAME_SECTION */
507
508 #endif /* defined(CRT_END) */
509
510 #else /* OBJECT_FORMAT_MACHO */
511
512 /* For Mach-O format executables, we assume that the system's runtime is
513 smart enough to handle constructors and destructors, but doesn't have
514 an init section (if it can't even handle constructors/destructors
515 you should be using INVOKE__main, not crtstuff). All we need to do
516 is install/deinstall the frame information for exceptions. We do this
517 by putting a constructor in crtbegin.o and a destructor in crtend.o.
518
519 crtend.o also puts in the terminating zero in the frame information
520 segment. */
521
522 /* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__
523 to figure out the start of the exception frame, but here we use
524 getsectbynamefromheader to find this value. Either method would work,
525 but this method avoids creating any global symbols, which seems
526 cleaner. */
527
528 #include <mach-o/ldsyms.h>
529 extern const struct section *
530 getsectbynamefromheader (const struct mach_header *,
531 const char *, const char *);
532
533 #ifdef CRT_BEGIN
534
535 static void __reg_frame_ctor () __attribute__ ((constructor));
536
537 static void
538 __reg_frame_ctor (void)
539 {
540 static struct object object;
541 const struct section *eh_frame;
542
543 eh_frame = getsectbynamefromheader (&_mh_execute_header,
544 "__TEXT", "__eh_frame");
545 __register_frame_info ((void *) eh_frame->addr, &object);
546 }
547
548 #endif /* CRT_BEGIN */
549
550 #ifdef CRT_END
551
552 static void __dereg_frame_dtor () __attribute__ ((destructor));
553
554 static
555 void
556 __dereg_frame_dtor (void)
557 {
558 const struct section *eh_frame;
559
560 eh_frame = getsectbynamefromheader (&_mh_execute_header,
561 "__TEXT", "__eh_frame");
562 __deregister_frame_info ((void *) eh_frame->addr);
563 }
564
565 /* Terminate the frame section with a final zero. */
566
567 /* Force cc1 to switch to .data section. */
568 static void * force_to_data[0] __attribute__ ((__unused__)) = { };
569
570 typedef unsigned int ui32 __attribute__ ((mode (SI)));
571 asm (EH_FRAME_SECTION_ASM_OP);
572 static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 };
573
574 #endif /* CRT_END */
575
576 #endif /* OBJECT_FORMAT_MACHO */
577
This page took 0.065016 seconds and 6 git commands to generate.