xref: /freebsd/sys/tools/syscalls/core/freebsd-syscall.lua (revision f29905cab576a0ccf454ee2e215f590e0e656d70)
19ded074eSagge3--
29ded074eSagge3-- SPDX-License-Identifier: BSD-2-Clause
39ded074eSagge3--
49ded074eSagge3-- Copyright (c) 2024 Tyler Baxter <agge@FreeBSD.org>
59ded074eSagge3-- Copyright (c) 2023 Warner Losh <imp@bsdimp.com>
69ded074eSagge3-- Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org>
79ded074eSagge3--
89ded074eSagge3
99ded074eSagge3local syscall = require("core.syscall")
109ded074eSagge3local util = require("tools.util")
119ded074eSagge3
129ded074eSagge3local FreeBSDSyscall = {}
139ded074eSagge3
149ded074eSagge3FreeBSDSyscall.__index = FreeBSDSyscall
159ded074eSagge3
169ded074eSagge3-- For each compat option in the provided config table, process them and insert
179ded074eSagge3-- them into known_flags for class syscall.
189ded074eSagge3function FreeBSDSyscall:processCompat()
199ded074eSagge3	for _, v in pairs(self.config.compat_options) do
209ded074eSagge3		if v.stdcompat ~= nil then
219ded074eSagge3			local stdcompat = v.stdcompat
229ded074eSagge3			v.definition = "COMPAT_" .. stdcompat:upper()
239ded074eSagge3			v.compatlevel = tonumber(stdcompat:match("([0-9]+)$"))
249ded074eSagge3			v.flag = stdcompat:gsub("FREEBSD", "COMPAT")
259ded074eSagge3			v.prefix = stdcompat:lower() .. "_"
269ded074eSagge3			v.descr = stdcompat:lower()
279ded074eSagge3		end
289ded074eSagge3
299ded074eSagge3		-- Add compat option to syscall.known_flags.
309ded074eSagge3		table.insert(syscall.known_flags, v.flag)
319ded074eSagge3	end
329ded074eSagge3end
339ded074eSagge3
349ded074eSagge3function FreeBSDSyscall:parseSysfile()
359ded074eSagge3	local file = self.sysfile
369ded074eSagge3	local config = self.config
379ded074eSagge3	local commentExpr = "^%s*;.*"
389ded074eSagge3
399ded074eSagge3	if file == nil then
409ded074eSagge3		return nil, "No file given"
419ded074eSagge3	end
429ded074eSagge3
439ded074eSagge3	self.syscalls = {}
449ded074eSagge3
459ded074eSagge3	local fh, msg = io.open(file)
469ded074eSagge3	if fh == nil then
479ded074eSagge3		return nil, msg
489ded074eSagge3	end
499ded074eSagge3
509ded074eSagge3	local incs = ""
5142d075f4SBrooks Davis	local prolog = ""
5242d075f4SBrooks Davis	local first = true
53*f29905caSBrooks Davis	local cpp_warned = false
549ded074eSagge3	local s
559ded074eSagge3	for line in fh:lines() do
569ded074eSagge3		line = line:gsub(commentExpr, "") -- Strip any comments.
579ded074eSagge3		-- NOTE: Can't use pure pattern matching here because of
589ded074eSagge3		-- the 's' test and this is shorter than a generic pattern
599ded074eSagge3		-- matching pattern.
609ded074eSagge3		if line == nil or line == "" then
619ded074eSagge3			goto skip	-- Blank line, skip this line.
629ded074eSagge3		elseif s ~= nil then
639ded074eSagge3			-- If we have a partial system call object s,
649ded074eSagge3			-- then feed it one more line.
659ded074eSagge3			if s:add(line) then
669ded074eSagge3				-- Append to system call list.
679ded074eSagge3				for t in s:iter() do
689ded074eSagge3					if t:validate(t.num - 1) then
699ded074eSagge3						table.insert(self.syscalls, t)
709ded074eSagge3					else
719ded074eSagge3						util.abort(1,
729ded074eSagge3						    "Skipped system call " ..
739ded074eSagge3						    "at number " .. t.num)
749ded074eSagge3					end
759ded074eSagge3				end
769ded074eSagge3				s = nil
779ded074eSagge3			end
789ded074eSagge3		elseif line:match("^#%s*include") then
799ded074eSagge3			incs = incs .. line .. "\n"
809ded074eSagge3		elseif line:match("%%ABI_HEADERS%%") then
819ded074eSagge3			local h = self.config.abi_headers
829ded074eSagge3			if h ~= nil and h ~= "" then
839ded074eSagge3				incs = incs .. h .. "\n"
849ded074eSagge3			end
859ded074eSagge3		elseif line:match("^#") then
86*f29905caSBrooks Davis			if not cpp_warned then
87*f29905caSBrooks Davis				util.warn("use of non-include cpp " ..
88*f29905caSBrooks Davis				    "directives is deprecated")
89*f29905caSBrooks Davis				cpp_warned = true
90*f29905caSBrooks Davis			end
9142d075f4SBrooks Davis			prolog = prolog .. line .. "\n"
929ded074eSagge3		else
939ded074eSagge3			s = syscall:new()
9442d075f4SBrooks Davis			if first then
9542d075f4SBrooks Davis				self.prolog = prolog
9642d075f4SBrooks Davis				s.prolog = ""
9742d075f4SBrooks Davis				first = false
9842d075f4SBrooks Davis			else
9942d075f4SBrooks Davis				s.prolog = prolog
10042d075f4SBrooks Davis			end
10142d075f4SBrooks Davis			prolog = ""
1029ded074eSagge3			if s:add(line) then
1039ded074eSagge3				-- Append to system call list.
1049ded074eSagge3				for t in s:iter() do
1059ded074eSagge3					if t:validate(t.num - 1) then
1069ded074eSagge3						table.insert(self.syscalls, t)
1079ded074eSagge3					else
1089ded074eSagge3						util.abort(1,
1099ded074eSagge3						    "Skipped system call " ..
1109ded074eSagge3						    "at number " .. t.num)
1119ded074eSagge3					end
1129ded074eSagge3				end
1139ded074eSagge3				s = nil
1149ded074eSagge3			end
1159ded074eSagge3		end
1169ded074eSagge3		::skip::
1179ded074eSagge3	end
1189ded074eSagge3
1199ded074eSagge3	-- Special handling for linux nosys.
1209ded074eSagge3	if config.syscallprefix:find("LINUX") ~= nil then
1219ded074eSagge3		s = nil
1229ded074eSagge3	end
1239ded074eSagge3
1249ded074eSagge3	if s ~= nil then
1259ded074eSagge3		util.abort(1, "Dangling system call at the end")
1269ded074eSagge3	end
1279ded074eSagge3
1289ded074eSagge3	assert(fh:close())
1299ded074eSagge3	self.includes = incs
13042d075f4SBrooks Davis	self.epilog = prolog
13142d075f4SBrooks Davis
13242d075f4SBrooks Davis	if self.prolog ~= "" then
13342d075f4SBrooks Davis		util.warn("non-include pre-processor directives in the " ..
13442d075f4SBrooks Davis		    "config prolog will not appear in generated output:\n" ..
13542d075f4SBrooks Davis		    self.prolog)
13642d075f4SBrooks Davis	end
1379ded074eSagge3end
1389ded074eSagge3
1399ded074eSagge3function FreeBSDSyscall:findStructs()
1409ded074eSagge3	self.structs = {}
1419ded074eSagge3
1429ded074eSagge3	for _, s in pairs(self.syscalls) do
1439ded074eSagge3		if s:native() and not s.type.NODEF then
1449ded074eSagge3			for _, v in ipairs(s.args) do
1459ded074eSagge3				local name = util.structName(v.type)
1469ded074eSagge3				if name ~= nil then
1479ded074eSagge3					self.structs[name] = name
1489ded074eSagge3				end
1499ded074eSagge3			end
1509ded074eSagge3		end
1519ded074eSagge3	end
1529ded074eSagge3end
1539ded074eSagge3
1549ded074eSagge3function FreeBSDSyscall:new(obj)
1559ded074eSagge3	obj = obj or {}
1569ded074eSagge3	setmetatable(obj, self)
1579ded074eSagge3	self.__index = self
1589ded074eSagge3
1599ded074eSagge3	obj:processCompat()
1609ded074eSagge3	obj:parseSysfile()
1619ded074eSagge3	obj:findStructs()
1629ded074eSagge3
1639ded074eSagge3	return obj
1649ded074eSagge3end
1659ded074eSagge3
1669ded074eSagge3return FreeBSDSyscall
167