ldso: prevent premature execution of ctors

Fixes #3487
This commit is contained in:
Norman Feske 2019-08-27 14:22:55 +02:00 committed by Christian Helmuth
parent 0aedabd245
commit efe7f5172d
3 changed files with 22 additions and 1 deletions

View File

@ -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) {

View File

@ -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
*

View File

@ -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;
}