1#!/usr/bin/env bash
2# Copyright 2009 The Go Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style
4# license that can be found in the LICENSE file.
5
6# The syscall package provides access to the raw system call
7# interface of the underlying operating system.  Porting Go to
8# a new architecture/operating system combination requires
9# some manual effort, though there are tools that automate
10# much of the process.  The auto-generated files have names
11# beginning with z.
12#
13# This script runs or (given -n) prints suggested commands to generate z files
14# for the current system.  Running those commands is not automatic.
15# This script is documentation more than anything else.
16#
17# * asm_${GOOS}_${GOARCH}.s
18#
19# This hand-written assembly file implements system call dispatch.
20# There are three entry points:
21#
22# 	func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
23# 	func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
24# 	func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
25#
26# The first and second are the standard ones; they differ only in
27# how many arguments can be passed to the kernel.
28# The third is for low-level use by the ForkExec wrapper;
29# unlike the first two, it does not call into the scheduler to
30# let it know that a system call is running.
31#
32# * syscall_${GOOS}.go
33#
34# This hand-written Go file implements system calls that need
35# special handling and lists "//sys" comments giving prototypes
36# for ones that can be auto-generated.  Mksyscall reads those
37# comments to generate the stubs.
38#
39# * syscall_${GOOS}_${GOARCH}.go
40#
41# Same as syscall_${GOOS}.go except that it contains code specific
42# to ${GOOS} on one particular architecture.
43#
44# * types_${GOOS}.c
45#
46# This hand-written C file includes standard C headers and then
47# creates typedef or enum names beginning with a dollar sign
48# (use of $ in variable names is a gcc extension).  The hardest
49# part about preparing this file is figuring out which headers to
50# include and which symbols need to be #defined to get the
51# actual data structures that pass through to the kernel system calls.
52# Some C libraries present alternate versions for binary compatibility
53# and translate them on the way in and out of system calls, but
54# there is almost always a #define that can get the real ones.
55# See types_darwin.c and types_linux.c for examples.
56#
57# * zerror_${GOOS}_${GOARCH}.go
58#
59# This machine-generated file defines the system's error numbers,
60# error strings, and signal numbers.  The generator is "mkerrors.sh".
61# Usually no arguments are needed, but mkerrors.sh will pass its
62# arguments on to godefs.
63#
64# * zsyscall_${GOOS}_${GOARCH}.go
65#
66# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
67#
68# * zsysnum_${GOOS}_${GOARCH}.go
69#
70# Generated by mksysnum_${GOOS}.
71#
72# * ztypes_${GOOS}_${GOARCH}.go
73#
74# Generated by godefs; see types_${GOOS}.c above.
75
76GOOSARCH="${GOOS}_${GOARCH}"
77
78# defaults
79mksyscall="./mksyscall.pl"
80mkerrors="./mkerrors.sh"
81zerrors="zerrors_$GOOSARCH.go"
82mksysctl=""
83zsysctl="zsysctl_$GOOSARCH.go"
84mksysnum=
85mktypes=
86mkasm=
87run="sh"
88
89case "$1" in
90-syscalls)
91	for i in zsyscall*go
92	do
93		# Run the command line that appears in the first line
94		# of the generated file to regenerate it.
95		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
96		rm _$i
97	done
98	exit 0
99	;;
100-n)
101	run="cat"
102	shift
103esac
104
105case "$#" in
1060)
107	;;
108*)
109	echo 'usage: mkall.sh [-n]' 1>&2
110	exit 2
111esac
112
113GOOSARCH_in=syscall_$GOOSARCH.go
114case "$GOOSARCH" in
115_* | *_ | _)
116	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
117	exit 1
118	;;
119aix_ppc64)
120	mkerrors="$mkerrors -maix64"
121	mksyscall="./mksyscall_libc.pl -aix"
122	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
123	;;
124darwin_386)
125	mkerrors="$mkerrors -m32"
126	mksyscall="./mksyscall.pl -l32 -darwin"
127	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
128	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
129	mkasm="go run mkasm_darwin.go"
130	;;
131darwin_amd64)
132	mkerrors="$mkerrors -m64"
133	mksyscall="./mksyscall.pl -darwin"
134	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
135	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
136	mkasm="go run mkasm_darwin.go"
137	;;
138darwin_arm64)
139	mkerrors="$mkerrors -m64"
140	mksyscall="./mksyscall.pl -darwin"
141	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
142	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
143	mkasm="go run mkasm_darwin.go"
144	;;
145darwin_arm)
146	mkerrors="$mkerrors -m32"
147	mksyscall="./mksyscall.pl -l32 -darwin"
148	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
149	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
150	mkasm="go run mkasm_darwin.go"
151	;;
152dragonfly_amd64)
153	mkerrors="$mkerrors -m64"
154	mksyscall="./mksyscall.pl -dragonfly"
155	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
156	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
157	;;
158freebsd_386)
159	mkerrors="$mkerrors -m32"
160	mksyscall="./mksyscall.pl -l32"
161	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
162	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
163	;;
164freebsd_amd64)
165	mkerrors="$mkerrors -m64"
166	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
167	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
168	;;
169freebsd_arm)
170	mkerrors="$mkerrors"
171	mksyscall="./mksyscall.pl -l32 -arm"
172	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
173	# Let the type of C char be signed to make the bare syscall
174	# API consistent between platforms.
175	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
176	;;
177freebsd_arm64)
178	mkerrors="$mkerrors"
179	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
180	# Let the type of C char be signed to make the bare syscall
181	# API consistent between platforms.
182	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
183	;;
184linux_386)
185	mkerrors="$mkerrors -m32"
186	mksyscall="./mksyscall.pl -l32"
187	mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_32.h"
188	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
189	;;
190linux_amd64)
191	unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
192	if [ "$unistd_h" = "" ]; then
193		echo >&2 cannot find unistd_64.h
194		exit 1
195	fi
196	mkerrors="$mkerrors -m64"
197	mksysnum="./mksysnum_linux.pl $unistd_h"
198	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
199	;;
200linux_arm)
201	mkerrors="$mkerrors"
202	mksyscall="./mksyscall.pl -l32 -arm"
203	mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl -"
204	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
205	;;
206linux_arm64)
207	unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
208	if [ "$unistd_h" = "" ]; then
209		echo >&2 cannot find unistd_64.h
210		exit 1
211	fi
212	mksysnum="./mksysnum_linux.pl $unistd_h"
213	# Let the type of C char be signed to make the bare syscall
214	# API consistent between platforms.
215	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
216	;;
217linux_mips)
218	GOOSARCH_in=syscall_linux_mipsx.go
219	unistd_h=/usr/include/asm/unistd.h
220	mksyscall="./mksyscall.pl -b32 -arm"
221	mkerrors="$mkerrors"
222	mksysnum="./mksysnum_linux.pl $unistd_h"
223	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
224	;;
225linux_mipsle)
226	GOOSARCH_in=syscall_linux_mipsx.go
227	unistd_h=/usr/include/asm/unistd.h
228	mksyscall="./mksyscall.pl -l32 -arm"
229	mkerrors="$mkerrors"
230	mksysnum="./mksysnum_linux.pl $unistd_h"
231	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
232	;;
233linux_mips64)
234	GOOSARCH_in=syscall_linux_mips64x.go
235	unistd_h=/usr/include/asm/unistd.h
236	mkerrors="$mkerrors -m64"
237	mksysnum="./mksysnum_linux.pl $unistd_h"
238	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
239	;;
240linux_mips64le)
241	GOOSARCH_in=syscall_linux_mips64x.go
242	unistd_h=/usr/include/asm/unistd.h
243	mkerrors="$mkerrors -m64"
244	mksysnum="./mksysnum_linux.pl $unistd_h"
245	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
246	;;
247linux_ppc64)
248	GOOSARCH_in=syscall_linux_ppc64x.go
249	unistd_h=/usr/include/asm/unistd.h
250	mkerrors="$mkerrors -m64"
251	mksysnum="./mksysnum_linux.pl $unistd_h"
252	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
253	;;
254linux_ppc64le)
255	GOOSARCH_in=syscall_linux_ppc64x.go
256	unistd_h=/usr/include/powerpc64le-linux-gnu/asm/unistd.h
257	mkerrors="$mkerrors -m64"
258	mksysnum="./mksysnum_linux.pl $unistd_h"
259	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
260	;;
261linux_riscv64)
262	unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
263	if [ "$unistd_h" = "" ]; then
264		echo >&2 cannot find unistd_64.h
265		exit 1
266	fi
267	mksysnum="./mksysnum_linux.pl $unistd_h"
268	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
269	;;
270linux_s390x)
271	GOOSARCH_in=syscall_linux_s390x.go
272	unistd_h=/usr/include/asm/unistd.h
273	mkerrors="$mkerrors -m64"
274	mksysnum="./mksysnum_linux.pl $unistd_h"
275	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
276	;;
277netbsd_386)
278	mkerrors="$mkerrors -m32"
279	mksyscall="./mksyscall.pl -l32 -netbsd"
280	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
281	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
282	;;
283netbsd_amd64)
284	mkerrors="$mkerrors -m64"
285	mksyscall="./mksyscall.pl -netbsd"
286	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
287	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
288	;;
289netbsd_arm)
290	mkerrors="$mkerrors -m32"
291	mksyscall="./mksyscall.pl -l32 -netbsd -arm"
292	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
293	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
294	;;
295netbsd_arm64)
296	mkerrors="$mkerrors -m64"
297	mksyscall="./mksyscall.pl -netbsd"
298	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
299	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
300	;;
301openbsd_386)
302	mkerrors="$mkerrors -m32"
303	mksyscall="./mksyscall.pl -l32 -openbsd"
304	mksysctl="./mksysctl_openbsd.pl"
305	zsysctl="zsysctl_openbsd.go"
306	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
307	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
308	;;
309openbsd_amd64)
310	mkerrors="$mkerrors -m64"
311	mksyscall="./mksyscall.pl -openbsd"
312	mksysctl="./mksysctl_openbsd.pl"
313	zsysctl="zsysctl_openbsd.go"
314	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
315	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
316	;;
317openbsd_arm)
318	mkerrors="$mkerrors"
319	mksyscall="./mksyscall.pl -l32 -openbsd -arm"
320	mksysctl="./mksysctl_openbsd.pl"
321	zsysctl="zsysctl_openbsd.go"
322	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
323	# Let the type of C char be signed to make the bare syscall
324	# API consistent between platforms.
325	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
326	;;
327openbsd_arm64)
328	mkerrors="$mkerrors -m64"
329	mksyscall="./mksyscall.pl -openbsd"
330	mksysctl="./mksysctl_openbsd.pl"
331	zsysctl="zsysctl_openbsd.go"
332	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
333	# Let the type of C char be signed to make the bare syscall
334	# API consistent between platforms.
335	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
336	;;
337plan9_386)
338	mkerrors=
339	mksyscall="./mksyscall.pl -l32 -plan9"
340	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
341	mktypes="XXX"
342	;;
343solaris_amd64)
344	mksyscall="./mksyscall_libc.pl -solaris"
345	mkerrors="$mkerrors -m64"
346	mksysnum=
347	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
348	;;
349windows_*)
350	echo 'run "go generate" instead' 1>&2
351	exit 1
352	;;
353*)
354	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
355	exit 1
356	;;
357esac
358
359(
360	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
361	syscall_goos="syscall_$GOOS.go"
362 	case "$GOOS" in
363	darwin | dragonfly | freebsd | netbsd | openbsd)
364		syscall_goos="syscall_bsd.go $syscall_goos"
365 		;;
366 	esac
367	if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
368	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
369	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
370	if [ -n "$mktypes" ]; then
371		# ztypes_$GOOSARCH.go could be erased before "go run mkpost.go" is called.
372		# Therefore, "go run" tries to recompile syscall package but ztypes is empty and it fails.
373		echo "$mktypes types_$GOOS.go |go run mkpost.go >ztypes_$GOOSARCH.go.NEW && mv ztypes_$GOOSARCH.go.NEW ztypes_$GOOSARCH.go";
374	fi
375	if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
376) | $run
377