Use global atexit data for all configurations

For the exit processing only members of _GLOBAL_REENT were used by default.  If
the _REENT_GLOBAL_ATEXIT option was enabled, then the data structures were
provided through dedicated global objects.  Make this option the default.
Remove the option.  Rename struct _reent members _atexit and _atexit0 to
_reserved_6 and _reserved_7, respectively.  Provide them only if
_REENT_BACKWARD_BINARY_COMPAT is defined.
This commit is contained in:
Sebastian Huber 2022-05-13 13:44:13 +02:00
parent 9035e406cb
commit 2faeaf50fd
12 changed files with 46 additions and 107 deletions

View File

@ -187,12 +187,13 @@ __start:
; calling atexit drags in malloc, so instead poke the function ; calling atexit drags in malloc, so instead poke the function
; address directly into the reent structure ; address directly into the reent structure
ld r1, [gp, @_impure_ptr@sda] ld r1, [gp, @_impure_ptr@sda]
mov_s r0, @_fini mov_s r1, @__atexit0
add r1, r1, 0x14c ; &_GLOBAL_REENT->atexit0 mov_s r2, @__atexit
st r1, [r1, -4] ; _GLOBAL_REENT->atexit st_s r1, [r2, 0] ; __atexit = &__atexit0
st_s r0, [r1, 8] ; _GLOBAL_REENT->atexit0._fns[0]
mov_s r0, 1 mov_s r0, 1
st_s r0, [r1, 4] ; _GLOBAL_REENT->atexit0._ind st_s r0, [r1, 4] ; __atexit0._ind = 1
mov_s r0, @_fini
st_s r0, [r1, 8] ; __atexit0._fns[0] = _fini
; branch to _init ; branch to _init
#if defined (__ARCEM__) || defined (__ARCHS__) #if defined (__ARCEM__) || defined (__ARCHS__)
jl @_init jl @_init

View File

@ -113,23 +113,19 @@ _external_start:
#else #else
; calling atexit drags in malloc, so instead poke the function ; calling atexit drags in malloc, so instead poke the function
; address directly into the reent structure ; address directly into the reent structure
mov r2,%low(__impure_ptr) mov r1,%low(__atexit0)
movt r2,%high(__impure_ptr) movt r1,%high(__atexit0)
ldr r2,[r2] mov r2,%low(__atexit)
mov r1,%low(fini) movt r2,%high(__atexit)
movt r1,%high(fini)
#ifdef __STRUCT_ALIGN_64__ #ifdef __STRUCT_ALIGN_64__
#error #error "not implemented"
add r2,r2,need_to_find_out; &_GLOBAL_REENT->atexit0
str r2, [r2,-1];??or -2?; _GLOBAL_REENT->atexit
mov r0, 1
str r0, [r2,1] ; _GLOBAL_REENT->atexit0._ind
str r1, [r2,2] ; _GLOBAL_REENT->atexit0._fns[0]
#else /* !__STRUCT_ALIGN_64__ */ #else /* !__STRUCT_ALIGN_64__ */
add r0,r2,0x14c ; &_GLOBAL_REENT->atexit0 str r1, [r2, 0] ; __atexit = &__atexit0
str r0, [r0,-1] ; _GLOBAL_REENT->atexit movr r0, 1
mov r0, 1 str r0, [r1, 4] ; __atexit0._ind = 1
strd r0, [r2,0x2a] ; _GLOBAL_REENT->atexit0._ind mov r0,%low(fini)
movt r0,%high(fini)
str r0, [r1, 8] ; __atexit0._fns[0] = fini
#endif /* !__STRUCT_ALIGN_64__ */ #endif /* !__STRUCT_ALIGN_64__ */
#endif /* !0 */ #endif /* !0 */
;; Call global and static constructors ;; Call global and static constructors

View File

@ -37,9 +37,9 @@ atexit (void (*fn) (void))
{ {
register struct _atexit *p; register struct _atexit *p;
p = _GLOBAL_REENT->_atexit; p = __atexit;
if (p == NULL) if (p == NULL)
_GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0; __atexit = p = &__atexit0;
if (p->_ind >= _ATEXIT_SIZE) if (p->_ind >= _ATEXIT_SIZE)
{ {
return -1; return -1;

View File

@ -294,12 +294,6 @@ One feature can be enabled by specifying `--enable-FEATURE=yes' or
Disable dynamic allocation of atexit entries. Disable dynamic allocation of atexit entries.
Most hosts and targets have it enabled in configure.host. Most hosts and targets have it enabled in configure.host.
`--enable-newlib-global-atexit'
Enable atexit data structure as global variable. By doing so it is
move out of _reent structure, and can be garbage collected if atexit
is not referenced.
Disabled by default.
`--enable-newlib-global-stdio-streams' `--enable-newlib-global-stdio-streams'
Enable to move the stdio stream FILE objects out of struct _reent and make Enable to move the stdio stream FILE objects out of struct _reent and make
them global. The stdio stream pointers of struct _reent are initialized them global. The stdio stream pointers of struct _reent are initialized

9
newlib/configure vendored
View File

@ -2373,12 +2373,11 @@ if test "${enable_newlib_global_atexit+set}" = set; then :
enableval=$enable_newlib_global_atexit; if test "${newlib_global_atexit+set}" != set; then enableval=$enable_newlib_global_atexit; if test "${newlib_global_atexit+set}" != set; then
case "${enableval}" in case "${enableval}" in
yes) newlib_global_atexit=yes ;; yes) newlib_global_atexit=yes ;;
no) newlib_global_atexit=no ;;
*) as_fn_error $? "bad value ${enableval} for newlib-global-atexit option" "$LINENO" 5 ;; *) as_fn_error $? "bad value ${enableval} for newlib-global-atexit option" "$LINENO" 5 ;;
esac esac
fi fi
else else
newlib_global_atexit=no newlib_global_atexit=yes
fi fi
# Check whether --enable-newlib-reent-small was given. # Check whether --enable-newlib-reent-small was given.
@ -6484,12 +6483,6 @@ $as_echo "#define _ATEXIT_DYNAMIC_ALLOC 1" >>confdefs.h
fi fi
if test "${newlib_global_atexit}" = "yes"; then
$as_echo "#define _REENT_GLOBAL_ATEXIT 1" >>confdefs.h
fi
if test "${newlib_fvwrite_in_streamio}" = "yes"; then if test "${newlib_fvwrite_in_streamio}" = "yes"; then
$as_echo "#define _FVWRITE_IN_STREAMIO 1" >>confdefs.h $as_echo "#define _FVWRITE_IN_STREAMIO 1" >>confdefs.h

View File

@ -142,16 +142,16 @@ AC_ARG_ENABLE(newlib-atexit-dynamic-alloc,
dnl Support --enable-newlib-global-atexit dnl Support --enable-newlib-global-atexit
dnl Enable atexit data structure as global variables to save memory usage in dnl Enable atexit data structure as global variables to save memory usage in
dnl _reent. dnl _reent. This is no longer optional. It is enabled in all Newlib
dnl configurations.
AC_ARG_ENABLE(newlib-global-atexit, AC_ARG_ENABLE(newlib-global-atexit,
[ --enable-newlib-global-atexit enable atexit data structure as global], [ --enable-newlib-global-atexit enable atexit data structure as global],
[if test "${newlib_global_atexit+set}" != set; then [if test "${newlib_global_atexit+set}" != set; then
case "${enableval}" in case "${enableval}" in
yes) newlib_global_atexit=yes ;; yes) newlib_global_atexit=yes ;;
no) newlib_global_atexit=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for newlib-global-atexit option) ;; *) AC_MSG_ERROR(bad value ${enableval} for newlib-global-atexit option) ;;
esac esac
fi], [newlib_global_atexit=no])dnl fi], [newlib_global_atexit=yes])dnl
dnl Support --enable-newlib-reent-small dnl Support --enable-newlib-reent-small
AC_ARG_ENABLE(newlib-reent-small, AC_ARG_ENABLE(newlib-reent-small,
@ -470,10 +470,6 @@ if test "${newlib_atexit_dynamic_alloc}" = "yes"; then
AC_DEFINE(_ATEXIT_DYNAMIC_ALLOC, 1, [If atexit() may dynamically allocate space for cleanup functions.]) AC_DEFINE(_ATEXIT_DYNAMIC_ALLOC, 1, [If atexit() may dynamically allocate space for cleanup functions.])
fi fi
if test "${newlib_global_atexit}" = "yes"; then
AC_DEFINE(_REENT_GLOBAL_ATEXIT, 1, [Define if declare atexit data as global.])
fi
if test "${newlib_fvwrite_in_streamio}" = "yes"; then if test "${newlib_fvwrite_in_streamio}" = "yes"; then
AC_DEFINE(_FVWRITE_IN_STREAMIO, 1, [Define if ivo supported in streamio.]) AC_DEFINE(_FVWRITE_IN_STREAMIO, 1, [Define if ivo supported in streamio.])
fi fi

View File

@ -242,7 +242,6 @@
#define __FILENAME_MAX__ 255 #define __FILENAME_MAX__ 255
#define _READ_WRITE_RETURN_TYPE _ssize_t #define _READ_WRITE_RETURN_TYPE _ssize_t
#define __DYNAMIC_REENT__ #define __DYNAMIC_REENT__
#define _REENT_GLOBAL_ATEXIT
#define _REENT_GLOBAL_STDIO_STREAMS #define _REENT_GLOBAL_STDIO_STREAMS
#endif #endif

View File

@ -105,13 +105,6 @@ struct _atexit {
# define _ATEXIT_INIT {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}} # define _ATEXIT_INIT {_NULL, 0, {_NULL}, {{_NULL}, {_NULL}, 0, 0}}
#endif #endif
#ifdef _REENT_GLOBAL_ATEXIT
# define _REENT_INIT_ATEXIT
#else
# define _REENT_INIT_ATEXIT \
_NULL, _ATEXIT_INIT,
#endif
/* /*
* Stdio buffers. * Stdio buffers.
* *
@ -346,10 +339,12 @@ struct _rand48 {
#define _REENT_INIT_RESERVED_0 0, #define _REENT_INIT_RESERVED_0 0,
#define _REENT_INIT_RESERVED_1 0, #define _REENT_INIT_RESERVED_1 0,
#define _REENT_INIT_RESERVED_2 0, #define _REENT_INIT_RESERVED_2 0,
#define _REENT_INIT_RESERVED_6_7 _NULL, _ATEXIT_INIT,
#else #else
#define _REENT_INIT_RESERVED_0 /* Nothing to initialize */ #define _REENT_INIT_RESERVED_0 /* Nothing to initialize */
#define _REENT_INIT_RESERVED_1 /* Nothing to initialize */ #define _REENT_INIT_RESERVED_1 /* Nothing to initialize */
#define _REENT_INIT_RESERVED_2 /* Nothing to initialize */ #define _REENT_INIT_RESERVED_2 /* Nothing to initialize */
#define _REENT_INIT_RESERVED_6_7 /* Nothing to initialize */
#endif #endif
/* /*
@ -428,11 +423,10 @@ struct _reent
/* signal info */ /* signal info */
void (**(_sig_func))(int); void (**(_sig_func))(int);
# ifndef _REENT_GLOBAL_ATEXIT #ifdef _REENT_BACKWARD_BINARY_COMPAT
/* atexit stuff */ struct _atexit *_reserved_6;
struct _atexit *_atexit; struct _atexit _reserved_7;
struct _atexit _atexit0; #endif
# endif
struct _glue __sglue; /* root of glue chain */ struct _glue __sglue; /* root of glue chain */
__FILE *__sf; /* file descriptors */ __FILE *__sf; /* file descriptors */
@ -461,7 +455,7 @@ struct _reent
_NULL, \ _NULL, \
_NULL, \ _NULL, \
_NULL, \ _NULL, \
_REENT_INIT_ATEXIT \ _REENT_INIT_RESERVED_6_7 \
{_NULL, 0, _NULL}, \ {_NULL, 0, _NULL}, \
_NULL, \ _NULL, \
_NULL, \ _NULL, \
@ -499,7 +493,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
_NULL, \ _NULL, \
_NULL, \ _NULL, \
_NULL, \ _NULL, \
_REENT_INIT_ATEXIT \ _REENT_INIT_RESERVED_6_7 \
{_NULL, 0, _NULL}, \ {_NULL, 0, _NULL}, \
_NULL, \ _NULL, \
_NULL, \ _NULL, \
@ -694,11 +688,10 @@ struct _reent
#endif #endif
} _new; } _new;
# ifndef _REENT_GLOBAL_ATEXIT #ifdef _REENT_BACKWARD_BINARY_COMPAT
/* atexit stuff */ struct _atexit *_reserved_6;
struct _atexit *_atexit; /* points to head of LIFO stack */ struct _atexit _reserved_7;
struct _atexit _atexit0; /* one guaranteed table, required by ANSI */ #endif
# endif
/* signal info */ /* signal info */
void (**_sig_func)(int); void (**_sig_func)(int);
@ -767,7 +760,7 @@ struct _reent
{0, {0}} \ {0, {0}} \
} \ } \
}, \ }, \
_REENT_INIT_ATEXIT \ _REENT_INIT_RESERVED_6_7 \
_NULL \ _NULL \
_REENT_INIT_SGLUE(&(var)) \ _REENT_INIT_SGLUE(&(var)) \
} }
@ -869,12 +862,8 @@ extern int _fwalk_sglue (struct _reent *, int (*)(struct _reent *, __FILE *),
#define _GLOBAL_REENT (&_impure_data) #define _GLOBAL_REENT (&_impure_data)
#ifdef _REENT_GLOBAL_ATEXIT extern struct _atexit *__atexit; /* points to head of LIFO stack */
extern struct _atexit *_global_atexit; /* points to head of LIFO stack */ extern struct _atexit __atexit0; /* one guaranteed table, required by ANSI */
# define _GLOBAL_ATEXIT _global_atexit
#else
# define _GLOBAL_ATEXIT (_GLOBAL_REENT->_atexit)
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -93,25 +93,6 @@ _reclaim_reent (struct _reent *ptr)
_free_r (ptr, ptr->_misc); _free_r (ptr, ptr->_misc);
#endif #endif
#ifndef _REENT_GLOBAL_ATEXIT
/* atexit stuff */
# ifdef _REENT_SMALL
if (ptr->_atexit && ptr->_atexit->_on_exit_args_ptr)
_free_r (ptr, ptr->_atexit->_on_exit_args_ptr);
# else
if ((ptr->_atexit) && (ptr->_atexit != &ptr->_atexit0))
{
struct _atexit *p, *q;
for (p = ptr->_atexit; p != &ptr->_atexit0;)
{
q = p;
p = p->_next;
_free_r (ptr, q);
}
}
# endif
#endif
if (ptr->_cvtbuf) if (ptr->_cvtbuf)
_free_r (ptr, ptr->_cvtbuf); _free_r (ptr, ptr->_cvtbuf);
/* We should free _sig_func to avoid a memory leak, but how to /* We should free _sig_func to avoid a memory leak, but how to

View File

@ -53,12 +53,7 @@ const void * __atexit_dummy = &__call_exitprocs;
extern _LOCK_RECURSIVE_T __atexit_recursive_mutex; extern _LOCK_RECURSIVE_T __atexit_recursive_mutex;
#endif #endif
#ifdef _REENT_GLOBAL_ATEXIT struct _atexit __atexit0 = _ATEXIT_INIT;
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. * Register a function to be performed at exit or on shared library unload.
@ -77,10 +72,10 @@ __register_exitproc (int type,
__lock_acquire_recursive(__atexit_recursive_mutex); __lock_acquire_recursive(__atexit_recursive_mutex);
#endif #endif
p = _GLOBAL_ATEXIT; p = __atexit;
if (p == NULL) if (p == NULL)
{ {
_GLOBAL_ATEXIT = p = _GLOBAL_ATEXIT0; __atexit = p = &__atexit0;
#ifdef _REENT_SMALL #ifdef _REENT_SMALL
extern struct _on_exit_args * const __on_exit_args _ATTRIBUTE ((weak)); extern struct _on_exit_args * const __on_exit_args _ATTRIBUTE ((weak));
if (&__on_exit_args != NULL) if (&__on_exit_args != NULL)
@ -104,8 +99,8 @@ __register_exitproc (int type,
return -1; return -1;
} }
p->_ind = 0; p->_ind = 0;
p->_next = _GLOBAL_ATEXIT; p->_next = __atexit;
_GLOBAL_ATEXIT = p; __atexit = p;
#ifndef _REENT_SMALL #ifndef _REENT_SMALL
p->_on_exit_args._fntypes = 0; p->_on_exit_args._fntypes = 0;
p->_on_exit_args._is_cxa = 0; p->_on_exit_args._is_cxa = 0;

View File

@ -17,9 +17,7 @@ void free(void *) _ATTRIBUTE((__weak__));
__LOCK_INIT_RECURSIVE(, __atexit_recursive_mutex); __LOCK_INIT_RECURSIVE(, __atexit_recursive_mutex);
#endif #endif
#ifdef _REENT_GLOBAL_ATEXIT struct _atexit *__atexit = _NULL;
struct _atexit *_global_atexit = _NULL;
#endif
#ifdef _WANT_REGISTER_FINI #ifdef _WANT_REGISTER_FINI
@ -83,8 +81,8 @@ __call_exitprocs (int code, void *d)
restart: restart:
p = _GLOBAL_ATEXIT; p = __atexit;
lastp = &_GLOBAL_ATEXIT; lastp = &__atexit;
while (p) while (p)
{ {
#ifdef _REENT_SMALL #ifdef _REENT_SMALL

View File

@ -378,9 +378,6 @@
/* Verify _REENT_CHECK macros allocate memory successfully. */ /* Verify _REENT_CHECK macros allocate memory successfully. */
#undef _REENT_CHECK_VERIFY #undef _REENT_CHECK_VERIFY
/* Define if declare atexit data as global. */
#undef _REENT_GLOBAL_ATEXIT
/* Define if using retargetable functions for default lock routines. */ /* Define if using retargetable functions for default lock routines. */
#undef _RETARGETABLE_LOCKING #undef _RETARGETABLE_LOCKING