diff --git a/lib/csu/common/crtbegin.c b/lib/csu/common/crtbegin.c index 35231fa904f9..859582c37305 100644 --- a/lib/csu/common/crtbegin.c +++ b/lib/csu/common/crtbegin.c @@ -32,10 +32,27 @@ typedef void (*crt_func)(void); extern void *__dso_handle __hidden; -#ifdef SHARED -void *__dso_handle = &__dso_handle; -#else +#ifndef SHARED void *__dso_handle = 0; +#else +void *__dso_handle = &__dso_handle; +void __cxa_finalize(void *) __weak_symbol; + +/* + * Call __cxa_finalize with the dso handle in shared objects. + * When we have ctors/dtors call from the dtor handler before calling + * any dtors, otherwise use a destructor. + */ +#ifndef HAVE_CTORS +__attribute__((destructor)) +#endif +static void +run_cxa_finalize(void) +{ + + if (__cxa_finalize != NULL) + __cxa_finalize(__dso_handle); +} #endif /* @@ -58,6 +75,10 @@ __do_global_dtors_aux(void) crt_func fn; int n; +#ifdef SHARED + run_cxa_finalize(); +#endif + for (n = 1;; n++) { fn = __DTOR_LIST__[n]; if (fn == (crt_func)0 || fn == (crt_func)-1)