diff --git a/repos/base/src/include/base/internal/globals.h b/repos/base/src/include/base/internal/globals.h index c934f8ccf..addaeb191 100644 --- a/repos/base/src/include/base/internal/globals.h +++ b/repos/base/src/include/base/internal/globals.h @@ -32,6 +32,7 @@ namespace Genode { void init_exception_handling(Env &); void init_signal_transmitter(Env &); void init_cxx_heap(Env &); + void init_cxx_guard(); void init_ldso_phdr(Env &); void init_signal_thread(Env &); void init_root_proxy(Env &); diff --git a/repos/base/src/lib/cxx/guard.cc b/repos/base/src/lib/cxx/guard.cc index 8f6b3a5bc..4c8c599fd 100644 --- a/repos/base/src/lib/cxx/guard.cc +++ b/repos/base/src/lib/cxx/guard.cc @@ -16,11 +16,24 @@ #include #include - -static Genode::Registry > blocked; +/* base-internal includes */ +#include +#include -namespace __cxxabiv1 +typedef Genode::Registry > Blockers; + + +static Blockers *blockers_ptr; + + +void Genode::init_cxx_guard() +{ + blockers_ptr = unmanaged_singleton(); +} + + +namespace __cxxabiv1 { enum State { INIT_NONE = 0, INIT_DONE = 1, IN_INIT = 0x100, WAITERS = 0x200 }; @@ -54,7 +67,7 @@ namespace __cxxabiv1 if (!Genode::cmpxchg(in_init, INIT_NONE, IN_INIT)) { /* register current thread for blocking */ - Genode::Registered_no_delete block(blocked); + Genode::Registered_no_delete block(*blockers_ptr); /* tell guard thread that current thread needs a wakeup */ while (!Genode::cmpxchg(in_init, *in_init, *in_init | WAITERS)) ; @@ -88,7 +101,7 @@ namespace __cxxabiv1 return; /* we had contention - wake all up */ - blocked.for_each([](Genode::Registered_no_delete &wake) { + blockers_ptr->for_each([](Genode::Registered_no_delete &wake) { wake.up(); }); } diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc index 9fa5487e0..277bea2c5 100644 --- a/repos/base/src/lib/ldso/main.cc +++ b/repos/base/src/lib/ldso/main.cc @@ -636,6 +636,9 @@ Elf::Sym const *Linker::lookup_symbol(char const *name, Dependency const &dep, */ extern "C" void init_rtld() { + /* init cxa guard mechanism before any local static variables are used */ + init_cxx_guard(); + /* * Allocate on stack, since the linker has not been relocated yet, the vtable * type relocation might produce a wrong vtable pointer (at least on ARM), do diff --git a/repos/base/src/lib/startup/init_main_thread.cc b/repos/base/src/lib/startup/init_main_thread.cc index 7082433a1..771ae7c6c 100644 --- a/repos/base/src/lib/startup/init_main_thread.cc +++ b/repos/base/src/lib/startup/init_main_thread.cc @@ -35,11 +35,17 @@ void prepare_init_main_thread(); enum { MAIN_THREAD_STACK_SIZE = 16*1024 }; + /** * Satisfy crt0.s in static programs, LDSO overrides this symbol */ extern "C" void init_rtld() __attribute__((weak)); -void init_rtld() { } +void init_rtld() +{ + /* init cxa guard mechanism before any local static variables are used */ + init_cxx_guard(); +} + /** * Lower bound of the stack, solely used for sanity checking