mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-21 00:23:16 +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:
committed by
Christian Helmuth
parent
b49e588c1c
commit
7274ca997d
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() { }
|
Reference in New Issue
Block a user