OSDN Git Service

Fix __eabi_atexit() implementation, as well as a bug in the BSD-originated __cxa_fina...
authorDavid 'Digit' Turner <digit@google.com>
Wed, 20 May 2009 09:42:52 +0000 (11:42 +0200)
committerDavid 'Digit' Turner <digit@google.com>
Wed, 20 May 2009 09:42:52 +0000 (11:42 +0200)
This patch uses "#if ANDROID" instead of "#if 1" in the __cxa_finalize() fix

libc/bionic/eabi.c
libc/stdlib/atexit.c

index 2e0c99c..a5f6627 100644 (file)
@@ -32,13 +32,20 @@ extern int  __cxa_atexit(void (*)(void*), void*, void* );
 
 void* __dso_handle = 0;
 
+/* The "C++ ABI for ARM" document states that static C++ constructors,
+ * which are called from the .init_array, should manually call
+ * __aeabi_atexit() to register static destructors explicitely.
+ *
+ * Note that 'dso_handle' is the address of a magic linker-generate
+ * variable from the shared object that contains the constructor/destructor
+ */
+
 /* Make this a weak symbol to avoid a multiple definition error when linking
  * with libstdc++-v3.  */
 int __attribute__((weak))
 __aeabi_atexit (void *object, void (*destructor) (void *), void *dso_handle)
 {
-    return 0;
-    //return __cxa_atexit(destructor, object, dso_handle);
+    return __cxa_atexit(destructor, object, dso_handle);
 }
 
 
index 5bf82ba..4ba2177 100644 (file)
@@ -147,10 +147,19 @@ __cxa_finalize(void *dso)
                                p->fns[n].fn_ptr.cxa_func = NULL;
                                mprotect(p, pgsize, PROT_READ);
                        }
+#if ANDROID
+                        /* it looks like we should always call the function
+                         * with an argument, even if dso is not NULL. Otherwise
+                         * static destructors will not be called properly on
+                         * the ARM.
+                         */
+                        (*fn.fn_ptr.cxa_func)(fn.fn_arg);
+#else /* !ANDROID */
                        if (dso != NULL)
                                (*fn.fn_ptr.cxa_func)(fn.fn_arg);
                        else
                                (*fn.fn_ptr.std_func)();
+#endif /* !ANDROID */
                }
        }