From e2ac49d3d7c6445c07467e2a4d271d5664f83830 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Tue, 2 Jul 2013 21:30:57 +0000 Subject: 2013-07-02 Joey Ye Lite exit support. * README: Add information about lite-exit. * acconfig.h (_LITE_EXIT): New macro. * configure.in (enable-lite-exit): New option. (_LITE_EXIT): Define new macro. * configure: Regenerated. * newlib.hin (_LITE_EXIT): New macro. * libc/stdlib/__atexit.c [_LITE_EXIT]: Add dummy explicit reference to __call_exitprocs. * libc/stdlib/cxa_atexit.c [_LITE_EXIT]: Make __register_exitproc a weak reference. * libc/stdlib/exit.c (exit)[_LITE_EXIT]: Remove TWS and weakly reference __call_exitprocs. --- newlib/libc/stdlib/__atexit.c | 36 ++++++++++++++++++++++++++++++++++++ newlib/libc/stdlib/cxa_atexit.c | 11 ++++++++++- newlib/libc/stdlib/exit.c | 9 +++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) (limited to 'newlib/libc') diff --git a/newlib/libc/stdlib/__atexit.c b/newlib/libc/stdlib/__atexit.c index f04f00d8e..d36a1a4e5 100644 --- a/newlib/libc/stdlib/__atexit.c +++ b/newlib/libc/stdlib/__atexit.c @@ -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 @@ -11,6 +41,12 @@ /* Make this a weak reference to avoid pulling in malloc. */ void * malloc(size_t) _ATTRIBUTE((__weak__)); +#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 diff --git a/newlib/libc/stdlib/cxa_atexit.c b/newlib/libc/stdlib/cxa_atexit.c index 8c39236de..c3c0d2a17 100644 --- a/newlib/libc/stdlib/cxa_atexit.c +++ b/newlib/libc/stdlib/cxa_atexit.c @@ -19,5 +19,14 @@ _DEFUN (__cxa_atexit, void *arg _AND void *d) { - return __register_exitproc (__et_cxa, (void (*)(void)) fn, arg, d); +#ifdef _LITE_EXIT + /* Refer to comments in __atexit.c for more details of lite exit. */ + int __register_exitproc _PARAMS ((int, void (*fn) (void), _PTR, _PTR)) + __attribute__ ((weak)); + + if (!__register_exitproc) + return 0; + else +#endif + return __register_exitproc (__et_cxa, (void (*)(void)) fn, arg, d); } diff --git a/newlib/libc/stdlib/exit.c b/newlib/libc/stdlib/exit.c index 195b72454..1dc56944a 100644 --- a/newlib/libc/stdlib/exit.c +++ b/newlib/libc/stdlib/exit.c @@ -54,11 +54,16 @@ Supporting OS subroutines required: <<_exit>>. * Exit, flushing stdio buffers if necessary. */ -void +void _DEFUN (exit, (code), int code) { - __call_exitprocs (code, NULL); +#ifdef _LITE_EXIT + /* Refer to comments in __atexit.c for more details of lite exit. */ + void __call_exitprocs _PARAMS ((int, _PTR)) __attribute__((weak)); + if (__call_exitprocs) +#endif + __call_exitprocs (code, NULL); if (_GLOBAL_REENT->__cleanup) (*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT); -- cgit v1.2.3