Shared library support.
[platform/upstream/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 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
240 #else  /* OBJECT_FORMAT_ELF */
241
242 /* Stick the real initialization code, followed by a normal sort of
243    function epilogue at the very end of the .init section for this
244    entire root executable file or for this entire shared library file.
245
246    Note that we use some tricks here to get *just* the body and just
247    a function epilogue (but no function prologue) into the .init
248    section of the crtend.o file.  Sepcifically, we switch to the .text
249    section, start to define a function, and then we switch to the .init
250    section just before the body code.
251
252    Earlier on, we put the corresponding function prologue into the .init
253    section of the crtbegin.o file (which will be linked in first).
254
255    Note that we want to invoke all constructors for C++ file-scope static-
256    storage objects AFTER any other possible initialization actions which
257    may be performed by the code in the .init section contributions made by
258    other libraries, etc.  That's because those other initializations may
259    include setup operations for very primitive things (e.g. initializing
260    the state of the floating-point coprocessor, etc.) which should be done
261    before we start to execute any of the user's code. */
262
263 static void
264 __do_global_ctors_aux ()        /* prologue goes in .text section */
265 {
266   asm (INIT_SECTION_ASM_OP);
267   DO_GLOBAL_CTORS_BODY;
268   ON_EXIT (__do_global_dtors, 0);
269 }                               /* epilogue and body go in .init section */
270
271 #endif /* OBJECT_FORMAT_ELF */
272
273 #endif /* defined(INIT_SECTION_ASM_OP) */
274
275 /* Force cc1 to switch to .data section.  */
276 static func_ptr force_to_data[0] = { };
277
278 /* Put a word containing zero at the end of each of our two lists of function
279    addresses.  Note that the words defined here go into the .ctors and .dtors
280    sections of the crtend.o file, and since that file is always linked in
281    last, these words naturally end up at the very ends of the two lists
282    contained in these two sections.  */
283
284 #ifdef CTOR_LIST_END
285 CTOR_LIST_END;
286 #else
287 asm (CTORS_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
288 STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
289 #endif
290
291 #ifdef DTOR_LIST_END
292 DTOR_LIST_END;
293 #else
294 asm (DTORS_SECTION_ASM_OP);     /* cc1 doesn't know that we are switching! */
295 STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
296 #endif
297
298 #endif /* defined(CRT_END) */