12#include <l4/cxx/std_ops>
13#include <l4/sys/cxx/ipc_epiface>
14#include <l4/cxx/string>
15#include <l4/re/util/debug>
23namespace L4Re {
namespace Util {
namespace Names {
32 Name(
const char *name =
"") :
String(name, __builtin_strlen(name)) {}
35 char const *name()
const {
return start(); }
36 bool operator < (
Name const &r)
const
38 unsigned long l = cxx::min(
len(), r.
len());
40 return v < 0 || (v == 0 &&
len() < r.
len());
67 F_rights_mask = F_rw | F_strong | F_trusted,
76 unsigned flags()
const {
return _f; }
77 void restrict_flags(
unsigned max_rights)
78 { _f &= (~F_rights_mask | (max_rights & F_rights_mask)); }
80 bool is_rw()
const {
return (_f & F_rw) == F_rw; }
81 bool is_strong()
const {
return _f & F_strong; }
83 bool is_valid()
const {
return _f & F_cap; }
84 bool is_complete()
const {
return is_valid(); }
85 bool is_local()
const {
return _f & F_local; }
86 bool is_replacable()
const {
return _f & F_replacable; }
87 bool is_trusted()
const {
return _f & F_trusted; }
89 L4::Epiface *obj()
const {
if (is_local())
return _obj;
return 0; }
96 return _obj->obj_cap();
100 void set(Obj
const &o,
unsigned flags)
103 restrict_flags(flags);
106 explicit Obj(
unsigned flags = 0)
111 : _f((f & ~F_base_mask) | F_cap), _cap(cap.cap())
115 : _f((f & ~F_base_mask) | F_cap | F_local), _obj(o)
118 void reset(
unsigned flags)
120 _f = (_f & F_replacable) | (flags & ~(F_cap | F_local));
134 friend class Name_space;
141 Entry(Name
const &n, Obj
const &o,
bool dynamic =
false)
142 : _n(n), _o(o), _dynamic(dynamic) {}
144 Name
const &name()
const {
return _n; }
145 Obj
const *obj()
const {
return &_o; }
146 Obj *obj() {
return &_o; }
147 void obj(Obj
const &o) { _o = o; }
149 bool is_placeholder()
const
150 {
return !obj()->is_complete(); }
152 bool is_dynamic()
const {
return _dynamic; }
154 void set(Obj
const &o)
156 obj()->set(o, obj()->flags());
160 void *
operator new (
size_t s);
161 void operator delete(
void *b);
167 typedef Name Key_type;
168 static Key_type
const &key_of(Entry
const *e)
169 {
return e->name(); }
189 L4Re::Util::Dbg
const &_dbg;
190 L4Re::Util::Err
const &_err;
196 Const_iterator begin()
const {
return _tree.
begin(); }
197 Const_iterator end()
const {
return _tree.
end(); }
199 Name_space(L4Re::Util::Dbg
const &dbg, L4Re::Util::Err
const &err)
200 : _dbg(dbg), _err(err)
208 Entry *find(
Name const &name)
const {
return _tree.
find_node(name); }
209 Entry *remove(Name
const &name) {
return _tree.
remove(name); }
210 Entry *find_iter(Name
const &pname)
const
213 _dbg.printf(
"resolve '%.*s': ", name.len(), name.start());
214 Name_space
const *ns =
this;
220 part = name.
head(sep);
224 _dbg.cprintf(
" '%.*s'", part.
len(), part.
start());
225 Entry *o = ns->find(Name(part.
start(), part.
len()));
229 _dbg.cprintf(
": resolution failed: '%.*s' remaining\n",
230 name.len(), name.start());
234 auto const *obj = o->obj()->obj();
235 ns =
dynamic_cast<Name_space
const *
>(obj);
240 name = name.substr(sep + 1);
245 _dbg.cprintf(
": found object: %p (%s)\n",
246 obj, obj ?
typeid(*obj).name() :
"");
254 bool insert(Entry *e) {
return _tree.
insert(e).second; }
256 void dump(
bool rec =
false,
int indent = 0)
const;
339 int insert_entry(
Name const &name,
unsigned flags, Entry **e)
341 Entry *n = find(name);
342 if (n && n->obj()->is_valid())
348 if (n->obj()->is_local())
361 if (!n->obj()->is_replacable())
363 n->obj()->reset(Obj::F_rw);
367 flags &= L4Re::Namespace::Cap_flags;
388 int op_query(L4Re::Namespace::Rights,
394 _dbg.printf(
"query: [%ld] '%.*s'\n", name.
length,
399 =
static_cast<char const*
>(memchr(name.
data,
'/', name.
length));
402 part = sep - name.
data;
406 Entry *n = find(
Name(name.
data, part));
409 else if (!n->obj()->is_valid())
415 if (n->obj()->is_local())
439 memcpy(out_name->data, name.
data + part + 1, name.
length - part - 1);
440 out_name->length = name.
length - part - 1;
443 out_name->length = 0;
450 _dbg.printf(
" result = %lx flgs=%x strg=%d\n",
451 result, flags,
static_cast<int>(n->obj()->is_strong()));
456 int op_register_obj(L4Re::Namespace::Rights,
unsigned flags,
475 flags &= (cap.
data() & 0x3UL) | ~0x3UL;
490 _dbg.printf(
"register: '%.*s' flags=%x\n",
static_cast<int>(name.
length),
496 if (
int r = insert_entry(_name, flags, &n))
507 n->set(Names::Obj(flags & L4Re::Namespace::Cap_flags, src_o));
508 else if (reg_cap.is_valid())
509 n->set(Names::Obj(flags & L4Re::Namespace::Cap_flags, reg_cap));
514 int op_unlink(L4Re::Namespace::Rights,
519 _dbg.printf(
"unlink: [%ld] '%.*s'\n", name.
length,
524 =
static_cast<char const*
>(memchr(name.
data,
'/', name.
length));
527 part = sep - name.
data;
531 Entry *n = find(Name(name.
data, part));
532 if (!n || !n->obj()->is_valid())
535 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.
l4_umword_t data() const noexcept
Return the raw flexpage descriptor.
Send item or return item.
bool id_received() const noexcept
*(Defined for return items only.)* Check if an IPC gate label has been received instead of a mapping.
bool local_id_received() const noexcept
*(Defined for return items only.)* Check if a raw object flexpage has been received instead of a mapp...
bool is_valid() const noexcept
Check if the capability is valid.
bool cap_received() const noexcept
*(Defined for return items only.)* Check if at least one object capability has been mapped for this i...
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 flexpages.
@ L4_CAP_FPAGE_W
Interface specific 'W' right for capability flexpages.
@ L4_CAP_FPAGE_S
Interface specific 'S' right for capability flexpages.
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.