]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/crtstuff.c
Add myself under Write After Approval.
[thirdparty/gcc.git] / libgcc / crtstuff.c
CommitLineData
9d13f5c4 1/* Specialized bits of code needed to support construction and
2 destruction of file-scope objects in C++ code.
f1717362 3 Copyright (C) 1991-2016 Free Software Foundation, Inc.
31dcf09a 4 Contributed by Ron Guilmette (rfg@monkeys.com).
9d13f5c4 5
f12b58b3 6This file is part of GCC.
9d13f5c4 7
f12b58b3 8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
6bc9506f 10Software Foundation; either version 3, or (at your option) any later
f12b58b3 11version.
9d13f5c4 12
f12b58b3 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
9d13f5c4 17
6bc9506f 18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
9d13f5c4 26
23573244 27/* This file is a bit like libgcc2.c in that it is compiled
9d13f5c4 28 multiple times and yields multiple .o files.
29
30 This file is useful on target machines where the object file format
31 supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On
32 such systems, this file allows us to avoid running collect (or any
33 other such slow and painful kludge). Additionally, if the target
34 system supports a .init section, this file allows us to support the
35 linking of C++ code with a non-C++ main program.
36
37 Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then
38 this file *will* make use of the .init section. If that symbol is
39 not defined however, then the .init section will not be used.
40
5dd605c6 41 Currently, only ELF and COFF are supported. It is likely however that
42 ROSE could also be supported, if someone was willing to do the work to
43 make whatever (small?) adaptations are needed. (Some work may be
44 needed on the ROSE assembler and linker also.)
9d13f5c4 45
46 This file must be compiled with gcc. */
47
fece7655 48/* Target machine header files require this define. */
49#define IN_LIBGCC2
50
dd41a27b 51/* FIXME: Including auto-host is incorrect, but until we have
52 identified the set of defines that need to go into auto-target.h,
53 this will have to do. */
54#include "auto-host.h"
e3108d46 55#undef caddr_t
9ed5ef25 56#undef pid_t
57#undef rlim_t
58#undef ssize_t
9ed5ef25 59#undef vfork
d826737c 60#include "tconfig.h"
069631e1 61#include "tsystem.h"
805e22b2 62#include "coretypes.h"
63#include "tm.h"
022a2799 64#include "libgcc_tm.h"
df4b504c 65#include "unwind-dw2-fde.h"
9d13f5c4 66
e1ff7102 67#ifndef FORCE_CODE_SECTION_ALIGN
68# define FORCE_CODE_SECTION_ALIGN
69#endif
70
a815e00c 71#ifndef CRT_CALL_STATIC_FUNCTION
e1ff7102 72# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
73static void __attribute__((__used__)) \
74call_ ## FUNC (void) \
75{ \
76 asm (SECTION_OP); \
77 FUNC (); \
78 FORCE_CODE_SECTION_ALIGN \
325b8c3c 79 asm (__LIBGCC_TEXT_SECTION_ASM_OP__); \
e1ff7102 80}
a815e00c 81#endif
82
463553db 83#if defined(TARGET_DL_ITERATE_PHDR) && \
84 (defined(__DragonFly__) || defined(__FreeBSD__))
85#define BSD_DL_ITERATE_PHDR_AVAILABLE
86#endif
87
fb4bac8b 88#if defined(OBJECT_FORMAT_ELF) \
89 && !defined(OBJECT_FORMAT_FLAT) \
90 && defined(HAVE_LD_EH_FRAME_HDR) \
91 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
463553db 92 && defined(BSD_DL_ITERATE_PHDR_AVAILABLE)
fb4bac8b 93#include <link.h>
94# define USE_PT_GNU_EH_FRAME
95#endif
96
bdd793b2 97#if defined(OBJECT_FORMAT_ELF) \
98 && !defined(OBJECT_FORMAT_FLAT) \
99 && defined(HAVE_LD_EH_FRAME_HDR) && defined(TARGET_DL_ITERATE_PHDR) \
100 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
101 && defined(__sun__) && defined(__svr4__)
102#include <link.h>
103# define USE_PT_GNU_EH_FRAME
104#endif
105
f8200b2a 106#if defined(OBJECT_FORMAT_ELF) \
107 && !defined(OBJECT_FORMAT_FLAT) \
108 && defined(HAVE_LD_EH_FRAME_HDR) \
3cfa3aba 109 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \
0d6378a9 110 && defined(__GLIBC__) && __GLIBC__ >= 2
111#include <link.h>
b0c091c8 112/* uClibc pretends to be glibc 2.2 and DT_CONFIG is defined in its link.h.
113 But it doesn't use PT_GNU_EH_FRAME ELF segment currently. */
114# if !defined(__UCLIBC__) \
115 && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
0d6378a9 116 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
117# define USE_PT_GNU_EH_FRAME
118# endif
119#endif
93547515 120
121#if defined(OBJECT_FORMAT_ELF) \
122 && !defined(OBJECT_FORMAT_FLAT) \
123 && defined(HAVE_LD_EH_FRAME_HDR) \
124 && !defined(CRTSTUFFT_O) \
125 && defined(inhibit_libc) \
126 && (defined(__GLIBC__) || defined(__gnu_linux__) || defined(__GNU__))
127/* On systems using glibc, an inhibit_libc build of libgcc is only
128 part of a bootstrap process. Build the same crt*.o as would be
129 built with headers present, so that it is not necessary to build
130 glibc more than once for the bootstrap to converge. */
131# define USE_PT_GNU_EH_FRAME
132#endif
133
d0eb4a95 134#ifdef USE_EH_FRAME_REGISTRY_ALWAYS
135# ifndef __LIBGCC_EH_FRAME_SECTION_NAME__
136# error "Can't use explicit exception-frame-registration without __LIBGCC_EH_FRAME_SECTION_NAME__"
137# endif
138#endif
139#if defined(__LIBGCC_EH_FRAME_SECTION_NAME__) && (!defined(USE_PT_GNU_EH_FRAME) || defined(USE_EH_FRAME_REGISTRY_ALWAYS))
0d6378a9 140# define USE_EH_FRAME_REGISTRY
141#endif
325b8c3c 142#if defined(__LIBGCC_EH_FRAME_SECTION_NAME__) \
143 && __LIBGCC_EH_TABLES_CAN_BE_READ_ONLY__
d5720b0c 144# define EH_FRAME_SECTION_CONST const
145#else
146# define EH_FRAME_SECTION_CONST
147#endif
0d6378a9 148
f9e6c0d4 149#if !defined(DTOR_LIST_END) && defined(OBJECT_FORMAT_ELF) \
150 && defined(HAVE_GAS_HIDDEN) && !defined(FINI_ARRAY_SECTION_ASM_OP)
151# define HIDDEN_DTOR_LIST_END
152#endif
153
2d171408 154#if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF)
155# define USE_TM_CLONE_REGISTRY 1
156#endif
157
ee055d40 158/* We do not want to add the weak attribute to the declarations of these
df4b504c 159 routines in unwind-dw2-fde.h because that will cause the definition of
160 these symbols to be weak as well.
ee055d40 161
162 This exposes a core issue, how to handle creating weak references vs
163 how to create weak definitions. Either we have to have the definition
164 of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or
165 have a second declaration if we want a function's references to be weak,
166 but not its definition.
167
168 Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until
0c6d8c36 169 one thinks about scaling to larger problems -- i.e., the condition under
ee055d40 170 which TARGET_WEAK_ATTRIBUTE is active will eventually get far too
171 complicated.
172
173 So, we take an approach similar to #pragma weak -- we have a second
174 declaration for functions that we want to have weak references.
175
176 Neither way is particularly good. */
48e1416a 177
ee055d40 178/* References to __register_frame_info and __deregister_frame_info should
179 be weak in this file if at all possible. */
49856054 180extern void __register_frame_info (const void *, struct object *)
ee055d40 181 TARGET_ATTRIBUTE_WEAK;
49856054 182extern void __register_frame_info_bases (const void *, struct object *,
f6338f42 183 void *, void *)
184 TARGET_ATTRIBUTE_WEAK;
49856054 185extern void *__deregister_frame_info (const void *)
ee055d40 186 TARGET_ATTRIBUTE_WEAK;
49856054 187extern void *__deregister_frame_info_bases (const void *)
ce32d35f 188 TARGET_ATTRIBUTE_WEAK;
db0f4f32 189extern void __do_global_ctors_1 (void);
ee055d40 190
f313c0e1 191/* Likewise for _Jv_RegisterClasses. */
192extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
193
2d171408 194/* Likewise for transactional memory clone tables. */
195extern void _ITM_registerTMCloneTable (void *, size_t) TARGET_ATTRIBUTE_WEAK;
196extern void _ITM_deregisterTMCloneTable (void *) TARGET_ATTRIBUTE_WEAK;
197
b7c87ff2 198#ifdef OBJECT_FORMAT_ELF
199
200/* Declare a pointer to void function type. */
201typedef void (*func_ptr) (void);
202#define STATIC static
203
204#else /* OBJECT_FORMAT_ELF */
205
9d13f5c4 206#include "gbl-ctors.h"
207
b7c87ff2 208#define STATIC
209
210#endif /* OBJECT_FORMAT_ELF */
9d13f5c4 211
212#ifdef CRT_BEGIN
213
f313c0e1 214/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
215 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
216 __DTOR_END__ } per root executable and also one set of these symbols
217 per shared library. So in any given whole process image, we may have
218 multiple definitions of each of these symbols. In order to prevent
219 these definitions from conflicting with one another, and in order to
220 ensure that the proper lists are used for the initialization/finalization
221 of each individual shared library (respectively), we give these symbols
222 only internal (i.e. `static') linkage, and we also make it a point to
223 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
224 symbol in crtbegin.o, where they are defined. */
225
ef1da805 226/* No need for .ctors/.dtors section if linker can place them in
227 .init_array/.fini_array section. */
228#ifndef USE_INITFINI_ARRAY
f313c0e1 229/* The -1 is a flag to __do_global_[cd]tors indicating that this table
230 does not start with a count of elements. */
231#ifdef CTOR_LIST_BEGIN
232CTOR_LIST_BEGIN;
325b8c3c 233#elif defined(__LIBGCC_CTORS_SECTION_ASM_OP__)
f313c0e1 234/* Hack: force cc1 to switch to .data section early, so that assembling
235 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
796535a3 236static func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
325b8c3c 237asm (__LIBGCC_CTORS_SECTION_ASM_OP__);
f313c0e1 238STATIC func_ptr __CTOR_LIST__[1]
796535a3 239 __attribute__ ((__used__, aligned(sizeof(func_ptr))))
f313c0e1 240 = { (func_ptr) (-1) };
241#else
242STATIC func_ptr __CTOR_LIST__[1]
796535a3 243 __attribute__ ((__used__, section(".ctors"), aligned(sizeof(func_ptr))))
f313c0e1 244 = { (func_ptr) (-1) };
245#endif /* __CTOR_LIST__ alternatives */
246
247#ifdef DTOR_LIST_BEGIN
248DTOR_LIST_BEGIN;
325b8c3c 249#elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__)
250asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
f313c0e1 251STATIC func_ptr __DTOR_LIST__[1]
252 __attribute__ ((aligned(sizeof(func_ptr))))
253 = { (func_ptr) (-1) };
254#else
255STATIC func_ptr __DTOR_LIST__[1]
256 __attribute__((section(".dtors"), aligned(sizeof(func_ptr))))
257 = { (func_ptr) (-1) };
258#endif /* __DTOR_LIST__ alternatives */
ef1da805 259#endif /* USE_INITFINI_ARRAY */
f313c0e1 260
fabbeb08 261#ifdef USE_EH_FRAME_REGISTRY
f313c0e1 262/* Stick a label at the beginning of the frame unwind info so we can register
263 and deregister it with the exception handling library code. */
d5720b0c 264STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
325b8c3c 265 __attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4)))
f313c0e1 266 = { };
fabbeb08 267#endif /* USE_EH_FRAME_REGISTRY */
f313c0e1 268
2d171408 269#if USE_TM_CLONE_REGISTRY
270STATIC func_ptr __TMC_LIST__[]
d9ca835b 271 __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void*))))
2d171408 272 = { };
d9ca835b 273# ifdef HAVE_GAS_HIDDEN
2d171408 274extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden")));
d9ca835b 275# endif
276
277static inline void
278deregister_tm_clones (void)
279{
280 void (*fn) (void *);
281
282#ifdef HAVE_GAS_HIDDEN
7dbfd9e6 283 func_ptr *end = __TMC_END__;
284 // Do not optimize the comparison to false.
285 __asm ("" : "+g" (end));
286 if (__TMC_LIST__ == end)
d9ca835b 287 return;
288#else
289 if (__TMC_LIST__[0] == NULL)
290 return;
291#endif
292
293 fn = _ITM_deregisterTMCloneTable;
294 __asm ("" : "+r" (fn));
295 if (fn)
296 fn (__TMC_LIST__);
297}
298
299static inline void
300register_tm_clones (void)
301{
302 void (*fn) (void *, size_t);
303 size_t size;
304
305#ifdef HAVE_GAS_HIDDEN
7dbfd9e6 306 func_ptr *end = __TMC_END__;
307 // Do not optimize the comparison to false.
308 __asm ("" : "+g" (end));
309 size = (end - __TMC_LIST__) / 2;
d9ca835b 310#else
311 for (size = 0; __TMC_LIST__[size * 2] != NULL; size++)
312 continue;
313#endif
314 if (size == 0)
315 return;
316
317 fn = _ITM_registerTMCloneTable;
318 __asm ("" : "+r" (fn));
319 if (fn)
320 fn (__TMC_LIST__, size);
321}
2d171408 322#endif /* USE_TM_CLONE_REGISTRY */
323
325b8c3c 324#if defined(__LIBGCC_INIT_SECTION_ASM_OP__) \
325 || defined(__LIBGCC_INIT_ARRAY_SECTION_ASM_OP__)
584907e7 326
b7c87ff2 327#ifdef OBJECT_FORMAT_ELF
328
39b6af4b 329/* Declare the __dso_handle variable. It should have a unique value
5be729c9 330 in every shared-object; in a main program its value is zero. The
331 object should in any case be protected. This means the instance
332 in one DSO or the main program is not used in another object. The
333 dynamic linker takes care of this. */
334
91e8ab5c 335#ifdef TARGET_LIBGCC_SDATA_SECTION
336extern void *__dso_handle __attribute__ ((__section__ (TARGET_LIBGCC_SDATA_SECTION)));
337#endif
5be729c9 338#ifdef HAVE_GAS_HIDDEN
b4cf9ec1 339extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
5be729c9 340#endif
39b6af4b 341#ifdef CRTSTUFFS_O
342void *__dso_handle = &__dso_handle;
343#else
344void *__dso_handle = 0;
345#endif
346
347/* The __cxa_finalize function may not be available so we use only a
348 weak declaration. */
349extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK;
350
b7c87ff2 351/* Run all the global destructors on exit from the program. */
48e1416a 352
b7c87ff2 353/* Some systems place the number of pointers in the first word of the
354 table. On SVR4 however, that word is -1. In all cases, the table is
355 null-terminated. On SVR4, we start from the beginning of the list and
356 invoke each per-compilation-unit destructor routine in order
357 until we find that null.
358
359 Note that this function MUST be static. There will be one of these
360 functions in each root executable and one in each shared library, but
361 although they all have the same code, each one is unique in that it
362 refers to one particular associated `__DTOR_LIST__' which belongs to the
113f9ca7 363 same particular root executable or shared library file.
364
365 On some systems, this routine is run more than once from the .fini,
366 when exit is called recursively, so we arrange to remember where in
367 the list we left off processing, and we resume at that point,
368 should we be re-invoked. */
b7c87ff2 369
e1ff7102 370static void __attribute__((used))
aedb00bf 371__do_global_dtors_aux (void)
b7c87ff2 372{
d24bc145 373 static _Bool completed;
dade0711 374
f6338f42 375 if (__builtin_expect (completed, 0))
dade0711 376 return;
377
f4513b3d 378#ifdef CRTSTUFFS_O
379 if (__cxa_finalize)
39b6af4b 380 __cxa_finalize (__dso_handle);
f4513b3d 381#endif
39b6af4b 382
d24bc145 383#ifdef FINI_ARRAY_SECTION_ASM_OP
384 /* If we are using .fini_array then destructors will be run via that
385 mechanism. */
f9e6c0d4 386#elif defined(HIDDEN_DTOR_LIST_END)
387 {
388 /* Safer version that makes sure only .dtors function pointers are
389 called even if the static variable is maliciously changed. */
390 extern func_ptr __DTOR_END__[] __attribute__((visibility ("hidden")));
391 static size_t dtor_idx;
392 const size_t max_idx = __DTOR_END__ - __DTOR_LIST__ - 1;
06f29f53 393 func_ptr *dtor_list;
f9e6c0d4 394
06f29f53 395 __asm ("" : "=g" (dtor_list) : "0" (__DTOR_LIST__));
f9e6c0d4 396 while (dtor_idx < max_idx)
06f29f53 397 dtor_list[++dtor_idx] ();
f9e6c0d4 398 }
d24bc145 399#else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */
f9e6c0d4 400 {
401 static func_ptr *p = __DTOR_LIST__ + 1;
402 func_ptr f;
403
404 while ((f = *p))
405 {
406 p++;
407 f ();
408 }
409 }
d24bc145 410#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
d757b8c9 411
2d171408 412#if USE_TM_CLONE_REGISTRY
d9ca835b 413 deregister_tm_clones ();
2d171408 414#endif /* USE_TM_CLONE_REGISTRY */
415
0d6378a9 416#ifdef USE_EH_FRAME_REGISTRY
6fa2a5a8 417#ifdef CRT_GET_RFIB_DATA
ce32d35f 418 /* If we used the new __register_frame_info_bases interface,
419 make sure that we deregister from the same place. */
420 if (__deregister_frame_info_bases)
421 __deregister_frame_info_bases (__EH_FRAME_BEGIN__);
422#else
ee055d40 423 if (__deregister_frame_info)
424 __deregister_frame_info (__EH_FRAME_BEGIN__);
d757b8c9 425#endif
ce32d35f 426#endif
427
dade0711 428 completed = 1;
b7c87ff2 429}
430
431/* Stick a call to __do_global_dtors_aux into the .fini section. */
d24bc145 432#ifdef FINI_SECTION_ASM_OP
e1ff7102 433CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux)
a9a8ff12 434#elif defined (FINI_ARRAY_SECTION_ASM_OP)
d24bc145 435static func_ptr __do_global_dtors_aux_fini_array_entry[]
a41e0f2d 436 __attribute__ ((__used__, section(".fini_array"), aligned(sizeof(func_ptr))))
d24bc145 437 = { __do_global_dtors_aux };
a9a8ff12 438#else /* !FINI_SECTION_ASM_OP && !FINI_ARRAY_SECTION_ASM_OP */
439static void __attribute__((used))
440__do_global_dtors_aux_1 (void)
441{
442 atexit (__do_global_dtors_aux);
443}
325b8c3c 444CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__,
445 __do_global_dtors_aux_1)
a9a8ff12 446#endif
b7c87ff2 447
2d171408 448#if defined(USE_EH_FRAME_REGISTRY) \
2d171408 449 || defined(USE_TM_CLONE_REGISTRY)
c4fa4c4d 450/* Stick a call to __register_frame_info into the .init section. For some
451 reason calls with no arguments work more reliably in .init, so stick the
452 call in another function. */
d757b8c9 453
e1ff7102 454static void __attribute__((used))
aedb00bf 455frame_dummy (void)
d757b8c9 456{
0d6378a9 457#ifdef USE_EH_FRAME_REGISTRY
ad87de1e 458 static struct object object;
6fa2a5a8 459#ifdef CRT_GET_RFIB_DATA
f6338f42 460 void *tbase, *dbase;
f6338f42 461 tbase = 0;
f6338f42 462 CRT_GET_RFIB_DATA (dbase);
f6338f42 463 if (__register_frame_info_bases)
464 __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
465#else
ee055d40 466 if (__register_frame_info)
467 __register_frame_info (__EH_FRAME_BEGIN__, &object);
6fa2a5a8 468#endif /* CRT_GET_RFIB_DATA */
71fcebb2 469#endif /* USE_EH_FRAME_REGISTRY */
2d171408 470
2d171408 471#if USE_TM_CLONE_REGISTRY
d9ca835b 472 register_tm_clones ();
2d171408 473#endif /* USE_TM_CLONE_REGISTRY */
d757b8c9 474}
475
325b8c3c 476#ifdef __LIBGCC_INIT_SECTION_ASM_OP__
477CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, frame_dummy)
478#else /* defined(__LIBGCC_INIT_SECTION_ASM_OP__) */
d24bc145 479static func_ptr __frame_dummy_init_array_entry[]
a41e0f2d 480 __attribute__ ((__used__, section(".init_array"), aligned(sizeof(func_ptr))))
d24bc145 481 = { frame_dummy };
325b8c3c 482#endif /* !defined(__LIBGCC_INIT_SECTION_ASM_OP__) */
bc6b11a7 483#endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */
d757b8c9 484
b7c87ff2 485#else /* OBJECT_FORMAT_ELF */
486
b13ae905 487/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
d8fa92ab 488 and once in crtend.o). It must be declared static to avoid a link
b13ae905 489 error. Here, we define __do_global_ctors as an externally callable
490 function. It is externally callable so that __main can invoke it when
491 INVOKE__main is defined. This has the additional effect of forcing cc1
492 to switch to the .text section. */
a92771b8 493
205b5771 494static void __do_global_ctors_aux (void);
aedb00bf 495void
496__do_global_ctors (void)
84b64a19 497{
584907e7 498#ifdef INVOKE__main
499 /* If __main won't actually call __do_global_ctors then it doesn't matter
500 what's inside the function. The inside of __do_global_ctors_aux is
501 called automatically in that case. And the Alliant fx2800 linker
502 crashes on this reference. So prevent the crash. */
84b64a19 503 __do_global_ctors_aux ();
504#endif
505}
9d13f5c4 506
325b8c3c 507asm (__LIBGCC_INIT_SECTION_ASM_OP__); /* cc1 doesn't know that we are switching! */
9d13f5c4 508
509/* A routine to invoke all of the global constructors upon entry to the
510 program. We put this into the .init section (for systems that have
511 such a thing) so that we can properly perform the construction of
1e625a2e 512 file-scope static-storage C++ objects within shared libraries. */
9d13f5c4 513
e1ff7102 514static void __attribute__((used))
aedb00bf 515__do_global_ctors_aux (void) /* prologue goes in .init section */
9d13f5c4 516{
e1ff7102 517 FORCE_CODE_SECTION_ALIGN /* explicit align before switch to .text */
325b8c3c 518 asm (__LIBGCC_TEXT_SECTION_ASM_OP__); /* don't put epilogue and body in .init */
9d13f5c4 519 DO_GLOBAL_CTORS_BODY;
75d3a87b 520 atexit (__do_global_dtors);
9d13f5c4 521}
522
b7c87ff2 523#endif /* OBJECT_FORMAT_ELF */
8313a782 524
325b8c3c 525#elif defined(HAS_INIT_SECTION) /* ! __LIBGCC_INIT_SECTION_ASM_OP__ */
8313a782 526
eb7ed20c 527extern void __do_global_dtors (void);
528
8313a782 529/* This case is used by the Irix 6 port, which supports named sections but
530 not an SVR4-style .fini section. __do_global_dtors can be non-static
d757b8c9 531 in this case because we protect it with -hidden_symbol. */
532
8313a782 533void
aedb00bf 534__do_global_dtors (void)
8313a782 535{
f6338f42 536 func_ptr *p, f;
537 for (p = __DTOR_LIST__ + 1; (f = *p); p++)
538 f ();
d757b8c9 539
2d171408 540#if USE_TM_CLONE_REGISTRY
d9ca835b 541 deregister_tm_clones ();
2d171408 542#endif /* USE_TM_CLONE_REGISTRY */
543
0d6378a9 544#ifdef USE_EH_FRAME_REGISTRY
ee055d40 545 if (__deregister_frame_info)
546 __deregister_frame_info (__EH_FRAME_BEGIN__);
d757b8c9 547#endif
8313a782 548}
72ac783d 549
2d171408 550#if defined(USE_EH_FRAME_REGISTRY) \
2d171408 551 || defined(USE_TM_CLONE_REGISTRY)
584907e7 552/* A helper function for __do_global_ctors, which is in crtend.o. Here
553 in crtbegin.o, we can reference a couple of symbols not visible there.
554 Plus, since we're before libgcc.a, we have no problems referencing
555 functions from there. */
72ac783d 556void
584907e7 557__do_global_ctors_1(void)
72ac783d 558{
0d6378a9 559#ifdef USE_EH_FRAME_REGISTRY
72ac783d 560 static struct object object;
ee055d40 561 if (__register_frame_info)
562 __register_frame_info (__EH_FRAME_BEGIN__, &object);
b13ae905 563#endif
2d171408 564
2d171408 565#if USE_TM_CLONE_REGISTRY
d9ca835b 566 register_tm_clones ();
2d171408 567#endif /* USE_TM_CLONE_REGISTRY */
f313c0e1 568}
bc6b11a7 569#endif /* USE_EH_FRAME_REGISTRY || USE_TM_CLONE_REGISTRY */
2cee371f 570
325b8c3c 571#else /* ! __LIBGCC_INIT_SECTION_ASM_OP__ && ! HAS_INIT_SECTION */
584907e7 572#error "What are you doing with crtstuff.c, then?"
573#endif
574
575#elif defined(CRT_END) /* ! CRT_BEGIN */
576
ef1da805 577/* No need for .ctors/.dtors section if linker can place them in
578 .init_array/.fini_array section. */
579#ifndef USE_INITFINI_ARRAY
584907e7 580/* Put a word containing zero at the end of each of our two lists of function
581 addresses. Note that the words defined here go into the .ctors and .dtors
582 sections of the crtend.o file, and since that file is always linked in
583 last, these words naturally end up at the very ends of the two lists
584 contained in these two sections. */
585
586#ifdef CTOR_LIST_END
587CTOR_LIST_END;
325b8c3c 588#elif defined(__LIBGCC_CTORS_SECTION_ASM_OP__)
584907e7 589/* Hack: force cc1 to switch to .data section early, so that assembling
590 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */
796535a3 591static func_ptr force_to_data[1] __attribute__ ((__used__)) = { };
325b8c3c 592asm (__LIBGCC_CTORS_SECTION_ASM_OP__);
584907e7 593STATIC func_ptr __CTOR_END__[1]
594 __attribute__((aligned(sizeof(func_ptr))))
595 = { (func_ptr) 0 };
596#else
597STATIC func_ptr __CTOR_END__[1]
598 __attribute__((section(".ctors"), aligned(sizeof(func_ptr))))
599 = { (func_ptr) 0 };
600#endif
601
602#ifdef DTOR_LIST_END
603DTOR_LIST_END;
f9e6c0d4 604#elif defined(HIDDEN_DTOR_LIST_END)
325b8c3c 605#ifdef __LIBGCC_DTORS_SECTION_ASM_OP__
606asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
f9e6c0d4 607#endif
608func_ptr __DTOR_END__[1]
bc200246 609 __attribute__ ((used,
325b8c3c 610#ifndef __LIBGCC_DTORS_SECTION_ASM_OP__
f9e6c0d4 611 section(".dtors"),
612#endif
613 aligned(sizeof(func_ptr)), visibility ("hidden")))
614 = { (func_ptr) 0 };
325b8c3c 615#elif defined(__LIBGCC_DTORS_SECTION_ASM_OP__)
616asm (__LIBGCC_DTORS_SECTION_ASM_OP__);
584907e7 617STATIC func_ptr __DTOR_END__[1]
bc200246 618 __attribute__ ((used, aligned(sizeof(func_ptr))))
584907e7 619 = { (func_ptr) 0 };
620#else
621STATIC func_ptr __DTOR_END__[1]
bc200246 622 __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr))))
584907e7 623 = { (func_ptr) 0 };
624#endif
ef1da805 625#endif /* USE_INITFINI_ARRAY */
9d13f5c4 626
325b8c3c 627#ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
584907e7 628/* Terminate the frame unwind info section with a 4byte 0 as a sentinel;
629 this would be the 'length' field in a real FDE. */
743a6f47 630# if __INT_MAX__ == 2147483647
631typedef int int32;
632# elif __LONG_MAX__ == 2147483647
633typedef long int32;
634# elif __SHRT_MAX__ == 2147483647
635typedef short int32;
636# else
637# error "Missing a 4 byte integer"
638# endif
639STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[]
325b8c3c 640 __attribute__ ((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__),
743a6f47 641 aligned(sizeof(int32))))
584907e7 642 = { 0 };
325b8c3c 643#endif /* __LIBGCC_EH_FRAME_SECTION_NAME__ */
584907e7 644
2d171408 645#if USE_TM_CLONE_REGISTRY
d9ca835b 646# ifndef HAVE_GAS_HIDDEN
647static
648# endif
2d171408 649func_ptr __TMC_END__[]
d9ca835b 650 __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void *))))
651# ifdef HAVE_GAS_HIDDEN
652 __attribute__((__visibility__ ("hidden"))) = { };
653# else
654 = { 0, 0 };
655# endif
2d171408 656#endif /* USE_TM_CLONE_REGISTRY */
657
325b8c3c 658#ifdef __LIBGCC_INIT_ARRAY_SECTION_ASM_OP__
d24bc145 659
660/* If we are using .init_array, there is nothing to do. */
661
325b8c3c 662#elif defined(__LIBGCC_INIT_SECTION_ASM_OP__)
9d13f5c4 663
b7c87ff2 664#ifdef OBJECT_FORMAT_ELF
e1ff7102 665static void __attribute__((used))
aedb00bf 666__do_global_ctors_aux (void)
b7c87ff2 667{
668 func_ptr *p;
669 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
670 (*p) ();
671}
672
673/* Stick a call to __do_global_ctors_aux into the .init section. */
325b8c3c 674CRT_CALL_STATIC_FUNCTION (__LIBGCC_INIT_SECTION_ASM_OP__, __do_global_ctors_aux)
b7c87ff2 675#else /* OBJECT_FORMAT_ELF */
676
677/* Stick the real initialization code, followed by a normal sort of
678 function epilogue at the very end of the .init section for this
679 entire root executable file or for this entire shared library file.
680
681 Note that we use some tricks here to get *just* the body and just
682 a function epilogue (but no function prologue) into the .init
c3418f42 683 section of the crtend.o file. Specifically, we switch to the .text
b7c87ff2 684 section, start to define a function, and then we switch to the .init
685 section just before the body code.
686
687 Earlier on, we put the corresponding function prologue into the .init
688 section of the crtbegin.o file (which will be linked in first).
689
690 Note that we want to invoke all constructors for C++ file-scope static-
691 storage objects AFTER any other possible initialization actions which
692 may be performed by the code in the .init section contributions made by
693 other libraries, etc. That's because those other initializations may
694 include setup operations for very primitive things (e.g. initializing
695 the state of the floating-point coprocessor, etc.) which should be done
a92771b8 696 before we start to execute any of the user's code. */
9d13f5c4 697
698static void
aedb00bf 699__do_global_ctors_aux (void) /* prologue goes in .text section */
9d13f5c4 700{
325b8c3c 701 asm (__LIBGCC_INIT_SECTION_ASM_OP__);
9d13f5c4 702 DO_GLOBAL_CTORS_BODY;
75d3a87b 703 atexit (__do_global_dtors);
997d68fe 704} /* epilogue and body go in .init section */
705
e1ff7102 706FORCE_CODE_SECTION_ALIGN
325b8c3c 707asm (__LIBGCC_TEXT_SECTION_ASM_OP__);
9d13f5c4 708
b7c87ff2 709#endif /* OBJECT_FORMAT_ELF */
710
325b8c3c 711#elif defined(HAS_INIT_SECTION) /* ! __LIBGCC_INIT_SECTION_ASM_OP__ */
8313a782 712
eb7ed20c 713extern void __do_global_ctors (void);
714
8313a782 715/* This case is used by the Irix 6 port, which supports named sections but
716 not an SVR4-style .init section. __do_global_ctors can be non-static
d757b8c9 717 in this case because we protect it with -hidden_symbol. */
8313a782 718void
aedb00bf 719__do_global_ctors (void)
8313a782 720{
721 func_ptr *p;
2d171408 722#if defined(USE_EH_FRAME_REGISTRY) \
2d171408 723 || defined(USE_TM_CLONE_REGISTRY)
584907e7 724 __do_global_ctors_1();
d757b8c9 725#endif
8313a782 726 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
727 (*p) ();
728}
b7c87ff2 729
325b8c3c 730#else /* ! __LIBGCC_INIT_SECTION_ASM_OP__ && ! HAS_INIT_SECTION */
584907e7 731#error "What are you doing with crtstuff.c, then?"
b13ae905 732#endif
9d13f5c4 733
584907e7 734#else /* ! CRT_BEGIN && ! CRT_END */
735#error "One of CRT_BEGIN or CRT_END must be defined."
b13ae905 736#endif