1# $NetBSD: makesyscalls.sh,v 1.143 2014/05/18 21:25:44 justin Exp $ 2# 3# Copyright (c) 1994, 1996, 2000 Christopher G. Demetriou 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 3. All advertising materials mentioning features or use of this software 15# must display the following acknowledgement: 16# This product includes software developed for the NetBSD Project 17# by Christopher G. Demetriou. 18# 4. The name of the author may not be used to endorse or promote products 19# derived from this software without specific prior written permission 20# 21# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32# @(#)makesyscalls.sh 8.1 (Berkeley) 6/10/93 33 34set -e 35 36case $# in 37 2) ;; 38 *) echo "Usage: $0 config-file input-file" 1>&2 39 exit 1 40 ;; 41esac 42 43# the config file sets the following variables: 44# sysalign check for alignment of off_t/dev_t/time_t 45# sysnames the syscall names file 46# sysnumhdr the syscall numbers file 47# syssw the syscall switch file 48# sysarghdr the syscall argument struct definitions 49# compatopts those syscall types that are for 'compat' syscalls 50# switchname the name for the 'struct sysent' we define 51# namesname the name for the 'const char *[]' we define 52# constprefix the prefix for the system call constants 53# registertype the type for register_t 54# nsysent the size of the sysent table 55# sys_nosys [optional] name of function called for unsupported 56# syscalls, if not sys_nosys() 57# maxsysargs [optiona] the maximum number or arguments 58# 59# NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'SYSLIBCOMPAT'. 60 61# source the config file. 62sys_nosys="sys_nosys" # default is sys_nosys(), if not specified otherwise 63maxsysargs=8 # default limit is 8 (32bit) arguments 64rumpcalls="/dev/null" 65rumpcallshdr="/dev/null" 66rumpsysmap="/dev/null" 67rumpsysent="rumpsysent.tmp" 68. ./$1 69 70# tmp files: 71sysdcl="sysent.dcl" 72sysprotos="sys.protos" 73syscompat_pref="sysent." 74sysent="sysent.switch" 75sysnamesbottom="sysnames.bottom" 76rumptypes="rumphdr.types" 77rumpprotos="rumphdr.protos" 78 79trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent $rumptypes $rumpprotos" 0 80 81# Awk program (must support nawk extensions) 82# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere. 83awk=${AWK:-awk} 84 85# Does this awk have a "toupper" function? 86have_toupper=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null` 87 88# If this awk does not define "toupper" then define our own. 89if [ "$have_toupper" = TRUE ] ; then 90 # Used awk (GNU awk or nawk) provides it 91 toupper= 92else 93 # Provide our own toupper() 94 toupper=' 95function toupper(str) { 96 _toupper_cmd = "echo "str" |tr a-z A-Z" 97 _toupper_cmd | getline _toupper_str; 98 close(_toupper_cmd); 99 return _toupper_str; 100}' 101fi 102 103# before handing it off to awk, make a few adjustments: 104# (1) insert spaces around {, }, (, ), *, and commas. 105# (2) get rid of any and all dollar signs (so that rcs id use safe) 106# 107# The awk script will deal with blank lines and lines that 108# start with the comment character (';'). 109 110sed -e ' 111s/\$//g 112:join 113 /\\$/{a\ 114 115 N 116 s/\\\n// 117 b join 118 } 1192,${ 120 /^#/!s/\([{}()*,|]\)/ \1 /g 121} 122' < $2 | $awk " 123$toupper 124BEGIN { 125 # Create a NetBSD tag that does not get expanded when checking 126 # this script out of CVS. (This part of the awk script is in a 127 # shell double-quoted string, so the backslashes are eaten by 128 # the shell.) 129 tag = \"\$\" \"NetBSD\" \"\$\" 130 131 # to allow nested #if/#else/#endif sets 132 savedepth = 0 133 # to track already processed syscalls 134 135 sysnames = \"$sysnames\" 136 sysprotos = \"$sysprotos\" 137 sysnumhdr = \"$sysnumhdr\" 138 sysarghdr = \"$sysarghdr\" 139 sysarghdrextra = \"$sysarghdrextra\" 140 rumpcalls = \"$rumpcalls\" 141 rumpcallshdr = \"$rumpcallshdr\" 142 rumpsysent = \"$rumpsysent\" 143 rumpsysmap = \"$rumpsysmap\" 144 switchname = \"$switchname\" 145 namesname = \"$namesname\" 146 constprefix = \"$constprefix\" 147 registertype = \"$registertype\" 148 sysalign=\"$sysalign\" 149 if (!registertype) { 150 registertype = \"register_t\" 151 } 152 nsysent = \"$nsysent\" 153 154 sysdcl = \"$sysdcl\" 155 syscompat_pref = \"$syscompat_pref\" 156 sysent = \"$sysent\" 157 sysnamesbottom = \"$sysnamesbottom\" 158 rumpprotos = \"$rumpprotos\" 159 rumptypes = \"$rumptypes\" 160 sys_nosys = \"$sys_nosys\" 161 maxsysargs = \"$maxsysargs\" 162 infile = \"$2\" 163 164 compatopts = \"$compatopts\" 165 "' 166 167 if (rumpcalls != "/dev/null") 168 haverumpcalls = 1 169 170 printf "/* %s */\n\n", tag > sysdcl 171 printf "/*\n * System call switch table.\n *\n" > sysdcl 172 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl 173 174 ncompat = split(compatopts,compat) 175 for (i = 1; i <= ncompat; i++) { 176 compat_upper[i] = toupper(compat[i]) 177 178 printf "\n#ifdef %s\n", compat_upper[i] > sysent 179 printf "#define %s(func) __CONCAT(%s_,func)\n", compat[i], \ 180 compat[i] > sysent 181 printf "#else\n" > sysent 182 printf "#define %s(func) %s\n", compat[i], sys_nosys > sysent 183 printf "#endif\n" > sysent 184 } 185 186 printf "\n#define\ts(type)\tsizeof(type)\n" > sysent 187 printf "#define\tn(type)\t(sizeof(type)/sizeof (%s))\n", registertype > sysent 188 printf "#define\tns(type)\tn(type), s(type)\n\n", registertype > sysent 189 printf "struct sysent %s[] = {\n",switchname > sysent 190 191 printf "/* %s */\n\n", tag > sysnames 192 printf "/*\n * System call names.\n *\n" > sysnames 193 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames 194 195 printf "\n/*\n * System call prototypes.\n */\n\n" > sysprotos 196 if (haverumpcalls) 197 printf("#ifndef RUMP_CLIENT\n") > sysprotos 198 199 printf "/* %s */\n\n", tag > sysnumhdr 200 printf "/*\n * System call numbers.\n *\n" > sysnumhdr 201 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr 202 203 printf "/* %s */\n\n", tag > sysarghdr 204 printf "/*\n * System call argument lists.\n *\n" > sysarghdr 205 printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr 206 207 printf "/* %s */\n\n", tag > rumpcalls 208 printf "/*\n * System call vector and marshalling for rump.\n *\n" > rumpcalls 209 printf " * DO NOT EDIT-- this file is automatically generated.\n" > rumpcalls 210 211 printf "/* %s */\n\n", tag > rumpcallshdr 212 printf "/*\n * System call protos in rump namespace.\n *\n" > rumpcallshdr 213 printf " * DO NOT EDIT-- this file is automatically generated.\n" > rumpcallshdr 214} 215NR == 1 { 216 sub(/ $/, "") 217 printf " * created from%s\n */\n\n", $0 > sysdcl 218 printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"%s\");\n\n", tag > sysdcl 219 220 printf " * created from%s\n */\n\n", $0 > sysnames 221 printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"%s\");\n\n", tag > sysnames 222 223 printf " * created from%s\n */\n\n", $0 > rumpcalls 224 printf "#ifdef RUMP_CLIENT\n" > rumpcalls 225 printf "#include <rump/rumpuser_port.h>\n" > rumpcalls 226 printf "#endif /* RUMP_CLIENT */\n\n" > rumpcalls 227 printf "#include <sys/param.h>\n\n" > rumpcalls 228 printf "#ifdef __NetBSD__\n" > rumpcalls 229 printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"%s\");\n\n", tag > rumpcalls 230 231 printf "#include <sys/fstypes.h>\n" > rumpcalls 232 printf "#include <sys/proc.h>\n" > rumpcalls 233 printf "#endif /* __NetBSD__ */\n\n" > rumpcalls 234 printf "#ifdef RUMP_CLIENT\n" > rumpcalls 235 printf "#include <errno.h>\n" > rumpcalls 236 printf "#include <stdint.h>\n" > rumpcalls 237 printf "#include <stdlib.h>\n" > rumpcalls 238 printf "#include <string.h>\n\n" > rumpcalls 239 printf "#include <srcsys/syscall.h>\n" > rumpcalls 240 printf "#include <srcsys/syscallargs.h>\n\n" > rumpcalls 241 printf "#include <rump/rumpclient.h>\n\n" > rumpcalls 242 printf "#define rsys_syscall(num, data, dlen, retval)\t\\\n" > rumpcalls 243 printf " rumpclient_syscall(num, data, dlen, retval)\n" > rumpcalls 244 printf "#define rsys_seterrno(error) errno = error\n" > rumpcalls 245 printf "#else\n" > rumpcalls 246 printf "#include <sys/syscall.h>\n" > rumpcalls 247 printf "#include <sys/syscallargs.h>\n\n" > rumpcalls 248 printf "#include <sys/syscallvar.h>\n\n" > rumpcalls 249 printf "#include <rump/rumpuser.h>\n" > rumpcalls 250 printf "#include \"rump_private.h\"\n\n" > rumpcalls 251 printf "#define rsys_syscall(num, data, dlen, retval)\t\\\n" > rumpcalls 252 printf " rump_syscall(num, data, dlen, retval)\n\n" > rumpcalls 253 printf "#define rsys_seterrno(error) rumpuser_seterrno(error)\n" \ 254 > rumpcalls 255 printf "#endif\n\n" > rumpcalls 256 257 printf "#ifdef RUMP_KERNEL_IS_LIBC\n" > rumpcalls 258 printf "#define rsys_aliases(what,where) \\\n" > rumpcalls 259 printf "\t__strong_alias(what,where); \\\n" > rumpcalls 260 printf "\t__strong_alias(_##what,where);\n" > rumpcalls 261 printf "#else\n#define rsys_aliases(a,b)\n#endif\n\n" > rumpcalls 262 263 printf "#if\tBYTE_ORDER == BIG_ENDIAN\n" > rumpcalls 264 printf "#define SPARG(p,k)\t((p)->k.be.datum)\n" > rumpcalls 265 printf "#else /* LITTLE_ENDIAN, I hope dearly */\n" > rumpcalls 266 printf "#define SPARG(p,k)\t((p)->k.le.datum)\n" > rumpcalls 267 printf "#endif\n\n" > rumpcalls 268 printf "\nvoid rumpns_sys_nomodule(void);\n" > rumpcalls 269 270 printf "\n#ifndef RUMP_CLIENT\n" > rumpsysent 271 printf "int rumpns_enosys(void);\n" > rumpsysent 272 printf "#define\ts(type)\tsizeof(type)\n" > rumpsysent 273 printf "#define\tn(type)\t(sizeof(type)/sizeof (%s))\n", registertype > rumpsysent 274 printf "#define\tns(type)\tn(type), s(type)\n\n", registertype > rumpsysent 275 printf "struct sysent rump_sysent[] = {\n" > rumpsysent 276 277 # System call names are included by userland (kdump(1)), so 278 # hide the include files from it. 279 printf "#if defined(_KERNEL_OPT)\n" > sysnames 280 281 printf "#endif /* _KERNEL_OPT */\n\n" > sysnamesbottom 282 printf "const char *const %s[] = {\n",namesname > sysnamesbottom 283 284 printf " * created from%s\n */\n\n", $0 > sysnumhdr 285 printf "#ifndef _" constprefix "SYSCALL_H_\n" > sysnumhdr 286 printf "#define _" constprefix "SYSCALL_H_\n\n" > sysnumhdr 287 288 printf " * created from%s\n */\n\n", $0 > sysarghdr 289 printf "#ifndef _" constprefix "SYSCALLARGS_H_\n" > sysarghdr 290 printf "#define _" constprefix "SYSCALLARGS_H_\n\n" > sysarghdr 291 292 printf " * created from%s\n */\n\n", $0 > rumpcallshdr 293 printf "#ifndef _RUMP_RUMP_SYSCALLS_H_\n" > rumpcallshdr 294 printf "#define _RUMP_RUMP_SYSCALLS_H_\n\n" > rumpcallshdr 295 printf "#ifdef _KERNEL\n" > rumpcallshdr 296 printf "#error Interface not supported inside kernel\n" > rumpcallshdr 297 printf "#endif /* _KERNEL */\n\n" > rumpcallshdr 298 printf "#include <rump/rump_syscalls_compat.h>\n\n" > rumpcallshdr 299 300 printf "%s", sysarghdrextra > sysarghdr 301 # Write max number of system call arguments to both headers 302 printf("#define\t%sMAXSYSARGS\t%d\n\n", constprefix, maxsysargs) \ 303 > sysnumhdr 304 printf("#define\t%sMAXSYSARGS\t%d\n\n", constprefix, maxsysargs) \ 305 > sysarghdr 306 printf "#undef\tsyscallarg\n" > sysarghdr 307 printf "#define\tsyscallarg(x)\t\t\t\t\t\t\t\\\n" > sysarghdr 308 printf "\tunion {\t\t\t\t\t\t\t\t\\\n" > sysarghdr 309 printf "\t\t%s pad;\t\t\t\t\t\t\\\n", registertype > sysarghdr 310 printf "\t\tstruct { x datum; } le;\t\t\t\t\t\\\n" > sysarghdr 311 printf "\t\tstruct { /* LINTED zero array dimension */\t\t\\\n" \ 312 > sysarghdr 313 printf "\t\t\tint8_t pad[ /* CONSTCOND */\t\t\t\\\n" > sysarghdr 314 printf "\t\t\t\t(sizeof (%s) < sizeof (x))\t\\\n", \ 315 registertype > sysarghdr 316 printf "\t\t\t\t? 0\t\t\t\t\t\\\n" > sysarghdr 317 printf "\t\t\t\t: sizeof (%s) - sizeof (x)];\t\\\n", \ 318 registertype > sysarghdr 319 printf "\t\t\tx datum;\t\t\t\t\t\\\n" > sysarghdr 320 printf "\t\t} be;\t\t\t\t\t\t\t\\\n" > sysarghdr 321 printf "\t}\n" > sysarghdr 322 printf("\n#undef check_syscall_args\n") >sysarghdr 323 printf("#define check_syscall_args(call) /*LINTED*/ \\\n" \ 324 "\ttypedef char call##_check_args" \ 325 "[sizeof (struct call##_args) \\\n" \ 326 "\t\t<= %sMAXSYSARGS * sizeof (%s) ? 1 : -1];\n", \ 327 constprefix, registertype) >sysarghdr 328 329 # compat types from syscalls.master. this is slightly ugly, 330 # but given that we have so few compats from over 17 years, 331 # a more complicated solution is not currently warranted. 332 uncompattypes["struct timeval50"] = "struct timeval"; 333 uncompattypes["struct timespec50"] = "struct timespec"; 334 uncompattypes["struct stat30"] = "struct stat"; 335 336 next 337} 338NF == 0 || $1 ~ /^;/ { 339 next 340} 341$0 ~ /^%%$/ { 342 intable = 1 343 next 344} 345$1 ~ /^#[ ]*include/ { 346 print > sysdcl 347 print > sysnames 348 next 349} 350$1 ~ /^#/ && !intable { 351 print > sysdcl 352 print > sysnames 353 next 354} 355$1 ~ /^#/ && intable { 356 if ($1 ~ /^#[ ]*if/) { 357 savedepth++ 358 savesyscall[savedepth] = syscall 359 } 360 if ($1 ~ /^#[ ]*else/) { 361 if (savedepth <= 0) { 362 printf("%s: line %d: unbalanced #else\n", \ 363 infile, NR) 364 exit 1 365 } 366 syscall = savesyscall[savedepth] 367 } 368 if ($1 ~ /^#[ ]*endif/) { 369 if (savedepth <= 0) { 370 printf("%s: line %d: unbalanced #endif\n", \ 371 infile, NR) 372 exit 1 373 } 374 savedepth-- 375 } 376 print > sysent 377 print > sysarghdr 378 print > sysnumhdr 379 print > sysprotos 380 print > sysnamesbottom 381 382 # XXX: technically we do not want to have conditionals in rump, 383 # but it is easier to just let the cpp handle them than try to 384 # figure out what we want here in this script 385 print > rumpsysent 386 next 387} 388syscall != $1 { 389 printf "%s: line %d: syscall number out of sync at %d\n", \ 390 infile, NR, syscall 391 printf "line is:\n" 392 print 393 exit 1 394} 395function parserr(was, wanted) { 396 printf "%s: line %d: unexpected %s (expected <%s>)\n", \ 397 infile, NR, was, wanted 398 printf "line is:\n" 399 print 400 exit 1 401} 402function parseline() { 403 f=3 # toss number and type 404 if ($2 == "INDIR") 405 sycall_flags="SYCALL_INDIRECT" 406 else 407 sycall_flags="0" 408 if ($NF != "}") { 409 funcalias=$NF 410 end=NF-1 411 } else { 412 funcalias="" 413 end=NF 414 } 415 if ($f == "INDIR") { # allow for "NOARG INDIR" 416 sycall_flags = "SYCALL_INDIRECT | " sycall_flags 417 f++ 418 } 419 if ($f == "MODULAR") { # registered at runtime 420 modular = 1 421 f++ 422 } else { 423 modular = 0; 424 } 425 if ($f == "RUMP") { 426 rumpable = 1 427 f++ 428 } else { 429 rumpable = 0 430 } 431 if ($f ~ /^[a-z0-9_]*$/) { # allow syscall alias 432 funcalias=$f 433 f++ 434 } 435 if ($f != "{") 436 parserr($f, "{") 437 f++ 438 if ($end != "}") 439 parserr($end, "}") 440 end-- 441 if ($end != ";") 442 parserr($end, ";") 443 end-- 444 if ($end != ")") 445 parserr($end, ")") 446 end-- 447 448 returntype = oldf = ""; 449 do { 450 if (returntype != "" && oldf != "*") 451 returntype = returntype" "; 452 returntype = returntype$f; 453 oldf = $f; 454 f++ 455 } while ($f != "|" && f < (end-1)) 456 if (f == (end - 1)) { 457 parserr($f, "function argument definition (maybe \"|\"?)"); 458 } 459 f++ 460 461 fprefix=$f 462 f++ 463 if ($f != "|") { 464 parserr($f, "function compat delimiter (maybe \"|\"?)"); 465 } 466 f++ 467 468 fcompat="" 469 if ($f != "|") { 470 fcompat=$f 471 f++ 472 } 473 474 if ($f != "|") { 475 parserr($f, "function name delimiter (maybe \"|\"?)"); 476 } 477 f++ 478 fbase=$f 479 480 # pipe is special in how to returns its values. 481 # So just generate it manually if present. 482 if (rumpable == 1 && fbase == "pipe") { 483 rumpable = 0; 484 rumphaspipe = 1; 485 } 486 487 if (fcompat != "") { 488 funcname=fprefix "___" fbase "" fcompat 489 } else { 490 funcname=fprefix "_" fbase 491 } 492 if (returntype == "quad_t" || returntype == "off_t") { 493 if (sycall_flags == "0") 494 sycall_flags = "SYCALL_RET_64"; 495 else 496 sycall_flags = "SYCALL_RET_64 | " sycall_flags; 497 } 498 499 if (funcalias == "") { 500 funcalias=funcname 501 sub(/^([^_]+_)*sys_/, "", funcalias) 502 realname=fbase 503 } else { 504 realname=funcalias 505 } 506 rumpfname=realname "" fcompat 507 f++ 508 509 if ($f != "(") 510 parserr($f, "(") 511 f++ 512 513 argc=0; 514 argalign=0; 515 if (f == end) { 516 if ($f != "void") 517 parserr($f, "argument definition") 518 isvarargs = 0; 519 varargc = 0; 520 argtype[0]="void"; 521 return 522 } 523 524 # some system calls (open() and fcntl()) can accept a variable 525 # number of arguments. If syscalls accept a variable number of 526 # arguments, they must still have arguments specified for 527 # the remaining argument "positions," because of the way the 528 # kernel system call argument handling works. 529 # 530 # Indirect system calls, e.g. syscall(), are exceptions to this 531 # rule, since they are handled entirely by machine-dependent code 532 # and do not need argument structures built. 533 534 isvarargs = 0; 535 args64 = 0; 536 ptr = 0; 537 while (f <= end) { 538 if ($f == "...") { 539 f++; 540 isvarargs = 1; 541 varargc = argc; 542 continue; 543 } 544 argc++ 545 argtype[argc]="" 546 oldf="" 547 while (f < end && $(f+1) != ",") { 548 if (argtype[argc] != "" && oldf != "*") 549 argtype[argc] = argtype[argc]" "; 550 argtype[argc] = argtype[argc]$f; 551 oldf = $f; 552 f++ 553 } 554 if (argtype[argc] == "") 555 parserr($f, "argument definition") 556 if (argtype[argc] == "off_t" \ 557 || argtype[argc] == "dev_t" \ 558 || argtype[argc] == "time_t") { 559 if ((argalign % 2) != 0 && sysalign && 560 funcname != "sys_posix_fadvise") # XXX for now 561 parserr($f, "a padding argument") 562 } else { 563 argalign++; 564 } 565 if (argtype[argc] == "quad_t" || argtype[argc] == "off_t" \ 566 || argtype[argc] == "dev_t" || argtype[argc] == "time_t") { 567 if (sycall_flags == "0") 568 sycall_flags = "SYCALL_ARG"argc-1"_64"; 569 else 570 sycall_flags = "SYCALL_ARG"argc-1"_64 | " sycall_flags; 571 args64++; 572 } 573 if (index(argtype[argc], "*") != 0 && ptr == 0) { 574 if (sycall_flags == "0") 575 sycall_flags = "SYCALL_ARG_PTR"; 576 else 577 sycall_flags = "SYCALL_ARG_PTR | " sycall_flags; 578 ptr = 1; 579 } 580 argname[argc]=$f; 581 f += 2; # skip name, and any comma 582 } 583 if (args64 > 0) 584 sycall_flags = "SYCALL_NARGS64_VAL("args64") | " sycall_flags; 585 # must see another argument after varargs notice. 586 if (isvarargs) { 587 if (argc == varargc) 588 parserr($f, "argument definition") 589 } else 590 varargc = argc; 591} 592 593function printproto(wrap) { 594 printf("/* syscall: \"%s%s\" ret: \"%s\" args:", wrap, funcalias, 595 returntype) > sysnumhdr 596 for (i = 1; i <= varargc; i++) 597 printf(" \"%s\"", argtype[i]) > sysnumhdr 598 if (isvarargs) 599 printf(" \"...\"") > sysnumhdr 600 printf(" */\n") > sysnumhdr 601 printf("#define\t%s%s%s\t%d\n\n", constprefix, wrap, funcalias, 602 syscall) > sysnumhdr 603 604 # rumpalooza 605 if (!rumpable) 606 return 607 608 # accumulate fbases we have seen. we want the last 609 # occurence for the default __RENAME() 610 seen = funcseen[fbase] 611 funcseen[fbase] = rumpfname 612 # special case for mknod as type of last argument changed from 613 # uint32_t to dev_t 614 if ((seen && fbase != "mknod") || (!seen && fbase == "mknod")) 615 return 616 617 printf("%s rump_sys_%s(", returntype, realname) > rumpprotos 618 619 for (i = 1; i < varargc; i++) 620 if (argname[i] != "PAD") 621 printf("%s, ", uncompattype(argtype[i])) > rumpprotos 622 623 if (isvarargs) 624 printf("%s, ...)", uncompattype(argtype[varargc]))>rumpprotos 625 else 626 printf("%s)", uncompattype(argtype[argc])) > rumpprotos 627 628 printf(" __RENAME(RUMP_SYS_RENAME_%s)", toupper(fbase))> rumpprotos 629 printf(";\n") > rumpprotos 630 631 # generate forward-declares for types, apart from the 632 # braindead typedef jungle we cannot easily handle here 633 for (i = 1; i <= varargc; i++) { 634 type=uncompattype(argtype[i]) 635 sub("const ", "", type) 636 ntype=type 637 sub(" *\\*.*", "", ntype); 638 if (!typeseen[ntype] && \ 639 match(type, "struct") && match(type, "\\*")) { 640 typeseen[ntype] = 1 641 printf("%s;\n", ntype) > rumptypes 642 } 643 } 644} 645 646function printrumpsysent(insysent, compatwrap) { 647 if (!insysent) { 648 eno[0] = "rumpns_enosys" 649 eno[1] = "rumpns_sys_nomodule" 650 flags[0] = "SYCALL_NOSYS" 651 flags[1] = "0" 652 printf("\t{ 0, 0, %s,\n\t (sy_call_t *)%s }, \t" \ 653 "/* %d = %s */\n", \ 654 flags[modular], eno[modular], syscall, funcalias) \ 655 > rumpsysent 656 return 657 } 658 659 printf("\t{ ") > rumpsysent 660 if (argc == 0) { 661 printf("0, 0, ") > rumpsysent 662 } else { 663 printf("ns(struct %ssys_%s_args), ", compatwrap_, funcalias) > rumpsysent 664 } 665 666 if (modular) 667 fn="(sy_call_t *)rumpns_sys_nomodule" 668 else 669 fn="(sy_call_t *)rumpns_enosys" 670 printf("0,\n\t %s },", fn) > rumpsysent 671 for (i = 0; i < (33 - length(fn)) / 8; i++) 672 printf("\t") > rumpsysent 673 printf("/* %d = %s%s */\n", syscall, compatwrap_, funcalias) > rumpsysent 674} 675 676function iscompattype(type) { 677 for (var in uncompattypes) { 678 if (match(type, var)) { 679 return 1 680 } 681 } 682 683 return 0 684} 685 686function uncompattype(type) { 687 for (var in uncompattypes) { 688 if (match(type, var)) { 689 sub(var, uncompattypes[var], type) 690 return type 691 } 692 } 693 694 return type 695} 696 697function printrumpsysmap(syscall, wfn, funcalias, rumpentry) { 698 printf("%-4d %-22s %-18s %s\n", 699 syscall, wfn, funcalias, rumpentry) > rumpsysmap 700} 701 702function putent(type, compatwrap) { 703 # output syscall declaration for switch table. 704 if (compatwrap == "") 705 compatwrap_ = "" 706 else 707 compatwrap_ = compatwrap "_" 708 if (argc == 0) 709 arg_type = "void"; 710 else { 711 arg_type = "struct " compatwrap_ funcname "_args"; 712 } 713 proto = "int\t" compatwrap_ funcname "(struct lwp *, const " \ 714 arg_type " *, register_t *);\n" 715 if (sysmap[proto] != 1) { 716 sysmap[proto] = 1; 717 print proto > sysprotos; 718 } 719 720 # output syscall switch entry 721 printf("\t{ ") > sysent 722 if (argc == 0) { 723 printf("0, 0, ") > sysent 724 } else { 725 printf("ns(struct %s%s_args), ", compatwrap_, funcname) > sysent 726 } 727 if (modular) 728 wfn = "sys_nomodule"; 729 else if (compatwrap == "") 730 wfn = funcname; 731 else 732 wfn = compatwrap "(" funcname ")"; 733 wfn_cast="(sy_call_t *)" wfn 734 printf("%s,\n\t %s },", sycall_flags, wfn_cast) > sysent 735 for (i = 0; i < (33 - length(wfn_cast)) / 8; i++) 736 printf("\t") > sysent 737 printf("/* %d = %s%s */\n", syscall, compatwrap_, funcalias) > sysent 738 739 # output syscall name for names table 740 printf("\t/* %3d */\t\"%s%s\",\n", syscall, compatwrap_, funcalias) \ 741 > sysnamesbottom 742 743 # output syscall number of header, if appropriate 744 if (type == "STD" || type == "NOARGS" || type == "INDIR" || \ 745 type == "NOERR") { 746 # output a prototype, to be used to generate lint stubs in 747 # libc. 748 printproto("") 749 } else if (type == "COMPAT" || type == "EXTERN") { 750 # Just define the syscall number with a comment. These 751 # may be used by compatibility stubs in libc. 752 printproto(compatwrap_) 753 } 754 755 # output syscall argument structure, if it has arguments 756 if (argc != 0) { 757 printf("\n") > sysarghdr 758 if (haverumpcalls && !rumpable) 759 printf("#ifndef RUMP_CLIENT\n") > sysarghdr 760 printf("struct %s%s_args", compatwrap_, funcname) > sysarghdr 761 if (type != "NOARGS") { 762 print " {" >sysarghdr; 763 for (i = 1; i <= argc; i++) 764 printf("\tsyscallarg(%s) %s;\n", argtype[i], 765 argname[i]) > sysarghdr 766 printf "}" >sysarghdr; 767 } 768 printf(";\n") > sysarghdr 769 if (type != "NOARGS" && type != "INDIR") { 770 printf("check_syscall_args(%s%s)\n", compatwrap_, 771 funcname) >sysarghdr 772 } 773 if (haverumpcalls && !rumpable) 774 printf("#endif /* !RUMP_CLIENT */\n") > sysarghdr 775 } 776 777 if (!rumpable) { 778 if (funcname == "sys_pipe" && rumphaspipe == 1) { 779 insysent = 1 780 printrumpsysmap(syscall, 781 funcname, funcalias, "rump_sys_pipe") 782 } else { 783 insysent = 0 784 } 785 } else { 786 insysent = 1 787 } 788 printrumpsysent(insysent, compatwrap) 789 790 # output rump marshalling code if necessary 791 if (!rumpable) { 792 return 793 } 794 795 printrumpsysmap(syscall, wfn, funcalias, "rump___sysimpl_" rumpfname) 796 797 # need a local prototype, we export the re-re-named one in .h 798 printf("\n%s rump___sysimpl_%s(", returntype, rumpfname) \ 799 > rumpcalls 800 for (i = 1; i < argc; i++) { 801 if (argname[i] != "PAD") 802 printf("%s, ", uncompattype(argtype[i])) > rumpcalls 803 } 804 printf("%s);", uncompattype(argtype[argc])) > rumpcalls 805 806 printf("\n%s\nrump___sysimpl_%s(", returntype, rumpfname) > rumpcalls 807 for (i = 1; i < argc; i++) { 808 if (argname[i] != "PAD") 809 printf("%s %s, ", uncompattype(argtype[i]), \ 810 argname[i]) > rumpcalls 811 } 812 printf("%s %s)\n", uncompattype(argtype[argc]), argname[argc]) \ 813 > rumpcalls 814 printf("{\n\tregister_t retval[2];\n") > rumpcalls 815 if (returntype != "void") { 816 if (type != "NOERR") { 817 printf("\tint error = 0;\n") > rumpcalls 818 } 819 # assume rumpcalls return only integral types 820 printf("\t%s rv = -1;\n", returntype) > rumpcalls 821 } 822 823 argarg = "NULL" 824 argsize = 0; 825 if (argc) { 826 argarg = "&callarg" 827 argsize = "sizeof(callarg)" 828 printf("\tstruct %s%s_args callarg;\n\n",compatwrap_,funcname) \ 829 > rumpcalls 830 printf "\tmemset(&callarg, 0, sizeof(callarg));\n" > rumpcalls 831 for (i = 1; i <= argc; i++) { 832 if (argname[i] == "PAD") { 833 printf("\tSPARG(&callarg, %s) = 0;\n", \ 834 argname[i]) > rumpcalls 835 } else { 836 if (iscompattype(argtype[i])) { 837 printf("\tSPARG(&callarg, %s) = " \ 838 "(%s)%s;\n", argname[i], argtype[i], \ 839 argname[i]) > rumpcalls 840 } else { 841 printf("\tSPARG(&callarg, %s) = %s;\n",\ 842 argname[i], argname[i]) > rumpcalls 843 } 844 } 845 } 846 printf("\n") > rumpcalls 847 } else { 848 printf("\n") > rumpcalls 849 } 850 printf("\t") > rumpcalls 851 if (returntype != "void" && type != "NOERR") 852 printf("error = ") > rumpcalls 853 printf("rsys_syscall(%s%s%s, " \ 854 "%s, %s, retval);\n", constprefix, compatwrap_, funcalias, \ 855 argarg, argsize) > rumpcalls 856 if (type != "NOERR") { 857 printf("\trsys_seterrno(error);\n") > rumpcalls 858 printf("\tif (error == 0) {\n") > rumpcalls 859 indent="\t\t" 860 ending="\t}\n" 861 } else { 862 indent="\t" 863 ending="" 864 } 865 if (returntype != "void") { 866 printf("%sif (sizeof(%s) > sizeof(register_t))\n", \ 867 indent, returntype) > rumpcalls 868 printf("%s\trv = *(%s *)retval;\n", \ 869 indent, returntype) > rumpcalls 870 printf("%selse\n", indent, indent) > rumpcalls 871 printf("%s\trv = *retval;\n", indent, returntype) > rumpcalls 872 printf("%s", ending) > rumpcalls 873 printf("\treturn rv;\n") > rumpcalls 874 } 875 printf("}\n") > rumpcalls 876 printf("rsys_aliases(%s%s,rump___sysimpl_%s);\n", \ 877 compatwrap_, funcalias, rumpfname) > rumpcalls 878 879} 880$2 == "STD" || $2 == "NODEF" || $2 == "NOARGS" || $2 == "INDIR" \ 881 || $2 == "NOERR" { 882 parseline() 883 putent($2, "") 884 syscall++ 885 next 886} 887$2 == "OBSOL" || $2 == "UNIMPL" || $2 == "EXCL" || $2 == "IGNORED" { 888 if ($2 == "OBSOL") 889 comment="obsolete" 890 else if ($2 == "EXCL") 891 comment="excluded" 892 else if ($2 == "IGNORED") 893 comment="ignored" 894 else 895 comment="unimplemented" 896 for (i = 3; i <= NF; i++) 897 comment=comment " " $i 898 899 if ($2 == "IGNORED") 900 sys_stub = "(sy_call_t *)nullop"; 901 else 902 sys_stub = sys_nosys; 903 904 printf("\t{ 0, 0, 0,\n\t %s },\t\t\t/* %d = %s */\n", \ 905 sys_stub, syscall, comment) > sysent 906 printf("\t{ 0, 0, SYCALL_NOSYS,\n\t %s },\t\t/* %d = %s */\n", \ 907 "(sy_call_t *)rumpns_enosys", syscall, comment) > rumpsysent 908 printf("\t/* %3d */\t\"#%d (%s)\",\n", syscall, syscall, comment) \ 909 > sysnamesbottom 910 if ($2 != "UNIMPL") 911 printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr 912 syscall++ 913 next 914} 915$2 == "EXTERN" { 916 parseline() 917 putent("EXTERN", "") 918 syscall++ 919 next 920} 921{ 922 for (i = 1; i <= ncompat; i++) { 923 if ($2 == compat_upper[i]) { 924 parseline(); 925 putent("COMPAT", compat[i]) 926 syscall++ 927 next 928 } 929 } 930 printf("%s: line %d: unrecognized keyword %s\n", infile, NR, $2) 931 exit 1 932} 933END { 934 # output pipe() syscall with its special retval[2] handling 935 if (rumphaspipe) { 936 printf("int rump_sys_pipe(int *);\n") > rumpprotos 937 printf("\nint rump_sys_pipe(int *);\n") > rumpcalls 938 printf("int\nrump_sys_pipe(int *fd)\n{\n") > rumpcalls 939 printf("\tregister_t retval[2];\n") > rumpcalls 940 printf("\tint error = 0;\n") > rumpcalls 941 printf("\n\terror = rsys_syscall(SYS_pipe, ") > rumpcalls 942 printf("NULL, 0, retval);\n") > rumpcalls 943 printf("\tif (error) {\n") > rumpcalls 944 printf("\t\trsys_seterrno(error);\n") > rumpcalls 945 printf("\t} else {\n\t\tfd[0] = retval[0];\n") > rumpcalls 946 printf("\t\tfd[1] = retval[1];\n\t}\n") > rumpcalls 947 printf("\treturn error ? -1 : 0;\n}\n") > rumpcalls 948 printf "rsys_aliases(pipe,rump_sys_pipe);\n" > rumpcalls 949 } 950 951 # print default rump syscall interfaces 952 for (var in funcseen) { 953 printf("#ifndef RUMP_SYS_RENAME_%s\n", \ 954 toupper(var)) > rumpcallshdr 955 printf("#define RUMP_SYS_RENAME_%s rump___sysimpl_%s\n", \ 956 toupper(var), funcseen[var]) > rumpcallshdr 957 printf("#endif\n\n") > rumpcallshdr 958 } 959 960 maxsyscall = syscall 961 if (nsysent) { 962 if (syscall > nsysent) { 963 printf("%s: line %d: too many syscalls [%d > %d]\n", infile, NR, syscall, nsysent) 964 exit 1 965 } 966 while (syscall < nsysent) { 967 printf("\t{ 0, 0, 0,\n\t %s },\t\t\t/* %d = filler */\n", \ 968 sys_nosys, syscall) > sysent 969 printf("\t{ 0, 0, SYCALL_NOSYS,\n\t %s },\t\t/* %d = filler */\n", \ 970 "(sy_call_t *)rumpns_enosys", syscall) > rumpsysent 971 printf("\t/* %3d */\t\"# filler\",\n", syscall) \ 972 > sysnamesbottom 973 syscall++ 974 } 975 } 976 printf("};\n") > sysent 977 printf("};\n") > rumpsysent 978 printf("CTASSERT(__arraycount(rump_sysent) == SYS_NSYSENT);\n") > rumpsysent 979 printf("__strong_alias(rumpns_sysent,rump_sysent);\n") > rumpsysent 980 printf("#endif /* RUMP_CLIENT */\n") > rumpsysent 981 if (haverumpcalls) 982 printf("#endif /* !RUMP_CLIENT */\n") > sysprotos 983 printf("};\n") > sysnamesbottom 984 printf("#define\t%sMAXSYSCALL\t%d\n", constprefix, maxsyscall) > sysnumhdr 985 if (nsysent) 986 printf("#define\t%sNSYSENT\t%d\n", constprefix, nsysent) > sysnumhdr 987} ' 988 989cat $sysprotos >> $sysarghdr 990echo "#endif /* _${constprefix}SYSCALL_H_ */" >> $sysnumhdr 991echo "#endif /* _${constprefix}SYSCALLARGS_H_ */" >> $sysarghdr 992printf "\n#endif /* _RUMP_RUMP_SYSCALLS_H_ */\n" >> $rumpprotos 993cat $sysdcl $sysent > $syssw 994cat $sysnamesbottom >> $sysnames 995cat $rumpsysent >> $rumpcalls 996 997touch $rumptypes 998cat $rumptypes >> $rumpcallshdr 999echo >> $rumpcallshdr 1000cat $rumpprotos >> $rumpcallshdr 1001 1002#chmod 444 $sysnames $sysnumhdr $syssw 1003 1004echo Generated following files: 1005echo $sysarghdr $sysnumhdr $syssw $sysnames $rumpcalls $rumpcallshdr $rumpsysmap 1006