Annotation of sys/kern/makesyscalls.sh, Revision 1.1.1.1
1.1 nbrk 1: #! /bin/sh -
2: # $OpenBSD: makesyscalls.sh,v 1.10 2002/03/14 23:44:37 millert 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: 2) ;;
40: *) echo "Usage: $0 config-file input-file" 1>&2
41: exit 1
42: ;;
43: esac
44:
45: # source the config file.
46: case $1 in
47: /*) . $1
48: ;;
49: *) . ./$1
50: ;;
51: esac
52:
53: # the config file sets the following variables:
54: # sysnames the syscall names file
55: # sysnumhdr the syscall numbers file
56: # syssw the syscall switch file
57: # sysarghdr the syscall argument struct definitions
58: # compatopts those syscall types that are for 'compat' syscalls
59: # switchname the name for the 'struct sysent' we define
60: # namesname the name for the 'char *[]' we define
61: # constprefix the prefix for the system call constants
62: #
63: # NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'LIBCOMPAT'.
64:
65: # tmp files:
66: sysdcl="sysent.dcl"
67: sysprotos="sys.protos"
68: syscompat_pref="sysent."
69: sysent="sysent.switch"
70:
71: trap "rm $sysdcl $sysprotos $sysent" 0
72:
73: # Awk program (must support nawk extensions)
74: # Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
75: awk=${AWK:-awk}
76:
77: # Does this awk have a "toupper" function? (i.e. is it GNU awk)
78: isgawk=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
79:
80: # If this awk does not define "toupper" then define our own.
81: if [ "$isgawk" = TRUE ] ; then
82: # GNU awk provides it.
83: toupper=
84: else
85: # Provide our own toupper()
86: toupper='
87: function toupper(str) {
88: _toupper_cmd = "echo "str" |tr a-z A-Z"
89: _toupper_cmd | getline _toupper_str;
90: close(_toupper_cmd);
91: return _toupper_str;
92: }'
93: fi
94:
95: # before handing it off to awk, make a few adjustments:
96: # (1) insert spaces around {, }, (, ), *, and commas.
97: # (2) get rid of any and all dollar signs (so that rcs id use safe)
98: #
99: # The awk script will deal with blank lines and lines that
100: # start with the comment character (';').
101:
102: sed -e '
103: s/\$//g
104: :join
105: /\\$/{a\
106:
107: N
108: s/\\\n//
109: b join
110: }
111: 2,${
112: /^#/!s/\([{}()*,]\)/ \1 /g
113: }
114: ' < $2 | $awk "
115: $toupper
116: BEGIN {
117: # to allow nested #if/#else/#endif sets
118: savedepth = 0
119:
120: sysnames = \"$sysnames\"
121: sysprotos = \"$sysprotos\"
122: sysnumhdr = \"$sysnumhdr\"
123: sysarghdr = \"$sysarghdr\"
124: switchname = \"$switchname\"
125: namesname = \"$namesname\"
126: constprefix = \"$constprefix\"
127:
128: sysdcl = \"$sysdcl\"
129: syscompat_pref = \"$syscompat_pref\"
130: sysent = \"$sysent\"
131: infile = \"$2\"
132:
133: compatopts = \"$compatopts\"
134: "'
135:
136: printf "/*\t\$OpenBSD\$\t*/\n\n" > sysdcl
137: printf "/*\n * System call switch table.\n *\n" > sysdcl
138: printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
139:
140: ncompat = split(compatopts,compat)
141: for (i = 1; i <= ncompat; i++) {
142: compat_upper[i] = toupper(compat[i])
143:
144: printf "\n#ifdef %s\n", compat_upper[i] > sysent
145: printf "#define %s(func) __CONCAT(%s_,func)\n", compat[i], \
146: compat[i] > sysent
147: printf "#else\n" > sysent
148: printf "#define %s(func) sys_nosys\n", compat[i] > sysent
149: printf "#endif\n" > sysent
150: }
151:
152: printf "\n#define\ts(type)\tsizeof(type)\n\n" > sysent
153: printf "struct sysent %s[] = {\n",switchname > sysent
154:
155: printf "/*\t\$OpenBSD\$\t*/\n\n" > sysnames
156: printf "/*\n * System call names.\n *\n" > sysnames
157: printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
158:
159: printf "\n/*\n * System call prototypes.\n */\n\n" > sysprotos
160:
161: printf "/*\t\$OpenBSD\$\t*/\n\n" > sysnumhdr
162: printf "/*\n * System call numbers.\n *\n" > sysnumhdr
163: printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr
164:
165: printf "/*\t\$OpenBSD\$\t*/\n\n" > sysarghdr
166: printf "/*\n * System call argument lists.\n *\n" > sysarghdr
167: printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr
168: }
169: NR == 1 {
170: printf " * created from%s\n */\n\n", $0 > sysdcl
171:
172: printf " * created from%s\n */\n\n", $0 > sysnames
173: printf "char *%s[] = {\n",namesname > sysnames
174:
175: printf " * created from%s\n */\n\n", $0 > sysnumhdr
176:
177: printf " * created from%s\n */\n\n", $0 > sysarghdr
178: printf "#ifdef\tsyscallarg\n" > sysarghdr
179: printf "#undef\tsyscallarg\n" > sysarghdr
180: printf "#endif\n\n" > sysarghdr
181: printf "#define\tsyscallarg(x)\t\t\t\t\t\t\t\\\n" > sysarghdr
182: printf "\tunion {\t\t\t\t\t\t\t\t\\\n" > sysarghdr
183: printf "\t\tregister_t pad;\t\t\t\t\t\t\\\n" > sysarghdr
184: printf "\t\tstruct { x datum; } le;\t\t\t\t\t\\\n" > sysarghdr
185: printf "\t\tstruct {\t\t\t\t\t\t\\\n" > sysarghdr
186: printf "\t\t\tint8_t pad[ (sizeof (register_t) < sizeof (x))\t\\\n" \
187: > sysarghdr
188: printf "\t\t\t\t? 0\t\t\t\t\t\\\n" > sysarghdr
189: printf "\t\t\t\t: sizeof (register_t) - sizeof (x)];\t\\\n" \
190: > sysarghdr
191: printf "\t\t\tx datum;\t\t\t\t\t\\\n" > sysarghdr
192: printf "\t\t} be;\t\t\t\t\t\t\t\\\n" > sysarghdr
193: printf "\t}\n" > sysarghdr
194: next
195: }
196: NF == 0 || $1 ~ /^;/ {
197: next
198: }
199: $1 ~ /^#[ ]*include/ {
200: print > sysdcl
201: next
202: }
203: $1 ~ /^#[ ]*if/ {
204: print > sysent
205: print > sysprotos
206: print > sysnames
207: savesyscall[++savedepth] = syscall
208: next
209: }
210: $1 ~ /^#[ ]*else/ {
211: print > sysent
212: print > sysprotos
213: print > sysnames
214: if (savedepth <= 0) {
215: printf "%s: line %d: unbalenced #else\n", \
216: infile, NR
217: exit 1
218: }
219: syscall = savesyscall[savedepth]
220: next
221: }
222: $1 ~ /^#/ {
223: if ($1 ~ /^#[ ]*endif/) {
224: if (savedepth <= 0) {
225: printf "%s: line %d: unbalenced #endif\n", \
226: infile, NR
227: exit 1
228: }
229: savedepth--;
230: }
231: print > sysent
232: print > sysprotos
233: print > sysnames
234: next
235: }
236: syscall != $1 {
237: printf "%s: line %d: syscall number out of sync at %d\n", \
238: infile, NR, syscall
239: printf "line is:\n"
240: print
241: exit 1
242: }
243: function parserr(was, wanted) {
244: printf "%s: line %d: unexpected %s (expected %s)\n", \
245: infile, NR, was, wanted
246: exit 1
247: }
248: function parseline() {
249: f=3 # toss number and type
250: if ($NF != "}") {
251: funcalias=$NF
252: end=NF-1
253: } else {
254: funcalias=""
255: end=NF
256: }
257: if ($f ~ /^[a-z0-9_]*$/) { # allow syscall alias
258: funcalias=$f
259: f++
260: }
261: if ($f != "{")
262: parserr($f, "{")
263: f++
264: if ($end != "}")
265: parserr($end, "}")
266: end--
267: if ($end != ";")
268: parserr($end, ";")
269: end--
270: if ($end != ")")
271: parserr($end, ")")
272: end--
273:
274: returntype = oldf = "";
275: do {
276: if (returntype != "" && oldf != "*")
277: returntype = returntype" ";
278: returntype = returntype$f;
279: oldf = $f;
280: f++
281: } while (f < (end - 1) && $(f+1) != "(");
282: if (f == (end - 1)) {
283: parserr($f, "function argument definition (maybe \"(\"?)");
284: }
285:
286: funcname=$f
287: if (funcalias == "") {
288: funcalias=funcname
289: sub(/^([^_]+_)*sys_/, "", funcalias)
290: }
291: f++
292:
293: if ($f != "(")
294: parserr($f, ")")
295: f++
296:
297: argc=0;
298: if (f == end) {
299: if ($f != "void")
300: parserr($f, "argument definition")
301: isvarargs = 0;
302: varargc = 0;
303: return
304: }
305:
306: # some system calls (open() and fcntl()) can accept a variable
307: # number of arguments. If syscalls accept a variable number of
308: # arguments, they must still have arguments specified for
309: # the remaining argument "positions," because of the way the
310: # kernel system call argument handling works.
311: #
312: # Indirect system calls, e.g. syscall(), are exceptions to this
313: # rule, since they are handled entirely by machine-dependent code
314: # and do not need argument structures built.
315:
316: isvarargs = 0;
317: while (f <= end) {
318: if ($f == "...") {
319: f++;
320: isvarargs = 1;
321: varargc = argc;
322: continue;
323: }
324: argc++
325: argtype[argc]=""
326: oldf=""
327: while (f < end && $(f+1) != ",") {
328: if (argtype[argc] != "" && oldf != "*")
329: argtype[argc] = argtype[argc]" ";
330: argtype[argc] = argtype[argc]$f;
331: oldf = $f;
332: f++
333: }
334: if (argtype[argc] == "")
335: parserr($f, "argument definition")
336: argname[argc]=$f;
337: f += 2; # skip name, and any comma
338: }
339: # must see another argument after varargs notice.
340: if (isvarargs) {
341: if (argc == varargc && $2 != "INDIR")
342: parserr($f, "argument definition")
343: } else
344: varargc = argc;
345: }
346: function putent(nodefs, compatwrap) {
347: # output syscall declaration for switch table. INDIR functions
348: # get none, since they always have sys_nosys() for their table
349: # entries.
350: if (nodefs != "INDIR") {
351: prototype = "(struct proc *, void *, register_t *)"
352: if (compatwrap == "")
353: printf("int\t%s%s;\n", funcname,
354: prototype) > sysprotos
355: else
356: printf("int\t%s_%s%s;\n", compatwrap, funcname,
357: prototype) > sysprotos
358: }
359:
360: # output syscall switch entry
361: if (nodefs == "INDIR") {
362: printf("\t{ 0, 0,\n\t sys_nosys },\t\t\t/* %d = %s (indir) */\n", \
363: syscall, funcalias) > sysent
364: } else {
365: # printf("\t{ { %d", argc) > sysent
366: # for (i = 1; i <= argc; i++) {
367: # if (i == 5) # wrap the line
368: # printf(",\n\t ") > sysent
369: # else
370: # printf(", ") > sysent
371: # printf("s(%s)", argtypenospc[i]) > sysent
372: # }
373: printf("\t{ %d, ", argc) > sysent
374: if (argc == 0)
375: printf("0") > sysent
376: else if (compatwrap == "")
377: printf("s(struct %s_args)", funcname) > sysent
378: else
379: printf("s(struct %s_%s_args)", compatwrap,
380: funcname) > sysent
381: if (compatwrap == "")
382: wfn = sprintf("%s", funcname);
383: else
384: wfn = sprintf("%s(%s)", compatwrap, funcname);
385: printf(",\n\t %s },", wfn) > sysent
386: for (i = 0; i < (33 - length(wfn)) / 8; i++)
387: printf("\t") > sysent
388: if (compatwrap == "")
389: printf("/* %d = %s */\n", syscall, funcalias) > sysent
390: else
391: printf("/* %d = %s %s */\n", syscall, compatwrap,
392: funcalias) > sysent
393: }
394:
395: # output syscall name for names table
396: if (compatwrap == "")
397: printf("\t\"%s\",\t\t\t/* %d = %s */\n", funcalias, syscall,
398: funcalias) > sysnames
399: else
400: printf("\t\"%s_%s\",\t/* %d = %s %s */\n", compatwrap,
401: funcalias, syscall, compatwrap, funcalias) > sysnames
402:
403: # output syscall number of header, if appropriate
404: if (nodefs == "" || nodefs == "NOARGS" || nodefs == "INDIR") {
405: # output a prototype, to be used to generate lint stubs in
406: # libc.
407: printf("/* syscall: \"%s\" ret: \"%s\" args:", funcalias,
408: returntype) > sysnumhdr
409: for (i = 1; i <= varargc; i++)
410: printf(" \"%s\"", argtype[i]) > sysnumhdr
411: if (isvarargs)
412: printf(" \"...\"") > sysnumhdr
413: printf(" */\n") > sysnumhdr
414:
415: printf("#define\t%s%s\t%d\n\n", constprefix, funcalias,
416: syscall) > sysnumhdr
417: } else if (nodefs != "NODEF")
418: printf("\t\t\t\t/* %d is %s %s */\n\n", syscall,
419: compatwrap, funcalias) > sysnumhdr
420:
421: # output syscall argument structure, if it has arguments
422: if (argc != 0 && nodefs != "NOARGS" && nodefs != "INDIR") {
423: if (compatwrap == "")
424: printf("\nstruct %s_args {\n", funcname) > sysarghdr
425: else
426: printf("\nstruct %s_%s_args {\n", compatwrap,
427: funcname) > sysarghdr
428: for (i = 1; i <= argc; i++)
429: printf("\tsyscallarg(%s) %s;\n", argtype[i],
430: argname[i]) > sysarghdr
431: printf("};\n") > sysarghdr
432: }
433: }
434: $2 == "STD" {
435: parseline()
436: putent("", "");
437: syscall++
438: next
439: }
440: $2 == "NODEF" || $2 == "NOARGS" || $2 == "INDIR" {
441: parseline()
442: putent($2, "")
443: syscall++
444: next
445: }
446: $2 == "OBSOL" || $2 == "UNIMPL" {
447: if ($2 == "OBSOL")
448: comment="obsolete"
449: else
450: comment="unimplemented"
451: for (i = 3; i <= NF; i++)
452: comment=comment " " $i
453:
454: printf("\t{ 0, 0,\n\t sys_nosys },\t\t\t/* %d = %s */\n", \
455: syscall, comment) > sysent
456: printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \
457: syscall, comment, syscall, comment) > sysnames
458: if ($2 != "UNIMPL")
459: printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr
460: syscall++
461: next
462: }
463: {
464: for (i = 1; i <= ncompat; i++) {
465: if ($2 == compat_upper[i]) {
466: parseline();
467: putent("COMMENT", compat[i])
468: syscall++
469: next
470: }
471: }
472: printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
473: exit 1
474: }
475: END {
476: printf("};\n\n") > sysent
477: printf("};\n") > sysnames
478: printf("#define\t%sMAXSYSCALL\t%d\n", constprefix, syscall) > sysnumhdr
479: } '
480:
481: cat $sysprotos >> $sysarghdr
482: cat $sysdcl $sysent > $syssw
483:
484: #chmod 444 $sysnames $sysnumhdr $syssw
CVSweb