23#include <l4/cxx/std_ops>
24#include <l4/sys/cxx/ipc_epiface>
25#include <l4/cxx/string>
26#include <l4/re/util/debug>
34namespace L4Re {
namespace Util {
namespace Names {
43 Name(
const char *name =
"") :
String(name, __builtin_strlen(name)) {}
46 char const *name()
const {
return start(); }
47 bool operator < (
Name const &r)
const
49 unsigned long l = cxx::min(
len(), r.
len());
51 return v < 0 || (v == 0 &&
len() < r.
len());
78 F_rights_mask = F_rw | F_strong | F_trusted,
87 unsigned flags()
const {
return _f; }
88 void restrict_flags(
unsigned max_rights)
89 { _f &= (~F_rights_mask | (max_rights & F_rights_mask)); }
91 bool is_rw()
const {
return (_f & F_rw) == F_rw; }
92 bool is_strong()
const {
return _f & F_strong; }
94 bool is_valid()
const {
return _f & F_cap; }
95 bool is_complete()
const {
return is_valid(); }
96 bool is_local()
const {
return _f & F_local; }
97 bool is_replacable()
const {
return _f & F_replacable; }
98 bool is_trusted()
const {
return _f & F_trusted; }
100 L4::Epiface *obj()
const {
if (is_local())
return _obj;
return 0; }
107 return _obj->obj_cap();
111 void set(Obj
const &o,
unsigned flags)
114 restrict_flags(flags);
117 explicit Obj(
unsigned flags = 0)
122 : _f((f & ~F_base_mask) | F_cap), _cap(cap.cap())
126 : _f((f & ~F_base_mask) | F_cap | F_local), _obj(o)
129 void reset(
unsigned flags)
131 _f = (_f & F_replacable) | (flags & ~(F_cap | F_local));
145 friend class Name_space;
152 Entry(Name
const &n, Obj
const &o,
bool dynamic =
false)
153 : _n(n), _o(o), _dynamic(dynamic) {}
155 Name
const &name()
const {
return _n; }
156 Obj
const *obj()
const {
return &_o; }
157 Obj *obj() {
return &_o; }
158 void obj(Obj
const &o) { _o = o; }
160 bool is_placeholder()
const
161 {
return !obj()->is_complete(); }
163 bool is_dynamic()
const {
return _dynamic; }
165 void set(Obj
const &o)
167 obj()->set(o, obj()->flags());
171 void *
operator new (
size_t s);
172 void operator delete(
void *b);
178 typedef Name Key_type;
179 static Key_type
const &key_of(Entry
const *e)
180 {
return e->name(); }
200 L4Re::Util::Dbg
const &_dbg;
201 L4Re::Util::Err
const &_err;
207 Const_iterator begin()
const {
return _tree.
begin(); }
208 Const_iterator end()
const {
return _tree.
end(); }
210 Name_space(L4Re::Util::Dbg
const &dbg, L4Re::Util::Err
const &err)
211 : _dbg(dbg), _err(err)
219 Entry *find(
Name const &name)
const {
return _tree.
find_node(name); }
220 Entry *remove(Name
const &name) {
return _tree.
remove(name); }
221 Entry *find_iter(Name
const &pname)
const
224 _dbg.printf(
"resolve '%.*s': ", name.len(), name.start());
225 Name_space
const *ns =
this;
231 part = name.
head(sep);
235 _dbg.cprintf(
" '%.*s'", part.
len(), part.
start());
236 Entry *o = ns->find(Name(part.
start(), part.
len()));
240 _dbg.cprintf(
": resolution failed: '%.*s' remaining\n",
241 name.len(), name.start());
245 auto const *obj = o->obj()->obj();
246 ns =
dynamic_cast<Name_space
const *
>(obj);
251 name = name.substr(sep + 1);
256 _dbg.cprintf(
": found object: %p (%s)\n",
257 obj, obj ?
typeid(*obj).name() :
"");
265 bool insert(Entry *e) {
return _tree.
insert(e).second; }
267 void dump(
bool rec =
false,
int indent = 0)
const;
350 int insert_entry(
Name const &name,
unsigned flags, Entry **e)
352 Entry *n = find(name);
353 if (n && n->obj()->is_valid())
359 if (n->obj()->is_local())
372 if (!n->obj()->is_replacable())
374 n->obj()->reset(Obj::F_rw);
378 flags &= L4Re::Namespace::Cap_flags;
399 int op_query(L4Re::Namespace::Rights,
405 _dbg.printf(
"query: [%ld] '%.*s'\n", name.
length,
410 =
static_cast<char const*
>(memchr(name.
data,
'/', name.
length));
413 part = sep - name.
data;
417 Entry *n = find(
Name(name.
data, part));
420 else if (!n->obj()->is_valid())
426 if (n->obj()->is_local())
444 out_name.set_valid();
448 memcpy(out_name->data, name.
data + part + 1, name.
length - part - 1);
449 out_name->length = name.
length - part - 1;
452 out_name->length = 0;
459 _dbg.printf(
" result = %lx flgs=%x strg=%d\n",
460 result, flags,
static_cast<int>(n->obj()->is_strong()));
465 int op_register_obj(L4Re::Namespace::Rights,
unsigned flags,
484 flags &= (cap.
data() & 0x3UL) | ~0x3UL;
499 _dbg.printf(
"register: '%.*s' flags=%x\n",
static_cast<int>(name.
length),
505 if (
int r = insert_entry(_name, flags, &n))
516 n->set(Names::Obj(flags & L4Re::Namespace::Cap_flags, src_o));
517 else if (reg_cap.is_valid())
518 n->set(Names::Obj(flags & L4Re::Namespace::Cap_flags, reg_cap));
523 int op_unlink(L4Re::Namespace::Rights,
528 _dbg.printf(
"unlink: [%ld] '%.*s'\n", name.
length,
533 =
static_cast<char const*
>(memchr(name.
data,
'/', name.
length));
536 part = sep - name.
data;
540 Entry *n = find(Name(name.
data, part));
541 if (!n || !n->obj()->is_valid())
544 if (n->obj()->is_local())
L4::Cap related definitions.
@ Partly_resolved
Name was only partly resolved.
@ Trusted
Obsolete, do not use.
@ Overwrite
If entry already exists, overwrite it.
Abstract server-side implementation of the L4::Namespace interface.
virtual void free_dynamic_entry(Entry *e)=0
Free an entry previously allocated with alloc_dynamic_entry().
virtual int get_epiface(l4_umword_t data, bool is_local, L4::Epiface **lo)=0
Return a pointer to the epiface assigned to a given label.
virtual Entry * alloc_dynamic_entry(Name const &n, unsigned flags)=0
Allocate a new entry for the given name.
virtual int copy_receive_cap(L4::Cap< void > *cap)=0
Return the receive capability for permanent use.
virtual ~Name_space()
The destructor of the derived class is responsible for freeing resources.
virtual void free_capability(L4::Cap< void > cap)=0
Free a capability previously acquired with copy_receive_cap().
virtual void free_epiface(L4::Epiface *epiface)=0
Free epiface previously acquired with get_epiface().
C++ interface for capabilities.
bool is_valid() const noexcept
Check if the capability is valid.
bool id_received() const noexcept
Check if a label was received instead of a mapping.
bool cap_received() const noexcept
Check if at least one capability has been mapped.
bool local_id_received() const noexcept
Check if a local capability id has been received.
l4_umword_t data() const noexcept
Return the raw flex page descriptor.
Pair< Node *, bool > insert(Node *new_node)
Insert a new node into this AVL tree.
Node * remove(Key_param_type key)
Remove the node with key from the tree.
Bst::Const_iterator Const_iterator
Constant forward iterator for the tree.
Node * find_node(Key_param_type key) const
find the node with the given key.
Const_iterator end() const
Get the end marker for the constant forward iterator.
Const_iterator begin() const
Get the constant forward iterator for the first element in the set.
Allocation free string class with explicit length field.
Index start() const
Pointer to first character.
String head(Index end) const
Return prefix up to index.
char const * Index
Character index type.
String()
Zero-initialize. Create an invalid string.
unsigned long l4_umword_t
Unsigned machine word.
unsigned long l4_cap_idx_t
Capability selector type.
@ L4_BASE_TASK_CAP
Capability selector for the current task.
@ L4_INVALID_CAP
Invalid capability selector.
@ L4_EEXIST
Already exists.
@ L4_ENOENT
No such entity.
@ L4_EACCESS
Permission denied.
@ L4_EINVAL
Invalid argument.
@ L4_CAP_FPAGE_R
Read right for capability flex-pages.
@ L4_CAP_FPAGE_W
Interface specific 'W' right for capability flex-pages.
@ L4_CAP_FPAGE_S
Interface specific 'S' right for capability flex-pages.
Base class for interface implementations.
Server-side copy in buffer for Array.
LEN_TYPE length
The length of the array.
ELEM_TYPE data[MAX]
The data elements.
Array reference data type for arrays located in the message.
Attribute for defining an optional RPC argument.
void set_valid(bool valid=true) noexcept
Set the argument to present or absent.