Remove Genode::Process from API

This patch makes the former 'Process' class private to the 'Child'
class and changes the constructor of the 'Child' in a way that
principally enables the implementation of single-threaded runtime
environments that virtualize the CPU, PD, and RAM services. The
new interfaces has become free from side effects. I.e., instead
of implicitly using Genode::env()->rm_session(), it takes the reference
to the local region map as argument. Also, the handling of the dynamic
linker via global variables is gone. Now, the linker binary must be
provided as constructor argument.

Fixes #1949
This commit is contained in:
Norman Feske 2016-04-27 16:04:58 +02:00 committed by Christian Helmuth
parent b49e588c1c
commit 7274ca997d
46 changed files with 756 additions and 689 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <base/env.h>
#include <base/child.h>
#include <base/printf.h>
#include <linux_native_pd/client.h>
/* base-internal includes */
#include <linux_syscalls.h>
#include <base/internal/elf.h>
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<Linux_native_pd>(pd.native_pd()));
lx_pd.start(elf_ds);
}
Child::Process::~Process() { }

View File

@ -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 <base/env.h>
#include <base/process.h>
#include <base/printf.h>
#include <linux_native_pd/client.h>
/* base-internal includes */
#include <linux_syscalls.h>
#include <base/internal/elf.h>
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<Linux_native_pd>(_pd_session_client.native_pd()));
_pd_session_client.assign_parent(parent_cap);
lx_pd.start(elf_data_ds_cap);
}
Process::~Process() { }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -16,14 +16,16 @@
#include <base/rpc_server.h>
#include <base/heap.h>
#include <base/process.h>
#include <base/service.h>
#include <base/lock.h>
#include <util/arg_string.h>
#include <parent/parent.h>
#include <ram_session/capability.h>
#include <region_map/client.h>
#include <pd_session/client.h>
#include <cpu_session/client.h>
#include <parent/capability.h>
namespace Genode {
struct Child_policy;
struct Child;
}
@ -157,12 +159,8 @@ class Genode::Child : protected Rpc_object<Parent>
/* 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<Parent>
/* 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<Parent>
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<Parent>
* 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<Parent>
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
*

View File

@ -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 <ram_session/capability.h>
#include <region_map/client.h>
#include <pd_session/client.h>
#include <cpu_session/client.h>
#include <parent/capability.h>
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_ */

View File

@ -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); });
}

View File

@ -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 <base/printf.h>
#include <base/child.h>
/* base-internal includes */
#include <base/internal/elf.h>
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() { }

View File

@ -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 <base/process.h>
#include <base/env.h>
#include <base/printf.h>
#include <ram_session/client.h>
#include <dataspace/client.h>
/* base-internal includes */
#include <base/internal/elf.h>
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) { }
}

View File

@ -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()))

View File

@ -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 */

View File

@ -152,12 +152,9 @@ class Launchpad_child : public Genode::List<Launchpad_child>::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<Launchpad_child>::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<Launchpad_child>::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; }

View File

@ -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());

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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<Main> _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);
}
}

View File

@ -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)
{

View File

@ -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> nitpicker_session,
Capability<Rom_session> dialog_rom_session,
Capability<Report::Session> 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); }

View File

@ -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);

View File

@ -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);

View File

@ -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<Child>::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 {

View File

@ -19,7 +19,6 @@
/* Genode includes */
#include <rom_session/connection.h>
#include <base/process.h>
#include <base/printf.h>
@ -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;
main_window->show();

View File

@ -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;
}

View File

@ -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)
{ }

View File

@ -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 &registry) {
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<Routed_service *>(s);
if (!s || !rs) {
PERR("%s: illegal announcement of service \"%s\"", name(), service_name);

View File

@ -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; }

View File

@ -31,7 +31,8 @@ struct Child : Child_base, List<Child>::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<Child>::Element
ram_quota,
ram_limit,
yield_response_sig_cap,
exit_sig_cap),
exit_sig_cap,
ldso_ds),
argument(label, "subsystem")
{ }
};

View File

@ -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));

View File

@ -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<Argument> _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"));

View File

@ -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) {
/*

View File

@ -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()

View File

@ -256,6 +256,7 @@ class Loader::Session_component : public Rpc_object<Session>
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<Session>
/**
* 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<Session>
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<Session_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<Session_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<Session_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_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));

View File

@ -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)
{

View File

@ -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)
{ }

View File

@ -36,7 +36,6 @@
#include <vfs/file_system_factory.h>
#include <vfs/dir_file_system.h>
#include <timer_session/connection.h>
#include <base/process.h>
#include <os/config.h>
#include <base/printf.h>
#include <base/snprintf.h>
@ -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];

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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,