diff --git a/repos/base-fiasco/lib/mk/base-common.mk b/repos/base-fiasco/lib/mk/base-common.mk
index a0a4c7daa..beadde5fd 100644
--- a/repos/base-fiasco/lib/mk/base-common.mk
+++ b/repos/base-fiasco/lib/mk/base-common.mk
@@ -14,7 +14,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
diff --git a/repos/base-foc/lib/mk/base-common.inc b/repos/base-foc/lib/mk/base-common.inc
index 30b7d61d2..21580206c 100644
--- a/repos/base-foc/lib/mk/base-common.inc
+++ b/repos/base-foc/lib/mk/base-common.inc
@@ -13,7 +13,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += env/spin_lock.cc env/cap_map.cc
diff --git a/repos/base-hw/lib/mk/base-common.inc b/repos/base-hw/lib/mk/base-common.inc
index b371cfa03..4dfd47315 100644
--- a/repos/base-hw/lib/mk/base-common.inc
+++ b/repos/base-hw/lib/mk/base-common.inc
@@ -14,7 +14,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc
SRC_CC += heap/sliced_heap.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += console/console.cc
SRC_CC += lock/lock.cc
diff --git a/repos/base-linux/lib/mk/base-common.mk b/repos/base-linux/lib/mk/base-common.mk
index e73a0e629..851e9d3e9 100644
--- a/repos/base-linux/lib/mk/base-common.mk
+++ b/repos/base-linux/lib/mk/base-common.mk
@@ -13,7 +13,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += env/region_map_mmap.cc env/debug.cc
diff --git a/repos/base-linux/src/base/child/process.cc b/repos/base-linux/src/base/child/process.cc
new file mode 100644
index 000000000..590b39b9b
--- /dev/null
+++ b/repos/base-linux/src/base/child/process.cc
@@ -0,0 +1,114 @@
+/*
+ * \brief Implementation of process creation for Linux
+ * \author Norman Feske
+ * \date 2006-07-06
+ */
+
+/*
+ * Copyright (C) 2006-2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+
+/* base-internal includes */
+#include
+#include
+
+
+using namespace Genode;
+
+
+/*
+ * Register main thread at core
+ *
+ * At this point in time, we do not yet know the TID and PID of the new
+ * thread. Those information will be provided to core by the constructor of
+ * the 'Platform_env' of the new process.
+ */
+Child::Process::Initial_thread::Initial_thread(Cpu_session &cpu,
+ Pd_session_capability pd,
+ char const *name)
+:
+ cpu(cpu),
+ cap(cpu.create_thread(pd, Cpu_session::DEFAULT_WEIGHT, name))
+{ }
+
+
+Child::Process::Initial_thread::~Initial_thread() { }
+
+
+/*
+ * On Linux, the ELF loading is performed by the kernel
+ */
+Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability,
+ Dataspace_capability,
+ Ram_session &,
+ Region_map &,
+ Region_map &,
+ Parent_capability) { }
+
+
+Child::Process::Process(Dataspace_capability elf_ds,
+ Dataspace_capability ldso_ds,
+ Pd_session_capability pd_cap,
+ Pd_session &pd,
+ Ram_session &ram,
+ Cpu_session &cpu,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Parent_capability parent_cap,
+ char const *name)
+:
+ initial_thread(cpu, pd_cap, name),
+ loaded_executable(elf_ds, ldso_ds, ram, local_rm, remote_rm, parent_cap)
+{
+ /* skip loading when called during fork */
+ if (!elf_ds.valid())
+ return;
+
+ /* attach ELF locally */
+ addr_t elf_addr;
+ try { elf_addr = local_rm.attach(elf_ds); }
+ catch (Region_map::Attach_failed) {
+ PERR("local attach of ELF executable failed"); throw; }
+
+ /* setup ELF object and read program entry pointer */
+ Elf_binary elf(elf_addr);
+ if (!elf.valid())
+ throw Invalid_executable();
+
+ bool const dynamically_linked = elf.is_dynamically_linked();
+
+ local_rm.detach(elf_addr);
+
+ /*
+ * If the specified executable is a dynamically linked program, we load
+ * the dynamic linker instead.
+ */
+ if (dynamically_linked) {
+
+ if (!ldso_ds.valid()) {
+ PERR("attempt to start dynamic executable without dynamic linker");
+ throw Missing_dynamic_linker();
+ }
+
+ elf_ds = ldso_ds;
+ }
+
+ pd.assign_parent(parent_cap);
+
+ Linux_native_pd_client
+ lx_pd(static_cap_cast(pd.native_pd()));
+
+ lx_pd.start(elf_ds);
+}
+
+
+Child::Process::~Process() { }
diff --git a/repos/base-linux/src/base/process/process.cc b/repos/base-linux/src/base/process/process.cc
deleted file mode 100644
index d5355dbeb..000000000
--- a/repos/base-linux/src/base/process/process.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * \brief Implementation of process creation for Linux
- * \author Norman Feske
- * \date 2006-07-06
- */
-
-/*
- * Copyright (C) 2006-2013 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-
-/* base-internal includes */
-#include
-#include
-
-
-using namespace Genode;
-
-Dataspace_capability Process::_dynamic_linker_cap;
-
-
-/**
- * Check for dynamic ELF header
- */
-static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap)
-{
- /* attach ELF locally */
- addr_t elf_addr;
-
- try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
- catch (...) { return false; }
-
- /*
- * If attach is called within core, it will return zero because
- * Linux uses Core_rm_session.
- */
- if (!elf_addr) return false;
-
- /* read program header and interpreter */
- Elf_binary elf((addr_t)elf_addr);
- env()->rm_session()->detach((void *)elf_addr);
-
- return elf.is_dynamically_linked();
-}
-
-
-Process::Process(Dataspace_capability elf_data_ds_cap,
- Pd_session_capability pd_session_cap,
- Ram_session_capability ram_session_cap,
- Cpu_session_capability cpu_session_cap,
- Region_map &,
- Parent_capability parent_cap,
- char const *name)
-:
- _pd_session_client(pd_session_cap),
- _cpu_session_client(cpu_session_cap)
-{
- /* check for dynamic program header */
- if (_check_dynamic_elf(elf_data_ds_cap)) {
- if (!_dynamic_linker_cap.valid()) {
- PERR("Dynamically linked file found, "
- "but no dynamic linker binary present");
- return;
- }
- elf_data_ds_cap = _dynamic_linker_cap;
- }
-
- /*
- * Register main thread at core
- *
- * At this point in time, we do not yet know the TID and PID of the new
- * thread. Those information will be provided to core by the constructor of
- * the 'Platform_env' of the new process.
- */
- enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
- _thread0_cap = _cpu_session_client.create_thread(pd_session_cap,
- WEIGHT, name);
-
- Linux_native_pd_client
- lx_pd(static_cap_cast(_pd_session_client.native_pd()));
-
- _pd_session_client.assign_parent(parent_cap);
- lx_pd.start(elf_data_ds_cap);
-}
-
-
-Process::~Process() { }
diff --git a/repos/base-nova/lib/mk/base-common.mk b/repos/base-nova/lib/mk/base-common.mk
index 5109da58c..b4874892b 100644
--- a/repos/base-nova/lib/mk/base-common.mk
+++ b/repos/base-nova/lib/mk/base-common.mk
@@ -13,7 +13,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
diff --git a/repos/base-okl4/lib/mk/base-common.mk b/repos/base-okl4/lib/mk/base-common.mk
index a0a4c7daa..beadde5fd 100644
--- a/repos/base-okl4/lib/mk/base-common.mk
+++ b/repos/base-okl4/lib/mk/base-common.mk
@@ -14,7 +14,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
diff --git a/repos/base-pistachio/lib/mk/base-common.mk b/repos/base-pistachio/lib/mk/base-common.mk
index 93b7ee797..68e0b9759 100644
--- a/repos/base-pistachio/lib/mk/base-common.mk
+++ b/repos/base-pistachio/lib/mk/base-common.mk
@@ -14,7 +14,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
diff --git a/repos/base-sel4/lib/mk/base-common.inc b/repos/base-sel4/lib/mk/base-common.inc
index 1db231895..3ad62dbc1 100644
--- a/repos/base-sel4/lib/mk/base-common.inc
+++ b/repos/base-sel4/lib/mk/base-common.inc
@@ -13,7 +13,7 @@ SRC_CC += allocator/allocator_avl.cc
SRC_CC += heap/heap.cc heap/sliced_heap.cc
SRC_CC += console/console.cc
SRC_CC += child/child.cc
-SRC_CC += process/process.cc
+SRC_CC += child/process.cc
SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h
index b19cbb129..23d80475e 100644
--- a/repos/base/include/base/child.h
+++ b/repos/base/include/base/child.h
@@ -16,14 +16,16 @@
#include
#include
-#include
#include
#include
#include
-#include
+#include
+#include
+#include
+#include
+#include
namespace Genode {
-
struct Child_policy;
struct Child;
}
@@ -157,12 +159,8 @@ class Genode::Child : protected Rpc_object
/* PD session representing the protection domain of the child */
Pd_session_capability _pd;
- /* PD session presented to the child as environment */
- Pd_session_capability _env_pd;
-
/* RAM session that contains the quota of the child */
Ram_session_capability _ram;
- Ram_session_client _ram_session_client { _ram };
/* CPU session that contains the quota of the child */
Cpu_session_capability _cpu;
@@ -175,11 +173,11 @@ class Genode::Child : protected Rpc_object
/* heap for child-specific allocations using the child's quota */
Heap _heap;
- Rpc_entrypoint *_entrypoint;
+ Rpc_entrypoint &_entrypoint;
Parent_capability _parent_cap;
/* child policy */
- Child_policy *_policy;
+ Child_policy &_policy;
/* sessions opened by the child */
Lock _lock; /* protect list manipulation */
@@ -200,6 +198,89 @@ class Genode::Child : protected Rpc_object
Lock _yield_request_lock;
Resource_args _yield_request_args;
+ struct Process
+ {
+ struct Initial_thread
+ {
+ Cpu_session &cpu;
+ Thread_capability cap;
+ Initial_thread(Cpu_session &, Pd_session_capability, char const *);
+ ~Initial_thread();
+ } initial_thread;
+
+ class Missing_dynamic_linker : Exception { };
+ class Invalid_executable : Exception { };
+
+ struct Loaded_executable
+ {
+ /**
+ * Initial instruction pointer of the new process, as defined
+ * in the header of the executable.
+ */
+ addr_t entry;
+
+ /**
+ * Constructor parses the executable and sets up segment
+ * dataspaces
+ *
+ * \param local_rm local address space, needed to make the
+ * segment dataspaces temporarily visible in
+ * the local address space to initialize their
+ * content with the data from the 'elf_ds'
+ *
+ * \throw Region_map::Attach_failed
+ * \throw Invalid_executable
+ * \throw Missing_dynamic_linker
+ * \throw Ram_session::Alloc_failed
+ */
+ Loaded_executable(Dataspace_capability elf_ds,
+ Dataspace_capability ldso_ds,
+ Ram_session &ram,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Parent_capability parent_cap);
+ } loaded_executable;
+
+ /**
+ * Constructor
+ *
+ * \param ram RAM session used to allocate the BSS and
+ * DATA segments for the new process
+ * \param cpu CPU session used to create the initial thread
+ * \param parent parent of the new protection domain
+ * \param name name of protection domain
+ *
+ * \throw Cpu_session::Thread_creation_failed
+ * \throw Cpu_session::Out_of_metadata
+ * \throw Missing_dynamic_linker
+ * \throw Invalid_executable
+ * \throw Region_map::Attach_failed
+ * \throw Ram_session::Alloc_failed
+ *
+ * The other arguments correspond to those of 'Child::Child'.
+ *
+ * On construction of a protection domain, the initial thread is
+ * started immediately.
+ *
+ * The argument 'elf_ds' may be invalid to create an empty process.
+ * In this case, all process initialization steps except for the
+ * creation of the initial thread must be done manually, i.e., as
+ * done for implementing fork.
+ */
+ Process(Dataspace_capability elf_ds,
+ Dataspace_capability ldso_ds,
+ Pd_session_capability pd_cap,
+ Pd_session &pd,
+ Ram_session &ram,
+ Cpu_session &cpu,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Parent_capability parent,
+ char const *name);
+
+ ~Process();
+ };
+
Process _process;
/**
@@ -225,52 +306,81 @@ class Genode::Child : protected Rpc_object
* solely used for targeting resource donations during
* 'Parent::upgrade_quota()' calls.
*/
- static Service *_parent_service();
+ static Service &_parent_service();
public:
+ /**
+ * Exception type
+ *
+ * The startup of the physical process of the child may fail if the
+ * ELF binary is invalid, if the ELF binary is dynamically linked
+ * but no dynamic linker is provided, if the creation of the initial
+ * thread failed, or if the RAM session of the child is exhausted.
+ * Each of those conditions will result in a diagnostic log message.
+ * But for the error handling, we only distinguish the RAM exhaustion
+ * from the other conditions and subsume the latter as
+ * 'Process_startup_failed'.
+ */
+ class Process_startup_failed : public Exception { };
+
/**
* Constructor
*
- * \param elf_ds dataspace containing the binary
- * \param pd PD session representing the protection domain
- * \param ram RAM session with the child's quota
- * \param cpu CPU session with the child's quota
- * \param entrypoint server entrypoint to serve the parent interface
- * \param policy child policy
+ * \param elf_ds dataspace that contains the ELF binary
+ * \param ldso_ds dataspace that contains the dynamic linker,
+ * started if 'elf_ds' is a dynamically linked
+ * executable
+ * \param pd_cap capability of the new protection domain,
+ * used as argument for creating the initial
+ * thread, and handed out to the child as its
+ * environment
+ * \param pd PD session used for assigning the parent
+ * capability of the new process
+ * \param ram_cap RAM session capability handed out to the
+ * child as its environment
+ * \param ram RAM session used to allocate the BSS and
+ * DATA segments and as backing store for the
+ * local heap partition to keep child-specific
+ * meta data
+ * \param cpu_cap CPU session capability handed out to the
+ * child as its environment
+ * \param cpu CPU session for the new protection domain
+ * \param local_rm local address space
+ * \param remote_rm address space of new protection domain
* \param pd_service provider of the 'pd' session
* \param ram_service provider of the 'ram' session
* \param cpu_service provider of the 'cpu' session
*
- * If assigning a separate entry point to each child, the host of
- * multiple children is able to handle a blocking invocation of
- * the parent interface of one child while still maintaining the
- * service to other children, each having an independent entry
- * point.
+ * \throw Ram_session::Alloc_failed
+ * \throw Process_startup_failed
+ *
+ * Usually, the pairs of 'pd' and 'pd_cap', 'cpu' and 'cpu_cap',
+ * 'ram' and 'ram_cap' belong to each other. References to the
+ * session interfaces are passed as separate arguments in addition
+ * to the capabilities to allow the creator of a child to operate on
+ * locally implemented sessions during the child initialization.
*
* The 'ram_service', 'cpu_service', and 'pd_service' arguments are
* needed to direct quota upgrades referring to the resources of
* the child environment. By default, we expect that these
* resources are provided by the parent.
- *
- * The 'env_pd' argument override the PD session capability that is
- * handed out as part of the child's environment. Normally, a child
- * will receive the physical PD capability of the PD session at core.
- * However, a runtime environment may wish to intercept the interaction
- * of the child with its PD session by specifying a capability to a
- * locally implemented PD session.
*/
Child(Dataspace_capability elf_ds,
- Pd_session_capability pd,
- Ram_session_capability ram,
- Cpu_session_capability cpu,
- Region_map &address_space,
- Rpc_entrypoint *entrypoint,
- Child_policy *policy,
- Service &pd_service = *_parent_service(),
- Service &ram_service = *_parent_service(),
- Service &cpu_service = *_parent_service(),
- Pd_session_capability env_pd = Pd_session_capability());
+ Dataspace_capability ldso_ds,
+ Pd_session_capability pd_cap,
+ Pd_session &pd,
+ Ram_session_capability ram_cap,
+ Ram_session &ram,
+ Cpu_session_capability cpu_cap,
+ Cpu_session &cpu,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Rpc_entrypoint &entrypoint,
+ Child_policy &policy,
+ Service &pd_service = _parent_service(),
+ Service &ram_service = _parent_service(),
+ Service &cpu_service = _parent_service());
/**
* Destructor
@@ -290,10 +400,6 @@ class Genode::Child : protected Rpc_object
Cpu_session_capability cpu_session_cap() const { return _cpu; }
Parent_capability parent_cap() const { return cap(); }
- /**
- */
- void env_pd(Pd_session_capability pd) { _env_pd = pd; }
-
/**
* Discard all sessions to specified service
*
diff --git a/repos/base/include/base/process.h b/repos/base/include/base/process.h
deleted file mode 100644
index 0701ac1da..000000000
--- a/repos/base/include/base/process.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * \brief Process-creation interface
- * \author Norman Feske
- * \date 2006-06-22
- */
-
-/*
- * Copyright (C) 2006-2013 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-
-#ifndef _INCLUDE__BASE__PROCESS_H_
-#define _INCLUDE__BASE__PROCESS_H_
-
-#include
-#include
-#include
-#include
-#include
-
-namespace Genode { class Process; }
-
-
-class Genode::Process
-{
- private:
-
- Pd_session_client _pd_session_client;
- Thread_capability _thread0_cap;
- Cpu_session_client _cpu_session_client;
-
- static Dataspace_capability _dynamic_linker_cap;
-
- public:
-
- /**
- * Constructor
- *
- * \param elf_data_ds dataspace that contains the elf binary
- * \param pd_session the new protection domain
- * \param ram_session RAM session providing the BSS for the
- * new protection domain
- * \param cpu_session CPU session for the new protection domain
- * \param address_space region map of new protection domain
- * \param parent parent of the new protection domain
- * \param name name of protection domain (can be used
- * for debugging)
- *
- * The dataspace 'elf_data_ds' can be read-only.
- *
- * On construction of a protection domain, execution of the initial
- * thread is started immediately.
- */
- Process(Dataspace_capability elf_data_ds,
- Pd_session_capability pd_session,
- Ram_session_capability ram_session,
- Cpu_session_capability cpu_session,
- Region_map &address_space,
- Parent_capability parent,
- char const *name);
-
- /**
- * Destructor
- *
- * When called, the protection domain gets killed.
- */
- ~Process();
-
- static void dynamic_linker(Dataspace_capability dynamic_linker_cap)
- {
- _dynamic_linker_cap = dynamic_linker_cap;
- }
-
- Thread_capability main_thread_cap() const { return _thread0_cap; }
-};
-
-#endif /* _INCLUDE__BASE__PROCESS_H_ */
diff --git a/repos/base/src/base/child/child.cc b/repos/base/src/base/child/child.cc
index da2ffa818..3feb66e79 100644
--- a/repos/base/src/base/child/child.cc
+++ b/repos/base/src/base/child/child.cc
@@ -201,17 +201,17 @@ void Child::_remove_session(Child::Session *s)
_session_list.remove(s);
/* return session quota to the ram session of the child */
- if (_policy->ref_ram_session()->transfer_quota(_ram, s->donated_ram_quota()))
+ if (_policy.ref_ram_session()->transfer_quota(_ram, s->donated_ram_quota()))
PERR("We ran out of our own quota");
destroy(heap(), s);
}
-Service *Child::_parent_service()
+Service &Child::_parent_service()
{
static Parent_service parent_service("");
- return &parent_service;
+ return parent_service;
}
@@ -247,7 +247,7 @@ void Child::_close(Session* s)
*/
if (s->service()->ram_session_cap().valid()) {
Ram_session_client server_ram(s->service()->ram_session_cap());
- if (server_ram.transfer_quota(_policy->ref_ram_cap(),
+ if (server_ram.transfer_quota(_policy.ref_ram_cap(),
s->donated_ram_quota())) {
PERR("Misbehaving server '%s'!", s->service()->name());
}
@@ -303,7 +303,7 @@ void Child::announce(Parent::Service_name const &name, Root_capability root)
{
if (!name.is_valid_string()) return;
- _policy->announce_service(name.string(), root, heap(), &_server);
+ _policy.announce_service(name.string(), root, heap(), &_server);
}
@@ -316,28 +316,28 @@ Session_capability Child::session(Parent::Service_name const &name,
/* return sessions that we created for the child */
if (!strcmp("Env::ram_session", name.string())) return _ram;
if (!strcmp("Env::cpu_session", name.string())) return _cpu;
- if (!strcmp("Env::pd_session", name.string())) return _env_pd;
+ if (!strcmp("Env::pd_session", name.string())) return _pd;
/* filter session arguments according to the child policy */
strncpy(_args, args.string(), sizeof(_args));
- _policy->filter_session_args(name.string(), _args, sizeof(_args));
+ _policy.filter_session_args(name.string(), _args, sizeof(_args));
/* filter session affinity */
- Affinity const filtered_affinity = _policy->filter_session_affinity(affinity);
+ Affinity const filtered_affinity = _policy.filter_session_affinity(affinity);
/* transfer the quota donation from the child's account to ourself */
size_t ram_quota = Arg_string::find_arg(_args, "ram_quota").ulong_value(0);
- Transfer donation_from_child(ram_quota, _ram, _policy->ref_ram_cap());
+ Transfer donation_from_child(ram_quota, _ram, _policy.ref_ram_cap());
- Service *service = _policy->resolve_session_request(name.string(), _args);
+ Service *service = _policy.resolve_session_request(name.string(), _args);
/* raise an error if no matching service provider could be found */
if (!service)
throw Service_denied();
/* transfer session quota from ourself to the service provider */
- Transfer donation_to_service(ram_quota, _policy->ref_ram_cap(),
+ Transfer donation_to_service(ram_quota, _policy.ref_ram_cap(),
service->ram_session_cap());
/* create session */
@@ -391,10 +391,10 @@ void Child::upgrade(Session_capability to_session, Parent::Upgrade_args const &a
Arg_string::find_arg(args.string(), "ram_quota").ulong_value(0);
/* transfer quota from client to ourself */
- Transfer donation_from_child(ram_quota, _ram, _policy->ref_ram_cap());
+ Transfer donation_from_child(ram_quota, _ram, _policy.ref_ram_cap());
/* transfer session quota from ourself to the service provider */
- Transfer donation_to_service(ram_quota, _policy->ref_ram_cap(),
+ Transfer donation_to_service(ram_quota, _policy.ref_ram_cap(),
targeted_service->ram_session_cap());
try { targeted_service->upgrade(to_session, args.string()); }
@@ -439,13 +439,13 @@ void Child::exit(int exit_value)
* Note that the child object must not be destructed from by this function
* because it is executed by the thread contained in the child object.
*/
- return _policy->exit(exit_value);
+ return _policy.exit(exit_value);
}
Thread_capability Child::main_thread_cap() const
{
- return _process.main_thread_cap();
+ return _process.initial_thread.cap;
}
@@ -457,7 +457,7 @@ void Child::resource_avail_sigh(Signal_context_capability sigh)
void Child::resource_request(Resource_args const &args)
{
- _policy->resource_request(args);
+ _policy.resource_request(args);
}
@@ -472,37 +472,48 @@ Parent::Resource_args Child::yield_request()
}
-void Child::yield_response() { _policy->yield_response(); }
+void Child::yield_response() { _policy.yield_response(); }
Child::Child(Dataspace_capability elf_ds,
- Pd_session_capability pd,
- Ram_session_capability ram,
- Cpu_session_capability cpu,
- Region_map &address_space,
- Rpc_entrypoint *entrypoint,
- Child_policy *policy,
+ Dataspace_capability ldso_ds,
+ Pd_session_capability pd_cap,
+ Pd_session &pd,
+ Ram_session_capability ram_cap,
+ Ram_session &ram,
+ Cpu_session_capability cpu_cap,
+ Cpu_session &cpu,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Rpc_entrypoint &entrypoint,
+ Child_policy &policy,
Service &pd_service,
Service &ram_service,
- Service &cpu_service,
- Pd_session_capability env_pd)
-:
- _pd(pd), _env_pd(env_pd.valid() ? env_pd : pd), _ram(ram),
- _cpu(cpu), _pd_service(pd_service),
- _ram_service(ram_service), _cpu_service(cpu_service),
- _heap(&_ram_session_client, env()->rm_session()),
+ Service &cpu_service)
+try :
+ _pd(pd_cap), _ram(ram_cap), _cpu(cpu_cap),
+ _pd_service(pd_service),
+ _ram_service(ram_service),
+ _cpu_service(cpu_service),
+ _heap(&ram, &local_rm),
_entrypoint(entrypoint),
- _parent_cap(_entrypoint->manage(this)),
+ _parent_cap(_entrypoint.manage(this)),
_policy(policy),
- _server(ram),
- _process(elf_ds, pd, ram, cpu, address_space, _parent_cap, policy->name())
+ _server(_ram),
+ _process(elf_ds, ldso_ds, pd_cap, pd, ram, cpu, local_rm, remote_rm,
+ _parent_cap, policy.name())
{ }
+catch (Cpu_session::Thread_creation_failed) { throw Process_startup_failed(); }
+catch (Cpu_session::Out_of_metadata) { throw Process_startup_failed(); }
+catch (Process::Missing_dynamic_linker) { throw Process_startup_failed(); }
+catch (Process::Invalid_executable) { throw Process_startup_failed(); }
+catch (Region_map::Attach_failed) { throw Process_startup_failed(); }
Child::~Child()
{
- _entrypoint->dissolve(this);
- _policy->unregister_services();
+ _entrypoint.dissolve(this);
+ _policy.unregister_services();
_session_pool.remove_all([&] (Session *s) { _close(s); });
}
diff --git a/repos/base/src/base/child/process.cc b/repos/base/src/base/child/process.cc
new file mode 100644
index 000000000..c9112cad5
--- /dev/null
+++ b/repos/base/src/base/child/process.cc
@@ -0,0 +1,213 @@
+/*
+ * \brief Process creation
+ * \author Norman Feske
+ * \author Christian Helmuth
+ * \date 2006-07-18
+ */
+
+/*
+ * Copyright (C) 2006-2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Genode includes */
+#include
+#include
+
+/* base-internal includes */
+#include
+
+using namespace Genode;
+
+
+Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds,
+ Dataspace_capability ldso_ds,
+ Ram_session &ram,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Parent_capability parent_cap)
+{
+ /* skip loading when called during fork */
+ if (!elf_ds.valid())
+ return;
+
+ /* attach ELF locally */
+ addr_t elf_addr;
+ try { elf_addr = local_rm.attach(elf_ds); }
+ catch (Region_map::Attach_failed) {
+ PERR("local attach of ELF executable failed"); throw; }
+
+ /* setup ELF object and read program entry pointer */
+ Elf_binary elf(elf_addr);
+ if (!elf.valid())
+ throw Invalid_executable();
+
+ /*
+ * If the specified executable is a dynamically linked program, we load
+ * the dynamic linker instead.
+ */
+ if (elf.is_dynamically_linked()) {
+
+ local_rm.detach(elf_addr);
+
+ if (!ldso_ds.valid()) {
+ PERR("attempt to start dynamic executable without dynamic linker");
+ throw Missing_dynamic_linker();
+ }
+
+ try { elf_addr = local_rm.attach(ldso_ds); }
+ catch (Region_map::Attach_failed) {
+ PERR("local attach of dynamic linker failed"); throw; }
+
+ elf_ds = ldso_ds;
+ elf = Elf_binary(elf_addr);
+ }
+
+ entry = elf.entry();
+
+ /* setup region map for the new pd */
+ Elf_segment seg;
+
+ for (unsigned n = 0; (seg = elf.get_segment(n)).valid(); ++n) {
+ if (seg.flags().skip) continue;
+
+ /* same values for r/o and r/w segments */
+ addr_t const addr = (addr_t)seg.start();
+ size_t const size = seg.mem_size();
+
+ bool parent_info = false;
+
+ bool const write = seg.flags().w;
+ bool const exec = seg.flags().x;
+
+ if (write) {
+
+ /* read-write segment */
+
+ /*
+ * Note that a failure to allocate a RAM dataspace after other
+ * segments were successfully allocated will not revert the
+ * previous allocations. The successful allocations will leak.
+ * In practice, this is not a problem as each component has its
+ * distinct RAM session. When the process creation failed, the
+ * entire RAM session will be destroyed and the memory will be
+ * regained.
+ */
+
+ /* alloc dataspace */
+ Dataspace_capability ds_cap;
+ try { ds_cap = ram.alloc(size); }
+ catch (Ram_session::Alloc_failed) {
+ PERR("allocation of read-write segment failed"); throw; };
+
+ /* attach dataspace */
+ void *base;
+ try { base = local_rm.attach(ds_cap); }
+ catch (Region_map::Attach_failed) {
+ PERR("local attach of segment dataspace failed"); throw; }
+
+ void * const ptr = base;
+ addr_t const laddr = elf_addr + seg.file_offset();
+
+ /* copy contents and fill with zeros */
+ memcpy(ptr, (void *)laddr, seg.file_size());
+ if (size > seg.file_size())
+ memset((void *)((addr_t)ptr + seg.file_size()),
+ 0, size - seg.file_size());
+
+ /*
+ * We store the parent information at the beginning of the first
+ * data segment
+ */
+ if (!parent_info) {
+ Native_capability::Raw *raw = (Native_capability::Raw *)ptr;
+
+ raw->dst = parent_cap.dst();
+ raw->local_name = parent_cap.local_name();
+
+ parent_info = true;
+ }
+
+ /* detach dataspace */
+ local_rm.detach(base);
+
+ off_t const offset = 0;
+ try { remote_rm.attach_at(ds_cap, addr, size, offset); }
+ catch (Region_map::Attach_failed) {
+ PERR("remote attach of read-write segment failed"); throw; }
+
+ } else {
+
+ /* read-only segment */
+
+ if (seg.file_size() != seg.mem_size())
+ PWRN("filesz and memsz for read-only segment differ");
+
+ off_t const offset = seg.file_offset();
+ try {
+ if (exec)
+ remote_rm.attach_executable(elf_ds, addr, size, offset);
+ else
+ remote_rm.attach_at(elf_ds, addr, size, offset);
+ }
+ catch (Region_map::Attach_failed) {
+ PERR("remote attach of read-only segment failed"); throw; }
+ }
+ }
+
+ /* detach ELF */
+ local_rm.detach((void *)elf_addr);
+}
+
+
+Child::Process::Initial_thread::Initial_thread(Cpu_session &cpu,
+ Pd_session_capability pd,
+ char const *name)
+:
+ cpu(cpu),
+ cap(cpu.create_thread(pd, Cpu_session::DEFAULT_WEIGHT, name))
+{ }
+
+
+Child::Process::Initial_thread::~Initial_thread()
+{
+ cpu.kill_thread(cap);
+}
+
+
+Child::Process::Process(Dataspace_capability elf_ds,
+ Dataspace_capability ldso_ds,
+ Pd_session_capability pd_cap,
+ Pd_session &pd,
+ Ram_session &ram,
+ Cpu_session &cpu,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Parent_capability parent_cap,
+ char const *name)
+:
+ initial_thread(cpu, pd_cap, name),
+ loaded_executable(elf_ds, ldso_ds, ram, local_rm, remote_rm, parent_cap)
+{
+ /* register parent interface for new protection domain */
+ pd.assign_parent(parent_cap);
+
+ /*
+ * Inhibit start of main thread if the new process happens to be forked
+ * from another. In this case, the main thread will get manually
+ * started after constructing the 'Process'.
+ */
+ if (!elf_ds.valid())
+ return;
+
+ /* start main thread */
+ if (cpu.start(initial_thread.cap, loaded_executable.entry, 0)) {
+ PERR("start of initial thread failed");
+ throw Cpu_session::Thread_creation_failed();
+ }
+}
+
+
+Child::Process::~Process() { }
diff --git a/repos/base/src/base/process/process.cc b/repos/base/src/base/process/process.cc
deleted file mode 100644
index ec062aeac..000000000
--- a/repos/base/src/base/process/process.cc
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * \brief Process creation
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2006-07-18
- */
-
-/*
- * Copyright (C) 2006-2013 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU General Public License version 2.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-
-/* base-internal includes */
-#include
-
-using namespace Genode;
-
-Dataspace_capability Process::_dynamic_linker_cap;
-
-/**
- * Check for dynamic ELF header
- *
- * \param elf_ds_cap dataspace containing the ELF binary
- */
-
-static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap)
-{
- /* attach ELF locally */
- addr_t elf_addr;
- try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
- catch (Region_map::Attach_failed) { return false; }
-
- /* read program header */
- Elf_binary elf((addr_t)elf_addr);
- env()->rm_session()->detach((void *)elf_addr);
-
- return elf.is_dynamically_linked();
-}
-
-/**
- * Parse ELF and setup segment dataspace
- *
- * \param parent_cap parent capability for child (i.e. myself)
- * \param elf_ds_cap dataspace containing the ELF binary
- * \param ram RAM session of the new protection domain
- * \param rm region map of the new protection domain
- */
-static addr_t _setup_elf(Parent_capability parent_cap,
- Dataspace_capability elf_ds_cap,
- Ram_session &ram, Region_map &rm)
-{
- /* attach ELF locally */
- addr_t elf_addr;
- try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
- catch (Region_map::Attach_failed) { return 0; }
-
- /* setup ELF object and read program entry pointer */
- Elf_binary elf((addr_t)elf_addr);
- if (!elf.valid())
- return 0;
-
- /*
- * entry point of program - can be set to 0 to indicate errors in ELF
- * handling
- */
- addr_t entry = elf.entry();
-
- /* setup region map for the new pd */
- Elf_segment seg;
-
- for (unsigned n = 0; (seg = elf.get_segment(n)).valid(); ++n) {
- if (seg.flags().skip) continue;
-
- /* same values for r/o and r/w segments */
- addr_t addr = (addr_t)seg.start();
- size_t size = seg.mem_size();
-
- bool parent_info = false;
- off_t offset;
- Dataspace_capability ds_cap;
- void *out_ptr = 0;
-
- bool write = seg.flags().w;
- bool exec = seg.flags().x;
-
- if (write) {
-
- /* read-write segment */
- offset = 0;
-
- /* alloc dataspace */
- try { ds_cap = ram.alloc(size); }
- catch (Ram_session::Alloc_failed) {
- PERR("Ram.alloc() failed");
- entry = 0;
- break;
- }
-
- /* attach dataspace */
- void *base;
- try { base = env()->rm_session()->attach(ds_cap); }
- catch (Region_map::Attach_failed) {
- PERR("env()->rm_session()->attach() failed");
- entry = 0;
- break;
- }
-
- void *ptr = base;
- addr_t laddr = elf_addr + seg.file_offset();
-
- /* copy contents and fill with zeros */
- memcpy(ptr, (void *)laddr, seg.file_size());
- if (size > seg.file_size())
- memset((void *)((addr_t)ptr + seg.file_size()),
- 0, size - seg.file_size());
-
- /*
- * we store the parent information at the beginning of the first
- * data segment
- */
- if (!parent_info) {
- Native_capability::Raw *raw = (Native_capability::Raw *)ptr;
-
- raw->dst = parent_cap.dst();
- raw->local_name = parent_cap.local_name();
-
- parent_info = true;
- }
-
- /* detach dataspace */
- env()->rm_session()->detach(base);
-
- try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); }
- catch (Region_map::Attach_failed) { }
-
- } else {
-
- /* read-only segment */
- offset = seg.file_offset();
- ds_cap = elf_ds_cap;
-
- /* XXX currently we assume r/o segment sizes never differ */
- if (seg.file_size() != seg.mem_size())
- PWRN("filesz and memsz for read-only segment differ");
-
- if (exec)
- try { out_ptr = rm.attach_executable(ds_cap, addr, size, offset); }
- catch (Region_map::Attach_failed) { }
- else
- try { out_ptr = rm.attach_at(ds_cap, addr, size, offset); }
- catch (Region_map::Attach_failed) { }
- }
-
- if ((addr_t)out_ptr != addr)
- PWRN("addresses differ after attach (addr=%p out_ptr=%p)",
- (void *)addr, out_ptr);
- }
-
- /* detach ELF */
- env()->rm_session()->detach((void *)elf_addr);
-
- return entry;
-}
-
-
-Process::Process(Dataspace_capability elf_ds_cap,
- Pd_session_capability pd_session_cap,
- Ram_session_capability ram_session_cap,
- Cpu_session_capability cpu_session_cap,
- Region_map &address_space,
- Parent_capability parent_cap,
- char const *name)
-: _pd_session_client(pd_session_cap),
- _cpu_session_client(cpu_session_cap)
-{
- if (!pd_session_cap.valid())
- return;
-
- enum Local_exception { THREAD_FAIL, ELF_FAIL, THREAD_START_FAIL };
-
- /* XXX this only catches local exceptions */
-
- /* FIXME find sane quota values or make them configurable */
- try {
- int err;
-
- /* create thread0 */
- try {
- enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
- _thread0_cap = _cpu_session_client.create_thread(pd_session_cap, WEIGHT, name);
- } catch (Cpu_session::Thread_creation_failed) {
- PERR("creation of initial thread failed");
- throw THREAD_FAIL;
- } catch (Cpu_session::Out_of_metadata) {
- PERR("out of meta data while creating initial thread");
- throw THREAD_FAIL;
- }
-
- /*
- * The argument 'elf_ds_cap' may be invalid, which is not an error.
- * This can happen when the process library is used to set up a process
- * forked from another. In this case, all process initialization should
- * be done except for the ELF loading and the startup of the main
- * thread (as a forked process does not start its execution at the ELF
- * entrypoint).
- */
- bool const forked = !elf_ds_cap.valid();
-
- /* check for dynamic program header */
- if (!forked && _check_dynamic_elf(elf_ds_cap)) {
- if (!_dynamic_linker_cap.valid()) {
- PERR("Dynamically linked file found, but no dynamic linker binary present");
- throw ELF_FAIL;
- }
- elf_ds_cap = _dynamic_linker_cap;
- }
-
- /* init temporary allocator object */
- Ram_session_client ram(ram_session_cap);
-
- /* parse ELF binary and setup segment dataspaces */
- addr_t entry = 0;
- if (elf_ds_cap.valid()) {
- entry = _setup_elf(parent_cap, elf_ds_cap, ram, address_space);
- if (!entry) {
- PERR("Setup ELF failed");
- throw ELF_FAIL;
- }
- }
-
- /* register parent interface for new protection domain */
- _pd_session_client.assign_parent(parent_cap);
-
- /*
- * Inhibit start of main thread if the new process happens to be forked
- * from another. In this case, the main thread will get manually
- * started after constructing the 'Process'.
- */
- if (!forked) {
-
- /* start main thread */
- err = _cpu_session_client.start(_thread0_cap, entry, 0 /* unused */);
- if (err) {
- PERR("Thread0 startup failed");
- throw THREAD_START_FAIL;
- }
- }
- }
- catch (Local_exception cause) {
-
- switch (cause) {
-
- case THREAD_START_FAIL:
- case ELF_FAIL:
-
- _cpu_session_client.kill_thread(_thread0_cap);
- _thread0_cap = Thread_capability();
-
- case THREAD_FAIL:
-
- default:
- PWRN("unknown exception?");
- }
- }
-}
-
-
-Process::~Process()
-{
- /*
- * Try to kill thread0, which was created in the process constructor. If
- * this fails, do nothing.
- */
- try { _cpu_session_client.kill_thread(_thread0_cap); }
- catch (Genode::Ipc_error) { }
-}
diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc
index 1e556ffa9..83c1bc222 100644
--- a/repos/base/src/core/main.cc
+++ b/repos/base/src/core/main.cc
@@ -111,6 +111,16 @@ class Core_child : public Child_policy
Service_registry &_local_services;
+ /*
+ * Dynamic linker, does not need to be valid because init is statically
+ * linked
+ */
+ Dataspace_capability _ldso_ds;
+
+ Pd_session_client _pd;
+ Ram_session_client _ram;
+ Cpu_session_client _cpu;
+
Region_map_client _address_space;
Child _child;
@@ -127,9 +137,10 @@ class Core_child : public Child_policy
:
_entrypoint(nullptr, STACK_SIZE, "init", false),
_local_services(services),
+ _pd(pd), _ram(ram), _cpu(cpu),
_address_space(Pd_session_client(pd).address_space()),
- _child(elf_ds, pd, ram, cpu, _address_space,
- &_entrypoint, this,
+ _child(elf_ds, _ldso_ds, _pd, _pd, _ram, _ram, _cpu, _cpu,
+ *env()->rm_session(), _address_space, _entrypoint, *this,
*_local_services.find(Pd_session::service_name()),
*_local_services.find(Ram_session::service_name()),
*_local_services.find(Cpu_session::service_name()))
diff --git a/repos/base/src/test/rm_fault/main.cc b/repos/base/src/test/rm_fault/main.cc
index 79c14622a..831290182 100644
--- a/repos/base/src/test/rm_fault/main.cc
+++ b/repos/base/src/test/rm_fault/main.cc
@@ -79,7 +79,10 @@ class Test_child : public Child_policy
*/
Rpc_entrypoint _entrypoint;
- Region_map_client _address_space;
+ Region_map_client _address_space;
+ Pd_session_client _pd;
+ Ram_session_client _ram;
+ Cpu_session_client _cpu;
Child _child;
@@ -97,8 +100,10 @@ class Test_child : public Child_policy
Genode::Cap_session *cap)
:
_entrypoint(cap, STACK_SIZE, "child", false),
- _address_space(pd.address_space()),
- _child(elf_ds, pd, ram, cpu, _address_space, &_entrypoint, this),
+ _address_space(pd.address_space()), _pd(pd), _ram(ram), _cpu(cpu),
+ _child(elf_ds, Dataspace_capability(), _pd, _pd, _ram, _ram,
+ _cpu, _cpu, *env()->rm_session(), _address_space,
+ _entrypoint, *this),
_log_service("LOG")
{
/* start execution of the new child */
diff --git a/repos/demo/include/launchpad/launchpad.h b/repos/demo/include/launchpad/launchpad.h
index a9eb8881e..306cfd9ce 100644
--- a/repos/demo/include/launchpad/launchpad.h
+++ b/repos/demo/include/launchpad/launchpad.h
@@ -152,12 +152,9 @@ class Launchpad_child : public Genode::List::Element
{
private:
- Launchpad *_launchpad;
+ static Genode::Dataspace_capability _ldso_ds();
- Genode::Rom_session_capability _rom;
- Genode::Ram_session_capability _ram;
- Genode::Cpu_session_capability _cpu;
- Genode::Server _server;
+ Launchpad *_launchpad;
/*
* Entry point used for serving the parent interface and the
@@ -167,7 +164,14 @@ class Launchpad_child : public Genode::List::Element
enum { ENTRYPOINT_STACK_SIZE = 12*1024 };
Genode::Rpc_entrypoint _entrypoint;
- Genode::Region_map_client _address_space;
+ Genode::Region_map_client _address_space;
+
+ Genode::Rom_session_client _rom;
+ Genode::Pd_session_client _pd;
+ Genode::Ram_session_client _ram;
+ Genode::Cpu_session_client _cpu;
+
+ Genode::Server _server;
Launchpad_child_policy _policy;
Genode::Child _child;
@@ -187,13 +191,17 @@ class Launchpad_child : public Genode::List::Element
Launchpad *launchpad)
:
_launchpad(launchpad),
- _rom(rom), _ram(ram), _cpu(cpu), _server(_ram),
_entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false),
_address_space(Genode::Pd_session_client(pd).address_space()),
+ _rom(rom), _pd(pd), _ram(ram), _cpu(cpu), _server(_ram),
_policy(name, &_server, parent_services, child_services,
config_ds, elf_ds, &_entrypoint),
- _child(elf_ds, pd, ram, cpu, _address_space, &_entrypoint, &_policy) {
- _entrypoint.activate(); }
+ _child(elf_ds, _ldso_ds(), _pd, _pd, _ram, _ram, _cpu, _cpu,
+ *Genode::env()->rm_session(), _address_space,
+ _entrypoint, _policy)
+ {
+ _entrypoint.activate();
+ }
Genode::Rom_session_capability rom_session_cap() { return _rom; }
Genode::Ram_session_capability ram_session_cap() { return _ram; }
diff --git a/repos/demo/src/app/launchpad/main.cc b/repos/demo/src/app/launchpad/main.cc
index 39cfac8b2..80aa07f8e 100644
--- a/repos/demo/src/app/launchpad/main.cc
+++ b/repos/demo/src/app/launchpad/main.cc
@@ -92,12 +92,6 @@ int main(int argc, char **argv)
{
using namespace Scout;
- /* look for dynamic linker */
- try {
- static Genode::Rom_connection rom("ld.lib.so");
- Genode::Process::dynamic_linker(rom.dataspace());
- } catch (...) { }
-
static Nitpicker::Connection nitpicker;
static Platform pf(*nitpicker.input());
diff --git a/repos/demo/src/lib/launchpad/launchpad.cc b/repos/demo/src/lib/launchpad/launchpad.cc
index 4fc403511..840c9e8d4 100644
--- a/repos/demo/src/lib/launchpad/launchpad.cc
+++ b/repos/demo/src/lib/launchpad/launchpad.cc
@@ -412,6 +412,23 @@ static Timer::Session *timer_session()
}
+Dataspace_capability Launchpad_child::_ldso_ds()
+{
+ static bool first_attempt_failed = false;
+
+ if (!first_attempt_failed) {
+ try {
+ static Rom_connection rom("ld.lib.so");
+ static Dataspace_capability ds = rom.dataspace();
+ return ds;
+ } catch (...) { }
+ }
+
+ first_attempt_failed = true;
+ return Dataspace_capability();
+}
+
+
/* construct child-destructor thread early - in case we run out of threads */
static Child_destructor_thread child_destructor;
diff --git a/repos/gems/src/app/launcher/context_dialog.h b/repos/gems/src/app/launcher/context_dialog.h
index a7e811ce9..ee6a00a37 100644
--- a/repos/gems/src/app/launcher/context_dialog.h
+++ b/repos/gems/src/app/launcher/context_dialog.h
@@ -106,10 +106,12 @@ class Launcher::Context_dialog : Input_event_handler, Dialog_generator,
public:
Context_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
+ Dataspace_capability ldso_ds,
Report_rom_slave &report_rom_slave,
Response_handler &response_handler)
:
- _dialog(ep, cap, ram, report_rom_slave, "context_dialog", "context_hover",
+ _dialog(ep, cap, ram, ldso_ds, report_rom_slave,
+ "context_dialog", "context_hover",
*this, *this, *this, *this,
Fading_dialog::Position(364, 64)),
_response_handler(response_handler)
diff --git a/repos/gems/src/app/launcher/fading_dialog.h b/repos/gems/src/app/launcher/fading_dialog.h
index 2853f324d..8e9fe737c 100644
--- a/repos/gems/src/app/launcher/fading_dialog.h
+++ b/repos/gems/src/app/launcher/fading_dialog.h
@@ -212,6 +212,7 @@ class Launcher::Fading_dialog : private Input_event_handler
Fading_dialog(Server::Entrypoint &ep,
Cap_session &cap,
Ram_session &ram,
+ Dataspace_capability ldso_ds,
Report_rom_slave &report_rom_slave,
char const *dialog_name,
char const *hover_name,
@@ -232,8 +233,9 @@ class Launcher::Fading_dialog : private Input_event_handler
_hover_update_dispatcher(ep, *this, &Fading_dialog::_handle_hover_update),
_fader_slave_ep(&cap, _fader_slave_ep_stack_size, "nit_fader"),
_nitpicker_service(ep, _fader_slave_ep, *this),
- _nit_fader_slave(_fader_slave_ep, ram, _nitpicker_service),
- _menu_view_slave(cap, ram, _nit_fader_slave.nitpicker_session("menu"),
+ _nit_fader_slave(_fader_slave_ep, ram, _nitpicker_service, ldso_ds),
+ _menu_view_slave(cap, ram, ldso_ds,
+ _nit_fader_slave.nitpicker_session("menu"),
_dialog_rom, _hover_report, initial_position)
{
Rom_session_client(_hover_rom).sigh(_hover_update_dispatcher);
diff --git a/repos/gems/src/app/launcher/main.cc b/repos/gems/src/app/launcher/main.cc
index fbb47b2a7..53b991a9c 100644
--- a/repos/gems/src/app/launcher/main.cc
+++ b/repos/gems/src/app/launcher/main.cc
@@ -30,6 +30,17 @@ struct Launcher::Main
{
Server::Entrypoint &_ep;
+ Genode::Dataspace_capability _request_ldso_ds()
+ {
+ try {
+ static Genode::Rom_connection rom("ld.lib.so");
+ return rom.dataspace();
+ } catch (...) { }
+ return Genode::Dataspace_capability();
+ }
+
+ Genode::Dataspace_capability _ldso_ds = _request_ldso_ds();
+
Genode::Cap_connection _cap;
char const *_report_rom_config =
@@ -65,9 +76,11 @@ struct Launcher::Main
Genode::Signal_rpc_member _exited_child_dispatcher =
{ _ep, *this, &Main::_handle_exited_child };
- Subsystem_manager _subsystem_manager { _ep, _cap, _exited_child_dispatcher };
+ Subsystem_manager _subsystem_manager { _ep, _cap, _exited_child_dispatcher,
+ _ldso_ds };
- Panel_dialog _panel_dialog { _ep, _cap, *env()->ram_session(), *env()->heap(),
+ Panel_dialog _panel_dialog { _ep, _cap, *env()->ram_session(), _ldso_ds,
+ *env()->heap(),
_report_rom_slave, _subsystem_manager, _nitpicker };
void _handle_config(unsigned);
@@ -184,12 +197,6 @@ namespace Server {
void construct(Entrypoint &ep)
{
- /* look for dynamic linker */
- try {
- static Rom_connection rom("ld.lib.so");
- Process::dynamic_linker(rom.dataspace());
- } catch (...) { }
-
static Launcher::Main desktop(ep);
}
}
diff --git a/repos/gems/src/app/launcher/menu_dialog.h b/repos/gems/src/app/launcher/menu_dialog.h
index 7ee1dfac0..b611ebd84 100644
--- a/repos/gems/src/app/launcher/menu_dialog.h
+++ b/repos/gems/src/app/launcher/menu_dialog.h
@@ -104,11 +104,13 @@ class Launcher::Menu_dialog : Input_event_handler, Dialog_generator,
public:
Menu_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
+ Dataspace_capability ldso_ds,
Report_rom_slave &report_rom_slave,
Response_handler &response_handler)
:
_response_handler(response_handler),
- _dialog(ep, cap, ram, report_rom_slave, "menu_dialog", "menu_hover",
+ _dialog(ep, cap, ram, ldso_ds, report_rom_slave,
+ "menu_dialog", "menu_hover",
*this, *this, *this, *this,
_position)
{
diff --git a/repos/gems/src/app/launcher/menu_view_slave.h b/repos/gems/src/app/launcher/menu_view_slave.h
index cae8ba9b6..04e4e9394 100644
--- a/repos/gems/src/app/launcher/menu_view_slave.h
+++ b/repos/gems/src/app/launcher/menu_view_slave.h
@@ -144,6 +144,7 @@ class Launcher::Menu_view_slave
* dataspace
*/
Menu_view_slave(Genode::Cap_session &cap, Genode::Ram_session &ram,
+ Genode::Dataspace_capability ldso_ds,
Capability nitpicker_session,
Capability dialog_rom_session,
Capability hover_report_session,
@@ -152,7 +153,7 @@ class Launcher::Menu_view_slave
_ep(&cap, _ep_stack_size, "nit_fader"),
_policy(_ep, ram, nitpicker_session, dialog_rom_session,
hover_report_session, initial_position),
- _slave(_ep, _policy, _quota)
+ _slave(_ep, _policy, _quota, env()->ram_session_cap(), ldso_ds)
{ }
void position(Position position) { _policy.position(position); }
diff --git a/repos/gems/src/app/launcher/nit_fader_slave.h b/repos/gems/src/app/launcher/nit_fader_slave.h
index 6d0f1b4e9..61ae260a4 100644
--- a/repos/gems/src/app/launcher/nit_fader_slave.h
+++ b/repos/gems/src/app/launcher/nit_fader_slave.h
@@ -113,10 +113,11 @@ class Launcher::Nit_fader_slave
* dataspace
*/
Nit_fader_slave(Rpc_entrypoint &ep, Ram_session &ram,
- Genode::Service &nitpicker_service)
+ Genode::Service &nitpicker_service,
+ Genode::Dataspace_capability ldso_ds)
:
_policy(ep, ram, nitpicker_service),
- _slave(ep, _policy, _quota),
+ _slave(ep, _policy, _quota, env()->ram_session_cap(), ldso_ds),
_nitpicker_root(_policy.nitpicker_root())
{
visible(false);
diff --git a/repos/gems/src/app/launcher/panel_dialog.h b/repos/gems/src/app/launcher/panel_dialog.h
index 777fa73fb..596bfc159 100644
--- a/repos/gems/src/app/launcher/panel_dialog.h
+++ b/repos/gems/src/app/launcher/panel_dialog.h
@@ -251,6 +251,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
public:
Panel_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
+ Dataspace_capability ldso_ds,
Genode::Allocator &alloc,
Report_rom_slave &report_rom_slave,
Subsystem_manager &subsystem_manager,
@@ -259,12 +260,13 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
_alloc(alloc),
_subsystem_manager(subsystem_manager),
_nitpicker(nitpicker),
- _dialog(ep, cap, ram, report_rom_slave, "panel_dialog", "panel_hover",
+ _dialog(ep, cap, ram, ldso_ds, report_rom_slave,
+ "panel_dialog", "panel_hover",
*this, *this, *this, *this,
_position),
_timer_dispatcher(ep, *this, &Panel_dialog::_handle_timer),
- _context_dialog(ep, cap, ram, report_rom_slave, *this),
- _menu_dialog(ep, cap, ram, report_rom_slave, *this)
+ _context_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this),
+ _menu_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this)
{
_elements.insert(&_menu_button);
_timer.sigh(_timer_dispatcher);
diff --git a/repos/gems/src/app/launcher/subsystem_manager.h b/repos/gems/src/app/launcher/subsystem_manager.h
index 586acd714..6dc0d90b1 100644
--- a/repos/gems/src/app/launcher/subsystem_manager.h
+++ b/repos/gems/src/app/launcher/subsystem_manager.h
@@ -27,6 +27,7 @@ namespace Launcher {
using Decorator::string_attribute;
}
+
/***************
** Utilities **
***************/
@@ -60,8 +61,9 @@ class Launcher::Subsystem_manager
private:
- Server::Entrypoint &_ep;
- Cap_session &_cap;
+ Server::Entrypoint &_ep;
+ Cap_session &_cap;
+ Dataspace_capability _ldso_ds;
struct Child : Child_base, List::Element
{
@@ -74,7 +76,8 @@ class Launcher::Subsystem_manager
size_t ram_quota,
size_t ram_limit,
Signal_context_capability yield_response_sig_cap,
- Signal_context_capability exit_sig_cap)
+ Signal_context_capability exit_sig_cap,
+ Dataspace_capability ldso_ds)
:
Child_base(ram,
label.string(),
@@ -83,7 +86,8 @@ class Launcher::Subsystem_manager
ram_quota,
ram_limit,
yield_response_sig_cap,
- exit_sig_cap)
+ exit_sig_cap,
+ ldso_ds)
{ }
};
@@ -184,9 +188,11 @@ class Launcher::Subsystem_manager
public:
Subsystem_manager(Server::Entrypoint &ep, Cap_session &cap,
- Genode::Signal_context_capability exited_child_sig_cap)
+ Genode::Signal_context_capability exited_child_sig_cap,
+ Dataspace_capability ldso_ds)
:
- _ep(ep), _cap(cap), _exited_child_sig_cap(exited_child_sig_cap)
+ _ep(ep), _cap(cap), _ldso_ds(ldso_ds),
+ _exited_child_sig_cap(exited_child_sig_cap)
{ }
/**
@@ -210,7 +216,7 @@ class Launcher::Subsystem_manager
Child(_ram, label, binary_name.string(), _cap,
ram_config.quantum, ram_config.limit,
_yield_broadcast_dispatcher,
- _exited_child_sig_cap);
+ _exited_child_sig_cap, _ldso_ds);
/* configure child */
try {
diff --git a/repos/libports/src/app/qt5/qt_avplay/main.cpp b/repos/libports/src/app/qt5/qt_avplay/main.cpp
index de37c2a27..997b333af 100644
--- a/repos/libports/src/app/qt5/qt_avplay/main.cpp
+++ b/repos/libports/src/app/qt5/qt_avplay/main.cpp
@@ -19,7 +19,6 @@
/* Genode includes */
#include
-#include
#include
@@ -42,14 +41,6 @@ int main(int argc, char *argv[])
load_stylesheet();
- /* look for dynamic linker */
- try {
- static Genode::Rom_connection ldso_rom("ld.lib.so");
- Genode::Process::dynamic_linker(ldso_rom.dataspace());
- } catch (...) {
- PERR("ld.lib.so not found");
- }
-
QMember main_window;
main_window->show();
diff --git a/repos/libports/src/app/qt5/qt_launchpad/main.cpp b/repos/libports/src/app/qt5/qt_launchpad/main.cpp
index 2462a2248..e1b204a61 100644
--- a/repos/libports/src/app/qt5/qt_launchpad/main.cpp
+++ b/repos/libports/src/app/qt5/qt_launchpad/main.cpp
@@ -17,14 +17,6 @@
int main(int argc, char *argv[])
{
- /* look for dynamic linker */
- try {
- static Genode::Rom_connection rom("ld.lib.so");
- Genode::Process::dynamic_linker(rom.dataspace());
- } catch (...) { }
-
- int result;
-
static QApplication a(argc, argv);
static Qt_launchpad launchpad(Genode::env()->ram_session()->quota());
@@ -38,7 +30,7 @@ int main(int argc, char *argv[])
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
- result = a.exec();
+ int const result = a.exec();
return result;
}
diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h
index 8cd5944a0..5f3704004 100644
--- a/repos/os/include/cli_monitor/child.h
+++ b/repos/os/include/cli_monitor/child.h
@@ -108,7 +108,8 @@ class Child_base : public Genode::Child_policy
Genode::size_t ram_quota,
Genode::size_t ram_limit,
Genode::Signal_context_capability yield_response_sig_cap,
- Genode::Signal_context_capability exit_sig_cap)
+ Genode::Signal_context_capability exit_sig_cap,
+ Genode::Dataspace_capability ldso_ds)
:
_ram(ram),
_label(label),
@@ -120,9 +121,10 @@ class Child_base : public Genode::Child_policy
_labeling_policy(_label.string()),
_binary_policy("binary", _binary_rom.dataspace(), &_entrypoint),
_config_policy("config", _entrypoint, &_resources.ram),
- _child(_binary_rom.dataspace(), _resources.pd.cap(),
- _resources.ram.cap(), _resources.cpu.cap(), _address_space,
- &_entrypoint, this),
+ _child(_binary_rom.dataspace(), ldso_ds, _resources.pd, _resources.pd,
+ _resources.ram, _resources.ram, _resources.cpu, _resources.cpu,
+ *Genode::env()->rm_session(), _address_space,
+ _entrypoint, *this),
_yield_response_sigh_cap(yield_response_sig_cap),
_exit_sig_cap(exit_sig_cap)
{ }
diff --git a/repos/os/include/init/child.h b/repos/os/include/init/child.h
index 125b5bbb4..5c8fb9144 100644
--- a/repos/os/include/init/child.h
+++ b/repos/os/include/init/child.h
@@ -370,7 +370,7 @@ class Init::Child : Genode::Child_policy
Genode::Xml_node _default_route_node;
- Name_registry *_name_registry;
+ Name_registry &_name_registry;
/**
* Unique child name and file name of ELF binary
@@ -389,7 +389,7 @@ class Init::Child : Genode::Child_policy
* \param start_node XML start node
* \param registry registry tracking unique names
*/
- Name(Genode::Xml_node start_node, Name_registry const *registry) {
+ Name(Genode::Xml_node start_node, Name_registry const ®istry) {
try {
start_node.attribute("name").value(unique, sizeof(unique)); }
catch (Genode::Xml_node::Nonexistent_attribute) {
@@ -397,7 +397,7 @@ class Init::Child : Genode::Child_policy
throw; }
/* check for a name confict with the other children */
- if (!registry->is_unique(unique)) {
+ if (!registry.is_unique(unique)) {
PERR("Child name \"%s\" is not unique", unique);
throw Child_name_is_not_unique();
}
@@ -527,8 +527,8 @@ class Init::Child : Genode::Child_policy
Genode::Region_map_client _address_space { _resources.pd.address_space() };
Genode::Child _child;
- Genode::Service_registry *_parent_services;
- Genode::Service_registry *_child_services;
+ Genode::Service_registry &_parent_services;
+ Genode::Service_registry &_child_services;
/**
* Policy helpers
@@ -542,14 +542,15 @@ class Init::Child : Genode::Child_policy
public:
- Child(Genode::Xml_node start_node,
- Genode::Xml_node default_route_node,
- Name_registry *name_registry,
- long prio_levels,
+ Child(Genode::Xml_node start_node,
+ Genode::Xml_node default_route_node,
+ Name_registry &name_registry,
+ long prio_levels,
Genode::Affinity::Space const &affinity_space,
- Genode::Service_registry *parent_services,
- Genode::Service_registry *child_services,
- Genode::Cap_session *cap_session)
+ Genode::Service_registry &parent_services,
+ Genode::Service_registry &child_services,
+ Genode::Cap_session &cap_session,
+ Genode::Dataspace_capability ldso_ds)
:
_list_element(this),
_start_node(start_node),
@@ -558,13 +559,16 @@ class Init::Child : Genode::Child_policy
_name(start_node, name_registry),
_resources(start_node, _name.unique, prio_levels,
affinity_space),
- _entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, _name.unique, false, _resources.affinity.location()),
+ _entrypoint(&cap_session, ENTRYPOINT_STACK_SIZE, _name.unique, false, _resources.affinity.location()),
_binary_rom(_name.file, _name.file),
_binary_rom_ds(_binary_rom.dataspace()),
_config(_resources.ram.cap(), start_node),
_server(_resources.ram.cap()),
- _child(_binary_rom_ds, _resources.pd.cap(), _resources.ram.cap(),
- _resources.cpu.cap(), _address_space, &_entrypoint, this),
+ _child(_binary_rom_ds, ldso_ds,
+ _resources.pd, _resources.pd,
+ _resources.ram, _resources.ram,
+ _resources.cpu, _resources.cpu,
+ *Genode::env()->rm_session(), _address_space, _entrypoint, *this),
_parent_services(parent_services),
_child_services(child_services),
_labeling_policy(_name.unique),
@@ -600,7 +604,7 @@ class Init::Child : Genode::Child_policy
if (config_verbose)
Genode::printf(" provides service %s\n", name);
- child_services->insert(new (_child.heap())
+ child_services.insert(new (_child.heap())
Routed_service(name, &_server));
}
@@ -609,8 +613,8 @@ class Init::Child : Genode::Child_policy
virtual ~Child() {
Genode::Service *s;
- while ((s = _child_services->find_by_server(&_server))) {
- _child_services->remove(s);
+ while ((s = _child_services.find_by_server(&_server))) {
+ _child_services.remove(s);
}
}
@@ -667,7 +671,7 @@ class Init::Child : Genode::Child_policy
for (; ; target = target.next()) {
if (target.has_type("parent")) {
- service = _parent_services->find(service_name);
+ service = _parent_services.find(service_name);
if (service)
return service;
@@ -682,13 +686,13 @@ class Init::Child : Genode::Child_policy
server_name[0] = 0;
target.attribute("name").value(server_name, sizeof(server_name));
- Genode::Server *server = _name_registry->lookup_server(server_name);
+ Genode::Server *server = _name_registry.lookup_server(server_name);
if (!server) {
PWRN("%s: invalid route to non-existing server \"%s\"", name(), server_name);
return 0;
}
- service = _child_services->find(service_name, server);
+ service = _child_services.find(service_name, server);
if (service)
return service;
@@ -699,11 +703,11 @@ class Init::Child : Genode::Child_policy
}
if (target.has_type("any-child")) {
- if (_child_services->is_ambiguous(service_name)) {
+ if (_child_services.is_ambiguous(service_name)) {
PERR("%s: ambiguous routes to service \"%s\"", name(), service_name);
return 0;
}
- service = _child_services->find(service_name);
+ service = _child_services.find(service_name);
if (service)
return service;
@@ -767,7 +771,7 @@ class Init::Child : Genode::Child_policy
Genode::printf("child \"%s\" announces service \"%s\"\n",
name(), service_name);
- Genode::Service *s = _child_services->find(service_name, &_server);
+ Genode::Service *s = _child_services.find(service_name, &_server);
Routed_service *rs = dynamic_cast(s);
if (!s || !rs) {
PERR("%s: illegal announcement of service \"%s\"", name(), service_name);
diff --git a/repos/os/include/os/slave.h b/repos/os/include/os/slave.h
index 04b840721..ef1fbdd27 100644
--- a/repos/os/include/os/slave.h
+++ b/repos/os/include/os/slave.h
@@ -187,12 +187,13 @@ class Genode::Slave
Slave(Genode::Rpc_entrypoint &entrypoint,
Slave_policy &slave_policy,
Genode::size_t ram_quota,
- Ram_session_capability ram_ref_cap = env()->ram_session_cap())
+ Ram_session_capability ram_ref_cap = env()->ram_session_cap(),
+ Dataspace_capability ldso_ds = Dataspace_capability())
:
_resources(slave_policy.name(), ram_quota, ram_ref_cap),
- _child(slave_policy.binary(), _resources.pd.cap(),
- _resources.ram.cap(), _resources.cpu.cap(),
- _address_space, &entrypoint, &slave_policy)
+ _child(slave_policy.binary(), ldso_ds, _resources.pd, _resources.pd,
+ _resources.ram, _resources.ram, _resources.cpu, _resources.cpu,
+ *env()->rm_session(), _address_space, entrypoint, slave_policy)
{ }
Genode::Ram_connection &ram() { return _resources.ram; }
diff --git a/repos/os/src/app/cli_monitor/child.h b/repos/os/src/app/cli_monitor/child.h
index cd66d2a58..947003bbe 100644
--- a/repos/os/src/app/cli_monitor/child.h
+++ b/repos/os/src/app/cli_monitor/child.h
@@ -31,7 +31,8 @@ struct Child : Child_base, List::Element
Genode::size_t ram_quota,
Genode::size_t ram_limit,
Genode::Signal_context_capability yield_response_sig_cap,
- Genode::Signal_context_capability exit_sig_cap)
+ Genode::Signal_context_capability exit_sig_cap,
+ Genode::Dataspace_capability ldso_ds)
:
Child_base(ram,
label,
@@ -40,7 +41,8 @@ struct Child : Child_base, List::Element
ram_quota,
ram_limit,
yield_response_sig_cap,
- exit_sig_cap),
+ exit_sig_cap,
+ ldso_ds),
argument(label, "subsystem")
{ }
};
diff --git a/repos/os/src/app/cli_monitor/main.cc b/repos/os/src/app/cli_monitor/main.cc
index 77c6b80aa..5918e828b 100644
--- a/repos/os/src/app/cli_monitor/main.cc
+++ b/repos/os/src/app/cli_monitor/main.cc
@@ -98,9 +98,10 @@ static Subsystem_config_registry &subsystem_config_registry()
int main(int argc, char **argv)
{
/* look for dynamic linker */
+ Genode::Dataspace_capability ldso_ds;
try {
static Genode::Rom_connection rom("ld.lib.so");
- Genode::Process::dynamic_linker(rom.dataspace());
+ ldso_ds = rom.dataspace();
} catch (...) { }
using Genode::Signal_context;
@@ -141,7 +142,8 @@ int main(int argc, char **argv)
commands.insert(new Start_command(ram, cap, children,
subsystem_config_registry(),
yield_response_sig_cap,
- exited_child_sig_cap));
+ exited_child_sig_cap,
+ ldso_ds));
commands.insert(new Status_command(ram, children));
commands.insert(new Yield_command(children));
commands.insert(new Ram_command(children));
diff --git a/repos/os/src/app/cli_monitor/start_command.h b/repos/os/src/app/cli_monitor/start_command.h
index 21ce27b0b..4c1c8b5ac 100644
--- a/repos/os/src/app/cli_monitor/start_command.h
+++ b/repos/os/src/app/cli_monitor/start_command.h
@@ -26,6 +26,7 @@ class Start_command : public Command
typedef Genode::Xml_node Xml_node;
typedef Genode::Signal_context_capability Signal_context_capability;
+ typedef Genode::Dataspace_capability Dataspace_capability;
Ram &_ram;
Child_registry &_children;
@@ -34,6 +35,7 @@ class Start_command : public Command
List _arguments;
Signal_context_capability _yield_response_sigh_cap;
Signal_context_capability _exit_sig_cap;
+ Dataspace_capability _ldso_ds;
void _execute_subsystem(char const *name, Command_line &cmd,
Terminal::Session &terminal,
@@ -106,7 +108,7 @@ class Start_command : public Command
try {
child = new (Genode::env()->heap())
Child(_ram, label, binary_name, _cap, ram, ram_limit,
- _yield_response_sigh_cap, _exit_sig_cap);
+ _yield_response_sigh_cap, _exit_sig_cap, _ldso_ds);
}
catch (Genode::Rom_connection::Rom_connection_failed) {
tprintf(terminal, "Error: could not obtain ROM module \"%s\"\n",
@@ -147,13 +149,15 @@ class Start_command : public Command
Start_command(Ram &ram, Genode::Cap_session &cap, Child_registry &children,
Subsystem_config_registry &subsustem_configs,
Signal_context_capability yield_response_sigh_cap,
- Signal_context_capability exit_sig_cap)
+ Signal_context_capability exit_sig_cap,
+ Dataspace_capability ldso_ds)
:
Command("start", "create new subsystem"),
_ram(ram), _children(children), _cap(cap),
_subsystem_configs(subsustem_configs),
_yield_response_sigh_cap(yield_response_sigh_cap),
- _exit_sig_cap(exit_sig_cap)
+ _exit_sig_cap(exit_sig_cap),
+ _ldso_ds(ldso_ds)
{
add_parameter(new Parameter("--count", Parameter::NUMBER, "number of instances"));
add_parameter(new Parameter("--ram", Parameter::NUMBER, "initial RAM quota"));
diff --git a/repos/os/src/init/main.cc b/repos/os/src/init/main.cc
index dece85aa8..e84c0330f 100644
--- a/repos/os/src/init/main.cc
+++ b/repos/os/src/init/main.cc
@@ -286,10 +286,11 @@ int main(int, char **)
using namespace Init;
using namespace Genode;
- /* look for dynamic linker */
+ /* obtain dynamic linker */
+ Dataspace_capability ldso_ds;
try {
static Rom_connection rom("ld.lib.so");
- Process::dynamic_linker(rom.dataspace());
+ ldso_ds = rom.dataspace();
} catch (...) { }
static Service_registry parent_services;
@@ -344,9 +345,10 @@ int main(int, char **)
try {
children.insert(new (env()->heap())
Init::Child(start_node, default_route_node,
- &children, read_prio_levels(),
+ children, read_prio_levels(),
read_affinity_space(),
- &parent_services, &child_services, &cap));
+ parent_services, child_services, cap,
+ ldso_ds));
}
catch (Rom_connection::Rom_connection_failed) {
/*
diff --git a/repos/os/src/server/loader/child.h b/repos/os/src/server/loader/child.h
index 5f61f34f9..a5650d52d 100644
--- a/repos/os/src/server/loader/child.h
+++ b/repos/os/src/server/loader/child.h
@@ -104,6 +104,7 @@ namespace Loader {
Child(char const *binary_name,
char const *label,
+ Dataspace_capability ldso_ds,
Rpc_entrypoint &ep,
Ram_session_client &ram_session_client,
size_t ram_quota,
@@ -125,9 +126,11 @@ namespace Loader {
_binary_rom_session(_rom_session(binary_name)),
_binary_policy("binary", _binary_rom_session.dataspace(), &_ep),
_labeling_policy(_label.string),
- _child(_binary_rom_session.dataspace(), _resources.pd.cap(),
- _resources.ram.cap(), _resources.cpu.cap(),
- _address_space, &_ep, this)
+ _child(_binary_rom_session.dataspace(), ldso_ds,
+ _resources.pd, _resources.pd,
+ _resources.ram, _resources.ram,
+ _resources.cpu, _resources.cpu,
+ *env()->rm_session(), _address_space, _ep, *this)
{ }
~Child()
diff --git a/repos/os/src/server/loader/main.cc b/repos/os/src/server/loader/main.cc
index 172d4b35e..3d43ee60e 100644
--- a/repos/os/src/server/loader/main.cc
+++ b/repos/os/src/server/loader/main.cc
@@ -256,6 +256,7 @@ class Loader::Session_component : public Rpc_object
Heap _md_alloc;
size_t _subsystem_ram_quota_limit;
Rpc_entrypoint _ep;
+ Dataspace_capability _ldso_ds;
Service_registry _parent_services;
Rom_module_registry _rom_modules;
Local_rom_service _rom_service;
@@ -281,13 +282,15 @@ class Loader::Session_component : public Rpc_object
/**
* Constructor
*/
- Session_component(size_t quota, Ram_session &ram, Cap_session &cap)
+ Session_component(size_t quota, Ram_session &ram, Cap_session &cap,
+ Dataspace_capability ldso_ds)
:
_ram_quota(quota),
_ram_session_client(env()->ram_session_cap(), _ram_quota),
_md_alloc(&_ram_session_client, env()->rm_session()),
_subsystem_ram_quota_limit(0),
_ep(&cap, STACK_SIZE, "session_ep"),
+ _ldso_ds(ldso_ds),
_rom_modules(_ram_session_client, _md_alloc),
_rom_service(_ep, _md_alloc, _rom_modules),
_nitpicker_service(_ep, _ram_session_client, _md_alloc),
@@ -380,7 +383,7 @@ class Loader::Session_component : public Rpc_object
try {
_child = new (&_md_alloc)
- Child(binary_name.string(), label.string(),
+ Child(binary_name.string(), label.string(), _ldso_ds,
_ep, _ram_session_client,
ram_quota, _parent_services, _rom_service,
_cpu_service, _pd_service, _nitpicker_service,
@@ -406,8 +409,9 @@ class Loader::Root : public Root_component
{
private:
- Ram_session &_ram;
- Cap_session &_cap;
+ Ram_session &_ram;
+ Cap_session &_cap;
+ Dataspace_capability _ldso_ds;
protected:
@@ -416,7 +420,7 @@ class Loader::Root : public Root_component
size_t quota =
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
- return new (md_alloc()) Session_component(quota, _ram, _cap);
+ return new (md_alloc()) Session_component(quota, _ram, _cap, _ldso_ds);
}
public:
@@ -429,14 +433,24 @@ class Loader::Root : public Root_component
* component
*/
Root(Rpc_entrypoint &session_ep, Allocator &md_alloc,
- Ram_session &ram, Cap_session &cap)
+ Ram_session &ram, Cap_session &cap, Dataspace_capability ldso_ds)
:
Root_component(&session_ep, &md_alloc),
- _ram(ram), _cap(cap)
+ _ram(ram), _cap(cap), _ldso_ds(ldso_ds)
{ }
};
+Genode::Dataspace_capability request_ldso_ds()
+{
+ try {
+ static Genode::Rom_connection rom("ld.lib.so");
+ return rom.dataspace();
+ } catch (...) { }
+ return Genode::Dataspace_capability();
+}
+
+
int main()
{
using namespace Genode;
@@ -445,7 +459,8 @@ int main()
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "loader_ep");
- static Loader::Root root(ep, *env()->heap(), *env()->ram_session(), cap);
+ static Loader::Root root(ep, *env()->heap(), *env()->ram_session(), cap,
+ request_ldso_ds());
env()->parent()->announce(ep.manage(&root));
diff --git a/repos/os/src/test/bomb/main.cc b/repos/os/src/test/bomb/main.cc
index 8ab73ce56..fa77a6b71 100644
--- a/repos/os/src/test/bomb/main.cc
+++ b/repos/os/src/test/bomb/main.cc
@@ -92,8 +92,9 @@ class Bomb_child : private Bomb_child_resources,
Bomb_child_resources(file_name, unique_name, ram_quota),
Init::Child_policy_enforce_labeling(Bomb_child_resources::_name),
_entrypoint(cap_session, STACK_SIZE, "bomb_ep_child", false),
- _child(_rom.dataspace(), _pd.cap(), _ram.cap(), _cpu.cap(),
- _address_space, &_entrypoint, this),
+ _child(_rom.dataspace(), Genode::Dataspace_capability(),
+ _pd, _pd, _ram, _ram, _cpu, _cpu,
+ *Genode::env()->rm_session(), _address_space, _entrypoint, *this),
_parent_services(parent_services),
_config_policy("config", _entrypoint, &_ram)
{
diff --git a/repos/os/src/test/fault_detection/main.cc b/repos/os/src/test/fault_detection/main.cc
index 532c94ddf..28bbb4e6d 100644
--- a/repos/os/src/test/fault_detection/main.cc
+++ b/repos/os/src/test/fault_detection/main.cc
@@ -101,8 +101,11 @@ class Test_child : public Genode::Child_policy
_resources(sigh, elf_name),
_elf(elf_name),
_log_service("LOG"), _rm_service("RM"),
- _child(_elf.dataspace(), _resources.pd.cap(), _resources.ram.cap(),
- _resources.cpu.cap(), _address_space, &ep, this)
+ _child(_elf.dataspace(), Genode::Dataspace_capability(),
+ _resources.pd, _resources.pd,
+ _resources.ram, _resources.ram,
+ _resources.cpu, _resources.cpu,
+ *Genode::env()->rm_session(), _address_space, ep, *this)
{ }
diff --git a/repos/os/src/test/vfs_stress/main.cc b/repos/os/src/test/vfs_stress/main.cc
index dc00ff50c..1f052949a 100644
--- a/repos/os/src/test/vfs_stress/main.cc
+++ b/repos/os/src/test/vfs_stress/main.cc
@@ -36,7 +36,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -476,12 +475,6 @@ struct Unlink_thread : public Stress_thread
int main()
{
- /* look for dynamic linker */
- try {
- static Genode::Rom_connection rom("ld.lib.so");
- Genode::Process::dynamic_linker(rom.dataspace());
- } catch (...) { }
-
static Vfs::Dir_file_system vfs_root(config()->xml_node().sub_node("vfs"),
Vfs::global_file_system_factory());
static char path[Vfs::MAX_PATH_LEN];
diff --git a/repos/ports/src/app/gdb_monitor/app_child.h b/repos/ports/src/app/gdb_monitor/app_child.h
index e5dca66e0..9a2892f6f 100644
--- a/repos/ports/src/app/gdb_monitor/app_child.h
+++ b/repos/ports/src/app/gdb_monitor/app_child.h
@@ -40,7 +40,7 @@ namespace Gdb_monitor {
enum { STACK_SIZE = 4*1024*sizeof(long) };
- const char *_unique_name;
+ const char *_unique_name;
Rpc_entrypoint _entrypoint;
@@ -56,9 +56,9 @@ namespace Gdb_monitor {
Dataspace_pool _managed_ds_map;
Cpu_root _cpu_root;
- Cpu_session_capability _cpu_session_cap;
+ Cpu_session_client _cpu_session;
- Ram_session_capability _ram_session_cap;
+ Ram_session_client _ram_session;
Pd_session_component _pd { _unique_name, _entrypoint,
_managed_ds_map };
@@ -227,6 +227,7 @@ namespace Gdb_monitor {
*/
App_child(const char *unique_name,
Genode::Dataspace_capability elf_ds,
+ Genode::Dataspace_capability ldso_ds,
Genode::Ram_session_capability ram_session,
Genode::Cap_session *cap_session,
Service_registry *parent_services,
@@ -241,10 +242,11 @@ namespace Gdb_monitor {
_config_policy("config", _child_config.dataspace(), &_entrypoint),
_gdb_stub_thread(),
_cpu_root(&_entrypoint, env()->heap() /* should be _child.heap() */, &_gdb_stub_thread),
- _cpu_session_cap(_get_cpu_session_cap()),
- _ram_session_cap(ram_session),
- _child(elf_ds, _pd.cap(), ram_session, _cpu_session_cap,
- _address_space, &_entrypoint, this),
+ _cpu_session(_get_cpu_session_cap()),
+ _ram_session(ram_session),
+ _child(elf_ds, ldso_ds, _pd.cap(), _pd,
+ _ram_session, _ram_session, _cpu_session, _cpu_session,
+ *Genode::env()->rm_session(), _address_space, _entrypoint, *this),
_root_ep(root_ep),
_rom_service(&_entrypoint, _child.heap())
{
@@ -301,7 +303,7 @@ namespace Gdb_monitor {
{
/* create and announce proxy for the child's root interface */
Child_service_root *r = new (alloc)
- Child_service_root(_ram_session_cap, root);
+ Child_service_root(_ram_session, root);
Genode::env()->parent()->announce(name, _root_ep->manage(r));
return true;
diff --git a/repos/ports/src/app/gdb_monitor/main.cc b/repos/ports/src/app/gdb_monitor/main.cc
index 489abff18..156b5ad19 100644
--- a/repos/ports/src/app/gdb_monitor/main.cc
+++ b/repos/ports/src/app/gdb_monitor/main.cc
@@ -41,9 +41,10 @@ extern "C" int _sigprocmask() { return -1; }
int main()
{
/* look for dynamic linker */
+ Dataspace_capability ldso_ds;
try {
Rom_connection ldso_rom("ld.lib.so");
- Process::dynamic_linker(clone_rom(ldso_rom.dataspace()));
+ ldso_ds = clone_rom(ldso_rom.dataspace());
} catch (...) {
PDBG("ld.lib.so not found");
}
@@ -114,6 +115,7 @@ int main()
new (env()->heap()) App_child(unique_name,
elf_cap,
+ ldso_ds,
ram.cap(),
&cap_session,
&parent_services,
diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h
index ccc7ccd2c..766dc8b78 100644
--- a/repos/ports/src/noux/child.h
+++ b/repos/ports/src/noux/child.h
@@ -142,7 +142,6 @@ namespace Noux {
*/
Rpc_entrypoint &ep;
-
/**
* Locally-provided services for accessing platform resources
*/
@@ -227,6 +226,8 @@ namespace Noux {
Static_dataspace_info _args_ds_info;
Static_dataspace_info _env_ds_info;
+ Dataspace_capability _ldso_ds;
+
Child_policy _child_policy;
Genode::Child _child;
@@ -328,6 +329,7 @@ namespace Noux {
* the parent
*/
Child(char const *binary_name,
+ Dataspace_capability ldso_ds,
Parent_exit *parent_exit,
Kill_broadcaster &kill_broadcaster,
Parent_execve &parent_execve,
@@ -374,16 +376,19 @@ namespace Noux {
_ldso_ds_info(_ds_registry, ldso_ds_cap()),
_args_ds_info(_ds_registry, _args.cap()),
_env_ds_info(_ds_registry, _env.cap()),
+ _ldso_ds(ldso_ds),
_child_policy(_elf._name, _elf._binary_ds, _args.cap(), _env.cap(),
_entrypoint, _local_noux_service,
_local_rom_service, _parent_services,
*this, parent_exit, *this, _destruct_context_cap,
_resources.ram, verbose),
_child(forked ? Dataspace_capability() : _elf._binary_ds,
- _pd.core_pd_cap(), _resources.ram.cap(), _resources.cpu.cap(),
- _address_space,
- &_entrypoint, &_child_policy, _parent_pd_service,
- _parent_ram_service, _local_cpu_service, _pd.cap())
+ _ldso_ds, _pd.cap(), _pd,
+ _resources.ram.cap(), _resources.ram,
+ _resources.cpu.cap(), _resources.cpu,
+ *Genode::env()->rm_session(), _address_space,
+ _entrypoint, _child_policy, _parent_pd_service,
+ _parent_ram_service, _local_cpu_service)
{
if (verbose)
_args.dump();
@@ -542,6 +547,7 @@ namespace Noux {
Lock::Guard signal_lock_guard(signal_lock());
Child *child = new Child(filename,
+ _ldso_ds,
_parent_exit,
_kill_broadcaster,
_parent_execve,
diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc
index c6756bbce..89af7e6c2 100644
--- a/repos/ports/src/noux/main.cc
+++ b/repos/ports/src/noux/main.cc
@@ -599,6 +599,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
* reusing the name of the parent.
*/
child = new Child(_child_policy.name(),
+ _ldso_ds,
this,
_kill_broadcaster,
*this,
@@ -1134,9 +1135,6 @@ int main(int argc, char **argv)
using namespace Noux;
PINF("--- noux started ---");
- /* register dynamic linker */
- Genode::Process::dynamic_linker(ldso_ds_cap());
-
/* whitelist of service requests to be routed to the parent */
static Genode::Service_registry parent_services;
char const *service_names[] = { "LOG", "ROM", "Timer", 0 };
@@ -1198,6 +1196,7 @@ int main(int argc, char **argv)
static Kill_broadcaster_implementation kill_broadcaster;
init_child = new Noux::Child(name_of_init_process(),
+ ldso_ds_cap(),
0,
kill_broadcaster,
*init_child,