Path: blob/main/sys/tools/syscalls/scripts/sysproto_h.lua
39530 views
#!/usr/libexec/flua1--2-- SPDX-License-Identifier: BSD-2-Clause3--4-- Copyright (c) 2024 Tyler Baxter <[email protected]>5-- Copyright (c) 2019 Kyle Evans <[email protected]>6--78-- Setup to be a module, or ran as its own script.9local sysproto_h = {}10local script = not pcall(debug.getlocal, 4, 1) -- TRUE if script.11if script then12-- Add library root to the package path.13local path = arg[0]:gsub("/[^/]+.lua$", "")14package.path = package.path .. ";" .. path .. "/../?.lua"15end1617local FreeBSDSyscall = require("core.freebsd-syscall")18local generator = require("tools.generator")1920-- File has not been decided yet; config will decide file. Default defined as21-- /dev/null.22sysproto_h.file = "/dev/null"2324function sysproto_h.generate(tbl, config, fh)25-- Grab the master system calls table.26local s = tbl.syscalls2728-- Bind the generator to the parameter file.29local gen = generator:new({}, fh)30gen.storage_levels = {} -- make sure storage is clear3132-- Write the generated preamble.33gen:preamble("System call prototypes.")3435-- Write out all the preprocessor directives.36gen:write(string.format([[37#ifndef %s38#define %s3940#include <sys/types.h>41#include <sys/signal.h>42#include <sys/cpuset.h>43#include <sys/domainset.h>44#include <sys/_ffcounter.h>45#include <sys/_semaphore.h>46#include <sys/ucontext.h>47#include <sys/wait.h>4849#include <bsm/audit_kevents.h>5051struct proc;5253struct thread;5455#define PAD_(t) (sizeof(syscallarg_t) <= sizeof(t) ? \560 : sizeof(syscallarg_t) - sizeof(t))5758#if BYTE_ORDER == LITTLE_ENDIAN59#define PADL_(t) 060#define PADR_(t) PAD_(t)61#else62#define PADL_(t) PAD_(t)63#define PADR_(t) 064#endif6566]], config.sysproto_h, config.sysproto_h))6768-- 64-bit padding preprocessor directive.69gen:pad64(config.abiChanges("pair_64bit"))7071--72-- Storing each compat entry requires storing multiple levels of file73-- generation; compat entries are given ranges of 10 instead to cope74-- with this. For example, 13 is indexed as 130; 131 is the second75-- storage level of 13.76--7778-- Store all the compat #ifdef from compat_options at their zero index.79for _, v in pairs(config.compat_options) do80-- Tag an extra newline to the end, so it doesn't have to be81-- worried about later.82gen:store(string.format("\n#ifdef %s\n\n", v.definition),83v.compatlevel * 10)84end8586for _, v in pairs(s) do87local c = v:compatLevel()8889-- Audit defines are stored at an arbitrarily large number so90-- that they're always at the last storage level, and compat91-- entries can be indexed by their compat level (more92-- intuitive).93local audit_idx = 10000 -- this should do9495gen:write(v.prolog)96gen:store(v.prolog, 1)97for _, w in pairs(config.compat_options) do98gen:store(v.prolog, w.compatlevel * 10)99end100101-- Handle non-compat:102if v:native() then103-- All these negation conditions are because (in104-- general) these are cases where code for sysproto.h105-- is not generated.106if not v.type.NOARGS and not v.type.NOPROTO and107not v.type.NODEF then108if #v.args > 0 then109gen:write(string.format(110"struct %s {\n", v.arg_alias))111for _, arg in ipairs(v.args) do112if arg.type == "int" and113arg.name == "_pad" and114config.abiChanges(115"pair_64bit") then116gen:write("#ifdef PAD64_REQUIRED\n")117end118119gen:write(string.format([[120char %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];121]],122arg.name, arg.type,123arg.type, arg.name,124arg.name, arg.type))125126if arg.type == "int" and127arg.name == "_pad" and128config.abiChanges(129"pair_64bit") then130gen:write("#endif\n")131end132end133gen:write("};\n")134else135gen:write(string.format(136"struct %s {\n\tsyscallarg_t dummy;\n};\n",137v.arg_alias))138end139end140if not v.type.NOPROTO and not v.type.NODEF then141local sys_prefix = "sys_"142if v.name == "nosys" or v.name == "lkmnosys" or143v.name == "sysarch" or144v.name:find("^freebsd") or145v.name:find("^linux") then146sys_prefix = ""147end148gen:store(string.format(149"%s\t%s%s(struct thread *, struct %s *);\n",150v.rettype, sys_prefix, v.name, v.arg_alias),1511)152gen:store(string.format(153"#define\t%sAUE_%s\t%s\n",154config.syscallprefix, v:symbol(), v.audit),155audit_idx)156end157158-- Handle compat (everything >= FREEBSD3):159elseif c >= 3 then160local idx = c * 10161if not v.type.NOARGS and not v.type.NOPROTO and162not v.type.NODEF then163if #v.args > 0 then164gen:store(string.format(165"struct %s {\n", v.arg_alias), idx)166for _, arg in ipairs(v.args) do167gen:store(string.format([[168char %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];169]],170arg.name, arg.type,171arg.type, arg.name,172arg.name, arg.type), idx)173end174gen:store("};\n", idx)175else176-- Not stored, written on the first run.177gen:write(string.format([[178struct %s {179syscallarg_t dummy;180};181]],182v.arg_alias))183end184end185if not v.type.NOPROTO and not v.type.NODEF then186gen:store(string.format([[187%s %s%s(struct thread *, struct %s *);188]],189v.rettype, v:compatPrefix(), v.name,190v.arg_alias), idx + 1)191gen:store(string.format([[192#define %sAUE_%s%s %s193]],194config.syscallprefix, v:compatPrefix(),195v.name, v.audit), audit_idx)196end197end198-- Do nothing for obsolete, unimplemented, and reserved.199end200201-- Append #endif to the end of each compat option.202for _, v in pairs(config.compat_options) do203-- Based on how they're indexed, 9 is the last index.204local end_idx = (v.compatlevel * 10) + 9205-- Need an extra newline after #endif.206gen:store(string.format("\n#endif /* %s */\n\n", v.definition),207end_idx)208end209210gen:write(tbl.epilog)211gen:store(tbl.epilog, 1)212for _, w in pairs(config.compat_options) do213gen:store(tbl.epilog, w.compatlevel * 10)214end215216if gen.storage_levels ~= nil then217gen:writeStorage()218end219220-- After storage has been unrolled, tag on the ending bits.221gen:write(string.format([[222223#undef PAD_224#undef PADL_225#undef PADR_226227#endif /* !%s */228]], config.sysproto_h))229end230231-- Entry of script:232if script then233local config = require("config")234235if #arg < 1 or #arg > 2 then236error("usage: " .. arg[0] .. " syscall.master")237end238239local sysfile, configfile = arg[1], arg[2]240241config.merge(configfile)242config.mergeCompat()243244-- The parsed system call table.245local tbl = FreeBSDSyscall:new{sysfile = sysfile, config = config}246247sysproto_h.file = config.sysproto -- change file here248sysproto_h.generate(tbl, config, sysproto_h.file)249end250251-- Return the module.252return sysproto_h253254255