258 |
|
|
259 |
/* Operations on capability classes. */ |
/* Operations on capability classes. */ |
260 |
|
|
261 |
/* Create a new capability class for objects with the size SIZE, |
/* Create a new capability class for objects with the size SIZE and |
262 |
including the struct hurd_cap_obj, which has to be placed at the |
alignment requirement ALIGNMENT. |
|
beginning of each capability object. |
|
263 |
|
|
264 |
The callback OBJ_INIT is used whenever a capability object in this |
The callback OBJ_INIT is used whenever a capability object in this |
265 |
class is created. The callback OBJ_REINIT is used whenever a |
class is created. The callback OBJ_REINIT is used whenever a |
275 |
|
|
276 |
The new capability class is returned in R_CLASS. If the creation |
The new capability class is returned in R_CLASS. If the creation |
277 |
fails, an error value will be returned. */ |
fails, an error value will be returned. */ |
278 |
error_t hurd_cap_class_create (size_t size, size_t alignment, |
error_t hurd_cap_class_create_untyped (size_t size, size_t alignment, |
279 |
hurd_cap_obj_init_t obj_init, |
hurd_cap_obj_init_t obj_init, |
280 |
hurd_cap_obj_alloc_t obj_alloc, |
hurd_cap_obj_alloc_t obj_alloc, |
281 |
hurd_cap_obj_reinit_t obj_reinit, |
hurd_cap_obj_reinit_t obj_reinit, |
282 |
hurd_cap_obj_destroy_t obj_destroy, |
hurd_cap_obj_destroy_t obj_destroy, |
283 |
hurd_cap_class_demuxer_t demuxer, |
hurd_cap_class_demuxer_t demuxer, |
284 |
hurd_cap_class_t *r_class); |
hurd_cap_class_t *r_class); |
285 |
|
|
286 |
|
/* Define a capability class for the pointer type TYPE. */ |
287 |
|
#define hurd_cap_class_create(type,init,alloc,reinit,destroy,demuxer,r_class) \ |
288 |
|
hurd_cap_class_create_untyped (({ type t; sizeof (*t); }), \ |
289 |
|
({ type t; __alignof__ (*t); }), \ |
290 |
|
init, alloc, reinit, destroy, demuxer, \ |
291 |
|
r_class); |
292 |
|
|
293 |
|
|
294 |
/* Destroy the capability class CAP_CLASS and release all associated |
/* Destroy the capability class CAP_CLASS and release all associated |
301 |
|
|
302 |
/* Same as hurd_cap_class_create, but doesn't allocate the storage for |
/* Same as hurd_cap_class_create, but doesn't allocate the storage for |
303 |
CAP_CLASS. Instead, you have to provide it. */ |
CAP_CLASS. Instead, you have to provide it. */ |
304 |
error_t hurd_cap_class_init (hurd_cap_class_t cap_class, |
error_t hurd_cap_class_init_untyped (hurd_cap_class_t cap_class, |
305 |
size_t size, size_t alignment, |
size_t size, size_t alignment, |
306 |
hurd_cap_obj_init_t obj_init, |
hurd_cap_obj_init_t obj_init, |
307 |
hurd_cap_obj_alloc_t obj_alloc, |
hurd_cap_obj_alloc_t obj_alloc, |
308 |
hurd_cap_obj_reinit_t obj_reinit, |
hurd_cap_obj_reinit_t obj_reinit, |
309 |
hurd_cap_obj_destroy_t obj_destroy, |
hurd_cap_obj_destroy_t obj_destroy, |
310 |
hurd_cap_class_demuxer_t demuxer); |
hurd_cap_class_demuxer_t demuxer); |
311 |
|
|
312 |
|
/* Define a capability class for the pointer type TYPE. */ |
313 |
|
#define hurd_cap_class_init(cclass,type,init,alloc,reinit,destroy,demuxer) \ |
314 |
|
hurd_cap_class_init_untyped (cclass, ({ type t; sizeof (*t); }), \ |
315 |
|
({ type t; __alignof__ (*t); }), \ |
316 |
|
init, alloc, reinit, destroy, demuxer); |
317 |
|
|
318 |
|
|
319 |
/* Destroy the capability class CAP_CLASS and release all associated |
/* Destroy the capability class CAP_CLASS and release all associated |
333 |
hurd_cap_obj_t *r_obj); |
hurd_cap_obj_t *r_obj); |
334 |
|
|
335 |
|
|
336 |
|
/* Get the size of the header, given the alignment requirement |
337 |
|
ALIGNMENT of the user object following it. */ |
338 |
|
static inline size_t |
339 |
|
__attribute__((__always_inline__)) |
340 |
|
hurd_cap_obj_get_size (size_t alignment) |
341 |
|
{ |
342 |
|
size_t obj_size = sizeof (struct hurd_cap_obj); |
343 |
|
size_t rest = sizeof (struct hurd_cap_obj) % alignment; |
344 |
|
|
345 |
|
if (rest) |
346 |
|
obj_size += alignment - rest; |
347 |
|
|
348 |
|
return obj_size; |
349 |
|
} |
350 |
|
|
351 |
|
|
352 |
|
/* Find the user object of the pointer type TYPE after the capability |
353 |
|
object OBJ. Note that in conjunction with the hurd_cap_obj_to_user |
354 |
|
macro below, all of this can and will be computed at compile time, |
355 |
|
if optimization is enabled. OBJ already fulfills the alignment |
356 |
|
requirement ALIGNMENT. */ |
357 |
|
static inline void * |
358 |
|
__attribute__((__always_inline__)) |
359 |
|
hurd_cap_obj_to_user_untyped (hurd_cap_obj_t obj, size_t alignment) |
360 |
|
{ |
361 |
|
uintptr_t obj_addr = (uintptr_t) obj; |
362 |
|
|
363 |
|
obj_addr += hurd_cap_obj_get_size (alignment); |
364 |
|
|
365 |
|
return (void *) obj_addr; |
366 |
|
} |
367 |
|
|
368 |
|
#define hurd_cap_obj_to_user(type,obj) \ |
369 |
|
((type) hurd_cap_obj_to_user_untyped (obj, ({ type t; __alignof (*t); }))) |
370 |
|
|
371 |
|
|
372 |
|
/* Find the hurd cap object before the user object OBJ of the pointer |
373 |
|
type TYPE. Note that in conjunction with the hurd_cap_obj_from_user |
374 |
|
macro below, all of this can and will be computed at compile time, |
375 |
|
if optimization is enabled. OBJ already fulfills the alignment |
376 |
|
requirement ALIGNMENT. */ |
377 |
|
static inline hurd_cap_obj_t |
378 |
|
__attribute__((__always_inline__)) |
379 |
|
hurd_cap_obj_from_user_untyped (void *obj, size_t alignment) |
380 |
|
{ |
381 |
|
uintptr_t obj_addr = (uintptr_t) obj; |
382 |
|
|
383 |
|
obj_addr -= hurd_cap_obj_get_size (alignment); |
384 |
|
|
385 |
|
return (hurd_cap_obj_t) obj_addr; |
386 |
|
} |
387 |
|
|
388 |
|
#define hurd_cap_obj_from_user(type,obj) \ |
389 |
|
hurd_cap_obj_from_user_untyped (obj, ({ type t; __alignof (*t); })) |
390 |
|
|
391 |
|
|
392 |
/* Inhibit all RPCs on the capability class CAP_CLASS (which must not |
/* Inhibit all RPCs on the capability class CAP_CLASS (which must not |
393 |
be locked). You _must_ follow up with a hurd_cap_class_resume |
be locked). You _must_ follow up with a hurd_cap_class_resume |
394 |
operation, and hold at least one reference to the object |
operation, and hold at least one reference to the object |
402 |
|
|
403 |
/* Operations on capability objects. */ |
/* Operations on capability objects. */ |
404 |
|
|
405 |
/* Lock the object OBJ, which must be locked. */ |
/* Lock the object OBJ. */ |
406 |
static inline void |
static inline void |
407 |
hurd_cap_obj_lock (hurd_cap_obj_t obj) |
hurd_cap_obj_lock (hurd_cap_obj_t obj) |
408 |
{ |
{ |