ldso: Disallow recursive initialization
Do not support the global construction from of objects from within a global constructor of another object. This can happen if, for example, dlopen is called from a global constructor. The construction will be post-boned until the current constructor has finished.
This commit is contained in:
parent
09e6c3457f
commit
038a7999bf
|
@ -363,6 +363,7 @@ struct Linker::Elf_object : Object, Genode::List<Elf_object>::Element,
|
||||||
Link_map map;
|
Link_map map;
|
||||||
unsigned ref_count = 1;
|
unsigned ref_count = 1;
|
||||||
unsigned flags = 0;
|
unsigned flags = 0;
|
||||||
|
bool relocated = false;
|
||||||
|
|
||||||
Elf_object(Dag const *dag) : dynamic(dag)
|
Elf_object(Dag const *dag) : dynamic(dag)
|
||||||
{ }
|
{ }
|
||||||
|
@ -408,7 +409,13 @@ struct Linker::Elf_object : Object, Genode::List<Elf_object>::Element,
|
||||||
Link_map::add(&map);
|
Link_map::add(&map);
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void relocate() { dynamic.relocate(); }
|
virtual void relocate()
|
||||||
|
{
|
||||||
|
if (!relocated)
|
||||||
|
dynamic.relocate();
|
||||||
|
|
||||||
|
relocated = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return symbol of given number from ELF
|
* Return symbol of given number from ELF
|
||||||
|
@ -577,6 +584,9 @@ struct Linker::Elf_object : Object, Genode::List<Elf_object>::Element,
|
||||||
*/
|
*/
|
||||||
struct Init : Genode::List<Elf_object>
|
struct Init : Genode::List<Elf_object>
|
||||||
{
|
{
|
||||||
|
bool in_progress = false;
|
||||||
|
bool restart = false;
|
||||||
|
|
||||||
static Init *list()
|
static Init *list()
|
||||||
{
|
{
|
||||||
static Init _list;
|
static Init _list;
|
||||||
|
@ -619,10 +629,25 @@ struct Init : Genode::List<Elf_object>
|
||||||
obj->relocate();
|
obj->relocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recursive initialization call is not allowed here. This might happend
|
||||||
|
* when Shared_objects (e.g. dlopen and friends) are constructed from within
|
||||||
|
* global constructors (ctors).
|
||||||
|
*/
|
||||||
|
if (in_progress) {
|
||||||
|
restart = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_progress = true;
|
||||||
|
|
||||||
/* call static constructors */
|
/* call static constructors */
|
||||||
obj = first();
|
obj = first();
|
||||||
while (obj) {
|
while (obj) {
|
||||||
|
|
||||||
|
Elf_object *next = obj->init_next();
|
||||||
|
remove(obj);
|
||||||
|
|
||||||
if (obj->dynamic.init_function) {
|
if (obj->dynamic.init_function) {
|
||||||
|
|
||||||
if (verbose_relocation)
|
if (verbose_relocation)
|
||||||
|
@ -631,10 +656,11 @@ struct Init : Genode::List<Elf_object>
|
||||||
obj->dynamic.init_function();
|
obj->dynamic.init_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf_object *next = obj->init_next();
|
obj = restart ? first() : next;
|
||||||
remove(obj);
|
restart = false;
|
||||||
obj = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_progress = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user