ARM: warn about atexit() calls from legacy shared libraries

Legacy ARM shared libraries use this generic version of atexit(),
which queues exit functions for invocation at program exit, at
which time the library may have been dlclose()'d, causing the
program to crash.

Change-Id: I41ae153c23268daa65ede7fb8966fc3e9caec369
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@gmail.com>
diff --git a/libc/arch-arm/bionic/atexit_legacy.c b/libc/arch-arm/bionic/atexit_legacy.c
index 09da17c..4abe839 100644
--- a/libc/arch-arm/bionic/atexit_legacy.c
+++ b/libc/arch-arm/bionic/atexit_legacy.c
@@ -27,6 +27,8 @@
  */
 
 #include <sys/types.h>
+#include <private/logd.h>
+#include <stdio.h>
 
 /*
  * This source file should only be included by libc.so, its purpose is
@@ -42,5 +44,17 @@
 int
 atexit(void (*func)(void))
 {
+    /*
+     * Exit functions queued by this version of atexit will not be called
+     * on dlclose(), and when they are called (at program exit), the
+     * calling library may have been dlclose()'d, causing the program to
+     * crash.
+     */
+    static char const warning[] =
+        "WARNING: generic atexit() called from legacy shared library\n";
+
+    __libc_android_log_print(ANDROID_LOG_WARN, "libc", warning);
+    fprintf(stderr, warning);
+
     return (__cxa_atexit((void (*)(void *))func, NULL, NULL));
 }