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