diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 19acbe0..2a7d853 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -70,12 +70,23 @@ libc_hidden_proto(__h_errno_location) extern void weak_function _stdio_init(void) attribute_hidden; #ifdef __UCLIBC_HAS_LOCALE__ +# define ___need__locale_init 1 extern void weak_function _locale_init(void) attribute_hidden; +#else +# define ___need__locale_init 0 #endif #ifdef __UCLIBC_HAS_THREADS__ extern void weak_function __pthread_initialize_minimal(void); #endif +/* work around gcc PR32219 */ +static void*init_table[1 + ___need__locale_init] = { +# ifdef __UCLIBC_HAS_LOCALE__ + _locale_init, +# endif + _stdio_init, +}; + /* If __UCLIBC_FORMAT_SHARED_FLAT__, all array initialisation and finalisation * is handled by the routines passed to __uClibc_main(). */ #if defined (__UCLIBC_CTOR_DTOR__) && !defined (__UCLIBC_FORMAT_SHARED_FLAT__) @@ -204,7 +212,7 @@ void __uClibc_init(void) # endif # endif #endif - +#if 0 #ifdef __UCLIBC_HAS_LOCALE__ /* Initialize the global locale structure. */ if (likely(_locale_init!=NULL)) @@ -219,7 +227,15 @@ void __uClibc_init(void) */ if (likely(_stdio_init != NULL)) _stdio_init(); - +#else + { + void (*foo)(void); + int i = 0; + for (foo = init_table[i]; i < 1 + ___need__locale_init; i++) + if (foo) + foo(); + } +#endif } libc_hidden_def(__uClibc_init) diff --git a/libc/stdlib/_atexit.c b/libc/stdlib/_atexit.c index 0d420d3..697c5fc 100644 --- a/libc/stdlib/_atexit.c +++ b/libc/stdlib/_atexit.c @@ -304,6 +304,8 @@ void __exit_handler(int status) #ifdef L_exit extern void weak_function _stdio_term(void) attribute_hidden; +/* work around gcc PR32219 */ +static void*fini_table[1] = {_stdio_term,}; attribute_hidden void (*__exit_cleanup) (int) = 0; __UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); @@ -323,14 +325,15 @@ void exit(int rv) __UCLIBC_MUTEX_UNLOCK(__atexit_lock); __uClibc_fini(); - + { /* If we are using stdio, try to shut it down. At the very least, * this will attempt to commit all buffered writes. It may also * unbuffer all writable files, or close them outright. * Check the stdio routines for details. */ - if (_stdio_term) - _stdio_term(); - + void (*foo)(void) = fini_table[0]; + if (foo) + foo(); + } _exit(rv); } libc_hidden_def(exit)