xref: /freebsd/sys/tools/syscalls/scripts/systrace_args.lua (revision 9ded074e875c29cb92d5f643801990d7bb23cca4)
1*9ded074eSagge3#!/usr/libexec/flua
2*9ded074eSagge3--
3*9ded074eSagge3-- SPDX-License-Identifier: BSD-2-Clause
4*9ded074eSagge3--
5*9ded074eSagge3-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org>
6*9ded074eSagge3-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com>
7*9ded074eSagge3-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
8*9ded074eSagge3--
9*9ded074eSagge3
10*9ded074eSagge3-- Setup to be a module, or ran as its own script.
11*9ded074eSagge3local systrace_args = {}
12*9ded074eSagge3local script = not pcall(debug.getlocal, 4, 1)	-- TRUE if script.
13*9ded074eSagge3if script then
14*9ded074eSagge3	-- Add library root to the package path.
15*9ded074eSagge3	local path = arg[0]:gsub("/[^/]+.lua$", "")
16*9ded074eSagge3	package.path = package.path .. ";" .. path .. "/../?.lua"
17*9ded074eSagge3end
18*9ded074eSagge3
19*9ded074eSagge3local FreeBSDSyscall = require("core.freebsd-syscall")
20*9ded074eSagge3local util = require("tools.util")
21*9ded074eSagge3local generator = require("tools.generator")
22*9ded074eSagge3
23*9ded074eSagge3-- File has not been decided yet; config will decide file.  Default defined as
24*9ded074eSagge3-- /dev/null.
25*9ded074eSagge3systrace_args.file = "/dev/null"
26*9ded074eSagge3
27*9ded074eSagge3function systrace_args.generate(tbl, config, fh)
28*9ded074eSagge3	-- Grab the master system calls table.
29*9ded074eSagge3	local s = tbl.syscalls
30*9ded074eSagge3
31*9ded074eSagge3	-- Bind the generator to the parameter file.
32*9ded074eSagge3	local gen = generator:new({}, fh)
33*9ded074eSagge3	gen.storage_levels = {}	-- make sure storage is clear
34*9ded074eSagge3
35*9ded074eSagge3	-- 64-bit padding preprocessor directive.
36*9ded074eSagge3	gen:pad64(config.abiChanges("pair_64bit"))
37*9ded074eSagge3
38*9ded074eSagge3	-- Write the generated preamble.
39*9ded074eSagge3	gen:preamble(
40*9ded074eSagge3	    "System call argument to DTrace register array conversion.\n" ..
41*9ded074eSagge3	    "\n" ..
42*9ded074eSagge3	    "This file is part of the DTrace syscall provider.")
43*9ded074eSagge3
44*9ded074eSagge3	gen:write(string.format([[
45*9ded074eSagge3static void
46*9ded074eSagge3systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
47*9ded074eSagge3{
48*9ded074eSagge3	int64_t *iarg = (int64_t *)uarg;
49*9ded074eSagge3	int a = 0;
50*9ded074eSagge3	switch (sysnum) {
51*9ded074eSagge3]]))
52*9ded074eSagge3
53*9ded074eSagge3	gen:store(string.format([[
54*9ded074eSagge3static void
55*9ded074eSagge3systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
56*9ded074eSagge3{
57*9ded074eSagge3	const char *p = NULL;
58*9ded074eSagge3	switch (sysnum) {
59*9ded074eSagge3]]), 1)
60*9ded074eSagge3
61*9ded074eSagge3	gen:store(string.format([[
62*9ded074eSagge3static void
63*9ded074eSagge3systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
64*9ded074eSagge3{
65*9ded074eSagge3	const char *p = NULL;
66*9ded074eSagge3	switch (sysnum) {
67*9ded074eSagge3]]), 2)
68*9ded074eSagge3
69*9ded074eSagge3	for _, v in pairs(s) do
70*9ded074eSagge3
71*9ded074eSagge3		-- Handle non compat:
72*9ded074eSagge3		if v:native() then
73*9ded074eSagge3			gen:write(string.format([[
74*9ded074eSagge3	/* %s */
75*9ded074eSagge3	case %d: {
76*9ded074eSagge3]], v.name, v.num))
77*9ded074eSagge3
78*9ded074eSagge3			gen:store(string.format([[
79*9ded074eSagge3	/* %s */
80*9ded074eSagge3	case %d:
81*9ded074eSagge3]], v.name, v.num), 1)
82*9ded074eSagge3
83*9ded074eSagge3			gen:store(string.format([[
84*9ded074eSagge3	/* %s */
85*9ded074eSagge3	case %d:
86*9ded074eSagge3]], v.name, v.num), 2)
87*9ded074eSagge3
88*9ded074eSagge3			local n_args = #v.args
89*9ded074eSagge3			if v.type.SYSMUX then
90*9ded074eSagge3				n_args = 0
91*9ded074eSagge3			end
92*9ded074eSagge3
93*9ded074eSagge3			if #v.args > 0 and not v.type.SYSMUX then
94*9ded074eSagge3				local padding = ""
95*9ded074eSagge3
96*9ded074eSagge3				gen:write(string.format([[
97*9ded074eSagge3		struct %s *p = params;
98*9ded074eSagge3]],
99*9ded074eSagge3				    v.arg_alias))
100*9ded074eSagge3
101*9ded074eSagge3				gen:store([[
102*9ded074eSagge3		switch (ndx) {
103*9ded074eSagge3]],
104*9ded074eSagge3				    1)
105*9ded074eSagge3
106*9ded074eSagge3				for idx, arg in ipairs(v.args) do
107*9ded074eSagge3					local argtype = util.trim(
108*9ded074eSagge3						arg.type:gsub(
109*9ded074eSagge3						    "__restrict$", ""), nil)
110*9ded074eSagge3					if argtype == "int" and
111*9ded074eSagge3					    arg.name == "_pad" and
112*9ded074eSagge3					    config.abiChanges("pair_64bit") then
113*9ded074eSagge3						gen:store(
114*9ded074eSagge3						    "#ifdef PAD64_REQUIRED\n",
115*9ded074eSagge3						    1)
116*9ded074eSagge3					end
117*9ded074eSagge3
118*9ded074eSagge3					-- Pointer arg?
119*9ded074eSagge3					local desc
120*9ded074eSagge3					if argtype:find("*") then
121*9ded074eSagge3						desc = "userland " .. argtype
122*9ded074eSagge3					else
123*9ded074eSagge3						desc = argtype;
124*9ded074eSagge3					end
125*9ded074eSagge3
126*9ded074eSagge3					gen:store(string.format([[
127*9ded074eSagge3		case %d%s:
128*9ded074eSagge3			p = "%s";
129*9ded074eSagge3			break;
130*9ded074eSagge3]],
131*9ded074eSagge3					    idx - 1, padding, desc), 1)
132*9ded074eSagge3
133*9ded074eSagge3					if argtype == "int" and
134*9ded074eSagge3					    arg.name == "_pad" and
135*9ded074eSagge3					   config.abiChanges("pair_64bit") then
136*9ded074eSagge3						padding = " - _P_"
137*9ded074eSagge3						gen:store([[
138*9ded074eSagge3#define _P_ 0
139*9ded074eSagge3#else
140*9ded074eSagge3#define _P_ 1
141*9ded074eSagge3#endif
142*9ded074eSagge3]],
143*9ded074eSagge3					    1)
144*9ded074eSagge3					end
145*9ded074eSagge3
146*9ded074eSagge3					if util.isPtrType(argtype,
147*9ded074eSagge3					    config.abi_intptr_t) then
148*9ded074eSagge3						gen:write(string.format([[
149*9ded074eSagge3		uarg[a++] = (%s)p->%s; /* %s */
150*9ded074eSagge3]],
151*9ded074eSagge3						    config.ptr_intptr_t_cast,
152*9ded074eSagge3						    arg.name, argtype))
153*9ded074eSagge3					elseif argtype == "union l_semun" then
154*9ded074eSagge3						gen:write(string.format([[
155*9ded074eSagge3		uarg[a++] = p->%s.buf; /* %s */
156*9ded074eSagge3]],
157*9ded074eSagge3						    arg.name, argtype))
158*9ded074eSagge3					elseif argtype:sub(1,1) == "u" or
159*9ded074eSagge3					    argtype == "size_t" then
160*9ded074eSagge3						gen:write(string.format([[
161*9ded074eSagge3		uarg[a++] = p->%s; /* %s */
162*9ded074eSagge3]],
163*9ded074eSagge3						    arg.name, argtype))
164*9ded074eSagge3					else
165*9ded074eSagge3						if argtype == "int" and
166*9ded074eSagge3						    arg.name == "_pad" and
167*9ded074eSagge3						    config.abiChanges(
168*9ded074eSagge3						    "pair_64bit") then
169*9ded074eSagge3							gen:write([[
170*9ded074eSagge3#ifdef PAD64_REQUIRED
171*9ded074eSagge3]])
172*9ded074eSagge3						end
173*9ded074eSagge3
174*9ded074eSagge3						gen:write(string.format([[
175*9ded074eSagge3		iarg[a++] = p->%s; /* %s */
176*9ded074eSagge3]],
177*9ded074eSagge3						    arg.name, argtype))
178*9ded074eSagge3
179*9ded074eSagge3						if argtype == "int" and
180*9ded074eSagge3						    arg.name == "_pad" and
181*9ded074eSagge3						    config.abiChanges(
182*9ded074eSagge3						    "pair_64bit") then
183*9ded074eSagge3							gen:write("#endif\n")
184*9ded074eSagge3						end
185*9ded074eSagge3					end
186*9ded074eSagge3				end
187*9ded074eSagge3
188*9ded074eSagge3				gen:store([[
189*9ded074eSagge3		default:
190*9ded074eSagge3			break;
191*9ded074eSagge3		};
192*9ded074eSagge3]],
193*9ded074eSagge3				    1)
194*9ded074eSagge3
195*9ded074eSagge3				if padding ~= "" then
196*9ded074eSagge3					gen:store("#undef _P_\n\n", 1)
197*9ded074eSagge3				end
198*9ded074eSagge3
199*9ded074eSagge3				gen:store(string.format([[
200*9ded074eSagge3		if (ndx == 0 || ndx == 1)
201*9ded074eSagge3			p = "%s";
202*9ded074eSagge3		break;
203*9ded074eSagge3]], v.ret), 2)
204*9ded074eSagge3		end
205*9ded074eSagge3
206*9ded074eSagge3		gen:write(string.format("\t\t*n_args = %d;\n\t\tbreak;\n\t}\n",
207*9ded074eSagge3		    n_args))
208*9ded074eSagge3		gen:store("\t\tbreak;\n", 1)
209*9ded074eSagge3
210*9ded074eSagge3		-- Handle compat (everything >= FREEBSD3):
211*9ded074eSagge3		-- Do nothing, only for native.
212*9ded074eSagge3		end
213*9ded074eSagge3	end
214*9ded074eSagge3
215*9ded074eSagge3	gen:write([[
216*9ded074eSagge3	default:
217*9ded074eSagge3		*n_args = 0;
218*9ded074eSagge3		break;
219*9ded074eSagge3	};
220*9ded074eSagge3}
221*9ded074eSagge3]])
222*9ded074eSagge3	gen:store([[
223*9ded074eSagge3	default:
224*9ded074eSagge3		break;
225*9ded074eSagge3	};
226*9ded074eSagge3	if (p != NULL)
227*9ded074eSagge3		strlcpy(desc, p, descsz);
228*9ded074eSagge3}
229*9ded074eSagge3]], 1)
230*9ded074eSagge3	gen:store([[
231*9ded074eSagge3	default:
232*9ded074eSagge3		break;
233*9ded074eSagge3	};
234*9ded074eSagge3	if (p != NULL)
235*9ded074eSagge3		strlcpy(desc, p, descsz);
236*9ded074eSagge3}
237*9ded074eSagge3]], 2)
238*9ded074eSagge3
239*9ded074eSagge3	-- Write all stored lines.
240*9ded074eSagge3	if gen.storage_levels ~= nil then
241*9ded074eSagge3		gen:writeStorage()
242*9ded074eSagge3	end
243*9ded074eSagge3
244*9ded074eSagge3end
245*9ded074eSagge3
246*9ded074eSagge3-- Entry of script:
247*9ded074eSagge3if script then
248*9ded074eSagge3	local config = require("config")
249*9ded074eSagge3
250*9ded074eSagge3	if #arg < 1 or #arg > 2 then
251*9ded074eSagge3		error("usage: " .. arg[0] .. " syscall.master")
252*9ded074eSagge3	end
253*9ded074eSagge3
254*9ded074eSagge3	local sysfile, configfile = arg[1], arg[2]
255*9ded074eSagge3
256*9ded074eSagge3	config.merge(configfile)
257*9ded074eSagge3	config.mergeCompat()
258*9ded074eSagge3	config.mergeCapability()
259*9ded074eSagge3
260*9ded074eSagge3	-- The parsed system call table.
261*9ded074eSagge3	local tbl = FreeBSDSyscall:new{sysfile = sysfile, config = config}
262*9ded074eSagge3
263*9ded074eSagge3	systrace_args.file = config.systrace	-- change file here
264*9ded074eSagge3	systrace_args.generate(tbl, config, systrace_args.file)
265*9ded074eSagge3end
266*9ded074eSagge3
267*9ded074eSagge3-- Return the module.
268*9ded074eSagge3return systrace_args
269