OSDN Git Service

* gcc-interface/decl.c (make_type_from_size) <INTEGER_TYPE>: Just copy
[pf3gnuchains/gcc-fork.git] / gcc / config / darwin-crt3.c
1 /* __cxa_atexit backwards-compatibility support for Darwin.
2    Copyright (C) 2006, 2009 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 <http://www.gnu.org/licenses/>.  */
24
25 /* Don't do anything if we are compiling for a kext multilib. */
26 #ifdef __PIC__
27
28 /* It is incorrect to include config.h here, because this file is being
29    compiled for the target, and hence definitions concerning only the host
30    do not apply.  */
31
32 #include "tconfig.h"
33 #include "tsystem.h"
34
35 #include <dlfcn.h>
36 #include <stdbool.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 /* This file works around two different problems.
41
42    The first problem is that there is no __cxa_atexit on Mac OS versions
43    before 10.4.  It fixes this by providing a complete atexit and
44    __cxa_atexit emulation called from the regular atexit.
45
46    The second problem is that on all shipping versions of Mac OS,
47    __cxa_finalize and exit() don't work right: they don't run routines
48    that were registered while other atexit routines are running.  This
49    is worked around by wrapping each atexit/__cxa_atexit routine with
50    our own routine which ensures that any __cxa_atexit calls while it
51    is running are honoured.
52
53    There are still problems which this does not solve.  Before 10.4,
54    shared objects linked with previous compilers won't have their
55    atexit calls properly interleaved with code compiled with newer
56    compilers.  Also, atexit routines registered from shared objects
57    linked with previous compilers won't get the bug fix.  */
58
59 typedef int (*cxa_atexit_p)(void (*func) (void*), void* arg, const void* dso);
60 typedef void (*cxa_finalize_p)(const void *dso);
61 typedef int (*atexit_p)(void (*func)(void));
62
63 /* These are from "keymgr.h".  */
64 extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
65 extern int _keymgr_get_and_lock_processwide_ptr_2 (unsigned, void **);
66 extern int _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr);
67
68 extern void *__keymgr_global[];
69 typedef struct _Sinfo_Node {
70         unsigned int size ;             /*size of this node*/
71         unsigned short major_version ;  /*API major version.*/
72         unsigned short minor_version ;  /*API minor version.*/
73         } _Tinfo_Node ;
74
75 #ifdef __ppc__
76 #define CHECK_KEYMGR_ERROR(e) \
77   (((_Tinfo_Node *)__keymgr_global[2])->major_version >= 4 ? (e) : 0)
78 #else
79 #define CHECK_KEYMGR_ERROR(e) (e)
80 #endif
81
82 /* Our globals are stored under this keymgr index.  */
83 #define KEYMGR_ATEXIT_LIST      14
84
85 /* The different kinds of callback routines.  */
86 typedef void (*atexit_callback)(void);
87 typedef void (*cxa_atexit_callback)(void *);
88
89 /* This structure holds a routine to call.  There may be extra fields
90    at the end of the structure that this code doesn't know about.  */
91 struct one_atexit_routine 
92 {
93   union {
94     atexit_callback ac;
95     cxa_atexit_callback cac;
96   } callback;
97   /* has_arg is 0/2/4 if 'ac' is live, 1/3/5 if 'cac' is live.  
98      Higher numbers indicate a later version of the structure that this
99      code doesn't understand and will ignore.  */
100   int has_arg;
101   void * arg;
102 };
103
104 struct atexit_routine_list
105 {
106   struct atexit_routine_list * next;
107   struct one_atexit_routine r;
108 };
109
110 /* The various possibilities for status of atexit().  */
111 enum atexit_status {
112   atexit_status_unknown = 0,
113   atexit_status_missing = 1,
114   atexit_status_broken = 2,
115   atexit_status_working = 16
116 };
117
118 struct keymgr_atexit_list
119 {
120   /* Version of this list.  This code knows only about version 0.
121      If the version is higher than 0, this code may add new atexit routines
122      but should not attempt to run the list.  */
123   short version;
124   /* 1 if an atexit routine is currently being run by this code, 0
125      otherwise.  */
126   char running_routines;
127   /* Holds a value from 'enum atexit_status'.  */
128   unsigned char atexit_status;
129   /* The list of atexit and cxa_atexit routines registered.  If
130    atexit_status_missing it contains all routines registered while
131    linked with this code.  If atexit_status_broken it contains all
132    routines registered during cxa_finalize while linked with this
133    code.  */
134   struct atexit_routine_list *l;
135   /* &__cxa_atexit; set if atexit_status >= atexit_status_broken.  */
136   cxa_atexit_p cxa_atexit_f;
137   /* &__cxa_finalize; set if atexit_status >= atexit_status_broken.  */
138   cxa_finalize_p cxa_finalize_f;
139   /* &atexit; set if atexit_status >= atexit_status_working
140      or atexit_status == atexit_status_missing.  */
141   atexit_p atexit_f;
142 };
143
144 /* Return 0 if __cxa_atexit has the bug it has in Mac OS 10.4: it
145    fails to call routines registered while an atexit routine is
146    running.  Return 1 if it works properly, and -1 if an error occurred.  */
147
148 struct atexit_data 
149 {
150   int result;
151   cxa_atexit_p cxa_atexit;
152 };
153
154 static void cxa_atexit_check_2 (void *arg)
155 {
156   ((struct atexit_data *)arg)->result = 1;
157 }
158
159 static void cxa_atexit_check_1 (void *arg)
160 {
161   struct atexit_data * aed = arg;
162   if (aed->cxa_atexit (cxa_atexit_check_2, arg, arg) != 0)
163     aed->result = -1;
164 }
165
166 static int
167 check_cxa_atexit (cxa_atexit_p cxa_atexit, cxa_finalize_p cxa_finalize)
168 {
169   struct atexit_data aed = { 0, cxa_atexit };
170
171   /* We re-use &aed as the 'dso' parameter, since it's a unique address.  */
172   if (cxa_atexit (cxa_atexit_check_1, &aed, &aed) != 0)
173     return -1;
174   cxa_finalize (&aed);
175   if (aed.result == 0)
176     {
177       /* Call __cxa_finalize again to make sure that cxa_atexit_check_2
178          is removed from the list before AED goes out of scope.  */
179       cxa_finalize (&aed);
180       aed.result = 0;
181     }
182   return aed.result;
183 }
184
185 #ifdef __ppc__
186 /* This comes from Csu.  It works only before 10.4.  The prototype has
187    been altered a bit to avoid casting.  */
188 extern int _dyld_func_lookup(const char *dyld_func_name,
189      void *address) __attribute__((visibility("hidden")));
190
191 static void our_atexit (void);
192
193 /* We're running on 10.3.9.  Find the address of the system atexit()
194    function.  So easy to say, so hard to do.  */
195 static atexit_p
196 find_atexit_10_3 (void)
197 {
198   unsigned int (*dyld_image_count_fn)(void);
199   const char *(*dyld_get_image_name_fn)(unsigned int image_index);
200   const void *(*dyld_get_image_header_fn)(unsigned int image_index);
201   const void *(*NSLookupSymbolInImage_fn)(const void *image, 
202                                           const char *symbolName,
203                                           unsigned int options);
204   void *(*NSAddressOfSymbol_fn)(const void *symbol);
205   unsigned i, count;
206   
207   /* Find some dyld functions.  */
208   _dyld_func_lookup("__dyld_image_count", &dyld_image_count_fn);
209   _dyld_func_lookup("__dyld_get_image_name", &dyld_get_image_name_fn);
210   _dyld_func_lookup("__dyld_get_image_header", &dyld_get_image_header_fn);
211   _dyld_func_lookup("__dyld_NSLookupSymbolInImage", &NSLookupSymbolInImage_fn);
212   _dyld_func_lookup("__dyld_NSAddressOfSymbol", &NSAddressOfSymbol_fn);
213
214   /* If any of these don't exist, that's an error.  */
215   if (! dyld_image_count_fn || ! dyld_get_image_name_fn
216       || ! dyld_get_image_header_fn || ! NSLookupSymbolInImage_fn
217       || ! NSAddressOfSymbol_fn)
218     return NULL;
219   
220   count = dyld_image_count_fn ();
221   for (i = 0; i < count; i++)
222     {
223       const char * path = dyld_get_image_name_fn (i);
224       const void * image;
225       const void * symbol;
226       
227       if (strcmp (path, "/usr/lib/libSystem.B.dylib") != 0)
228         continue;
229       image = dyld_get_image_header_fn (i);
230       if (! image)
231         return NULL;
232       /* '4' is NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR.  */
233       symbol = NSLookupSymbolInImage_fn (image, "_atexit", 4);
234       if (! symbol)
235         return NULL;
236       return NSAddressOfSymbol_fn (symbol);
237     }
238   return NULL;
239 }
240 #endif
241
242 /* Create (if necessary), find, lock, fill in, and return our globals.  
243    Return NULL on error, in which case the globals will not be locked.  
244    The caller should call keymgr_set_and_unlock.  */
245 static struct keymgr_atexit_list *
246 get_globals (void)
247 {
248   struct keymgr_atexit_list * r;
249   
250 #ifdef __ppc__
251   /* 10.3.9 doesn't have _keymgr_get_and_lock_processwide_ptr_2 so the
252      PPC side can't use it.  On 10.4 this just means the error gets
253      reported a little later when
254      _keymgr_set_and_unlock_processwide_ptr finds that the key was
255      never locked.  */
256   r = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
257 #else
258   void * rr;
259   if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ATEXIT_LIST, &rr))
260     return NULL;
261   r = rr;
262 #endif
263   
264   if (r == NULL)
265     {
266       r = calloc (sizeof (struct keymgr_atexit_list), 1);
267       if (! r)
268         return NULL;
269     }
270
271   if (r->atexit_status == atexit_status_unknown)
272     {
273       void *handle;
274
275       handle = dlopen ("/usr/lib/libSystem.B.dylib", RTLD_NOLOAD);
276       if (!handle)
277         {
278 #ifdef __ppc__
279           r->atexit_status = atexit_status_missing;
280           r->atexit_f = find_atexit_10_3 ();
281           if (! r->atexit_f)
282             goto error;
283           if (r->atexit_f (our_atexit))
284             goto error;
285 #else
286           goto error;
287 #endif
288         }
289       else
290         {
291           int chk_result;
292
293           r->cxa_atexit_f = (cxa_atexit_p)dlsym (handle, "__cxa_atexit");
294           r->cxa_finalize_f = (cxa_finalize_p)dlsym (handle, "__cxa_finalize");
295           if (! r->cxa_atexit_f || ! r->cxa_finalize_f)
296             goto error;
297
298           chk_result = check_cxa_atexit (r->cxa_atexit_f, r->cxa_finalize_f);
299           if (chk_result == -1)
300             goto error;
301           else if (chk_result == 0)
302             r->atexit_status = atexit_status_broken;
303           else
304             {
305               r->atexit_f = (atexit_p)dlsym (handle, "atexit");
306               if (! r->atexit_f)
307                 goto error;
308               r->atexit_status = atexit_status_working;
309             }
310         }
311     }
312
313   return r;
314   
315  error:
316   _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, r);
317   return NULL;
318 }
319
320 /* Add TO_ADD to ATEXIT_LIST.  ATEXIT_LIST may be NULL but is
321    always the result of calling _keymgr_get_and_lock_processwide_ptr and
322    so KEYMGR_ATEXIT_LIST is known to be locked; this routine is responsible
323    for unlocking it.  */
324
325 static int
326 add_routine (struct keymgr_atexit_list * g,
327              const struct one_atexit_routine * to_add)
328 {
329   struct atexit_routine_list * s
330     = malloc (sizeof (struct atexit_routine_list));
331   int result;
332   
333   if (!s)
334     {
335       _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
336       return -1;
337     }
338   s->r = *to_add;
339   s->next = g->l;
340   g->l = s;
341   result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
342   return CHECK_KEYMGR_ERROR (result) == 0 ? 0 : -1;
343 }
344
345 /* This runs the routines in G->L up to STOP.  */
346 static struct keymgr_atexit_list *
347 run_routines (struct keymgr_atexit_list *g,
348               struct atexit_routine_list *stop)
349 {
350   for (;;)
351     {
352       struct atexit_routine_list * cur = g->l;
353       if (! cur || cur == stop)
354         break;
355       g->l = cur->next;
356       _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
357
358       switch (cur->r.has_arg) {
359       case 0: case 2: case 4:
360         cur->r.callback.ac ();
361         break;
362       case 1: case 3: case 5:
363         cur->r.callback.cac (cur->r.arg);
364         break;
365       default:
366         /* Don't understand, so don't call it.  */
367         break;
368       }
369       free (cur);
370
371       g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
372       if (! g)
373         break;
374     }
375   return g;
376 }
377
378 /* Call the routine described by ROUTINE_PARAM and then call any
379    routines added to KEYMGR_ATEXIT_LIST while that routine was
380    running, all with in_cxa_finalize set.  */
381
382 static void
383 cxa_atexit_wrapper (void* routine_param)
384 {
385   struct one_atexit_routine * routine = routine_param;
386   struct keymgr_atexit_list *g;
387   struct atexit_routine_list * base = NULL;
388   char prev_running = 0;
389   
390   g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
391   if (g)
392     {
393       prev_running = g->running_routines;
394       g->running_routines = 1;
395       base = g->l;
396       _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
397     }
398
399   if (routine->has_arg)
400     routine->callback.cac (routine->arg);
401   else
402     routine->callback.ac ();
403
404   if (g)
405     g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
406   if (g)
407     g = run_routines (g, base);
408   if (g)
409     {
410       g->running_routines = prev_running;
411       _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
412     }
413 }
414
415 #ifdef __ppc__
416 /* This code is used while running on 10.3.9, when __cxa_atexit doesn't
417    exist in the system library.  10.3.9 only supported regular PowerPC,
418    so this code isn't necessary on x86 or ppc64.  */
419
420 /* This routine is called from the system atexit(); it runs everything
421    registered on the KEYMGR_ATEXIT_LIST.  */
422
423 static void
424 our_atexit (void)
425 {
426   struct keymgr_atexit_list *g;
427   char prev_running;
428
429   g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
430   if (! g || g->version != 0 || g->atexit_status != atexit_status_missing)
431     return;
432   
433   prev_running = g->running_routines;
434   g->running_routines = 1;
435   g = run_routines (g, NULL);
436   if (! g)
437     return;
438   g->running_routines = prev_running;
439   _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
440 }
441 #endif
442
443 /* This is our wrapper around atexit and __cxa_atexit.  It will return
444    nonzero if an error occurs, and otherwise:
445    - if in_cxa_finalize is set, or running on 10.3.9, add R to
446      KEYMGR_ATEXIT_LIST; or
447    - call the system __cxa_atexit to add cxa_atexit_wrapper with an argument
448      that indicates how cxa_atexit_wrapper should call R.  */
449
450 static int
451 atexit_common (const struct one_atexit_routine *r, const void *dso)
452 {
453   struct keymgr_atexit_list *g = get_globals ();
454
455   if (! g)
456     return -1;
457   
458   if (g->running_routines || g->atexit_status == atexit_status_missing)
459     return add_routine (g, r);
460
461   if (g->atexit_status >= atexit_status_working)
462     {
463       int result;
464       if (r->has_arg)
465         {
466           cxa_atexit_p cxa_atexit = g->cxa_atexit_f;
467           result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST,
468                                                            g);
469           if (CHECK_KEYMGR_ERROR (result))
470             return -1;
471           return cxa_atexit (r->callback.cac, r->arg, dso);
472         }
473       else
474         {
475           atexit_p atexit_f = g->atexit_f;
476           result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST,
477                                                            g);
478           if (CHECK_KEYMGR_ERROR (result))
479             return -1;
480           return atexit_f (r->callback.ac);
481         }
482     }
483   else
484     {
485       cxa_atexit_p cxa_atexit = g->cxa_atexit_f;
486       struct one_atexit_routine *alloced;
487       int result;
488
489       result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
490       if (CHECK_KEYMGR_ERROR (result))
491         return -1;
492
493       alloced = malloc (sizeof (struct one_atexit_routine));
494       if (! alloced)
495         return -1;
496       *alloced = *r;
497       return cxa_atexit (cxa_atexit_wrapper, alloced, dso);
498     }
499 }
500
501 /* These are the actual replacement routines; they just funnel into
502    atexit_common.  */
503
504 int __cxa_atexit (cxa_atexit_callback func, void* arg, 
505                   const void* dso) __attribute__((visibility("hidden")));
506
507 int
508 __cxa_atexit (cxa_atexit_callback func, void* arg, const void* dso)
509 {
510   struct one_atexit_routine r;
511   r.callback.cac = func;
512   r.has_arg = 1;
513   r.arg = arg;
514   return atexit_common (&r, dso);
515 }
516
517 int atexit (atexit_callback func) __attribute__((visibility("hidden")));
518
519 /* Use __dso_handle to allow even bundles that call atexit() to be unloaded
520    on 10.4.  */
521 extern void __dso_handle;
522
523 int
524 atexit (atexit_callback func)
525 {
526   struct one_atexit_routine r;
527   r.callback.ac = func;
528   r.has_arg = 0;
529   return atexit_common (&r, &__dso_handle);
530 }
531
532 #endif /* __PIC__ */