b10a87a3c29f0312e3555e3301089e50f00bb245
[gcc.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) */