diff --git a/Makefile.inc1 b/Makefile.inc1 index efa1299b76a7e8..99d86cb5a13b1c 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1604,7 +1604,8 @@ _sysent_dirs+= sys/compat/freebsd32 _sysent_dirs+= sys/amd64/linux \ sys/amd64/linux32 \ sys/arm64/linux \ - sys/i386/linux + sys/i386/linux \ + sys/tools/syscalls/test sysent: .PHONY .for _dir in ${_sysent_dirs} diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index d3c4f2c6423132..7551bd45f83964 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -107,9 +107,11 @@ ; timet_ Object contains a time_t and varies between i386 and other ; ABIs. -; #include's, #defines's, etc. may be included, and are copied to the output -; files. However, #ifdef, etc will be copied, but any lines that don't start -; with # will not. Caveat Emptor. +; #include's, #defines's, etc. may be included, and are copied to a +; limited set of output files. Before the first syscalls, #include lines will +; be copied and %%ABI_HEADERS%% expanded. Between system call entries, +; all lines beginning with # will be copied. Caveat Emptor. +; WARNING: this functionality is deprecated. #include #include diff --git a/sys/tools/syscalls/core/freebsd-syscall.lua b/sys/tools/syscalls/core/freebsd-syscall.lua index 193b1e43563c30..2ef0fdea640123 100644 --- a/sys/tools/syscalls/core/freebsd-syscall.lua +++ b/sys/tools/syscalls/core/freebsd-syscall.lua @@ -48,7 +48,9 @@ function FreeBSDSyscall:parseSysfile() end local incs = "" - local defs = "" + local prolog = "" + local first = true + local cpp_warned = false local s for line in fh:lines() do line = line:gsub(commentExpr, "") -- Strip any comments. @@ -80,12 +82,23 @@ function FreeBSDSyscall:parseSysfile() if h ~= nil and h ~= "" then incs = incs .. h .. "\n" end - elseif line:match("^#%s*define") then - defs = defs .. line.. "\n" elseif line:match("^#") then - util.abort(1, "Unsupported cpp op " .. line) + if not cpp_warned then + util.warn("use of non-include cpp " .. + "directives is deprecated") + cpp_warned = true + end + prolog = prolog .. line .. "\n" else s = syscall:new() + if first then + self.prolog = prolog + s.prolog = "" + first = false + else + s.prolog = prolog + end + prolog = "" if s:add(line) then -- Append to system call list. for t in s:iter() do @@ -114,7 +127,13 @@ function FreeBSDSyscall:parseSysfile() assert(fh:close()) self.includes = incs - self.defines = defs + self.epilog = prolog + + if self.prolog ~= "" then + util.warn("non-include pre-processor directives in the " .. + "config prolog will not appear in generated output:\n" .. + self.prolog) + end end function FreeBSDSyscall:findStructs() diff --git a/sys/tools/syscalls/scripts/init_sysent.lua b/sys/tools/syscalls/scripts/init_sysent.lua index 66683250b482e0..a1f51b5f3152e8 100755 --- a/sys/tools/syscalls/scripts/init_sysent.lua +++ b/sys/tools/syscalls/scripts/init_sysent.lua @@ -66,6 +66,8 @@ struct sysent %s[] = { -- based on the type of system call. local comment = v.name + gen:write(v.prolog); + -- Handle non-compat: if v:native() then gen:write(string.format( @@ -163,6 +165,7 @@ struct sysent %s[] = { gen:write(string.format("\t/* %d = %s */\n", v.num, comment)) end + gen:write(tbl.epilog) -- End gen:write("};\n") diff --git a/sys/tools/syscalls/scripts/syscall_mk.lua b/sys/tools/syscalls/scripts/syscall_mk.lua index 49d3f6f86c201d..8f8755af31c078 100755 --- a/sys/tools/syscalls/scripts/syscall_mk.lua +++ b/sys/tools/syscalls/scripts/syscall_mk.lua @@ -43,24 +43,14 @@ function syscall_mk.generate(tbl, config, fh) gen:write("MIASM = \\\n") -- preamble for _, v in pairs(s) do local c = v:compatLevel() + local bs = " \\" idx = idx + 1 - if v:native() and not v.type.NODEF and not v.type.NOLIB then + if (v:native() or c >= 7) and not v.type.NODEF and not v.type.NOLIB then if idx >= size then -- At last system call, no backslash. - gen:write(string.format("\t%s.o\n", v:symbol())) - else - -- Normal behavior. - gen:write(string.format("\t%s.o \\\n", v:symbol())) - end - -- Handle compat (everything >= FREEBSD3): - elseif c >= 7 and not v.type.NODEF and not v.type.NOLIB then - if idx >= size then - -- At last system call, no backslash. - gen:write(string.format("\t%s.o\n", v:symbol())) - else - -- Normal behavior. - gen:write(string.format("\t%s.o \\\n", v:symbol())) + bs = "" end + gen:write(string.format("\t%s.o%s\n", v:symbol(), bs)) end end end diff --git a/sys/tools/syscalls/scripts/syscalls.lua b/sys/tools/syscalls/scripts/syscalls.lua index 38ed396a73aef8..a40ebc1376277d 100755 --- a/sys/tools/syscalls/scripts/syscalls.lua +++ b/sys/tools/syscalls/scripts/syscalls.lua @@ -38,6 +38,9 @@ function syscalls.generate(tbl, config, fh) for _, v in pairs(s) do --print("num " .. v.num .. " name " .. v.name) local c = v:compatLevel() + + gen:write(v.prolog); + if v:native() then gen:write(string.format([[ "%s", /* %d = %s */ @@ -80,6 +83,7 @@ function syscalls.generate(tbl, config, fh) end end + gen:write(tbl.epilog) -- End gen:write("};\n") end diff --git a/sys/tools/syscalls/scripts/syscalls_map.lua b/sys/tools/syscalls/scripts/syscalls_map.lua index 023b4305292197..52c3b294e33876 100755 --- a/sys/tools/syscalls/scripts/syscalls_map.lua +++ b/sys/tools/syscalls/scripts/syscalls_map.lua @@ -37,7 +37,7 @@ function syscalls_map.generate(tbl, config, fh) gen:write(string.format("FBSDprivate_1.0 {\n")) for _, v in pairs(s) do - --print("num " .. v.num .. " name " .. v.name) + gen:write(v.prolog) if v:native() and not v.type.NODEF and not v.type.NOLIB then if v.name ~= "exit" and v.name ~= "vfork" then gen:write(string.format("\t_%s;\n", v.name)) @@ -45,6 +45,8 @@ function syscalls_map.generate(tbl, config, fh) gen:write(string.format("\t__sys_%s;\n", v.name)) end end + gen:write(tbl.epilog) + -- End gen:write("};\n") end diff --git a/sys/tools/syscalls/scripts/sysproto_h.lua b/sys/tools/syscalls/scripts/sysproto_h.lua index 6770e054889951..2b0b9293ea6678 100755 --- a/sys/tools/syscalls/scripts/sysproto_h.lua +++ b/sys/tools/syscalls/scripts/sysproto_h.lua @@ -93,6 +93,12 @@ struct thread; -- intuitive). local audit_idx = 10000 -- this should do + gen:write(v.prolog) + gen:store(v.prolog, 1) + for _, w in pairs(config.compat_options) do + gen:store(v.prolog, w.compatlevel * 10) + end + -- Handle non-compat: if v:native() then -- All these negation conditions are because (in @@ -202,6 +208,12 @@ struct %s { end_idx) end + gen:write(tbl.epilog) + gen:store(tbl.epilog, 1) + for _, w in pairs(config.compat_options) do + gen:store(tbl.epilog, w.compatlevel * 10) + end + if gen.storage_levels ~= nil then gen:writeStorage() end diff --git a/sys/tools/syscalls/scripts/systrace_args.lua b/sys/tools/syscalls/scripts/systrace_args.lua index 88170b85e73737..40dd072bc0c3fd 100755 --- a/sys/tools/syscalls/scripts/systrace_args.lua +++ b/sys/tools/syscalls/scripts/systrace_args.lua @@ -68,6 +68,10 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) for _, v in pairs(s) do + gen:write(v.prolog); + gen:store(v.prolog, 1); + gen:store(v.prolog, 2); + -- Handle non compat: if v:native() then gen:write(string.format([[ @@ -212,6 +216,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) end end + gen:write(tbl.epilog) gen:write([[ default: *n_args = 0; @@ -219,6 +224,8 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; } ]]) + + gen:store(tbl.epilog, 1) gen:store([[ default: break; @@ -227,6 +234,8 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) strlcpy(desc, p, descsz); } ]], 1) + + gen:store(tbl.epilog, 2) gen:store([[ default: break; diff --git a/sys/tools/syscalls/test/Makefile b/sys/tools/syscalls/test/Makefile new file mode 100644 index 00000000000000..670388ebf52e55 --- /dev/null +++ b/sys/tools/syscalls/test/Makefile @@ -0,0 +1,3 @@ +GENERATED_PREFIX= test_ + +.include "../../../conf/sysent.mk" diff --git a/sys/tools/syscalls/test/syscalls.conf b/sys/tools/syscalls/test/syscalls.conf new file mode 100644 index 00000000000000..ffcfa8d4c6aa65 --- /dev/null +++ b/sys/tools/syscalls/test/syscalls.conf @@ -0,0 +1,11 @@ +sysnames="test_syscalls.c" +sysproto="test_proto.h" +sysproto_h=_TEST_SYSPROTO_H_ +syshdr="test_syscall.h" +syssw="test_sysent.c" +syscallprefix="TEST_SYS_" +switchname="test_sysent" +namesname="test_syscallnames" +systrace="test_systrace_args.c" +libsysmap="test_syscalls.map" +compat_set="" diff --git a/sys/tools/syscalls/test/syscalls.master b/sys/tools/syscalls/test/syscalls.master new file mode 100644 index 00000000000000..4986ad41fc6a9d --- /dev/null +++ b/sys/tools/syscalls/test/syscalls.master @@ -0,0 +1,26 @@ +#include +#include +#include + +0 AUE_NULL UNIMPL unimpl_syscall0 + +; Scenario #1: Vendor uses a reserved slot on just a single platform +#ifdef PLATFORM_FOO +1 AUE_NULL STD { + int syscall1( + int arg1 + ); + } +#else +1 AUE_NULL RESERVED +#endif + +; Scenario #2: The other way around; vendor obsoletes a syscall on newer +; platforms +#ifdef PLATFORM_FOO +2 AUE_NULL OBSOL syscall2 +#else +2 AUE_NULL STD { + int syscall2(void); + } +#endif diff --git a/sys/tools/syscalls/test/test_proto.h b/sys/tools/syscalls/test/test_proto.h new file mode 100644 index 00000000000000..db1f507b8be093 --- /dev/null +++ b/sys/tools/syscalls/test/test_proto.h @@ -0,0 +1,63 @@ +/* + * System call prototypes. + * + * DO NOT EDIT-- this file is automatically @generated. + */ + +#ifndef _TEST_SYSPROTO_H_ +#define _TEST_SYSPROTO_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct proc; + +struct thread; + +#define PAD_(t) (sizeof(syscallarg_t) <= sizeof(t) ? \ + 0 : sizeof(syscallarg_t) - sizeof(t)) + +#if BYTE_ORDER == LITTLE_ENDIAN +#define PADL_(t) 0 +#define PADR_(t) PAD_(t) +#else +#define PADL_(t) PAD_(t) +#define PADR_(t) 0 +#endif + +#ifdef PLATFORM_FOO +struct syscall1_args { + char arg1_l_[PADL_(int)]; int arg1; char arg1_r_[PADR_(int)]; +}; +#else +#endif +#ifdef PLATFORM_FOO +#else +struct syscall2_args { + syscallarg_t dummy; +}; +#endif +#ifdef PLATFORM_FOO +int sys_syscall1(struct thread *, struct syscall1_args *); +#else +#endif +#ifdef PLATFORM_FOO +#else +int sys_syscall2(struct thread *, struct syscall2_args *); +#endif +#define TEST_SYS_AUE_syscall1 AUE_NULL +#define TEST_SYS_AUE_syscall2 AUE_NULL + +#undef PAD_ +#undef PADL_ +#undef PADR_ + +#endif /* !_TEST_SYSPROTO_H_ */ diff --git a/sys/tools/syscalls/test/test_syscall.h b/sys/tools/syscalls/test/test_syscall.h new file mode 100644 index 00000000000000..026e82d9ac6271 --- /dev/null +++ b/sys/tools/syscalls/test/test_syscall.h @@ -0,0 +1,10 @@ +/* + * System call numbers. + * + * DO NOT EDIT-- this file is automatically @generated. + */ + +#define TEST_SYS_syscall1 1 + /* 2 is obsolete syscall2 */ +#define TEST_SYS_syscall2 2 +#define TEST_SYS_MAXSYSCALL 3 diff --git a/sys/tools/syscalls/test/test_syscalls.c b/sys/tools/syscalls/test/test_syscalls.c new file mode 100644 index 00000000000000..0e73c8223507c3 --- /dev/null +++ b/sys/tools/syscalls/test/test_syscalls.c @@ -0,0 +1,19 @@ +/* + * System call names. + * + * DO NOT EDIT-- this file is automatically @generated. + */ + +const char *test_syscallnames[] = { + "#0", /* 0 = unimpl_syscall0 */ +#ifdef PLATFORM_FOO + "syscall1", /* 1 = syscall1 */ +#else + "#1", /* 1 = reserved for local use */ +#endif +#ifdef PLATFORM_FOO + "obs_syscall2", /* 2 = obsolete syscall2 */ +#else + "syscall2", /* 2 = syscall2 */ +#endif +}; diff --git a/sys/tools/syscalls/test/test_syscalls.map b/sys/tools/syscalls/test/test_syscalls.map new file mode 100644 index 00000000000000..137496186402de --- /dev/null +++ b/sys/tools/syscalls/test/test_syscalls.map @@ -0,0 +1,18 @@ +/* + * FreeBSD system call symbols. + * + * DO NOT EDIT-- this file is automatically @generated. + */ + +FBSDprivate_1.0 { +#ifdef PLATFORM_FOO + _syscall1; + __sys_syscall1; +#else +#endif +#ifdef PLATFORM_FOO +#else + _syscall2; + __sys_syscall2; +#endif +}; diff --git a/sys/tools/syscalls/test/test_sysent.c b/sys/tools/syscalls/test/test_sysent.c new file mode 100644 index 00000000000000..18d2b0fd97121e --- /dev/null +++ b/sys/tools/syscalls/test/test_sysent.c @@ -0,0 +1,26 @@ +/* + * System call switch table. + * + * DO NOT EDIT-- this file is automatically @generated. + */ + +#include +#include +#include + +#define AS(name) (sizeof(struct name) / sizeof(syscallarg_t)) + +/* The casts are bogus but will do for now. */ +struct sysent test_sysent[] = { + { .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 0 = unimpl_syscall0 */ +#ifdef PLATFORM_FOO + { .sy_narg = AS(syscall1_args), .sy_call = (sy_call_t *)sys_syscall1, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 1 = syscall1 */ +#else + { .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 1 = reserved for local use */ +#endif +#ifdef PLATFORM_FOO + { .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 2 = obsolete syscall2 */ +#else + { .sy_narg = 0, .sy_call = (sy_call_t *)sys_syscall2, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 2 = syscall2 */ +#endif +}; diff --git a/sys/tools/syscalls/test/test_systrace_args.c b/sys/tools/syscalls/test/test_systrace_args.c new file mode 100644 index 00000000000000..74d0aa0ee8623a --- /dev/null +++ b/sys/tools/syscalls/test/test_systrace_args.c @@ -0,0 +1,91 @@ +/* + * System call argument to DTrace register array conversion. + * + * This file is part of the DTrace syscall provider. + * + * DO NOT EDIT-- this file is automatically @generated. + */ + +static void +systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) +{ + int64_t *iarg = (int64_t *)uarg; + int a = 0; + switch (sysnum) { +#ifdef PLATFORM_FOO + /* syscall1 */ + case 1: { + struct syscall1_args *p = params; + iarg[a++] = p->arg1; /* int */ + *n_args = 1; + break; + } +#else +#endif +#ifdef PLATFORM_FOO +#else + /* syscall2 */ + case 2: { + *n_args = 0; + break; + } +#endif + default: + *n_args = 0; + break; + }; +} +static void +systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) +{ + const char *p = NULL; + switch (sysnum) { +#ifdef PLATFORM_FOO + /* syscall1 */ + case 1: + switch (ndx) { + case 0: + p = "int"; + break; + default: + break; + }; + break; +#else +#endif +#ifdef PLATFORM_FOO +#else + /* syscall2 */ + case 2: + break; +#endif + default: + break; + }; + if (p != NULL) + strlcpy(desc, p, descsz); +} +static void +systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) +{ + const char *p = NULL; + switch (sysnum) { +#ifdef PLATFORM_FOO + /* syscall1 */ + case 1: + if (ndx == 0 || ndx == 1) + p = "int"; + break; +#else +#endif +#ifdef PLATFORM_FOO +#else + /* syscall2 */ + case 2: +#endif + default: + break; + }; + if (p != NULL) + strlcpy(desc, p, descsz); +} diff --git a/sys/tools/syscalls/tools/util.lua b/sys/tools/syscalls/tools/util.lua index c9ff98dda786ff..41247e34a10e9f 100644 --- a/sys/tools/syscalls/tools/util.lua +++ b/sys/tools/syscalls/tools/util.lua @@ -35,6 +35,11 @@ function util.split(s, re) return t end +-- Prints a warning to stderr +function util.warn(msg) + assert(io.stderr:write("WARNING: " .. msg .. "\n")) +end + -- Aborts with a message and does a clean exit procedure. function util.abort(status, msg) assert(io.stderr:write(msg .. "\n"))