mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
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:
parent
b49e588c1c
commit
7274ca997d
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
114
repos/base-linux/src/base/child/process.cc
Normal file
114
repos/base-linux/src/base/child/process.cc
Normal 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() { }
|
@ -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() { }
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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_ */
|
@ -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); });
|
||||
}
|
||||
|
213
repos/base/src/base/child/process.cc
Normal file
213
repos/base/src/base/child/process.cc
Normal 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() { }
|
@ -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) { }
|
||||
}
|
@ -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()))
|
||||
|
@ -80,6 +80,9 @@ class Test_child : public Child_policy
|
||||
Rpc_entrypoint _entrypoint;
|
||||
|
||||
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 */
|
||||
|
@ -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
|
||||
@ -169,6 +166,13 @@ class Launchpad_child : public Genode::List<Launchpad_child>::Element
|
||||
|
||||
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; }
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -27,6 +27,7 @@ namespace Launcher {
|
||||
using Decorator::string_attribute;
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
@ -62,6 +63,7 @@ class Launcher::Subsystem_manager
|
||||
|
||||
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 {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{ }
|
||||
|
@ -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
|
||||
@ -544,12 +544,13 @@ class Init::Child : Genode::Child_policy
|
||||
|
||||
Child(Genode::Xml_node start_node,
|
||||
Genode::Xml_node default_route_node,
|
||||
Name_registry *name_registry,
|
||||
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);
|
||||
|
@ -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; }
|
||||
|
@ -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")
|
||||
{ }
|
||||
};
|
||||
|
@ -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));
|
||||
|
@ -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"));
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
@ -408,6 +411,7 @@ class Loader::Root : public Root_component<Session_component>
|
||||
|
||||
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));
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user