xref: /xnu-11417.140.69/bsd/kern/makesyscalls.sh (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
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
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
37output_tracecodes=0
38output_systrace=0
39
40use_stdout=0
41
42# output files:
43syscallnamesfile="syscalls.c"
44sysprotofile="sysproto.h"
45sysproto_h=_SYS_SYSPROTO_H_
46syshdrfile="syscall.h"
47syscall_h=_SYS_SYSCALL_H_
48syscalltablefile="init_sysent.c"
49auditevfile="audit_kevents.c"
50syscallprefix="SYS_"
51switchname="sysent"
52namesname="syscallnames"
53tracecodename="syscall.codes"
54systraceargsfile="systrace_args.c"
55# tmp files:
56syslegal="sysent.syslegal.$$"
57sysent="sysent.switch.$$"
58sysinc="sysinc.switch.$$"
59sysarg="sysarg.switch.$$"
60sysprotoend="sysprotoend.$$"
61syscallnamestempfile="syscallnamesfile.$$"
62syshdrtempfile="syshdrtempfile.$$"
63audittempfile="audittempfile.$$"
64tracecodetempfile="tracecodetempfile.$$"
65systraceargstempfile="systraceargstempfile.$$"
66systraceargdesctempfile="systraceargdesctempfile.$$"
67systracerettempfile="systracerettempfile.$$"
68
69trap "rm $syslegal $sysent $sysinc $sysarg $sysprotoend $syscallnamestempfile $syshdrtempfile $audittempfile $tracecodetempfile $systraceargstempfile $systraceargdesctempfile $systracerettempfile" 0
70
71touch $syslegal $sysent $sysinc $sysarg $sysprotoend $syscallnamestempfile $syshdrtempfile $audittempfile $tracecodetempfile $systraceargstempfile $systraceargdesctempfile $systracerettempfile
72
73case $# in
74    0)
75	echo "usage: $0 input-file [<names|proto|header|table|audit|trace> [<config-file>]]" 1>&2
76	exit 1
77	;;
78esac
79
80input_file="$1"
81shift
82
83if [ -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;
109else
110    output_syscallnamesfile=1
111    output_sysprotofile=1
112    output_syshdrfile=1
113    output_syscalltablefile=1
114    output_auditevfile=1
115    output_tracecodes=1
116fi
117
118if [ -n "$1" -a -f "$1" ]; then
119	. $1
120fi
121
122
123
124sed -e '
125s/\$//g
126:join
127	/\\$/{a\
128
129	N
130	s/\\\n//
131	b join
132	}
1332,${
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" || arg == "caddr_ut")
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" || arg == "size_ut")
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] == "size_ut") {
567						ext_argtype[i] = "user_size_ut";
568						munge32 = munge32 "w"
569						size32 += 4
570					}
571					else if (argtype[i] == "ssize_t") {
572						ext_argtype[i] = "user_ssize_t";
573						munge32 = munge32 "s"
574						size32 += 4
575					}
576					else if (argtype[i] == "user_ssize_t" || argtype[i] == "user_long_t") {
577						munge32 = munge32 "s"
578						size32 += 4
579					}
580					else if (argtype[i] == "user_addr_t" || argtype[i] == "user_size_t" ||
581						argtype[i] == "user_ulong_t") {
582						munge32 = munge32 "w"
583						size32 += 4
584					}
585					else if (argtype[i] == "caddr_t" ||
586						  argtype[i] == "semun_t" || argtype[i] == "uuid_t" ||
587							match(argtype[i], "[\*]") != 0) {
588						ext_argtype[i] = "user_addr_t";
589						munge32 = munge32 "w"
590						size32 += 4
591					}
592				  else if (argtype[i] == "caddr_ut") {
593						ext_argtype[i] = "user_addr_ut";
594						munge32 = munge32 "w"
595						size32 += 4
596				  }
597					else if (argtype[i] == "int" || argtype[i] == "u_int" ||
598							 argtype[i] == "uid_t" || argtype[i] == "pid_t" ||
599							 argtype[i] == "id_t" || argtype[i] == "idtype_t" ||
600							 argtype[i] == "socklen_t" || argtype[i] == "uint32_t" || argtype[i] == "int32_t" ||
601							 argtype[i] == "sigset_t" || argtype[i] == "gid_t" || argtype[i] == "unsigned int" ||
602							 argtype[i] == "mode_t" || argtype[i] == "key_t" ||
603							 argtype[i] == "mach_port_name_t" || argtype[i] == "au_asid_t" ||
604							 argtype[i] == "sae_associd_t" || argtype[i] == "sae_connid_t") {
605						munge32 = munge32 "w"
606						size32 += 4
607					}
608					else if (argtype[i] == "off_t" || argtype[i] == "int64_t" || argtype[i] == "uint64_t") {
609						munge32 = munge32 "l"
610						size32 += 8
611					}
612					else {
613						printf "%s: line %d: invalid type \"%s\" \n",
614							infile, NR, argtype[i]
615						printf "You need to add \"%s\" into the type checking code. \n",
616							 argtype[i]
617						exit 1
618					}
619					if (add_sysproto_entry == 1) {
620						printf("\tchar %s_l_[PADL_(%s)]; " \
621							"%s %s; char %s_r_[PADR_(%s)];\n",
622							argname[i], ext_argtype[i],
623							ext_argtype[i], argname[i],
624							argname[i], ext_argtype[i]) > sysarg
625					}
626				}
627				if (add_sysproto_entry == 1) {
628					printf("};\n") > sysarg
629				}
630			}
631			else if (add_sysproto_entry == 1) {
632				printf("struct %s {\n\tint32_t dummy;\n};\n", argalias) > sysarg
633			}
634		}
635
636		# output to init_sysent.c
637		tempname = funcname
638		if (add_sysent_entry == 0) {
639			argssize = "0"
640			munge32 = "NULL"
641			munge_ret = "_SYSCALL_RET_NONE"
642			if (tempname != "enosys") {
643				tempname = "nosys"
644			}
645		}
646		else {
647			# figure out which return value type to munge
648			if (returntype == "user_addr_t") {
649				munge_ret = "_SYSCALL_RET_ADDR_T"
650			}
651			else if (returntype == "user_ssize_t") {
652				munge_ret = "_SYSCALL_RET_SSIZE_T"
653			}
654			else if (returntype == "user_size_t") {
655				munge_ret = "_SYSCALL_RET_SIZE_T"
656			}
657			else if (returntype == "int") {
658				munge_ret = "_SYSCALL_RET_INT_T"
659			}
660			else if (returntype == "u_int" || returntype == "mach_port_name_t") {
661				munge_ret = "_SYSCALL_RET_UINT_T"
662			}
663			else if (returntype == "uint32_t") {
664				munge_ret = "_SYSCALL_RET_UINT_T"
665			}
666			else if (returntype == "uint64_t") {
667				munge_ret = "_SYSCALL_RET_UINT64_T"
668			}
669			else if (returntype == "off_t") {
670				munge_ret = "_SYSCALL_RET_OFF_T"
671			}
672			else if (returntype == "void") {
673				munge_ret = "_SYSCALL_RET_NONE"
674			}
675			else {
676				printf "%s: line %d: invalid return type \"%s\" \n",
677					infile, NR, returntype
678				printf "You need to add \"%s\" into the return type checking code. \n",
679					 returntype
680				exit 1
681			}
682		}
683
684		printf("#if CONFIG_REQUIRES_U32_MUNGING\n") > sysent
685		printf("\t{ \(sy_call_t *\)(void (*)(void))%s, %s, %s, %s, %s},",
686				tempname, munge32, munge_ret, argssize, size32) > sysent
687		linesize = length(tempname) + length(munge32) + \
688			length(munge_ret) + length(argssize) + length(size32) + 28
689		align_comment(linesize, 88, sysent)
690		printf("/* %d = %s%s*/\n", syscall_num, funcname, additional_comments) > sysent
691		printf("#else\n") > sysent
692		printf("\t{ \(sy_call_t *\)(void (*)(void))%s, %s, %s, %s},\n",
693				tempname, munge_ret, argssize, size32) > sysent
694		printf("#endif\n") > sysent
695
696		# output to syscalls.c
697		if (add_sysnames_entry == 1) {
698			tempname = funcname
699			if (substr(tempname, 1, 4) == "sys_") {
700				tempname = substr(tempname, 5)
701			}
702			if (funcname == "nosys" || funcname == "enosys") {
703				if (syscall_num == 0)
704					tempname = "syscall"
705				else
706					tempname = "#" syscall_num
707			}
708			printf("\t\"%s\", ", tempname) > syscallnamestempfile
709			linesize = length(tempname) + 8
710			align_comment(linesize, 25, syscallnamestempfile)
711			if (substr(tempname,1,1) == "#") {
712				printf("/* %d =%s*/\n", syscall_num, additional_comments) > syscallnamestempfile
713			}
714			else {
715				printf("/* %d = %s%s*/\n", syscall_num, tempname, additional_comments) > syscallnamestempfile
716			}
717		}
718
719		# output to syscalls.h
720		if (add_sysheader_entry == 1) {
721			tempname = funcname
722			if (substr(tempname, 1, 4) == "sys_") {
723				tempname = substr(tempname, 5)
724			}
725			if (syscall_num == 0) {
726				tempname = "syscall"
727			}
728			if (tempname != "nosys" && tempname != "enosys") {
729				printf("#define\t%s%s", syscallprefix, tempname) > syshdrtempfile
730				linesize = length(syscallprefix) + length(tempname) + 12
731				align_comment(linesize, 30, syshdrtempfile)
732				printf("%d\n", syscall_num) > syshdrtempfile
733			}
734			else if (skip_for_header == 0) {
735				printf("\t\t\t/* %d %s*/\n", syscall_num, additional_comments) > syshdrtempfile
736			}
737		}
738
739		# output function prototypes to sysproto.h
740		if (add_sysproto_entry == 1) {
741			if (funcname =="exit") {
742				printf("void %s(struct proc *, struct %s *, int32_t *);\n",
743						funcname, argalias) > sysprotoend
744			}
745			else if ((funcname != "nosys" && funcname != "enosys") || (syscall_num == 0 && funcname == "nosys")) {
746				printf("int %s(struct proc *, struct %s *, %s *);\n",
747						funcname, argalias, returntype) > sysprotoend
748			}
749		}
750
751		# output to audit_kevents.c
752		printf("\t%s,\t\t", auditev) > audittempfile
753		printf("/* %d = %s%s*/\n", syscall_num, tempname, additional_comments) > audittempfile
754
755		tempname = funcname
756		if (skip_for_header == 0) {
757			if (tempname == "nosys" || tempname == "enosys") {
758				if (obs_comments == "") {
759					printf("0x40c%04x\tBSC_#%d%s\n", (syscall_num*4), syscall_num, obs_comments) > tracecodetempfile
760				} else {
761					printf("0x40c%04x\tBSC%s\n", (syscall_num*4), obs_comments) > tracecodetempfile
762				}
763			} else {
764				sub(/^_+/, "", tempname)
765				printf("0x40c%04x\tBSC_%s\n", (syscall_num*4), tempname) > tracecodetempfile
766			}
767		}
768
769		syscall_num++
770		next
771	}
772
773	END {
774		printf "#define AC(name) (sizeof(struct name) / sizeof(syscall_arg_t))\n" > sysinc
775		printf "\n" > sysinc
776
777		printf("\n__END_DECLS\n") > sysprotoend
778		printf("#undef PAD_\n") > sysprotoend
779		printf("#undef PADL_\n") > sysprotoend
780		printf("#undef PADR_\n") > sysprotoend
781		printf "\n#endif /* __APPLE_API_PRIVATE */\n" > sysprotoend
782		printf "#endif /* KERNEL */\n" > sysprotoend
783		printf("\n#endif /* !%s */\n", sysproto_h) > sysprotoend
784
785		printf("};\n") > sysent
786		printf("const unsigned int nsysent = sizeof(sysent) / sizeof(sysent[0]);\n") > sysent
787
788		printf("};\n") > syscallnamestempfile
789		printf("#define\t%sMAXSYSCALL\t%d\n", syscallprefix, syscall_num) \
790		    > syshdrtempfile
791		printf("#define\t%sinvalid\t%d\n", syscallprefix, 63) \
792		    > syshdrtempfile
793		printf("\n#endif /* __APPLE_API_PRIVATE */\n") > syshdrtempfile
794		printf("#endif /* !%s */\n", syscall_h) > syshdrtempfile
795		printf("};\n\n") > audittempfile
796		printf("#endif /* AUDIT */\n") > audittempfile
797
798		printf "\tdefault:\n\t\tbreak;\n\t};\n}\n" > systraceargstempfile
799		printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p != NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systraceargdesctempfile
800		printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p != NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systracerettempfile
801	} '
802
803if [ $output_syscalltablefile -eq 1 ]; then
804    cat $syslegal > $syscalltablefile
805    cat $sysinc $sysent >> $syscalltablefile
806fi
807
808if [ $output_syscallnamesfile -eq 1 ]; then
809    cat $syslegal $syscallnamestempfile > $syscallnamesfile
810fi
811
812if [ $output_sysprotofile -eq 1 ]; then
813    cat $syslegal $sysarg $sysprotoend > $sysprotofile
814fi
815
816if [ $output_syshdrfile -eq 1 ]; then
817    cat $syslegal $syshdrtempfile > $syshdrfile
818fi
819
820if [ $output_auditevfile -eq 1 ]; then
821    cat $syslegal $audittempfile > $auditevfile
822fi
823
824if [ $output_systrace -eq 1 ]; then
825	cat $systraceargstempfile > $systraceargsfile
826	cat $systraceargdesctempfile >> $systraceargsfile
827	cat $systracerettempfile >> $systraceargsfile
828fi
829
830if [ $output_tracecodes -eq 1 ]; then
831	if [ $use_stdout -eq 1 ]; then
832		cat $tracecodetempfile
833	else
834		cat $tracecodetempfile > $tracecodename
835	fi
836fi
837
838