diff --git a/repos/base/src/lib/ldso/dependency.cc b/repos/base/src/lib/ldso/dependency.cc index 50d8dafaa..cb30c0c62 100644 --- a/repos/base/src/lib/ldso/dependency.cc +++ b/repos/base/src/lib/ldso/dependency.cc @@ -111,7 +111,7 @@ Linker::Root_object::Root_object(Env &env, Allocator &md_alloc, /* relocate and call constructors */ try { - Init::list()->initialize(bind, STAGE_SO); + Init::list()->initialize(bind, Linker::stage); } catch (...) { Init::list()->flush(); _deps.dequeue_all([&] (Dependency &d) { diff --git a/repos/base/src/lib/ldso/include/linker.h b/repos/base/src/lib/ldso/include/linker.h index 3dab1fef2..b2eca88c3 100644 --- a/repos/base/src/lib/ldso/include/linker.h +++ b/repos/base/src/lib/ldso/include/linker.h @@ -47,6 +47,23 @@ namespace Linker { */ extern bool verbose; + /** + * Stage of execution + * + * This state variable is used to control the implicit execution of global + * static constructors as a side effect of loading a shared library. + * + * At STAGE_BINARY, the binary is initialized and 'Component::construct' + * is executed. At this early stage, no global static constructor must be + * executed. + * + * Once, 'Env::exec_static_constructors' is called, or + * 'Component::construct' returned, we enter the 'STAGE_SO'. At this stage, + * global static constructors can safely be executed, i.e., as side effect + * of loading a shared library. + */ + extern Stage stage; + /** * Find symbol via index * diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc index c639c7ae6..608400b20 100644 --- a/repos/base/src/lib/ldso/main.cc +++ b/repos/base/src/lib/ldso/main.cc @@ -44,6 +44,7 @@ namespace Linker { static Binary *binary_ptr = nullptr; bool Linker::verbose = false; +Stage Linker::stage = STAGE_BINARY; Link_map *Link_map::first; /** @@ -415,6 +416,7 @@ struct Linker::Binary : private Root_object, public Elf_object for (Func * dtor = dtors_start; dtor != dtors_end; genode_atexit(*dtor++)); static_construction_finished = true; + stage = STAGE_SO; } void call_entry_point(Env &env) @@ -439,6 +441,8 @@ struct Linker::Binary : private Root_object, public Elf_object "Genode::Env::exec_static_constructors())"); throw Fatal(); } + + stage = STAGE_SO; return; }