mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[kernel] Add automatic verification to syscalls
Since we have a DSL for specifying syscalls, we can create a verificaton method for each syscall that can cover most argument (and eventually capability) verification instead of doing it piecemeal in each syscall implementation, which can be more error-prone. Now a new _syscall_verify_* function exists for every syscall, which calls the real implementation. The syscall table for the syscall handler now maps to these verify functions. Other changes: - Updated the definition grammar to allow options to have a "key:value" style, to eventually support capabilities. - Added an "optional" option for parameters that says a syscall will accept a null value. - Some bonnibel fixes, as definition file changes weren't always properly causing updates in the build dep graph. - The syscall implementation function signatures are no longer exposed in syscall.h. Also, the unused syscall enum has been removed.
This commit is contained in:
@@ -141,6 +141,7 @@ class Module:
|
||||
|
||||
inputs = []
|
||||
parse_deps = []
|
||||
parse_dep = "${module_dir}/.parse_dep.phony"
|
||||
|
||||
for start in self.sources:
|
||||
source = start
|
||||
@@ -148,6 +149,11 @@ class Module:
|
||||
while source and source.action:
|
||||
output = source.output
|
||||
|
||||
if source.action.parse_deps:
|
||||
oodeps = [parse_dep]
|
||||
else:
|
||||
oodeps = []
|
||||
|
||||
if source.action.rule:
|
||||
build.newline()
|
||||
build.build(
|
||||
@@ -156,6 +162,7 @@ class Module:
|
||||
inputs = source.input,
|
||||
implicit = list(map(resolve, source.deps)) +
|
||||
list(source.action.deps),
|
||||
order_only = oodeps,
|
||||
variables = {"name": source.name},
|
||||
)
|
||||
|
||||
@@ -167,7 +174,6 @@ class Module:
|
||||
|
||||
source = output
|
||||
|
||||
parse_dep = "${module_dir}/.parse_dep.phony"
|
||||
build.newline()
|
||||
build.build(
|
||||
rule = "touch",
|
||||
@@ -183,7 +189,7 @@ class Module:
|
||||
rule = self.kind,
|
||||
outputs = output,
|
||||
inputs = inputs,
|
||||
implicit = [parse_dep] + libs,
|
||||
implicit = libs,
|
||||
order_only = order_only,
|
||||
)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ class Action:
|
||||
implicit = property(lambda self: False)
|
||||
rule = property(lambda self: None)
|
||||
deps = property(lambda self: tuple())
|
||||
parse_deps = property(lambda self: False)
|
||||
|
||||
def __init__(self, name):
|
||||
self.__name = name
|
||||
@@ -14,6 +15,7 @@ class Action:
|
||||
class Compile(Action):
|
||||
rule = property(lambda self: f'compile_{self.name}')
|
||||
deps = property(lambda self: ("${module_dir}/.parse_dep.phony",))
|
||||
parse_deps = property(lambda self: True)
|
||||
|
||||
def __init__(self, name, suffix = ".o"):
|
||||
super().__init__(name)
|
||||
|
||||
@@ -34,6 +34,7 @@ class Context:
|
||||
pending = set()
|
||||
pending.add(filename)
|
||||
|
||||
from .parser import LarkError
|
||||
from .parser import Lark_StandAlone as Parser
|
||||
from .transformer import DefTransformer
|
||||
|
||||
@@ -47,7 +48,16 @@ class Context:
|
||||
path = self.find(name)
|
||||
|
||||
parser = Parser(transformer=DefTransformer(name))
|
||||
imps, objs, ints = parser.parse(open(path, "r").read())
|
||||
|
||||
try:
|
||||
imps, objs, ints = parser.parse(open(path, "r").read())
|
||||
except LarkError as e:
|
||||
import sys
|
||||
import textwrap
|
||||
print(f"\nError parsing {name}:", file=sys.stderr)
|
||||
print(textwrap.indent(str(e), " "), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
objects.update(objs)
|
||||
interfaces.update(ints)
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,10 +5,15 @@ def _indent(x):
|
||||
class Description(str): pass
|
||||
class Import(str): pass
|
||||
|
||||
class Options(set):
|
||||
class Options(dict):
|
||||
def __init__(self, opts = tuple()):
|
||||
for opt in opts:
|
||||
parts = opt.split(":", 1)
|
||||
self[parts[0]] = "".join(parts[1:])
|
||||
|
||||
def __str__(self):
|
||||
if not self: return ""
|
||||
return "[{}]".format(" ".join(self))
|
||||
return "[{}]".format(" ".join(self.keys()))
|
||||
|
||||
class UID(int):
|
||||
def __str__(self):
|
||||
|
||||
@@ -47,3 +47,15 @@ class Param:
|
||||
return "param {} {} {} {}".format(
|
||||
self.name, repr(self.type), self.options, self.desc or "")
|
||||
|
||||
@property
|
||||
def outparam(self):
|
||||
return "out" in self.options or "inout" in self.options
|
||||
|
||||
@property
|
||||
def refparam(self):
|
||||
return self.type.reference or self.outparam
|
||||
|
||||
@property
|
||||
def optional(self):
|
||||
return "optional" in self.options
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ class Primitive(Type):
|
||||
def __repr__(self):
|
||||
return f'Primitive({self.name})'
|
||||
|
||||
def c_names(self, options=None):
|
||||
def c_names(self, options=dict()):
|
||||
one = self.c_type
|
||||
if options and "out" in options or "inout" in options:
|
||||
if "out" in options or "inout" in options:
|
||||
one += " *"
|
||||
|
||||
return ((one, ""),)
|
||||
@@ -23,11 +23,13 @@ class PrimitiveRef(Primitive):
|
||||
super().__init__(name, c_type)
|
||||
self.__counted = counted
|
||||
|
||||
def c_names(self, options=None):
|
||||
reference = property(lambda self: True)
|
||||
|
||||
def c_names(self, options=dict()):
|
||||
one = f"{self.c_type} *"
|
||||
two = "size_t"
|
||||
|
||||
if options and "out" in options or "inout" in options:
|
||||
if "out" in options or "inout" in options:
|
||||
two += " *"
|
||||
else:
|
||||
one = "const " + one
|
||||
|
||||
@@ -3,6 +3,7 @@ class Type:
|
||||
self.__name = name
|
||||
|
||||
name = property(lambda self: self.__name)
|
||||
reference = property(lambda self: False)
|
||||
|
||||
def c_names(self, options):
|
||||
raise NotImplemented("Call to base Type.c_names")
|
||||
|
||||
Reference in New Issue
Block a user