From d2bb300b9bb7917d33e3bc37fca3bf6ee6e5fcc4 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Mon, 21 Dec 2015 11:49:28 -0500 Subject: [PATCH] Add static instance of _on_exit_args for _REENT_SMALL platforms. 2015-12-21 Freddie Chopin * libc/stdlib/on_exit_args.{c,h}: New files. * libc/stdlib/Makefile.am: Add new source file. * libc/stdlib/Makefile.in: Regenerate. * libc/stdlib/__atexit.c (__register_exitproc): Initialize _on_exit_args_ptr field of _GLOBAL_ATEXIT on first run. * libc/stdlib/on_exit.c: Force linking of static instance of _on_exit_args. * libc/stdlib/cxa_atexit.c: Likewise. --- newlib/ChangeLog | 13 ++++++++- newlib/libc/stdlib/Makefile.am | 1 + newlib/libc/stdlib/Makefile.in | 48 +++++++++++++++++-------------- newlib/libc/stdlib/__atexit.c | 9 +++++- newlib/libc/stdlib/cxa_atexit.c | 9 ++++++ newlib/libc/stdlib/on_exit.c | 9 ++++++ newlib/libc/stdlib/on_exit_args.c | 30 +++++++++++++++++++ newlib/libc/stdlib/on_exit_args.h | 12 ++++++++ 8 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 newlib/libc/stdlib/on_exit_args.c create mode 100644 newlib/libc/stdlib/on_exit_args.h diff --git a/newlib/ChangeLog b/newlib/ChangeLog index c22589285..480eb863f 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,14 @@ +2015-12-21 Freddie Chopin + + * libc/stdlib/on_exit_args.{c,h}: New files. + * libc/stdlib/Makefile.am: Add new source file. + * libc/stdlib/Makefile.in: Regenerate. + * libc/stdlib/__atexit.c (__register_exitproc): Initialize + _on_exit_args_ptr field of _GLOBAL_ATEXIT on first run. + * libc/stdlib/on_exit.c: Force linking of static instance of + _on_exit_args. + * libc/stdlib/cxa_atexit.c: Likewise. + 2015-12-17 Anton Kolesov * libc/machine/arc/asm.h: Define new GCC definition for old compiler. @@ -6,7 +17,7 @@ * libc/machine/arc/memcmp.S: Likewise. * libc/machine/arc/memcpy-archs.S: Likewise. * libc/machine/arc/memcpy-bs.S: Likewise. - * libc/machine/arc/memcpy.S: Likewise. + * libc/machine/arc/memcpy.S: Likewise. * libc/machine/arc/memset-archs.S: Likewise. * libc/machine/arc/memset-archs.S: Likewise. * libc/machine/arc/memset-bs.S: Likewise. * libc/machine/arc/memset.S: Likewise. diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am index 33d4a0c2e..c1067eacb 100644 --- a/newlib/libc/stdlib/Makefile.am +++ b/newlib/libc/stdlib/Makefile.am @@ -46,6 +46,7 @@ GENERAL_SOURCES = \ mlock.c \ mprec.c \ mstats.c \ + on_exit_args.c \ quick_exit.c \ rand.c \ rand_r.c \ diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in index d0368c054..36e81c884 100644 --- a/newlib/libc/stdlib/Makefile.in +++ b/newlib/libc/stdlib/Makefile.in @@ -101,17 +101,17 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \ lib_a-mbstowcs.$(OBJEXT) lib_a-mbstowcs_r.$(OBJEXT) \ lib_a-mbtowc.$(OBJEXT) lib_a-mbtowc_r.$(OBJEXT) \ lib_a-mlock.$(OBJEXT) lib_a-mprec.$(OBJEXT) \ - lib_a-mstats.$(OBJEXT) lib_a-quick_exit.$(OBJEXT) \ - lib_a-rand.$(OBJEXT) lib_a-rand_r.$(OBJEXT) \ - lib_a-realloc.$(OBJEXT) lib_a-reallocf.$(OBJEXT) \ - lib_a-sb_charsets.$(OBJEXT) lib_a-strtod.$(OBJEXT) \ - lib_a-strtodg.$(OBJEXT) lib_a-strtol.$(OBJEXT) \ - lib_a-strtorx.$(OBJEXT) lib_a-strtoul.$(OBJEXT) \ - lib_a-utoa.$(OBJEXT) lib_a-wcstod.$(OBJEXT) \ - lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \ - lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \ - lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \ - $(am__objects_1) + lib_a-mstats.$(OBJEXT) lib_a-on_exit_args.$(OBJEXT) \ + lib_a-quick_exit.$(OBJEXT) lib_a-rand.$(OBJEXT) \ + lib_a-rand_r.$(OBJEXT) lib_a-realloc.$(OBJEXT) \ + lib_a-reallocf.$(OBJEXT) lib_a-sb_charsets.$(OBJEXT) \ + lib_a-strtod.$(OBJEXT) lib_a-strtodg.$(OBJEXT) \ + lib_a-strtol.$(OBJEXT) lib_a-strtorx.$(OBJEXT) \ + lib_a-strtoul.$(OBJEXT) lib_a-utoa.$(OBJEXT) \ + lib_a-wcstod.$(OBJEXT) lib_a-wcstol.$(OBJEXT) \ + lib_a-wcstoul.$(OBJEXT) lib_a-wcstombs.$(OBJEXT) \ + lib_a-wcstombs_r.$(OBJEXT) lib_a-wctomb.$(OBJEXT) \ + lib_a-wctomb_r.$(OBJEXT) $(am__objects_1) am__objects_3 = lib_a-cxa_atexit.$(OBJEXT) \ lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \ lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \ @@ -157,11 +157,11 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \ exit.lo gdtoa-gethex.lo gdtoa-hexnan.lo getenv.lo getenv_r.lo \ itoa.lo labs.lo ldiv.lo ldtoa.lo malloc.lo mblen.lo mblen_r.lo \ mbstowcs.lo mbstowcs_r.lo mbtowc.lo mbtowc_r.lo mlock.lo \ - mprec.lo mstats.lo quick_exit.lo rand.lo rand_r.lo realloc.lo \ - reallocf.lo sb_charsets.lo strtod.lo strtodg.lo strtol.lo \ - strtorx.lo strtoul.lo utoa.lo wcstod.lo wcstol.lo wcstoul.lo \ - wcstombs.lo wcstombs_r.lo wctomb.lo wctomb_r.lo \ - $(am__objects_8) + mprec.lo mstats.lo on_exit_args.lo quick_exit.lo rand.lo \ + rand_r.lo realloc.lo reallocf.lo sb_charsets.lo strtod.lo \ + strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo wcstod.lo \ + wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo wctomb.lo \ + wctomb_r.lo $(am__objects_8) am__objects_10 = cxa_atexit.lo cxa_finalize.lo drand48.lo ecvtbuf.lo \ efgcvt.lo erand48.lo jrand48.lo lcong48.lo lrand48.lo \ mrand48.lo msize.lo mtrim.lo nrand48.lo rand48.lo seed48.lo \ @@ -361,11 +361,11 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \ dtoastub.c environ.c envlock.c eprintf.c exit.c gdtoa-gethex.c \ gdtoa-hexnan.c getenv.c getenv_r.c itoa.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 quick_exit.c \ - rand.c rand_r.c realloc.c reallocf.c sb_charsets.c strtod.c \ - strtodg.c strtol.c strtorx.c strtoul.c utoa.c wcstod.c \ - wcstol.c wcstoul.c wcstombs.c wcstombs_r.c wctomb.c wctomb_r.c \ - $(am__append_1) + mbtowc.c mbtowc_r.c mlock.c mprec.c mstats.c on_exit_args.c \ + quick_exit.c rand.c rand_r.c realloc.c reallocf.c \ + sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \ + utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \ + wctomb.c wctomb_r.c $(am__append_1) @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr @@ -856,6 +856,12 @@ lib_a-mstats.o: mstats.c lib_a-mstats.obj: mstats.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mstats.obj `if test -f 'mstats.c'; then $(CYGPATH_W) 'mstats.c'; else $(CYGPATH_W) '$(srcdir)/mstats.c'; fi` +lib_a-on_exit_args.o: on_exit_args.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-on_exit_args.o `test -f 'on_exit_args.c' || echo '$(srcdir)/'`on_exit_args.c + +lib_a-on_exit_args.obj: on_exit_args.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-on_exit_args.obj `if test -f 'on_exit_args.c'; then $(CYGPATH_W) 'on_exit_args.c'; else $(CYGPATH_W) '$(srcdir)/on_exit_args.c'; fi` + lib_a-quick_exit.o: quick_exit.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-quick_exit.o `test -f 'quick_exit.c' || echo '$(srcdir)/'`quick_exit.c diff --git a/newlib/libc/stdlib/__atexit.c b/newlib/libc/stdlib/__atexit.c index a3d5bdfbf..23eab29a9 100644 --- a/newlib/libc/stdlib/__atexit.c +++ b/newlib/libc/stdlib/__atexit.c @@ -79,7 +79,14 @@ _DEFUN (__register_exitproc, p = _GLOBAL_ATEXIT; if (p == NULL) - _GLOBAL_ATEXIT = p = _GLOBAL_ATEXIT0; + { + _GLOBAL_ATEXIT = p = _GLOBAL_ATEXIT0; +#ifdef _REENT_SMALL + extern struct _on_exit_args * const __on_exit_args _ATTRIBUTE ((weak)); + if (&__on_exit_args != NULL) + p->_on_exit_args_ptr = __on_exit_args; +#endif /* def _REENT_SMALL */ + } if (p->_ind >= _ATEXIT_SIZE) { #ifndef _ATEXIT_DYNAMIC_ALLOC diff --git a/newlib/libc/stdlib/cxa_atexit.c b/newlib/libc/stdlib/cxa_atexit.c index c3c0d2a17..39a59d53a 100644 --- a/newlib/libc/stdlib/cxa_atexit.c +++ b/newlib/libc/stdlib/cxa_atexit.c @@ -8,6 +8,15 @@ #include #include "atexit.h" +#ifdef _REENT_SMALL + +#include "on_exit_args.h" + +/* force linking of static instance of _on_exit_args */ +const void * const __cxa_atexit_dummy = &__on_exit_args; + +#endif /* def _REENT_SMALL */ + /* * Register a function to be performed at exit or DSO unload. */ diff --git a/newlib/libc/stdlib/on_exit.c b/newlib/libc/stdlib/on_exit.c index b7fd130dc..a405b1b51 100644 --- a/newlib/libc/stdlib/on_exit.c +++ b/newlib/libc/stdlib/on_exit.c @@ -58,6 +58,15 @@ Supporting OS subroutines required: None #include #include "atexit.h" +#ifdef _REENT_SMALL + +#include "on_exit_args.h" + +/* force linking of static instance of _on_exit_args */ +const void * const __on_exit_dummy = &__on_exit_args; + +#endif /* def _REENT_SMALL */ + /* * Register a function to be performed at exit. */ diff --git a/newlib/libc/stdlib/on_exit_args.c b/newlib/libc/stdlib/on_exit_args.c new file mode 100644 index 000000000..88f9ffdbd --- /dev/null +++ b/newlib/libc/stdlib/on_exit_args.c @@ -0,0 +1,30 @@ +/* + * Static instance of _on_exit_args struct. + * + * When _REENT_SMALL is used, _atexit struct only contains a pointer to + * _on_exit_args struct, so this was always allocated with malloc() - even for + * the first 32 calls of atexit()-like functions, which are guaranteed to + * succeed, but could fail because of "out of memory" error. This is even worse + * when _ATEXIT_DYNAMIC_ALLOC is _NOT_ defined, in which case malloc() is not + * used by internals of atexit()-like functions. In such configuration all calls + * to the functions that need _on_exit_args struct (on_exit() and + * __cxa_atexit()) would fail. + * + * Thats why a static instance of _on_exit_args struct is provided for + * _REENT_SMALL configuration. This way the first 32 calls to atexit()-like + * functions don't need malloc() and will always succeed. + * + * Because this struct is not needed for "normal" atexit(), it is used as a weak + * reference in __register_exitproc(), but any use of on_exit() or + * __cxa_atexit() will force it to be linked. + */ + +#include + +#ifdef _REENT_SMALL + +static struct _on_exit_args _on_exit_args_instance = {{_NULL}, {_NULL}, 0, 0}; + +struct _on_exit_args * const __on_exit_args = &_on_exit_args_instance; + +#endif /* def _REENT_SMALL */ diff --git a/newlib/libc/stdlib/on_exit_args.h b/newlib/libc/stdlib/on_exit_args.h new file mode 100644 index 000000000..c54ad1ef2 --- /dev/null +++ b/newlib/libc/stdlib/on_exit_args.h @@ -0,0 +1,12 @@ +#ifndef NEWLIB_CYGWIN_NEWLIB_LIBC_STDLIB_ON_EXIT_ARGS_H_ +#define NEWLIB_CYGWIN_NEWLIB_LIBC_STDLIB_ON_EXIT_ARGS_H_ + +#include + +#ifdef _REENT_SMALL + +extern struct _on_exit_args * const __on_exit_args; + +#endif /* def _REENT_SMALL */ + +#endif /* def NEWLIB_CYGWIN_NEWLIB_LIBC_STDLIB_ON_EXIT_ARGS_H_ */