xref: /freebsd/sys/tools/syscalls/scripts/systrace_args.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 systrace_args = {}
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 util = require("tools.util")
219ded074eSagge3local generator = require("tools.generator")
229ded074eSagge3
239ded074eSagge3-- File has not been decided yet; config will decide file.  Default defined as
249ded074eSagge3-- /dev/null.
259ded074eSagge3systrace_args.file = "/dev/null"
269ded074eSagge3
279ded074eSagge3function systrace_args.generate(tbl, config, fh)
289ded074eSagge3	-- Grab the master system calls table.
299ded074eSagge3	local s = tbl.syscalls
309ded074eSagge3
319ded074eSagge3	-- Bind the generator to the parameter file.
329ded074eSagge3	local gen = generator:new({}, fh)
339ded074eSagge3	gen.storage_levels = {}	-- make sure storage is clear
349ded074eSagge3
359ded074eSagge3	-- 64-bit padding preprocessor directive.
369ded074eSagge3	gen:pad64(config.abiChanges("pair_64bit"))
379ded074eSagge3
389ded074eSagge3	-- Write the generated preamble.
399ded074eSagge3	gen:preamble(
409ded074eSagge3	    "System call argument to DTrace register array conversion.\n" ..
419ded074eSagge3	    "\n" ..
429ded074eSagge3	    "This file is part of the DTrace syscall provider.")
439ded074eSagge3
449ded074eSagge3	gen:write(string.format([[
459ded074eSagge3static void
469ded074eSagge3systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
479ded074eSagge3{
489ded074eSagge3	int64_t *iarg = (int64_t *)uarg;
499ded074eSagge3	int a = 0;
509ded074eSagge3	switch (sysnum) {
519ded074eSagge3]]))
529ded074eSagge3
539ded074eSagge3	gen:store(string.format([[
549ded074eSagge3static void
559ded074eSagge3systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
569ded074eSagge3{
579ded074eSagge3	const char *p = NULL;
589ded074eSagge3	switch (sysnum) {
599ded074eSagge3]]), 1)
609ded074eSagge3
619ded074eSagge3	gen:store(string.format([[
629ded074eSagge3static void
639ded074eSagge3systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
649ded074eSagge3{
659ded074eSagge3	const char *p = NULL;
669ded074eSagge3	switch (sysnum) {
679ded074eSagge3]]), 2)
689ded074eSagge3
699ded074eSagge3	for _, v in pairs(s) do
709ded074eSagge3
71*42d075f4SBrooks Davis		gen:write(v.prolog);
72*42d075f4SBrooks Davis		gen:store(v.prolog, 1);
73*42d075f4SBrooks Davis		gen:store(v.prolog, 2);
74*42d075f4SBrooks Davis
759ded074eSagge3		-- Handle non compat:
769ded074eSagge3		if v:native() then
779ded074eSagge3			gen:write(string.format([[
789ded074eSagge3	/* %s */
799ded074eSagge3	case %d: {
809ded074eSagge3]], v.name, v.num))
819ded074eSagge3
829ded074eSagge3			gen:store(string.format([[
839ded074eSagge3	/* %s */
849ded074eSagge3	case %d:
859ded074eSagge3]], v.name, v.num), 1)
869ded074eSagge3
879ded074eSagge3			gen:store(string.format([[
889ded074eSagge3	/* %s */
899ded074eSagge3	case %d:
909ded074eSagge3]], v.name, v.num), 2)
919ded074eSagge3
929ded074eSagge3			local n_args = #v.args
939ded074eSagge3			if v.type.SYSMUX then
949ded074eSagge3				n_args = 0
959ded074eSagge3			end
969ded074eSagge3
979ded074eSagge3			if #v.args > 0 and not v.type.SYSMUX then
989ded074eSagge3				local padding = ""
999ded074eSagge3
1009ded074eSagge3				gen:write(string.format([[
1019ded074eSagge3		struct %s *p = params;
1029ded074eSagge3]],
1039ded074eSagge3				    v.arg_alias))
1049ded074eSagge3
1059ded074eSagge3				gen:store([[
1069ded074eSagge3		switch (ndx) {
1079ded074eSagge3]],
1089ded074eSagge3				    1)
1099ded074eSagge3
1109ded074eSagge3				for idx, arg in ipairs(v.args) do
1119ded074eSagge3					local argtype = util.trim(
1129ded074eSagge3						arg.type:gsub(
1139ded074eSagge3						    "__restrict$", ""), nil)
1149ded074eSagge3					if argtype == "int" and
1159ded074eSagge3					    arg.name == "_pad" and
1169ded074eSagge3					    config.abiChanges("pair_64bit") then
1179ded074eSagge3						gen:store(
1189ded074eSagge3						    "#ifdef PAD64_REQUIRED\n",
1199ded074eSagge3						    1)
1209ded074eSagge3					end
1219ded074eSagge3
1229ded074eSagge3					-- Pointer arg?
1239ded074eSagge3					local desc
1249ded074eSagge3					if argtype:find("*") then
1259ded074eSagge3						desc = "userland " .. argtype
1269ded074eSagge3					else
1279ded074eSagge3						desc = argtype;
1289ded074eSagge3					end
1299ded074eSagge3
1309ded074eSagge3					gen:store(string.format([[
1319ded074eSagge3		case %d%s:
1329ded074eSagge3			p = "%s";
1339ded074eSagge3			break;
1349ded074eSagge3]],
1359ded074eSagge3					    idx - 1, padding, desc), 1)
1369ded074eSagge3
1379ded074eSagge3					if argtype == "int" and
1389ded074eSagge3					    arg.name == "_pad" and
1399ded074eSagge3					   config.abiChanges("pair_64bit") then
1409ded074eSagge3						padding = " - _P_"
1419ded074eSagge3						gen:store([[
1429ded074eSagge3#define _P_ 0
1439ded074eSagge3#else
1449ded074eSagge3#define _P_ 1
1459ded074eSagge3#endif
1469ded074eSagge3]],
1479ded074eSagge3					    1)
1489ded074eSagge3					end
1499ded074eSagge3
1509ded074eSagge3					if util.isPtrType(argtype,
1519ded074eSagge3					    config.abi_intptr_t) then
1529ded074eSagge3						gen:write(string.format([[
1539ded074eSagge3		uarg[a++] = (%s)p->%s; /* %s */
1549ded074eSagge3]],
1559ded074eSagge3						    config.ptr_intptr_t_cast,
1569ded074eSagge3						    arg.name, argtype))
1579ded074eSagge3					elseif argtype == "union l_semun" then
1589ded074eSagge3						gen:write(string.format([[
1599ded074eSagge3		uarg[a++] = p->%s.buf; /* %s */
1609ded074eSagge3]],
1619ded074eSagge3						    arg.name, argtype))
1629ded074eSagge3					elseif argtype:sub(1,1) == "u" or
1639ded074eSagge3					    argtype == "size_t" then
1649ded074eSagge3						gen:write(string.format([[
1659ded074eSagge3		uarg[a++] = p->%s; /* %s */
1669ded074eSagge3]],
1679ded074eSagge3						    arg.name, argtype))
1689ded074eSagge3					else
1699ded074eSagge3						if argtype == "int" and
1709ded074eSagge3						    arg.name == "_pad" and
1719ded074eSagge3						    config.abiChanges(
1729ded074eSagge3						    "pair_64bit") then
1739ded074eSagge3							gen:write([[
1749ded074eSagge3#ifdef PAD64_REQUIRED
1759ded074eSagge3]])
1769ded074eSagge3						end
1779ded074eSagge3
1789ded074eSagge3						gen:write(string.format([[
1799ded074eSagge3		iarg[a++] = p->%s; /* %s */
1809ded074eSagge3]],
1819ded074eSagge3						    arg.name, argtype))
1829ded074eSagge3
1839ded074eSagge3						if argtype == "int" and
1849ded074eSagge3						    arg.name == "_pad" and
1859ded074eSagge3						    config.abiChanges(
1869ded074eSagge3						    "pair_64bit") then
1879ded074eSagge3							gen:write("#endif\n")
1889ded074eSagge3						end
1899ded074eSagge3					end
1909ded074eSagge3				end
1919ded074eSagge3
1929ded074eSagge3				gen:store([[
1939ded074eSagge3		default:
1949ded074eSagge3			break;
1959ded074eSagge3		};
1969ded074eSagge3]],
1979ded074eSagge3				    1)
1989ded074eSagge3
1999ded074eSagge3				if padding ~= "" then
2009ded074eSagge3					gen:store("#undef _P_\n\n", 1)
2019ded074eSagge3				end
2029ded074eSagge3
2039ded074eSagge3				gen:store(string.format([[
2049ded074eSagge3		if (ndx == 0 || ndx == 1)
2059ded074eSagge3			p = "%s";
2069ded074eSagge3		break;
2079ded074eSagge3]], v.ret), 2)
2089ded074eSagge3		end
2099ded074eSagge3
2109ded074eSagge3		gen:write(string.format("\t\t*n_args = %d;\n\t\tbreak;\n\t}\n",
2119ded074eSagge3		    n_args))
2129ded074eSagge3		gen:store("\t\tbreak;\n", 1)
2139ded074eSagge3
2149ded074eSagge3		-- Handle compat (everything >= FREEBSD3):
2159ded074eSagge3		-- Do nothing, only for native.
2169ded074eSagge3		end
2179ded074eSagge3	end
2189ded074eSagge3
219*42d075f4SBrooks Davis	gen:write(tbl.epilog)
2209ded074eSagge3	gen:write([[
2219ded074eSagge3	default:
2229ded074eSagge3		*n_args = 0;
2239ded074eSagge3		break;
2249ded074eSagge3	};
2259ded074eSagge3}
2269ded074eSagge3]])
227*42d075f4SBrooks Davis
228*42d075f4SBrooks Davis	gen:store(tbl.epilog, 1)
2299ded074eSagge3	gen:store([[
2309ded074eSagge3	default:
2319ded074eSagge3		break;
2329ded074eSagge3	};
2339ded074eSagge3	if (p != NULL)
2349ded074eSagge3		strlcpy(desc, p, descsz);
2359ded074eSagge3}
2369ded074eSagge3]], 1)
237*42d075f4SBrooks Davis
238*42d075f4SBrooks Davis	gen:store(tbl.epilog, 2)
2399ded074eSagge3	gen:store([[
2409ded074eSagge3	default:
2419ded074eSagge3		break;
2429ded074eSagge3	};
2439ded074eSagge3	if (p != NULL)
2449ded074eSagge3		strlcpy(desc, p, descsz);
2459ded074eSagge3}
2469ded074eSagge3]], 2)
2479ded074eSagge3
2489ded074eSagge3	-- Write all stored lines.
2499ded074eSagge3	if gen.storage_levels ~= nil then
2509ded074eSagge3		gen:writeStorage()
2519ded074eSagge3	end
2529ded074eSagge3
2539ded074eSagge3end
2549ded074eSagge3
2559ded074eSagge3-- Entry of script:
2569ded074eSagge3if script then
2579ded074eSagge3	local config = require("config")
2589ded074eSagge3
2599ded074eSagge3	if #arg < 1 or #arg > 2 then
2609ded074eSagge3		error("usage: " .. arg[0] .. " syscall.master")
2619ded074eSagge3	end
2629ded074eSagge3
2639ded074eSagge3	local sysfile, configfile = arg[1], arg[2]
2649ded074eSagge3
2659ded074eSagge3	config.merge(configfile)
2669ded074eSagge3	config.mergeCompat()
2679ded074eSagge3
2689ded074eSagge3	-- The parsed system call table.
2699ded074eSagge3	local tbl = FreeBSDSyscall:new{sysfile = sysfile, config = config}
2709ded074eSagge3
2719ded074eSagge3	systrace_args.file = config.systrace	-- change file here
2729ded074eSagge3	systrace_args.generate(tbl, config, systrace_args.file)
2739ded074eSagge3end
2749ded074eSagge3
2759ded074eSagge3-- Return the module.
2769ded074eSagge3return systrace_args
277