Annotation of gcc/crtstuff.c, revision 1.1.1.6

1.1       root        1: /* Specialized bits of code needed to support construction and
                      2:    destruction of file-scope objects in C++ code.
                      3: 
1.1.1.5   root        4:    Written by Ron Guilmette ([email protected]) with help from Richard Stallman.
1.1       root        5: 
1.1.1.6 ! root        6: Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
1.1       root        7: 
                      8: This file is part of GNU CC.
                      9: 
                     10: GNU CC is free software; you can redistribute it and/or modify
                     11: it under the terms of the GNU General Public License as published by
                     12: the Free Software Foundation; either version 2, or (at your option)
                     13: any later version.
                     14: 
                     15: GNU CC is distributed in the hope that it will be useful,
                     16: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: GNU General Public License for more details.
                     19: 
                     20: You should have received a copy of the GNU General Public License
                     21: along with GNU CC; see the file COPYING.  If not, write to
1.1.1.6 ! root       22: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            23: Boston, MA 02111-1307, USA.  */
1.1       root       24: 
                     25: /* As a special exception, if you link this library with files
                     26:    compiled with GCC to produce an executable, this does not cause
                     27:    the resulting executable to be covered by the GNU General Public License.
                     28:    This exception does not however invalidate any other reasons why
                     29:    the executable file might be covered by the GNU General Public License.  */
                     30: 
                     31: /* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled
                     32:    multiple times and yields multiple .o files.
                     33: 
                     34:    This file is useful on target machines where the object file format
                     35:    supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE).  On
                     36:    such systems, this file allows us to avoid running collect (or any
                     37:    other such slow and painful kludge).  Additionally, if the target
                     38:    system supports a .init section, this file allows us to support the
                     39:    linking of C++ code with a non-C++ main program.
                     40: 
                     41:    Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then
                     42:    this file *will* make use of the .init section.  If that symbol is
                     43:    not defined however, then the .init section will not be used.
                     44: 
1.1.1.3   root       45:    Currently, only ELF and COFF are supported.  It is likely however that
                     46:    ROSE could also be supported, if someone was willing to do the work to
                     47:    make whatever (small?) adaptations are needed.  (Some work may be
                     48:    needed on the ROSE assembler and linker also.)
1.1       root       49: 
                     50:    This file must be compiled with gcc.  */
                     51: 
                     52: /* It is incorrect to include config.h here, because this file is being
                     53:    compiled for the target, and hence definitions concerning only the host
                     54:    do not apply.  */
                     55: 
                     56: #include "tm.h"
                     57: 
1.1.1.6 ! root       58: /* Provide default definitions for the pseudo-ops used to switch to the
        !            59:    .ctors and .dtors sections.
        !            60:  
        !            61:    Note that we want to give these sections the SHF_WRITE attribute
        !            62:    because these sections will actually contain data (i.e. tables of
        !            63:    addresses of functions in the current root executable or shared library
        !            64:    file) and, in the case of a shared library, the relocatable addresses
        !            65:    will have to be properly resolved/relocated (and then written into) by
        !            66:    the dynamic linker when it actually attaches the given shared library
        !            67:    to the executing process.  (Note that on SVR4, you may wish to use the
        !            68:    `-z text' option to the ELF linker, when building a shared library, as
        !            69:    an additional check that you are doing everything right.  But if you do
        !            70:    use the `-z text' option when building a shared library, you will get
        !            71:    errors unless the .ctors and .dtors sections are marked as writable
        !            72:    via the SHF_WRITE attribute.)  */
        !            73: 
1.1       root       74: #ifndef CTORS_SECTION_ASM_OP
1.1.1.6 ! root       75: #define CTORS_SECTION_ASM_OP   ".section\t.ctors,\"aw\""
1.1       root       76: #endif
                     77: #ifndef DTORS_SECTION_ASM_OP
1.1.1.6 ! root       78: #define DTORS_SECTION_ASM_OP   ".section\t.dtors,\"aw\""
1.1       root       79: #endif
                     80: 
1.1.1.6 ! root       81: #ifdef OBJECT_FORMAT_ELF
        !            82: 
        !            83: /*  Declare a pointer to void function type.  */
        !            84: typedef void (*func_ptr) (void);
        !            85: #define STATIC static
        !            86: 
        !            87: #else  /* OBJECT_FORMAT_ELF */
        !            88: 
1.1       root       89: #include "gbl-ctors.h"
                     90: 
1.1.1.2   root       91: #ifndef ON_EXIT
1.1       root       92: #define ON_EXIT(a, b)
                     93: #endif
1.1.1.6 ! root       94: #define STATIC
        !            95: 
        !            96: #endif /* OBJECT_FORMAT_ELF */
1.1       root       97: 
                     98: #ifdef CRT_BEGIN
                     99: 
                    100: #ifdef INIT_SECTION_ASM_OP
                    101: 
1.1.1.6 ! root      102: #ifdef OBJECT_FORMAT_ELF
        !           103: 
        !           104: /* Run all the global destructors on exit from the program.  */
        !           105:  
        !           106: /* Some systems place the number of pointers in the first word of the
        !           107:    table.  On SVR4 however, that word is -1.  In all cases, the table is
        !           108:    null-terminated.  On SVR4, we start from the beginning of the list and
        !           109:    invoke each per-compilation-unit destructor routine in order
        !           110:    until we find that null.
        !           111: 
        !           112:    Note that this function MUST be static.  There will be one of these
        !           113:    functions in each root executable and one in each shared library, but
        !           114:    although they all have the same code, each one is unique in that it
        !           115:    refers to one particular associated `__DTOR_LIST__' which belongs to the
        !           116:    same particular root executable or shared library file.  */
        !           117: 
        !           118: static func_ptr __DTOR_LIST__[];
        !           119: static void
        !           120: __do_global_dtors_aux ()
        !           121: {
        !           122:   func_ptr *p;
        !           123:   for (p = __DTOR_LIST__ + 1; *p; p++)
        !           124:     (*p) ();
        !           125: }
        !           126: 
        !           127: /* Stick a call to __do_global_dtors_aux into the .fini section.  */
        !           128: static void
        !           129: fini_dummy ()
        !           130: {
        !           131:   asm (FINI_SECTION_ASM_OP);
        !           132:   __do_global_dtors_aux ();
        !           133: #ifdef FORCE_FINI_SECTION_ALIGN
        !           134:   FORCE_FINI_SECTION_ALIGN;
        !           135: #endif
        !           136:   asm (TEXT_SECTION_ASM_OP);
        !           137: }
        !           138: 
        !           139: #else  /* OBJECT_FORMAT_ELF */
        !           140: 
1.1.1.2   root      141: /* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
1.1.1.3   root      142:    and once in crtend.o).  It must be declared static to avoid a link
1.1.1.2   root      143:    error.  Here, we define __do_global_ctors as an externally callable
                    144:    function.  It is externally callable so that __main can invoke it when
                    145:    INVOKE__main is defined.  This has the additional effect of forcing cc1
                    146:    to switch to the .text section.  */
                    147: static void __do_global_ctors_aux ();
1.1.1.3   root      148: void __do_global_ctors ()
                    149: {
                    150: #ifdef INVOKE__main  /* If __main won't actually call __do_global_ctors
                    151:                        then it doesn't matter what's inside the function.
                    152:                        The inside of __do_global_ctors_aux is called
                    153:                        automatically in that case.
                    154:                        And the Alliant fx2800 linker crashes
                    155:                        on this reference.  So prevent the crash.  */
                    156:   __do_global_ctors_aux ();
                    157: #endif
                    158: }
1.1       root      159: 
                    160: asm (INIT_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
                    161: 
1.1.1.6 ! root      162: /* On some svr4 systems, the initial .init section preamble code provided in
        !           163:    crti.o may do something, such as bump the stack, which we have to 
        !           164:    undo before we reach the function prologue code for __do_global_ctors 
        !           165:    (directly below).  For such systems, define the macro INIT_SECTION_PREAMBLE
        !           166:    to expand into the code needed to undo the actions of the crti.o file. */
        !           167: 
1.1.1.2   root      168: #ifdef INIT_SECTION_PREAMBLE
                    169:   INIT_SECTION_PREAMBLE;
                    170: #endif
                    171: 
1.1       root      172: /* A routine to invoke all of the global constructors upon entry to the
                    173:    program.  We put this into the .init section (for systems that have
                    174:    such a thing) so that we can properly perform the construction of
                    175:    file-scope static-storage C++ objects within shared libraries.   */
                    176: 
                    177: static void
1.1.1.2   root      178: __do_global_ctors_aux ()       /* prologue goes in .init section */
1.1       root      179: {
1.1.1.4   root      180: #ifdef FORCE_INIT_SECTION_ALIGN
                    181:   FORCE_INIT_SECTION_ALIGN;    /* Explicit align before switch to .text */
                    182: #endif
1.1       root      183:   asm (TEXT_SECTION_ASM_OP);   /* don't put epilogue and body in .init */
                    184:   DO_GLOBAL_CTORS_BODY;
1.1.1.2   root      185:   ON_EXIT (__do_global_dtors, 0);
1.1       root      186: }
                    187: 
1.1.1.6 ! root      188: #endif /* OBJECT_FORMAT_ELF */
1.1       root      189: #endif /* defined(INIT_SECTION_ASM_OP) */
                    190: 
                    191: /* Force cc1 to switch to .data section.  */
                    192: static func_ptr force_to_data[0] = { };
                    193: 
1.1.1.6 ! root      194: /* NOTE:  In order to be able to support SVR4 shared libraries, we arrange
        !           195:    to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
        !           196:    __DTOR_END__ } per root executable and also one set of these symbols
        !           197:    per shared library.  So in any given whole process image, we may have
        !           198:    multiple definitions of each of these symbols.  In order to prevent
        !           199:    these definitions from conflicting with one another, and in order to
        !           200:    ensure that the proper lists are used for the initialization/finalization
        !           201:    of each individual shared library (respectively), we give these symbols
        !           202:    only internal (i.e. `static') linkage, and we also make it a point to
        !           203:    refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
        !           204:    symbol in crtbegin.o, where they are defined.  */
        !           205: 
1.1       root      206: /* The -1 is a flag to __do_global_[cd]tors
                    207:    indicating that this table does not start with a count of elements.  */
1.1.1.2   root      208: #ifdef CTOR_LIST_BEGIN
                    209: CTOR_LIST_BEGIN;
                    210: #else
1.1       root      211: asm (CTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
1.1.1.6 ! root      212: STATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) };
1.1.1.2   root      213: #endif
1.1       root      214: 
1.1.1.2   root      215: #ifdef DTOR_LIST_BEGIN
                    216: DTOR_LIST_BEGIN;
                    217: #else
1.1       root      218: asm (DTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
1.1.1.6 ! root      219: STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
1.1.1.2   root      220: #endif
1.1       root      221: 
                    222: #endif /* defined(CRT_BEGIN) */
                    223: 
                    224: #ifdef CRT_END
                    225: 
                    226: #ifdef INIT_SECTION_ASM_OP
                    227: 
1.1.1.6 ! root      228: #ifdef OBJECT_FORMAT_ELF
1.1       root      229: 
1.1.1.6 ! root      230: static func_ptr __CTOR_END__[];
        !           231: static void
        !           232: __do_global_ctors_aux ()
        !           233: {
        !           234:   func_ptr *p;
        !           235:   for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
        !           236:     (*p) ();
        !           237: }
        !           238: 
        !           239: /* Stick a call to __do_global_ctors_aux into the .init section.  */
        !           240: static void
        !           241: init_dummy ()
        !           242: {
        !           243:   asm (INIT_SECTION_ASM_OP);
        !           244:   __do_global_ctors_aux ();
        !           245: #ifdef FORCE_INIT_SECTION_ALIGN
        !           246:   FORCE_INIT_SECTION_ALIGN;
        !           247: #endif
        !           248:   asm (TEXT_SECTION_ASM_OP);
        !           249: 
        !           250: /* This is a kludge. The Linux dynamic linker needs  ___brk_addr, __environ
        !           251:    and atexit (). We have to make sure they are in the .dynsym section. We
        !           252:    accomplish it by making a dummy call here. This
        !           253:    code is never reached. */
        !           254:  
        !           255: #if defined(__linux__) && defined(__PIC__)
        !           256:   {
        !           257:     extern void *___brk_addr;
        !           258:     extern char **__environ;
        !           259: 
        !           260:     ___brk_addr = __environ;
        !           261:     atexit ();
        !           262:   }
        !           263: #endif
        !           264: }
        !           265: 
        !           266: #else  /* OBJECT_FORMAT_ELF */
        !           267: 
        !           268: /* Stick the real initialization code, followed by a normal sort of
        !           269:    function epilogue at the very end of the .init section for this
        !           270:    entire root executable file or for this entire shared library file.
        !           271: 
        !           272:    Note that we use some tricks here to get *just* the body and just
        !           273:    a function epilogue (but no function prologue) into the .init
        !           274:    section of the crtend.o file.  Specifically, we switch to the .text
        !           275:    section, start to define a function, and then we switch to the .init
        !           276:    section just before the body code.
        !           277: 
        !           278:    Earlier on, we put the corresponding function prologue into the .init
        !           279:    section of the crtbegin.o file (which will be linked in first).
        !           280: 
        !           281:    Note that we want to invoke all constructors for C++ file-scope static-
        !           282:    storage objects AFTER any other possible initialization actions which
        !           283:    may be performed by the code in the .init section contributions made by
        !           284:    other libraries, etc.  That's because those other initializations may
        !           285:    include setup operations for very primitive things (e.g. initializing
        !           286:    the state of the floating-point coprocessor, etc.) which should be done
        !           287:    before we start to execute any of the user's code. */
1.1       root      288: 
                    289: static void
1.1.1.2   root      290: __do_global_ctors_aux ()       /* prologue goes in .text section */
1.1       root      291: {
                    292:   asm (INIT_SECTION_ASM_OP);
                    293:   DO_GLOBAL_CTORS_BODY;
1.1.1.2   root      294:   ON_EXIT (__do_global_dtors, 0);
1.1       root      295: }                              /* epilogue and body go in .init section */
                    296: 
1.1.1.6 ! root      297: #endif /* OBJECT_FORMAT_ELF */
        !           298: 
1.1       root      299: #endif /* defined(INIT_SECTION_ASM_OP) */
                    300: 
                    301: /* Force cc1 to switch to .data section.  */
                    302: static func_ptr force_to_data[0] = { };
                    303: 
1.1.1.6 ! root      304: /* Put a word containing zero at the end of each of our two lists of function
        !           305:    addresses.  Note that the words defined here go into the .ctors and .dtors
        !           306:    sections of the crtend.o file, and since that file is always linked in
        !           307:    last, these words naturally end up at the very ends of the two lists
        !           308:    contained in these two sections.  */
        !           309: 
1.1.1.2   root      310: #ifdef CTOR_LIST_END
                    311: CTOR_LIST_END;
                    312: #else
1.1       root      313: asm (CTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
1.1.1.6 ! root      314: STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
1.1.1.2   root      315: #endif
1.1       root      316: 
1.1.1.2   root      317: #ifdef DTOR_LIST_END
                    318: DTOR_LIST_END;
                    319: #else
1.1       root      320: asm (DTORS_SECTION_ASM_OP);    /* cc1 doesn't know that we are switching! */
1.1.1.6 ! root      321: STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
1.1.1.2   root      322: #endif
1.1       root      323: 
                    324: #endif /* defined(CRT_END) */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.