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) 2019 Kyle Evans <kevans@FreeBSD.org> 7*9ded074eSagge3-- 8*9ded074eSagge3 9*9ded074eSagge3-- Setup to be a module, or ran as its own script. 10*9ded074eSagge3local sysproto_h = {} 11*9ded074eSagge3local script = not pcall(debug.getlocal, 4, 1) -- TRUE if script. 12*9ded074eSagge3if script then 13*9ded074eSagge3 -- Add library root to the package path. 14*9ded074eSagge3 local path = arg[0]:gsub("/[^/]+.lua$", "") 15*9ded074eSagge3 package.path = package.path .. ";" .. path .. "/../?.lua" 16*9ded074eSagge3end 17*9ded074eSagge3 18*9ded074eSagge3local FreeBSDSyscall = require("core.freebsd-syscall") 19*9ded074eSagge3local generator = require("tools.generator") 20*9ded074eSagge3 21*9ded074eSagge3-- File has not been decided yet; config will decide file. Default defined as 22*9ded074eSagge3-- /dev/null. 23*9ded074eSagge3sysproto_h.file = "/dev/null" 24*9ded074eSagge3 25*9ded074eSagge3function sysproto_h.generate(tbl, config, fh) 26*9ded074eSagge3 -- Grab the master system calls table. 27*9ded074eSagge3 local s = tbl.syscalls 28*9ded074eSagge3 29*9ded074eSagge3 -- Bind the generator to the parameter file. 30*9ded074eSagge3 local gen = generator:new({}, fh) 31*9ded074eSagge3 gen.storage_levels = {} -- make sure storage is clear 32*9ded074eSagge3 33*9ded074eSagge3 -- Write the generated preamble. 34*9ded074eSagge3 gen:preamble("System call prototypes.") 35*9ded074eSagge3 36*9ded074eSagge3 -- Write out all the preprocessor directives. 37*9ded074eSagge3 gen:write(string.format([[ 38*9ded074eSagge3#ifndef %s 39*9ded074eSagge3#define %s 40*9ded074eSagge3 41*9ded074eSagge3#include <sys/types.h> 42*9ded074eSagge3#include <sys/signal.h> 43*9ded074eSagge3#include <sys/cpuset.h> 44*9ded074eSagge3#include <sys/domainset.h> 45*9ded074eSagge3#include <sys/_ffcounter.h> 46*9ded074eSagge3#include <sys/_semaphore.h> 47*9ded074eSagge3#include <sys/ucontext.h> 48*9ded074eSagge3#include <sys/wait.h> 49*9ded074eSagge3 50*9ded074eSagge3#include <bsm/audit_kevents.h> 51*9ded074eSagge3 52*9ded074eSagge3struct proc; 53*9ded074eSagge3 54*9ded074eSagge3struct thread; 55*9ded074eSagge3 56*9ded074eSagge3#define PAD_(t) (sizeof(syscallarg_t) <= sizeof(t) ? \ 57*9ded074eSagge3 0 : sizeof(syscallarg_t) - sizeof(t)) 58*9ded074eSagge3 59*9ded074eSagge3#if BYTE_ORDER == LITTLE_ENDIAN 60*9ded074eSagge3#define PADL_(t) 0 61*9ded074eSagge3#define PADR_(t) PAD_(t) 62*9ded074eSagge3#else 63*9ded074eSagge3#define PADL_(t) PAD_(t) 64*9ded074eSagge3#define PADR_(t) 0 65*9ded074eSagge3#endif 66*9ded074eSagge3 67*9ded074eSagge3]], config.sysproto_h, config.sysproto_h)) 68*9ded074eSagge3 69*9ded074eSagge3 -- 64-bit padding preprocessor directive. 70*9ded074eSagge3 gen:pad64(config.abiChanges("pair_64bit")) 71*9ded074eSagge3 72*9ded074eSagge3 -- 73*9ded074eSagge3 -- Storing each compat entry requires storing multiple levels of file 74*9ded074eSagge3 -- generation; compat entries are given ranges of 10 instead to cope 75*9ded074eSagge3 -- with this. For example, 13 is indexed as 130; 131 is the second 76*9ded074eSagge3 -- storage level of 13. 77*9ded074eSagge3 -- 78*9ded074eSagge3 79*9ded074eSagge3 -- Store all the compat #ifdef from compat_options at their zero index. 80*9ded074eSagge3 for _, v in pairs(config.compat_options) do 81*9ded074eSagge3 -- Tag an extra newline to the end, so it doesn't have to be 82*9ded074eSagge3 -- worried about later. 83*9ded074eSagge3 gen:store(string.format("\n#ifdef %s\n\n", v.definition), 84*9ded074eSagge3 v.compatlevel * 10) 85*9ded074eSagge3 end 86*9ded074eSagge3 87*9ded074eSagge3 for _, v in pairs(s) do 88*9ded074eSagge3 local c = v:compatLevel() 89*9ded074eSagge3 90*9ded074eSagge3 -- Audit defines are stored at an arbitrarily large number so 91*9ded074eSagge3 -- that they're always at the last storage level, and compat 92*9ded074eSagge3 -- entries can be indexed by their compat level (more 93*9ded074eSagge3 -- intuitive). 94*9ded074eSagge3 local audit_idx = 10000 -- this should do 95*9ded074eSagge3 96*9ded074eSagge3 -- Handle non-compat: 97*9ded074eSagge3 if v:native() then 98*9ded074eSagge3 -- All these negation conditions are because (in 99*9ded074eSagge3 -- general) these are cases where code for sysproto.h 100*9ded074eSagge3 -- is not generated. 101*9ded074eSagge3 if not v.type.NOARGS and not v.type.NOPROTO and 102*9ded074eSagge3 not v.type.NODEF then 103*9ded074eSagge3 if #v.args > 0 then 104*9ded074eSagge3 gen:write(string.format( 105*9ded074eSagge3 "struct %s {\n", v.arg_alias)) 106*9ded074eSagge3 for _, arg in ipairs(v.args) do 107*9ded074eSagge3 if arg.type == "int" and 108*9ded074eSagge3 arg.name == "_pad" and 109*9ded074eSagge3 config.abiChanges( 110*9ded074eSagge3 "pair_64bit") then 111*9ded074eSagge3 gen:write("#ifdef PAD64_REQUIRED\n") 112*9ded074eSagge3 end 113*9ded074eSagge3 114*9ded074eSagge3 gen:write(string.format([[ 115*9ded074eSagge3 char %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)]; 116*9ded074eSagge3]], 117*9ded074eSagge3 arg.name, arg.type, 118*9ded074eSagge3 arg.type, arg.name, 119*9ded074eSagge3 arg.name, arg.type)) 120*9ded074eSagge3 121*9ded074eSagge3 if arg.type == "int" and 122*9ded074eSagge3 arg.name == "_pad" and 123*9ded074eSagge3 config.abiChanges( 124*9ded074eSagge3 "pair_64bit") then 125*9ded074eSagge3 gen:write("#endif\n") 126*9ded074eSagge3 end 127*9ded074eSagge3 end 128*9ded074eSagge3 gen:write("};\n") 129*9ded074eSagge3 else 130*9ded074eSagge3 gen:write(string.format( 131*9ded074eSagge3 "struct %s {\n\tsyscallarg_t dummy;\n};\n", 132*9ded074eSagge3 v.arg_alias)) 133*9ded074eSagge3 end 134*9ded074eSagge3 end 135*9ded074eSagge3 if not v.type.NOPROTO and not v.type.NODEF then 136*9ded074eSagge3 local sys_prefix = "sys_" 137*9ded074eSagge3 if v.name == "nosys" or v.name == "lkmnosys" or 138*9ded074eSagge3 v.name == "sysarch" or 139*9ded074eSagge3 v.name:find("^freebsd") or 140*9ded074eSagge3 v.name:find("^linux") then 141*9ded074eSagge3 sys_prefix = "" 142*9ded074eSagge3 end 143*9ded074eSagge3 gen:store(string.format( 144*9ded074eSagge3 "%s\t%s%s(struct thread *, struct %s *);\n", 145*9ded074eSagge3 v.rettype, sys_prefix, v.name, v.arg_alias), 146*9ded074eSagge3 1) 147*9ded074eSagge3 gen:store(string.format( 148*9ded074eSagge3 "#define\t%sAUE_%s\t%s\n", 149*9ded074eSagge3 config.syscallprefix, v:symbol(), v.audit), 150*9ded074eSagge3 audit_idx) 151*9ded074eSagge3 end 152*9ded074eSagge3 153*9ded074eSagge3 -- Handle compat (everything >= FREEBSD3): 154*9ded074eSagge3 elseif c >= 3 then 155*9ded074eSagge3 local idx = c * 10 156*9ded074eSagge3 if not v.type.NOARGS and not v.type.NOPROTO and 157*9ded074eSagge3 not v.type.NODEF then 158*9ded074eSagge3 if #v.args > 0 then 159*9ded074eSagge3 gen:store(string.format( 160*9ded074eSagge3 "struct %s {\n", v.arg_alias), idx) 161*9ded074eSagge3 for _, arg in ipairs(v.args) do 162*9ded074eSagge3 gen:store(string.format([[ 163*9ded074eSagge3 char %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)]; 164*9ded074eSagge3]], 165*9ded074eSagge3 arg.name, arg.type, 166*9ded074eSagge3 arg.type, arg.name, 167*9ded074eSagge3 arg.name, arg.type), idx) 168*9ded074eSagge3 end 169*9ded074eSagge3 gen:store("};\n", idx) 170*9ded074eSagge3 else 171*9ded074eSagge3 -- Not stored, written on the first run. 172*9ded074eSagge3 gen:write(string.format([[ 173*9ded074eSagge3struct %s { 174*9ded074eSagge3 syscallarg_t dummy; 175*9ded074eSagge3}; 176*9ded074eSagge3]], 177*9ded074eSagge3 v.arg_alias)) 178*9ded074eSagge3 end 179*9ded074eSagge3 end 180*9ded074eSagge3 if not v.type.NOPROTO and not v.type.NODEF then 181*9ded074eSagge3 gen:store(string.format([[ 182*9ded074eSagge3%s %s%s(struct thread *, struct %s *); 183*9ded074eSagge3]], 184*9ded074eSagge3 v.rettype, v:compatPrefix(), v.name, 185*9ded074eSagge3 v.arg_alias), idx + 1) 186*9ded074eSagge3 gen:store(string.format([[ 187*9ded074eSagge3#define %sAUE_%s%s %s 188*9ded074eSagge3]], 189*9ded074eSagge3 config.syscallprefix, v:compatPrefix(), 190*9ded074eSagge3 v.name, v.audit), audit_idx) 191*9ded074eSagge3 end 192*9ded074eSagge3 end 193*9ded074eSagge3 -- Do nothing for obsolete, unimplemented, and reserved. 194*9ded074eSagge3 end 195*9ded074eSagge3 196*9ded074eSagge3 -- Append #endif to the end of each compat option. 197*9ded074eSagge3 for _, v in pairs(config.compat_options) do 198*9ded074eSagge3 -- Based on how they're indexed, 9 is the last index. 199*9ded074eSagge3 local end_idx = (v.compatlevel * 10) + 9 200*9ded074eSagge3 -- Need an extra newline after #endif. 201*9ded074eSagge3 gen:store(string.format("\n#endif /* %s */\n\n", v.definition), 202*9ded074eSagge3 end_idx) 203*9ded074eSagge3 end 204*9ded074eSagge3 205*9ded074eSagge3 if gen.storage_levels ~= nil then 206*9ded074eSagge3 gen:writeStorage() 207*9ded074eSagge3 end 208*9ded074eSagge3 209*9ded074eSagge3 -- After storage has been unrolled, tag on the ending bits. 210*9ded074eSagge3 gen:write(string.format([[ 211*9ded074eSagge3 212*9ded074eSagge3#undef PAD_ 213*9ded074eSagge3#undef PADL_ 214*9ded074eSagge3#undef PADR_ 215*9ded074eSagge3 216*9ded074eSagge3#endif /* !%s */ 217*9ded074eSagge3]], config.sysproto_h)) 218*9ded074eSagge3end 219*9ded074eSagge3 220*9ded074eSagge3-- Entry of script: 221*9ded074eSagge3if script then 222*9ded074eSagge3 local config = require("config") 223*9ded074eSagge3 224*9ded074eSagge3 if #arg < 1 or #arg > 2 then 225*9ded074eSagge3 error("usage: " .. arg[0] .. " syscall.master") 226*9ded074eSagge3 end 227*9ded074eSagge3 228*9ded074eSagge3 local sysfile, configfile = arg[1], arg[2] 229*9ded074eSagge3 230*9ded074eSagge3 config.merge(configfile) 231*9ded074eSagge3 config.mergeCompat() 232*9ded074eSagge3 config.mergeCapability() 233*9ded074eSagge3 234*9ded074eSagge3 -- The parsed system call table. 235*9ded074eSagge3 local tbl = FreeBSDSyscall:new{sysfile = sysfile, config = config} 236*9ded074eSagge3 237*9ded074eSagge3 sysproto_h.file = config.sysproto -- change file here 238*9ded074eSagge3 sysproto_h.generate(tbl, config, sysproto_h.file) 239*9ded074eSagge3end 240*9ded074eSagge3 241*9ded074eSagge3-- Return the module. 242*9ded074eSagge3return sysproto_h 243