19 #pragma GCC system_header 24 namespace L4 {
namespace Ipc L4_EXPORT {
26 template<
typename T,
template <
typename X>
class B >
27 struct Generic_va_type : B<T>
29 enum { Id = B<T>::Id };
31 typedef T
const &Ret_value;
34 static Ret_value value(
void const *d)
35 {
return *
reinterpret_cast<Value
const *
>(d); }
37 static void const *addr_of(Value
const &v) {
return &v; }
39 static unsigned size(
void const *) {
return sizeof(T); }
41 static L4_varg_type unsigned_id() {
return (L4_varg_type)(Id & ~L4_VARG_TYPE_SIGN); }
42 static L4_varg_type signed_id() {
return (L4_varg_type)(Id | L4_VARG_TYPE_SIGN); }
43 static L4_varg_type id() {
return (L4_varg_type)Id; }
46 template<
typename T >
struct Va_type_id;
47 template<>
struct Va_type_id<
l4_umword_t> {
enum { Id = L4_VARG_TYPE_UMWORD }; };
48 template<>
struct Va_type_id<
l4_mword_t> {
enum { Id = L4_VARG_TYPE_MWORD }; };
49 template<>
struct Va_type_id<
l4_fpage_t> {
enum { Id = L4_VARG_TYPE_FPAGE }; };
50 template<>
struct Va_type_id<void> {
enum { Id = L4_VARG_TYPE_NIL }; };
51 template<>
struct Va_type_id<char const *> {
enum { Id = L4_VARG_TYPE_STRING }; };
53 template<
typename T >
struct Va_type;
55 template<>
struct Va_type<
l4_umword_t> : Generic_va_type<l4_umword_t, Va_type_id> {};
56 template<>
struct Va_type<
l4_mword_t> : Generic_va_type<l4_mword_t, Va_type_id> {};
57 template<>
struct Va_type<
l4_fpage_t> : Generic_va_type<l4_fpage_t, Va_type_id> {};
59 template<>
struct Va_type<void>
61 typedef void Ret_value;
64 static void const *addr_of(
void) {
return 0; }
66 static void value(
void const *) {}
67 static L4_varg_type id() {
return L4_VARG_TYPE_NIL; }
68 static unsigned size(
void const *) {
return 0; }
71 template<>
struct Va_type<char const *>
73 typedef char const *Ret_value;
74 typedef char const *Value;
76 static void const *addr_of(Value v) {
return v; }
78 static L4_varg_type id() {
return L4_VARG_TYPE_STRING; }
79 static unsigned size(
void const *s)
81 char const *_s =
reinterpret_cast<char const *
>(s);
90 static Ret_value value(
void const *d) {
return (
char const *)d; }
99 enum { Direct_data = 0x8000 };
109 L4_varg_type
type()
const {
return (L4_varg_type)(_tag & 0xff); }
114 unsigned length()
const {
return _tag >> 16; }
116 Tag
tag()
const {
return _tag & ~Direct_data; }
120 void data(
char const *d) { _d = d; }
125 if (_tag & Direct_data)
127 union T {
char const *d;
char v[
sizeof(
char const *)]; };
128 return reinterpret_cast<T
const *
>(&_d)->v;
134 #if __cplusplus >= 201103L 141 Varg(L4_varg_type t,
void const *v,
int len)
142 : _tag(t | ((l4_mword_t)len << 16)), _d((char const *)v)
145 static Varg nil() {
return Varg(L4_VARG_TYPE_NIL, 0, 0); }
153 template<
typename V >
154 typename Va_type<V>::Ret_value
value()
const 156 if (_tag & Direct_data)
158 union X {
char const *d; V v; };
159 return reinterpret_cast<X
const &
>(_d).v;
162 return Va_type<V>::value(_d);
167 template<
typename T >
168 bool is_of()
const {
return Va_type<T>::id() == type(); }
171 bool is_nil()
const {
return is_of<void>(); }
175 {
return (type() & ~L4_VARG_TYPE_SIGN) == L4_VARG_TYPE_UMWORD; }
183 template<
typename T >
189 *v = this->value<T>();
194 template<
typename T >
197 typedef Va_type<T> Vt;
198 _tag = Vt::id() | (Vt::size(d) << 16);
199 _d = (
char const *)d;
204 void set_direct_value(T val,
typename L4::Types::Enable_if<
sizeof(T) <=
sizeof(
char const *),
bool>::type =
true)
206 static_assert(
sizeof(T) <=
sizeof(
char const *),
"direct Varg value too big");
207 typedef Va_type<T> Vt;
208 _tag = Vt::id() | (
sizeof(T) << 16) | Direct_data;
209 union X {
char const *d; T v; };
210 reinterpret_cast<X &
>(_d).v = val;
214 template<
typename T>
explicit 215 Varg(T
const *data) { set_value<T>(data); }
217 Varg(
char const *data) { set_value<char const *>(data); }
220 template<
typename T>
explicit 221 Varg(T data,
typename L4::Types::Enable_if<
sizeof(T) <=
sizeof(
char const *),
bool>::type =
true)
222 { set_direct_value<T>(data); }
227 class Varg_t :
public Varg 230 typedef typename Va_type<T>::Value Value;
231 explicit Varg_t(Value v) :
Varg()
232 { _data = v; set_value<T>(Va_type<T>::addr_of(_data)); }
238 template<
unsigned MAX = L4_UTCB_GENERIC_DATA_SIZE>
257 l4_umword_t
const *_end;
258 l4_umword_t
const *_current;
270 : _end(reinterpret_cast<l4_umword_t const *>(end)),
271 _current(reinterpret_cast<l4_umword_t const *>(start))
277 if (_current >= _end)
281 a.
data(reinterpret_cast<char const *>(_current));
282 _current += Msg::align_to<l4_umword_t>(a.
length()) /
sizeof(l4_umword_t);
297 template<
unsigned MAX>
300 l4_umword_t data[MAX];
307 for (
unsigned i = 0; i < r._end - r._current; ++i)
308 data[i] = r._current[i];
310 this->_current = data;
311 this->_end = data + (r._end - r._current);
317 template<>
struct Elem<Varg const *>
319 typedef Varg
const *arg_type;
322 enum { Is_optional =
false };
330 template<>
struct Direction<Varg const *> : Dir_in {};
331 template<>
struct Class<Varg const *> : Cls_data {};
333 template<
typename DIR,
typename CLASS>
334 struct Clnt_val_ops<Varg, DIR, CLASS>;
337 struct Clnt_val_ops<Varg, Dir_in, Cls_data> :
338 Clnt_noops<Varg const &>
340 using Clnt_noops<Varg const &>::to_msg;
341 static int to_msg(
char *msg,
unsigned offs,
unsigned limit,
342 Varg
const &a, Dir_in, Cls_data)
344 for (Varg
const *i = &a; i->
tag(); ++i)
346 offs = align_to<l4_umword_t>(offs);
347 if (
L4_UNLIKELY(!check_size<l4_umword_t>(offs, limit)))
349 *
reinterpret_cast<l4_umword_t*
>(msg + offs) = i->tag();
351 if (
L4_UNLIKELY(!check_size<char>(offs, limit, i->length())))
353 char const *d = i->data();
354 for (
unsigned x = 0; x < i->length(); ++x)
363 struct Svr_val_ops<Varg_list_ref, Dir_in, Cls_data> :
364 Svr_noops<Varg_list_ref>
366 using Svr_noops<Varg_list_ref>::to_svr;
367 static int to_svr(
char *msg,
unsigned offset,
unsigned limit,
368 Varg_list_ref &a, Dir_in, Cls_data)
370 unsigned start = align_to<l4_umword_t>(offset);
372 for (offs = start; offs < limit;)
374 unsigned noffs = align_to<l4_umword_t>(offs);
375 if (
L4_UNLIKELY(!check_size<l4_umword_t>(noffs, limit)))
380 arg.
tag(*reinterpret_cast<l4_umword_t*>(msg + offs));
392 a = Varg_list_ref(msg + start, msg + align_to<l4_umword_t>(offs));
Varg(L4_varg_type t, void const *v, int len)
Make an indirect varg.
void set_value(void const *d)
Set to indirect value of type T.
Varg(T const *data)
Make Varg from indirect value (pointer)
char const * data() const
signed long l4_mword_t
Signed machine word.
Variably sized RPC argument.
L4 low-level kernel interface.
void data(char const *d)
Set Varg to indirect data value (usually in UTCB)
void set_direct_value(T val, typename L4::Types::Enable_if< sizeof(T)<=sizeof(char const *), bool >::type=true)
Set to directly stored value of type T.
void tag(Tag tag)
Set Varg tag (usually from message)
Varg(char const *data)
Make Varg from null-terminated string.
l4_umword_t Tag
The data type for the tag.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
unsigned long l4_umword_t
Unsigned machine word.
List of variable-sized RPC parameters as received by the server.
Varg_list_ref()
Create an empty parameter list.
Self-contained list of variable-sized RPC parameters.
bool get_value(typename Va_type< T >::Value *v) const
Get the value of the Varg as type T.
Varg_list(Varg_list_ref const &r)
Create a parameter list as a copy from a referencing list.
L4_varg_type type() const
unsigned length() const
Get the size of the RPC argument.
Varg_list_ref(void const *start, void const *end)
Create a parameter list over a given memory region.
Varg(T data, typename L4::Types::Enable_if< sizeof(T)<=sizeof(char const *), bool >::type=true)
Make Varg from direct value.
Va_type< V >::Ret_value value() const
Varg next()
Get the next parameter in the list.