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