OSDN Git Service

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