ldso: check ctors sections of shared-object deps

The sole existence of shared-object dependencies lead to fatal
static-constructor errors before. Now, ldso checks if the ctors section
of objects in the init list are non-empty before whining.

Issue #2759
This commit is contained in:
Christian Helmuth
2018-05-14 14:10:16 +02:00
parent 058b92ca99
commit cbfec0deed
4 changed files with 36 additions and 6 deletions

View File

@ -104,6 +104,15 @@ struct Linker::Init : List<Object>
exec_static_constructors(); exec_static_constructors();
} }
bool needs_static_construction()
{
for (Object *obj = first(); obj; obj = obj->next_init())
if (obj->needs_static_construction())
return true;
return false;
}
void exec_static_constructors() void exec_static_constructors()
{ {
in_progress = true; in_progress = true;

View File

@ -132,6 +132,8 @@ class Linker::Object : private Fifo<Object>::Element,
Object *_next_object() const { return List<Object>::Element::next(); } Object *_next_object() const { return List<Object>::Element::next(); }
Elf::Addr _symbol_address(char const *name);
Name _name { }; Name _name { };
File const *_file { nullptr }; File const *_file { nullptr };
Elf::Addr _reloc_base { 0 }; Elf::Addr _reloc_base { 0 };
@ -195,6 +197,8 @@ class Linker::Object : private Fifo<Object>::Element,
* Return address info for symboal at addr * Return address info for symboal at addr
*/ */
virtual Symbol_info symbol_at_address(addr_t addr) const = 0; virtual Symbol_info symbol_at_address(addr_t addr) const = 0;
bool needs_static_construction();
}; };

View File

@ -385,10 +385,7 @@ struct Linker::Binary : private Root_object, public Elf_object
{ {
if (static_construction_finished) return false; if (static_construction_finished) return false;
Func * const ctors_start = (Func *)lookup_symbol("_ctors_start"); return Init::list()->needs_static_construction();
Func * const ctors_end = (Func *)lookup_symbol("_ctors_end");
return (ctors_end != ctors_start) || Init::list()->contains_deps();
} }
void finish_static_construction() void finish_static_construction()
@ -477,6 +474,28 @@ struct Linker::Binary : private Root_object, public Elf_object
}; };
/**********************************
** Linker object implementation **
**********************************/
Elf::Addr Linker::Object::_symbol_address(char const *name)
{
unsigned long hash = Hash_table::hash(name);
Elf::Sym const *sym = dynamic().lookup_symbol(name, hash);
if (sym)
return reloc_base() + sym->st_value;
else
return Elf::Addr(0);
}
bool Linker::Object::needs_static_construction()
{
return _symbol_address("_ctors_end") != _symbol_address("_ctors_start");
}
/*************************************** /***************************************
** Global Linker namespace functions ** ** Global Linker namespace functions **
***************************************/ ***************************************/

View File

@ -6,8 +6,6 @@ extern int main (int argc, char* argv[]);
void Libc::Component::construct(Libc::Env &env) void Libc::Component::construct(Libc::Env &env)
{ {
env.exec_static_constructors();
Genode::Heap heap(env.ram(), env.rm()); Genode::Heap heap(env.ram(), env.rm());
Fatfs::block_init(env, heap); Fatfs::block_init(env, heap);