mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-29 15:44:02 +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() { }
|
||||
|
||||
|
||||
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) { }
|
||||
|
||||
|
||||
Child::Process::Process(Type type,
|
||||
Dataspace_capability ldso_ds,
|
||||
Pd_session &pd,
|
||||
Initial_thread_base &,
|
||||
Region_map &local_rm,
|
||||
Region_map &remote_rm,
|
||||
Parent_capability parent_cap)
|
||||
Child::Process::Process(Type type,
|
||||
Dataspace_capability ldso_ds,
|
||||
Pd_session &pd,
|
||||
Initial_thread_base &,
|
||||
Initial_thread::Start &,
|
||||
Region_map &local_rm,
|
||||
Region_map &remote_rm,
|
||||
Parent_capability parent_cap)
|
||||
:
|
||||
loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
|
||||
{
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <cpu_session/connection.h>
|
||||
#include <log_session/connection.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <cpu_thread/client.h>
|
||||
#include <parent/capability.h>
|
||||
|
||||
namespace Genode {
|
||||
@ -226,6 +227,14 @@ struct Genode::Child_policy
|
||||
_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
|
||||
*/
|
||||
@ -263,10 +272,18 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
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
|
||||
*
|
||||
* 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
|
||||
@ -283,6 +300,8 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
public:
|
||||
|
||||
using Initial_thread_base::Start;
|
||||
|
||||
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();
|
||||
|
||||
void start(addr_t) override;
|
||||
void start(addr_t, Start &) override;
|
||||
|
||||
Capability<Cpu_thread> cap() const override { return _cap; }
|
||||
};
|
||||
@ -348,6 +367,19 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
* implementing fork.
|
||||
*/
|
||||
Process(Type type,
|
||||
Dataspace_capability ldso_ds,
|
||||
Pd_session &pd,
|
||||
Initial_thread_base &initial_thread,
|
||||
Region_map &local_rm,
|
||||
Region_map &remote_rm,
|
||||
Parent_capability parent);
|
||||
Process(Type type,
|
||||
Dataspace_capability ldso_ds,
|
||||
Pd_session &pd,
|
||||
Initial_thread_base &,
|
||||
Initial_thread::Start &,
|
||||
Region_map &local_rm,
|
||||
Region_map &remote_rm,
|
||||
Parent_capability parent);
|
||||
|
||||
~Process();
|
||||
};
|
||||
|
@ -766,7 +766,8 @@ void Child::_try_construct_env_dependent_members()
|
||||
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
|
||||
_policy.with_address_space(_pd.session(), [&] (Region_map &address_space) {
|
||||
_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_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,
|
||||
Dataspace_capability ldso_ds,
|
||||
Pd_session &pd,
|
||||
Initial_thread_base &initial_thread,
|
||||
Region_map &local_rm,
|
||||
Region_map &remote_rm,
|
||||
Parent_capability parent_cap)
|
||||
Child::Process::Process(Type type,
|
||||
Dataspace_capability ldso_ds,
|
||||
Pd_session &pd,
|
||||
Initial_thread_base &initial_thread,
|
||||
Initial_thread::Start &start,
|
||||
Region_map &local_rm,
|
||||
Region_map &remote_rm,
|
||||
Parent_capability parent_cap)
|
||||
:
|
||||
loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
|
||||
{
|
||||
@ -198,7 +199,7 @@ Child::Process::Process(Type type,
|
||||
return;
|
||||
|
||||
/* 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