diff --git a/libc/bionic/eabi.c b/libc/bionic/eabi.c index 2e0c99cc4..a5f662746 100644 --- a/libc/bionic/eabi.c +++ b/libc/bionic/eabi.c @@ -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); } diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c index 5bf82ba3a..4ba217732 100644 --- a/libc/stdlib/atexit.c +++ b/libc/stdlib/atexit.c @@ -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 */ } }