From ed68417bd42e25ea9b715faf47827244898a53b6 Mon Sep 17 00:00:00 2001 From: dgilbert Date: Thu, 28 Jul 2011 16:20:54 -0500 Subject: _fini and static dtor handling Change-Id: I157e067261a1cf80450dc29a4b60d5ffd2ef6f9e Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/222 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell Reviewed-by: Douglas R. Gilbert --- src/libc++/builtins.C | 71 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'src/libc++') diff --git a/src/libc++/builtins.C b/src/libc++/builtins.C index 04ea744f9..22336fa51 100755 --- a/src/libc++/builtins.C +++ b/src/libc++/builtins.C @@ -2,6 +2,8 @@ #include #include +#include +//#include void* operator new(size_t s) { @@ -65,16 +67,73 @@ extern "C" void __cxa_guard_release(volatile uint64_t* gv) return; } - -extern "C" int __cxa_atexit(void (*)(void*), void*, void*) -{ - return 0; -} - extern "C" void __cxa_pure_virtual() { // TODO: Add better code for invalid pure virtual call. while(1); } +// ---------------------------------------------------------------------------- +// Module exit support +// ---------------------------------------------------------------------------- + + +// This one is just for the base object. Each module has it's own giving +// each module a unique value for __dso_handle. void* __dso_handle = (void*) &__dso_handle; + +struct DtorEntry_t +{ + typedef void * key_type; + key_type key; + void (*dtor)(void*); + void * arg; + void * dso_handle; + + DtorEntry_t * next; + DtorEntry_t * prev; +}; + +Util::Locked::List g_dtorRegistry; + + +/** + * Call all the static destructors for the module identified by i_dso_handle + * @param[in] i_dso_handle unique identifier for a module + * @post matching dtor functions called and then removed from the dtor registry + */ +void call_dtors(void * i_dso_handle) +{ + DtorEntry_t * entry = NULL; + // A module is never exited by different threads so + // assume no locking needed here. + while( NULL != (entry = g_dtorRegistry.find(i_dso_handle)) ) + { + g_dtorRegistry.erase(entry); // remove from list + (*(entry->dtor))(entry->arg); + delete entry; + } +} + + +extern "C" int __cxa_atexit(void (*i_dtor)(void*), + void* i_arg, + void* i_dso_handle) +{ + // Base kernel code may try to call this before mem heap is + // available - so don't add it. + // TODO - Only need dtors for extended image modules + if(i_dso_handle != __dso_handle) + { + // printk("Register dtor for %p\n",i_dso_handle); + DtorEntry_t * entry = new DtorEntry_t; + entry->key = i_dso_handle; + entry->dtor = i_dtor; + entry->arg = i_arg; + g_dtorRegistry.insert(entry); + } + return 0; +} + + + -- cgit v1.2.1