Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2010-06-04 19:30:40 +0400
committerJeff Johnston <jjohnstn@redhat.com>2010-06-04 19:30:40 +0400
commitced5f59df9ba6e869ecd284e568ef5c3be82158f (patch)
tree1f579fec2d51c1eb48eba2b968c10a2ec51b8f49 /newlib/libc/stdlib
parente4f9551b407ad1a538d039fb4be395aab0c7fa51 (diff)
2010-06-04 Mark Mitchell <mark@codesourcery.com>
* libc/stdlib/__call_atexit.c (__libc_fini): Declare. (register_fini): New function. * libc/misc/init.c (_fini): Remove. (__libc_fini_array): Likewise. * libc/misc/fini.c: New file. * libc/misc/Makefile.am (LIB_SOURCES): Add fini.c. * libc/misc/Makefile.in: Regenerate.
Diffstat (limited to 'newlib/libc/stdlib')
-rw-r--r--newlib/libc/stdlib/__call_atexit.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c
index 6dd2ec63a..c99b2744e 100644
--- a/newlib/libc/stdlib/__call_atexit.c
+++ b/newlib/libc/stdlib/__call_atexit.c
@@ -15,6 +15,42 @@ void free(void *) _ATTRIBUTE((__weak__));
extern _LOCK_RECURSIVE_T __atexit_lock;
#endif
+/* If "__libc_fini" is defined, finalizers (either
+ "__libc_fini_array", or "_fini", as appropriate) will be run after
+ all user-specified atexit handlers. For example, you can define
+ "__libc_fini" to "_fini" in your linker script if you want the C
+ library, rather than startup code, to register finalizers. If you
+ do that, then your startup code need not contain references to
+ "atexit" or "exit". As a result, only applications that reference
+ "exit" explicitly will pull in finalization code.
+
+ The choice of whether to register finalizers from libc or from
+ startup code is deferred to link-time, rather than being a
+ configure-time option, so that the same C library binary can be
+ used with multiple BSPs, some of which register finalizers from
+ startup code, while others defer to the C library. */
+extern char __libc_fini __attribute__((weak));
+
+/* Register the application finalization function with atexit. These
+ finalizers should run last. Therefore, we want to call atexit as
+ soon as possible. */
+static void
+register_fini(void) __attribute__((constructor (0)));
+
+static void
+register_fini(void)
+{
+ if (&__libc_fini) {
+#ifdef HAVE_INITFINI_ARRAY
+ extern void __libc_fini_array (void);
+ atexit (__libc_fini_array);
+#else
+ extern void _fini (void);
+ atexit (_fini);
+#endif
+ }
+}
+
/*
* Call registered exit handlers. If D is null then all handlers are called,
* otherwise only the handlers from that DSO are called.