/ duct-tape / xnu / bsd / kern / makesyscalls.sh
makesyscalls.sh
  1  #! /bin/sh -
  2  #	@(#)makesyscalls.sh	8.1 (Berkeley) 6/10/93
  3  # $FreeBSD: src/sys/kern/makesyscalls.sh,v 1.60 2003/04/01 01:12:24 jeff Exp $
  4  #
  5  # Copyright (c) 2004-2008 Apple Inc. All rights reserved.
  6  #
  7  # @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  8  # 
  9  # This file contains Original Code and/or Modifications of Original Code
 10  # as defined in and that are subject to the Apple Public Source License
 11  # Version 2.0 (the 'License'). You may not use this file except in
 12  # compliance with the License. Please obtain a copy of the License at
 13  # http://www.opensource.apple.com/apsl/ and read it before using this
 14  # file.
 15  # 
 16  # The Original Code and all software distributed under the License are
 17  # distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 18  # EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 19  # INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 20  # FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 21  # Please see the License for the specific language governing rights and
 22  # limitations under the License.
 23  # 
 24  # @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 25  #
 26  
 27  set -e
 28  
 29  input_file="" # first argument
 30  
 31  # output type:
 32  output_syscallnamesfile=0
 33  output_sysprotofile=0
 34  output_syshdrfile=0
 35  output_syscalltablefile=0
 36  output_auditevfile=0
 37  output_tracecodes=0
 38  output_systrace=0
 39  
 40  use_stdout=0
 41  
 42  # output files:
 43  syscallnamesfile="syscalls.c"
 44  sysprotofile="sysproto.h"
 45  sysproto_h=_SYS_SYSPROTO_H_
 46  syshdrfile="syscall.h"
 47  syscall_h=_SYS_SYSCALL_H_
 48  syscalltablefile="init_sysent.c"
 49  auditevfile="audit_kevents.c"
 50  syscallprefix="SYS_"
 51  switchname="sysent"
 52  namesname="syscallnames"
 53  tracecodename="syscall.codes"
 54  systraceargsfile="systrace_args.c"
 55  # tmp files:
 56  syslegal="sysent.syslegal.$$"
 57  sysent="sysent.switch.$$"
 58  sysinc="sysinc.switch.$$"
 59  sysarg="sysarg.switch.$$"
 60  sysprotoend="sysprotoend.$$"
 61  syscallnamestempfile="syscallnamesfile.$$"
 62  syshdrtempfile="syshdrtempfile.$$"
 63  audittempfile="audittempfile.$$"
 64  tracecodetempfile="tracecodetempfile.$$"
 65  systraceargstempfile="systraceargstempfile.$$"
 66  systraceargdesctempfile="systraceargdesctempfile.$$"
 67  systracerettempfile="systracerettempfile.$$"
 68  
 69  trap "rm $syslegal $sysent $sysinc $sysarg $sysprotoend $syscallnamestempfile $syshdrtempfile $audittempfile $tracecodetempfile $systraceargstempfile $systraceargdesctempfile $systracerettempfile" 0
 70  
 71  touch $syslegal $sysent $sysinc $sysarg $sysprotoend $syscallnamestempfile $syshdrtempfile $audittempfile $tracecodetempfile $systraceargstempfile $systraceargdesctempfile $systracerettempfile
 72  
 73  case $# in
 74      0)
 75  	echo "usage: $0 input-file [<names|proto|header|table|audit|trace> [<config-file>]]" 1>&2
 76  	exit 1
 77  	;;
 78  esac
 79  
 80  input_file="$1"
 81  shift
 82  
 83  if [ -n "$1" ]; then
 84      case $1 in
 85  	names)
 86  	    output_syscallnamesfile=1
 87  	    ;;
 88  	proto)
 89  	    output_sysprotofile=1
 90  	    ;;
 91  	header)
 92  	    output_syshdrfile=1
 93  	    ;;
 94  	table)
 95  	    output_syscalltablefile=1
 96  	    ;;
 97  	audit)
 98  	    output_auditevfile=1
 99  	    ;;
100  	systrace)
101  	    output_systrace=1
102  	    ;;
103  	trace)
104  	    output_tracecodes=1
105  	    use_stdout=1
106  	    ;;
107      esac
108      shift;
109  else
110      output_syscallnamesfile=1
111      output_sysprotofile=1
112      output_syshdrfile=1
113      output_syscalltablefile=1
114      output_auditevfile=1
115      output_tracecodes=1
116  fi
117  
118  if [ -n "$1" -a -f "$1" ]; then
119  	. $1
120  fi
121  
122  
123  
124  sed -e '
125  s/\$//g
126  :join
127  	/\\$/{a\
128  
129  	N
130  	s/\\\n//
131  	b join
132  	}
133  2,${
134  	/^#/!s/\([{}()*,;]\)/ \1 /g
135  }
136  ' < "$input_file" | awk "
137  	BEGIN {
138  		syslegal = \"$syslegal\"
139  		sysprotofile = \"$sysprotofile\"
140  		sysprotoend = \"$sysprotoend\"
141  		sysproto_h = \"$sysproto_h\"
142  		syscall_h = \"$syscall_h\"
143  		sysent = \"$sysent\"
144  		syscalltablefile = \"$syscalltablefile\"
145  		sysinc = \"$sysinc\"
146  		sysarg = \"$sysarg\"
147  		syscallnamesfile = \"$syscallnamesfile\"
148  		syscallnamestempfile = \"$syscallnamestempfile\"
149  		syshdrfile = \"$syshdrfile\"
150  		syshdrtempfile = \"$syshdrtempfile\"
151  		systraceargstempfile = \"$systraceargstempfile\"
152  		systraceargdesctempfile = \"$systraceargdesctempfile\"
153  		systracerettempfile = \"$systracerettempfile\"
154  		audittempfile = \"$audittempfile\"
155  		tracecodetempfile = \"$tracecodetempfile\"
156  		syscallprefix = \"$syscallprefix\"
157  		switchname = \"$switchname\"
158  		namesname = \"$namesname\"
159  		infile = \"$input_file\"
160  		infilepretty = \"${input_file#"$TARGET"}\"
161  		"'
162  
163  		printf "/*\n" > syslegal
164  		printf " * Copyright (c) 2004-2008 Apple Inc. All rights reserved.\n" > syslegal
165  		printf " * \n" > syslegal
166  		printf " * @APPLE_OSREFERENCE_LICENSE_HEADER_START@\n" > syslegal
167  		printf " * \n" > syslegal
168  		printf " * This file contains Original Code and/or Modifications of Original Code\n" > syslegal
169  		printf " * as defined in and that are subject to the Apple Public Source License\n" > syslegal
170  		printf " * Version 2.0 (the \047License\047). You may not use this file except in\n" > syslegal
171  		printf " * compliance with the License. The rights granted to you under the License\n" > syslegal
172  		printf " * may not be used to create, or enable the creation or redistribution of,\n" > syslegal
173  		printf " * unlawful or unlicensed copies of an Apple operating system, or to\n" > syslegal
174  		printf " * circumvent, violate, or enable the circumvention or violation of, any\n" > syslegal
175  		printf " * terms of an Apple operating system software license agreement.\n" > syslegal
176  		printf " * \n" > syslegal
177  		printf " * Please obtain a copy of the License at\n" > syslegal
178  		printf " * http://www.opensource.apple.com/apsl/ and read it before using this file.\n" > syslegal
179  		printf " * \n" > syslegal
180  		printf " * The Original Code and all software distributed under the License are\n" > syslegal
181  		printf " * distributed on an \047AS IS\047 basis, WITHOUT WARRANTY OF ANY KIND, EITHER\n" > syslegal
182  		printf " * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\n" > syslegal
183  		printf " * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\n" > syslegal
184  		printf " * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\n" > syslegal
185  		printf " * Please see the License for the specific language governing rights and\n" > syslegal
186  		printf " * limitations under the License.\n" > syslegal
187  		printf " * \n" > syslegal
188  		printf " * @APPLE_OSREFERENCE_LICENSE_HEADER_END@\n" > syslegal
189  		printf " * \n" > syslegal
190  		printf " * \n" > syslegal
191  		printf " * System call switch table.\n *\n" > syslegal
192  		printf " * DO NOT EDIT-- this file is automatically generated.\n" > syslegal
193  		printf " * created from %s\n */\n\n", infilepretty > syslegal
194  	}
195  	NR == 1 {
196  		printf "\n/* The casts are bogus but will do for now. */\n" > sysent
197  		printf "__private_extern__ const struct sysent %s[] = {\n",switchname > sysent
198  
199  		printf "#ifndef %s\n", sysproto_h > sysarg
200  		printf "#define\t%s\n\n", sysproto_h > sysarg
201  		printf "#ifndef %s\n", syscall_h > syshdrtempfile
202  		printf "#define\t%s\n\n", syscall_h > syshdrtempfile
203  		printf "#include <sys/appleapiopts.h>\n" > syshdrtempfile
204  		printf "#ifdef __APPLE_API_PRIVATE\n" > syshdrtempfile
205  		printf "#include <sys/appleapiopts.h>\n" > sysarg
206  		printf "#include <sys/cdefs.h>\n" > sysarg
207  		printf "#include <sys/mount_internal.h>\n" > sysarg
208  		printf "#include <sys/types.h>\n" > sysarg
209  		printf "#include <sys/sem_internal.h>\n" > sysarg
210  		printf "#include <sys/semaphore.h>\n" > sysarg
211  		printf "#include <sys/wait.h>\n" > sysarg
212  		printf "#include <mach/shared_region.h>\n" > sysarg
213  		printf "\n#ifdef KERNEL\n" > sysarg
214  		printf "#ifdef __APPLE_API_PRIVATE\n" > sysarg
215  		printf "/*\n" > sysarg
216  		printf " * The kernel may support multiple userspace ABIs, and must use\n" > sysarg
217  		printf " * argument structures with elements large enough for any of them.\n" > sysarg
218  		printf "*/\n" > sysarg
219  		printf "\n" > sysarg
220  		printf "#if CONFIG_REQUIRES_U32_MUNGING\n" > sysarg
221  		printf "#define\tPAD_(t)\t(sizeof(uint64_t) <= sizeof(t) \\\n " > sysarg
222  		printf "\t\t? 0 : sizeof(uint64_t) - sizeof(t))\n" > sysarg
223  		printf "#else\n" > sysarg
224  		printf "#define\tPAD_(t)\t(sizeof(uint32_t) <= sizeof(t) \\\n" > sysarg
225  		printf " 		? 0 : sizeof(uint32_t) - sizeof(t))\n" > sysarg
226  		printf "#endif\n" > sysarg
227  		printf "#if BYTE_ORDER == LITTLE_ENDIAN\n"> sysarg
228  		printf "#define\tPADL_(t)\t0\n" > sysarg
229  		printf "#define\tPADR_(t)\tPAD_(t)\n" > sysarg
230  		printf "#else\n" > sysarg
231  		printf "#define\tPADL_(t)\tPAD_(t)\n" > sysarg
232  		printf "#define\tPADR_(t)\t0\n" > sysarg
233  		printf "#endif\n" > sysarg
234  		printf "\n__BEGIN_DECLS\n" > sysarg
235  		printf "#include <sys/munge.h>\n" > sysarg
236  		
237  		printf "\n" > sysarg
238  
239  		printf "const char *%s[] = {\n", namesname > syscallnamestempfile
240  
241  		printf "#include <sys/param.h>\n" > audittempfile
242  		printf "#include <sys/types.h>\n\n" > audittempfile
243  		printf "#include <bsm/audit.h>\n" > audittempfile
244  		printf "#include <bsm/audit_kevents.h>\n\n" > audittempfile
245  		printf "#if CONFIG_AUDIT\n\n" > audittempfile
246  		printf "au_event_t sys_au_event[] = {\n" > audittempfile
247  
248  		printf "/*\n * System call argument to DTrace register array conversion.\n */\n" > systraceargstempfile
249  		printf "#include <sys/systrace_args.h>\n" > systraceargstempfile
250  		printf "void\nsystrace_args(int sysnum, void *params, uint64_t *uarg)\n{\n" > systraceargstempfile
251  		printf "\tint64_t *iarg  = (int64_t *) uarg;\n" > systraceargstempfile
252  		printf "\tswitch (sysnum) {\n" > systraceargstempfile
253  
254  		printf "void\nsystrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p = NULL;\n" > systraceargdesctempfile
255  		printf "\tswitch (sysnum) {\n" > systraceargdesctempfile
256  
257  		printf "void\nsystrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p = NULL;\n" > systracerettempfile
258  		printf "\tswitch (sysnum) {\n" > systracerettempfile
259  
260  		next
261  	}
262  	NF == 0 || $1 ~ /^;/ {
263  		next
264  	}
265  	$1 ~ /^#[ 	]*include/ {
266  		print > sysinc
267  		next
268  	}
269  	$1 ~ /^#[ 	]*if/ {
270  		print > sysent
271  		print > sysarg
272  		print > syscallnamestempfile
273  		print > sysprotoend
274  		print > audittempfile
275  		print > systraceargstempfile
276  		print > systraceargdesctempfile
277  		print > systracerettempfile
278  		savesyscall = syscall_num
279  		skip_for_header = 0
280  		next
281  	}
282  	$1 ~ /^#[ 	]*else/ {
283  		print > sysent
284  		print > sysarg
285  		print > syscallnamestempfile
286  		print > sysprotoend
287  		print > audittempfile
288  		print > systraceargstempfile
289  		print > systraceargdesctempfile
290  		print > systracerettempfile
291  		syscall_num = savesyscall
292  		skip_for_header = 1
293  		next
294  	}
295  	$1 ~ /^#/ {
296  		print > sysent
297  		print > sysarg
298  		print > syscallnamestempfile
299  		print > sysprotoend
300  		print > audittempfile
301  		print > systraceargstempfile
302  		print > systraceargdesctempfile
303  		print > systracerettempfile
304  		skip_for_header = 0
305  		next
306  	}
307  	syscall_num != $1 {
308  		printf "%s: line %d: syscall number out of sync at %d\n",
309  		    infile, NR, syscall_num
310  		printf "line is:\n"
311  		print
312  		exit 1
313  	}
314  	function align_comment(linesize, location, thefile) {
315  		printf(" ") > thefile
316  		while (linesize < location) {
317  			printf(" ") > thefile
318  			linesize++
319  		}
320  	}
321  	function parserr(was, wanted) {
322  		printf "%s: line %d: unexpected %s (expected %s)\n",
323  		    infile, NR, was, wanted
324  		exit 1
325  	}
326  	
327  	function parseline() {
328  		funcname = ""
329  		current_field = 4	# skip number, audit event, type
330  		args_start = 0
331  		args_end = 0
332  		comments_start = 0
333  		comments_end = 0
334  		argc = 0
335  		argssize = "0"
336  		additional_comments = " "
337  		obs_comments = "_"
338  
339  		# find start and end of call name and arguments
340  		if ($current_field != "{")
341  			parserr($current_field, "{")
342  		args_start = current_field
343  		current_field++
344  		while (current_field <= NF) {
345  			if ($current_field == "}") {
346  				args_end = current_field
347  				break
348  			}
349  			current_field++
350  		}
351  		if (args_end == 0) {
352  			printf "%s: line %d: invalid call name and arguments\n",
353  		    	infile, NR
354  			exit 1
355  		}
356  
357  		# find start and end of optional comments
358  		current_field++
359  		if (current_field < NF && $current_field == "{") {
360  			comments_start = current_field
361  			while (current_field <= NF) {
362  				if ($current_field == "}") {
363  					comments_end = current_field
364  					break
365  				}
366  				current_field++
367  			}
368  			if (comments_end == 0) {
369  				printf "%s: line %d: invalid comments \n",
370  					infile, NR
371  				exit 1
372  			}
373  		}
374  
375  		if ($args_end != "}")
376  			parserr($args_end, "}")
377  		args_end--
378  		if ($args_end != ";")
379  			parserr($args_end, ";")
380  		args_end--
381  
382  		# skip any NO_SYSCALL_STUB qualifier
383  		if ($args_end == "NO_SYSCALL_STUB")
384  			args_end--
385  
386  		if ($args_end != ")")
387  			parserr($args_end, ")")
388  		args_end--
389  
390  		# extract additional comments
391  		if (comments_start != 0) {
392  			current_field = comments_start + 1
393  			while (current_field < comments_end) {
394  				additional_comments = additional_comments $current_field " "
395  				obs_comments = obs_comments $current_field "_"
396  				current_field++
397  			}
398  		}
399  		sub(/old/, "obs", obs_comments)
400  		obs_comments = substr(obs_comments, 1, length(obs_comments)-1)
401  		if (obs_comments == "_") {
402  			obs_comments = ""
403  		}
404  
405  		# get function return type
406  		current_field = args_start + 1
407  		returntype = $current_field
408  
409  		# get function name and set up to get arguments
410  		current_field++
411  		funcname = $current_field
412  		argalias = funcname "_args"
413  		if (substr(argalias, 1, 4) == "sys_") {
414  			argalias = substr(argalias, 5)
415  		}
416  		current_field++ # bump past function name
417  
418  		if ($current_field != "(")
419  			parserr($current_field, "(")
420  		current_field++
421  
422  		if (current_field == args_end) {
423  			if ($current_field != "void")
424  				parserr($current_field, "argument definition")
425  			return
426  		}
427  
428  		# extract argument types and names
429  		while (current_field <= args_end) {
430  			argc++
431  			argtype[argc]=""
432  			ext_argtype[argc]=""
433  			oldf=""
434  			while (current_field < args_end && $(current_field + 1) != ",") {
435  				if (argtype[argc] != "" && oldf != "*") {
436  					argtype[argc] = argtype[argc] " ";
437  				}
438  				argtype[argc] = argtype[argc] $current_field;
439  				ext_argtype[argc] = argtype[argc];
440  				oldf = $current_field;
441  				current_field++
442  			}
443  			if (argtype[argc] == "")
444  				parserr($current_field, "argument definition")
445  			argname[argc] = $current_field;
446  			current_field += 2;			# skip name, and any comma
447  		}
448  		if (argc > 8) {
449  			printf "%s: line %d: too many arguments!\n", infile, NR
450  			exit 1
451  		}
452  		if (argc != 0)
453  			argssize = "AC(" argalias ")"
454  	}
455  
456  	{
457  		auditev = $2;
458  	}
459  
460  	{
461  		add_sysent_entry = 1
462  		add_sysnames_entry = 1
463  		add_sysheader_entry = 1
464  		add_sysproto_entry = 1
465  
466  
467  		if ($3 != "ALL") {
468  			files_keyword_OK = 0
469  			add_sysent_entry = 0
470  			add_sysnames_entry = 0
471  			add_sysheader_entry = 0
472  			add_sysproto_entry = 0
473  			
474  			if (match($3, "[T]") != 0) {
475  				add_sysent_entry = 1
476  				files_keyword_OK = 1
477  			}
478  			if (match($3, "[N]") != 0) {
479  				add_sysnames_entry = 1
480  				files_keyword_OK = 1
481  			}
482  			if (match($3, "[H]") != 0) {
483  				add_sysheader_entry = 1
484  				files_keyword_OK = 1
485  			}
486  			if (match($3, "[P]") != 0) {
487  				add_sysproto_entry = 1
488  				files_keyword_OK = 1
489  			}
490  			
491  			if (files_keyword_OK == 0) {
492  				printf "%s: line %d: unrecognized keyword %s\n", infile, NR, $2
493  				exit 1
494  			}
495  		}
496  		
497  		
498  		parseline()
499  		
500  		# output function argument structures to sysproto.h and build the
501  		# name of the appropriate argument mungers
502  		munge32 = "NULL"
503  		size32 = 0
504  
505  		if ((funcname != "nosys" && funcname != "enosys") || (syscall_num == 0 && funcname == "nosys")) {
506  			printf("\t/* %s */\n\tcase %d: {\n", funcname, syscall_num) > systraceargstempfile
507  			printf("\t/* %s */\n\tcase %d:\n", funcname, syscall_num) > systraceargdesctempfile
508  			printf("\t/* %s */\n\tcase %d:\n", funcname, syscall_num) > systracerettempfile
509  			if (argc > 0) {
510  				printf("\t\tswitch(ndx) {\n") > systraceargdesctempfile
511  				printf("\t\tstruct %s *p = params;\n", argalias) > systraceargstempfile
512  				for (i = 1; i <= argc; i++) {
513  					arg = argtype[i]
514  					sub("__restrict$", "", arg)
515  					if (index(arg, "*") > 0)
516  						printf("\t\tcase %d:\n\t\t\tp = \"userland %s\";\n\t\t\tbreak;\n", i - 1, arg) > systraceargdesctempfile
517  					else
518  						printf("\t\tcase %d:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n", i - 1, arg) > systraceargdesctempfile
519  					if (index(arg, "*") > 0 || arg == "caddr_t")
520                          printf("\t\tuarg[%d] = (uint64_t) p->%s; /* %s */\n", \
521  							i - 1, \
522  							argname[i], arg) > systraceargstempfile
523  					else if (substr(arg, 1, 1) == "u" || arg == "size_t")
524                          printf("\t\tuarg[%d] = (uint64_t) p->%s; /* %s */\n", \
525  							i - 1, \
526  							argname[i], arg) > systraceargstempfile
527  					else
528                          printf("\t\tiarg[%d] = (int64_t) p->%s; /* %s */\n", \
529  							i - 1, \
530  							argname[i], arg) > systraceargstempfile
531  				}
532  				printf("\t\tdefault:\n\t\t\tbreak;\n\t\t};\n") > systraceargdesctempfile
533  
534  			}
535  			printf("\t\tbreak;\n\t}\n", argc) > systraceargstempfile
536  			printf("\t\tif (ndx == 0 || ndx == 1)\n") > systracerettempfile
537  			printf("\t\t\tp = \"%s\";\n", returntype) > systracerettempfile
538  			printf("\t\tbreak;\n") > systracerettempfile
539  			printf("\t\tbreak;\n") > systraceargdesctempfile
540  			if (argc != 0) {
541  				if (add_sysproto_entry == 1) {
542  					printf("struct %s {\n", argalias) > sysarg
543  				}
544  				munge32 = "munge_"
545  				for (i = 1; i <= argc; i++) {
546  					# Build name of argument munger.
547  					# We account for all sys call argument types here.
548  					# This is where you add any new types.  With LP64 support
549  					# each argument consumes 64-bits.  
550  					# see .../xnu/bsd/dev/munge.c for munge argument types.
551  					if (argtype[i] == "long") {
552  						ext_argtype[i] = "user_long_t";
553  						munge32 = munge32 "s"
554  						size32 += 4
555  					}
556  					else if (argtype[i] == "u_long") {
557  						ext_argtype[i] = "user_ulong_t";
558  						munge32 = munge32 "w"
559  						size32 += 4
560  					}
561  					else if (argtype[i] == "size_t") {
562  						ext_argtype[i] = "user_size_t";
563  						munge32 = munge32 "w"
564  						size32 += 4
565  					}
566  					else if (argtype[i] == "ssize_t") {
567  						ext_argtype[i] = "user_ssize_t";
568  						munge32 = munge32 "s"
569  						size32 += 4
570  					}
571  					else if (argtype[i] == "user_ssize_t" || argtype[i] == "user_long_t") {
572  						munge32 = munge32 "s"
573  						size32 += 4
574  					}
575  					else if (argtype[i] == "user_addr_t" || argtype[i] == "user_size_t" ||
576  						argtype[i] == "user_ulong_t") {
577  						munge32 = munge32 "w"
578  						size32 += 4
579  					}
580  					else if (argtype[i] == "caddr_t" || argtype[i] == "semun_t" ||
581    						argtype[i] == "uuid_t" || match(argtype[i], "[\*]") != 0) {
582  						ext_argtype[i] = "user_addr_t";
583  						munge32 = munge32 "w"
584  						size32 += 4
585  					}
586  					else if (argtype[i] == "int" || argtype[i] == "u_int" ||
587  							 argtype[i] == "uid_t" || argtype[i] == "pid_t" ||
588  							 argtype[i] == "id_t" || argtype[i] == "idtype_t" ||
589  							 argtype[i] == "socklen_t" || argtype[i] == "uint32_t" || argtype[i] == "int32_t" ||
590  							 argtype[i] == "sigset_t" || argtype[i] == "gid_t" || argtype[i] == "unsigned int" ||
591  							 argtype[i] == "mode_t" || argtype[i] == "key_t" ||
592  							 argtype[i] == "mach_port_name_t" || argtype[i] == "au_asid_t" ||
593  							 argtype[i] == "sae_associd_t" || argtype[i] == "sae_connid_t") {
594  						munge32 = munge32 "w"
595  						size32 += 4
596  					}
597  					else if (argtype[i] == "off_t" || argtype[i] == "int64_t" || argtype[i] == "uint64_t") {
598  						munge32 = munge32 "l"
599  						size32 += 8
600  					}
601  					else {
602  						printf "%s: line %d: invalid type \"%s\" \n", 
603  							infile, NR, argtype[i]
604  						printf "You need to add \"%s\" into the type checking code. \n", 
605  							 argtype[i]
606  						exit 1
607  					}
608  					if (add_sysproto_entry == 1) {
609  						printf("\tchar %s_l_[PADL_(%s)]; " \
610  							"%s %s; char %s_r_[PADR_(%s)];\n",
611  							argname[i], ext_argtype[i],
612  							ext_argtype[i], argname[i],
613  							argname[i], ext_argtype[i]) > sysarg
614  					}
615  				}
616  				if (add_sysproto_entry == 1) {
617  					printf("};\n") > sysarg
618  				}
619  			}
620  			else if (add_sysproto_entry == 1) { 
621  				printf("struct %s {\n\tint32_t dummy;\n};\n", argalias) > sysarg
622  			}
623  		}
624  		
625  		# output to init_sysent.c
626  		tempname = funcname
627  		if (add_sysent_entry == 0) {
628  			argssize = "0"
629  			munge32 = "NULL"
630  			munge_ret = "_SYSCALL_RET_NONE"
631  			if (tempname != "enosys") {
632  				tempname = "nosys"
633  			}
634  		}
635  		else {
636  			# figure out which return value type to munge
637  			if (returntype == "user_addr_t") {
638  				munge_ret = "_SYSCALL_RET_ADDR_T"
639  			}
640  			else if (returntype == "user_ssize_t") {
641  				munge_ret = "_SYSCALL_RET_SSIZE_T"
642  			}
643  			else if (returntype == "user_size_t") {
644  				munge_ret = "_SYSCALL_RET_SIZE_T"
645  			}
646  			else if (returntype == "int") {
647  				munge_ret = "_SYSCALL_RET_INT_T"
648  			}
649  			else if (returntype == "u_int" || returntype == "mach_port_name_t") {
650  				munge_ret = "_SYSCALL_RET_UINT_T"
651  			}
652  			else if (returntype == "uint32_t") {
653  				munge_ret = "_SYSCALL_RET_UINT_T"
654  			}
655  			else if (returntype == "uint64_t") {
656  				munge_ret = "_SYSCALL_RET_UINT64_T"
657  			}
658  			else if (returntype == "off_t") {
659  				munge_ret = "_SYSCALL_RET_OFF_T"
660  			}
661  			else if (returntype == "void") {
662  				munge_ret = "_SYSCALL_RET_NONE"
663  			}
664  			else {
665  				printf "%s: line %d: invalid return type \"%s\" \n", 
666  					infile, NR, returntype
667  				printf "You need to add \"%s\" into the return type checking code. \n", 
668  					 returntype
669  				exit 1
670  			}
671  		}
672  
673  		printf("#if CONFIG_REQUIRES_U32_MUNGING || (__arm__ && (__BIGGEST_ALIGNMENT__ > 4))\n") > sysent
674  		printf("\t{ \(sy_call_t *\)%s, %s, %s, %s, %s},", 
675  				tempname, munge32, munge_ret, argssize, size32) > sysent
676  		linesize = length(tempname) + length(munge32) + \
677  			length(munge_ret) + length(argssize) + length(size32) + 28
678  		align_comment(linesize, 88, sysent)
679  		printf("/* %d = %s%s*/\n", syscall_num, funcname, additional_comments) > sysent
680  		printf("#else\n") > sysent
681  		printf("\t{ \(sy_call_t *\)%s, %s, %s, %s},\n", 
682  				tempname, munge_ret, argssize, size32) > sysent
683  		printf("#endif\n") > sysent
684  		
685  		# output to syscalls.c
686  		if (add_sysnames_entry == 1) {
687  			tempname = funcname
688  			if (substr(tempname, 1, 4) == "sys_") {
689  				tempname = substr(tempname, 5)
690  			}
691  			if (funcname == "nosys" || funcname == "enosys") {
692  				if (syscall_num == 0)
693  					tempname = "syscall"
694  				else
695  					tempname = "#" syscall_num
696  			}
697  			printf("\t\"%s\", ", tempname) > syscallnamestempfile
698  			linesize = length(tempname) + 8
699  			align_comment(linesize, 25, syscallnamestempfile)
700  			if (substr(tempname,1,1) == "#") {
701  				printf("/* %d =%s*/\n", syscall_num, additional_comments) > syscallnamestempfile
702  			}
703  			else {
704  				printf("/* %d = %s%s*/\n", syscall_num, tempname, additional_comments) > syscallnamestempfile
705  			}
706  		}
707  
708  		# output to syscalls.h
709  		if (add_sysheader_entry == 1) {
710  			tempname = funcname
711  			if (substr(tempname, 1, 4) == "sys_") {
712  				tempname = substr(tempname, 5)
713  			}
714  			if (syscall_num == 0) {
715  				tempname = "syscall"
716  			}
717  			if (tempname != "nosys" && tempname != "enosys") {
718  				printf("#define\t%s%s", syscallprefix, tempname) > syshdrtempfile
719  				linesize = length(syscallprefix) + length(tempname) + 12
720  				align_comment(linesize, 30, syshdrtempfile)
721  				printf("%d\n", syscall_num) > syshdrtempfile
722  			}
723  			else if (skip_for_header == 0) {
724  				printf("\t\t\t/* %d %s*/\n", syscall_num, additional_comments) > syshdrtempfile
725  			}
726  		}
727  		
728  		# output function prototypes to sysproto.h
729  		if (add_sysproto_entry == 1) {
730  			if (funcname =="exit") {
731  				printf("void %s(struct proc *, struct %s *, int32_t *);\n", 
732  						funcname, argalias) > sysprotoend
733  			}
734  			else if ((funcname != "nosys" && funcname != "enosys") || (syscall_num == 0 && funcname == "nosys")) {
735  				printf("int %s(struct proc *, struct %s *, %s *);\n", 
736  						funcname, argalias, returntype) > sysprotoend
737  			}
738  		}
739  
740  		# output to audit_kevents.c
741  		printf("\t%s,\t\t", auditev) > audittempfile
742  		printf("/* %d = %s%s*/\n", syscall_num, tempname, additional_comments) > audittempfile 
743  
744  		tempname = funcname
745  		if (skip_for_header == 0) {
746  			if (tempname == "nosys" || tempname == "enosys") {
747  				if (obs_comments == "") {
748  					printf("0x40c%04x\tBSC_#%d%s\n", (syscall_num*4), syscall_num, obs_comments) > tracecodetempfile 
749  				} else {
750  					printf("0x40c%04x\tBSC%s\n", (syscall_num*4), obs_comments) > tracecodetempfile 
751  				}
752  			} else {	
753  				sub(/^_+/, "", tempname)
754  				printf("0x40c%04x\tBSC_%s\n", (syscall_num*4), tempname) > tracecodetempfile 
755  			}
756  		}
757  
758  		syscall_num++
759  		next
760  	}
761  
762  	END {
763  		printf "#define AC(name) (sizeof(struct name) / sizeof(syscall_arg_t))\n" > sysinc
764  		printf "\n" > sysinc
765  
766  		printf("\n__END_DECLS\n") > sysprotoend
767  		printf("#undef PAD_\n") > sysprotoend
768  		printf("#undef PADL_\n") > sysprotoend
769  		printf("#undef PADR_\n") > sysprotoend
770  		printf "\n#endif /* __APPLE_API_PRIVATE */\n" > sysprotoend
771  		printf "#endif /* KERNEL */\n" > sysprotoend
772  		printf("\n#endif /* !%s */\n", sysproto_h) > sysprotoend
773  
774  		printf("};\n") > sysent
775  		printf("const unsigned int nsysent = sizeof(sysent) / sizeof(sysent[0]);\n") > sysent
776  
777  		printf("};\n") > syscallnamestempfile
778  		printf("#define\t%sMAXSYSCALL\t%d\n", syscallprefix, syscall_num) \
779  		    > syshdrtempfile
780  		printf("#define\t%sinvalid\t%d\n", syscallprefix, 63) \
781  		    > syshdrtempfile
782  		printf("\n#endif /* __APPLE_API_PRIVATE */\n") > syshdrtempfile
783  		printf("#endif /* !%s */\n", syscall_h) > syshdrtempfile
784  		printf("};\n\n") > audittempfile
785  		printf("#endif /* AUDIT */\n") > audittempfile
786  
787  		printf "\tdefault:\n\t\tbreak;\n\t};\n}\n" > systraceargstempfile
788  		printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p != NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systraceargdesctempfile
789  		printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p != NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systracerettempfile
790  	} '
791  
792  if [ $output_syscalltablefile -eq 1 ]; then
793      cat $syslegal > $syscalltablefile
794      cat $sysinc $sysent >> $syscalltablefile
795  fi
796  
797  if [ $output_syscallnamesfile -eq 1 ]; then
798      cat $syslegal $syscallnamestempfile > $syscallnamesfile
799  fi
800  
801  if [ $output_sysprotofile -eq 1 ]; then
802      cat $syslegal $sysarg $sysprotoend > $sysprotofile
803  fi
804  
805  if [ $output_syshdrfile -eq 1 ]; then
806      cat $syslegal $syshdrtempfile > $syshdrfile
807  fi
808  
809  if [ $output_auditevfile -eq 1 ]; then
810      cat $syslegal $audittempfile > $auditevfile
811  fi
812  
813  if [ $output_systrace -eq 1 ]; then
814  	cat $systraceargstempfile > $systraceargsfile
815  	cat $systraceargdesctempfile >> $systraceargsfile
816  	cat $systracerettempfile >> $systraceargsfile
817  fi
818  
819  if [ $output_tracecodes -eq 1 ]; then
820  	if [ $use_stdout -eq 1 ]; then
821  		cat $tracecodetempfile
822  	else
823  		cat $tracecodetempfile > $tracecodename
824  	fi
825  fi
826