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:
Norman Feske 2023-05-16 16:51:53 +02:00
parent f2153f9b2f
commit 734fc252e8
4 changed files with 64 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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