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