xref: /freebsd/sys/tools/syscalls/scripts/init_sysent.lua (revision 42d075f4b7b74eb3c4f943d6bdcc2aeb56be6388)
19ded074eSagge3#!/usr/libexec/flua
29ded074eSagge3--
39ded074eSagge3-- SPDX-License-Identifier: BSD-2-Clause
49ded074eSagge3--
59ded074eSagge3-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org>
69ded074eSagge3-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com>
79ded074eSagge3-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
89ded074eSagge3--
99ded074eSagge3
109ded074eSagge3-- Setup to be a module, or ran as its own script.
119ded074eSagge3local init_sysent = {}
129ded074eSagge3local script = not pcall(debug.getlocal, 4, 1)	-- TRUE if script.
139ded074eSagge3if script then
149ded074eSagge3	-- Add library root to the package path.
159ded074eSagge3	local path = arg[0]:gsub("/[^/]+.lua$", "")
169ded074eSagge3	package.path = package.path .. ";" .. path .. "/../?.lua"
179ded074eSagge3end
189ded074eSagge3
199ded074eSagge3local FreeBSDSyscall = require("core.freebsd-syscall")
209ded074eSagge3local generator = require("tools.generator")
219ded074eSagge3
229ded074eSagge3-- File has not been decided yet; config will decide file.  Default defined as
239ded074eSagge3-- /dev/null.
249ded074eSagge3init_sysent.file = "/dev/null"
259ded074eSagge3
269ded074eSagge3function init_sysent.generate(tbl, config, fh)
279ded074eSagge3	-- Grab the master system calls table.
289ded074eSagge3	local s = tbl.syscalls
299ded074eSagge3
309ded074eSagge3	-- Bind the generator to the parameter file.
319ded074eSagge3	local gen = generator:new({}, fh)
329ded074eSagge3
339ded074eSagge3	-- Write the generated preamble.
349ded074eSagge3	gen:preamble("System call switch table.")
359ded074eSagge3
369ded074eSagge3	gen:write(tbl.includes)
379ded074eSagge3
389ded074eSagge3	-- Newline before and after this line.
399ded074eSagge3	gen:write(
409ded074eSagge3	    "\n#define AS(name) (sizeof(struct name) / sizeof(syscallarg_t))\n")
419ded074eSagge3
429ded074eSagge3	-- Write out all the compat directives from compat_options.
439ded074eSagge3	for _, v in pairs(config.compat_options) do
449ded074eSagge3		gen:write(string.format([[
459ded074eSagge3
469ded074eSagge3#ifdef %s
479ded074eSagge3#define %s(n, name) .sy_narg = n, .sy_call = (sy_call_t *)__CONCAT(%s, name)
489ded074eSagge3#else
499ded074eSagge3#define %s(n, name) .sy_narg = 0, .sy_call = (sy_call_t *)nosys
509ded074eSagge3#endif
519ded074eSagge3]], v.definition, v.flag:lower(), v.prefix, v.flag:lower()))
529ded074eSagge3	end
539ded074eSagge3	-- Add a newline only if there were compat_options.
549ded074eSagge3	if config.compat_options ~= nil then
559ded074eSagge3		gen:write("\n")
569ded074eSagge3	end
579ded074eSagge3
589ded074eSagge3	gen:write(string.format([[
599ded074eSagge3/* The casts are bogus but will do for now. */
609ded074eSagge3struct sysent %s[] = {
619ded074eSagge3]], config.switchname))
629ded074eSagge3
639ded074eSagge3	for _, v in pairs(s) do
649ded074eSagge3		local c = v:compatLevel()
659ded074eSagge3		-- Comment is the function name by default, but may change
669ded074eSagge3		-- based on the type of system call.
679ded074eSagge3		local comment = v.name
689ded074eSagge3
69*42d075f4SBrooks Davis		gen:write(v.prolog);
70*42d075f4SBrooks Davis
719ded074eSagge3		-- Handle non-compat:
729ded074eSagge3		if v:native() then
739ded074eSagge3			gen:write(string.format(
749ded074eSagge3			    "\t{ .sy_narg = %s, .sy_call = (sy_call_t *)",
759ded074eSagge3			    v.args_size))
769ded074eSagge3			-- Handle SYSMUX flag:
779ded074eSagge3			if v.type.SYSMUX then
789ded074eSagge3				gen:write(string.format("nosys, " ..
799ded074eSagge3				    ".sy_auevent = AUE_NULL, " ..
809ded074eSagge3				    ".sy_flags = %s, " ..
819ded074eSagge3				    ".sy_thrcnt = SY_THR_STATIC },",
829ded074eSagge3				    v.cap))
839ded074eSagge3			-- Handle NOSTD flag:
849ded074eSagge3			elseif v.type.NOSTD then
859ded074eSagge3				gen:write(string.format("lkmressys, " ..
869ded074eSagge3				    ".sy_auevent = AUE_NULL, " ..
879ded074eSagge3				    ".sy_flags = %s, " ..
889ded074eSagge3				    ".sy_thrcnt = SY_THR_ABSENT },",
899ded074eSagge3				    v.cap))
909ded074eSagge3			-- Handle rest of non-compat:
919ded074eSagge3			else
929ded074eSagge3				if v.name == "nosys" or
939ded074eSagge3				    v.name == "lkmnosys" or
949ded074eSagge3				    v.name == "sysarch" or
959ded074eSagge3				    v.name:find("^freebsd") or
969ded074eSagge3				    v.name:find("^linux") then
979ded074eSagge3					gen:write(string.format("%s, " ..
989ded074eSagge3					    ".sy_auevent = %s, " ..
999ded074eSagge3					    ".sy_flags = %s, " ..
1009ded074eSagge3					    ".sy_thrcnt = %s },",
1019ded074eSagge3					    v:symbol(), v.audit, v.cap, v.thr))
1029ded074eSagge3				else
1039ded074eSagge3					gen:write(string.format("sys_%s, " ..
1049ded074eSagge3					    ".sy_auevent = %s, " ..
1059ded074eSagge3					    ".sy_flags = %s, " ..
1069ded074eSagge3					    ".sy_thrcnt = %s },",
1079ded074eSagge3					    v:symbol(), v.audit, v.cap, v.thr))
1089ded074eSagge3				end
1099ded074eSagge3			end
1109ded074eSagge3
1119ded074eSagge3		-- Handle compat (everything >= FREEBSD3):
1129ded074eSagge3		elseif c >= 3 then
1139ded074eSagge3			-- Lookup the info for this specific compat option.
1149ded074eSagge3			local flag, descr
1159ded074eSagge3			for _, opt in pairs(config.compat_options) do
1169ded074eSagge3				if opt.compatlevel == c then
1179ded074eSagge3					flag = opt.flag
1189ded074eSagge3					flag = flag:lower()
1199ded074eSagge3					descr = opt.descr
1209ded074eSagge3					break
1219ded074eSagge3				end
1229ded074eSagge3			end
1239ded074eSagge3
1249ded074eSagge3			if v.type.NOSTD then
1259ded074eSagge3				gen:write(string.format("\t{ " ..
1269ded074eSagge3				    ".sy_narg = %s, " ..
1279ded074eSagge3				    ".sy_call = (sy_call_t *)%s, " ..
1289ded074eSagge3				    ".sy_auevent = %s, " ..
1299ded074eSagge3				    ".sy_flags = 0, " ..
1309ded074eSagge3				    ".sy_thrcnt = SY_THR_ABSENT },",
1319ded074eSagge3				    "0", "lkmressys", "AUE_NULL"))
1329ded074eSagge3			else
1339ded074eSagge3				gen:write(string.format("\t{ %s(%s,%s), " ..
1349ded074eSagge3				    ".sy_auevent = %s, " ..
1359ded074eSagge3				    ".sy_flags = %s, " ..
1369ded074eSagge3				    ".sy_thrcnt = %s },",
1379ded074eSagge3				    flag, v.args_size, v.name, v.audit, v.cap, v.thr))
1389ded074eSagge3			end
1399ded074eSagge3			comment = descr .. " " .. v.name
1409ded074eSagge3
1419ded074eSagge3		-- Handle obsolete:
1429ded074eSagge3		elseif v.type.OBSOL then
1439ded074eSagge3			gen:write("\t{ " ..
1449ded074eSagge3			    ".sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
1459ded074eSagge3			    ".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
1469ded074eSagge3			    ".sy_thrcnt = SY_THR_ABSENT },")
1479ded074eSagge3			comment = "obsolete " .. v.name
1489ded074eSagge3
1499ded074eSagge3		-- Handle unimplemented:
1509ded074eSagge3		elseif v.type.UNIMPL then
1519ded074eSagge3			gen:write("\t{ " ..
1529ded074eSagge3			    ".sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
1539ded074eSagge3			    ".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
1549ded074eSagge3			    ".sy_thrcnt = SY_THR_ABSENT },")
1559ded074eSagge3			-- UNIMPL comment is not different in sysent.
1569ded074eSagge3
1579ded074eSagge3		-- Handle reserved:
1589ded074eSagge3		elseif v.type.RESERVED then
1599ded074eSagge3			gen:write("\t{ " ..
1609ded074eSagge3			    ".sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
1619ded074eSagge3			    ".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
1629ded074eSagge3			    ".sy_thrcnt = SY_THR_ABSENT },")
1639ded074eSagge3			comment = "reserved for local use"
1649ded074eSagge3		end
1659ded074eSagge3
1669ded074eSagge3		gen:write(string.format("\t/* %d = %s */\n", v.num, comment))
1679ded074eSagge3	end
168*42d075f4SBrooks Davis	gen:write(tbl.epilog)
1699ded074eSagge3
1709ded074eSagge3	-- End
1719ded074eSagge3	gen:write("};\n")
1729ded074eSagge3end
1739ded074eSagge3
1749ded074eSagge3-- Entry of script:
1759ded074eSagge3if script then
1769ded074eSagge3	local config = require("config")
1779ded074eSagge3
1789ded074eSagge3	if #arg < 1 or #arg > 2 then
1799ded074eSagge3		error("usage: " .. arg[0] .. " syscall.master")
1809ded074eSagge3	end
1819ded074eSagge3
1829ded074eSagge3	local sysfile, configfile = arg[1], arg[2]
1839ded074eSagge3
1849ded074eSagge3	config.merge(configfile)
1859ded074eSagge3	config.mergeCompat()
1869ded074eSagge3
1879ded074eSagge3	-- The parsed syscall table.
1889ded074eSagge3	local tbl = FreeBSDSyscall:new{sysfile = sysfile, config = config}
1899ded074eSagge3
1909ded074eSagge3	init_sysent.file = config.syssw 	-- change file here
1919ded074eSagge3	init_sysent.generate(tbl, config, init_sysent.file)
1929ded074eSagge3end
1939ded074eSagge3
1949ded074eSagge3-- Return the module.
1959ded074eSagge3return init_sysent
196