aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/tools/makesyscalls.lua1710
1 files changed, 0 insertions, 1710 deletions
diff --git a/sys/tools/makesyscalls.lua b/sys/tools/makesyscalls.lua
deleted file mode 100644
index 7e3116107483..000000000000
--- a/sys/tools/makesyscalls.lua
+++ /dev/null
@@ -1,1710 +0,0 @@
---
--- SPDX-License-Identifier: BSD-2-Clause
---
--- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
---
--- Redistribution and use in source and binary forms, with or without
--- modification, are permitted provided that the following conditions
--- are met:
--- 1. Redistributions of source code must retain the above copyright
--- notice, this list of conditions and the following disclaimer.
--- 2. Redistributions in binary form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
--- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
--- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
--- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
--- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
--- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
--- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
--- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
--- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
--- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
--- SUCH DAMAGE.
---
-
-
--- We generally assume that this script will be run by flua, however we've
--- carefully crafted modules for it that mimic interfaces provided by modules
--- available in ports. Currently, this script is compatible with lua from ports
--- along with the compatible luafilesystem and lua-posix modules.
-local lfs = require("lfs")
-local unistd = require("posix.unistd")
-
-local savesyscall = -1
-local maxsyscall = -1
-local structs = {}
-local generated_tag = "@" .. "generated"
-
--- Default configuration; any of these may get replaced by a configuration file
--- optionally specified.
-local config = {
- os_id_keyword = "FreeBSD", -- obsolete, ignored on input, not generated
- abi_func_prefix = "",
- libsysmap = "/dev/null",
- libsys_h = "/dev/null",
- sysnames = "syscalls.c",
- sysproto = "../sys/sysproto.h",
- sysproto_h = "_SYS_SYSPROTO_H_",
- syshdr = "../sys/syscall.h",
- sysmk = "/dev/null",
- syssw = "init_sysent.c",
- syscallprefix = "SYS_",
- switchname = "sysent",
- namesname = "syscallnames",
- systrace = "systrace_args.c",
- capabilities_conf = "capabilities.conf",
- capenabled = {},
- compat_set = "native",
- mincompat = 0,
- abi_type_suffix = "",
- abi_flags = "",
- abi_flags_mask = 0,
- abi_headers = "",
- abi_intptr_t = "intptr_t",
- abi_size_t = "size_t",
- abi_u_long = "u_long",
- abi_long = "long",
- abi_semid_t = "semid_t",
- abi_ptr_array_t = "",
- ptr_intptr_t_cast = "intptr_t",
- syscall_abi_change = "",
- sys_abi_change = {},
- syscall_no_abi_change = "",
- sys_no_abi_change = {},
- obsol = "",
- obsol_dict = {},
- unimpl = "",
- unimpl_dict = {},
-}
-
-local config_modified = {}
-local cleantmp = true
-local tmpspace = "/tmp/sysent." .. unistd.getpid() .. "/"
-
-local output_files = {
- "sysnames",
- "syshdr",
- "sysmk",
- "libsysmap",
- "libsys_h",
- "syssw",
- "systrace",
- "sysproto",
-}
-
--- These ones we'll create temporary files for; generation purposes.
-local temp_files = {
- "libsys_h_type",
- "libsys_h_func",
- "sysaue",
- "sysdcl",
- "syscompat",
- "syscompatdcl",
- "sysent",
- "sysinc",
- "sysarg",
- "sysprotoend",
- "systracetmp",
- "systraceret",
-}
-
--- Opened files
-local files = {}
-
-local function cleanup()
- for _, v in pairs(files) do
- assert(v:close())
- end
- if cleantmp then
- if lfs.dir(tmpspace) then
- for fname in lfs.dir(tmpspace) do
- if fname ~= "." and fname ~= ".." then
- assert(os.remove(tmpspace .. "/" ..
- fname))
- end
- end
- end
-
- if lfs.attributes(tmpspace) and not lfs.rmdir(tmpspace) then
- assert(io.stderr:write("Failed to clean up tmpdir: " ..
- tmpspace .. "\n"))
- end
- else
- assert(io.stderr:write("Temp files left in " .. tmpspace ..
- "\n"))
- end
-end
-
-local function abort(status, msg)
- assert(io.stderr:write(msg .. "\n"))
- cleanup()
- os.exit(status)
-end
-
--- Each entry should have a value so we can represent abi flags as a bitmask
--- for convenience. One may also optionally provide an expr; this gets applied
--- to each argument type to indicate whether this argument is subject to ABI
--- change given the configured flags.
-local known_abi_flags = {
- long_size = {
- value = 0x00000001,
- exprs = {
- "_Contains[a-z_]*_long_",
- "^long [a-z0-9_]+$",
- "long [*]",
- "size_t [*]",
- -- semid_t is not included because it is only used
- -- as an argument or written out individually and
- -- said writes are handled by the ksem framework.
- -- Technically a sign-extension issue exists for
- -- arguments, but because semid_t is actually a file
- -- descriptor negative 32-bit values are invalid
- -- regardless of sign-extension.
- },
- },
- time_t_size = {
- value = 0x00000002,
- exprs = {
- "_Contains[a-z_]*_timet_",
- },
- },
- pointer_args = {
- value = 0x00000004,
- },
- pointer_size = {
- value = 0x00000008,
- exprs = {
- "_Contains[a-z_]*_ptr_",
- "[*][*]",
- },
- },
- pair_64bit = {
- value = 0x00000010,
- exprs = {
- "^dev_t[ ]*$",
- "^id_t[ ]*$",
- "^off_t[ ]*$",
- },
- },
-}
-
-local known_flags = {
- STD = 0x00000001,
- OBSOL = 0x00000002,
- RESERVED = 0x00000004,
- UNIMPL = 0x00000008,
- NODEF = 0x00000010,
- NOARGS = 0x00000020,
- NOPROTO = 0x00000040,
- NOSTD = 0x00000080,
- NOTSTATIC = 0x00000100,
- CAPENABLED = 0x00000200,
- SYSMUX = 0x00000400,
-
- -- Compat flags start from here. We have plenty of space.
-}
-
--- All compat option entries should have five entries:
--- definition: The preprocessor macro that will be set for this
--- compatlevel: The level this compatibility should be included at. This
--- generally represents the version of FreeBSD that it is compatible
--- with, but ultimately it's just the level of mincompat in which it's
--- included.
--- flag: The name of the flag in syscalls.master.
--- prefix: The prefix to use for _args and syscall prototype. This will be
--- used as-is, without "_" or any other character appended.
--- descr: The description of this compat option in init_sysent.c comments.
--- The special "stdcompat" entry will cause the other five to be autogenerated.
-local compat_option_sets = {
- native = {
- {
- definition = "COMPAT_43",
- compatlevel = 3,
- flag = "COMPAT",
- prefix = "o",
- descr = "old",
- },
- { stdcompat = "FREEBSD4" },
- { stdcompat = "FREEBSD6" },
- { stdcompat = "FREEBSD7" },
- { stdcompat = "FREEBSD10" },
- { stdcompat = "FREEBSD11" },
- { stdcompat = "FREEBSD12" },
- { stdcompat = "FREEBSD13" },
- { stdcompat = "FREEBSD14" },
- },
-}
-
--- compat_options will be resolved to a set from the configuration.
-local compat_options
-
-local function trim(s, char)
- if s == nil then
- return nil
- end
- if char == nil then
- char = "%s"
- end
- return s:gsub("^" .. char .. "+", ""):gsub(char .. "+$", "")
-end
-
--- config looks like a shell script; in fact, the previous makesyscalls.sh
--- script actually sourced it in. It had a pretty common format, so we should
--- be fine to make various assumptions
-local function process_config(file)
- local cfg = {}
- local comment_line_expr = "^%s*#.*"
- -- We capture any whitespace padding here so we can easily advance to
- -- the end of the line as needed to check for any trailing bogus bits.
- -- Alternatively, we could drop the whitespace and instead try to
- -- use a pattern to strip out the meaty part of the line, but then we
- -- would need to sanitize the line for potentially special characters.
- local line_expr = "^([%w%p]+%s*)=(%s*[`\"]?[^\"`]*[`\"]?)"
-
- if not file then
- return nil, "No file given"
- end
-
- local fh = assert(io.open(file))
-
- for nextline in fh:lines() do
- -- Strip any whole-line comments
- nextline = nextline:gsub(comment_line_expr, "")
- -- Parse it into key, value pairs
- local key, value = nextline:match(line_expr)
- if key ~= nil and value ~= nil then
- local kvp = key .. "=" .. value
- key = trim(key)
- value = trim(value)
- local delim = value:sub(1,1)
- if delim == '"' then
- local trailing_context
-
- -- Strip off the key/value part
- trailing_context = nextline:sub(kvp:len() + 1)
- -- Strip off any trailing comment
- trailing_context = trailing_context:gsub("#.*$",
- "")
- -- Strip off leading/trailing whitespace
- trailing_context = trim(trailing_context)
- if trailing_context ~= "" then
- print(trailing_context)
- abort(1, "Malformed line: " .. nextline)
- end
-
- value = trim(value, delim)
- else
- -- Strip off potential comments
- value = value:gsub("#.*$", "")
- -- Strip off any padding whitespace
- value = trim(value)
- if value:match("%s") then
- abort(1, "Malformed config line: " ..
- nextline)
- end
- end
- cfg[key] = value
- elseif not nextline:match("^%s*$") then
- -- Make sure format violations don't get overlooked
- -- here, but ignore blank lines. Comments are already
- -- stripped above.
- abort(1, "Malformed config line: " .. nextline)
- end
- end
-
- assert(io.close(fh))
- return cfg
-end
-
-local function grab_capenabled(file, open_fail_ok)
- local capentries = {}
- local commentExpr = "#.*"
-
- if file == nil then
- print "No file"
- return {}
- end
-
- local fh = io.open(file)
- if fh == nil then
- if not open_fail_ok then
- abort(1, "Failed to open " .. file)
- end
- return {}
- end
-
- for nextline in fh:lines() do
- -- Strip any comments
- nextline = nextline:gsub(commentExpr, "")
- if nextline ~= "" then
- capentries[nextline] = true
- end
- end
-
- assert(io.close(fh))
- return capentries
-end
-
-local function process_compat()
- local nval = 0
- for _, v in pairs(known_flags) do
- if v > nval then
- nval = v
- end
- end
-
- nval = nval << 1
- for _, v in pairs(compat_options) do
- if v.stdcompat ~= nil then
- local stdcompat = v.stdcompat
- v.definition = "COMPAT_" .. stdcompat:upper()
- v.compatlevel = tonumber(stdcompat:match("([0-9]+)$"))
- v.flag = stdcompat:gsub("FREEBSD", "COMPAT")
- v.prefix = stdcompat:lower() .. "_"
- v.descr = stdcompat:lower()
- end
-
- local tmpname = "sys" .. v.flag:lower()
- local dcltmpname = tmpname .. "dcl"
- files[tmpname] = io.tmpfile()
- files[dcltmpname] = io.tmpfile()
- v.tmp = tmpname
- v.dcltmp = dcltmpname
-
- known_flags[v.flag] = nval
- v.mask = nval
- nval = nval << 1
-
- v.count = 0
- end
-end
-
-local function process_abi_flags()
- local flags, mask = config.abi_flags, 0
- for txtflag in flags:gmatch("([^|]+)") do
- if known_abi_flags[txtflag] == nil then
- abort(1, "Unknown abi_flag: " .. txtflag)
- end
-
- mask = mask | known_abi_flags[txtflag].value
- end
-
- config.abi_flags_mask = mask
-end
-
-local function process_obsol()
- local obsol = config.obsol
- for syscall in obsol:gmatch("([^ ]+)") do
- config.obsol_dict[syscall] = true
- end
-end
-
-local function process_unimpl()
- local unimpl = config.unimpl
- for syscall in unimpl:gmatch("([^ ]+)") do
- config.unimpl_dict[syscall] = true
- end
-end
-
-local function process_syscall_abi_change()
- local changes_abi = config.syscall_abi_change
- for syscall in changes_abi:gmatch("([^ ]+)") do
- config.sys_abi_change[syscall] = true
- end
-
- local no_changes = config.syscall_no_abi_change
- for syscall in no_changes:gmatch("([^ ]+)") do
- config.sys_no_abi_change[syscall] = true
- end
-end
-
-local function abi_changes(name)
- if known_abi_flags[name] == nil then
- abort(1, "abi_changes: unknown flag: " .. name)
- end
-
- return config.abi_flags_mask & known_abi_flags[name].value ~= 0
-end
-
-local function strip_abi_prefix(funcname)
- local abiprefix = config.abi_func_prefix
- local stripped_name
- if funcname == nil then
- return nil
- end
- if abiprefix ~= "" and funcname:find("^" .. abiprefix) then
- stripped_name = funcname:gsub("^" .. abiprefix, "")
- else
- stripped_name = funcname
- end
-
- return stripped_name
-end
-
-local function read_file(tmpfile)
- if files[tmpfile] == nil then
- print("Not found: " .. tmpfile)
- return
- end
-
- local fh = files[tmpfile]
- assert(fh:seek("set"))
- return assert(fh:read("a"))
-end
-
-local function write_line(tmpfile, line)
- if files[tmpfile] == nil then
- print("Not found: " .. tmpfile)
- return
- end
- assert(files[tmpfile]:write(line))
-end
-
-local function write_line_pfile(tmppat, line)
- for k in pairs(files) do
- if k:match(tmppat) ~= nil then
- assert(files[k]:write(line))
- end
- end
-end
-
--- Check both literal intptr_t and the abi version because this needs
--- to work both before and after the substitution
-local function isptrtype(type)
- return type:find("*") or type:find("caddr_t") or
- type:find("intptr_t") or type:find(config.abi_intptr_t)
-end
-
-local function isptrarraytype(type)
- return type:find("[*][*]") or type:find("[*][ ]*const[ ]*[*]")
-end
-
--- Find types that are always 64-bits wide
-local function is64bittype(type)
- return type:find("^dev_t[ ]*$") or type:find("^id_t[ ]*$") or type:find("^off_t[ ]*$")
-end
-
-local process_syscall_def
-
--- These patterns are processed in order on any line that isn't empty.
-local pattern_table = {
- {
- -- To be removed soon
- pattern = "%s*$" .. config.os_id_keyword,
- process = function(_, _)
- -- Ignore... ID tag
- end,
- },
- {
- dump_prevline = true,
- pattern = "^#%s*include",
- process = function(line)
- line = line .. "\n"
- write_line("sysinc", line)
- end,
- },
- {
- dump_prevline = true,
- pattern = "^#",
- process = function(line)
- if line:find("^#%s*if") then
- savesyscall = maxsyscall
- elseif line:find("^#%s*else") then
- maxsyscall = savesyscall
- end
- line = line .. "\n"
- write_line("sysent", line)
- write_line("sysdcl", line)
- write_line("sysarg", line)
- write_line_pfile("syscompat[0-9]*$", line)
- write_line("sysnames", line)
- write_line_pfile("systrace.*", line)
- end,
- },
- {
- dump_prevline = true,
- pattern = "%%ABI_HEADERS%%",
- process = function()
- if config.abi_headers ~= "" then
- local line = config.abi_headers .. "\n"
- write_line("sysinc", line)
- end
- end,
- },
- {
- -- Buffer anything else
- pattern = ".+",
- process = function(line, prevline)
- local incomplete = line:find("\\$") ~= nil
- -- Lines that end in \ get the \ stripped
- -- Lines that start with a syscall number, prepend \n
- line = trim(line):gsub("\\$", "")
- if line:find("^[0-9]") and prevline then
- process_syscall_def(prevline)
- prevline = nil
- end
-
- prevline = (prevline or '') .. line
- incomplete = incomplete or prevline:find(",$") ~= nil
- incomplete = incomplete or prevline:find("{") ~= nil and
- prevline:find("}") == nil
- if prevline:find("^[0-9]") and not incomplete then
- process_syscall_def(prevline)
- prevline = nil
- end
-
- return prevline
- end,
- },
-}
-
-local function process_sysfile(file)
- local capentries = {}
- local commentExpr = "^%s*;.*"
-
- if file == nil then
- print "No file"
- return {}
- end
-
- local fh = io.open(file)
- if fh == nil then
- print("Failed to open " .. file)
- return {}
- end
-
- local function do_match(nextline, prevline)
- local pattern, handler, dump
- for _, v in pairs(pattern_table) do
- pattern = v.pattern
- handler = v.process
- dump = v.dump_prevline
- if nextline:match(pattern) then
- if dump and prevline then
- process_syscall_def(prevline)
- prevline = nil
- end
-
- return handler(nextline, prevline)
- end
- end
-
- abort(1, "Failed to handle: " .. nextline)
- end
-
- local prevline
- for nextline in fh:lines() do
- -- Strip any comments
- nextline = nextline:gsub(commentExpr, "")
- if nextline ~= "" then
- prevline = do_match(nextline, prevline)
- end
- end
-
- -- Dump any remainder
- if prevline ~= nil and prevline:find("^[0-9]") then
- process_syscall_def(prevline)
- end
-
- assert(io.close(fh))
- return capentries
-end
-
-local function get_mask(flags)
- local mask = 0
- for _, v in ipairs(flags) do
- if known_flags[v] == nil then
- abort(1, "Checking for unknown flag " .. v)
- end
-
- mask = mask | known_flags[v]
- end
-
- return mask
-end
-
-local function get_mask_pat(pflags)
- local mask = 0
- for k, v in pairs(known_flags) do
- if k:find(pflags) then
- mask = mask | v
- end
- end
-
- return mask
-end
-
-local function strip_arg_annotations(arg)
- arg = arg:gsub("_Contains_[^ ]*[_)] ?", "")
- arg = arg:gsub("_In[^ ]*[_)] ?", "")
- arg = arg:gsub("_Out[^ ]*[_)] ?", "")
- return trim(arg)
-end
-
-local function check_abi_changes(arg)
- for k, v in pairs(known_abi_flags) do
- local exprs = v.exprs
- if abi_changes(k) and exprs ~= nil then
- for _, e in pairs(exprs) do
- if arg:find(e) then
- return true
- end
- end
- end
- end
-
- return false
-end
-
-local function process_args(args)
- local funcargs = {}
- local changes_abi = false
-
- for arg in args:gmatch("([^,]+)") do
- local arg_abi_change = check_abi_changes(arg)
- changes_abi = changes_abi or arg_abi_change
-
- arg = strip_arg_annotations(arg)
-
- local argname = arg:match("([^* ]+)$")
-
- -- argtype is... everything else.
- local argtype = trim(arg:gsub(argname .. "$", ""), nil)
-
- if argtype == "" and argname == "void" then
- goto out
- end
-
- -- is64bittype() needs a bare type so check it after argname
- -- is removed
- changes_abi = changes_abi or (abi_changes("pair_64bit") and is64bittype(argtype))
-
- argtype = argtype:gsub("intptr_t", config.abi_intptr_t)
- argtype = argtype:gsub("semid_t", config.abi_semid_t)
- if isptrtype(argtype) then
- argtype = argtype:gsub("size_t", config.abi_size_t)
- argtype = argtype:gsub("^long", config.abi_long);
- argtype = argtype:gsub("^u_long", config.abi_u_long);
- argtype = argtype:gsub("^const u_long", "const " .. config.abi_u_long);
- elseif argtype:find("^long$") then
- argtype = config.abi_long
- end
- if isptrarraytype(argtype) and config.abi_ptr_array_t ~= "" then
- -- `* const *` -> `**`
- argtype = argtype:gsub("[*][ ]*const[ ]*[*]", "**")
- -- e.g., `struct aiocb **` -> `uint32_t *`
- argtype = argtype:gsub("[^*]*[*]", config.abi_ptr_array_t .. " ", 1)
- end
-
- -- XX TODO: Forward declarations? See: sysstubfwd in CheriBSD
- if arg_abi_change then
- local abi_type_suffix = config.abi_type_suffix
- argtype = argtype:gsub("(struct [^ ]*)", "%1" ..
- abi_type_suffix)
- argtype = argtype:gsub("(union [^ ]*)", "%1" ..
- abi_type_suffix)
- end
-
- if abi_changes("pair_64bit") and is64bittype(argtype) then
- if #funcargs % 2 == 1 then
- funcargs[#funcargs + 1] = {
- type = "int",
- name = "_pad",
- }
- end
- funcargs[#funcargs + 1] = {
- type = "uint32_t",
- name = argname .. "1",
- }
- funcargs[#funcargs + 1] = {
- type = "uint32_t",
- name = argname .. "2",
- }
- else
- funcargs[#funcargs + 1] = {
- type = argtype,
- name = argname,
- }
- end
- end
-
- ::out::
- return funcargs, changes_abi
-end
-
-local function handle_noncompat(sysnum, thr_flag, flags, sysflags, rettype,
- auditev, syscallret, funcname, funcalias, funcargs, argalias)
- local argssize
-
- if flags & known_flags.SYSMUX ~= 0 then
- argssize = "0"
- elseif #funcargs > 0 or flags & known_flags.NODEF ~= 0 then
- argssize = "AS(" .. argalias .. ")"
- else
- argssize = "0"
- end
-
- write_line("systrace", string.format([[
- /* %s */
- case %d: {
-]], funcname, sysnum))
- write_line("systracetmp", string.format([[
- /* %s */
- case %d:
-]], funcname, sysnum))
- write_line("systraceret", string.format([[
- /* %s */
- case %d:
-]], funcname, sysnum))
-
- if #funcargs > 0 and flags & known_flags.SYSMUX == 0 then
- write_line("systracetmp", "\t\tswitch (ndx) {\n")
- write_line("systrace", string.format(
- "\t\tstruct %s *p = params;\n", argalias))
-
-
- local argtype, argname, desc, padding
- padding = ""
- for idx, arg in ipairs(funcargs) do
- argtype = arg.type
- argname = arg.name
-
- argtype = trim(argtype:gsub("__restrict$", ""), nil)
- if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then
- write_line("systracetmp", "#ifdef PAD64_REQUIRED\n")
- end
- -- Pointer arg?
- if argtype:find("*") then
- desc = "userland " .. argtype
- else
- desc = argtype;
- end
- write_line("systracetmp", string.format(
- "\t\tcase %d%s:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n",
- idx - 1, padding, desc))
- if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then
- padding = " - _P_"
- write_line("systracetmp", "#define _P_ 0\n#else\n#define _P_ 1\n#endif\n")
- end
-
- if isptrtype(argtype) then
- write_line("systrace", string.format(
- "\t\tuarg[a++] = (%s)p->%s; /* %s */\n",
- config.ptr_intptr_t_cast,
- argname, argtype))
- elseif argtype == "union l_semun" then
- write_line("systrace", string.format(
- "\t\tuarg[a++] = p->%s.buf; /* %s */\n",
- argname, argtype))
- elseif argtype:sub(1,1) == "u" or argtype == "size_t" then
- write_line("systrace", string.format(
- "\t\tuarg[a++] = p->%s; /* %s */\n",
- argname, argtype))
- else
- if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then
- write_line("systrace", "#ifdef PAD64_REQUIRED\n")
- end
- write_line("systrace", string.format(
- "\t\tiarg[a++] = p->%s; /* %s */\n",
- argname, argtype))
- if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then
- write_line("systrace", "#endif\n")
- end
- end
- end
-
- write_line("systracetmp",
- "\t\tdefault:\n\t\t\tbreak;\n\t\t};\n")
- if padding ~= "" then
- write_line("systracetmp", "#undef _P_\n\n")
- end
-
- write_line("systraceret", string.format([[
- if (ndx == 0 || ndx == 1)
- p = "%s";
- break;
-]], syscallret))
- end
- local n_args = #funcargs
- if flags & known_flags.SYSMUX ~= 0 then
- n_args = 0
- end
- write_line("systrace", string.format(
- "\t\t*n_args = %d;\n\t\tbreak;\n\t}\n", n_args))
- write_line("systracetmp", "\t\tbreak;\n")
-
- local nargflags = get_mask({"NOARGS", "NOPROTO", "NODEF"})
- if flags & nargflags == 0 then
- if #funcargs > 0 then
- write_line("sysarg", string.format("struct %s {\n",
- argalias))
- for _, v in ipairs(funcargs) do
- local argname, argtype = v.name, v.type
- if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then
- write_line("sysarg", "#ifdef PAD64_REQUIRED\n")
- end
- write_line("sysarg", string.format(
- "\tchar %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];\n",
- argname, argtype,
- argtype, argname,
- argname, argtype))
- if argtype == "int" and argname == "_pad" and abi_changes("pair_64bit") then
- write_line("sysarg", "#endif\n")
- end
- end
- write_line("sysarg", "};\n")
- else
- write_line("sysarg", string.format(
- "struct %s {\n\tsyscallarg_t dummy;\n};\n", argalias))
- end
- end
-
- local protoflags = get_mask({"NOPROTO", "NODEF"})
- if flags & protoflags == 0 then
- local sys_prefix = "sys_"
- if funcname == "nosys" or funcname == "lkmnosys" or
- funcname == "sysarch" or funcname:find("^freebsd") or
- funcname:find("^linux") then
- sys_prefix = ""
- end
- write_line("sysdcl", string.format(
- "%s\t%s%s(struct thread *, struct %s *);\n",
- rettype, sys_prefix, funcname, argalias))
- write_line("sysaue", string.format("#define\t%sAUE_%s\t%s\n",
- config.syscallprefix, funcalias, auditev))
- end
-
- write_line("sysent",
- string.format("\t{ .sy_narg = %s, .sy_call = (sy_call_t *)", argssize))
-
- if flags & known_flags.SYSMUX ~= 0 then
- write_line("sysent", string.format(
- "nosys, .sy_auevent = AUE_NULL, " ..
- ".sy_flags = %s, .sy_thrcnt = SY_THR_STATIC },",
- sysflags))
- elseif flags & known_flags.NOSTD ~= 0 then
- write_line("sysent", string.format(
- "lkmressys, .sy_auevent = AUE_NULL, " ..
- ".sy_flags = %s, .sy_thrcnt = SY_THR_ABSENT },",
- sysflags))
- else
- if funcname == "nosys" or funcname == "lkmnosys" or
- funcname == "sysarch" or funcname:find("^freebsd") or
- funcname:find("^linux") then
- write_line("sysent", string.format(
- "%s, .sy_auevent = %s, .sy_flags = %s, .sy_thrcnt = %s },",
- funcname, auditev, sysflags, thr_flag))
- else
- write_line("sysent", string.format(
- "sys_%s, .sy_auevent = %s, .sy_flags = %s, .sy_thrcnt = %s },",
- funcname, auditev, sysflags, thr_flag))
- end
- end
-
- write_line("sysent", string.format("\t/* %d = %s */\n",
- sysnum, funcalias))
- write_line("sysnames", string.format("\t\"%s\",\t\t\t/* %d = %s */\n",
- funcalias, sysnum, funcalias))
-
- if flags & known_flags.NODEF == 0 then
- write_line("syshdr", string.format("#define\t%s%s\t%d\n",
- config.syscallprefix, funcalias, sysnum))
- write_line("sysmk", string.format(" \\\n\t%s.o",
- funcalias))
- -- yield has never been exposed as a syscall
- if funcalias == "yield" then
- return
- end
- if funcalias ~= "exit" and funcalias ~= "vfork" then
- write_line("libsysmap", string.format("\t_%s;\n",
- funcalias))
- end
- write_line("libsysmap", string.format("\t__sys_%s;\n",
- funcalias))
-
- if flags & known_flags.SYSMUX == 0 then
- local argstr_type = ""
- local argstr_var = ""
- local comma = ""
- if #funcargs == 0 then
- argstr_type = "void"
- argstr_var = "void"
- end
- for _, v in ipairs(funcargs) do
- local argname, argtype = v.name, v.type
- argstr_type = argstr_type .. comma .. argtype
- argstr_var = argstr_var .. comma .. argtype .. " " .. argname
- comma = ", "
-
- -- Accumulate a list of struct types for
- -- forward decls. We can't do this in
- -- process_args because we don't want compat
- -- types in userspace even as no-op.
- if isptrtype(argtype) then
- local is_struct = false
- for word in argtype:gmatch("[^ *]+") do
- if is_struct then
- structs[word] = word
- break
- end
- if word == "struct" then
- is_struct = true
- -- next word is the name
- end
- end
- end
- end
- write_line("libsys_h_type",
- string.format("typedef %s (__sys_%s_t)(%s);\n",
- syscallret, funcalias, argstr_type))
- write_line("libsys_h_func",
- string.format("%s __sys_%s(%s);\n",
- syscallret, funcalias, argstr_var))
-
- end
- end
-end
-
-local function handle_obsol(sysnum, funcname, comment)
- write_line("sysent",
- "\t{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
- ".sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT },")
-
- write_line("sysent", string.format("\t/* %d = obsolete %s */\n",
- sysnum, comment))
- write_line("sysnames", string.format(
- "\t\"obs_%s\",\t\t\t/* %d = obsolete %s */\n",
- funcname, sysnum, comment))
- write_line("syshdr", string.format("\t\t\t\t/* %d is obsolete %s */\n",
- sysnum, comment))
-end
-
-local function handle_compat(sysnum, thr_flag, flags, sysflags, rettype,
- auditev, funcname, funcalias, funcargs, argalias)
- local argssize, out, outdcl, wrap, prefix, descr
-
- if #funcargs > 0 or flags & known_flags.NODEF ~= 0 then
- argssize = "AS(" .. argalias .. ")"
- else
- argssize = "0"
- end
-
- for _, v in pairs(compat_options) do
- if flags & v.mask ~= 0 then
- if config.mincompat > v.compatlevel then
- funcname = strip_abi_prefix(funcname)
- funcname = v.prefix .. funcname
- return handle_obsol(sysnum, funcname, funcname)
- end
- v.count = v.count + 1
- out = v.tmp
- outdcl = v.dcltmp
- wrap = v.flag:lower()
- prefix = v.prefix
- descr = v.descr
- goto compatdone
- end
- end
-
- ::compatdone::
- local dprotoflags = get_mask({"NOPROTO", "NODEF"})
- local nargflags = dprotoflags | known_flags.NOARGS
- if #funcargs > 0 and flags & nargflags == 0 then
- write_line(out, string.format("struct %s {\n", argalias))
- for _, v in ipairs(funcargs) do
- local argname, argtype = v.name, v.type
- write_line(out, string.format(
- "\tchar %s_l_[PADL_(%s)]; %s %s; char %s_r_[PADR_(%s)];\n",
- argname, argtype,
- argtype, argname,
- argname, argtype))
- end
- write_line(out, "};\n")
- elseif flags & nargflags == 0 then
- write_line("sysarg", string.format(
- "struct %s {\n\tsyscallarg_t dummy;\n};\n", argalias))
- end
- if flags & dprotoflags == 0 then
- write_line(outdcl, string.format(
- "%s\t%s%s(struct thread *, struct %s *);\n",
- rettype, prefix, funcname, argalias))
- write_line("sysaue", string.format(
- "#define\t%sAUE_%s%s\t%s\n", config.syscallprefix,
- prefix, funcname, auditev))
- end
-
- if flags & known_flags.NOSTD ~= 0 then
- write_line("sysent", string.format(
- "\t{ .sy_narg = %s, .sy_call = (sy_call_t *)%s, " ..
- ".sy_auevent = %s, .sy_flags = 0, " ..
- ".sy_thrcnt = SY_THR_ABSENT },",
- "0", "lkmressys", "AUE_NULL"))
- else
- write_line("sysent", string.format(
- "\t{ %s(%s,%s), .sy_auevent = %s, .sy_flags = %s, .sy_thrcnt = %s },",
- wrap, argssize, funcname, auditev, sysflags, thr_flag))
- end
-
- write_line("sysent", string.format("\t/* %d = %s %s */\n",
- sysnum, descr, funcalias))
- write_line("sysnames", string.format(
- "\t\"%s.%s\",\t\t/* %d = %s %s */\n",
- wrap, funcalias, sysnum, descr, funcalias))
- -- Do not provide freebsdN_* symbols in libc for < FreeBSD 7
- local nosymflags = get_mask({"COMPAT", "COMPAT4", "COMPAT6"})
- if flags & nosymflags ~= 0 then
- write_line("syshdr", string.format(
- "\t\t\t\t/* %d is %s %s */\n",
- sysnum, descr, funcalias))
- elseif flags & known_flags.NODEF == 0 then
- write_line("syshdr", string.format("#define\t%s%s%s\t%d\n",
- config.syscallprefix, prefix, funcalias, sysnum))
- write_line("sysmk", string.format(" \\\n\t%s%s.o",
- prefix, funcalias))
- end
-end
-
-local function handle_unimpl(sysnum, sysstart, sysend, comment)
- if sysstart == nil and sysend == nil then
- sysstart = tonumber(sysnum)
- sysend = tonumber(sysnum)
- end
-
- sysnum = sysstart
- while sysnum <= sysend do
- write_line("sysent", string.format(
- "\t{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
- ".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
- ".sy_thrcnt = SY_THR_ABSENT },\t/* %d = %s */\n",
- sysnum, comment))
- write_line("sysnames", string.format(
- "\t\"#%d\",\t\t\t/* %d = %s */\n",
- sysnum, sysnum, comment))
- sysnum = sysnum + 1
- end
-end
-
-local function handle_reserved(sysnum, sysstart, sysend)
- handle_unimpl(sysnum, sysstart, sysend, "reserved for local use")
-end
-
-process_syscall_def = function(line)
- local sysstart, sysend, flags, funcname, sysflags
- local thr_flag, syscallret
- local orig = line
- flags = 0
- thr_flag = "SY_THR_STATIC"
-
- -- Parse out the interesting information first
- local initialExpr = "^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s*"
- local sysnum, auditev, allflags = line:match(initialExpr)
-
- if sysnum == nil or auditev == nil or allflags == nil then
- -- XXX TODO: Better?
- abort(1, "Completely malformed: " .. line)
- end
-
- if sysnum:find("-") then
- sysstart, sysend = sysnum:match("^([%d]+)-([%d]+)$")
- if sysstart == nil or sysend == nil then
- abort(1, "Malformed range: " .. sysnum)
- end
- sysnum = nil
- sysstart = tonumber(sysstart)
- sysend = tonumber(sysend)
- if sysstart ~= maxsyscall + 1 then
- abort(1, "syscall number out of sync, missing " ..
- maxsyscall + 1)
- end
- else
- sysnum = tonumber(sysnum)
- if sysnum ~= maxsyscall + 1 then
- abort(1, "syscall number out of sync, missing " ..
- maxsyscall + 1)
- end
- end
-
- -- Split flags
- for flag in allflags:gmatch("([^|]+)") do
- if known_flags[flag] == nil then
- abort(1, "Unknown flag " .. flag .. " for " .. sysnum)
- end
- flags = flags | known_flags[flag]
- end
-
- if (flags & get_mask({"RESERVED", "UNIMPL"})) == 0 and sysnum == nil then
- abort(1, "Range only allowed with RESERVED and UNIMPL: " .. line)
- end
-
- if (flags & known_flags.NOTSTATIC) ~= 0 then
- thr_flag = "SY_THR_ABSENT"
- end
-
- -- Strip earlier bits out, leave declaration + alt
- line = line:gsub("^.+" .. allflags .. "%s*", "")
-
- local decl_fnd = line:find("^{") ~= nil
- if decl_fnd and line:find("}") == nil then
- abort(1, "Malformed, no closing brace: " .. line)
- end
-
- local decl, alt
- if decl_fnd then
- line = line:gsub("^{", "")
- decl, alt = line:match("([^}]*)}[%s]*(.*)$")
- else
- alt = line
- end
-
- if decl == nil and alt == nil then
- abort(1, "Malformed bits: " .. line)
- end
-
- local funcalias, funcomment, argalias, rettype, args
- if not decl_fnd and alt ~= nil and alt ~= "" then
- -- Peel off one entry for name
- funcname = trim(alt:match("^([^%s]+)"), nil)
- alt = alt:gsub("^([^%s]+)[%s]*", "")
- end
- -- Do we even need it?
- if flags & get_mask({"OBSOL", "UNIMPL"}) ~= 0 then
- local NF = 0
- for _ in orig:gmatch("[^%s]+") do
- NF = NF + 1
- end
-
- funcomment = funcname or ''
- if NF < 6 then
- funcomment = funcomment .. " " .. alt
- end
-
- funcomment = trim(funcomment)
-
--- if funcname ~= nil then
--- else
--- funcomment = trim(alt)
--- end
- goto skipalt
- end
-
- if alt ~= nil and alt ~= "" then
- local altExpr = "^([^%s]+)%s+([^%s]+)%s+([^%s]+)"
- funcalias, argalias, rettype = alt:match(altExpr)
- funcalias = trim(funcalias)
- if funcalias == nil or argalias == nil or rettype == nil then
- abort(1, "Malformed alt: " .. line)
- end
- end
- if decl_fnd then
- -- Don't clobber rettype set in the alt information
- if rettype == nil then
- rettype = "int"
- end
- -- Peel off the return type
- syscallret = line:match("([^%s]+)%s")
- line = line:match("[^%s]+%s(.+)")
- -- Pointer incoming
- if line:sub(1,1) == "*" then
- syscallret = syscallret .. " "
- end
- while line:sub(1,1) == "*" do
- line = line:sub(2)
- syscallret = syscallret .. "*"
- end
- funcname = line:match("^([^(]+)%(")
- if funcname == nil then
- abort(1, "Not a signature? " .. line)
- end
- args = line:match("^[^(]+%((.+)%)[^)]*$")
- args = trim(args, '[,%s]')
- end
-
- ::skipalt::
-
- if funcname == nil then
- funcname = funcalias
- end
-
- funcname = trim(funcname)
-
- if config.obsol_dict[funcname] then
- local compat_prefix = ""
- for _, v in pairs(compat_options) do
- if flags & v.mask ~= 0 then
- compat_prefix = v.prefix
- goto obsol_compat_done
- end
- end
- ::obsol_compat_done::
- args = nil
- flags = known_flags.OBSOL
- funcomment = compat_prefix .. funcname
- end
- if config.unimpl_dict[funcname] then
- flags = known_flags.UNIMPL
- funcomment = funcname
- end
-
- sysflags = "0"
-
- -- NODEF events do not get audited
- if flags & known_flags.NODEF ~= 0 then
- auditev = 'AUE_NULL'
- end
-
- -- If applicable; strip the ABI prefix from the name
- local stripped_name = strip_abi_prefix(funcname)
-
- if flags & known_flags.CAPENABLED ~= 0 or
- config.capenabled[funcname] ~= nil or
- config.capenabled[stripped_name] ~= nil then
- sysflags = "SYF_CAPENABLED"
- end
-
- local funcargs = {}
- local changes_abi = false
- if args ~= nil then
- funcargs, changes_abi = process_args(args)
- end
- if config.sys_no_abi_change[funcname] then
- changes_abi = false
- end
- local noproto = config.abi_flags ~= "" and not changes_abi
-
- local argprefix = ''
- local funcprefix = ''
- if abi_changes("pointer_args") then
- for _, v in ipairs(funcargs) do
- if isptrtype(v.type) then
- if config.sys_no_abi_change[funcname] then
- print("WARNING: " .. funcname ..
- " in syscall_no_abi_change, but pointers args are present")
- end
- changes_abi = true
- goto ptrfound
- end
- end
- ::ptrfound::
- end
- if config.sys_abi_change[funcname] then
- changes_abi = true
- end
- if changes_abi then
- -- argalias should be:
- -- COMPAT_PREFIX + ABI Prefix + funcname
- argprefix = config.abi_func_prefix
- funcprefix = config.abi_func_prefix
- funcalias = funcprefix .. funcname
- noproto = false
- end
- if funcname ~= nil then
- funcname = funcprefix .. funcname
- end
- if funcalias == nil or funcalias == "" then
- funcalias = funcname
- end
-
- if argalias == nil and funcname ~= nil then
- argalias = funcname .. "_args"
- for _, v in pairs(compat_options) do
- local mask = v.mask
- if (flags & mask) ~= 0 then
- -- Multiple aliases doesn't seem to make
- -- sense.
- argalias = v.prefix .. argalias
- goto out
- end
- end
- ::out::
- elseif argalias ~= nil then
- argalias = argprefix .. argalias
- end
-
- local ncompatflags = get_mask({"STD", "NODEF", "NOARGS", "NOPROTO",
- "NOSTD"})
- local compatflags = get_mask_pat("COMPAT.*")
- if noproto or flags & known_flags.SYSMUX ~= 0 then
- flags = flags | known_flags.NOPROTO;
- end
- if flags & known_flags.OBSOL ~= 0 then
- handle_obsol(sysnum, funcname, funcomment)
- elseif flags & known_flags.RESERVED ~= 0 then
- handle_reserved(sysnum, sysstart, sysend)
- elseif flags & known_flags.UNIMPL ~= 0 then
- handle_unimpl(sysnum, sysstart, sysend, funcomment)
- elseif flags & compatflags ~= 0 then
- if flags & known_flags.STD ~= 0 then
- abort(1, "Incompatible COMPAT/STD: " .. line)
- end
- handle_compat(sysnum, thr_flag, flags, sysflags, rettype,
- auditev, funcname, funcalias, funcargs, argalias)
- elseif flags & ncompatflags ~= 0 then
- handle_noncompat(sysnum, thr_flag, flags, sysflags, rettype,
- auditev, syscallret, funcname, funcalias, funcargs,
- argalias)
- else
- abort(1, "Bad flags? " .. line)
- end
-
- if sysend ~= nil then
- maxsyscall = sysend
- elseif sysnum ~= nil then
- maxsyscall = sysnum
- end
-end
-
-local function pairsByKeys (t, f)
- local a = {}
- for n in pairs(t) do table.insert(a, n) end
- table.sort(a, f)
- local i = 0 -- iterator variable
- local iter = function () -- iterator function
- i = i + 1
- if a[i] == nil then return nil
- else return a[i], t[a[i]]
- end
- end
- return iter
-end
-
--- Entry point
-
-if #arg < 1 or #arg > 2 then
- error("usage: " .. arg[0] .. " input-file <config-file>")
-end
-
-local sysfile, configfile = arg[1], arg[2]
-
--- process_config either returns nil and a message, or a
--- table that we should merge into the global config
-if configfile ~= nil then
- local res = assert(process_config(configfile))
-
- for k, v in pairs(res) do
- if v ~= config[k] then
- config[k] = v
- config_modified[k] = true
- end
- end
-end
-
-local compat_set = config.compat_set
-if compat_set ~= "" then
- if not compat_option_sets[compat_set] then
- abort(1, "Undefined compat set: " .. compat_set)
- end
-
- compat_options = compat_option_sets[compat_set]
-else
- compat_options = {}
-end
-
--- We ignore errors here if we're relying on the default configuration.
-if not config_modified.capenabled then
- config.capenabled = grab_capenabled(config.capabilities_conf,
- config_modified.capabilities_conf == nil)
-elseif config.capenabled ~= "" then
- -- Due to limitations in the config format mostly, we'll have a comma
- -- separated list. Parse it into lines
- local capenabled = {}
- -- print("here: " .. config.capenabled)
- for sysc in config.capenabled:gmatch("([^,]+)") do
- capenabled[sysc] = true
- end
- config.capenabled = capenabled
-end
-process_compat()
-process_abi_flags()
-process_syscall_abi_change()
-process_obsol()
-process_unimpl()
-
-if not lfs.mkdir(tmpspace) then
- error("Failed to create tempdir " .. tmpspace)
-end
-
--- XXX Revisit the error handling here, we should probably move the rest of this
--- into a function that we pcall() so we can catch the errors and clean up
--- gracefully.
-for _, v in ipairs(temp_files) do
- local tmpname = tmpspace .. v
- files[v] = io.open(tmpname, "w+")
- -- XXX Revisit these with a pcall() + error handler
- if not files[v] then
- abort(1, "Failed to open temp file: " .. tmpname)
- end
-end
-
-for _, v in ipairs(output_files) do
- local tmpname = tmpspace .. v
- files[v] = io.open(tmpname, "w+")
- -- XXX Revisit these with a pcall() + error handler
- if not files[v] then
- abort(1, "Failed to open temp output file: " .. tmpname)
- end
-end
-
--- Write out all of the preamble bits
-write_line("sysent", string.format([[
-
-/* The casts are bogus but will do for now. */
-struct sysent %s[] = {
-]], config.switchname))
-
-write_line("syssw", string.format([[/*
- * System call switch table.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-]], generated_tag))
-
-write_line("sysarg", string.format([[/*
- * System call prototypes.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-#ifndef %s
-#define %s
-
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <sys/cpuset.h>
-#include <sys/domainset.h>
-#include <sys/_ffcounter.h>
-#include <sys/_semaphore.h>
-#include <sys/ucontext.h>
-#include <sys/wait.h>
-
-#include <bsm/audit_kevents.h>
-
-struct proc;
-
-struct thread;
-
-#define PAD_(t) (sizeof(syscallarg_t) <= sizeof(t) ? \
- 0 : sizeof(syscallarg_t) - sizeof(t))
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define PADL_(t) 0
-#define PADR_(t) PAD_(t)
-#else
-#define PADL_(t) PAD_(t)
-#define PADR_(t) 0
-#endif
-
-]], generated_tag, config.sysproto_h, config.sysproto_h))
-if abi_changes("pair_64bit") then
- write_line("sysarg", string.format([[
-#if !defined(PAD64_REQUIRED) && !defined(__amd64__)
-#define PAD64_REQUIRED
-#endif
-]]))
-end
-if abi_changes("pair_64bit") then
- write_line("systrace", string.format([[
-#if !defined(PAD64_REQUIRED) && !defined(__amd64__)
-#define PAD64_REQUIRED
-#endif
-]]))
-end
-for _, v in pairs(compat_options) do
- write_line(v.tmp, string.format("\n#ifdef %s\n\n", v.definition))
-end
-
-write_line("sysnames", string.format([[/*
- * System call names.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-const char *%s[] = {
-]], generated_tag, config.namesname))
-
-write_line("syshdr", string.format([[/*
- * System call numbers.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-]], generated_tag))
-
-write_line("sysmk", string.format([[
-#
-# FreeBSD system call object files.
-#
-# DO NOT EDIT-- this file is automatically %s.
-#
-
-MIASM = ]], generated_tag))
-
-write_line("libsysmap", string.format([[/*
- * FreeBSD system call symbols.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-FBSDprivate_1.0 {
-]], generated_tag))
-
-write_line("libsys_h", string.format([[/*
- * Public system call stubs provided by libsys.
- *
- * Do not use directly, include <libsys.h> instead.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-#ifndef __LIBSYS_H_
-#define __LIBSYS_H_
-
-#include <sys/_cpuset.h>
-#include <sys/_domainset.h>
-#include <sys/_ffcounter.h>
-#include <sys/_semaphore.h>
-#include <sys/_sigaltstack.h>
-#include <machine/ucontext.h> /* for mcontext_t */
-#include <sys/_ucontext.h>
-#include <sys/wait.h>
-
-]], generated_tag))
-
-write_line("systrace", string.format([[/*
- * System call argument to DTrace register array conversion.
- *
- * This file is part of the DTrace syscall provider.
- *
- * DO NOT EDIT-- this file is automatically %s.
- */
-
-static void
-systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
-{
- int64_t *iarg = (int64_t *)uarg;
- int a = 0;
- switch (sysnum) {
-]], generated_tag))
-
-write_line("systracetmp", [[static void
-systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
-{
- const char *p = NULL;
- switch (sysnum) {
-]])
-
-write_line("systraceret", [[static void
-systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
-{
- const char *p = NULL;
- switch (sysnum) {
-]])
-
--- Processing the sysfile will parse out the preprocessor bits and put them into
--- the appropriate place. Any syscall-looking lines get thrown into the sysfile
--- buffer, one per line, for later processing once they're all glued together.
-process_sysfile(sysfile)
-
-write_line("sysinc",
- "\n#define AS(name) (sizeof(struct name) / sizeof(syscallarg_t))\n")
-
-for _, v in pairs(compat_options) do
- if v.count > 0 then
- write_line("sysinc", string.format([[
-
-#ifdef %s
-#define %s(n, name) .sy_narg = n, .sy_call = (sy_call_t *)__CONCAT(%s, name)
-#else
-#define %s(n, name) .sy_narg = 0, .sy_call = (sy_call_t *)nosys
-#endif
-]], v.definition, v.flag:lower(), v.prefix, v.flag:lower()))
- end
-
- write_line(v.dcltmp, string.format("\n#endif /* %s */\n\n",
- v.definition))
-end
-
-write_line("sysprotoend", string.format([[
-
-#undef PAD_
-#undef PADL_
-#undef PADR_
-
-#endif /* !%s */
-]], config.sysproto_h))
-
-write_line("sysmk", "\n")
-write_line("libsysmap", "};\n")
-write_line("sysent", "};\n")
-write_line("sysnames", "};\n")
--- maxsyscall is the highest seen; MAXSYSCALL should be one higher
-write_line("syshdr", string.format("#define\t%sMAXSYSCALL\t%d\n",
- config.syscallprefix, maxsyscall + 1))
-write_line("systrace", [[
- default:
- *n_args = 0;
- break;
- };
-}
-]])
-
-write_line("systracetmp", [[
- default:
- break;
- };
- if (p != NULL)
- strlcpy(desc, p, descsz);
-}
-]])
-
-write_line("systraceret", [[
- default:
- break;
- };
- if (p != NULL)
- strlcpy(desc, p, descsz);
-}
-]])
-
--- Finish up; output
-table.sort(structs)
-for name,_ in pairsByKeys(structs) do
- write_line("libsys_h", string.format("struct %s;\n", name))
-end
-write_line("libsys_h", "union semun;\n\n__BEGIN_DECLS\n")
-write_line("libsys_h", read_file("libsys_h_type"))
-write_line("libsys_h", "\n")
-write_line("libsys_h", read_file("libsys_h_func"))
-write_line("libsys_h", "__END_DECLS\n\n#endif /* __LIBSYS_H_ */\n")
-
-write_line("syssw", read_file("sysinc"))
-write_line("syssw", read_file("sysent"))
-
-write_line("sysproto", read_file("sysarg"))
-write_line("sysproto", read_file("sysdcl"))
-for _, v in pairs(compat_options) do
- write_line("sysproto", read_file(v.tmp))
- write_line("sysproto", read_file(v.dcltmp))
-end
-write_line("sysproto", read_file("sysaue"))
-write_line("sysproto", read_file("sysprotoend"))
-
-write_line("systrace", read_file("systracetmp"))
-write_line("systrace", read_file("systraceret"))
-
-for _, v in ipairs(output_files) do
- local target = config[v]
- if target ~= "/dev/null" then
- local fh = assert(io.open(target, "w+"))
- if fh == nil then
- abort(1, "Failed to open '" .. target .. "'")
- end
- assert(fh:write(read_file(v)))
- assert(fh:close())
- end
-end
-
-cleanup()