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