crtstuff.c revision 96263
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 Free Software Foundation, Inc. 5 Contributed by Ron Guilmette (rfg@monkeys.com). 6 7This file is part of GCC. 8 9GCC is free software; you can redistribute it and/or modify it under 10the terms of the GNU General Public License as published by the Free 11Software Foundation; either version 2, or (at your option) any later 12version. 13 14In addition to the permissions in the GNU General Public License, the 15Free Software Foundation gives you unlimited permission to link the 16compiled version of this file into combinations with other programs, 17and to distribute those combinations without any restriction coming 18from the use of this file. (The General Public License restrictions 19do apply in other respects; for example, they cover modification of 20the file, and distribution when not linked into a combine 21executable.) 22 23GCC is distributed in the hope that it will be useful, but WITHOUT ANY 24WARRANTY; without even the implied warranty of MERCHANTABILITY or 25FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26for more details. 27 28You should have received a copy of the GNU General Public License 29along with GCC; see the file COPYING. If not, write to the Free 30Software Foundation, 59 Temple Place - Suite 330, Boston, MA 3102111-1307, 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/* It is incorrect to include config.h here, because this file is being 55 compiled for the target, and hence definitions concerning only the host 56 do not apply. */ 57 58/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is 59 supposedly valid even though this is a "target" file. */ 60#include "auto-host.h" 61#include "tconfig.h" 62#include "tsystem.h" 63#include "unwind-dw2-fde.h" 64 65#ifndef FORCE_CODE_SECTION_ALIGN 66# define FORCE_CODE_SECTION_ALIGN 67#endif 68 69#ifndef CRT_CALL_STATIC_FUNCTION 70# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ 71static void __attribute__((__used__)) \ 72call_ ## FUNC (void) \ 73{ \ 74 asm (SECTION_OP); \ 75 FUNC (); \ 76 FORCE_CODE_SECTION_ALIGN \ 77 asm (TEXT_SECTION_ASM_OP); \ 78} 79#endif 80 81#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \ 82 && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ 83 && defined(__GLIBC__) && __GLIBC__ >= 2 84#include <link.h> 85# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ 86 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) 87# define USE_PT_GNU_EH_FRAME 88# endif 89#endif 90#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME) 91# define USE_EH_FRAME_REGISTRY 92#endif 93 94/* We do not want to add the weak attribute to the declarations of these 95 routines in unwind-dw2-fde.h because that will cause the definition of 96 these symbols to be weak as well. 97 98 This exposes a core issue, how to handle creating weak references vs 99 how to create weak definitions. Either we have to have the definition 100 of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or 101 have a second declaration if we want a function's references to be weak, 102 but not its definition. 103 104 Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until 105 one thinks about scaling to larger problems -- ie, the condition under 106 which TARGET_WEAK_ATTRIBUTE is active will eventually get far too 107 complicated. 108 109 So, we take an approach similar to #pragma weak -- we have a second 110 declaration for functions that we want to have weak references. 111 112 Neither way is particularly good. */ 113 114/* References to __register_frame_info and __deregister_frame_info should 115 be weak in this file if at all possible. */ 116extern void __register_frame_info (void *, struct object *) 117 TARGET_ATTRIBUTE_WEAK; 118extern void __register_frame_info_bases (void *, struct object *, 119 void *, void *) 120 TARGET_ATTRIBUTE_WEAK; 121extern void *__deregister_frame_info (void *) 122 TARGET_ATTRIBUTE_WEAK; 123extern void *__deregister_frame_info_bases (void *) 124 TARGET_ATTRIBUTE_WEAK; 125 126/* Likewise for _Jv_RegisterClasses. */ 127extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK; 128 129#ifndef OBJECT_FORMAT_MACHO 130 131#ifdef OBJECT_FORMAT_ELF 132 133/* Declare a pointer to void function type. */ 134typedef void (*func_ptr) (void); 135#define STATIC static 136 137#else /* OBJECT_FORMAT_ELF */ 138 139#include "gbl-ctors.h" 140 141#define STATIC 142 143#endif /* OBJECT_FORMAT_ELF */ 144 145#ifdef CRT_BEGIN 146 147/* NOTE: In order to be able to support SVR4 shared libraries, we arrange 148 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, 149 __DTOR_END__ } per root executable and also one set of these symbols 150 per shared library. So in any given whole process image, we may have 151 multiple definitions of each of these symbols. In order to prevent 152 these definitions from conflicting with one another, and in order to 153 ensure that the proper lists are used for the initialization/finalization 154 of each individual shared library (respectively), we give these symbols 155 only internal (i.e. `static') linkage, and we also make it a point to 156 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ 157 symbol in crtbegin.o, where they are defined. */ 158 159/* The -1 is a flag to __do_global_[cd]tors indicating that this table 160 does not start with a count of elements. */ 161#ifdef CTOR_LIST_BEGIN 162CTOR_LIST_BEGIN; 163#elif defined(CTORS_SECTION_ASM_OP) 164/* Hack: force cc1 to switch to .data section early, so that assembling 165 __CTOR_LIST__ does not undo our behind-the-back change to .ctors. */ 166static func_ptr force_to_data[1] __attribute__ ((__unused__)) = { }; 167asm (CTORS_SECTION_ASM_OP); 168STATIC func_ptr __CTOR_LIST__[1] 169 __attribute__ ((__unused__, aligned(sizeof(func_ptr)))) 170 = { (func_ptr) (-1) }; 171#else 172STATIC func_ptr __CTOR_LIST__[1] 173 __attribute__ ((__unused__, section(".ctors"), aligned(sizeof(func_ptr)))) 174 = { (func_ptr) (-1) }; 175#endif /* __CTOR_LIST__ alternatives */ 176 177#ifdef DTOR_LIST_BEGIN 178DTOR_LIST_BEGIN; 179#elif defined(DTORS_SECTION_ASM_OP) 180asm (DTORS_SECTION_ASM_OP); 181STATIC func_ptr __DTOR_LIST__[1] 182 __attribute__ ((aligned(sizeof(func_ptr)))) 183 = { (func_ptr) (-1) }; 184#else 185STATIC func_ptr __DTOR_LIST__[1] 186 __attribute__((section(".dtors"), aligned(sizeof(func_ptr)))) 187 = { (func_ptr) (-1) }; 188#endif /* __DTOR_LIST__ alternatives */ 189 190#ifdef EH_FRAME_SECTION_NAME 191/* Stick a label at the beginning of the frame unwind info so we can register 192 and deregister it with the exception handling library code. */ 193STATIC char __EH_FRAME_BEGIN__[] 194 __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4))) 195 = { }; 196#endif /* EH_FRAME_SECTION_NAME */ 197 198#ifdef JCR_SECTION_NAME 199/* Stick a label at the beginning of the java class registration info 200 so we can register them properly. */ 201STATIC void *__JCR_LIST__[] 202 __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*)))) 203 = { }; 204#endif /* JCR_SECTION_NAME */ 205 206#ifdef INIT_SECTION_ASM_OP 207 208#ifdef OBJECT_FORMAT_ELF 209 210/* Declare the __dso_handle variable. It should have a unique value 211 in every shared-object; in a main program its value is zero. The 212 object should in any case be protected. This means the instance 213 in one DSO or the main program is not used in another object. The 214 dynamic linker takes care of this. */ 215 216/* XXX Ideally the following should be implemented using 217 __attribute__ ((__visibility__ ("hidden"))) 218 but the __attribute__ support is not yet there. */ 219#ifdef HAVE_GAS_HIDDEN 220asm (".hidden\t__dso_handle"); 221#endif 222 223#ifdef CRTSTUFFS_O 224void *__dso_handle = &__dso_handle; 225#else 226void *__dso_handle = 0; 227#endif 228 229/* The __cxa_finalize function may not be available so we use only a 230 weak declaration. */ 231extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK; 232 233/* Run all the global destructors on exit from the program. */ 234 235/* Some systems place the number of pointers in the first word of the 236 table. On SVR4 however, that word is -1. In all cases, the table is 237 null-terminated. On SVR4, we start from the beginning of the list and 238 invoke each per-compilation-unit destructor routine in order 239 until we find that null. 240 241 Note that this function MUST be static. There will be one of these 242 functions in each root executable and one in each shared library, but 243 although they all have the same code, each one is unique in that it 244 refers to one particular associated `__DTOR_LIST__' which belongs to the 245 same particular root executable or shared library file. 246 247 On some systems, this routine is run more than once from the .fini, 248 when exit is called recursively, so we arrange to remember where in 249 the list we left off processing, and we resume at that point, 250 should we be re-invoked. */ 251 252static void __attribute__((used)) 253__do_global_dtors_aux (void) 254{ 255 static func_ptr *p = __DTOR_LIST__ + 1; 256 static _Bool completed; 257 func_ptr f; 258 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