diff --git a/repos/base-hw/src/include/base/internal/native_utcb.h b/repos/base-hw/src/include/base/internal/native_utcb.h index 9ce79a8793..73ff38aba1 100644 --- a/repos/base-hw/src/include/base/internal/native_utcb.h +++ b/repos/base-hw/src/include/base/internal/native_utcb.h @@ -56,29 +56,29 @@ class Genode::Native_utcb private: /* - * Note thats the member variables are sorted from the largest to the - * smallest size to avoid padding. Otherwise, the dimensioning of - * '_data' would not yield a page-sized 'Native_utcb'. + * Note, the member variables are put into a header structure to ensure + * the header is padded by the compiler to the next machine-word + * boundary and '_data' is aligned. This also makes the dimensioning of + * '_data' easy (page size - size of header). */ - - size_t _cap_cnt; /* capability counter */ - size_t _data_size; /* bytes to transfer */ - long _exception_code; /* result code of RPC */ - Kernel::capid_t _destination; /* invoked object */ - Kernel::capid_t _caps[MAX_CAP_ARGS]; /* capability buffer */ - uint8_t _data[get_page_size() - sizeof(_caps) - - sizeof(_cap_cnt) - sizeof(_data_size) - - sizeof(_destination) - sizeof(_exception_code)]; + struct { + size_t cap_cnt; /* capability counter */ + size_t data_size; /* bytes to transfer */ + long exception_code; /* result code of RPC */ + Kernel::capid_t destination; /* invoked object */ + Kernel::capid_t caps[MAX_CAP_ARGS]; /* capability buffer */ + } _header; /* is padded to machine word boundary by the compiler */ + uint8_t _data[get_page_size() - sizeof(_header)]; public: Native_utcb& operator= (const Native_utcb &other) { - _cap_cnt = 0; - _data_size = min(sizeof(_data), other._data_size); - _exception_code = other._exception_code; - _destination = other._destination; - memcpy(_data, other._data, _data_size); + _header.cap_cnt = 0; + _header.data_size = min(sizeof(_data), other._header.data_size); + _header.exception_code = other._header.exception_code; + _header.destination = other._header.destination; + memcpy(_data, other._data, _header.data_size); return *this; } @@ -86,26 +86,26 @@ class Genode::Native_utcb /** * Set the destination capability id (server object identity) */ - void destination(Kernel::capid_t id) { _destination = id; } + void destination(Kernel::capid_t id) { _header.destination = id; } /** * Return identity of invoked server object */ - Kernel::capid_t destination() const { return _destination; } + Kernel::capid_t destination() const { return _header.destination; } - void exception_code(long code) { _exception_code = code; } + void exception_code(long code) { _header.exception_code = code; } - long exception_code() const { return _exception_code; } + long exception_code() const { return _header.exception_code; } /** * Return the count of capabilities in the UTCB */ - size_t cap_cnt() const { return _cap_cnt; } + size_t cap_cnt() const { return _header.cap_cnt; } /** * Set the count of capabilities in the UTCB */ - void cap_cnt(size_t cnt) { _cap_cnt = cnt; } + void cap_cnt(size_t cnt) { _header.cap_cnt = cnt; } /** * Return the start address of the payload data @@ -121,14 +121,14 @@ class Genode::Native_utcb /** * Return size of message data in bytes */ - size_t data_size() const { return _data_size; } + size_t data_size() const { return _header.data_size; } /** * Define size of message data to be transferred, in bytes */ void data_size(size_t data_size) { - _data_size = min(data_size, sizeof(_data)); + _header.data_size = min(data_size, sizeof(_data)); } /** @@ -136,7 +136,7 @@ class Genode::Native_utcb */ Kernel::capid_t cap_get(unsigned i) const { - return (i < MAX_CAP_ARGS) ? _caps[i] : Kernel::cap_id_invalid(); + return (i < MAX_CAP_ARGS) ? _header.caps[i] : Kernel::cap_id_invalid(); } /** @@ -145,14 +145,14 @@ class Genode::Native_utcb void cap_set(unsigned i, Kernel::capid_t cap) { if (i < MAX_CAP_ARGS) - _caps[i] = cap; + _header.caps[i] = cap; } /** * Set the capability id 'cap_id' at the next index */ void cap_add(Kernel::capid_t cap_id) { - if (_cap_cnt < MAX_CAP_ARGS) _caps[_cap_cnt++] = cap_id; } + if (_header.cap_cnt < MAX_CAP_ARGS) _header.caps[_header.cap_cnt++] = cap_id; } }; static_assert(sizeof(Genode::Native_utcb) == Genode::get_page_size(),