1 /* 2 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de> 3 * economic rights: Technische Universität Dresden (Germany) 4 * 5 * This file is part of TUD:OS and distributed under the terms of the 6 * GNU General Public License 2. 7 * Please see the COPYING-GPL-2 file for details. 8 */ 9 #pragma once 10 11 #include <l4/cxx/avl_tree> 12 #include <l4/cxx/std_ops> 13 #include <l4/cxx/unique_ptr> 14 #include <l4/sys/cxx/ipc_epiface> 15 16 #include <l4/sys/capability> 17 #include <l4/re/namespace> 18 19 #include "server_obj.h" 20 #include "quota.h" 21 #include "obj_reg.h" 22 #include <l4/cxx/string> 23 24 #include <cstring> 25 #include <cstdlib> 26 27 28 namespace Moe { 29 30 class Name_space; 31 32 class Entry 33 : public cxx::Avl_tree_node, 34 public Q_object 35 { 36 public: 37 friend class Name_space; 38 typedef cxx::String Name; 39 40 enum Flags 41 { 42 F_rw = L4Re::Namespace::Rw, 43 F_strong = L4Re::Namespace::Strong, 44 45 F_trusted = L4Re::Namespace::Trusted, 46 47 F_rights_mask = F_rw | F_strong | F_trusted, 48 49 F_cap = 0x100, 50 F_local = 0x200, 51 F_allocated = 0x400, 52 F_static = 0x800, 53 F_base_mask = 0xf00, 54 }; 55 56 private: 57 typedef cxx::Weak_ref<Moe::Server_object> Weak_ref; 58 Name _name; 59 unsigned _flags; 60 union 61 { 62 l4_cap_idx_t _cap; 63 Weak_ref _obj; 64 }; 65 66 void set(L4::Cap<void> cap); 67 void set(Moe::Server_object *o); 68 69 public: Entry(char const * name,unsigned flags)70 Entry(char const *name, unsigned flags) 71 : Entry(name, strlen(name), flags) 72 {} 73 Entry(char const * name,unsigned long len,unsigned flags)74 Entry(char const *name, unsigned long len, unsigned flags) 75 : _flags(flags) 76 { 77 auto namecpy = qalloc()->alloc<char>(len + 1); 78 memcpy(namecpy, name, len); 79 namecpy[len] = 0; 80 _name = Name(namecpy, len); 81 } 82 83 ~Entry(); 84 name()85 Name const &name() const 86 { return _name; } 87 is_dynamic()88 bool is_dynamic() const 89 { return !(_flags & F_static); } 90 is_valid()91 bool is_valid() const 92 { return (_flags & F_cap) && !(is_local() && !_obj); } 93 is_local()94 bool is_local() const 95 { return _flags & F_local; } 96 is_rw()97 bool is_rw() const 98 { return (_flags & F_rw) == F_rw; } 99 is_strong()100 bool is_strong() const 101 { return _flags & F_strong; } 102 flags()103 unsigned flags() const 104 { return _flags; } 105 cap()106 L4::Cap<void> cap() const 107 { 108 if (!is_local()) 109 return L4::Cap<void>(_cap); 110 if (!_obj) 111 return L4::Cap<void>::Invalid; 112 return _obj.get()->obj_cap(); 113 } 114 obj()115 L4::Epiface *obj() const 116 { return _obj.get(); } 117 118 void set_epiface(l4_umword_t data); 119 void set_cap_copy(L4::Cap<L4::Kobject> cap); 120 }; 121 122 struct Entry_get_key 123 { 124 typedef Entry::Name Key_type; key_ofEntry_get_key125 static Key_type const &key_of(Entry const *e) 126 { return e->name(); } 127 }; 128 129 struct Entry_key_compare 130 { operatorEntry_key_compare131 bool operator () (Entry::Name const &l, Entry::Name const &r) const 132 { 133 unsigned long len = cxx::min(l.len(), r.len()); 134 int v = memcmp(l.start(), r.start(), len); 135 return v < 0 || (v == 0 && l.len() < r.len()); 136 } 137 }; 138 139 140 class Name_space : 141 public L4::Epiface_t<Name_space, L4Re::Namespace, Moe::Server_object>, 142 public Q_object 143 { 144 friend class Entry; 145 typedef cxx::Avl_tree<Entry, Entry_get_key, Entry_key_compare> Tree; 146 typedef L4::Ipc::Array_in_buf<char, unsigned long> Name_buffer; 147 Tree _tree; 148 find(Entry::Name const & name)149 Entry *find(Entry::Name const &name) const 150 { return _tree.find_node(name); } 151 remove(Entry::Name const & name)152 Entry *remove(Entry::Name const &name) 153 { return _tree.remove(name); } 154 insert(Entry * e)155 bool insert(Entry *e) 156 { return _tree.insert(e).second; } 157 158 Entry *check_existing(Name_buffer const &name, unsigned flags); 159 create_entry(Name_buffer const & name,unsigned flags)160 Entry *create_entry(Name_buffer const &name, unsigned flags) 161 { 162 return qalloc()->make_obj<Entry>(name.data, name.length, 163 flags & Entry::F_rights_mask); 164 } 165 public: 166 typedef Tree::Const_iterator Const_iterator; 167 168 virtual ~Name_space(); 169 begin()170 Const_iterator begin() const { return _tree.begin(); } end()171 Const_iterator end() const { return _tree.end(); } 172 173 // server interface ------------------------------------------ 174 int op_query(L4Re::Namespace::Rights, 175 Name_buffer const &name, 176 L4::Ipc::Snd_fpage &snd_cap, L4::Ipc::Opt<L4::Opcode> &, 177 L4::Ipc::Opt<L4::Ipc::Array_ref<char, unsigned long> > &out_name); 178 179 int op_register_obj(L4Re::Namespace::Rights, unsigned flags, 180 Name_buffer const &name, L4::Ipc::Snd_fpage &cap); 181 182 int op_unlink(L4Re::Namespace::Rights r, Name_buffer const &name); 183 184 // internally used to register bootfs files, name spaces... 185 template <typename T> register_obj(Entry::Name const & name,unsigned long flags,T cap)186 int register_obj(Entry::Name const &name, unsigned long flags, T cap) 187 { 188 cxx::unique_ptr<Entry> n(qalloc()->make_obj<Entry>(name.start(), name.len(), 189 flags | Entry::F_static)); 190 n->set(cap); 191 if (!insert(n.get())) 192 return -L4_EEXIST; 193 194 n.release(); 195 return 0; 196 } 197 198 Entry *find_iter(Entry::Name const &name) const; 199 200 void dump(bool rec = false, int indent = 0) const; 201 }; 202 203 } 204 205 Moe::Name_space *root_name_space(); 206 207