ldso: config option to disarm ctors check

By specifying the config attribute 'check_ctors="no"', the dynamic
linker won't abort the program on a missing call of
'Env::exec_static_constructors'. This is the case for forked programs
where the ctors were already executed by the forking program prior the
fork operation.

Issue #3478
This commit is contained in:
Norman Feske 2019-08-15 10:28:50 +02:00 committed by Christian Helmuth
parent abdf422681
commit e499a04de7
3 changed files with 22 additions and 5 deletions

View File

@ -68,3 +68,15 @@ Debugging dynamic binaries with GDB stubs
GDB 7.2 has a regression bug in its line information parser. These issue has
been fixed with version 7.3.
Execution of global static constructors
---------------------------------------
The dynamic linker does not implicitely execute global static constructors
(ctors) at the loading time of a program but leaves this up to the loaded
program, which can trigger the execution of the ctors by calling
'Env::exec_static_constructors()'. This gives the program the power over
the point in time for such initializations. However, once a component's
initialization is complete (when 'Component::construct') returned, the linker
checks that static constructors - if present - were executed and aborts
otherwise. This check can be explicitely disabled by specifying the config
attribute 'ld_check_ctors="no"'.

View File

@ -47,14 +47,16 @@ class Linker::Config : Noncopyable
Bind const _bind = _config.attribute_value("ld_bind_now", false)
? BIND_NOW : BIND_LAZY;
bool const _verbose = _config.attribute_value("ld_verbose", false);
bool const _verbose = _config.attribute_value("ld_verbose", false);
bool const _check_ctors = _config.attribute_value("ld_check_ctors", true);
public:
Config(Env &env) : _config(env) { }
Bind bind() const { return _bind; }
bool verbose() const { return _verbose; }
Bind bind() const { return _bind; }
bool verbose() const { return _verbose; }
bool check_ctors() const { return _check_ctors; }
typedef String<100> Rom_name;

View File

@ -345,13 +345,16 @@ struct Linker::Binary : private Root_object, public Elf_object
{
using Root_object::first_dep;
bool const _check_ctors;
bool static_construction_finished = false;
Binary(Env &env, Allocator &md_alloc, Config const &config)
:
Root_object(md_alloc),
Elf_object(env, md_alloc, binary_name(),
*new (md_alloc) Dependency(*this, this), KEEP)
*new (md_alloc) Dependency(*this, this), KEEP),
_check_ctors(config.check_ctors())
{
/* create dep for binary and linker */
Dependency *binary = const_cast<Dependency *>(&dynamic().dep());
@ -423,7 +426,7 @@ struct Linker::Binary : private Root_object, public Elf_object
if (Elf::Addr addr = lookup_symbol("_ZN9Component9constructERN6Genode3EnvE")) {
((void(*)(Env &))addr)(env);
if (static_construction_pending()) {
if (_check_ctors && static_construction_pending()) {
error("Component::construct() returned without executing "
"pending static constructors (fix by calling "
"Genode::Env::exec_static_constructors())");