summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgilbert <dgilbert@us.ibm.com>2011-07-28 16:20:54 -0500
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2011-08-03 16:47:06 -0500
commited68417bd42e25ea9b715faf47827244898a53b6 (patch)
tree0615f2b09ff055fcb5c80cfc55c49f1d04918b6c
parent1fa888465e302181368021fefa15a44e1854914f (diff)
downloadtalos-hostboot-ed68417bd42e25ea9b715faf47827244898a53b6.tar.gz
talos-hostboot-ed68417bd42e25ea9b715faf47827244898a53b6.zip
_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 <dcrowell@us.ibm.com> Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
-rwxr-xr-xsrc/libc++/builtins.C71
-rw-r--r--src/usr/module_init.C14
2 files changed, 79 insertions, 6 deletions
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 <stdlib.h>
#include <arch/ppc.H>
+#include <util/locked/list.H>
+//#include <kernel/console.H>
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<DtorEntry_t, DtorEntry_t::key_type> 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;
+}
+
+
+
diff --git a/src/usr/module_init.C b/src/usr/module_init.C
index 93c3f35a7..9a652381e 100644
--- a/src/usr/module_init.C
+++ b/src/usr/module_init.C
@@ -1,3 +1,8 @@
+void call_dtors(void * i_dso_handle);
+
+// This identifies the module
+void* __dso_handle = (void*) &__dso_handle;
+
extern "C"
void _init(void*)
{
@@ -11,3 +16,12 @@ void _init(void*)
ctors++;
}
}
+
+extern "C"
+void _fini(void)
+{
+ call_dtors(__dso_handle);
+}
+
+
+
OpenPOWER on IntegriCloud