forked from KolibriOS/kolibrios
newlib-2.1.0
git-svn-id: svn://kolibrios.org@4921 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
@@ -1,5 +1,35 @@
|
||||
/*
|
||||
* Common routine to implement atexit-like functionality.
|
||||
*
|
||||
* This is also the key function to be configured as lite exit, a size-reduced
|
||||
* implementation of exit that doesn't invoke clean-up functions such as _fini
|
||||
* or global destructors.
|
||||
*
|
||||
* Default (without lite exit) call graph is like:
|
||||
* _start -> atexit -> __register_exitproc
|
||||
* _start -> __libc_init_array -> __cxa_atexit -> __register_exitproc
|
||||
* on_exit -> __register_exitproc
|
||||
* _start -> exit -> __call_exitprocs
|
||||
*
|
||||
* Here an -> means arrow tail invokes arrow head. All invocations here
|
||||
* are non-weak reference in current newlib/libgloss.
|
||||
*
|
||||
* Lite exit makes some of above calls as weak reference, so that size expansive
|
||||
* functions __register_exitproc and __call_exitprocs may not be linked. These
|
||||
* calls are:
|
||||
* _start w-> atexit
|
||||
* __cxa_atexit w-> __register_exitproc
|
||||
* exit w-> __call_exitprocs
|
||||
*
|
||||
* Lite exit also makes sure that __call_exitprocs will be referenced as non-weak
|
||||
* whenever __register_exitproc is referenced as non-weak.
|
||||
*
|
||||
* Thus with lite exit libs, a program not explicitly calling atexit or on_exit
|
||||
* will escape from the burden of cleaning up code. A program with atexit or on_exit
|
||||
* will work consistently to normal libs.
|
||||
*
|
||||
* Lite exit is enabled with --enable-lite-exit, and is controlled with macro
|
||||
* _LITE_EXIT.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -10,7 +40,23 @@
|
||||
|
||||
/* Make this a weak reference to avoid pulling in malloc. */
|
||||
void * malloc(size_t) _ATTRIBUTE((__weak__));
|
||||
__LOCK_INIT_RECURSIVE(, __atexit_lock);
|
||||
|
||||
#ifdef _LITE_EXIT
|
||||
/* As __call_exitprocs is weak reference in lite exit, make a
|
||||
non-weak reference to it here. */
|
||||
const void * __atexit_dummy = &__call_exitprocs;
|
||||
#endif
|
||||
|
||||
#ifndef __SINGLE_THREAD__
|
||||
extern _LOCK_RECURSIVE_T __atexit_lock;
|
||||
#endif
|
||||
|
||||
#ifdef _REENT_GLOBAL_ATEXIT
|
||||
static struct _atexit _global_atexit0 = _ATEXIT_INIT;
|
||||
# define _GLOBAL_ATEXIT0 (&_global_atexit0)
|
||||
#else
|
||||
# define _GLOBAL_ATEXIT0 (&_GLOBAL_REENT->_atexit0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Register a function to be performed at exit or on shared library unload.
|
||||
@@ -31,9 +77,9 @@ _DEFUN (__register_exitproc,
|
||||
__lock_acquire_recursive(__atexit_lock);
|
||||
#endif
|
||||
|
||||
p = _GLOBAL_REENT->_atexit;
|
||||
p = _GLOBAL_ATEXIT;
|
||||
if (p == NULL)
|
||||
_GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
|
||||
_GLOBAL_ATEXIT = p = _GLOBAL_ATEXIT0;
|
||||
if (p->_ind >= _ATEXIT_SIZE)
|
||||
{
|
||||
#ifndef _ATEXIT_DYNAMIC_ALLOC
|
||||
@@ -53,11 +99,13 @@ _DEFUN (__register_exitproc,
|
||||
return -1;
|
||||
}
|
||||
p->_ind = 0;
|
||||
p->_next = _GLOBAL_REENT->_atexit;
|
||||
_GLOBAL_REENT->_atexit = p;
|
||||
p->_next = _GLOBAL_ATEXIT;
|
||||
_GLOBAL_ATEXIT = p;
|
||||
#ifndef _REENT_SMALL
|
||||
p->_on_exit_args._fntypes = 0;
|
||||
p->_on_exit_args._is_cxa = 0;
|
||||
#else
|
||||
p->_on_exit_args_ptr = NULL;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -74,7 +122,7 @@ _DEFUN (__register_exitproc,
|
||||
if (args == NULL)
|
||||
{
|
||||
#ifndef __SINGLE_THREAD__
|
||||
__lock_release(lock);
|
||||
__lock_release(__atexit_lock);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user