[kernel] Allow handle lists in syscall definitions

This change allows for parameters in definition files to have the "list"
option while also needing the handle verification. The verify function
will now iterate through the list checking capabilities and types on
every valid handle in the list.
This commit is contained in:
Justin C. Miller
2023-08-06 18:50:29 -07:00
parent 77590b31a6
commit a0f91ed0fd
2 changed files with 54 additions and 50 deletions

View File

@@ -22,7 +22,6 @@ for obj in syscalls.exposes:
]]]*/
//[[[end]]]
/*[[[cog code generation
cog.outl(f'constexpr size_t syscall_count = {len(syscalls.methods)};')
]]]*/
@@ -115,25 +114,39 @@ for id, scope, method in syscalls.methods:
scope.cname,
"self",
get_caps(method.options, scope),
False))
False,
None))
for param in method.params:
needs_obj = param.type.needs_object(param.options)
needs_handle = ("handle" in param.options) or needs_obj
argnames = []
for type, suffix in param.type.c_names(param.options):
arg = f"{param.name}{suffix}"
argnames.append(arg)
argdefs.append((type, arg))
for type, suffix in param.type.cxx_names(param.options):
is_list = "list" in param.options
count_arg = None
if is_list:
count_arg = argnames[1]
if param.refparam:
count_arg = "*" + count_arg
cxx_names = param.type.cxx_names(param.options)
for i in range(len(cxx_names)):
type, suffix = cxx_names[i]
arg = f"{param.name}{suffix}"
if needs_handle:
if needs_handle and i == 0:
handles.append((
param.type.object.cname,
arg,
get_caps(param.options, param.type.object),
param.optional != "required"))
param.optional != "required",
count_arg))
if needs_obj:
objparams.append((type, arg))
@@ -148,8 +161,9 @@ for id, scope, method in syscalls.methods:
handles.append((
f"obj::{param.type.object.cname}",
arg,
get_caps(param.options, param.type.object,
param.optional != "required")))
get_caps(param.options, param.type.object),
param.optional != "required",
count_arg))
if param.refparam:
subs = param.type.c_names(param.options)
@@ -184,16 +198,30 @@ for id, scope, method in syscalls.methods:
if handles:
cog.outl(f" j6_status_t res;")
for type, arg, caps, optional in handles:
for type, arg, caps, optional, count_arg in handles:
capsval = "0"
if caps:
capsval = " | ".join(caps)
optstr = (optional and "true") or "false"
cog.outl(f" obj::{type} *{arg}_obj = nullptr;")
cog.outl(f" res = get_handle<typename obj::{type}>({arg}, {capsval}, {arg}_obj, {optstr});")
cog.outl(f" if (res != j6_status_ok) return res;")
handle_arg = arg
if count_arg is not None:
cog.outl(f" for(unsigned i = 0; i < {count_arg}; ++i) {{")
handle_arg = arg + "[i]"
optional = True
else:
cog.outl( " do {")
optstr = (optional and "true") or "false"
cog.outl(f" res = get_handle<typename obj::{type}>({handle_arg}, {capsval}, {arg}_obj, {optstr});")
cog.outl(f" if (res != j6_status_ok) return res;")
if count_arg is not None:
cog.outl( " }")
else:
cog.outl( " } while (0);")
cog.outl()
if "noreturn" in method.options:
@@ -208,8 +236,20 @@ for id, scope, method in syscalls.methods:
cog.outl(f""" _retval = {name}({", ".join(args)});""")
cog.outl(" }\n")
for type, arg, caps, optional in handles:
cog.outl(f" release_handle({arg});")
for type, arg, caps, optional, count_arg in handles:
handle_arg = arg
if count_arg is not None:
cog.outl(f" for(unsigned i = 0; i < {count_arg}; ++i) {{")
handle_arg = arg + "[i]"
optional = True
else:
cog.outl( " do {")
cog.outl(f" release_handle({handle_arg});")
if count_arg is not None:
cog.outl( " }")
else:
cog.outl( " } while (0);")
cog.outl(f""" return _retval;""")

View File

@@ -1,36 +0,0 @@
SYSCALL(0x00, system_log, const char *)
SYSCALL(0x01, system_noop, void)
SYSCALL(0x02, system_get_log, j6_handle_t, void *, size_t *)
SYSCALL(0x03, system_bind_irq, j6_handle_t, j6_handle_t, unsigned)
SYSCALL(0x04, system_map_phys, j6_handle_t, j6_handle_t *, uintptr_t, size_t, uint32_t)
SYSCALL(0x08, object_koid, j6_handle_t, j6_koid_t *)
SYSCALL(0x09, object_wait, j6_handle_t, j6_signal_t, j6_signal_t *)
SYSCALL(0x0a, object_wait_many, j6_handle_t *, uint32_t, j6_signal_t, j6_handle_t *, j6_signal_t *)
SYSCALL(0x0b, object_signal, j6_handle_t, j6_signal_t)
SYSCALL(0x0c, object_close, j6_handle_t)
SYSCALL(0x10, process_create, j6_handle_t *)
SYSCALL(0x11, process_start, j6_handle_t, uintptr_t, j6_handle_t *, size_t)
SYSCALL(0x11, process_kill, j6_handle_t)
SYSCALL(0x17, process_exit, int32_t)
SYSCALL(0x18, thread_create, void *, j6_handle_t *)
SYSCALL(0x19, thread_exit, int32_t)
SYSCALL(0x1a, thread_pause, void)
SYSCALL(0x1b, thread_sleep, uint64_t)
SYSCALL(0x20, channel_create, j6_handle_t *)
SYSCALL(0x21, channel_send, j6_handle_t, size_t *, void *)
SYSCALL(0x22, channel_receive, j6_handle_t, size_t *, void *)
SYSCALL(0x28, endpoint_create, j6_handle_t *)
SYSCALL(0x29, endpoint_send, j6_handle_t, j6_tag_t, size_t, void *)
SYSCALL(0x2a, endpoint_receive, j6_handle_t, j6_tag_t *, size_t *, void *)
SYSCALL(0x2b, endpoint_sendrecv, j6_handle_t, j6_tag_t *, size_t *, void *)
SYSCALL(0x30, vma_create, j6_handle_t *, size_t, uint32_t)
SYSCALL(0x31, vma_create_map, j6_handle_t *, size_t, uintptr_t, uint32_t)
SYSCALL(0x32, vma_map, j6_handle_t, j6_handle_t, uintptr_t)
SYSCALL(0x33, vma_unmap, j6_handle_t, j6_handle_t)
SYSCALL(0x34, vma_resize, j6_handle_t, size_t *)