1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #pragma once
11 
12 #include <lua.h>
13 #include <lauxlib.h>
14 #include <lualib.h>
15 
16 #include <l4/re/util/cap_alloc>
17 
18 #if 0
19 #include <cstdio>
20 #include <typeinfo>
21 #endif
22 
23 #include "lua.h"
24 
25 namespace Lua {
26 
27 static char const *const CAP_TYPE = "L4::Cap";
28 static char const *const CAST_TABLE = "_CAP_TYPES";
29 void set_cap_metatable(lua_State *l);
30 
31 #define L4_LUA_DECLARE_KOBJECT(_cap_type)                          \
32   private:                                                         \
33     void operator = (_cap_type const &);                           \
34     _cap_type(_cap_type const &) = default;                        \
35   public:                                                          \
36     virtual _cap_type *clone(lua_State *l) const                   \
37     {                                                              \
38       _cap_type *c = new (lua_newuserdata(l, sizeof(_cap_type)))   \
39         _cap_type(*this);                                          \
40       set_cap_metatable(l);                                        \
41       return c;                                                    \
42     }                                                              \
43   private:
44 
45 
46 class Cap
47 {
48   L4_LUA_DECLARE_KOBJECT(Cap)
49 
50 public:
51   template< typename T >
52   struct C : public L4Re::Util::Ref_cap<T> {};
53 
54   template< typename T >
cap()55   typename C<T>::Cap cap() const
56   { return L4::cap_cast<T>(_c); }
57 
fpage()58   l4_fpage_t fpage() const
59   { return _c.fpage(_rights & L4_CAP_FPAGE_RWSD); }
60 
ext_rights()61   unsigned long ext_rights() const
62   { return _rights & 0xf0; }
63 
flags()64   unsigned flags() const { return _flags; }
65 
all_rights()66   unsigned all_rights() const
67   { return _rights; }
68 
rights()69   L4_cap_fpage_rights rights() const
70   { return L4_cap_fpage_rights(_rights & 0xf); }
71 
72   Cap(C<void>::Cap c = C<void>::Cap(), unsigned flags = 0)
_c(c)73   : _c(c), _rights(L4_FPAGE_RO), _flags(flags) {}
74 
75   template< typename T >
set(typename C<T>::Cap c)76   void set(typename C<T>::Cap c)
77   { _c = c; }
78 
set(C<void>::Cap c)79   void set(C<void>::Cap c)
80   { _c = c; }
81 
trim_rights(L4_cap_fpage_rights keep)82   void trim_rights(L4_cap_fpage_rights keep)
83   { _rights = _rights & (keep | (~0U << 4)); }
84 
set_flags(unsigned flags)85   void set_flags(unsigned flags)
86   { _flags |= flags; }
87 
set_rights(unsigned char r)88   void set_rights(unsigned char r)
89   { _rights = r | L4_FPAGE_RO; }
90 
91   virtual ~Cap();
92 
93   int index(lua_State *l) const;
94   int get_method_table(lua_State *l, char const *typ) const;
95 
new(size_t,void * p)96   void *operator new (size_t, void *p) throw() { return p; }
delete(void *)97   void operator delete (void *) {}
98 
assign(Cap * o)99   void assign(Cap *o)
100   {
101     if (o == this)
102       return;
103 
104     _c = o->_c;
105     _rights = o->_rights;
106   }
107 
108 public:
109   typedef void Register_methods(lua_State *l);
110   static void register_methods(lua_State *l);
111   static void create_class(lua_State *l, Register_methods *rm,
112                            char const *type);
113   static void get_class(lua_State *l);
114 
115 
add_class_metatable(lua_State * l)116   static void add_class_metatable(lua_State *l)
117   {
118     lua_newtable(l);
119     get_class(l);
120     lua_setfield(l, -2, "__index");
121     lua_setmetatable(l, -2);
122   }
123 
124   bool find_dynamic_type(lua_State *) const;
125 
126 private:
127   C<void>::Cap _c;
128   unsigned _rights : 16;
129   unsigned _flags  : 16;
130 };
131 
132 
133 Cap *
134 push_new_cap(lua_State *l, bool void_cap = false);
135 
136 Cap *
137 push_void_cap(lua_State *l);
138 
139 void
140 register_cap(lua_State *l, char const *name, L4::Cap<void> i, long proto = 0);
141 
142 inline
143 Cap *
check_cap(lua_State * l,int idx)144 check_cap(lua_State *l, int idx)
145 { return (Cap*)luaL_checkudata(l, idx, CAP_TYPE); }
146 
147 void get_cap_cast_table(lua_State *l);
148 
149 template< typename C, typename Register_func >
150 void
register_cap_type(lua_State * l,Register_func r)151 register_cap_type(lua_State *l, Register_func r)
152 {
153   get_cap_cast_table(l);
154   L4::Type_info const *m = L4::kobject_typeid<C>();
155   char const *class_name = m->name() ? m->name() : "<unk-class>";
156   Cap::create_class(l, r, class_name);
157 
158   if (0)
159     printf("register new cap type %s: '%s'\n", typeid(C).name(), class_name);
160   long proto = m->proto();
161   if (proto)
162     {
163       lua_pushinteger(l, proto);
164       lua_pushvalue(l, -2);
165       lua_settable(l, -4);
166     }
167 
168   lua_setfield(l, -2, class_name);
169   lua_pop(l, 1);
170 }
171 
172 template< typename KO, typename Lua_model >
173 class Cap_type_lib : public Lib
174 {
175 public:
Cap_type_lib()176   Cap_type_lib() : Lib(P_cap_type) {}
init(lua_State * l)177   void init(lua_State *l)
178   { register_cap_type<KO>(l, Lua_model::register_methods); }
179 };
180 
181 void init_lua_cap(lua_State *l);
182 
183 }
184 
185 
186