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