2013-07-18 16:27:42 +02:00
|
|
|
/*
|
|
|
|
* \brief ROM session implementation used by Noux processes
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2013-07-18
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _NOUX__ROM_SESSION_COMPONENT_H_
|
|
|
|
#define _NOUX__ROM_SESSION_COMPONENT_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <rom_session/connection.h>
|
|
|
|
#include <base/rpc_server.h>
|
|
|
|
|
|
|
|
namespace Noux {
|
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
struct Rom_dataspace_info;
|
|
|
|
class Rom_session_component;
|
|
|
|
}
|
2013-07-18 16:27:42 +02:00
|
|
|
|
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
struct Noux::Rom_dataspace_info : Dataspace_info
|
|
|
|
{
|
|
|
|
Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { }
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
~Rom_dataspace_info() { }
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
Dataspace_capability fork(Ram_session &,
|
2017-01-06 12:12:39 +01:00
|
|
|
Region_map &,
|
|
|
|
Allocator &alloc,
|
2016-11-23 17:07:49 +01:00
|
|
|
Dataspace_registry &ds_registry,
|
|
|
|
Rpc_entrypoint &) override
|
2013-07-18 16:27:42 +02:00
|
|
|
{
|
2017-01-06 12:12:39 +01:00
|
|
|
ds_registry.insert(new (alloc) Rom_dataspace_info(ds_cap()));
|
2016-11-23 17:07:49 +01:00
|
|
|
return ds_cap();
|
|
|
|
}
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2017-01-06 12:12:39 +01:00
|
|
|
void poke(Region_map &, addr_t dst_offset, char const *src, size_t len)
|
2016-11-23 17:07:49 +01:00
|
|
|
{
|
|
|
|
error("attempt to poke onto a ROM dataspace");
|
|
|
|
}
|
|
|
|
};
|
2013-07-18 16:27:42 +02:00
|
|
|
|
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
/**
|
|
|
|
* Local ROM service
|
|
|
|
*
|
|
|
|
* Depending on the ROM name, the data is provided by the VFS (if the name
|
|
|
|
* starts with a '/' or the parent's ROM service. If the name empty, an
|
|
|
|
* invalid dataspace capability is returned (this is used for the binary
|
|
|
|
* ROM session of a forked process).
|
|
|
|
*/
|
|
|
|
class Noux::Rom_session_component : public Rpc_object<Rom_session>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
Rpc_entrypoint &_ep;
|
|
|
|
Vfs::Dir_file_system &_root_dir;
|
|
|
|
Dataspace_registry &_ds_registry;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dataspace obtained from the VFS
|
|
|
|
*/
|
|
|
|
struct Vfs_dataspace
|
|
|
|
{
|
|
|
|
Vfs::Dir_file_system &root_dir;
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
Name const name;
|
|
|
|
Dataspace_capability const ds;
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
Vfs_dataspace(Vfs::Dir_file_system &root_dir, Name const &name)
|
2013-07-18 16:27:42 +02:00
|
|
|
:
|
2016-11-23 17:07:49 +01:00
|
|
|
root_dir(root_dir), name(name), ds(root_dir.dataspace(name.string()))
|
|
|
|
{ }
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
~Vfs_dataspace() { root_dir.release(name.string(), ds); }
|
|
|
|
};
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
|
2016-12-01 17:37:08 +01:00
|
|
|
Constructible<Vfs_dataspace> _rom_from_vfs;
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
/**
|
|
|
|
* Wrapped ROM session at core
|
|
|
|
*/
|
2016-12-01 17:37:08 +01:00
|
|
|
Constructible<Rom_connection> _rom_from_parent;
|
2013-08-30 08:46:21 +02:00
|
|
|
|
2017-01-06 12:12:39 +01:00
|
|
|
Dataspace_capability _init_ds_cap(Env &env, Name const &name)
|
2016-11-23 17:07:49 +01:00
|
|
|
{
|
|
|
|
if (name.string()[0] == '/') {
|
|
|
|
_rom_from_vfs.construct(_root_dir, name);
|
|
|
|
return _rom_from_vfs->ds;
|
2013-07-18 16:27:42 +02:00
|
|
|
}
|
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
if (name == forked_magic_binary_name())
|
|
|
|
return Dataspace_capability();
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2017-01-06 12:12:39 +01:00
|
|
|
_rom_from_parent.construct(env, name.string());
|
2016-11-23 17:07:49 +01:00
|
|
|
Dataspace_capability ds = _rom_from_parent->dataspace();
|
|
|
|
return ds;
|
|
|
|
}
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
Dataspace_capability const _ds_cap;
|
2013-07-18 16:27:42 +02:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
public:
|
|
|
|
|
2017-01-06 12:12:39 +01:00
|
|
|
Rom_session_component(Allocator &alloc, Env &env, Rpc_entrypoint &ep,
|
|
|
|
Vfs::Dir_file_system &root_dir,
|
2016-11-23 17:07:49 +01:00
|
|
|
Dataspace_registry &ds_registry, Name const &name)
|
|
|
|
:
|
|
|
|
_ep(ep), _root_dir(root_dir), _ds_registry(ds_registry),
|
2017-01-06 12:12:39 +01:00
|
|
|
_ds_cap(_init_ds_cap(env, name))
|
2016-11-23 17:07:49 +01:00
|
|
|
{
|
|
|
|
_ep.manage(this);
|
2017-01-06 12:12:39 +01:00
|
|
|
_ds_registry.insert(new (alloc) Rom_dataspace_info(_ds_cap));
|
2016-11-23 17:07:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~Rom_session_component()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Lookup and lock ds info instead of directly accessing
|
|
|
|
* the '_ds_info' member.
|
|
|
|
*/
|
|
|
|
_ds_registry.apply(_ds_cap, [this] (Dataspace_info *info) {
|
|
|
|
|
|
|
|
if (!info) {
|
|
|
|
error("~Rom_session_component: unexpected !info");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_ds_registry.remove(info);
|
|
|
|
|
|
|
|
info->dissolve_users();
|
|
|
|
});
|
|
|
|
_ep.dissolve(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************************
|
|
|
|
** ROM session interface **
|
|
|
|
***************************/
|
|
|
|
|
|
|
|
Rom_dataspace_capability dataspace()
|
|
|
|
{
|
|
|
|
return static_cap_cast<Rom_dataspace>(_ds_cap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sigh(Signal_context_capability) { }
|
|
|
|
};
|
2013-07-18 16:27:42 +02:00
|
|
|
|
|
|
|
#endif /* _NOUX__ROM_SESSION_COMPONENT_H_ */
|