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