[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:
Justin C. Miller
2022-01-17 23:23:04 -08:00
parent e0246df26b
commit 1d30322820
50 changed files with 492 additions and 300 deletions

View File

@@ -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")
]]]*/