diff options
Diffstat (limited to 'gcc/config/rs6000/eabi-ctors.c')
| -rw-r--r-- | gcc/config/rs6000/eabi-ctors.c | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/gcc/config/rs6000/eabi-ctors.c b/gcc/config/rs6000/eabi-ctors.c index 2ff3c1abc61..9785a112a6d 100644 --- a/gcc/config/rs6000/eabi-ctors.c +++ b/gcc/config/rs6000/eabi-ctors.c @@ -1,7 +1,7 @@ /* Stripped down support to run global constructors and destructors on embedded PowerPC systems. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2000 Free Software Foundation, Inc. Contributed by Michael Meissner (meissner@cygnus.com). This file is part of GNU CC. @@ -28,65 +28,77 @@ Boston, MA 02111-1307, USA. */ This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ +#include "tm.h" +#include "defaults.h" +#include <stddef.h> +#include "frame.h" +#include "gbl-ctors.h" -/* Declare a pointer to void function type. */ - -typedef void (*func_ptr) (void); +/* FIXME: This file should share code with all the other + constructor/destructor implementations in crtstuff.c and libgcc2.c. */ /* Declare the set of symbols use as begin and end markers for the lists of global object constructors and global object destructors. */ -extern func_ptr __CTOR_LIST__[]; -extern func_ptr __CTOR_END__ []; -extern func_ptr __DTOR_LIST__[]; -extern func_ptr __DTOR_END__ []; +extern func_ptr __CTOR_LIST__[] asm ("__CTOR_LIST__"); +extern func_ptr __CTOR_END__ [] asm ("__CTOR_END__"); +extern func_ptr __DTOR_LIST__[] asm ("__DTOR_LIST__"); +extern func_ptr __DTOR_END__ [] asm ("__DTOR_END__"); +extern unsigned char __EH_FRAME_BEGIN__[] asm ("__EH_FRAME_BEGIN__"); extern void __do_global_ctors (void); -extern void __do_global_dtors (void); extern void __init (), __fini (); -/* The Solaris linker seems to incorrectly relocate PC relative relocations - to a different section (ie, calls to __init, __fini), so avoid it by - using a function pointer. */ -static void (*init_ptr) (void) = __init; -static void (*fini_ptr) (void) = __fini; - void (*__atexit)(func_ptr); /* Call all global constructors */ void __do_global_ctors (void) { - func_ptr *ptr = &__CTOR_END__[0] - 1; - func_ptr *start = &__CTOR_LIST__[0]; + func_ptr *p = __CTOR_END__ - 1; - if (__atexit) - __atexit (__do_global_dtors); +#ifdef EH_FRAME_SECTION + { + static struct object object; + __register_frame_info (__EH_FRAME_BEGIN__, &object); + } +#endif /* Call the constructors collected in the .ctors section. */ - for ( ; ptr >= start; ptr--) - if (*ptr) - (*ptr)(); + for ( ; p >= __CTOR_LIST__; p--) + if (*p) + (*p)(); + + if (__atexit) + __atexit (__do_global_dtors); /* Call the initialization function in the .init section. */ - (*init_ptr) (); + __init (); } /* Call all global destructors */ void __do_global_dtors (void) { - func_ptr *ptr = &__DTOR_LIST__[0]; - func_ptr *end = &__DTOR_END__[0]; + static func_ptr *p = __DTOR_LIST__ + 1; + static int completed = 0; - /* Call the termination function in the .fini section. */ - (*fini_ptr) (); + if (completed) + return; - /* Call the destructors collected in the .dtors section. Run - the destructors in reverse order. */ - for ( ; ptr < end; ptr++) - if (*ptr) - (*ptr)(); + /* Call the termination function in the .fini section. */ + __fini (); + + while (p < __DTOR_END__) + { + p++; + (*(p-1)) (); + } + +#ifdef EH_FRAME_SECTION_ASM_OP + if (__deregister_frame_info) + __deregister_frame_info (__EH_FRAME_BEGIN__); +#endif + completed = 1; } - |

