diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index c05f97aa535226ed7444f27bf1291d016ca60ebf..d3bd7dc0f0ae5668b6fb4af238e164b35414a053 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -1,6 +1,6 @@ /* More subroutines needed by GCC output code on some machines. */ /* Compile this one with gcc. */ -/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1989, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. This file is part of GNU CC. @@ -1466,19 +1466,7 @@ BLOCK_PROFILER_CODE #include <stdio.h> char *ctime (); -#ifdef HAVE_ATEXIT -#ifdef WINNT -extern int atexit (void (*) (void)); -#else -extern void atexit (void (*) (void)); -#endif -#define ON_EXIT(FUNC,ARG) atexit ((FUNC)) -#else -#ifdef sun -extern void on_exit (void*, void*); -#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG)) -#endif -#endif +#include "gbl-ctors.h" static struct bb *bb_head; @@ -2911,8 +2899,48 @@ func_ptr __DTOR_LIST__[2]; #include "gbl-ctors.h" +#ifdef NEED_ATEXIT +# ifdef ON_EXIT +# undef ON_EXIT +# endif +int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ +#endif + #ifndef ON_EXIT +#ifdef NEED_ATEXIT +# include <errno.h> + +extern void *malloc (); +extern void *realloc (); + +static func_ptr *atexit_chain = NULL; +static long atexit_chain_length = 0; +static volatile long last_atexit_chain_slot = -1; + +int atexit (func_ptr func) +{ + if (++last_atexit_chain_slot == atexit_chain_length) + { + atexit_chain_length += 32; + if (atexit_chain) + atexit_chain = realloc (atexit_chain, + atexit_chain_length * sizeof (func_ptr)); + else + atexit_chain = malloc (atexit_chain_length * sizeof (func_ptr)); + if (! atexit_chain) + { + atexit_chain_length = 0; + last_atexit_chain_slot = -1; + errno = ENOMEM; + return (-1); + } + } + atexit_chain[last_atexit_chain_slot] = func; + return (0); +} +#endif /* NEED_ATEXIT */ + /* If we have no known way of registering our own __do_global_dtors routine so that it will be invoked at program exit time, then we have to define our own exit routine which will get this to happen. */ @@ -2926,7 +2954,20 @@ exit (status) int status; { #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF) +#ifdef NEED_ATEXIT + if (atexit_chain) + { + for ( ; last_atexit_chain_slot-- >= 0; ) + { + (*atexit_chain[last_atexit_chain_slot + 1]) (); + atexit_chain[last_atexit_chain_slot + 1] = NULL; + } + free (atexit_chain); + atexit_chain = NULL; + } +#else /* No NEED_ATEXIT */ __do_global_dtors (); +#endif /* No NEED_ATEXIT */ #endif #ifdef EXIT_BODY EXIT_BODY;