diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h index bffd9871fe..e63b020922 100644 --- a/repos/ports/src/noux/child.h +++ b/repos/ports/src/noux/child.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,8 @@ class Noux::Child : public Rpc_object, /* * Locally-provided ROM service */ + Empty_rom_factory _empty_rom_factory { _heap, _ep }; + Empty_rom_service _empty_rom_service { _empty_rom_factory }; Local_rom_factory _rom_factory { _heap, _env, _ep, _root_dir, _ds_registry }; Local_rom_service _rom_service { _rom_factory }; @@ -359,12 +362,11 @@ class Noux::Child : public Rpc_object, _args_ds_info(_ds_registry, _args.cap()), _sysio_env_ds_info(_ds_registry, _sysio_env.cap()), _config_ds_info(_ds_registry, _config.cap()), - _child_policy(name, - forked ? Rom_session_component::forked_magic_binary_name() - : name, + _child_policy(name, forked, _args.cap(), _sysio_env.cap(), _config.cap(), _ep, _pd_service, _ram_service, _cpu_service, - _noux_service, _rom_service, _parent_services, + _noux_service, _empty_rom_service, + _rom_service, _parent_services, *this, parent_exit, *this, _destruct_handler, ref_ram, ref_ram_cap, _verbose.enabled()), _child(_env.rm(), _ep, _child_policy) diff --git a/repos/ports/src/noux/child_policy.h b/repos/ports/src/noux/child_policy.h index 6f9f66603a..a87f79decd 100644 --- a/repos/ports/src/noux/child_policy.h +++ b/repos/ports/src/noux/child_policy.h @@ -21,6 +21,7 @@ #include #include #include +#include #include namespace Noux { @@ -42,7 +43,7 @@ class Noux::Child_policy : public Genode::Child_policy private: Name const _name; - Binary_name const _binary_name; + bool _forked; Init::Child_policy_provide_rom_file _args_policy; Init::Child_policy_provide_rom_file _env_policy; Init::Child_policy_provide_rom_file _config_policy; @@ -50,6 +51,7 @@ class Noux::Child_policy : public Genode::Child_policy Ram_service &_ram_service; Cpu_service &_cpu_service; Noux_service &_noux_service; + Empty_rom_service &_empty_rom_service; Local_rom_service &_rom_service; Parent_services &_parent_services; Family_member &_family_member; @@ -75,7 +77,7 @@ class Noux::Child_policy : public Genode::Child_policy public: Child_policy(Name const &name, - Binary_name const &binary_name, + bool forked, Dataspace_capability args_ds, Dataspace_capability env_ds, Dataspace_capability config_ds, @@ -84,6 +86,7 @@ class Noux::Child_policy : public Genode::Child_policy Ram_service &ram_service, Cpu_service &cpu_service, Noux_service &noux_service, + Empty_rom_service &empty_rom_service, Local_rom_service &rom_service, Parent_services &parent_services, Family_member &family_member, @@ -94,13 +97,13 @@ class Noux::Child_policy : public Genode::Child_policy Ram_session_capability ref_ram_cap, bool verbose) : - _name(name), - _binary_name(binary_name), + _name(name), _forked(forked), _args_policy( "args", args_ds, &entrypoint), _env_policy( "env", env_ds, &entrypoint), _config_policy("config", config_ds, &entrypoint), _pd_service(pd_service), _ram_service(ram_service), _cpu_service(cpu_service), _noux_service(noux_service), + _empty_rom_service(empty_rom_service), _rom_service(rom_service), _parent_services(parent_services), _family_member(family_member), _parent_exit(parent_exit), @@ -117,8 +120,7 @@ class Noux::Child_policy : public Genode::Child_policy ** Child policy interface ** ****************************/ - Name name() const override { return _name; } - Binary_name binary_name() const override { return _binary_name; } + Name name() const override { return _name; } Ram_session &ref_ram() override { return _ref_ram; } @@ -134,10 +136,14 @@ class Noux::Child_policy : public Genode::Child_policy { Session_label const label(Genode::label_from_args(args.string())); - /* route initial ROM requests (binary and linker) to the parent */ - if (service_name == Genode::Rom_session::service_name()) { - if (label.last_element() == binary_name()) return _rom_service; - if (label.last_element() == linker_name()) return _rom_service; + /* + * Route initial ROM requests (binary and linker) of a forked child + * to the empty ROM service, since the ROMs are already attached in + * the replayed region map. + */ + if (_forked && (service_name == Genode::Rom_session::service_name())) { + if (label.last_element() == name()) return _empty_rom_service; + if (label.last_element() == linker_name()) return _empty_rom_service; } Genode::Service *service = nullptr; diff --git a/repos/ports/src/noux/empty_rom_service.h b/repos/ports/src/noux/empty_rom_service.h new file mode 100644 index 0000000000..59ab74e966 --- /dev/null +++ b/repos/ports/src/noux/empty_rom_service.h @@ -0,0 +1,61 @@ +/* + * \brief ROM service provided to Noux processes for initial ROMs + * \author Christian Prochaska + * \date 2017-01-31 + * + * The initial ROMs (binary and linker) are already attached in a forked + * child and don't need a new ROM dataspace. + */ + +/* + * Copyright (C) 2017 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 _NOUX__EMPTY_ROM_SERVICE_H_ +#define _NOUX__EMPTY_ROM_SERVICE_H_ + +/* Genode includes */ +#include + +/* Noux includes */ +#include + +namespace Noux { + + typedef Local_service Empty_rom_service; + class Empty_rom_factory; +} + + +class Noux::Empty_rom_factory : public Empty_rom_service::Factory +{ + private: + + Allocator &_alloc; + Rpc_entrypoint &_ep; + + public: + + Empty_rom_factory(Allocator &alloc, Rpc_entrypoint &ep) + : _alloc(alloc), _ep(ep) { } + + Empty_rom_session_component &create(Args const &args, Affinity) override + { + try { + return *new (_alloc) Empty_rom_session_component(_ep); + } + catch (Rom_connection::Rom_connection_failed) { throw Denied(); } + } + + void upgrade(Empty_rom_session_component &, Args const &) override { } + + void destroy(Empty_rom_session_component &session) override + { + Genode::destroy(_alloc, &session); + } +}; + +#endif /* _NOUX__EMPTY_ROM_SERVICE_H_ */ diff --git a/repos/ports/src/noux/empty_rom_session_component.h b/repos/ports/src/noux/empty_rom_session_component.h new file mode 100644 index 0000000000..4f29089ea0 --- /dev/null +++ b/repos/ports/src/noux/empty_rom_session_component.h @@ -0,0 +1,58 @@ +/* + * \brief ROM session implementation used by Noux processes for initial ROMs + * \author Christian Prochaska + * \date 2017-01-31 + * + * The initial ROMs (binary and linker) are already attached in a forked + * child and don't need a new ROM dataspace. The invalid dataspace returned + * by this component is handled in 'Child::Process'. + */ + +/* + * Copyright (C) 2017 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 _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ +#define _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ + +/* Genode includes */ +#include + +namespace Noux { class Empty_rom_session_component; } + +class Noux::Empty_rom_session_component : public Rpc_object +{ + private: + + Rpc_entrypoint &_ep; + + public: + + Empty_rom_session_component(Rpc_entrypoint &ep) + : _ep(ep) + { + _ep.manage(this); + } + + ~Empty_rom_session_component() + { + _ep.dissolve(this); + } + + + /*************************** + ** ROM session interface ** + ***************************/ + + Rom_dataspace_capability dataspace() + { + return Rom_dataspace_capability(); + } + + void sigh(Signal_context_capability) { } +}; + +#endif /* _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/noux/rom_session_component.h b/repos/ports/src/noux/rom_session_component.h index 861cc1510f..492f8b69f6 100644 --- a/repos/ports/src/noux/rom_session_component.h +++ b/repos/ports/src/noux/rom_session_component.h @@ -62,16 +62,6 @@ class Noux::Rom_session_component : public Rpc_object typedef Child_policy::Name Name; - /** - * Label of ROM session requested for the binary of a forked process - * - * In this case, the loading of the binary must be omitted because the - * address space is replayed by the fork operation. Hence, requests for - * such ROM modules are answered by an invalid dataspace, which is - * handled in 'Child::Process'. - */ - static Name forked_magic_binary_name() { return "(forked)"; } - private: Allocator &_alloc; @@ -111,9 +101,6 @@ class Noux::Rom_session_component : public Rpc_object return _rom_from_vfs->ds; } - if (name == forked_magic_binary_name()) - return Dataspace_capability(); - _rom_from_parent.construct(env, name.string()); Dataspace_capability ds = _rom_from_parent->dataspace(); return ds;