2004-09-09 Paul Brook <paul@codesourcery.com>
* libc/include/sys/reent.h (struct _on_exit_args): Add _dso_handle
        and _is_cxa.
        (struct _atexit): Add _next when _REENT_SMALL.
        (struct _reent): Add _atexit0 when _REENT_SMALL.
        (_REENT_INIT_PTR): Adjust.
        * libc/stdlib/Makefile.am (GENERAL_SOURCES): Add __atexit.c and
        __call_exit.c.
        (EXTENDED_SOURCES): Add cxa_atexit.c and cxa_finalize.c.
        * libc/stdlib/Makefile.in: Regenerate.
        * libc/stdlib/__atexit.c: New file.
        * libc/stdlib/__call_atexit.c: New file.
        * libc/stdlib/atexit.h: Remove old definitions.  Add new.
        * libc/stdlib/atexit.c (atexit): Use __register_exitproc.
        * libc/stdlib/cxa_atexit.c: New file.
        * libc/stdlib/cxa_finalize.c: New file.
        * libc/stdlib/exit.c (exit): Use __call_exitprocs.
        * libc/stdlib/on_exit.c (on_exit): Use __register_exitproc.
        2004-09-09  Jeff Johnston  <jjohnstn@redhat.com>
        * libc/reent/reent.c [_REENT_SMALL]: Fix reference to
        _on_exit_args_ptr.
			
			
This commit is contained in:
		| @@ -1,3 +1,26 @@ | ||||
| 2004-09-09  Paul Brook  <paul@codesourcery.com> | ||||
|  | ||||
| 	* libc/include/sys/reent.h (struct _on_exit_args): Add _dso_handle | ||||
| 	and _is_cxa. | ||||
| 	(struct _atexit): Add _next when _REENT_SMALL. | ||||
| 	(struct _reent): Add _atexit0 when _REENT_SMALL. | ||||
| 	(_REENT_INIT_PTR): Adjust. | ||||
| 	* libc/stdlib/Makefile.am (GENERAL_SOURCES): Add __atexit.c and | ||||
| 	__call_exit.c. | ||||
| 	(EXTENDED_SOURCES): Add cxa_atexit.c and cxa_finalize.c. | ||||
| 	* libc/stdlib/Makefile.in: Regenerate. | ||||
| 	* libc/stdlib/__atexit.c: New file. | ||||
| 	* libc/stdlib/__call_atexit.c: New file. | ||||
| 	* libc/stdlib/atexit.h: Remove old definitions.  Add new. | ||||
| 	* libc/stdlib/atexit.c (atexit): Use __register_exitproc. | ||||
| 	* libc/stdlib/cxa_atexit.c: New file. | ||||
| 	* libc/stdlib/cxa_finalize.c: New file. | ||||
| 	* libc/stdlib/exit.c (exit): Use __call_exitprocs. | ||||
| 	* libc/stdlib/on_exit.c (on_exit): Use __register_exitproc. | ||||
| 	2004-09-09  Jeff Johnston  <jjohnstn@redhat.com> | ||||
| 	* libc/reent/reent.c [_REENT_SMALL]: Fix reference to | ||||
| 	_on_exit_args_ptr. | ||||
|  | ||||
| 2004-08-23  Jeff Johnston  <jjohnstn@redhat.com> | ||||
|  | ||||
| 	* libc/include/sys/unistd.h (getpass): Change prototype to use | ||||
|   | ||||
| @@ -59,19 +59,24 @@ struct __tm | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * atexit() support.  For _REENT_SMALL, we limit to 32 max. | ||||
|  * atexit() support. | ||||
|  */ | ||||
|  | ||||
| #define	_ATEXIT_SIZE 32	/* must be at least 32 to guarantee ANSI conformance */ | ||||
|  | ||||
| struct _on_exit_args { | ||||
| 	void *  _fnargs[_ATEXIT_SIZE];	        /* fn args for on_exit */ | ||||
| 	void *  _fnargs[_ATEXIT_SIZE];	        /* user fn args */ | ||||
| 	void *	_dso_handle[_ATEXIT_SIZE]; | ||||
| 	/* Bitmask is set if user function takes arguments.  */ | ||||
| 	__ULong _fntypes;           	        /* type of exit routine - | ||||
| 				   Must have at least _ATEXIT_SIZE bits */ | ||||
| 	/* Bitmask is set if function was registered via __cxa_atexit.  */ | ||||
| 	__ULong _is_cxa; | ||||
| }; | ||||
|  | ||||
| #ifdef _REENT_SMALL | ||||
| struct _atexit { | ||||
| 	struct	_atexit *_next;			/* next in list */ | ||||
| 	int	_ind;				/* next index in this table */ | ||||
| 	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */ | ||||
|         struct _on_exit_args * _on_exit_args_ptr; | ||||
| @@ -80,6 +85,7 @@ struct _atexit { | ||||
| struct _atexit { | ||||
| 	struct	_atexit *_next;			/* next in list */ | ||||
| 	int	_ind;				/* next index in this table */ | ||||
| 	/* Some entries may already have been called, and will be NULL.  */ | ||||
| 	void	(*_fns[_ATEXIT_SIZE])(void);	/* the table itself */ | ||||
|         struct _on_exit_args _on_exit_args; | ||||
| }; | ||||
| @@ -371,7 +377,8 @@ struct _reent | ||||
|   void (**(_sig_func))(int); | ||||
|  | ||||
|   /* atexit stuff */ | ||||
|   struct _atexit _atexit; | ||||
|   struct _atexit *_atexit; | ||||
|   struct _atexit _atexit0; | ||||
|  | ||||
|   struct _glue __sglue;			/* root of glue chain */ | ||||
|   __FILE *__sf;			        /* file descriptors */ | ||||
| @@ -399,7 +406,8 @@ struct _reent | ||||
|     _NULL, \ | ||||
|     _NULL, \ | ||||
|     _NULL, \ | ||||
|     {0, {_NULL}, _NULL}, \ | ||||
|     _NULL, \ | ||||
|     {_NULL, 0, {_NULL}, _NULL}, \ | ||||
|     {_NULL, 0, _NULL}, \ | ||||
|     _NULL, \ | ||||
|     {_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL}, \ | ||||
| @@ -426,9 +434,11 @@ struct _reent | ||||
|     var->_localtime_buf = _NULL; \ | ||||
|     var->_asctime_buf = _NULL; \ | ||||
|     var->_sig_func = _NULL; \ | ||||
|     var->_atexit._ind = 0; \ | ||||
|     var->_atexit._fns[0] = _NULL; \ | ||||
|     var->_atexit._on_exit_args = _NULL; \ | ||||
|     var->_atexit = _NULL; \ | ||||
|     var->_atexit0._next = _NULL; \ | ||||
|     var->_atexit0._ind = 0; \ | ||||
|     var->_atexit0._fns[0] = _NULL; \ | ||||
|     var->_atexit0._on_exit_args_ptr = _NULL; \ | ||||
|     var->__sglue._next = _NULL; \ | ||||
|     var->__sglue._niobs = 0; \ | ||||
|     var->__sglue._iobs = _NULL; \ | ||||
| @@ -673,7 +683,7 @@ struct _reent | ||||
|       } \ | ||||
|     }, \ | ||||
|     _NULL, \ | ||||
|     {_NULL, 0, {_NULL}, {{_NULL}, 0}}, \ | ||||
|     {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}, \ | ||||
|     _NULL, \ | ||||
|     {_NULL, 0, _NULL} \ | ||||
|   } | ||||
|   | ||||
| @@ -81,8 +81,8 @@ _DEFUN (_reclaim_reent, (ptr), | ||||
| 	_free_r (ptr, ptr->_localtime_buf); | ||||
|       if (ptr->_asctime_buf) | ||||
| 	_free_r (ptr, ptr->_asctime_buf); | ||||
|       if (ptr->_atexit._on_exit_args_ptr) | ||||
| 	_free_r (ptr, ptr->_atexit._on_exit_args_ptr); | ||||
|       if (ptr->_atexit->_on_exit_args_ptr) | ||||
| 	_free_r (ptr, ptr->_atexit->_on_exit_args_ptr); | ||||
| #else | ||||
|       /* atexit stuff */ | ||||
|       if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0)) | ||||
|   | ||||
| @@ -6,6 +6,8 @@ INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) | ||||
|  | ||||
| GENERAL_SOURCES = \ | ||||
| 	__adjust.c 	\ | ||||
| 	__atexit.c	\ | ||||
| 	__call_atexit.c	\ | ||||
| 	__exp10.c 	\ | ||||
| 	__ten_mu.c 	\ | ||||
| 	_Exit.c		\ | ||||
| @@ -52,6 +54,8 @@ GENERAL_SOURCES = \ | ||||
| 	wctomb_r.c | ||||
|  | ||||
| EXTENDED_SOURCES = \ | ||||
| 	cxa_atexit.c	\ | ||||
| 	cxa_finalize.c	\ | ||||
| 	drand48.c	\ | ||||
| 	ecvtbuf.c 	\ | ||||
| 	efgcvt.c 	\ | ||||
|   | ||||
| @@ -110,10 +110,10 @@ AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) | ||||
|  | ||||
| GENERAL_SOURCES =  	__adjust.c 		__exp10.c 		__ten_mu.c 		_Exit.c			abort.c  		abs.c 			assert.c  		atexit.c		atof.c 			atoff.c			atoi.c  		atol.c			calloc.c		div.c  			dtoa.c 			dtoastub.c 		environ.c		envlock.c		eprintf.c		exit.c 			getenv.c  		getenv_r.c		labs.c 			ldiv.c  		ldtoa.c			malloc.c  		mblen.c			mblen_r.c		mbstowcs.c		mbstowcs_r.c		mbtowc.c		mbtowc_r.c		mlock.c			mprec.c			mstats.c		rand.c			rand_r.c		realloc.c		strtod.c		strtol.c		strtoul.c		wcstombs.c		wcstombs_r.c		wctomb.c		wctomb_r.c | ||||
| GENERAL_SOURCES =  	__adjust.c 		__atexit.c		__call_atexit.c		__exp10.c 		__ten_mu.c 		_Exit.c			abort.c  		abs.c 			assert.c  		atexit.c		atof.c 			atoff.c			atoi.c  		atol.c			calloc.c		div.c  			dtoa.c 			dtoastub.c 		environ.c		envlock.c		eprintf.c		exit.c 			getenv.c  		getenv_r.c		labs.c 			ldiv.c  		ldtoa.c			malloc.c  		mblen.c			mblen_r.c		mbstowcs.c		mbstowcs_r.c		mbtowc.c		mbtowc_r.c		mlock.c			mprec.c			mstats.c		rand.c			rand_r.c		realloc.c		strtod.c		strtol.c		strtoul.c		wcstombs.c		wcstombs_r.c		wctomb.c		wctomb_r.c | ||||
|  | ||||
|  | ||||
| EXTENDED_SOURCES =  	drand48.c		ecvtbuf.c 		efgcvt.c 		erand48.c		jrand48.c		lcong48.c		lrand48.c		mrand48.c		msize.c			mtrim.c			nrand48.c		rand48.c		seed48.c		srand48.c		strtoll.c		strtoll_r.c		strtoull.c		strtoull_r.c		atoll.c			llabs.c			lldiv.c | ||||
| EXTENDED_SOURCES =  	cxa_atexit.c		cxa_finalize.c		drand48.c		ecvtbuf.c 		efgcvt.c 		erand48.c		jrand48.c		lcong48.c		lrand48.c		mrand48.c		msize.c			mtrim.c			nrand48.c		rand48.c		seed48.c		srand48.c		strtoll.c		strtoll_r.c		strtoull.c		strtoull_r.c		atoll.c			llabs.c			lldiv.c | ||||
|  | ||||
|  | ||||
| ELIX_2_OBJS =  	a64l.$(oext)			btowc.$(oext)			getopt.$(oext)			getsubopt.$(oext)		l64a.$(oext)			malign.$(oext)			malignr.$(oext)			malloptr.$(oext)		mbrlen.$(oext)			mbrtowc.$(oext)			mbsinit.$(oext)			mbsrtowcs.$(oext)		on_exit.$(oext)			pvallocr.$(oext)		valloc.$(oext)			vallocr.$(oext)			wcrtomb.$(oext)			wcsrtombs.$(oext)		wctob.$(oext) | ||||
| @@ -168,23 +168,26 @@ LIBRARIES =  $(noinst_LIBRARIES) | ||||
| DEFS = @DEFS@ -I. -I$(srcdir)  | ||||
| CPPFLAGS = @CPPFLAGS@ | ||||
| LIBS = @LIBS@ | ||||
| @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  __adjust.$(OBJEXT) __exp10.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@__ten_mu.$(OBJEXT) _Exit.$(OBJEXT) abort.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@abs.$(OBJEXT) assert.$(OBJEXT) atexit.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@atof.$(OBJEXT) atoff.$(OBJEXT) atoi.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@atol.$(OBJEXT) calloc.$(OBJEXT) div.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dtoa.$(OBJEXT) dtoastub.$(OBJEXT) environ.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@envlock.$(OBJEXT) eprintf.$(OBJEXT) exit.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@getenv.$(OBJEXT) getenv_r.$(OBJEXT) labs.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@ldiv.$(OBJEXT) ldtoa.$(OBJEXT) malloc.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mblen.$(OBJEXT) mblen_r.$(OBJEXT) mbstowcs.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  __adjust.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@__atexit.$(OBJEXT) __call_atexit.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@__exp10.$(OBJEXT) __ten_mu.$(OBJEXT) _Exit.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@abort.$(OBJEXT) abs.$(OBJEXT) assert.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@atexit.$(OBJEXT) atof.$(OBJEXT) atoff.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@atoi.$(OBJEXT) atol.$(OBJEXT) calloc.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@div.$(OBJEXT) dtoa.$(OBJEXT) dtoastub.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@environ.$(OBJEXT) envlock.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@eprintf.$(OBJEXT) exit.$(OBJEXT) getenv.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@getenv_r.$(OBJEXT) labs.$(OBJEXT) ldiv.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@ldtoa.$(OBJEXT) malloc.$(OBJEXT) mblen.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mblen_r.$(OBJEXT) mbstowcs.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mbstowcs_r.$(OBJEXT) mbtowc.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mbtowc_r.$(OBJEXT) mlock.$(OBJEXT) mprec.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@mstats.$(OBJEXT) rand.$(OBJEXT) rand_r.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@realloc.$(OBJEXT) strtod.$(OBJEXT) strtol.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@strtoul.$(OBJEXT) wcstombs.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@wcstombs_r.$(OBJEXT) wctomb.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@wctomb_r.$(OBJEXT) drand48.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@wctomb_r.$(OBJEXT) cxa_atexit.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@cxa_finalize.$(OBJEXT) drand48.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@ecvtbuf.$(OBJEXT) efgcvt.$(OBJEXT) erand48.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@jrand48.$(OBJEXT) lcong48.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@lrand48.$(OBJEXT) mrand48.$(OBJEXT) msize.$(OBJEXT) \ | ||||
| @@ -195,16 +198,17 @@ LIBS = @LIBS@ | ||||
| @USE_LIBTOOL_FALSE@lldiv.$(OBJEXT) | ||||
| LTLIBRARIES =  $(noinst_LTLIBRARIES) | ||||
|  | ||||
| @USE_LIBTOOL_TRUE@libstdlib_la_OBJECTS =  __adjust.lo __exp10.lo \ | ||||
| @USE_LIBTOOL_TRUE@__ten_mu.lo _Exit.lo abort.lo abs.lo assert.lo \ | ||||
| @USE_LIBTOOL_TRUE@atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \ | ||||
| @USE_LIBTOOL_TRUE@div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo \ | ||||
| @USE_LIBTOOL_TRUE@eprintf.lo exit.lo getenv.lo getenv_r.lo labs.lo \ | ||||
| @USE_LIBTOOL_TRUE@ldiv.lo ldtoa.lo malloc.lo mblen.lo mblen_r.lo \ | ||||
| @USE_LIBTOOL_TRUE@mbstowcs.lo mbstowcs_r.lo mbtowc.lo mbtowc_r.lo \ | ||||
| @USE_LIBTOOL_TRUE@mlock.lo mprec.lo mstats.lo rand.lo rand_r.lo \ | ||||
| @USE_LIBTOOL_TRUE@realloc.lo strtod.lo strtol.lo strtoul.lo wcstombs.lo \ | ||||
| @USE_LIBTOOL_TRUE@wcstombs_r.lo wctomb.lo wctomb_r.lo drand48.lo \ | ||||
| @USE_LIBTOOL_TRUE@libstdlib_la_OBJECTS =  __adjust.lo __atexit.lo \ | ||||
| @USE_LIBTOOL_TRUE@__call_atexit.lo __exp10.lo __ten_mu.lo _Exit.lo \ | ||||
| @USE_LIBTOOL_TRUE@abort.lo abs.lo assert.lo atexit.lo atof.lo atoff.lo \ | ||||
| @USE_LIBTOOL_TRUE@atoi.lo atol.lo calloc.lo div.lo dtoa.lo dtoastub.lo \ | ||||
| @USE_LIBTOOL_TRUE@environ.lo envlock.lo eprintf.lo exit.lo getenv.lo \ | ||||
| @USE_LIBTOOL_TRUE@getenv_r.lo labs.lo ldiv.lo ldtoa.lo malloc.lo \ | ||||
| @USE_LIBTOOL_TRUE@mblen.lo mblen_r.lo mbstowcs.lo mbstowcs_r.lo \ | ||||
| @USE_LIBTOOL_TRUE@mbtowc.lo mbtowc_r.lo mlock.lo mprec.lo mstats.lo \ | ||||
| @USE_LIBTOOL_TRUE@rand.lo rand_r.lo realloc.lo strtod.lo strtol.lo \ | ||||
| @USE_LIBTOOL_TRUE@strtoul.lo wcstombs.lo wcstombs_r.lo wctomb.lo \ | ||||
| @USE_LIBTOOL_TRUE@wctomb_r.lo cxa_atexit.lo cxa_finalize.lo drand48.lo \ | ||||
| @USE_LIBTOOL_TRUE@ecvtbuf.lo efgcvt.lo erand48.lo jrand48.lo lcong48.lo \ | ||||
| @USE_LIBTOOL_TRUE@lrand48.lo mrand48.lo msize.lo mtrim.lo nrand48.lo \ | ||||
| @USE_LIBTOOL_TRUE@rand48.lo seed48.lo srand48.lo strtoll.lo \ | ||||
|   | ||||
							
								
								
									
										86
									
								
								newlib/libc/stdlib/__atexit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								newlib/libc/stdlib/__atexit.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|  *  Common routine to implement atexit-like functionality. | ||||
|  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdlib.h> | ||||
| #include <reent.h> | ||||
| #include <sys/lock.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| /* | ||||
|  * Register a function to be performed at exit or on shared library unload. | ||||
|  */ | ||||
|  | ||||
| int | ||||
| _DEFUN (__register_exitproc, | ||||
| 	(type, fn, arg, d), | ||||
| 	int type _AND | ||||
| 	void (*fn) (void) _AND | ||||
| 	void *arg _AND | ||||
| 	void *d) | ||||
| { | ||||
|   struct _on_exit_args * args; | ||||
|   register struct _atexit *p; | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __LOCK_INIT(static, lock); | ||||
|  | ||||
|   __lock_acquire(lock); | ||||
| #endif | ||||
|  | ||||
|   p = _GLOBAL_REENT->_atexit; | ||||
|   if (p == NULL) | ||||
|     _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0; | ||||
|   if (p->_ind >= _ATEXIT_SIZE) | ||||
|     { | ||||
|       p = (struct _atexit *) malloc (sizeof *p); | ||||
|       if (p == NULL) | ||||
| 	{ | ||||
| #ifndef __SINGLE_THREAD__ | ||||
| 	  __lock_release(lock); | ||||
| #endif | ||||
| 	  return -1; | ||||
| 	} | ||||
|       p->_ind = 0; | ||||
|       p->_next = _GLOBAL_REENT->_atexit; | ||||
|       _GLOBAL_REENT->_atexit = p; | ||||
| #ifndef _REENT_SMALL | ||||
|       p->_on_exit_args._fntypes = 0; | ||||
|       p->_on_exit_args._is_cxa = 0; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|   if (type != __et_atexit) | ||||
|     { | ||||
| #ifdef _REENT_SMALL | ||||
|       args = p->_on_exit_args_ptr; | ||||
|       if (args == NULL) | ||||
| 	{ | ||||
| 	  args = malloc (sizeof * p->_on_exit_args_ptr); | ||||
| 	  if (args == NULL) | ||||
| 	    { | ||||
| #ifndef __SINGLE_THREAD__ | ||||
| 	      __lock_release(lock); | ||||
| #endif | ||||
| 	      return -1; | ||||
| 	    } | ||||
| 	  args->_fntypes = 0; | ||||
| 	  args->_is_cxa = 0; | ||||
| 	  p->_on_exit_args_ptr = args; | ||||
| 	} | ||||
| #else | ||||
|       args = &p->_on_exit_args; | ||||
| #endif | ||||
|       args->_fnargs[p->_ind] = arg; | ||||
|       args->_dso_handle[p->_ind] = d; | ||||
|       args->_fntypes |= (1 << p->_ind); | ||||
|       if (type == __et_cxa) | ||||
| 	args->_is_cxa |= (1 << p->_ind); | ||||
|     } | ||||
|   p->_fns[p->_ind++] = fn; | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										83
									
								
								newlib/libc/stdlib/__call_atexit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								newlib/libc/stdlib/__call_atexit.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| /* | ||||
|  * COmmon routine to call call registered atexit-like routines. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <reent.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| /* | ||||
|  * Call registered exit handlers.  If D is null then all handlers are called, | ||||
|  * otherwise only the handlers from that DSO are called. | ||||
|  */ | ||||
|  | ||||
| void  | ||||
| _DEFUN (__call_exitprocs, (code, d), | ||||
| 	int code _AND _PTR d) | ||||
| { | ||||
|   register struct _atexit *p; | ||||
|   struct _atexit **lastp; | ||||
|   register struct _on_exit_args * args; | ||||
|   register int n; | ||||
|   int i; | ||||
|   void (*fn) (void); | ||||
|  | ||||
|   p = _GLOBAL_REENT->_atexit; | ||||
|   lastp = &_GLOBAL_REENT->_atexit; | ||||
|   while (p) | ||||
|     { | ||||
| #ifdef _REENT_SMALL | ||||
|       args = p->_on_exit_args_ptr; | ||||
| #else | ||||
|       args = &p->_on_exit_args; | ||||
| #endif | ||||
|       for (n = p->_ind - 1; n >= 0; n--) | ||||
| 	{ | ||||
| 	  i = 1 << n; | ||||
|  | ||||
| 	  /* Skip functions not from this dso.  */ | ||||
| 	  if (d && (!args || args->_dso_handle[n] != d)) | ||||
| 	    continue; | ||||
|  | ||||
| 	  /* Remove the function now to protect against the | ||||
| 	     function calling exit recursively.  */ | ||||
| 	  fn = p->_fns[n]; | ||||
| 	  if (n == p->_ind - 1) | ||||
| 	    p->_ind--; | ||||
| 	  else | ||||
| 	    p->_fns[n] = NULL; | ||||
|  | ||||
| 	  /* Skip functions that have already been called.  */ | ||||
| 	  if (!fn) | ||||
| 	    continue; | ||||
|  | ||||
| 	  /* Call the function.  */ | ||||
| 	  if (!args || (args->_fntypes & i) == 0) | ||||
| 	    fn (); | ||||
| 	  else if ((args->_is_cxa & i) == 0) | ||||
| 	    (*((void (*)(int, _PTR)) fn))(code, args->_fnargs[n]); | ||||
| 	  else | ||||
| 	    (*((void (*)(_PTR)) fn))(args->_fnargs[n]); | ||||
| 	} | ||||
|  | ||||
|       /* Move to the next block.  Free empty blocks except the last one, | ||||
| 	 which is part of _GLOBAL_REENT.  */ | ||||
|       if (p->_ind == 0 && p->_next) | ||||
| 	{ | ||||
| 	  /* Remove empty block from the list.  */ | ||||
| 	  *lastp = p->_next; | ||||
| #ifdef _REENT_SMALL | ||||
| 	  if (args) | ||||
| 	    free (args); | ||||
| #endif | ||||
| 	  free (p); | ||||
| 	  p = *lastp; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  lastp = &p->_next; | ||||
| 	  p = p->_next; | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| @@ -50,10 +50,8 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, | ||||
| <<lseek>>, <<read>>, <<sbrk>>, <<write>>. | ||||
| */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdlib.h> | ||||
| #include <reent.h> | ||||
| #include <sys/lock.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| /* | ||||
|  * Register a function to be performed at exit. | ||||
| @@ -64,45 +62,5 @@ _DEFUN (atexit, | ||||
| 	(fn), | ||||
| 	_VOID _EXFUN ((*fn), (_VOID))) | ||||
| { | ||||
|   register struct _atexit *p; | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __LOCK_INIT(static, lock); | ||||
|  | ||||
|   __lock_acquire(lock); | ||||
| #endif | ||||
|        | ||||
|   /* _REENT_SMALL atexit() doesn't allow more than the required 32 entries.  */ | ||||
| #ifndef _REENT_SMALL | ||||
|   if ((p = _GLOBAL_REENT->_atexit) == NULL) | ||||
|     _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0; | ||||
|   if (p->_ind >= _ATEXIT_SIZE) | ||||
|     { | ||||
|       if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL) | ||||
|         { | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|           __lock_release(lock); | ||||
| #endif | ||||
|           return -1; | ||||
|         } | ||||
|       p->_ind = 0; | ||||
|       p->_on_exit_args._fntypes = 0; | ||||
|       p->_next = _GLOBAL_REENT->_atexit; | ||||
|       _GLOBAL_REENT->_atexit = p; | ||||
|     } | ||||
| #else | ||||
|   p = &_GLOBAL_REENT->_atexit; | ||||
|   if (p->_ind >= _ATEXIT_SIZE) | ||||
|     { | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|       __lock_release(lock); | ||||
| #endif | ||||
|       return -1; | ||||
|     } | ||||
| #endif | ||||
|   p->_fns[p->_ind++] = fn; | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|   return 0; | ||||
|   return __register_exitproc (__et_atexit, fn, NULL, NULL); | ||||
| } | ||||
|   | ||||
| @@ -1,13 +1,14 @@ | ||||
| /* | ||||
|  *	%G% (UofMD) %D% | ||||
|  *	Common definitions for atexit-like routines | ||||
|  */ | ||||
|  | ||||
| #define	ATEXIT_SIZE 32	/* must be at least 32 to guarantee ANSI conformance */ | ||||
|  | ||||
| struct atexit { | ||||
| 	struct	atexit *next;		/* next in list */ | ||||
| 	int	ind;			/* next index in this table */ | ||||
| 	void	(*fns[ATEXIT_SIZE])();	/* the table itself */ | ||||
| enum __atexit_types | ||||
| { | ||||
|   __et_atexit, | ||||
|   __et_onexit, | ||||
|   __et_cxa | ||||
| }; | ||||
|  | ||||
| struct atexit *__atexit;	/* points to head of LIFO stack */ | ||||
| void __call_exitprocs _PARAMS ((int, _PTR)); | ||||
| int __register_exitproc _PARAMS ((int, void (*fn) (void), _PTR, _PTR)); | ||||
|  | ||||
|   | ||||
							
								
								
									
										23
									
								
								newlib/libc/stdlib/cxa_atexit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								newlib/libc/stdlib/cxa_atexit.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| /* | ||||
|  * Implementation of __cxa_atexit. | ||||
|  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdlib.h> | ||||
| #include <reent.h> | ||||
| #include <sys/lock.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| /* | ||||
|  * Register a function to be performed at exit or DSO unload. | ||||
|  */ | ||||
|  | ||||
| int | ||||
| _DEFUN (__cxa_atexit, | ||||
| 	(fn, arg, d), | ||||
| 	void (*fn) (void *) _AND | ||||
| 	void *arg _AND | ||||
| 	void *d) | ||||
| { | ||||
|   return __register_exitproc (__et_cxa, (void (*)(void)) fn, arg, d); | ||||
| } | ||||
							
								
								
									
										20
									
								
								newlib/libc/stdlib/cxa_finalize.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								newlib/libc/stdlib/cxa_finalize.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| /* | ||||
|  * Implementation if __cxa_finalize. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <reent.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| /* | ||||
|  * Call registered exit handlers.  If D is null then all handlers are called, | ||||
|  * otherwise only the handlers from that DSO are called. | ||||
|  */ | ||||
|  | ||||
| void  | ||||
| _DEFUN (__cxa_finalize, (d), | ||||
| 	void * d) | ||||
| { | ||||
|   __call_exitprocs (0, d); | ||||
| } | ||||
| @@ -48,6 +48,7 @@ Supporting OS subroutines required: <<_exit>>. | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h>	/* for _exit() declaration */ | ||||
| #include <reent.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| #ifndef _REENT_ONLY | ||||
|  | ||||
| @@ -59,43 +60,7 @@ void | ||||
| _DEFUN (exit, (code), | ||||
| 	int code) | ||||
| { | ||||
|   register struct _atexit *p; | ||||
|   register struct _on_exit_args * args; | ||||
|   register int n; | ||||
|   int i; | ||||
|  | ||||
| #ifdef _REENT_SMALL | ||||
|   p = &_GLOBAL_REENT->_atexit; | ||||
|   args = p->_on_exit_args_ptr; | ||||
|    | ||||
|   if (args == NULL) | ||||
|     { | ||||
|       for (n = p->_ind; n--;) | ||||
|         p->_fns[n] (); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1) | ||||
|         if (args->_fntypes & i) | ||||
|           (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]); | ||||
|         else | ||||
|           p->_fns[n] (); | ||||
|     } | ||||
| #else | ||||
|   p = _GLOBAL_REENT->_atexit; | ||||
|   while (p) | ||||
|     { | ||||
|       args = & p->_on_exit_args; | ||||
|    | ||||
|       for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1) | ||||
|         if (args->_fntypes & i) | ||||
|           (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]); | ||||
|         else | ||||
|           p->_fns[n] (); | ||||
|  | ||||
|       p = p->_next; | ||||
|     } | ||||
| #endif | ||||
|   __call_exitprocs (code, NULL); | ||||
|  | ||||
|   if (_GLOBAL_REENT->__cleanup) | ||||
|     (*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT); | ||||
|   | ||||
| @@ -56,7 +56,7 @@ Supporting OS subroutines required: None | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdlib.h> | ||||
| #include <reent.h> | ||||
| #include "atexit.h" | ||||
|  | ||||
| /* | ||||
|  * Register a function to be performed at exit. | ||||
| @@ -68,40 +68,5 @@ _DEFUN (on_exit, | ||||
| 	_VOID _EXFUN ((*fn), (int, _PTR)) _AND | ||||
|         _PTR arg) | ||||
| { | ||||
|   struct _on_exit_args * args; | ||||
|   register struct _atexit *p; | ||||
|   void (*x)(void) = (void (*)(void))fn; | ||||
|  | ||||
| /* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries.  */ | ||||
| #ifdef _REENT_SMALL | ||||
|   p = &_GLOBAL_REENT->_atexit; | ||||
|   if (p->_ind >= _ATEXIT_SIZE) | ||||
|     return -1; | ||||
|   args = p->_on_exit_args_ptr; | ||||
|   if (args == NULL) | ||||
|     { | ||||
|       args = malloc (sizeof * p->_on_exit_args_ptr); | ||||
|       if (args == NULL) | ||||
|         return -1; | ||||
|       args->_fntypes = 0; | ||||
|       p->_on_exit_args_ptr = args; | ||||
|     } | ||||
| #else | ||||
|   if ((p = _GLOBAL_REENT->_atexit) == NULL) | ||||
|     _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0; | ||||
|   if (p->_ind >= _ATEXIT_SIZE) | ||||
|     { | ||||
|       if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL) | ||||
|         return -1; | ||||
|       p->_ind = 0; | ||||
|       p->_on_exit_args._fntypes = 0; | ||||
|       p->_next = _GLOBAL_REENT->_atexit; | ||||
|       _GLOBAL_REENT->_atexit = p; | ||||
|     } | ||||
|   args = & p->_on_exit_args; | ||||
| #endif | ||||
|   args->_fntypes |= (1 << p->_ind); | ||||
|   args->_fnargs[p->_ind] = arg; | ||||
|   p->_fns[p->_ind++] = x; | ||||
|   return 0; | ||||
|   return __register_exitproc (__et_onexit, (void (*)(void)) fn, arg, NULL); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user