The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/makesyscalls.sh

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #! /bin/sh -
    2 #       $NetBSD: makesyscalls.sh,v 1.55 2003/09/30 20:34:28 christos 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 
   35 set -e
   36 
   37 case $# in
   38     2)  ;;
   39     *)  echo "Usage: $0 config-file input-file" 1>&2
   40         exit 1
   41         ;;
   42 esac
   43 
   44 # the config file sets the following variables:
   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 #
   58 # NOTE THAT THIS makesyscalls.sh DOES NOT SUPPORT 'LIBCOMPAT'.
   59 
   60 # source the config file.
   61 sys_nosys="sys_nosys"   # default is sys_nosys(), if not specified otherwise
   62 . ./$1
   63 
   64 # tmp files:
   65 sysdcl="sysent.dcl"
   66 sysprotos="sys.protos"
   67 syscompat_pref="sysent."
   68 sysent="sysent.switch"
   69 sysnamesbottom="sysnames.bottom"
   70 
   71 trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom" 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         # to track already processed syscalls
  120 
  121         sysnames = \"$sysnames\"
  122         sysprotos = \"$sysprotos\"
  123         sysnumhdr = \"$sysnumhdr\"
  124         sysarghdr = \"$sysarghdr\"
  125         switchname = \"$switchname\"
  126         namesname = \"$namesname\"
  127         constprefix = \"$constprefix\"
  128         registertype = \"$registertype\"
  129         if (!registertype) {
  130             registertype = \"register_t\"
  131         }
  132         nsysent = \"$nsysent\"
  133 
  134         sysdcl = \"$sysdcl\"
  135         syscompat_pref = \"$syscompat_pref\"
  136         sysent = \"$sysent\"
  137         sysnamesbottom = \"$sysnamesbottom\"
  138         sys_nosys = \"$sys_nosys\"
  139         infile = \"$2\"
  140 
  141         compatopts = \"$compatopts\"
  142         "'
  143 
  144         printf "/* \$NetBSD\$ */\n\n" > sysdcl
  145         printf "/*\n * System call switch table.\n *\n" > sysdcl
  146         printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysdcl
  147 
  148         ncompat = split(compatopts,compat)
  149         for (i = 1; i <= ncompat; i++) {
  150                 compat_upper[i] = toupper(compat[i])
  151 
  152                 printf "\n#ifdef %s\n", compat_upper[i] > sysent
  153                 printf "#define %s(func) __CONCAT(%s_,func)\n", compat[i], \
  154                     compat[i] > sysent
  155                 printf "#else\n" > sysent
  156                 printf "#define %s(func) %s\n", compat[i], sys_nosys > sysent
  157                 printf "#endif\n" > sysent
  158         }
  159 
  160         printf "\n#define\ts(type)\tsizeof(type)\n\n" > sysent
  161         printf "struct sysent %s[] = {\n",switchname > sysent
  162 
  163         printf "/* \$NetBSD\$ */\n\n" > sysnames
  164         printf "/*\n * System call names.\n *\n" > sysnames
  165         printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
  166 
  167         printf "\n/*\n * System call prototypes.\n */\n\n" > sysprotos
  168 
  169         printf "/* \$NetBSD\$ */\n\n" > sysnumhdr
  170         printf "/*\n * System call numbers.\n *\n" > sysnumhdr
  171         printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnumhdr
  172 
  173         printf "/* \$NetBSD\$ */\n\n" > sysarghdr
  174         printf "/*\n * System call argument lists.\n *\n" > sysarghdr
  175         printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysarghdr
  176 }
  177 NR == 1 {
  178         printf " * created from%s\n */\n\n", $0 > sysdcl
  179         printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"\$NetBSD\$\");\n\n" > sysdcl
  180 
  181         printf " * created from%s\n */\n\n", $0 > sysnames
  182         printf "#include <sys/cdefs.h>\n__KERNEL_RCSID(0, \"\$NetBSD\$\");\n\n" > sysnames
  183 
  184         # System call names are included by userland (kdump(1)), so
  185         # hide the include files from it.
  186         printf "#if defined(_KERNEL_OPT)\n" > sysnames
  187 
  188         printf "#endif /* _KERNEL_OPT */\n\n" > sysnamesbottom
  189         printf "const char *const %s[] = {\n",namesname > sysnamesbottom
  190 
  191         printf " * created from%s\n */\n\n", $0 > sysnumhdr
  192 
  193         printf " * created from%s\n */\n\n", $0 > sysarghdr
  194         printf "#ifndef _" constprefix "_SYSCALLARGS_H_\n" > sysarghdr
  195         printf "#define _" constprefix "_SYSCALLARGS_H_\n\n" > sysarghdr
  196         printf "#ifdef\tsyscallarg\n" > sysarghdr
  197         printf "#undef\tsyscallarg\n" > sysarghdr
  198         printf "#endif\n\n" > sysarghdr
  199         printf "#define\tsyscallarg(x)\t\t\t\t\t\t\t\\\n" > sysarghdr
  200         printf "\tunion {\t\t\t\t\t\t\t\t\\\n" > sysarghdr
  201         printf "\t\t%s pad;\t\t\t\t\t\t\\\n", registertype > sysarghdr
  202         printf "\t\tstruct { x datum; } le;\t\t\t\t\t\\\n" > sysarghdr
  203         printf "\t\tstruct { /* LINTED zero array dimension */\t\t\\\n" \
  204                 > sysarghdr
  205         printf "\t\t\tint8_t pad[  /* CONSTCOND */\t\t\t\\\n" > sysarghdr
  206         printf "\t\t\t\t(sizeof (%s) < sizeof (x))\t\\\n", \
  207                 registertype > sysarghdr
  208         printf "\t\t\t\t? 0\t\t\t\t\t\\\n" > sysarghdr
  209         printf "\t\t\t\t: sizeof (%s) - sizeof (x)];\t\\\n", \
  210                 registertype > sysarghdr
  211         printf "\t\t\tx datum;\t\t\t\t\t\\\n" > sysarghdr
  212         printf "\t\t} be;\t\t\t\t\t\t\t\\\n" > sysarghdr
  213         printf "\t}\n" > sysarghdr
  214         next
  215 }
  216 NF == 0 || $1 ~ /^;/ {
  217         next
  218 }
  219 $0 ~ /^%%$/ {
  220         intable = 1
  221         next
  222 }
  223 $1 ~ /^#[       ]*include/ {
  224         print > sysdcl
  225         print > sysnames
  226         next
  227 }
  228 $1 ~ /^#/ && !intable {
  229         print > sysdcl
  230         print > sysnames
  231         next
  232 }
  233 $1 ~ /^#/ && intable {
  234         if ($1 ~ /^#[   ]*if/) {
  235                 savedepth++
  236                 savesyscall[savedepth] = syscall
  237         }
  238         if ($1 ~ /^#[   ]*else/) {
  239                 if (savedepth <= 0) {
  240                         printf("%s: line %d: unbalanced #else\n", \
  241                             infile, NR)
  242                         exit 1
  243                 }
  244                 syscall = savesyscall[savedepth]
  245         }
  246         if ($1 ~ /^#[       ]*endif/) {
  247                 if (savedepth <= 0) {
  248                         printf("%s: line %d: unbalanced #endif\n", \
  249                             infile, NR)
  250                         exit 1
  251                 }
  252                 savedepth--
  253         }
  254         print > sysent
  255         print > sysarghdr
  256         print > sysnumhdr
  257         print > sysprotos
  258         print > sysnamesbottom
  259         next
  260 }
  261 syscall != $1 {
  262         printf "%s: line %d: syscall number out of sync at %d\n", \
  263            infile, NR, syscall
  264         printf "line is:\n"
  265         print
  266         exit 1
  267 }
  268 function parserr(was, wanted) {
  269         printf "%s: line %d: unexpected %s (expected %s)\n", \
  270             infile, NR, was, wanted
  271         printf "line is:\n"
  272         print
  273         exit 1
  274 }
  275 function parseline() {
  276         f=3                     # toss number and type
  277         sycall_flags="0"
  278         if ($NF != "}") {
  279                 funcalias=$NF
  280                 end=NF-1
  281         } else {
  282                 funcalias=""
  283                 end=NF
  284         }
  285         if ($f == "MPSAFE") {           # allow for MP-safe syscalls
  286                 sycall_flags = sprintf("SYCALL_MPSAFE | %s", sycall_flags)
  287                 f++
  288         }
  289         if ($f ~ /^[a-z0-9_]*$/) {      # allow syscall alias
  290                 funcalias=$f
  291                 f++
  292         }
  293         if ($f != "{")
  294                 parserr($f, "{")
  295         f++
  296         if ($end != "}")
  297                 parserr($end, "}")
  298         end--
  299         if ($end != ";")
  300                 parserr($end, ";")
  301         end--
  302         if ($end != ")")
  303                 parserr($end, ")")
  304         end--
  305 
  306         returntype = oldf = "";
  307         do {
  308                 if (returntype != "" && oldf != "*")
  309                         returntype = returntype" ";
  310                 returntype = returntype$f;
  311                 oldf = $f;
  312                 f++
  313         } while (f < (end - 1) && $(f+1) != "(");
  314         if (f == (end - 1)) {
  315                 parserr($f, "function argument definition (maybe \"(\"?)");
  316         }
  317 
  318         funcname=$f
  319         if (funcalias == "") {
  320                 funcalias=funcname
  321                 sub(/^([^_]+_)*sys_/, "", funcalias)
  322         }
  323         f++
  324 
  325         if ($f != "(")
  326                 parserr($f, ")")
  327         f++
  328 
  329         argc=0;
  330         if (f == end) {
  331                 if ($f != "void")
  332                         parserr($f, "argument definition")
  333                 isvarargs = 0;
  334                 varargc = 0;
  335                 return
  336         }
  337 
  338         # some system calls (open() and fcntl()) can accept a variable
  339         # number of arguments.  If syscalls accept a variable number of
  340         # arguments, they must still have arguments specified for
  341         # the remaining argument "positions," because of the way the
  342         # kernel system call argument handling works.
  343         #
  344         # Indirect system calls, e.g. syscall(), are exceptions to this
  345         # rule, since they are handled entirely by machine-dependent code
  346         # and do not need argument structures built.
  347 
  348         isvarargs = 0;
  349         while (f <= end) {
  350                 if ($f == "...") {
  351                         f++;
  352                         isvarargs = 1;
  353                         varargc = argc;
  354                         continue;
  355                 }
  356                 argc++
  357                 argtype[argc]=""
  358                 oldf=""
  359                 while (f < end && $(f+1) != ",") {
  360                         if (argtype[argc] != "" && oldf != "*")
  361                                 argtype[argc] = argtype[argc]" ";
  362                         argtype[argc] = argtype[argc]$f;
  363                         oldf = $f;
  364                         f++
  365                 }
  366                 if (argtype[argc] == "")
  367                         parserr($f, "argument definition")
  368                 argname[argc]=$f;
  369                 f += 2;                 # skip name, and any comma
  370         }
  371         # must see another argument after varargs notice.
  372         if (isvarargs) {
  373                 if (argc == varargc && $2 != "INDIR")
  374                         parserr($f, "argument definition")
  375         } else
  376                 varargc = argc;
  377 }
  378 
  379 function printproto(wrap) {
  380         printf("/* syscall: \"%s%s\" ret: \"%s\" args:", wrap, funcalias,
  381             returntype) > sysnumhdr
  382         for (i = 1; i <= varargc; i++)
  383                 printf(" \"%s\"", argtype[i]) > sysnumhdr
  384         if (isvarargs)
  385                 printf(" \"...\"") > sysnumhdr
  386         printf(" */\n") > sysnumhdr
  387         printf("#define\t%s%s%s\t%d\n\n", constprefix, wrap, funcalias,
  388             syscall) > sysnumhdr
  389 }
  390 
  391 function putent(nodefs, compatwrap) {
  392         # output syscall declaration for switch table.  INDIR functions
  393         # get none, since they always have sys_nosys() for their table
  394         # entries.
  395         if (nodefs != "INDIR") {
  396                 prototype = "(struct lwp *, void *, register_t *)"
  397                 if (compatwrap == "")
  398                         proto = sprintf("int\t%s%s;\n", funcname, prototype);
  399                 else
  400                         proto = sprintf("int\t%s_%s%s;\n", compatwrap,
  401                             funcname, prototype);
  402                 if (sysmap[proto] != 1) {
  403                         sysmap[proto] = 1;
  404                         print proto > sysprotos;
  405                 }
  406         }
  407 
  408         # output syscall switch entry
  409         if (nodefs == "INDIR") {
  410                 printf("\t{ 0, 0, %s,\n\t    %s },\t\t\t/* %d = %s (indir) */\n", \
  411                     sycall_flags, sys_nosys, syscall, funcalias) > sysent
  412         } else {
  413 #               printf("\t{ { %d", argc) > sysent
  414 #               for (i = 1; i <= argc; i++) {
  415 #                       if (i == 5)             # wrap the line
  416 #                               printf(",\n\t    ") > sysent
  417 #                       else
  418 #                               printf(", ") > sysent
  419 #                       printf("s(%s)", argtypenospc[i]) > sysent
  420 #               }
  421                 printf("\t{ %d, ", argc) > sysent
  422                 if (argc == 0)
  423                         printf("0") > sysent
  424                 else if (compatwrap == "")
  425                         printf("s(struct %s_args)", funcname) > sysent
  426                 else
  427                         printf("s(struct %s_%s_args)", compatwrap,
  428                             funcname) > sysent
  429                 if (compatwrap == "")
  430                         wfn = sprintf("%s", funcname);
  431                 else
  432                         wfn = sprintf("%s(%s)", compatwrap, funcname);
  433                 printf(", %s,\n\t    %s },", sycall_flags, wfn) > sysent
  434                 for (i = 0; i < (33 - length(wfn)) / 8; i++)
  435                         printf("\t") > sysent
  436                 if (compatwrap == "")
  437                         printf("/* %d = %s */\n", syscall, funcalias) > sysent
  438                 else
  439                         printf("/* %d = %s %s */\n", syscall, compatwrap,
  440                             funcalias) > sysent
  441         }
  442 
  443         # output syscall name for names table
  444         if (compatwrap == "")
  445                 printf("\t\"%s\",\t\t\t/* %d = %s */\n", funcalias, syscall,
  446                     funcalias) > sysnamesbottom
  447         else
  448                 printf("\t\"%s_%s\",\t/* %d = %s %s */\n", compatwrap,
  449                     funcalias, syscall, compatwrap, funcalias) > sysnamesbottom
  450 
  451         # output syscall number of header, if appropriate
  452         if (nodefs == "" || nodefs == "NOARGS" || nodefs == "INDIR") {
  453                 # output a prototype, to be used to generate lint stubs in
  454                 # libc.
  455                 printproto("")
  456 
  457         } else if (nodefs == "COMPAT") {
  458                 # Just define the syscall number with a comment.  These
  459                 # may be used by compatibility stubs in libc.
  460                 printproto(compatwrap "_")
  461         } else if (nodefs != "NODEF")
  462                 printf("\t\t\t\t/* %d is %s %s */\n\n", syscall,
  463                     compatwrap, funcalias) > sysnumhdr
  464 
  465         # output syscall argument structure, if it has arguments
  466         if (argc != 0 && nodefs != "NOARGS" && nodefs != "INDIR") {
  467                 if (compatwrap == "")
  468                         printf("\nstruct %s_args {\n", funcname) > sysarghdr
  469                 else
  470                         printf("\nstruct %s_%s_args {\n", compatwrap,
  471                             funcname) > sysarghdr
  472                 for (i = 1; i <= argc; i++)
  473                         printf("\tsyscallarg(%s) %s;\n", argtype[i],
  474                             argname[i]) > sysarghdr
  475                 printf("};\n") > sysarghdr
  476         }
  477 }
  478 $2 == "STD" {
  479         parseline()
  480         putent("", "");
  481         syscall++
  482         next
  483 }
  484 $2 == "NODEF" || $2 == "NOARGS" || $2 == "INDIR" {
  485         parseline()
  486         putent($2, "")
  487         syscall++
  488         next
  489 }
  490 $2 == "OBSOL" || $2 == "UNIMPL" || $2 == "EXCL" {
  491         if ($2 == "OBSOL")
  492                 comment="obsolete"
  493         else if ($2 == "EXCL")
  494                 comment="excluded"
  495         else
  496                 comment="unimplemented"
  497         for (i = 3; i <= NF; i++)
  498                 comment=comment " " $i
  499 
  500         printf("\t{ 0, 0, 0,\n\t    %s },\t\t\t/* %d = %s */\n", \
  501             sys_nosys, syscall, comment) > sysent
  502         printf("\t\"#%d (%s)\",\t\t/* %d = %s */\n", \
  503             syscall, comment, syscall, comment) > sysnamesbottom
  504         if ($2 != "UNIMPL")
  505                 printf("\t\t\t\t/* %d is %s */\n", syscall, comment) > sysnumhdr
  506         syscall++
  507         next
  508 }
  509 {
  510         for (i = 1; i <= ncompat; i++) {
  511                 if ($2 == compat_upper[i]) {
  512                         parseline();
  513                         putent("COMPAT", compat[i])
  514                         syscall++
  515                         next
  516                 }
  517         }
  518         printf("%s: line %d: unrecognized keyword %s\n", infile, NR, $2)
  519         exit 1
  520 }
  521 END {
  522         maxsyscall = syscall
  523         if (nsysent) {
  524                 if (syscall > nsysent) {
  525                         printf("%s: line %d: too many syscalls [%d > %d]\n", infile, NR, syscall, nsysent)
  526                         exit 1
  527                 }
  528                 while (syscall < nsysent) {
  529                         printf("\t{ 0, 0, 0,\n\t    %s },\t\t\t/* %d = filler */\n", \
  530                             sys_nosys, syscall) > sysent
  531                         syscall++
  532                 }
  533         }
  534         printf("};\n\n") > sysent
  535         printf("};\n") > sysnamesbottom
  536         printf("#define\t%sMAXSYSCALL\t%d\n", constprefix, maxsyscall) > sysnumhdr
  537         if (nsysent)
  538                 printf("#define\t%sNSYSENT\t%d\n", constprefix, nsysent) > sysnumhdr
  539 } '
  540 
  541 cat $sysprotos >> $sysarghdr
  542 echo "#endif /* _${constprefix}_SYSCALLARGS_H_ */" >> $sysarghdr
  543 cat $sysdcl $sysent > $syssw
  544 cat $sysnamesbottom >> $sysnames
  545 
  546 #chmod 444 $sysnames $sysnumhdr $syssw

Cache object: 5125f43977fac9cde5937cbd2a19b2ce


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.