aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc/stdlib/on_exit_args.c
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2015-12-21 11:49:28 -0500
committerJeff Johnston <jjohnstn@redhat.com>2015-12-21 11:49:28 -0500
commitd2bb300b9bb7917d33e3bc37fca3bf6ee6e5fcc4 (patch)
tree5b55b35d828623191420773e7b0e5a42387f0107 /newlib/libc/stdlib/on_exit_args.c
parentddb7e770dd48a97fe80cca3ab3b26d85f3ac5139 (diff)
downloadnewlib-d2bb300b9bb7917d33e3bc37fca3bf6ee6e5fcc4.zip
newlib-d2bb300b9bb7917d33e3bc37fca3bf6ee6e5fcc4.tar.gz
newlib-d2bb300b9bb7917d33e3bc37fca3bf6ee6e5fcc4.tar.bz2
Add static instance of _on_exit_args for _REENT_SMALL platforms.
2015-12-21 Freddie Chopin <freddie.chopin@gmail.com> * 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.
Diffstat (limited to 'newlib/libc/stdlib/on_exit_args.c')
-rw-r--r--newlib/libc/stdlib/on_exit_args.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/on_exit_args.c b/newlib/libc/stdlib/on_exit_args.c
new file mode 100644
index 0000000..88f9ffd
--- /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 <reent.h>
+
+#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 */