提交 860627e6 创建 作者: Austin Clements's avatar Austin Clements

Automatically generate syscall entry point array

This uses the special comments marking syscalls to find syscall entry points and their prototypes. For now, it also parses include/syscall.h to get syscall numbers.
上级 66991942
......@@ -58,6 +58,11 @@ $(O)/%.o: %.cc
$(Q)mkdir -p $(@D)
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $<
$(O)/%.o: $(O)/%.cc
@echo " CXX $@"
$(Q)mkdir -p $(@D)
$(Q)$(CXX) $(CXXFLAGS) -c -o $@ $<
$(O)/%.o: %.S
@echo " CC $@"
$(Q)mkdir -p $(@D)
......
......@@ -52,7 +52,8 @@ OBJS = \
wqlib.o \
script.o \
zalloc.o \
incbin.o
incbin.o \
sysvectors.o \
ifeq ($(EXCEPTIONS),y)
OBJS += \
......@@ -135,6 +136,11 @@ $(O)/include/asmdefines.h: $(O)/kernel/asmdefines.S
$(O)/kernel/trapasm.o: $(O)/include/asmdefines.h
$(O)/kernel/uaccess.o: $(O)/include/asmdefines.h
$(O)/kernel/sysvectors.cc: tools/syscalls.py kernel/*.cc
@echo " GEN $@"
$(Q)mkdir -p $(@D)
$(Q)python $^ --kvectors > $@
.PRECIOUS: $(O)/kernel/%.o
-include $(O)/kernel/*.d
......
......@@ -80,46 +80,8 @@ argcheckptr(const void *p, int size)
return 0;
}
#define SYSCALL(name) (long(*)(u64,u64,u64,u64,u64))sys_##name
static long (*syscalls[])(u64, u64, u64, u64, u64) = {
nullptr,
SYSCALL(fork),
SYSCALL(exit),
SYSCALL(wait),
SYSCALL(pipe),
SYSCALL(write),
SYSCALL(read),
SYSCALL(close),
SYSCALL(kill),
SYSCALL(exec),
SYSCALL(openat),
SYSCALL(mknod),
SYSCALL(unlink),
SYSCALL(fstat),
SYSCALL(link),
SYSCALL(mkdirat),
SYSCALL(chdir),
SYSCALL(dup),
SYSCALL(getpid),
SYSCALL(sbrk),
SYSCALL(nsleep),
SYSCALL(uptime),
SYSCALL(map),
SYSCALL(unmap),
SYSCALL(halt),
SYSCALL(socket),
SYSCALL(bind),
SYSCALL(listen),
SYSCALL(accept),
SYSCALL(pread),
SYSCALL(async),
SYSCALL(script),
SYSCALL(setfs),
SYSCALL(wqwait),
SYSCALL(setaffinity),
SYSCALL(futex),
};
extern u64 (*syscalls[])(u64, u64, u64, u64, u64);
extern const int nsyscalls;
u64
syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
......@@ -130,7 +92,7 @@ syscall(u64 a0, u64 a1, u64 a2, u64 a3, u64 a4, u64 num)
#if EXCEPTIONS
try {
#endif
if(num < SYS_ncount && syscalls[num]) {
if(num < nsyscalls && syscalls[num]) {
mtstart(syscalls[num], myproc());
mtrec();
u64 r = syscalls[num](a0, a1, a2, a3, a4);
......
from optparse import OptionParser
import sys, re
def main():
parser = OptionParser(usage="usage: %prog [options] source...")
parser.add_option("--kvectors", action="store_true",
help="output kernel syscall vectors")
(options, args) = parser.parse_args()
if len(args) < 1:
parser.print_help()
parser.exit()
# Parse source files
syscalls = []
for fname in args:
syscalls.extend(parse(file(fname, "r")))
# Parse syscall numbers
nums = dict(re.findall("#define SYS_([^ ]*) +([0-9]+)", file("include/syscall.h").read()))
for syscall in syscalls:
syscall.num = int(nums[syscall.basename])
# Output
if options.kvectors:
print "#include \"types.h\""
print "#include \"userptr.hh\""
print
for syscall in syscalls:
print "extern %s %s(%s);" % (syscall.rettype, syscall.kname,
", ".join(syscall.kargs))
print
print "u64 (*syscalls[])(u64, u64, u64, u64, u64) = {"
bynum = dict((s.num, s) for s in syscalls)
for num in range(max(bynum.keys()) + 1):
if num not in bynum:
print " nullptr,"
else:
print " (u64(*)(u64,u64,u64,u64,u64))%s," % bynum[num].kname
print "};"
print
print "extern const int nsyscalls = %d;" % (max(bynum.keys()) + 1)
class Syscall(object):
def __init__(self, kname, rettype, kargs, num=None):
self.kname, self.rettype, self.kargs, self.num = \
kname, rettype, kargs, num
self.basename = kname[4:]
def __repr__(self):
return "Syscall(%r,%r,%r,%r)" % (
self.kname, self.rettype, self.kargs, self.num)
class ParseError(RuntimeError):
def __init__(self, fname, msg):
RuntimeError.__init__(self, "%s: %s" % (fname, msg))
def parse(fp):
res = []
for proto in re.findall(r"//SYSCALL\n([^{]*)", fp.read()):
# Parse the prototype
proto = " ".join(proto.split())
m = re.match(r"(.+) ([a-z_]+) *\(([^)]+)\)", proto)
if not m:
raise ParseError(fp.name, "could not parse prototype %r" % proto)
rettype, name, kargs = m.groups()
kargs = re.split(" *, *", kargs)
res.append(Syscall(name, rettype, kargs))
return res
if __name__ == "__main__":
main()
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论