mirror of
https://github.com/opnsense/src.git
synced 2026-06-06 15:22:34 -04:00
We haven't used this since commitbe67ea40c5in 2021 so stop carrying it forward. Also remove support for setting the list in syscalls.conf via the capenabled variable. This was last used by cloudabi (removed in 2021 by commitcf0ee8738e).
263 lines
7.6 KiB
Lua
263 lines
7.6 KiB
Lua
--
|
|
-- SPDX-License-Identifier: BSD-2-Clause
|
|
--
|
|
-- Copyright (c) 2021-2024 SRI International
|
|
-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org>
|
|
-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com>
|
|
-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
|
|
--
|
|
|
|
--
|
|
-- Code to read in the config file that drives this. Since we inherit from the
|
|
-- FreeBSD makesyscall.sh legacy, all config is done through a config file that
|
|
-- sets a number of variables (as noted below); it used to be a .sh file that
|
|
-- was sourced in. This dodges the need to write a command line parser.
|
|
--
|
|
|
|
local util = require("tools.util")
|
|
|
|
--
|
|
-- Global config map.
|
|
-- Default configuration is native. Any of these may get replaced by an
|
|
-- optionally specified configuration file.
|
|
--
|
|
local config = {
|
|
sysnames = "syscalls.c",
|
|
syshdr = "../sys/syscall.h",
|
|
sysmk = "/dev/null",
|
|
syssw = "init_sysent.c",
|
|
systrace = "systrace_args.c",
|
|
sysproto = "../sys/sysproto.h",
|
|
libsysmap = "/dev/null",
|
|
libsys_h = "/dev/null",
|
|
sysproto_h = "_SYS_SYSPROTO_H_",
|
|
syscallprefix = "SYS_",
|
|
switchname = "sysent",
|
|
namesname = "syscallnames",
|
|
abi_flags = {},
|
|
abi_func_prefix = "",
|
|
abi_type_suffix = "",
|
|
abi_long = "long",
|
|
abi_u_long = "u_long",
|
|
abi_semid_t = "semid_t",
|
|
abi_size_t = "size_t",
|
|
abi_ptr_array_t = "",
|
|
abi_headers = "",
|
|
abi_intptr_t = "intptr_t",
|
|
ptr_intptr_t_cast = "intptr_t",
|
|
obsol = {},
|
|
unimpl = {},
|
|
compat_set = "native",
|
|
mincompat = 0,
|
|
-- System calls that require ABI-specific handling.
|
|
syscall_abi_change = {},
|
|
-- System calls that appear to require handling, but don't.
|
|
syscall_no_abi_change = {},
|
|
-- Keep track of modifications if there are.
|
|
modifications = {},
|
|
-- Stores compat_sets from syscalls.conf; config.mergeCompat()
|
|
-- instantiates.
|
|
compat_options = {},
|
|
}
|
|
|
|
--
|
|
-- For each entry, the ABI flag is the key. One may also optionally provide an
|
|
-- expr, which are contained in an array associated with each key; expr gets
|
|
-- applied to each argument type to indicate whether this argument is subject to
|
|
-- ABI change given the configured flags.
|
|
--
|
|
config.known_abi_flags = {
|
|
long_size = {
|
|
"_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 = {
|
|
"_Contains[a-z_]*_timet_",
|
|
},
|
|
pointer_args = {
|
|
-- no expr
|
|
},
|
|
pointer_size = {
|
|
"_Contains[a-z_]*_ptr_",
|
|
"[*][*]",
|
|
},
|
|
pair_64bit = {
|
|
"^dev_t[ ]*$",
|
|
"^id_t[ ]*$",
|
|
"^off_t[ ]*$",
|
|
},
|
|
}
|
|
|
|
-- 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" },
|
|
},
|
|
}
|
|
|
|
--
|
|
-- 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.
|
|
--
|
|
-- This function processes config to be merged into our global config map with
|
|
-- config.merge(). It aborts if there's malformed lines and returns NIL and a
|
|
-- message if no file was provided.
|
|
--
|
|
function config.process(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 = util.trim(key)
|
|
value = util.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 = util.trim(trailing_context)
|
|
if trailing_context ~= "" then
|
|
print(trailing_context)
|
|
util.abort(1,
|
|
"Malformed line: " .. nextline)
|
|
end
|
|
|
|
value = util.trim(value, delim)
|
|
else
|
|
-- Strip off potential comments.
|
|
value = value:gsub("#.*$", "")
|
|
-- Strip off any padding whitespace.
|
|
value = util.trim(value)
|
|
if value:match("%s") then
|
|
util.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.
|
|
util.abort(1, "Malformed config line: " .. nextline)
|
|
end
|
|
end
|
|
|
|
assert(fh:close())
|
|
return cfg
|
|
end
|
|
|
|
-- Merges processed configuration file into the global config map (see above),
|
|
-- or returns NIL and a message if no file was provided.
|
|
function config.merge(fh)
|
|
if not fh then
|
|
return nil, "No file given"
|
|
end
|
|
|
|
local res = assert(config.process(fh))
|
|
|
|
for k, v in pairs(res) do
|
|
if v ~= config[k] then
|
|
-- Handling of string lists:
|
|
if k:find("abi_flags") then
|
|
-- Match for pipe, that's how abi_flags
|
|
-- is formatted.
|
|
config[k] = util.setFromString(v, "[^|]+")
|
|
elseif k:find("syscall_abi_change") or
|
|
k:find("syscall_no_abi_change") or
|
|
k:find("obsol") or
|
|
k:find("unimpl") then
|
|
-- Match for space, that's how these
|
|
-- are formatted.
|
|
config[k] = util.setFromString(v, "[^ ]+")
|
|
else
|
|
config[k] = v
|
|
end
|
|
-- Construct config modified table as config
|
|
-- is processed.
|
|
config.modifications[k] = true
|
|
else
|
|
-- config wasn't modified.
|
|
config.modifications[k] = false
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Returns TRUE if there are ABI changes from native for the provided ABI flag.
|
|
function config.abiChanges(name)
|
|
if config.known_abi_flags[name] == nil then
|
|
util.abort(1, "abi_changes: unknown flag: " .. name)
|
|
end
|
|
return config.abi_flags[name] ~= nil
|
|
end
|
|
|
|
-- Instantiates config.compat_options.
|
|
function config.mergeCompat()
|
|
if config.compat_set ~= "" then
|
|
if not compat_option_sets[config.compat_set] then
|
|
util.abort(1, "Undefined compat set: " ..
|
|
config.compat_set)
|
|
end
|
|
|
|
config.compat_options = compat_option_sets[config.compat_set]
|
|
end
|
|
end
|
|
|
|
return config
|