OSDN Git Service

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