OSDN Git Service

(CRT_END): Add dummy refs to ___brk_addr, __environ and atexit if
[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 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 /* A routine to invoke all of the global constructors upon entry to the
162    program.  We put this into the .init section (for systems that have
163    such a thing) so that we can properly perform the construction of
164    file-scope static-storage C++ objects within shared libraries.   */
165
166 static void
167 __do_global_ctors_aux ()        /* prologue goes in .init section */
168 {
169 #ifdef FORCE_INIT_SECTION_ALIGN
170   FORCE_INIT_SECTION_ALIGN;     /* Explicit align before switch to .text */
171 #endif
172   asm (TEXT_SECTION_ASM_OP);    /* don't put epilogue and body in .init */
173   DO_GLOBAL_CTORS_BODY;
174   ON_EXIT (__do_global_dtors, 0);
175 }
176
177 #endif /* OBJECT_FORMAT_ELF */
178 #endif /* defined(INIT_SECTION_ASM_OP) */
179
180 /* Force cc1 to switch to .data section.  */
181 static func_ptr force_to_data[0] = { };
182
183 /* NOTE:  In order to be able to support SVR4 shared libraries, we arrange
184    to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
185    __DTOR_END__ } per root executable and also one set of these symbols
186    per shared library.  So in any given whole process image, we may have
187    multiple definitions of each of these symbols.  In order to prevent
188    these definitions from conflicting with one another, and in order to
189    ensure that the proper lists are used for the initialization/finalization
190    of each individual shared library (respectively), we give these symbols
191    only internal (i.e. `static') linkage, and we also make it a point to
192    refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
193    symbol in crtbegin.o, where they are defined.  */
194
195 /* The -1 is a flag to __do_global_[cd]tors
196    indicating that this table does not start with a count of elements.  */
197 #ifdef CTOR_LIST_BEGIN
198 CTOR_LIST_BEGIN;
199 #else
200 asm (CTORS_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
201 STATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) };
202 #endif
203
204 #ifdef DTOR_LIST_BEGIN
205 DTOR_LIST_BEGIN;
206 #else
207 asm (DTORS_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
208 STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
209 #endif
210
211 #endif /* defined(CRT_BEGIN) */
212
213 #ifdef CRT_END
214
215 #ifdef INIT_SECTION_ASM_OP
216
217 #ifdef OBJECT_FORMAT_ELF
218
219 static func_ptr __CTOR_END__[];
220 static void
221 __do_global_ctors_aux ()
222 {
223   func_ptr *p;
224   for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
225     (*p) ();
226 }
227
228 /* Stick a call to __do_global_ctors_aux into the .init section.  */
229 static void
230 init_dummy ()
231 {
232   asm (INIT_SECTION_ASM_OP);
233   __do_global_ctors_aux ();
234 #ifdef FORCE_INIT_SECTION_ALIGN
235   FORCE_INIT_SECTION_ALIGN;
236 #endif
237   asm (TEXT_SECTION_ASM_OP);
238
239 /* This is a kludge. The Linux dynamic linker needs  ___brk_addr, __environ
240    and atexit (). We have to make sure they are in the .dynsym section. We
241    accomplish it by making a dummy call here. This
242    code is never reached. */
243  
244 #if defined(__linux__) && defined(__PIC__)
245   {
246     extern void *___brk_addr;
247     extern char **__environ;
248
249     ___brk_addr = __environ;
250     atexit ();
251   }
252 #endif
253 }
254
255 #else  /* OBJECT_FORMAT_ELF */
256
257 /* Stick the real initialization code, followed by a normal sort of
258    function epilogue at the very end of the .init section for this
259    entire root executable file or for this entire shared library file.
260
261    Note that we use some tricks here to get *just* the body and just
262    a function epilogue (but no function prologue) into the .init
263    section of the crtend.o file.  Sepcifically, we switch to the .text
264    section, start to define a function, and then we switch to the .init
265    section just before the body code.
266
267    Earlier on, we put the corresponding function prologue into the .init
268    section of the crtbegin.o file (which will be linked in first).
269
270    Note that we want to invoke all constructors for C++ file-scope static-
271    storage objects AFTER any other possible initialization actions which
272    may be performed by the code in the .init section contributions made by
273    other libraries, etc.  That's because those other initializations may
274    include setup operations for very primitive things (e.g. initializing
275    the state of the floating-point coprocessor, etc.) which should be done
276    before we start to execute any of the user's code. */
277
278 static void
279 __do_global_ctors_aux ()        /* prologue goes in .text section */
280 {
281   asm (INIT_SECTION_ASM_OP);
282   DO_GLOBAL_CTORS_BODY;
283   ON_EXIT (__do_global_dtors, 0);
284 }                               /* epilogue and body go in .init section */
285
286 #endif /* OBJECT_FORMAT_ELF */
287
288 #endif /* defined(INIT_SECTION_ASM_OP) */
289
290 /* Force cc1 to switch to .data section.  */
291 static func_ptr force_to_data[0] = { };
292
293 /* Put a word containing zero at the end of each of our two lists of function
294    addresses.  Note that the words defined here go into the .ctors and .dtors
295    sections of the crtend.o file, and since that file is always linked in
296    last, these words naturally end up at the very ends of the two lists
297    contained in these two sections.  */
298
299 #ifdef CTOR_LIST_END
300 CTOR_LIST_END;
301 #else
302 asm (CTORS_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
303 STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
304 #endif
305
306 #ifdef DTOR_LIST_END
307 DTOR_LIST_END;
308 #else
309 asm (DTORS_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
310 STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
311 #endif
312
313 #endif /* defined(CRT_END) */