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