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