From 073cd03a2c5b0eb6c0872622f840f4a9724a9b04 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Thu, 8 Sep 2005 02:29:37 +0000
Subject: Fix by Martin Schlemmer: If _DL_FINI_CRT_COMPAT is defined, _dl_fini
 is setup to run at exit via atexit(), but this makes it run _before_ the fini
 (__app_fini()) of the app, causing stuff like sandbox that frees structs, etc
 via its fini to segfault. http://bugs.gentoo.org/98187

---
 libc/misc/internals/__uClibc_main.c | 10 ++++++++++
 libc/stdlib/atexit.c                |  8 ++++++++
 2 files changed, 18 insertions(+)

(limited to 'libc')

diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 6f74e39e8..53bb02820 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -161,6 +161,16 @@ void attribute_hidden (*__app_fini)(void) = NULL;
 
 void attribute_hidden (*__rtld_fini)(void) = NULL;
 
+#ifdef _DL_FINI_CRT_COMPAT
+void attribute_hidden (*__dl_fini)(void) = NULL;
+
+void _set__dl_fini(void *fini_func)
+{
+	if (fini_func != NULL)
+		__dl_fini = fini_func;
+}
+#endif
+
 /* __uClibc_start_main is the new main stub for uClibc. This function is
  * called from crt0 (version 0.9.16 or newer), after ALL shared libraries
  * are initialized, just before we call the application's main function.
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index 280f42cb7..c70318148 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -223,6 +223,11 @@ extern void (*__app_fini)(void);
 #endif
 
 extern void (*__rtld_fini)(void);
+
+#ifdef _DL_FINI_CRT_COMPAT
+extern void (*__dl_fini)(void);
+#endif
+
 /*
  * Normal program termination
  */
@@ -242,6 +247,9 @@ void exit(int rv)
 #ifndef _DL_FINI_CRT_COMPAT
 	if (__rtld_fini != NULL)
 		(__rtld_fini)();
+#else
+	if (__dl_fini != NULL)
+		(__dl_fini)();
 #endif
 
     /* If we are using stdio, try to shut it down.  At the very least,
-- 
cgit v1.2.3