[kernel] Let objects inherit caps from superclasses
The main point of this change is to allow "global" capabilities defined on the base object type. The example here is the clone capability on all objects, which governs the ability to clone a handle. Related changes in this commit: - Renamed `kobject` to `object` as far as the syscall interface is concerned. `kobject` is the cname, but j6_cap_kobject_clone feels clunky. - The above change made me realize that the "object <type>" syntax for specifying object references was also clunky, so now it's "ref <type>" - Having to add `.object` on everywhere to access objects in interface.exposes or object.super was cumbersome, so those properties now return object types directly, instead of ObjectRef. - syscall_verify.cpp.cog now generates code to check capabilities on handles if they're specified in the definition, even when not passing an object to the implementation function.
This commit is contained in:
@@ -17,7 +17,7 @@ ctx.parse("syscalls.def")
|
||||
syscalls = ctx.interfaces["syscalls"]
|
||||
|
||||
for obj in syscalls.exposes:
|
||||
cog.outl(f'#include "objects/{obj.object.cname}.h"')
|
||||
cog.outl(f'#include "objects/{obj.cname}.h"')
|
||||
]]]*/
|
||||
//[[[end]]]
|
||||
|
||||
@@ -51,7 +51,9 @@ for id, scope, method in syscalls.methods:
|
||||
argdefs = []
|
||||
cxxargdefs = []
|
||||
refparams = []
|
||||
|
||||
handles = []
|
||||
objparams = []
|
||||
|
||||
if method.constructor:
|
||||
argdefs.append("j6_handle_t *self")
|
||||
@@ -63,11 +65,10 @@ for id, scope, method in syscalls.methods:
|
||||
argdefs.append("j6_handle_t self")
|
||||
cxxargdefs.append(f"obj::{scope.cname} *self")
|
||||
args.append("self_obj")
|
||||
handles.append((
|
||||
f"obj::{scope.cname} *",
|
||||
"self",
|
||||
"self_obj",
|
||||
get_caps(method.options, scope)))
|
||||
|
||||
type = f"obj::{scope.cname} *"
|
||||
handles.append((type, "self", get_caps(method.options, scope)))
|
||||
objparams.append((type, "self"))
|
||||
|
||||
for param in method.params:
|
||||
needs_obj = param.type.needs_object(param.options)
|
||||
@@ -81,12 +82,17 @@ for id, scope, method in syscalls.methods:
|
||||
cxxargdefs.append(f"{type} {arg}")
|
||||
|
||||
if needs_obj:
|
||||
oarg = f"{arg}_obj"
|
||||
handles.append((type, arg, oarg, get_caps(param.options, param.type.object)))
|
||||
args.append(oarg)
|
||||
handles.append((type, arg, get_caps(param.options, param.type.object)))
|
||||
objparams.append((type, arg))
|
||||
args.append(f"{arg}_obj")
|
||||
break
|
||||
else:
|
||||
args.append(arg)
|
||||
|
||||
if not needs_obj and param.caps:
|
||||
handles.append((
|
||||
f"obj::{param.type.object.cname}",
|
||||
arg, get_caps(param.options, param.type.object)))
|
||||
|
||||
if param.refparam:
|
||||
subs = param.type.c_names(param.options)
|
||||
@@ -103,20 +109,24 @@ for id, scope, method in syscalls.methods:
|
||||
cog.outl( " return j6_err_invalid_arg;")
|
||||
cog.outl()
|
||||
|
||||
for type, inarg, outarg, caps in handles:
|
||||
for type, arg, caps in handles:
|
||||
if type.endswith('*'):
|
||||
type = type[:-1].strip()
|
||||
|
||||
cog.outl(f" obj::handle *{inarg}_handle = get_handle<typename {type}>({inarg});")
|
||||
cog.outl(f" if (!{inarg}_handle) return j6_err_invalid_arg;")
|
||||
cog.outl(f" obj::handle *{arg}_handle = get_handle<typename {type}>({arg});")
|
||||
cog.outl(f" if (!{arg}_handle) return j6_err_invalid_arg;")
|
||||
|
||||
if caps:
|
||||
allcaps = " | ".join(caps)
|
||||
cog.outl(f" j6_cap_t {inarg}_caps_req = {allcaps};")
|
||||
cog.outl(f" if (!{inarg}_handle->has_cap({inarg}_caps_req)) return j6_err_denied;")
|
||||
cog.outl(f" j6_cap_t {arg}_caps_req = {allcaps};")
|
||||
cog.outl(f" if (!{arg}_handle->has_cap({arg}_caps_req)) return j6_err_denied;")
|
||||
|
||||
cog.outl(f" {type} *{outarg} = {inarg}_handle->as<typename {type}>();")
|
||||
cog.outl(f" if (!{outarg}) return j6_err_invalid_arg;")
|
||||
for type, arg in objparams:
|
||||
if type.endswith('*'):
|
||||
type = type[:-1].strip()
|
||||
|
||||
cog.outl(f" {type} *{arg}_obj = {arg}_handle->as<typename {type}>();")
|
||||
cog.outl(f" if (!{arg}_obj) return j6_err_invalid_arg;")
|
||||
cog.outl()
|
||||
|
||||
cog.outl(f""" return {name}({", ".join(args)});""")
|
||||
|
||||
@@ -13,14 +13,14 @@ using namespace obj;
|
||||
namespace syscalls {
|
||||
|
||||
j6_status_t
|
||||
kobject_koid(kobject *self, j6_koid_t *koid)
|
||||
object_koid(kobject *self, j6_koid_t *koid)
|
||||
{
|
||||
*koid = self->koid();
|
||||
return j6_status_ok;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
kobject_wait(kobject *self, j6_signal_t mask, j6_signal_t *sigs)
|
||||
object_wait(kobject *self, j6_signal_t mask, j6_signal_t *sigs)
|
||||
{
|
||||
j6_signal_t current = self->signals();
|
||||
if ((current & mask) != 0) {
|
||||
@@ -40,7 +40,7 @@ kobject_wait(kobject *self, j6_signal_t mask, j6_signal_t *sigs)
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
kobject_wait_many(j6_handle_t * handles, size_t handles_count, uint64_t mask, j6_handle_t * woken, uint64_t * signals)
|
||||
object_wait_many(j6_handle_t * handles, size_t handles_count, uint64_t mask, j6_handle_t * woken, uint64_t * signals)
|
||||
{
|
||||
util::vector<kobject*> objects {uint32_t(handles_count)};
|
||||
|
||||
@@ -90,7 +90,7 @@ kobject_wait_many(j6_handle_t * handles, size_t handles_count, uint64_t mask, j6
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
kobject_signal(kobject *self, j6_signal_t signals)
|
||||
object_signal(kobject *self, j6_signal_t signals)
|
||||
{
|
||||
if ((signals & j6_signal_user_mask) != signals)
|
||||
return j6_err_invalid_arg;
|
||||
@@ -100,7 +100,7 @@ kobject_signal(kobject *self, j6_signal_t signals)
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
kobject_close(kobject *self)
|
||||
object_close(kobject *self)
|
||||
{
|
||||
self->close();
|
||||
return j6_status_ok;
|
||||
|
||||
@@ -44,7 +44,7 @@ j6_status_t
|
||||
process_give_handle(process *self, j6_handle_t target, j6_handle_t *received)
|
||||
{
|
||||
handle *target_handle = get_handle<kobject>(target);
|
||||
j6_handle_t out = self->add_handle(target_handle->object, target_handle->caps);
|
||||
j6_handle_t out = self->add_handle(target_handle->object, target_handle->caps());
|
||||
|
||||
if (received)
|
||||
*received = out;
|
||||
|
||||
@@ -13,12 +13,15 @@ syscalls = ctx.interfaces["syscalls"]
|
||||
|
||||
for obj in syscalls.exposes:
|
||||
i = 0
|
||||
for cap in obj.object.caps:
|
||||
name = f"j6_cap_{obj.object.name}_{cap}"
|
||||
if obj.super:
|
||||
i = len(obj.super.caps)
|
||||
|
||||
for cap in obj.caps:
|
||||
name = f"j6_cap_{obj.name}_{cap}"
|
||||
cog.outl(f"#define {name:<30} (1 << {i})")
|
||||
i += 1
|
||||
|
||||
name = f"j6_cap_{obj.object.name}_all"
|
||||
name = f"j6_cap_{obj.name}_all"
|
||||
cog.outl(f"#define {name:<30} ((1<<{i})-1)")
|
||||
cog.outl()
|
||||
]]]*/
|
||||
|
||||
@@ -96,7 +96,7 @@ log_pump_proc()
|
||||
|
||||
if (size == 0) {
|
||||
j6_signal_t sigs = 0;
|
||||
j6_kobject_wait(__handle_sys, j6_signal_system_has_log, &sigs);
|
||||
j6_object_wait(__handle_sys, j6_signal_system_has_log, &sigs);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user