crtstuff.c revision 96489
182498Sroberto/* Specialized bits of code needed to support construction and 282498Sroberto destruction of file-scope objects in C++ code. 382498Sroberto Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998, 482498Sroberto 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 582498Sroberto Contributed by Ron Guilmette (rfg@monkeys.com). 682498Sroberto 782498SrobertoThis file is part of GCC. 882498Sroberto 982498SrobertoGCC is free software; you can redistribute it and/or modify it under 1082498Srobertothe terms of the GNU General Public License as published by the Free 1182498SrobertoSoftware Foundation; either version 2, or (at your option) any later 1282498Srobertoversion. 1382498Sroberto 1482498SrobertoIn addition to the permissions in the GNU General Public License, the 1582498SrobertoFree Software Foundation gives you unlimited permission to link the 1682498Srobertocompiled version of this file into combinations with other programs, 1782498Srobertoand to distribute those combinations without any restriction coming 1882498Srobertofrom the use of this file. (The General Public License restrictions 1982498Srobertodo apply in other respects; for example, they cover modification of 2082498Srobertothe file, and distribution when not linked into a combine 2182498Srobertoexecutable.) 2282498Sroberto 2382498SrobertoGCC is distributed in the hope that it will be useful, but WITHOUT ANY 2482498SrobertoWARRANTY; without even the implied warranty of MERCHANTABILITY or 2582498SrobertoFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2682498Srobertofor more details. 2782498Sroberto 2882498SrobertoYou should have received a copy of the GNU General Public License 2982498Srobertoalong with GCC; see the file COPYING. If not, write to the Free 3082498SrobertoSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 3182498Sroberto02111-1307, USA. */ 3282498Sroberto 3382498Sroberto/* This file is a bit like libgcc2.c in that it is compiled 3482498Sroberto multiple times and yields multiple .o files. 3582498Sroberto 3682498Sroberto This file is useful on target machines where the object file format 3782498Sroberto supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On 3882498Sroberto such systems, this file allows us to avoid running collect (or any 3982498Sroberto other such slow and painful kludge). Additionally, if the target 4082498Sroberto system supports a .init section, this file allows us to support the 4182498Sroberto linking of C++ code with a non-C++ main program. 4282498Sroberto 4382498Sroberto Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then 4482498Sroberto this file *will* make use of the .init section. If that symbol is 4582498Sroberto not defined however, then the .init section will not be used. 4682498Sroberto 4782498Sroberto Currently, only ELF and COFF are supported. It is likely however that 4882498Sroberto ROSE could also be supported, if someone was willing to do the work to 4982498Sroberto make whatever (small?) adaptations are needed. (Some work may be 5082498Sroberto needed on the ROSE assembler and linker also.) 51132451Sroberto 5282498Sroberto This file must be compiled with gcc. */ 5382498Sroberto 5482498Sroberto/* It is incorrect to include config.h here, because this file is being 5582498Sroberto compiled for the target, and hence definitions concerning only the host 5682498Sroberto do not apply. */ 5782498Sroberto 5882498Sroberto/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is 5982498Sroberto supposedly valid even though this is a "target" file. */ 6082498Sroberto#include "auto-host.h" 6182498Sroberto#include "tconfig.h" 6282498Sroberto#include "tsystem.h" 6382498Sroberto#include "unwind-dw2-fde.h" 6482498Sroberto 6582498Sroberto#ifndef FORCE_CODE_SECTION_ALIGN 6682498Sroberto# define FORCE_CODE_SECTION_ALIGN 6782498Sroberto#endif 6882498Sroberto 6982498Sroberto#ifndef CRT_CALL_STATIC_FUNCTION 7082498Sroberto# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ 7182498Srobertostatic void __attribute__((__used__)) \ 7282498Srobertocall_ ## FUNC (void) \ 7382498Sroberto{ \ 7482498Sroberto asm (SECTION_OP); \ 7582498Sroberto FUNC (); \ 7682498Sroberto FORCE_CODE_SECTION_ALIGN \ 7782498Sroberto asm (TEXT_SECTION_ASM_OP); \ 7882498Sroberto} 7982498Sroberto#endif 8082498Sroberto 8182498Sroberto#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \ 8282498Sroberto && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ 8382498Sroberto && defined(__GLIBC__) && __GLIBC__ >= 2 8482498Sroberto#include <link.h> 8582498Sroberto# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ 8682498Sroberto || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) 8782498Sroberto# define USE_PT_GNU_EH_FRAME 8882498Sroberto# endif 8982498Sroberto#endif 9082498Sroberto#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME) 9182498Sroberto# define USE_EH_FRAME_REGISTRY 9282498Sroberto#endif 9382498Sroberto 9482498Sroberto/* We do not want to add the weak attribute to the declarations of these 9582498Sroberto routines in unwind-dw2-fde.h because that will cause the definition of 9682498Sroberto these symbols to be weak as well. 9782498Sroberto 9882498Sroberto This exposes a core issue, how to handle creating weak references vs 9982498Sroberto how to create weak definitions. Either we have to have the definition 10082498Sroberto of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or 10182498Sroberto have a second declaration if we want a function's references to be weak, 10282498Sroberto but not its definition. 10382498Sroberto 10482498Sroberto Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until 10582498Sroberto one thinks about scaling to larger problems -- ie, the condition under 10682498Sroberto which TARGET_WEAK_ATTRIBUTE is active will eventually get far too 10782498Sroberto complicated. 10882498Sroberto 10982498Sroberto So, we take an approach similar to #pragma weak -- we have a second 11082498Sroberto declaration for functions that we want to have weak references. 11182498Sroberto 11282498Sroberto Neither way is particularly good. */ 11382498Sroberto 11482498Sroberto/* References to __register_frame_info and __deregister_frame_info should 11582498Sroberto be weak in this file if at all possible. */ 11682498Srobertoextern void __register_frame_info (void *, struct object *) 11782498Sroberto TARGET_ATTRIBUTE_WEAK; 11882498Srobertoextern void __register_frame_info_bases (void *, struct object *, 11982498Sroberto void *, void *) 12082498Sroberto TARGET_ATTRIBUTE_WEAK; 12182498Srobertoextern void *__deregister_frame_info (void *) 12282498Sroberto TARGET_ATTRIBUTE_WEAK; 12382498Srobertoextern void *__deregister_frame_info_bases (void *) 12482498Sroberto TARGET_ATTRIBUTE_WEAK; 12582498Sroberto 12682498Sroberto/* Likewise for _Jv_RegisterClasses. */ 127290000Sglebiusextern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK; 12882498Sroberto 12982498Sroberto#ifndef OBJECT_FORMAT_MACHO 13082498Sroberto 13182498Sroberto#ifdef OBJECT_FORMAT_ELF 13282498Sroberto 13382498Sroberto/* Declare a pointer to void function type. */ 134290000Sglebiustypedef void (*func_ptr) (void); 135290000Sglebius#define STATIC static 136290000Sglebius 13782498Sroberto#else /* OBJECT_FORMAT_ELF */ 13882498Sroberto 13982498Sroberto#include "gbl-ctors.h" 14082498Sroberto 14182498Sroberto#define STATIC 14282498Sroberto 143290000Sglebius#endif /* OBJECT_FORMAT_ELF */ 14482498Sroberto 145132451Sroberto#ifdef CRT_BEGIN 146290000Sglebius 14782498Sroberto/* NOTE: In order to be able to support SVR4 shared libraries, we arrange 14882498Sroberto to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, 14982498Sroberto __DTOR_END__ } per root executable and also one set of these symbols 15082498Sroberto per shared library. So in any given whole process image, we may have 15182498Sroberto multiple definitions of each of these symbols. In order to prevent 15282498Sroberto these definitions from conflicting with one another, and in order to 153290000Sglebius ensure that the proper lists are used for the initialization/finalization 154290000Sglebius of each individual shared library (respectively), we give these symbols 155290000Sglebius only internal (i.e. `static') linkage, and we also make it a point to 156290000Sglebius refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ 157290000Sglebius symbol in crtbegin.o, where they are defined. */ 158290000Sglebius 15982498Sroberto/* The -1 is a flag to __do_global_[cd]tors indicating that this table 16082498Sroberto does not start with a count of elements. */ 16182498Sroberto#ifdef CTOR_LIST_BEGIN 16282498SrobertoCTOR_LIST_BEGIN; 16382498Sroberto#elif defined(CTORS_SECTION_ASM_OP) 16482498Sroberto/* Hack: force cc1 to switch to .data section early, so that assembling 16582498Sroberto __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */ 16682498Srobertostatic func_ptr force_to_data[1] __attribute__ ((__unused__)) = { }; 16782498Srobertoasm (CTORS_SECTION_ASM_OP); 16882498SrobertoSTATIC func_ptr __CTOR_LIST__[1] 16982498Sroberto __attribute__ ((__unused__, aligned(sizeof(func_ptr)))) 17082498Sroberto = { (func_ptr) (-1) }; 17182498Sroberto#else 17282498SrobertoSTATIC func_ptr __CTOR_LIST__[1] 17382498Sroberto __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr)))) 17482498Sroberto = { (func_ptr) (-1) }; 17582498Sroberto#endif /* __CTOR_LIST__ alternatives */ 17682498Sroberto 177290000Sglebius#ifdef DTOR_LIST_BEGIN 178290000SglebiusDTOR_LIST_BEGIN; 17982498Sroberto#elif defined(DTORS_SECTION_ASM_OP) 18082498Srobertoasm (DTORS_SECTION_ASM_OP); 18182498SrobertoSTATIC func_ptr __DTOR_LIST__[1] 18282498Sroberto __attribute__ ((aligned(sizeof(func_ptr)))) 18382498Sroberto = { (func_ptr) (-1) }; 18482498Sroberto#else 18582498SrobertoSTATIC func_ptr __DTOR_LIST__[1] 18682498Sroberto __attribute__((section(".dtors"), aligned(sizeof(func_ptr)))) 18782498Sroberto = { (func_ptr) (-1) }; 18882498Sroberto#endif /* __DTOR_LIST__ alternatives */ 18982498Sroberto 19082498Sroberto#ifdef EH_FRAME_SECTION_NAME 19182498Sroberto/* Stick a label at the beginning of the frame unwind info so we can register 19282498Sroberto and deregister it with the exception handling library code. */ 19382498SrobertoSTATIC char __EH_FRAME_BEGIN__[] 19482498Sroberto __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4))) 19582498Sroberto = { }; 19682498Sroberto#endif /* EH_FRAME_SECTION_NAME */ 197290000Sglebius 198290000Sglebius#ifdef JCR_SECTION_NAME 199290000Sglebius/* Stick a label at the beginning of the java class registration info 20082498Sroberto so we can register them properly. */ 20182498SrobertoSTATIC void *__JCR_LIST__[] 20282498Sroberto __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*)))) 20382498Sroberto = { }; 20482498Sroberto#endif /* JCR_SECTION_NAME */ 20582498Sroberto 20682498Sroberto#ifdef INIT_SECTION_ASM_OP 20782498Sroberto 20882498Sroberto#ifdef OBJECT_FORMAT_ELF 209132451Sroberto 21082498Sroberto/* Declare the __dso_handle variable. It should have a unique value 21182498Sroberto in every shared-object; in a main program its value is zero. The 21282498Sroberto object should in any case be protected. This means the instance 21382498Sroberto in one DSO or the main program is not used in another object. The 21482498Sroberto dynamic linker takes care of this. */ 215290000Sglebius 216290000Sglebius/* XXX Ideally the following should be implemented using 217290000Sglebius __attribute__ ((__visibility__ ("hidden"))) 218290000Sglebius but the __attribute__ support is not yet there. */ 219290000Sglebius#ifdef HAVE_GAS_HIDDEN 220132451Srobertoasm (".hidden\t__dso_handle"); 22182498Sroberto#endif 22282498Sroberto 22382498Sroberto#ifdef CRTSTUFFS_O 22482498Srobertovoid *__dso_handle = &__dso_handle; 22582498Sroberto#else 22682498Srobertovoid *__dso_handle = 0; 22782498Sroberto#endif 22882498Sroberto 22982498Sroberto/* The __cxa_finalize function may not be available so we use only a 23082498Sroberto weak declaration. */ 23182498Srobertoextern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK; 23282498Sroberto 23382498Sroberto/* Run all the global destructors on exit from the program. */ 23482498Sroberto 23582498Sroberto/* Some systems place the number of pointers in the first word of the 23682498Sroberto table. On SVR4 however, that word is -1. In all cases, the table is 23782498Sroberto null-terminated. On SVR4, we start from the beginning of the list and 23882498Sroberto invoke each per-compilation-unit destructor routine in order 23982498Sroberto until we find that null. 24082498Sroberto 24182498Sroberto Note that this function MUST be static. There will be one of these 24282498Sroberto functions in each root executable and one in each shared library, but 24382498Sroberto although they all have the same code, each one is unique in that it 24482498Sroberto refers to one particular associated `__DTOR_LIST__' which belongs to the 24582498Sroberto same particular root executable or shared library file. 24682498Sroberto 24782498Sroberto On some systems, this routine is run more than once from the .fini, 24882498Sroberto when exit is called recursively, so we arrange to remember where in 24982498Sroberto the list we left off processing, and we resume at that point, 250132451Sroberto should we be re-invoked. */ 25182498Sroberto 25282498Srobertostatic void __attribute__((used)) 25382498Sroberto__do_global_dtors_aux (void) 25482498Sroberto{ 25582498Sroberto static func_ptr *p = __DTOR_LIST__ + 1; 25682498Sroberto static _Bool completed; 25782498Sroberto func_ptr f; 25882498Sroberto 259 if (__builtin_expect (completed, 0)) 260 return; 261 262#ifdef CRTSTUFFS_O 263 if (__cxa_finalize) 264 __cxa_finalize (__dso_handle); 265#endif 266 267 while ((f = *p)) 268 { 269 p++; 270 f (); 271 } 272 273#ifdef USE_EH_FRAME_REGISTRY 274#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA) 275 /* If we used the new __register_frame_info_bases interface, 276 make sure that we deregister from the same place. */ 277 if (__deregister_frame_info_bases) 278 __deregister_frame_info_bases (__EH_FRAME_BEGIN__); 279#else 280 if (__deregister_frame_info) 281 __deregister_frame_info (__EH_FRAME_BEGIN__); 282#endif 283#endif 284 285 completed = 1; 286} 287 288/* Stick a call to __do_global_dtors_aux into the .fini section. */ 289CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux) 290 291#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) 292/* Stick a call to __register_frame_info into the .init section. For some 293 reason calls with no arguments work more reliably in .init, so stick the 294 call in another function. */ 295 296static void __attribute__((used)) 297frame_dummy (void) 298{ 299#ifdef USE_EH_FRAME_REGISTRY 300 static struct object object; 301#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA) 302 void *tbase, *dbase; 303#ifdef CRT_GET_RFIB_TEXT 304 CRT_GET_RFIB_TEXT (tbase); 305#else 306 tbase = 0; 307#endif 308#ifdef CRT_GET_RFIB_DATA 309 CRT_GET_RFIB_DATA (dbase); 310#else 311 dbase = 0; 312#endif 313 if (__register_frame_info_bases) 314 __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase); 315#else 316 if (__register_frame_info) 317 __register_frame_info (__EH_FRAME_BEGIN__, &object); 318#endif 319#endif /* USE_EH_FRAME_REGISTRY */ 320#ifdef JCR_SECTION_NAME 321 if (__JCR_LIST__[0] && _Jv_RegisterClasses) 322 _Jv_RegisterClasses (__JCR_LIST__); 323#endif /* JCR_SECTION_NAME */ 324} 325 326CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy) 327#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */ 328 329#else /* OBJECT_FORMAT_ELF */ 330 331/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o 332 and once in crtend.o). It must be declared static to avoid a link 333 error. Here, we define __do_global_ctors as an externally callable 334 function. It is externally callable so that __main can invoke it when 335 INVOKE__main is defined. This has the additional effect of forcing cc1 336 to switch to the .text section. */ 337 338static void __do_global_ctors_aux (void); 339void 340__do_global_ctors (void) 341{ 342#ifdef INVOKE__main 343 /* If __main won't actually call __do_global_ctors then it doesn't matter 344 what's inside the function. The inside of __do_global_ctors_aux is 345 called automatically in that case. And the Alliant fx2800 linker 346 crashes on this reference. So prevent the crash. */ 347 __do_global_ctors_aux (); 348#endif 349} 350 351asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 352 353/* On some svr4 systems, the initial .init section preamble code provided in 354 crti.o may do something, such as bump the stack, which we have to 355 undo before we reach the function prologue code for __do_global_ctors 356 (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE 357 to expand into the code needed to undo the actions of the crti.o file. */ 358 359#ifdef INIT_SECTION_PREAMBLE 360 INIT_SECTION_PREAMBLE; 361#endif 362 363/* A routine to invoke all of the global constructors upon entry to the 364 program. We put this into the .init section (for systems that have 365 such a thing) so that we can properly perform the construction of 366 file-scope static-storage C++ objects within shared libraries. */ 367 368static void __attribute__((used)) 369__do_global_ctors_aux (void) /* prologue goes in .init section */ 370{ 371 FORCE_CODE_SECTION_ALIGN /* explicit align before switch to .text */ 372 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */ 373 DO_GLOBAL_CTORS_BODY; 374 atexit (__do_global_dtors); 375} 376 377#endif /* OBJECT_FORMAT_ELF */ 378 379#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */ 380 381/* This case is used by the Irix 6 port, which supports named sections but 382 not an SVR4-style .fini section. __do_global_dtors can be non-static 383 in this case because we protect it with -hidden_symbol. */ 384 385void 386__do_global_dtors (void) 387{ 388 func_ptr *p, f; 389 for (p = __DTOR_LIST__ + 1; (f = *p); p++) 390 f (); 391 392#ifdef USE_EH_FRAME_REGISTRY 393 if (__deregister_frame_info) 394 __deregister_frame_info (__EH_FRAME_BEGIN__); 395#endif 396} 397 398#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) 399/* A helper function for __do_global_ctors, which is in crtend.o. Here 400 in crtbegin.o, we can reference a couple of symbols not visible there. 401 Plus, since we're before libgcc.a, we have no problems referencing 402 functions from there. */ 403void 404__do_global_ctors_1(void) 405{ 406#ifdef USE_EH_FRAME_REGISTRY 407 static struct object object; 408 if (__register_frame_info) 409 __register_frame_info (__EH_FRAME_BEGIN__, &object); 410#endif 411#ifdef JCR_SECTION_NAME 412 if (__JCR_LIST__[0] && _Jv_RegisterClasses) 413 _Jv_RegisterClasses (__JCR_LIST__); 414#endif 415} 416#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */ 417 418#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ 419#error "What are you doing with crtstuff.c, then?" 420#endif 421 422#elif defined(CRT_END) /* ! CRT_BEGIN */ 423 424/* Put a word containing zero at the end of each of our two lists of function 425 addresses. Note that the words defined here go into the .ctors and .dtors 426 sections of the crtend.o file, and since that file is always linked in 427 last, these words naturally end up at the very ends of the two lists 428 contained in these two sections. */ 429 430#ifdef CTOR_LIST_END 431CTOR_LIST_END; 432#elif defined(CTORS_SECTION_ASM_OP) 433/* Hack: force cc1 to switch to .data section early, so that assembling 434 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */ 435static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { }; 436asm (CTORS_SECTION_ASM_OP); 437STATIC func_ptr __CTOR_END__[1] 438 __attribute__((aligned(sizeof(func_ptr)))) 439 = { (func_ptr) 0 }; 440#else 441STATIC func_ptr __CTOR_END__[1] 442 __attribute__((section(".ctors"), aligned(sizeof(func_ptr)))) 443 = { (func_ptr) 0 }; 444#endif 445 446#ifdef DTOR_LIST_END 447DTOR_LIST_END; 448#elif defined(DTORS_SECTION_ASM_OP) 449asm (DTORS_SECTION_ASM_OP); 450STATIC func_ptr __DTOR_END__[1] 451 __attribute__ ((unused, aligned(sizeof(func_ptr)))) 452 = { (func_ptr) 0 }; 453#else 454STATIC func_ptr __DTOR_END__[1] 455 __attribute__((unused, section(".dtors"), aligned(sizeof(func_ptr)))) 456 = { (func_ptr) 0 }; 457#endif 458 459#ifdef EH_FRAME_SECTION_NAME 460/* Terminate the frame unwind info section with a 4byte 0 as a sentinel; 461 this would be the 'length' field in a real FDE. */ 462STATIC int __FRAME_END__[] 463 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME), 464 aligned(4))) 465 = { 0 }; 466#endif /* EH_FRAME_SECTION_NAME */ 467 468#ifdef JCR_SECTION_NAME 469/* Null terminate the .jcr section array. */ 470STATIC void *__JCR_END__[1] 471 __attribute__ ((unused, section(JCR_SECTION_NAME), 472 aligned(sizeof(void *)))) 473 = { 0 }; 474#endif /* JCR_SECTION_NAME */ 475 476#ifdef INIT_SECTION_ASM_OP 477 478#ifdef OBJECT_FORMAT_ELF 479static void __attribute__((used)) 480__do_global_ctors_aux (void) 481{ 482 func_ptr *p; 483 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 484 (*p) (); 485} 486 487/* Stick a call to __do_global_ctors_aux into the .init section. */ 488CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux) 489#else /* OBJECT_FORMAT_ELF */ 490 491/* Stick the real initialization code, followed by a normal sort of 492 function epilogue at the very end of the .init section for this 493 entire root executable file or for this entire shared library file. 494 495 Note that we use some tricks here to get *just* the body and just 496 a function epilogue (but no function prologue) into the .init 497 section of the crtend.o file. Specifically, we switch to the .text 498 section, start to define a function, and then we switch to the .init 499 section just before the body code. 500 501 Earlier on, we put the corresponding function prologue into the .init 502 section of the crtbegin.o file (which will be linked in first). 503 504 Note that we want to invoke all constructors for C++ file-scope static- 505 storage objects AFTER any other possible initialization actions which 506 may be performed by the code in the .init section contributions made by 507 other libraries, etc. That's because those other initializations may 508 include setup operations for very primitive things (e.g. initializing 509 the state of the floating-point coprocessor, etc.) which should be done 510 before we start to execute any of the user's code. */ 511 512static void 513__do_global_ctors_aux (void) /* prologue goes in .text section */ 514{ 515 asm (INIT_SECTION_ASM_OP); 516 DO_GLOBAL_CTORS_BODY; 517 atexit (__do_global_dtors); 518} /* epilogue and body go in .init section */ 519 520FORCE_CODE_SECTION_ALIGN 521asm (TEXT_SECTION_ASM_OP); 522 523#endif /* OBJECT_FORMAT_ELF */ 524 525#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */ 526 527/* This case is used by the Irix 6 port, which supports named sections but 528 not an SVR4-style .init section. __do_global_ctors can be non-static 529 in this case because we protect it with -hidden_symbol. */ 530extern void __do_global_ctors_1(void); 531void 532__do_global_ctors (void) 533{ 534 func_ptr *p; 535#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) 536 __do_global_ctors_1(); 537#endif 538 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 539 (*p) (); 540} 541 542#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ 543#error "What are you doing with crtstuff.c, then?" 544#endif 545 546#else /* ! CRT_BEGIN && ! CRT_END */ 547#error "One of CRT_BEGIN or CRT_END must be defined." 548#endif 549 550#else /* OBJECT_FORMAT_MACHO */ 551 552/* For Mach-O format executables, we assume that the system's runtime is 553 smart enough to handle constructors and destructors, but doesn't have 554 an init section (if it can't even handle constructors/destructors 555 you should be using INVOKE__main, not crtstuff). All we need to do 556 is install/deinstall the frame information for exceptions. We do this 557 by putting a constructor in crtbegin.o and a destructor in crtend.o. 558 559 crtend.o also puts in the terminating zero in the frame information 560 segment. */ 561 562/* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__ 563 to figure out the start of the exception frame, but here we use 564 getsectbynamefromheader to find this value. Either method would work, 565 but this method avoids creating any global symbols, which seems 566 cleaner. */ 567 568#include <mach-o/ldsyms.h> 569extern const struct section * 570 getsectbynamefromheader (const struct mach_header *, 571 const char *, const char *); 572 573#ifdef CRT_BEGIN 574 575static void __reg_frame_ctor (void) __attribute__ ((constructor)); 576 577static void 578__reg_frame_ctor (void) 579{ 580 static struct object object; 581 const struct section *eh_frame; 582 583 eh_frame = getsectbynamefromheader (&_mh_execute_header, 584 "__TEXT", "__eh_frame"); 585 __register_frame_info ((void *) eh_frame->addr, &object); 586} 587 588#elif defined(CRT_END) 589 590static void __dereg_frame_dtor (void) __attribute__ ((destructor)); 591 592static void 593__dereg_frame_dtor (void) 594{ 595 const struct section *eh_frame; 596 597 eh_frame = getsectbynamefromheader (&_mh_execute_header, 598 "__TEXT", "__eh_frame"); 599 __deregister_frame_info ((void *) eh_frame->addr); 600} 601 602/* Terminate the frame section with a final zero. */ 603STATIC int __FRAME_END__[] 604 __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME), 605 aligned(4))) 606 = { 0 }; 607 608#else /* ! CRT_BEGIN && ! CRT_END */ 609#error "One of CRT_BEGIN or CRT_END must be defined." 610#endif 611 612#endif /* OBJECT_FORMAT_MACHO */ 613