mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-06 11:10:24 +00:00
ldso: defer execution of static constructors
Ldso now does not automatically execute static constructors of the binary and shared libraries the binary depends on. If static construction is required (e.g., if a shared library with constructor is used or a compilation unit contains global statics) the component needs to execute the constructors explicitly in Component::construct() via Genode::Env::exec_static_constructors(). In the case of libc components this is done by the libc startup code (i.e., the Component::construct() implementation in the libc). The loading of shared objects at runtime is not affected by this change and constructors of those objects are executed immediately. Fixes #2332
This commit is contained in:
parent
67ac0dde6e
commit
cb43e04691
@ -128,6 +128,17 @@ struct Genode::Env
|
|||||||
* Close session and block until the session is gone
|
* Close session and block until the session is gone
|
||||||
*/
|
*/
|
||||||
virtual void close(Parent::Client::Id) = 0;
|
virtual void close(Parent::Client::Id) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excecute pending static constructors
|
||||||
|
*
|
||||||
|
* On component startup, the dynamic linker does not call possible static
|
||||||
|
* constructors in the binary and shared libraries the binary depends on. If
|
||||||
|
* the component requires static construction it needs to call this function
|
||||||
|
* at construction time explicitly. For example, the libc implementation
|
||||||
|
* executes this function before constructing libc components.
|
||||||
|
*/
|
||||||
|
virtual void exec_static_constructors() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__BASE__ENV_H_ */
|
#endif /* _INCLUDE__BASE__ENV_H_ */
|
||||||
|
@ -35,6 +35,7 @@ namespace Genode {
|
|||||||
void init_signal_thread(Env &);
|
void init_signal_thread(Env &);
|
||||||
void init_root_proxy(Env &);
|
void init_root_proxy(Env &);
|
||||||
void init_log();
|
void init_log();
|
||||||
|
void exec_static_constructors();
|
||||||
|
|
||||||
Id_space<Parent::Client> &env_session_id_space();
|
Id_space<Parent::Client> &env_session_id_space();
|
||||||
Env &internal_env();
|
Env &internal_env();
|
||||||
|
@ -27,6 +27,15 @@
|
|||||||
*/
|
*/
|
||||||
static Genode::Env *env_ptr = nullptr;
|
static Genode::Env *env_ptr = nullptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Excecute pending static constructors
|
||||||
|
*
|
||||||
|
* The weak function is used for statically linked binaries. The dynamic linker
|
||||||
|
* provides the real implementation for dynamically linked components.
|
||||||
|
*/
|
||||||
|
void Genode::exec_static_constructors() __attribute__((weak));
|
||||||
|
void Genode::exec_static_constructors() { }
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -184,6 +193,11 @@ namespace {
|
|||||||
if (_parent.close(id) == Parent::CLOSE_PENDING)
|
if (_parent.close(id) == Parent::CLOSE_PENDING)
|
||||||
_block_for_session();
|
_block_for_session();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exec_static_constructors() override
|
||||||
|
{
|
||||||
|
Genode::exec_static_constructors();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,5 +91,5 @@ Linker::Root_object::Root_object(Env &env, Allocator &md_alloc,
|
|||||||
new (md_alloc) Dependency(env, md_alloc, linker_name(), this, _deps, DONT_KEEP);
|
new (md_alloc) Dependency(env, md_alloc, linker_name(), this, _deps, DONT_KEEP);
|
||||||
|
|
||||||
/* relocate and call constructors */
|
/* relocate and call constructors */
|
||||||
Init::list()->initialize(bind);
|
Init::list()->initialize(bind, STAGE_SO);
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ class Linker::Dynamic
|
|||||||
{
|
{
|
||||||
if (!_md_alloc) {
|
if (!_md_alloc) {
|
||||||
error("unexpected call of section_dt_needed");
|
error("unexpected call of section_dt_needed");
|
||||||
return;
|
throw Fatal();
|
||||||
}
|
}
|
||||||
Needed *n = new (*_md_alloc) Needed(d->un.ptr);
|
Needed *n = new (*_md_alloc) Needed(d->un.ptr);
|
||||||
_needed.enqueue(n);
|
_needed.enqueue(n);
|
||||||
|
@ -36,6 +36,18 @@ struct Linker::Init : List<Object>
|
|||||||
return &_list;
|
return &_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool contains_deps() const
|
||||||
|
{
|
||||||
|
for (Object const *obj = first(); obj; obj = obj->next_init()) {
|
||||||
|
if (obj->is_linker()) continue;
|
||||||
|
if (obj->is_binary()) continue;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Object *contains(char const *file)
|
Object *contains(char const *file)
|
||||||
{
|
{
|
||||||
for (Object *elf = first(); elf; elf = elf->next_init())
|
for (Object *elf = first(); elf; elf = elf->next_init())
|
||||||
@ -62,7 +74,7 @@ struct Linker::Init : List<Object>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize(Bind bind)
|
void initialize(Bind bind, Stage stage)
|
||||||
{
|
{
|
||||||
Object *obj = first();
|
Object *obj = first();
|
||||||
|
|
||||||
@ -74,7 +86,7 @@ struct Linker::Init : List<Object>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recursive initialization call is not allowed here. This might happend
|
* Recursive initialization call is not allowed here. This might happen
|
||||||
* when Shared_objects (e.g. dlopen and friends) are constructed from within
|
* when Shared_objects (e.g. dlopen and friends) are constructed from within
|
||||||
* global constructors (ctors).
|
* global constructors (ctors).
|
||||||
*/
|
*/
|
||||||
@ -83,10 +95,21 @@ struct Linker::Init : List<Object>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not call static constructors in the binary stage as this must
|
||||||
|
* be done by the component itself. Later for shared objects, the
|
||||||
|
* constructors are executed immediately.
|
||||||
|
*/
|
||||||
|
if (stage != STAGE_BINARY)
|
||||||
|
exec_static_constructors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exec_static_constructors()
|
||||||
|
{
|
||||||
in_progress = true;
|
in_progress = true;
|
||||||
|
|
||||||
/* call static constructors */
|
/* call static constructors */
|
||||||
obj = first();
|
Object *obj = first();
|
||||||
while (obj) {
|
while (obj) {
|
||||||
|
|
||||||
Object *next = obj->next_init();
|
Object *next = obj->next_init();
|
||||||
|
@ -32,6 +32,7 @@ namespace Linker {
|
|||||||
class Incompatible : Exception { };
|
class Incompatible : Exception { };
|
||||||
class Invalid_file : Exception { };
|
class Invalid_file : Exception { };
|
||||||
class Not_found : Exception { };
|
class Not_found : Exception { };
|
||||||
|
class Fatal : Exception { };
|
||||||
|
|
||||||
enum Keep { DONT_KEEP = Shared_object::DONT_KEEP,
|
enum Keep { DONT_KEEP = Shared_object::DONT_KEEP,
|
||||||
KEEP = Shared_object::KEEP };
|
KEEP = Shared_object::KEEP };
|
||||||
@ -39,6 +40,8 @@ namespace Linker {
|
|||||||
enum Bind { BIND_LAZY = Shared_object::BIND_LAZY,
|
enum Bind { BIND_LAZY = Shared_object::BIND_LAZY,
|
||||||
BIND_NOW = Shared_object::BIND_NOW };
|
BIND_NOW = Shared_object::BIND_NOW };
|
||||||
|
|
||||||
|
enum Stage { STAGE_BINARY, STAGE_SO };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invariants
|
* Invariants
|
||||||
*/
|
*/
|
||||||
|
@ -290,7 +290,10 @@ Elf::Addr Ld::jmp_slot(Dependency const &dep, Elf::Size index)
|
|||||||
Reloc_jmpslot slot(dep, dep.obj().dynamic().pltrel_type(),
|
Reloc_jmpslot slot(dep, dep.obj().dynamic().pltrel_type(),
|
||||||
dep.obj().dynamic().pltrel(), index);
|
dep.obj().dynamic().pltrel(), index);
|
||||||
return slot.target_addr();
|
return slot.target_addr();
|
||||||
} catch (...) { error("LD: jump slot relocation failed. FATAL!"); }
|
} catch (...) {
|
||||||
|
error("LD: jump slot relocation failed. FATAL!");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -336,6 +339,8 @@ static void exit_on_suspended() { genode_exit(exit_status); }
|
|||||||
*/
|
*/
|
||||||
struct Linker::Binary : Root_object, Elf_object
|
struct Linker::Binary : Root_object, Elf_object
|
||||||
{
|
{
|
||||||
|
bool static_construction_finished = false;
|
||||||
|
|
||||||
Binary(Env &env, Allocator &md_alloc, Bind bind)
|
Binary(Env &env, Allocator &md_alloc, Bind bind)
|
||||||
:
|
:
|
||||||
Root_object(md_alloc),
|
Root_object(md_alloc),
|
||||||
@ -357,7 +362,7 @@ struct Linker::Binary : Root_object, Elf_object
|
|||||||
binary->load_needed(env, md_alloc, deps(), DONT_KEEP);
|
binary->load_needed(env, md_alloc, deps(), DONT_KEEP);
|
||||||
|
|
||||||
/* relocate and call constructors */
|
/* relocate and call constructors */
|
||||||
Init::list()->initialize(bind);
|
Init::list()->initialize(bind, STAGE_BINARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf::Addr lookup_symbol(char const *name)
|
Elf::Addr lookup_symbol(char const *name)
|
||||||
@ -370,6 +375,32 @@ struct Linker::Binary : Root_object, Elf_object
|
|||||||
catch (Linker::Not_found) { return 0; }
|
catch (Linker::Not_found) { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool static_construction_pending()
|
||||||
|
{
|
||||||
|
if (static_construction_finished) return false;
|
||||||
|
|
||||||
|
Func * const ctors_start = (Func *)lookup_symbol("_ctors_start");
|
||||||
|
Func * const ctors_end = (Func *)lookup_symbol("_ctors_end");
|
||||||
|
|
||||||
|
return (ctors_end != ctors_start) || Init::list()->contains_deps();
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_static_construction()
|
||||||
|
{
|
||||||
|
Init::list()->exec_static_constructors();
|
||||||
|
|
||||||
|
/* call static construtors and register destructors */
|
||||||
|
Func * const ctors_start = (Func *)lookup_symbol("_ctors_start");
|
||||||
|
Func * const ctors_end = (Func *)lookup_symbol("_ctors_end");
|
||||||
|
for (Func * ctor = ctors_end; ctor != ctors_start; (*--ctor)());
|
||||||
|
|
||||||
|
Func * const dtors_start = (Func *)lookup_symbol("_dtors_start");
|
||||||
|
Func * const dtors_end = (Func *)lookup_symbol("_dtors_end");
|
||||||
|
for (Func * dtor = dtors_start; dtor != dtors_end; genode_atexit(*dtor++));
|
||||||
|
|
||||||
|
static_construction_finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
void call_entry_point(Env &env)
|
void call_entry_point(Env &env)
|
||||||
{
|
{
|
||||||
/* apply the component-provided stack size */
|
/* apply the component-provided stack size */
|
||||||
@ -382,18 +413,16 @@ struct Linker::Binary : Root_object, Elf_object
|
|||||||
Thread::myself()->stack_size(stack_size);
|
Thread::myself()->stack_size(stack_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call static construtors and register destructors */
|
|
||||||
Func * const ctors_start = (Func *)lookup_symbol("_ctors_start");
|
|
||||||
Func * const ctors_end = (Func *)lookup_symbol("_ctors_end");
|
|
||||||
for (Func * ctor = ctors_end; ctor != ctors_start; (*--ctor)());
|
|
||||||
|
|
||||||
Func * const dtors_start = (Func *)lookup_symbol("_dtors_start");
|
|
||||||
Func * const dtors_end = (Func *)lookup_symbol("_dtors_end");
|
|
||||||
for (Func * dtor = dtors_start; dtor != dtors_end; genode_atexit(*dtor++));
|
|
||||||
|
|
||||||
/* call 'Component::construct' function if present */
|
/* call 'Component::construct' function if present */
|
||||||
if (Elf::Addr addr = lookup_symbol("_ZN9Component9constructERN6Genode3EnvE")) {
|
if (Elf::Addr addr = lookup_symbol("_ZN9Component9constructERN6Genode3EnvE")) {
|
||||||
((void(*)(Env &))addr)(env);
|
((void(*)(Env &))addr)(env);
|
||||||
|
|
||||||
|
if (static_construction_pending()) {
|
||||||
|
error("Component::construct() returned without executing "
|
||||||
|
"pending static constructors (fix by calling "
|
||||||
|
"Genode::Env::exec_static_constructors())");
|
||||||
|
throw Fatal();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +435,9 @@ struct Linker::Binary : Root_object, Elf_object
|
|||||||
if (Elf::Addr addr = lookup_symbol("main")) {
|
if (Elf::Addr addr = lookup_symbol("main")) {
|
||||||
warning("using legacy main function, please convert to 'Component::construct'");
|
warning("using legacy main function, please convert to 'Component::construct'");
|
||||||
|
|
||||||
|
/* execute static constructors before calling legacy 'main' */
|
||||||
|
finish_static_construction();
|
||||||
|
|
||||||
exit_status = ((int (*)(int, char **, char **))addr)(genode_argc,
|
exit_status = ((int (*)(int, char **, char **))addr)(genode_argc,
|
||||||
genode_argv,
|
genode_argv,
|
||||||
genode_envp);
|
genode_envp);
|
||||||
@ -418,6 +450,7 @@ struct Linker::Binary : Root_object, Elf_object
|
|||||||
}
|
}
|
||||||
|
|
||||||
error("dynamic linker: component-entrypoint lookup failed");
|
error("dynamic linker: component-entrypoint lookup failed");
|
||||||
|
throw Fatal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void relocate(Bind bind) override
|
void relocate(Bind bind) override
|
||||||
@ -612,6 +645,11 @@ void Genode::init_ldso_phdr(Env &env)
|
|||||||
Ld::linker().load_phdr(env, *heap());
|
Ld::linker().load_phdr(env, *heap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Genode::exec_static_constructors()
|
||||||
|
{
|
||||||
|
binary_ptr->finish_static_construction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env)
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
|
@ -532,8 +532,10 @@ struct Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/***************
|
void Component::construct(Genode::Env &env)
|
||||||
** Component **
|
{
|
||||||
***************/
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main server(env); }
|
static Main server(env);
|
||||||
|
}
|
||||||
|
@ -160,4 +160,10 @@ struct Main
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main main(env);
|
||||||
|
}
|
||||||
|
@ -121,4 +121,10 @@ static void run_linux(void * m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main m(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main m(env);
|
||||||
|
}
|
||||||
|
@ -16,4 +16,10 @@
|
|||||||
extern void start_usb_driver(Genode::Env &env);
|
extern void start_usb_driver(Genode::Env &env);
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { start_usb_driver(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
start_usb_driver(env);
|
||||||
|
}
|
||||||
|
@ -49,4 +49,10 @@ struct Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main inst(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main inst(env);
|
||||||
|
}
|
||||||
|
@ -521,4 +521,10 @@ struct File_system::Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static File_system::Main inst(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics (uses shared objects) */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static File_system::Main inst(env);
|
||||||
|
}
|
||||||
|
@ -160,4 +160,10 @@ struct Main : Scout::Event_handler
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main main(env);
|
||||||
|
}
|
||||||
|
@ -168,4 +168,10 @@ struct Scout::Main : Scout::Event_handler
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Scout::Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Scout::Main main(env);
|
||||||
|
}
|
||||||
|
@ -311,4 +311,10 @@ class Liquid_fb::Main : public Scout::Event_handler
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Liquid_fb::Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Liquid_fb::Main main(env);
|
||||||
|
}
|
||||||
|
@ -496,4 +496,10 @@ struct Nitlog::Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Nitlog::Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Nitlog::Main main(env);
|
||||||
|
}
|
||||||
|
@ -194,4 +194,10 @@ struct Cpu_sampler::Main : Thread_list_change_handler
|
|||||||
** Component **
|
** Component **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Cpu_sampler::Main inst(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics (uses shared objects) */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Cpu_sampler::Main inst(env);
|
||||||
|
}
|
||||||
|
@ -690,6 +690,9 @@ extern char _binary_terminus_16_tff_start;
|
|||||||
|
|
||||||
void Component::construct(Genode::Env &env)
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
Attached_rom_dataspace config(env, "config");
|
Attached_rom_dataspace config(env, "config");
|
||||||
|
@ -304,6 +304,13 @@ ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler,
|
|||||||
|
|
||||||
|
|
||||||
/* used by normal (no-printf-debug) target */
|
/* used by normal (no-printf-debug) target */
|
||||||
void Component::construct(Genode::Env &env) { static Acpica::Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Acpica::Main main(env);
|
||||||
|
}
|
||||||
|
|
||||||
/* used by debug target (using printf of libc) */
|
/* used by debug target (using printf of libc) */
|
||||||
void Libc::Component::construct(Libc::Env &env) { static Acpica::Main main(env); }
|
void Libc::Component::construct(Libc::Env &env) { static Acpica::Main main(env); }
|
||||||
|
@ -54,6 +54,8 @@ struct Qt_launchpad_namespace::Local_env : Genode::Env
|
|||||||
{ return genode_env.upgrade(id, args); }
|
{ return genode_env.upgrade(id, args); }
|
||||||
|
|
||||||
void close(Parent::Client::Id id) { return genode_env.close(id); }
|
void close(Parent::Client::Id id) { return genode_env.close(id); }
|
||||||
|
|
||||||
|
void exec_static_constructors() override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,4 +243,10 @@ struct Framebuffer::Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Framebuffer::Main inst(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Framebuffer::Main inst(env);
|
||||||
|
}
|
||||||
|
@ -159,6 +159,9 @@ class Libc::Env_implementation : public Libc::Env
|
|||||||
|
|
||||||
void close(Parent::Client::Id id) override {
|
void close(Parent::Client::Id id) override {
|
||||||
return _env.close(id); }
|
return _env.close(id); }
|
||||||
|
|
||||||
|
/* already done by the libc */
|
||||||
|
void exec_static_constructors() override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -864,16 +867,30 @@ void Component::construct(Genode::Env &env)
|
|||||||
Libc::init_dl(env);
|
Libc::init_dl(env);
|
||||||
Libc::sysctl_init(env);
|
Libc::sysctl_init(env);
|
||||||
|
|
||||||
|
kernel = unmanaged_singleton<Libc::Kernel>(env);
|
||||||
|
|
||||||
|
Libc::libc_config_init(kernel->libc_env().libc_config());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX The following two steps leave us with the dilemma that we don't know
|
||||||
|
* which linked library may depend on the successfull initialization of a
|
||||||
|
* plugin. For example, some high-level library may try to open a network
|
||||||
|
* connection in its constructor before the network-stack library is
|
||||||
|
* initialized. But, we can't initialize plugins before calling static
|
||||||
|
* constructors as those are needed to know about the libc plugin. The only
|
||||||
|
* solution is to remove all libc plugins beside the VFS implementation,
|
||||||
|
* which is our final goal anyway.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* finish static construction of component and libraries */
|
||||||
|
Libc::with_libc([&] () { env.exec_static_constructors(); });
|
||||||
|
|
||||||
/* initialize plugins that require Genode::Env */
|
/* initialize plugins that require Genode::Env */
|
||||||
auto init_plugin = [&] (Libc::Plugin &plugin) {
|
auto init_plugin = [&] (Libc::Plugin &plugin) {
|
||||||
plugin.init(env);
|
plugin.init(env);
|
||||||
};
|
};
|
||||||
Libc::plugin_registry()->for_each_plugin(init_plugin);
|
Libc::plugin_registry()->for_each_plugin(init_plugin);
|
||||||
|
|
||||||
kernel = unmanaged_singleton<Libc::Kernel>(env);
|
|
||||||
|
|
||||||
Libc::libc_config_init(kernel->libc_env().libc_config());
|
|
||||||
|
|
||||||
/* construct libc component on kernel stack */
|
/* construct libc component on kernel stack */
|
||||||
Libc::Component::construct(kernel->libc_env());
|
Libc::Component::construct(kernel->libc_env());
|
||||||
}
|
}
|
||||||
|
@ -404,4 +404,10 @@ struct Transform::Main {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Transform::Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Transform::Main main(env);
|
||||||
|
}
|
||||||
|
@ -26,23 +26,20 @@
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************
|
|
||||||
** Implementation of the input service **
|
|
||||||
*****************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Input event buffer that is shared with the client
|
|
||||||
*/
|
|
||||||
enum { MAX_EVENTS = 1000 };
|
|
||||||
static Dataspace_capability ev_ds_cap;
|
|
||||||
|
|
||||||
namespace Input {
|
namespace Input {
|
||||||
|
|
||||||
class Session_component : public Genode::Rpc_object<Session>
|
class Session_component : public Genode::Rpc_object<Session>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Dataspace_capability _ev_ds_cap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Dataspace_capability dataspace() override { return ev_ds_cap; }
|
Session_component(Dataspace_capability ev_ds_cap)
|
||||||
|
: _ev_ds_cap(ev_ds_cap) { }
|
||||||
|
|
||||||
|
Dataspace_capability dataspace() override { return _ev_ds_cap; }
|
||||||
|
|
||||||
bool pending() const override { return 0; }
|
bool pending() const override { return 0; }
|
||||||
|
|
||||||
@ -60,36 +57,36 @@ namespace Input {
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
Dataspace_capability _ev_ds_cap;
|
||||||
|
|
||||||
Session_component *_create_session(const char *args) {
|
Session_component *_create_session(const char *args) {
|
||||||
return new (md_alloc()) Session_component(); }
|
return new (md_alloc()) Session_component(_ev_ds_cap); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Root(Genode::Entrypoint &ep, Allocator &md_alloc)
|
Root(Genode::Entrypoint &ep, Allocator &md_alloc,
|
||||||
: Root_component<Session_component>(ep, md_alloc) { }
|
Dataspace_capability ev_ds_cap)
|
||||||
|
:
|
||||||
|
Root_component<Session_component>(ep, md_alloc),
|
||||||
|
_ev_ds_cap(ev_ds_cap)
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Genode::Sliced_heap heap;
|
Genode::Env &env;
|
||||||
|
|
||||||
Input::Root root;
|
Sliced_heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
Main(Genode::Env &env)
|
Dataspace_capability ev_ds_cap {
|
||||||
:
|
env.ram().alloc(1000*sizeof(Input::Event)) };
|
||||||
heap(env.ram(), env.rm()),
|
|
||||||
root(env.ep(), heap)
|
Input::Root root { env.ep(), heap, ev_ds_cap };
|
||||||
|
|
||||||
|
Main(Genode::Env &env) : env(env)
|
||||||
{
|
{
|
||||||
/* create dataspace for event buffer that is shared with the client */
|
|
||||||
try { ev_ds_cap = env.ram().alloc(MAX_EVENTS*sizeof(Input::Event)); }
|
|
||||||
catch (Ram_session::Alloc_failed) {
|
|
||||||
Genode::error("could not allocate dataspace for event buffer");
|
|
||||||
throw Genode::Exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tell parent about the service */
|
|
||||||
env.parent().announce(env.ep().manage(root));
|
env.parent().announce(env.ep().manage(root));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -143,4 +143,10 @@ struct Platform::Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Platform::Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Platform::Main main(env);
|
||||||
|
}
|
||||||
|
@ -82,4 +82,10 @@ struct Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main server(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main server(env);
|
||||||
|
}
|
||||||
|
@ -43,8 +43,6 @@ class Iso::Sector {
|
|||||||
BLOCK_SIZE = 2048,
|
BLOCK_SIZE = 2048,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Lock _lock;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Block::Session::Tx::Source &_source;
|
Block::Session::Tx::Source &_source;
|
||||||
@ -56,8 +54,6 @@ class Iso::Sector {
|
|||||||
unsigned long blk_nr, unsigned long count)
|
unsigned long blk_nr, unsigned long count)
|
||||||
: _source(*block.tx())
|
: _source(*block.tx())
|
||||||
{
|
{
|
||||||
// Lock::Guard lock_guard(_lock);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_p = Block::Packet_descriptor(
|
_p = Block::Packet_descriptor(
|
||||||
block.dma_alloc_packet(blk_size() * count),
|
block.dma_alloc_packet(blk_size() * count),
|
||||||
@ -81,7 +77,6 @@ class Iso::Sector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~Sector() {
|
~Sector() {
|
||||||
// Lock::Guard lock_guard(_lock);
|
|
||||||
_source.release_packet(_p);
|
_source.release_packet(_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,12 +93,6 @@ class Iso::Sector {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Static members of Sector
|
|
||||||
*/
|
|
||||||
Lock Iso::Sector::_lock;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rock ridge extension (see IEEE P1282)
|
* Rock ridge extension (see IEEE P1282)
|
||||||
*/
|
*/
|
||||||
|
@ -65,4 +65,10 @@ struct Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main nic_bridge(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main nic_bridge(env);
|
||||||
|
}
|
||||||
|
@ -55,4 +55,10 @@ Main::Main(Env &env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Env &env) { static Main main(env); }
|
void Component::construct(Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main main(env);
|
||||||
|
}
|
||||||
|
@ -59,4 +59,10 @@ Main::Main(Env &env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Env &env) { static Main main(env); }
|
void Component::construct(Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main main(env);
|
||||||
|
}
|
||||||
|
@ -1394,4 +1394,10 @@ void Nitpicker::Main::handle_fb_mode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Nitpicker::Main nitpicker(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Nitpicker::Main nitpicker(env);
|
||||||
|
}
|
||||||
|
@ -385,6 +385,9 @@ void perform(Genode::Env &env, Genode::Heap &heap, unsigned timeo_ms = 0)
|
|||||||
|
|
||||||
void Component::construct(Genode::Env &env)
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
#include <base/lock.h>
|
#include <base/lock.h>
|
||||||
|
|
||||||
@ -39,19 +38,19 @@ void (*libc_select_notify)();
|
|||||||
Socket_io_channel_backend *name = \
|
Socket_io_channel_backend *name = \
|
||||||
dynamic_cast<Socket_io_channel_backend*>(backend)
|
dynamic_cast<Socket_io_channel_backend*>(backend)
|
||||||
|
|
||||||
static Genode::Lock _select_notify_lock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback function is called from lwip via the libc_select_notify
|
* This callback function is called from lwip via the libc_select_notify
|
||||||
* function pointer if an event occurs.
|
* function pointer if an event occurs.
|
||||||
*/
|
*/
|
||||||
static void select_notify()
|
static void select_notify()
|
||||||
{
|
{
|
||||||
|
static Genode::Lock mutex;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The function could be called multiple times while actually
|
* The function could be called multiple times while actually
|
||||||
* still running.
|
* still running.
|
||||||
*/
|
*/
|
||||||
Genode::Lock::Guard guard(_select_notify_lock);
|
Genode::Lock::Guard guard(mutex);
|
||||||
|
|
||||||
for (Io_receptor *r = io_receptor_registry()->first();
|
for (Io_receptor *r = io_receptor_registry()->first();
|
||||||
r != 0; r = r->next()) {
|
r != 0; r = r->next()) {
|
||||||
|
@ -185,4 +185,10 @@ struct Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Genode::Env &env) { static Main main(env); }
|
void Component::construct(Genode::Env &env)
|
||||||
|
{
|
||||||
|
/* XXX execute constructors of global statics */
|
||||||
|
env.exec_static_constructors();
|
||||||
|
|
||||||
|
static Main main(env);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user