Annotation of sys/kern/makesyscalls.sh, Revision 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