Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/tools/syscalls/scripts/init_sysent.lua
39530 views
1
#!/usr/libexec/flua
2
--
3
-- SPDX-License-Identifier: BSD-2-Clause
4
--
5
-- Copyright (c) 2024 Tyler Baxter <[email protected]>
6
-- Copyright (c) 2023 Warner Losh <[email protected]>
7
-- Copyright (c) 2019 Kyle Evans <[email protected]>
8
--
9
10
-- Setup to be a module, or ran as its own script.
11
local init_sysent = {}
12
local script = not pcall(debug.getlocal, 4, 1) -- TRUE if script.
13
if script then
14
-- Add library root to the package path.
15
local path = arg[0]:gsub("/[^/]+.lua$", "")
16
package.path = package.path .. ";" .. path .. "/../?.lua"
17
end
18
19
local FreeBSDSyscall = require("core.freebsd-syscall")
20
local generator = require("tools.generator")
21
22
-- File has not been decided yet; config will decide file. Default defined as
23
-- /dev/null.
24
init_sysent.file = "/dev/null"
25
26
function init_sysent.generate(tbl, config, fh)
27
-- Grab the master system calls table.
28
local s = tbl.syscalls
29
30
-- Bind the generator to the parameter file.
31
local gen = generator:new({}, fh)
32
33
-- Write the generated preamble.
34
gen:preamble("System call switch table.")
35
36
gen:write(tbl.includes)
37
38
-- Newline before and after this line.
39
gen:write(
40
"\n#define AS(name) (sizeof(struct name) / sizeof(syscallarg_t))\n")
41
42
-- Write out all the compat directives from compat_options.
43
for _, v in pairs(config.compat_options) do
44
gen:write(string.format([[
45
46
#ifdef %s
47
#define %s(n, name) .sy_narg = n, .sy_call = (sy_call_t *)__CONCAT(%s, name)
48
#else
49
#define %s(n, name) .sy_narg = 0, .sy_call = (sy_call_t *)nosys
50
#endif
51
]], v.definition, v.flag:lower(), v.prefix, v.flag:lower()))
52
end
53
-- Add a newline only if there were compat_options.
54
if config.compat_options ~= nil then
55
gen:write("\n")
56
end
57
58
gen:write(string.format([[
59
/* The casts are bogus but will do for now. */
60
struct sysent %s[] = {
61
]], config.switchname))
62
63
for _, v in pairs(s) do
64
local c = v:compatLevel()
65
-- Comment is the function name by default, but may change
66
-- based on the type of system call.
67
local comment = v.name
68
69
gen:write(v.prolog);
70
71
-- Handle non-compat:
72
if v:native() then
73
gen:write(string.format(
74
"\t{ .sy_narg = %s, .sy_call = (sy_call_t *)",
75
v.args_size))
76
-- Handle SYSMUX flag:
77
if v.type.SYSMUX then
78
gen:write(string.format("nosys, " ..
79
".sy_auevent = AUE_NULL, " ..
80
".sy_flags = %s, " ..
81
".sy_thrcnt = SY_THR_STATIC },",
82
v.cap))
83
-- Handle NOSTD flag:
84
elseif v.type.NOSTD then
85
gen:write(string.format("lkmressys, " ..
86
".sy_auevent = AUE_NULL, " ..
87
".sy_flags = %s, " ..
88
".sy_thrcnt = SY_THR_ABSENT },",
89
v.cap))
90
-- Handle rest of non-compat:
91
else
92
if v.name == "nosys" or
93
v.name == "lkmnosys" or
94
v.name == "sysarch" or
95
v.name:find("^freebsd") or
96
v.name:find("^linux") then
97
gen:write(string.format("%s, " ..
98
".sy_auevent = %s, " ..
99
".sy_flags = %s, " ..
100
".sy_thrcnt = %s },",
101
v:symbol(), v.audit, v.cap, v.thr))
102
else
103
gen:write(string.format("sys_%s, " ..
104
".sy_auevent = %s, " ..
105
".sy_flags = %s, " ..
106
".sy_thrcnt = %s },",
107
v:symbol(), v.audit, v.cap, v.thr))
108
end
109
end
110
111
-- Handle compat (everything >= FREEBSD3):
112
elseif c >= 3 then
113
-- Lookup the info for this specific compat option.
114
local flag, descr
115
for _, opt in pairs(config.compat_options) do
116
if opt.compatlevel == c then
117
flag = opt.flag
118
flag = flag:lower()
119
descr = opt.descr
120
break
121
end
122
end
123
124
if v.type.NOSTD then
125
gen:write(string.format("\t{ " ..
126
".sy_narg = %s, " ..
127
".sy_call = (sy_call_t *)%s, " ..
128
".sy_auevent = %s, " ..
129
".sy_flags = 0, " ..
130
".sy_thrcnt = SY_THR_ABSENT },",
131
"0", "lkmressys", "AUE_NULL"))
132
else
133
gen:write(string.format("\t{ %s(%s,%s), " ..
134
".sy_auevent = %s, " ..
135
".sy_flags = %s, " ..
136
".sy_thrcnt = %s },",
137
flag, v.args_size, v.name, v.audit, v.cap, v.thr))
138
end
139
comment = descr .. " " .. v.name
140
141
-- Handle obsolete:
142
elseif v.type.OBSOL then
143
gen:write("\t{ " ..
144
".sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
145
".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
146
".sy_thrcnt = SY_THR_ABSENT },")
147
comment = "obsolete " .. v.name
148
149
-- Handle unimplemented:
150
elseif v.type.UNIMPL then
151
gen:write("\t{ " ..
152
".sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
153
".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
154
".sy_thrcnt = SY_THR_ABSENT },")
155
-- UNIMPL comment is not different in sysent.
156
157
-- Handle reserved:
158
elseif v.type.RESERVED then
159
gen:write("\t{ " ..
160
".sy_narg = 0, .sy_call = (sy_call_t *)nosys, " ..
161
".sy_auevent = AUE_NULL, .sy_flags = 0, " ..
162
".sy_thrcnt = SY_THR_ABSENT },")
163
comment = "reserved for local use"
164
end
165
166
gen:write(string.format("\t/* %d = %s */\n", v.num, comment))
167
end
168
gen:write(tbl.epilog)
169
170
-- End
171
gen:write("};\n")
172
end
173
174
-- Entry of script:
175
if script then
176
local config = require("config")
177
178
if #arg < 1 or #arg > 2 then
179
error("usage: " .. arg[0] .. " syscall.master")
180
end
181
182
local sysfile, configfile = arg[1], arg[2]
183
184
config.merge(configfile)
185
config.mergeCompat()
186
187
-- The parsed syscall table.
188
local tbl = FreeBSDSyscall:new{sysfile = sysfile, config = config}
189
190
init_sysent.file = config.syssw -- change file here
191
init_sysent.generate(tbl, config, init_sysent.file)
192
end
193
194
-- Return the module.
195
return init_sysent
196
197