base/core: use references instead of pointers

This patch replaces the former prominent use of pointers by references
wherever feasible. This has the following benefits:

* The contract between caller and callee becomes more obvious. When
  passing a reference, the contract says that the argument cannot be
  a null pointer. The caller is responsible to ensure that. Therefore,
  the use of reference eliminates the need to add defensive null-pointer
  checks at the callee site, which sometimes merely exist to be on the
  safe side. The bottom line is that the code becomes easier to follow.

* Reference members must be initialized via an object initializer,
  which promotes a programming style that avoids intermediate object-
  construction states. Within core, there are still a few pointers
  as member variables left though. E.g., caused by the late association
  of 'Platform_thread' objects with their 'Platform_pd' objects.

* If no pointers are present as member variables, we don't need to
  manually provide declarations of a private copy constructor and
  an assignment operator to avoid -Weffc++ errors "class ... has
  pointer data members [-Werror=effc++]".

This patch also changes a few system bindings on NOVA and Fiasco.OC,
e.g., the return value of the global 'cap_map' accessor has become a
reference. Hence, the patch touches a few places outside of core.

Fixes #3135
This commit is contained in:
Norman Feske
2019-01-24 22:00:01 +01:00
parent f9373b4430
commit 6b289a1423
242 changed files with 2390 additions and 2434 deletions

View File

@ -38,15 +38,15 @@ namespace Genode {
{
private:
Filename _fname { }; /* filename for mmap */
size_t _size { 0 }; /* size of dataspace in bytes */
addr_t _addr { 0 }; /* meaningless on linux */
int _fd { -1 }; /* file descriptor */
bool _writable { false }; /* false if read-only */
Filename _fname { }; /* filename for mmap */
size_t const _size; /* size of dataspace in bytes */
addr_t const _addr; /* meaningless on linux */
int _fd { -1 }; /* file descriptor */
bool const _writable; /* false if read-only */
/* Holds the dataspace owner if a distinction between owner and
* others is necessary on the dataspace, otherwise it is 0 */
Dataspace_owner * _owner;
Dataspace_owner const * const _owner;
static Filename _file_name(const char *args);
size_t _file_size();
@ -72,7 +72,7 @@ namespace Genode {
* Default constructor returns invalid dataspace
*/
Dataspace_component()
: _size(0), _addr(0), _fd(-1), _writable(false), _owner(0) { }
: _size(0), _addr(0), _fd(-1), _writable(false), _owner(nullptr) { }
/**
* This constructor is only provided for compatibility
@ -81,7 +81,8 @@ namespace Genode {
Dataspace_component(size_t size, addr_t, addr_t phys_addr,
Cache_attribute, bool, Dataspace_owner *_owner)
:
_size(size), _addr(phys_addr), _fd(-1), _owner(_owner)
_size(size), _addr(phys_addr), _fd(-1), _writable(false),
_owner(_owner)
{
warning("Should only be used for IOMEM and not within Linux.");
_fname.buf[0] = 0;
@ -105,20 +106,21 @@ namespace Genode {
/**
* Check if dataspace is owned by a specified object
*/
bool owner(Dataspace_owner const *o) const { return _owner == o; }
bool owner(Dataspace_owner const &o) const { return _owner == &o; }
/**
* Detach dataspace from all rm sessions.
*/
void detach_from_rm_sessions() { }
/*************************
** Dataspace interface **
*************************/
size_t size() { return _size; }
addr_t phys_addr() { return _addr; }
bool writable() { return _writable; }
size_t size() override { return _size; }
addr_t phys_addr() override { return _addr; }
bool writable() override { return _writable; }
/****************************************

View File

@ -40,9 +40,9 @@ namespace Genode {
* particular MMIO region base, size and
* caching demands
*/
Io_mem_session_component(Range_allocator *io_mem_alloc,
Range_allocator *ram_alloc,
Rpc_entrypoint *ds_ep,
Io_mem_session_component(Range_allocator &io_mem_alloc,
Range_allocator &ram_alloc,
Rpc_entrypoint &ds_ep,
const char *args);
/**

View File

@ -34,7 +34,7 @@ class Genode::Irq_session_component : public Rpc_object<Irq_session>,
/**
* Constructor
*/
Irq_session_component(Range_allocator *, const char *) { }
Irq_session_component(Range_allocator &, const char *) { }
/**
* Destructor
@ -49,8 +49,9 @@ class Genode::Irq_session_component : public Rpc_object<Irq_session>,
void ack_irq() override { }
void sigh(Signal_context_capability) override { }
Info info() override {
return { .type = Genode::Irq_session::Info::Type::INVALID,
.address = 0, .value = 0 }; }
return { .type = Genode::Irq_session::Info::Type::INVALID,
.address = 0,
.value = 0 }; }
};
#endif /* _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_ */

View File

@ -52,9 +52,9 @@ namespace Genode {
auto apply(Pager_capability, FUNC f) -> decltype(f(nullptr)) {
return f(nullptr); }
Pager_capability manage(Pager_object *) { return Pager_capability(); }
Pager_capability manage(Pager_object &) { return Pager_capability(); }
void dissolve(Pager_object *) { }
void dissolve(Pager_object &) { }
};
}

View File

@ -22,6 +22,7 @@
#include <platform_pd.h>
#include <platform_thread.h>
#include <synced_range_allocator.h>
#include <assertion.h>
namespace Genode {
@ -36,6 +37,29 @@ namespace Genode {
*/
Synced_range_allocator<Allocator_avl> _core_mem_alloc;
Rom_fs _dummy_rom_fs { };
struct Dummy_allocator : Range_allocator
{
void free(void *, size_t) override { ASSERT_NEVER_CALLED; }
bool need_size_for_free() const override { ASSERT_NEVER_CALLED; }
size_t consumed() const override { ASSERT_NEVER_CALLED; }
size_t overhead(size_t) const override { ASSERT_NEVER_CALLED; }
int add_range (addr_t, size_t ) override { ASSERT_NEVER_CALLED; }
int remove_range(addr_t, size_t ) override { ASSERT_NEVER_CALLED; }
void free(void *) override { ASSERT_NEVER_CALLED; }
size_t avail() const override { ASSERT_NEVER_CALLED; }
bool valid_addr(addr_t ) const override { ASSERT_NEVER_CALLED; }
bool alloc(size_t, void **) override { ASSERT_NEVER_CALLED; }
Alloc_return alloc_aligned(size_t, void **, int, addr_t, addr_t) override
{ ASSERT_NEVER_CALLED; }
Alloc_return alloc_addr(size_t, addr_t) override
{ ASSERT_NEVER_CALLED; }
} _dummy_alloc { };
/**
* Allocator for pseudo physical memory
*/
@ -61,15 +85,14 @@ namespace Genode {
int add_range(addr_t, size_t) override { return 0; }
int remove_range(addr_t, size_t) override { return 0; }
void free(void *) override { }
void free(void *, size_t) override { }
size_t avail() const override { return ~0; }
bool valid_addr(addr_t) const override { return true; }
size_t overhead(size_t) const override { return 0; }
bool need_size_for_free() const override { return true; }
};
void free(void *) override { }
void free(void *, size_t) override { }
size_t avail() const override { return ~0; }
bool valid_addr(addr_t) const override { return true; }
size_t overhead(size_t) const override { return 0; }
bool need_size_for_free() const override { return true; }
Pseudo_ram_allocator _ram_alloc { };
} _ram_alloc { };
public:
@ -83,15 +106,15 @@ namespace Genode {
** Generic platform interface **
********************************/
Range_allocator *core_mem_alloc() override { return &_core_mem_alloc; }
Range_allocator *ram_alloc() override { return &_ram_alloc; }
Range_allocator *io_mem_alloc() override { return 0; }
Range_allocator *io_port_alloc() override { return 0; }
Range_allocator *irq_alloc() override { return 0; }
Range_allocator *region_alloc() override { return 0; }
Range_allocator &core_mem_alloc() override { return _core_mem_alloc; }
Range_allocator &ram_alloc() override { return _ram_alloc; }
Range_allocator &io_mem_alloc() override { return _dummy_alloc; }
Range_allocator &io_port_alloc() override { return _dummy_alloc; }
Range_allocator &irq_alloc() override { return _dummy_alloc; }
Range_allocator &region_alloc() override { return _dummy_alloc; }
addr_t vm_start() const override { return 0; }
size_t vm_size() const override { return 0; }
Rom_fs *rom_fs() override { return 0; }
Rom_fs &rom_fs() override { return _dummy_rom_fs; }
/*
* On Linux, the maximum number of capabilities is primarily

View File

@ -26,9 +26,9 @@ namespace Genode {
struct Genode::Platform_pd
{
Platform_pd(Allocator *, char const *) { }
Platform_pd(Allocator &, char const *) { }
bool bind_thread(Platform_thread *) { return true; }
bool bind_thread(Platform_thread &) { return true; }
void assign_parent(Capability<Parent>) { }
};

View File

@ -60,7 +60,7 @@ namespace Genode {
/**
* Return singleton instance of 'Platform_thread::Registry'
*/
static Registry *_registry();
static Registry &_registry();
unsigned long _tid = -1;
unsigned long _pid = -1;
@ -110,8 +110,8 @@ namespace Genode {
/**
* Dummy implementation of platform-thread interface
*/
Pager_object *pager() { return &_pager; }
void pager(Pager_object *) { }
Pager_object &pager() { return _pager; }
void pager(Pager_object &) { }
int start(void *, void *) { return 0; }
Thread_state state()
@ -164,7 +164,7 @@ namespace Genode {
*/
static void submit_exception(int pid)
{
_registry()->submit_exception(pid);
_registry().submit_exception(pid);
}
/**

View File

@ -65,22 +65,16 @@ class Genode::Region_map_component : public Rpc_object<Region_map>,
Dataspace_capability dataspace() { return Dataspace_capability(); }
Rm_dataspace_component *dataspace_component() { return 0; }
Rm_dataspace_component *dataspace_component() { return nullptr; }
void address_space(Platform_pd *) { }
};
struct Genode::Rm_member : Interface
struct Genode::Rm_client : Pager_object
{
Region_map_component *member_rm() { return 0; }
};
struct Genode::Rm_client : Pager_object, Rm_member
{
Rm_client(Cpu_session_capability, Thread_capability,
Region_map_component *, unsigned long,
Rm_client(Cpu_session_capability, Thread_capability,
Region_map_component &, unsigned long,
Affinity::Location, Cpu_session::Name const&,
Session_label const&)
{ }

View File

@ -24,7 +24,7 @@ class Genode::Rpc_cap_factory
{
private:
static Native_capability _alloc(Rpc_cap_factory *owner,
static Native_capability _alloc(Rpc_cap_factory &owner,
Native_capability ep);
public:

View File

@ -95,7 +95,7 @@ static inline Genode::Socket_pair create_server_socket_pair(long id)
throw Connect_failed();
}
socket_pair.client_sd = Genode::ep_sd_registry()->try_associate(socket_pair.client_sd, id);
socket_pair.client_sd = Genode::ep_sd_registry().try_associate(socket_pair.client_sd, id);
/*
* Wipe Unix domain socket from the file system. It will live as long as

View File

@ -18,8 +18,8 @@
using namespace Genode;
Io_mem_session_component::Io_mem_session_component(Range_allocator *,
Range_allocator *,
Rpc_entrypoint *,
Io_mem_session_component::Io_mem_session_component(Range_allocator &,
Range_allocator &,
Rpc_entrypoint &,
const char *args) {
warning("no io_mem support on Linux (args=\"", args, "\")"); }

View File

@ -54,7 +54,7 @@ Untyped_capability Native_cpu_component::client_sd(Thread_capability thread_cap)
Native_cpu_component::Native_cpu_component(Cpu_session_component &cpu_session, char const *)
:
_cpu_session(cpu_session), _thread_ep(*_cpu_session._thread_ep)
_cpu_session(cpu_session), _thread_ep(_cpu_session._thread_ep)
{
_thread_ep.manage(this);
}

View File

@ -183,7 +183,7 @@ size_t Region_map_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
return Local_capability<Dataspace>::deref(ds_cap)->size();
/* use local function call if called from the entrypoint */
return core_env()->entrypoint()->apply(ds_cap, [] (Dataspace *ds) {
return core_env().entrypoint().apply(ds_cap, [] (Dataspace *ds) {
return ds ? ds->size() : 0; });
}
@ -201,13 +201,13 @@ int Region_map_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
* socket descriptor during the RPC handling). When later destroying the
* dataspace, the descriptor would unexpectedly be closed again.
*/
return core_env()->entrypoint()->apply(lx_ds_cap, [] (Linux_dataspace *ds) {
return core_env().entrypoint().apply(lx_ds_cap, [] (Linux_dataspace *ds) {
return ds ? lx_dup(Capability_space::ipc_cap_data(ds->fd()).dst.socket) : -1; });
}
bool Region_map_mmap::_dataspace_writable(Dataspace_capability ds_cap)
{
return core_env()->entrypoint()->apply(ds_cap, [] (Dataspace *ds) {
return core_env().entrypoint().apply(ds_cap, [] (Dataspace *ds) {
return ds ? ds->writable() : false; });
}

View File

@ -63,10 +63,10 @@ void Platform_thread::Registry::submit_exception(unsigned long pid)
}
Platform_thread::Registry *Platform_thread::_registry()
Platform_thread::Registry &Platform_thread::_registry()
{
static Platform_thread::Registry registry;
return &registry;
return registry;
}
@ -79,13 +79,13 @@ Platform_thread::Platform_thread(size_t, const char *name, unsigned,
{
strncpy(_name, name, min(sizeof(_name), strlen(name) + 1));
_registry()->insert(this);
_registry().insert(this);
}
Platform_thread::~Platform_thread()
{
ep_sd_registry()->disassociate(_socket_pair.client_sd);
ep_sd_registry().disassociate(_socket_pair.client_sd);
if (_socket_pair.client_sd)
lx_close(_socket_pair.client_sd);
@ -93,7 +93,7 @@ Platform_thread::~Platform_thread()
if (_socket_pair.server_sd)
lx_close(_socket_pair.server_sd);
_registry()->remove(this);
_registry().remove(this);
}

View File

@ -33,7 +33,7 @@ using namespace Genode;
static int ram_ds_cnt = 0; /* counter for creating unique dataspace IDs */
void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds)
void Ram_dataspace_factory::_export_ram_ds(Dataspace_component &ds)
{
char fname[Linux_dataspace::FNAME_LEN];
@ -41,10 +41,10 @@ void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds)
snprintf(fname, sizeof(fname), "%s/ds-%d", resource_path(), ram_ds_cnt++);
lx_unlink(fname);
int const fd = lx_open(fname, O_CREAT|O_RDWR|O_TRUNC|LX_O_CLOEXEC, S_IRWXU);
lx_ftruncate(fd, ds->size());
lx_ftruncate(fd, ds.size());
/* remember file descriptor in dataspace component object */
ds->fd(fd);
ds.fd(fd);
/*
* Wipe the file from the Linux file system. The kernel will still keep the
@ -56,12 +56,12 @@ void Ram_dataspace_factory::_export_ram_ds(Dataspace_component *ds)
}
void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component *ds)
void Ram_dataspace_factory::_revoke_ram_ds(Dataspace_component &ds)
{
int const fd = Capability_space::ipc_cap_data(ds->fd()).dst.socket;
int const fd = Capability_space::ipc_cap_data(ds.fd()).dst.socket;
if (fd != -1)
lx_close(fd);
}
void Ram_dataspace_factory::_clear_ds(Dataspace_component *) { }
void Ram_dataspace_factory::_clear_ds(Dataspace_component &) { }

View File

@ -33,19 +33,29 @@
using namespace Genode;
Rom_session_component::Rom_session_component(Rom_fs *,
Rpc_entrypoint *ds_ep,
const char *args)
: _ds(args), _ds_ep(ds_ep)
/**
* Convert 'Capability<Linux_dataspace>' to 'Capability<Rom_dataspace>'
*
* The downcast from 'Linux_dataspace' to 'Dataspace' happens implicitly by
* passing the argument. To upcast to 'Linux_dataspace' happens explicitly.
*/
static Capability<Rom_dataspace> rom_ds_cap(Capability<Dataspace> cap)
{
Dataspace_capability ds_cap = _ds_ep->manage(&_ds);
_ds_cap = static_cap_cast<Rom_dataspace>(ds_cap);
return static_cap_cast<Rom_dataspace>(cap);
}
Rom_session_component::Rom_session_component(Rom_fs &,
Rpc_entrypoint &ds_ep,
const char *args)
:
_ds(args), _ds_ep(ds_ep), _ds_cap(rom_ds_cap(_ds_ep.manage(&_ds)))
{ }
Rom_session_component::~Rom_session_component()
{
_ds_ep->dissolve(&_ds);
_ds_ep.dissolve(&_ds);
int const fd = Capability_space::ipc_cap_data(_ds.fd()).dst.socket;
if (fd != -1)

View File

@ -30,11 +30,11 @@ static void empty_signal_handler(int) { }
void Thread::_thread_start()
{
Thread * const thread = Thread::myself();
Thread * const thread_ptr = Thread::myself();
/* use primary stack as alternate stack for fatal signals (exceptions) */
void *stack_base = (void *)thread->_stack->base();
size_t stack_size = thread->_stack->top() - thread->_stack->base();
void *stack_base = (void *)thread_ptr->_stack->base();
size_t stack_size = thread_ptr->_stack->top() - thread_ptr->_stack->base();
lx_sigaltstack(stack_base, stack_size);