1 #! /bin/sh -
2 # $OpenBSD: makesyscalls.sh,v 1.18 2022/12/05 23:18:37 deraadt Exp $
3 # $NetBSD: makesyscalls.sh,v 1.26 1998/01/09 06:17:51 thorpej Exp $
4 #
5 # Copyright (c) 1994,1996 Christopher G. Demetriou
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 # 1. Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 # 3. All advertising materials mentioning features or use of this software
17 # must display the following acknowledgement:
18 # This product includes software developed for the NetBSD Project
19 # by Christopher G. Demetriou.
20 # 4. The name of the author may not be used to endorse or promote products
21 # derived from this software without specific prior written permission
22 #
23 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34 # @(#)makesyscalls.sh 8.1 (Berkeley) 6/10/93
35
36 set -e
37
38 case $# in
39 1) ;;
40 *) echo "Usage: $0 input-file" 1>&2
41 exit 1
42 ;;
43 esac
44
45 sysnames="syscalls.c"
46 sysnumhdr="../sys/syscall.h"
47 syssw="init_sysent.c"
48 sysarghdr="../sys/syscallargs.h"
49
50 # Any additions to the next line for options that are required for the
51 # (new) kernel to boot an existing userland must be coordinated with
52 # the snapshot builders
53 compatopts=""
54
55 switchname="sysent"
56 namesname="syscallnames"
57 constprefix="SYS_"
58
59 # this script sets the following variables:
60 # sysnames the syscall names file
61 # sysnumhdr the syscall numbers file
62 # syssw the syscall switch file
63 # sysarghdr the syscall argument struct definitions
64 # compatopts those syscall types that are for 'compat' syscalls
65 # switchname the name for the 'const struct sysent' we define
66 # namesname the name for the 'const char *const[]' we define
67 # constprefix the prefix for the system call constants
68 #
69 # NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'LIBCOMPAT'.
70
71 # tmp files:
72 sysdcl="sysent.dcl"
73 sysprotos="sys.protos"
74 syscompat_pref="sysent."
75 sysent="sysent.switch"
76
77 trap "rm $sysdcl $sysprotos $sysent" 0
78
79 # before handing it off to awk, make a few adjustments:
80 # (1) insert spaces around {, }, (, ), *, and commas.
81 # (2) get rid of any and all dollar signs (so that rcs id use safe)
82 #
83 # The awk script will deal with blank lines and lines that
84 # start with the comment character (';').
85
86 sed -e '
87 s/\$//g
88 :join
89 /\\$/{a\
90
91 N
92 s/\\\n//
93 b join
94 }
95 2,${
96 /^#/!s/\([{}()*,]\)/ \1 /g
97 }
98 ' < $1 | awk "
99 BEGIN {
100 # to allow nested #if/#else/#endif sets
101 savedepth = 0
102
103 sysnames = \"$sysnames\"
104 sysprotos = \"$sysprotos\"
105 sysnumhdr = \"$sysnumhdr\"
106 sysarghdr = \"$sysarghdr\"
107 switchname = \"$switchname\"
108 namesname = \"$namesname\"
109 constprefix = \"$constprefix\"
110
111 sysdcl = \"$sysdcl\"
112 syscompat_pref = \"$syscompat_pref\"
113 sysent = \"$sysent\"
114 infile = \"$1\"
115
116 compatopts = \"$compatopts\"
117 "'
118
119 printf "/*\t\$OpenBSD\$\t*/\n\n" > sysdcl
120 printf "/*\n * System call switch table.\n *\n" > sysdcl
121 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
122
123 ncompat = split(compatopts,compat)
124 for (i = 1; i <= ncompat; i++) {
125 compat_upper[i] = toupper(compat[i])
126
127 printf "\n#ifdef %s\n", compat_upper[i] > sysent
128 printf "#define %s(func) __CONCAT(%s_,func)\n", compat[i], \
129 compat[i] > sysent
130 printf "#else\n" > sysent
131 printf "#define %s(func) sys_nosys\n", compat[i] > sysent
132 printf "#endif\n" > sysent
133 }
134
135 printf "\n#define\ts(type)\tsizeof(type)\n\n" > sysent
136 printf "const struct sysent %s[] = {\n",switchname > sysent
137
138 printf "/*\t\$OpenBSD\$\t*/\n\n" > sysnames
139 printf "/*\n * System call names.\n *\n" > sysnames
140 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
141
142 printf "\n/*\n * System call prototypes.\n */\n\n" > sysprotos
143
144 printf "/*\t\$OpenBSD\$\t*/\n\n" > sysnumhdr
145 printf "/*\n * System call numbers.\n *\n" > sysnumhdr
146 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr
147
148 printf "/*\t\$OpenBSD\$\t*/\n\n" > sysarghdr
149 printf "/*\n * System call argument lists.\n *\n" > sysarghdr
150 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr
151 }
152 NR == 1 {
153 printf " * created from%s\n */\n\n", $0 > sysdcl
154
155 printf " * created from%s\n */\n\n", $0 > sysnames
156 printf "const char *const %s[] = {\n",namesname > sysnames
157
158 printf " * created from%s\n */\n\n", $0 > sysnumhdr
159
160 printf " * created from%s\n */\n\n", $0 > sysarghdr
161 printf "#ifdef\tsyscallarg\n" > sysarghdr
162 printf "#undef\tsyscallarg\n" > sysarghdr
163 printf "#endif\n\n" > sysarghdr
164 printf "#define\tsyscallarg(x)\t\t\t\t\t\t\t\\\n" > sysarghdr
165 printf "\tunion {\t\t\t\t\t\t\t\t\\\n" > sysarghdr
166 printf "\t\tregister_t pad;\t\t\t\t\t\t\\\n" > sysarghdr
167 printf "\t\tstruct { x datum; } le;\t\t\t\t\t\\\n" > sysarghdr
168 printf "\t\tstruct {\t\t\t\t\t\t\\\n" > sysarghdr
169 printf "\t\t\tint8_t pad[ (sizeof (register_t) < sizeof (x))\t\\\n" \
170 > sysarghdr
171 printf "\t\t\t\t? 0\t\t\t\t\t\\\n" > sysarghdr
172 printf "\t\t\t\t: sizeof (register_t) - sizeof (x)];\t\\\n" \
173 > sysarghdr
174 printf "\t\t\tx datum;\t\t\t\t\t\\\n" > sysarghdr
175 printf "\t\t} be;\t\t\t\t\t\t\t\\\n" > sysarghdr
176 printf "\t}\n" > sysarghdr
177 next
178 }
179 NF == 0 || $1 ~ /^;/ {
180 next
181 }
182 $1 ~ /^#[ ]*include/ {
183 print > sysdcl
184 next
185 }
186 $1 ~ /^#[ ]*if/ {
187 print > sysent
188 print > sysprotos
189 print > sysnames
190 savesyscall[++savedepth] = syscall
191 next
192 }
193 $1 ~ /^#[ ]*else/ {
194 print > sysent
195 print > sysprotos
196 print > sysnames
197 if (savedepth <= 0) {
198 printf "%s: line %d: unbalanced #else\n", \
199 infile, NR
200 exit 1
201 }
202 syscall = savesyscall[savedepth]
203 next
204 }
205 $1 ~ /^#/ {
206 if ($1 ~ /^#[ ]*endif/) {
207 if (savedepth <= 0) {
208 printf "%s: line %d: unbalanced #endif\n", \
209 infile, NR
210 exit 1
211 }
212 savedepth--;
213 }
214 print > sysent
215 print > sysprotos
216 print > sysnames
217 next
218 }
219 syscall != $1 {
220 printf "%s: line %d: syscall number out of sync at %d\n", \
221 infile, NR, syscall
222 printf "line is:\n"
223 print
224 exit 1
225 }
226 function parserr(was, wanted) {
227 printf "%s: line %d: unexpected %s (expected %s)\n", \
228 infile, NR, was, wanted
229 exit 1
230 }
231 function parseline() {
232 f=3 # toss number and type
233 sycall_flags="0"
234 if ($NF != "}") {
235 funcalias=$NF
236 end=NF-1
237 } else {
238 funcalias=""
239 end=NF
240 }
241 if ($f == "NOLOCK") { # syscall does not need locks
242 sycall_flags = sprintf("SY_NOLOCK | %s", sycall_flags)
243 f++
244 }
245 if ($f ~ /^[a-z0-9_]*$/) { # allow syscall alias
246 funcalias=$f
247 f++
248 }
249 if ($f != "{")
250 parserr($f, "{")
251 f++
252 if ($end != "}")
253 parserr($end, "}")
254 end--
255 if ($end != ";")
256 parserr($end, ";")
257 end--
258 if ($end != ")")
259 parserr($end, ")")
260 end--
261
262 returntype = oldf = "";
263 do {
264 if (returntype != "" && oldf != "*")
265 returntype = returntype" ";
266 returntype = returntype$f;
267 oldf = $f;
268 f++
269 } while (f < (end - 1) && $(f+1) != "(");
270 if (f == (end - 1)) {
271 parserr($f, "function argument definition (maybe \"(\"?)");
272 }
273
274 funcname=$f
275 if (funcalias == "") {
276 funcalias=funcname
277 sub(/^([^_]+_)*sys_/, "", funcalias)
278 }
279 f++
280
281 if ($f != "(")
282 parserr($f, ")")
283 f++
284
285 argc=0;
286 if (f == end) {
287 if ($f != "void")
288 parserr($f, "argument definition")
289 isvarargs = 0;
290 varargc = 0;
291 return
292 }
293
294 # some system calls (open() and fcntl()) can accept a variable
295 # number of arguments. If syscalls accept a variable number of
296 # arguments, they must still have arguments specified for
297 # the remaining argument "positions," because of the way the
298 # kernel system call argument handling works.
299 #
300 # Indirect system calls, e.g. syscall(), are exceptions to this
301 # rule, since they are handled entirely by machine-dependent code
302 # and do not need argument structures built.
303
304 isvarargs = 0;
305 while (f <= end) {
306 if ($f == "...") {
307 f++;
308 isvarargs = 1;
309 varargc = argc;
310 continue;
311 }
312 argc++
313 argtype[argc]=""
314 oldf=""
315 while (f < end && $(f+1) != ",") {
316 if (argtype[argc] != "" && oldf != "*")
317 argtype[argc] = argtype[argc]" ";
318 argtype[argc] = argtype[argc]$f;
319 oldf = $f;
320 f++
321 }
322 if (argtype[argc] == "")
323 parserr($f, "argument definition")
324 argname[argc]=$f;
325 f += 2; # skip name, and any comma
326 }
327 # must see another argument after varargs notice.
328 if (isvarargs) {
329 if (argc == varargc && $2 != "INDIR")
330 parserr($f, "argument definition")
331 } else
332 varargc = argc;
333 }
334 function putent(nodefs, compatwrap) {
335 # output syscall declaration for switch table. INDIR functions
336 # get none, since they always have sys_nosys() for their table
337 # entries.
338 if (nodefs != "INDIR") {
339 prototype = "(struct proc *, void *, register_t *)"
340 if (compatwrap == "")
341 printf("int\t%s%s;\n", funcname,
342 prototype) > sysprotos
343 else
344 printf("int\t%s_%s%s;\n", compatwrap, funcname,
345 prototype) > sysprotos
346 }
347
348 # output syscall switch entry
349 if (nodefs == "INDIR") {
350 printf("\t{ 0, 0, %s,\n\t sys_nosys },\t\t\t/* %d = %s (indir) */\n", \
351 sycall_flags, syscall, funcalias) > sysent
352 } else {
353 # printf("\t{ { %d", argc) > sysent
354 # for (i = 1; i <= argc; i++) {
355 # if (i == 5) # wrap the line
356 # printf(",\n\t ") > sysent
357 # else
358 # printf(", ") > sysent
359 # printf("s(%s)", argtypenospc[i]) > sysent
360 # }
361 printf("\t{ %d, ", argc) > sysent
362 if (argc == 0)
363 printf("0") > sysent
364 else if (compatwrap == "")
365 printf("s(struct %s_args)", funcname) > sysent
366 else
367 printf("s(struct %s_%s_args)", compatwrap,
368 funcname) > sysent
369 if (compatwrap == "")
370 wfn = sprintf("%s", funcname);
371 else
372 wfn = sprintf("%s(%s)", compatwrap, funcname);
373 printf(", %s,\n\t %s },", sycall_flags, wfn) > sysent
374 for (i = 0; i < (33 - length(wfn)) / 8; i++)
375 printf("\t") > sysent
376 if (compatwrap == "")
377 printf("/* %d = %s */\n", syscall, funcalias) > sysent
378 else
379 printf("/* %d = %s %s */\n", syscall, compatwrap,
380 funcalias) > sysent
381 }
382
383 # output syscall name for names table
384 if (compatwrap == "")
385 printf("\t\"%s\",\t\t\t/* %d = %s */\n", funcalias, syscall,
386 funcalias) > sysnames
387 else
388 printf("\t\"%s_%s\",\t/* %d = %s %s */\n", compatwrap,
389 funcalias, syscall, compatwrap, funcalias) > sysnames
390
391 # output syscall number of header, if appropriate
392 if (nodefs == "" || nodefs == "NOARGS" || nodefs == "INDIR") {
393 # output a prototype, to be used to generate lint stubs in
394 # libc.
395 printf("/* syscall: \"%s\" ret: \"%s\" args:", funcalias,
396 returntype) > sysnumhdr
397 for (i = 1; i <= varargc; i++)
398 printf(" \"%s\"", argtype[i]) > sysnumhdr
399 if (isvarargs)
400 printf(" \"...\"") > sysnumhdr
401 printf(" */\n") > sysnumhdr
402
403 printf("#define\t%s%s\t%d\n\n", constprefix, funcalias,
404 syscall) > sysnumhdr
405 } else if (nodefs != "NODEF")
406 printf("\t\t\t\t/* %d is %s %s */\n\n", syscall,
407 compatwrap, funcalias) > sysnumhdr
408
409 # output syscall argument structure, if it has arguments
410 if (argc != 0 && nodefs != "NOARGS" && nodefs != "INDIR") {
411 if (compatwrap == "")
412 printf("\nstruct %s_args {\n", funcname) > sysarghdr
413 else
414 printf("\nstruct %s_%s_args {\n", compatwrap,
415 funcname) > sysarghdr
416 for (i = 1; i <= argc; i++)
417 printf("\tsyscallarg(%s) %s;\n", argtype[i],
418 argname[i]) > sysarghdr
419 printf("};\n") > sysarghdr
420 }
421 }
422 $2 == "STD" {
423 parseline()
424 putent("", "");
425 syscall++
426 next
427 }
428 $2 == "NODEF" || $2 == "NOARGS" || $2 == "INDIR" {
429 parseline()
430 putent($2, "")
431 syscall++
432 next
433 }
434 $2 == "OBSOL" || $2 == "UNIMPL" {
435 if ($2 == "OBSOL")
436 comment="obsolete"
437 else
438 comment="unimplemented"
439 for (i = 3; i <= NF; i++)
440 comment=comment " " $i
441
442 printf("\t{ 0, 0, 0,\n\t sys_nosys },\t\t\t/* %d = %s */\n", \
443 syscall, comment) > sysent
444 printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \
445 syscall, comment, syscall, comment) > sysnames
446 if ($2 != "UNIMPL")
447 printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr
448 syscall++
449 next
450 }
451 {
452 for (i = 1; i <= ncompat; i++) {
453 if ($2 == compat_upper[i]) {
454 parseline();
455 putent("COMMENT", compat[i])
456 syscall++
457 next
458 }
459 }
460 printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
461 exit 1
462 }
463 END {
464 printf("};\n\n") > sysent
465 printf("};\n") > sysnames
466 printf("#define\t%sMAXSYSCALL\t%d\n", constprefix, syscall) > sysnumhdr
467 } '
468
469 cat $sysprotos >> $sysarghdr
470 cat $sysdcl $sysent > $syssw
471
472 #chmod 444 $sysnames $sysnumhdr $syssw
Cache object: 2ce9f0502c500daff378dba1f2d49168
|