mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-30 08:03:59 +00:00
base: add Child_policy::start_initial_thread
The added interface allows for the local interception of 'Cpu_thread::start' RPC calls. Issue #4917
This commit is contained in:
parent
f2153f9b2f
commit
734fc252e8
@ -43,7 +43,7 @@ Child::Initial_thread::Initial_thread(Cpu_session &cpu,
|
|||||||
Child::Initial_thread::~Initial_thread() { }
|
Child::Initial_thread::~Initial_thread() { }
|
||||||
|
|
||||||
|
|
||||||
void Child::Initial_thread::start(addr_t) { }
|
void Child::Initial_thread::start(addr_t, Start &) { }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -57,13 +57,14 @@ Child::Process::Loaded_executable::Loaded_executable(Type,
|
|||||||
Parent_capability) { }
|
Parent_capability) { }
|
||||||
|
|
||||||
|
|
||||||
Child::Process::Process(Type type,
|
Child::Process::Process(Type type,
|
||||||
Dataspace_capability ldso_ds,
|
Dataspace_capability ldso_ds,
|
||||||
Pd_session &pd,
|
Pd_session &pd,
|
||||||
Initial_thread_base &,
|
Initial_thread_base &,
|
||||||
Region_map &local_rm,
|
Initial_thread::Start &,
|
||||||
Region_map &remote_rm,
|
Region_map &local_rm,
|
||||||
Parent_capability parent_cap)
|
Region_map &remote_rm,
|
||||||
|
Parent_capability parent_cap)
|
||||||
:
|
:
|
||||||
loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
|
loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <cpu_session/connection.h>
|
#include <cpu_session/connection.h>
|
||||||
#include <log_session/connection.h>
|
#include <log_session/connection.h>
|
||||||
#include <rom_session/connection.h>
|
#include <rom_session/connection.h>
|
||||||
|
#include <cpu_thread/client.h>
|
||||||
#include <parent/capability.h>
|
#include <parent/capability.h>
|
||||||
|
|
||||||
namespace Genode {
|
namespace Genode {
|
||||||
@ -226,6 +227,14 @@ struct Genode::Child_policy
|
|||||||
_with_address_space(pd, Impl(fn));
|
_with_address_space(pd, Impl(fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start initial thread of the child at instruction pointer 'ip'
|
||||||
|
*/
|
||||||
|
virtual void start_initial_thread(Capability<Cpu_thread> thread, addr_t ip)
|
||||||
|
{
|
||||||
|
Cpu_thread_client(thread).start(ip, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if ELF loading should be inhibited
|
* Return true if ELF loading should be inhibited
|
||||||
*/
|
*/
|
||||||
@ -263,10 +272,18 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
|
|
||||||
struct Initial_thread_base : Interface
|
struct Initial_thread_base : Interface
|
||||||
{
|
{
|
||||||
|
struct Start : Interface
|
||||||
|
{
|
||||||
|
virtual void start_initial_thread(Capability<Cpu_thread>, addr_t ip) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start execution at specified instruction pointer
|
* Start execution at specified instruction pointer
|
||||||
|
*
|
||||||
|
* The 'Child_policy' allows for the overriding of the default
|
||||||
|
* RPC-based implementation of 'start_initial_thread'.
|
||||||
*/
|
*/
|
||||||
virtual void start(addr_t ip) = 0;
|
virtual void start(addr_t ip, Start &) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return capability of the initial thread
|
* Return capability of the initial thread
|
||||||
@ -283,6 +300,8 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
using Initial_thread_base::Start;
|
||||||
|
|
||||||
typedef Cpu_session::Name Name;
|
typedef Cpu_session::Name Name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,7 +314,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
Initial_thread(Cpu_session &, Pd_session_capability, Name const &);
|
Initial_thread(Cpu_session &, Pd_session_capability, Name const &);
|
||||||
~Initial_thread();
|
~Initial_thread();
|
||||||
|
|
||||||
void start(addr_t) override;
|
void start(addr_t, Start &) override;
|
||||||
|
|
||||||
Capability<Cpu_thread> cap() const override { return _cap; }
|
Capability<Cpu_thread> cap() const override { return _cap; }
|
||||||
};
|
};
|
||||||
@ -348,6 +367,19 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
|
|
||||||
Constructible<Initial_thread> _initial_thread { };
|
Constructible<Initial_thread> _initial_thread { };
|
||||||
|
|
||||||
|
struct Initial_thread_start : Initial_thread::Start
|
||||||
|
{
|
||||||
|
Child_policy &_policy;
|
||||||
|
|
||||||
|
void start_initial_thread(Capability<Cpu_thread> cap, addr_t ip) override
|
||||||
|
{
|
||||||
|
_policy.start_initial_thread(cap, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
Initial_thread_start(Child_policy &policy) : _policy(policy) { }
|
||||||
|
|
||||||
|
} _initial_thread_start { _policy };
|
||||||
|
|
||||||
struct Process
|
struct Process
|
||||||
{
|
{
|
||||||
class Missing_dynamic_linker : Exception { };
|
class Missing_dynamic_linker : Exception { };
|
||||||
@ -405,13 +437,14 @@ class Genode::Child : protected Rpc_object<Parent>,
|
|||||||
* initial thread must be done manually, i.e., as done for
|
* initial thread must be done manually, i.e., as done for
|
||||||
* implementing fork.
|
* implementing fork.
|
||||||
*/
|
*/
|
||||||
Process(Type type,
|
Process(Type type,
|
||||||
Dataspace_capability ldso_ds,
|
Dataspace_capability ldso_ds,
|
||||||
Pd_session &pd,
|
Pd_session &pd,
|
||||||
Initial_thread_base &initial_thread,
|
Initial_thread_base &,
|
||||||
Region_map &local_rm,
|
Initial_thread::Start &,
|
||||||
Region_map &remote_rm,
|
Region_map &local_rm,
|
||||||
Parent_capability parent);
|
Region_map &remote_rm,
|
||||||
|
Parent_capability parent);
|
||||||
|
|
||||||
~Process();
|
~Process();
|
||||||
};
|
};
|
||||||
|
@ -766,7 +766,8 @@ void Child::_try_construct_env_dependent_members()
|
|||||||
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
|
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
|
||||||
_policy.with_address_space(_pd.session(), [&] (Region_map &address_space) {
|
_policy.with_address_space(_pd.session(), [&] (Region_map &address_space) {
|
||||||
_process.construct(type, _linker_dataspace(), _pd.session(),
|
_process.construct(type, _linker_dataspace(), _pd.session(),
|
||||||
*_initial_thread, _local_rm, address_space, cap()); });
|
*_initial_thread, _initial_thread_start,
|
||||||
|
_local_rm, address_space, cap()); });
|
||||||
}
|
}
|
||||||
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
|
catch (Out_of_ram) { _error("out of RAM during ELF loading"); }
|
||||||
catch (Out_of_caps) { _error("out of caps during ELF loading"); }
|
catch (Out_of_caps) { _error("out of caps during ELF loading"); }
|
||||||
|
@ -170,19 +170,20 @@ Child::Initial_thread::~Initial_thread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Child::Initial_thread::start(addr_t ip)
|
void Child::Initial_thread::start(addr_t ip, Start &start)
|
||||||
{
|
{
|
||||||
Cpu_thread_client(_cap).start(ip, 0);
|
start.start_initial_thread(_cap, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Child::Process::Process(Type type,
|
Child::Process::Process(Type type,
|
||||||
Dataspace_capability ldso_ds,
|
Dataspace_capability ldso_ds,
|
||||||
Pd_session &pd,
|
Pd_session &pd,
|
||||||
Initial_thread_base &initial_thread,
|
Initial_thread_base &initial_thread,
|
||||||
Region_map &local_rm,
|
Initial_thread::Start &start,
|
||||||
Region_map &remote_rm,
|
Region_map &local_rm,
|
||||||
Parent_capability parent_cap)
|
Region_map &remote_rm,
|
||||||
|
Parent_capability parent_cap)
|
||||||
:
|
:
|
||||||
loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
|
loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
|
||||||
{
|
{
|
||||||
@ -198,7 +199,7 @@ Child::Process::Process(Type type,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* start main thread */
|
/* start main thread */
|
||||||
initial_thread.start(loaded_executable.entry);
|
initial_thread.start(loaded_executable.entry, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user