crtstuff.c revision 50397
1/* Specialized bits of code needed to support construction and 2 destruction of file-scope objects in C++ code. 3 Copyright (C) 1991, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. 4 Contributed by Ron Guilmette (rfg@monkeys.com). 5 6This file is part of GNU CC. 7 8GNU CC is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 2, or (at your option) 11any later version. 12 13GNU CC is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with GNU CC; see the file COPYING. If not, write to 20the Free Software Foundation, 59 Temple Place - Suite 330, 21Boston, MA 02111-1307, USA. */ 22 23/* As a special exception, if you link this library with files 24 compiled with GCC to produce an executable, this does not cause 25 the resulting executable to be covered by the GNU General Public License. 26 This exception does not however invalidate any other reasons why 27 the executable file might be covered by the GNU General Public License. */ 28 29/* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled 30 multiple times and yields multiple .o files. 31 32 This file is useful on target machines where the object file format 33 supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On 34 such systems, this file allows us to avoid running collect (or any 35 other such slow and painful kludge). Additionally, if the target 36 system supports a .init section, this file allows us to support the 37 linking of C++ code with a non-C++ main program. 38 39 Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then 40 this file *will* make use of the .init section. If that symbol is 41 not defined however, then the .init section will not be used. 42 43 Currently, only ELF and COFF are supported. It is likely however that 44 ROSE could also be supported, if someone was willing to do the work to 45 make whatever (small?) adaptations are needed. (Some work may be 46 needed on the ROSE assembler and linker also.) 47 48 This file must be compiled with gcc. */ 49 50/* It is incorrect to include config.h here, because this file is being 51 compiled for the target, and hence definitions concerning only the host 52 do not apply. */ 53 54#include "tm.h" 55#include "defaults.h" 56#include <stddef.h> 57#include "frame.h" 58 59/* This really belongs in gansidecl.h, but for the egcs-1.1.x branch, the 60 only code which uses weak attributes is in this file and this file does 61 not include gansidecl.h. */ 62#ifndef TARGET_ATTRIBUTE_WEAK 63# if SUPPORTS_WEAK 64# define TARGET_ATTRIBUTE_WEAK __attribute__ ((weak)) 65# else 66# define TARGET_ATTRIBUTE_WEAK 67# endif 68#endif 69 70/* We do not want to add the weak attribute to the declarations of these 71 routines in frame.h because that will cause the definition of these 72 symbols to be weak as well. 73 74 This exposes a core issue, how to handle creating weak references vs 75 how to create weak definitions. Either we have to have the definition 76 of TARGET_WEAK_ATTRIBUTE be conditional in the shared header files or 77 have a second declaration if we want a function's references to be weak, 78 but not its definition. 79 80 Making TARGET_WEAK_ATTRIBUTE conditional seems like a good solution until 81 one thinks about scaling to larger problems -- ie, the condition under 82 which TARGET_WEAK_ATTRIBUTE is active will eventually get far too 83 complicated. 84 85 So, we take an approach similar to #pragma weak -- we have a second 86 declaration for functions that we want to have weak references. 87 88 Neither way is particularly good. */ 89 90/* References to __register_frame_info and __deregister_frame_info should 91 be weak in this file if at all possible. */ 92extern void __register_frame_info (void *, struct object *) 93 TARGET_ATTRIBUTE_WEAK; 94 95extern void *__deregister_frame_info (void *) 96 TARGET_ATTRIBUTE_WEAK; 97 98/* Provide default definitions for the pseudo-ops used to switch to the 99 .ctors and .dtors sections. 100 101 Note that we want to give these sections the SHF_WRITE attribute 102 because these sections will actually contain data (i.e. tables of 103 addresses of functions in the current root executable or shared library 104 file) and, in the case of a shared library, the relocatable addresses 105 will have to be properly resolved/relocated (and then written into) by 106 the dynamic linker when it actually attaches the given shared library 107 to the executing process. (Note that on SVR4, you may wish to use the 108 `-z text' option to the ELF linker, when building a shared library, as 109 an additional check that you are doing everything right. But if you do 110 use the `-z text' option when building a shared library, you will get 111 errors unless the .ctors and .dtors sections are marked as writable 112 via the SHF_WRITE attribute.) */ 113 114#ifndef CTORS_SECTION_ASM_OP 115#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" 116#endif 117#ifndef DTORS_SECTION_ASM_OP 118#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\"" 119#endif 120#if !defined (EH_FRAME_SECTION_ASM_OP) && defined (DWARF2_UNWIND_INFO) && defined(ASM_OUTPUT_SECTION_NAME) 121#define EH_FRAME_SECTION_ASM_OP ".section\t.eh_frame,\"aw\"" 122#endif 123 124#ifdef OBJECT_FORMAT_ELF 125 126/* Declare a pointer to void function type. */ 127typedef void (*func_ptr) (void); 128#define STATIC static 129 130#else /* OBJECT_FORMAT_ELF */ 131 132#include "gbl-ctors.h" 133 134#ifndef ON_EXIT 135#define ON_EXIT(a, b) 136#endif 137#define STATIC 138 139#endif /* OBJECT_FORMAT_ELF */ 140 141#ifdef CRT_BEGIN 142 143#ifdef INIT_SECTION_ASM_OP 144 145#ifdef OBJECT_FORMAT_ELF 146 147/* Run all the global destructors on exit from the program. */ 148 149/* Some systems place the number of pointers in the first word of the 150 table. On SVR4 however, that word is -1. In all cases, the table is 151 null-terminated. On SVR4, we start from the beginning of the list and 152 invoke each per-compilation-unit destructor routine in order 153 until we find that null. 154 155 Note that this function MUST be static. There will be one of these 156 functions in each root executable and one in each shared library, but 157 although they all have the same code, each one is unique in that it 158 refers to one particular associated `__DTOR_LIST__' which belongs to the 159 same particular root executable or shared library file. 160 161 On some systems, this routine is run more than once from the .fini, 162 when exit is called recursively, so we arrange to remember where in 163 the list we left off processing, and we resume at that point, 164 should we be re-invoked. */ 165 166static char __EH_FRAME_BEGIN__[]; 167static func_ptr __DTOR_LIST__[]; 168static void 169__do_global_dtors_aux () 170{ 171 static func_ptr *p = __DTOR_LIST__ + 1; 172 static int completed = 0; 173 174 if (completed) 175 return; 176 177 while (*p) 178 { 179 p++; 180 (*(p-1)) (); 181 } 182 183#ifdef EH_FRAME_SECTION_ASM_OP 184 if (__deregister_frame_info) 185 __deregister_frame_info (__EH_FRAME_BEGIN__); 186#endif 187 completed = 1; 188} 189 190 191/* Stick a call to __do_global_dtors_aux into the .fini section. */ 192 193static void __attribute__ ((__unused__)) 194fini_dummy () 195{ 196 asm (FINI_SECTION_ASM_OP); 197 __do_global_dtors_aux (); 198#ifdef FORCE_FINI_SECTION_ALIGN 199 FORCE_FINI_SECTION_ALIGN; 200#endif 201 asm (TEXT_SECTION_ASM_OP); 202} 203 204#ifdef EH_FRAME_SECTION_ASM_OP 205/* Stick a call to __register_frame_info into the .init section. For some 206 reason calls with no arguments work more reliably in .init, so stick the 207 call in another function. */ 208 209static void 210frame_dummy () 211{ 212 static struct object object; 213 if (__register_frame_info) 214 __register_frame_info (__EH_FRAME_BEGIN__, &object); 215} 216 217static void __attribute__ ((__unused__)) 218init_dummy () 219{ 220 asm (INIT_SECTION_ASM_OP); 221 frame_dummy (); 222#ifdef FORCE_INIT_SECTION_ALIGN 223 FORCE_INIT_SECTION_ALIGN; 224#endif 225 asm (TEXT_SECTION_ASM_OP); 226} 227#endif /* EH_FRAME_SECTION_ASM_OP */ 228 229#else /* OBJECT_FORMAT_ELF */ 230 231/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o 232 and once in crtend.o). It must be declared static to avoid a link 233 error. Here, we define __do_global_ctors as an externally callable 234 function. It is externally callable so that __main can invoke it when 235 INVOKE__main is defined. This has the additional effect of forcing cc1 236 to switch to the .text section. */ 237 238static void __do_global_ctors_aux (); 239void __do_global_ctors () 240{ 241#ifdef INVOKE__main /* If __main won't actually call __do_global_ctors 242 then it doesn't matter what's inside the function. 243 The inside of __do_global_ctors_aux is called 244 automatically in that case. 245 And the Alliant fx2800 linker crashes 246 on this reference. So prevent the crash. */ 247 __do_global_ctors_aux (); 248#endif 249} 250 251asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 252 253/* On some svr4 systems, the initial .init section preamble code provided in 254 crti.o may do something, such as bump the stack, which we have to 255 undo before we reach the function prologue code for __do_global_ctors 256 (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE 257 to expand into the code needed to undo the actions of the crti.o file. */ 258 259#ifdef INIT_SECTION_PREAMBLE 260 INIT_SECTION_PREAMBLE; 261#endif 262 263/* A routine to invoke all of the global constructors upon entry to the 264 program. We put this into the .init section (for systems that have 265 such a thing) so that we can properly perform the construction of 266 file-scope static-storage C++ objects within shared libraries. */ 267 268static void 269__do_global_ctors_aux () /* prologue goes in .init section */ 270{ 271#ifdef FORCE_INIT_SECTION_ALIGN 272 FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */ 273#endif 274 asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */ 275 DO_GLOBAL_CTORS_BODY; 276 ON_EXIT (__do_global_dtors, 0); 277} 278 279#endif /* OBJECT_FORMAT_ELF */ 280 281#else /* defined(INIT_SECTION_ASM_OP) */ 282 283#ifdef HAS_INIT_SECTION 284/* This case is used by the Irix 6 port, which supports named sections but 285 not an SVR4-style .fini section. __do_global_dtors can be non-static 286 in this case because we protect it with -hidden_symbol. */ 287 288static char __EH_FRAME_BEGIN__[]; 289static func_ptr __DTOR_LIST__[]; 290void 291__do_global_dtors () 292{ 293 func_ptr *p; 294 for (p = __DTOR_LIST__ + 1; *p; p++) 295 (*p) (); 296 297#ifdef EH_FRAME_SECTION_ASM_OP 298 if (__deregister_frame_info) 299 __deregister_frame_info (__EH_FRAME_BEGIN__); 300#endif 301} 302 303#ifdef EH_FRAME_SECTION_ASM_OP 304/* Define a function here to call __register_frame. crtend.o is linked in 305 after libgcc.a, and hence can't call libgcc.a functions directly. That 306 can lead to unresolved function references. */ 307void 308__frame_dummy () 309{ 310 static struct object object; 311 if (__register_frame_info) 312 __register_frame_info (__EH_FRAME_BEGIN__, &object); 313} 314#endif 315#endif 316 317#endif /* defined(INIT_SECTION_ASM_OP) */ 318 319/* Force cc1 to switch to .data section. */ 320static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { }; 321 322/* NOTE: In order to be able to support SVR4 shared libraries, we arrange 323 to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, 324 __DTOR_END__ } per root executable and also one set of these symbols 325 per shared library. So in any given whole process image, we may have 326 multiple definitions of each of these symbols. In order to prevent 327 these definitions from conflicting with one another, and in order to 328 ensure that the proper lists are used for the initialization/finalization 329 of each individual shared library (respectively), we give these symbols 330 only internal (i.e. `static') linkage, and we also make it a point to 331 refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ 332 symbol in crtbegin.o, where they are defined. */ 333 334/* The -1 is a flag to __do_global_[cd]tors 335 indicating that this table does not start with a count of elements. */ 336#ifdef CTOR_LIST_BEGIN 337CTOR_LIST_BEGIN; 338#else 339asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 340STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__)) 341 = { (func_ptr) (-1) }; 342#endif 343 344#ifdef DTOR_LIST_BEGIN 345DTOR_LIST_BEGIN; 346#else 347asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 348STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) }; 349#endif 350 351#ifdef EH_FRAME_SECTION_ASM_OP 352/* Stick a label at the beginning of the frame unwind info so we can register 353 and deregister it with the exception handling library code. */ 354 355asm (EH_FRAME_SECTION_ASM_OP); 356#ifdef INIT_SECTION_ASM_OP 357STATIC 358#endif 359char __EH_FRAME_BEGIN__[] = { }; 360#endif /* EH_FRAME_SECTION_ASM_OP */ 361 362#endif /* defined(CRT_BEGIN) */ 363 364#ifdef CRT_END 365 366#ifdef INIT_SECTION_ASM_OP 367 368#ifdef OBJECT_FORMAT_ELF 369 370static func_ptr __CTOR_END__[]; 371static void 372__do_global_ctors_aux () 373{ 374 func_ptr *p; 375 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 376 (*p) (); 377} 378 379/* Stick a call to __do_global_ctors_aux into the .init section. */ 380 381static void __attribute__ ((__unused__)) 382init_dummy () 383{ 384 asm (INIT_SECTION_ASM_OP); 385 __do_global_ctors_aux (); 386#ifdef FORCE_INIT_SECTION_ALIGN 387 FORCE_INIT_SECTION_ALIGN; 388#endif 389 asm (TEXT_SECTION_ASM_OP); 390 391/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr, 392 __environ and atexit (). We have to make sure they are in the .dynsym 393 section. We accomplish it by making a dummy call here. This 394 code is never reached. */ 395 396#if defined(__linux__) && defined(__PIC__) && defined(__i386__) 397 { 398 extern void *___brk_addr; 399 extern char **__environ; 400 401 ___brk_addr = __environ; 402 atexit (); 403 } 404#endif 405} 406 407#else /* OBJECT_FORMAT_ELF */ 408 409/* Stick the real initialization code, followed by a normal sort of 410 function epilogue at the very end of the .init section for this 411 entire root executable file or for this entire shared library file. 412 413 Note that we use some tricks here to get *just* the body and just 414 a function epilogue (but no function prologue) into the .init 415 section of the crtend.o file. Specifically, we switch to the .text 416 section, start to define a function, and then we switch to the .init 417 section just before the body code. 418 419 Earlier on, we put the corresponding function prologue into the .init 420 section of the crtbegin.o file (which will be linked in first). 421 422 Note that we want to invoke all constructors for C++ file-scope static- 423 storage objects AFTER any other possible initialization actions which 424 may be performed by the code in the .init section contributions made by 425 other libraries, etc. That's because those other initializations may 426 include setup operations for very primitive things (e.g. initializing 427 the state of the floating-point coprocessor, etc.) which should be done 428 before we start to execute any of the user's code. */ 429 430static void 431__do_global_ctors_aux () /* prologue goes in .text section */ 432{ 433 asm (INIT_SECTION_ASM_OP); 434 DO_GLOBAL_CTORS_BODY; 435 ON_EXIT (__do_global_dtors, 0); 436} /* epilogue and body go in .init section */ 437 438#ifdef FORCE_INIT_SECTION_ALIGN 439FORCE_INIT_SECTION_ALIGN; 440#endif 441 442asm (TEXT_SECTION_ASM_OP); 443 444#endif /* OBJECT_FORMAT_ELF */ 445 446#else /* defined(INIT_SECTION_ASM_OP) */ 447 448#ifdef HAS_INIT_SECTION 449/* This case is used by the Irix 6 port, which supports named sections but 450 not an SVR4-style .init section. __do_global_ctors can be non-static 451 in this case because we protect it with -hidden_symbol. */ 452static func_ptr __CTOR_END__[]; 453#ifdef EH_FRAME_SECTION_ASM_OP 454extern void __frame_dummy (void); 455#endif 456void 457__do_global_ctors () 458{ 459 func_ptr *p; 460#ifdef EH_FRAME_SECTION_ASM_OP 461 __frame_dummy (); 462#endif 463 for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) 464 (*p) (); 465} 466#endif 467 468#endif /* defined(INIT_SECTION_ASM_OP) */ 469 470/* Force cc1 to switch to .data section. */ 471static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { }; 472 473/* Put a word containing zero at the end of each of our two lists of function 474 addresses. Note that the words defined here go into the .ctors and .dtors 475 sections of the crtend.o file, and since that file is always linked in 476 last, these words naturally end up at the very ends of the two lists 477 contained in these two sections. */ 478 479#ifdef CTOR_LIST_END 480CTOR_LIST_END; 481#else 482asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 483STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 }; 484#endif 485 486#ifdef DTOR_LIST_END 487DTOR_LIST_END; 488#else 489asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ 490STATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__)) 491 = { (func_ptr) 0 }; 492#endif 493 494#ifdef EH_FRAME_SECTION_ASM_OP 495/* Terminate the frame unwind info section with a 4byte 0 as a sentinel; 496 this would be the 'length' field in a real FDE. */ 497 498typedef unsigned int ui32 __attribute__ ((mode (SI))); 499asm (EH_FRAME_SECTION_ASM_OP); 500STATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 }; 501#endif /* EH_FRAME_SECTION */ 502 503#endif /* defined(CRT_END) */ 504