[kernel] Pass objects not handles to syscall impls
This commit contains a couple large, interdependent changes: - In preparation for capability checking, the _syscall_verify_* functions now load most handles passed in, and verify that they exist and are of the correct type. Lists and out-handles are not converted to objects. - Also in preparation for capability checking, the internal representation of handles has changed. j6_handle_t is now 32 bits, and a new j6_cap_t (also 32 bits) is added. Handles of a process are now a util::map<j6_handle_t, handle> where handle is a new struct containing the id, capabilities, and object pointer. - The kernel object definition DSL gained a few changes to support auto generating the handle -> object conversion in the _syscall_verify_* functions, mostly knowing the object type, and an optional "cname" attribute on objects where their names differ from C++ code. (Specifically vma/vm_area) - Kernel object code and other code under kernel/objects is now in a new obj:: namespace, because fuck you <cstdlib> for putting "system" in the global namespace. Why even have that header then? - Kernel object types constructed with the construct_handle helper now have a creation_caps static member to declare what capabilities a newly created object's handle should have.
This commit is contained in:
@@ -4,6 +4,21 @@
|
||||
#include <arch/memory.h>
|
||||
#include <j6/errors.h>
|
||||
#include <j6/types.h>
|
||||
#include <util/counted.h>
|
||||
|
||||
#include "syscalls/helpers.h"
|
||||
|
||||
/*[[[cog code generation
|
||||
from definitions.context import Context
|
||||
|
||||
ctx = Context(definitions_path)
|
||||
ctx.parse("syscalls.def")
|
||||
syscalls = ctx.interfaces["syscalls"]
|
||||
|
||||
for obj in syscalls.exposes:
|
||||
cog.outl(f'#include "objects/{obj.object.cname}.h"')
|
||||
]]]*/
|
||||
//[[[end]]]
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
@@ -16,13 +31,9 @@ namespace {
|
||||
|
||||
namespace syscalls {
|
||||
|
||||
using util::buffer;
|
||||
|
||||
/*[[[cog code generation
|
||||
from definitions.context import Context
|
||||
|
||||
ctx = Context(definitions_path)
|
||||
ctx.parse("syscalls.def")
|
||||
syscalls = ctx.interfaces["syscalls"]
|
||||
|
||||
cbool = {True: "true", False: "false"}
|
||||
|
||||
for id, scope, method in syscalls.methods:
|
||||
@@ -33,21 +44,40 @@ for id, scope, method in syscalls.methods:
|
||||
|
||||
args = []
|
||||
argdefs = []
|
||||
cxxargdefs = []
|
||||
refparams = []
|
||||
handles = []
|
||||
|
||||
if method.constructor:
|
||||
argdefs.append("j6_handle_t *handle")
|
||||
args.append("handle")
|
||||
refparams.append(("handle", False))
|
||||
argdefs.append("j6_handle_t *self")
|
||||
cxxargdefs.append("j6_handle_t *self")
|
||||
args.append("self")
|
||||
refparams.append(("self", False))
|
||||
|
||||
elif not method.static:
|
||||
argdefs.append("j6_handle_t handle")
|
||||
args.append("handle")
|
||||
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"))
|
||||
|
||||
for param in method.params:
|
||||
needs_obj = param.type.needs_object(param.options)
|
||||
|
||||
for type, suffix in param.type.c_names(param.options):
|
||||
arg = f"{param.name}{suffix}"
|
||||
argdefs.append(f"{type} {arg}")
|
||||
args.append(arg)
|
||||
|
||||
for type, suffix in param.type.cxx_names(param.options):
|
||||
arg = f"{param.name}{suffix}"
|
||||
cxxargdefs.append(f"{type} {arg}")
|
||||
|
||||
if needs_obj:
|
||||
oarg = f"{arg}_obj"
|
||||
handles.append((type, arg, oarg))
|
||||
args.append(oarg)
|
||||
else:
|
||||
args.append(arg)
|
||||
|
||||
|
||||
if param.refparam:
|
||||
subs = param.type.c_names(param.options)
|
||||
@@ -56,7 +86,7 @@ for id, scope, method in syscalls.methods:
|
||||
for sub in subs[1:]:
|
||||
refparams.append((param.name + sub[1], param.optional))
|
||||
|
||||
cog.outl(f"""extern j6_status_t {name} ({", ".join(argdefs)});""")
|
||||
cog.outl(f"""j6_status_t {name} ({", ".join(cxxargdefs)});""")
|
||||
cog.outl(f"""j6_status_t _syscall_verify_{name} ({", ".join(argdefs)}) {{""")
|
||||
|
||||
for pname, optional in refparams:
|
||||
@@ -64,7 +94,17 @@ for id, scope, method in syscalls.methods:
|
||||
cog.outl( " return j6_err_invalid_arg;")
|
||||
cog.outl()
|
||||
|
||||
cog.outl(f""" return syscalls::{name}({", ".join(args)});""")
|
||||
for type, inarg, outarg 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" {type} *{outarg} = {inarg}_handle->as<typename {type}>();")
|
||||
cog.outl(f" if (!{outarg}) return j6_err_invalid_arg;")
|
||||
cog.outl()
|
||||
|
||||
cog.outl(f""" return {name}({", ".join(args)});""")
|
||||
cog.outl("}")
|
||||
cog.outl("\n")
|
||||
]]]*/
|
||||
|
||||
Reference in New Issue
Block a user