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	shift
92	for i in ${@:-zsyscall*go}
93	do
94		# Run the command line that appears in the first line
95		# of the generated file to regenerate it.
96		sed 1q $i | sed 's;^// ;./;' | sh > _$i && gofmt < _$i > $i
97		rm _$i
98	done
99	exit 0
100	;;
101-n)
102	run="cat"
103	shift
104esac
105
106case "$#" in
1070)
108	;;
109*)
110	echo 'usage: mkall.sh [-n]' 1>&2
111	exit 2
112esac
113
114GOOSARCH_in=syscall_$GOOSARCH.go
115case "$GOOSARCH" in
116_* | *_ | _)
117	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
118	exit 1
119	;;
120aix_ppc64)
121	mkerrors="$mkerrors -maix64"
122	mksyscall="./mksyscall_libc.pl -aix"
123	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
124	;;
125darwin_amd64)
126	mkerrors="$mkerrors -m64"
127	mksyscall="./mksyscall.pl -darwin"
128	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
129	mkasm="go run mkasm.go"
130	;;
131darwin_arm64)
132	mkerrors="$mkerrors -m64"
133	mksyscall="./mksyscall.pl -darwin"
134	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
135	mkasm="go run mkasm.go"
136	;;
137dragonfly_amd64)
138	mkerrors="$mkerrors -m64"
139	mksyscall="./mksyscall.pl -dragonfly"
140	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
141	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
142	;;
143freebsd_386)
144	mkerrors="$mkerrors -m32"
145	mksyscall="./mksyscall.pl -l32"
146	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
147	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
148	;;
149freebsd_amd64)
150	mkerrors="$mkerrors -m64"
151	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
152	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
153	;;
154freebsd_arm)
155	mkerrors="$mkerrors"
156	mksyscall="./mksyscall.pl -l32 -arm"
157	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
158	# Let the type of C char be signed to make the bare syscall
159	# API consistent between platforms.
160	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
161	;;
162freebsd_arm64)
163	mkerrors="$mkerrors"
164	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
165	# Let the type of C char be signed to make the bare syscall
166	# API consistent between platforms.
167	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
168	;;
169freebsd_riscv64)
170	mkerrors="$mkerrors"
171	mksysnum="curl -s 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12' | ./mksysnum_freebsd.pl"
172	# Let the type of C char be signed to make the bare syscall
173	# API consistent between platforms.
174	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
175	;;
176linux_386)
177	mkerrors="$mkerrors -m32"
178	mksyscall="./mksyscall.pl -l32"
179	mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_32.h"
180	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
181	;;
182linux_amd64)
183	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)
184	if [ "$unistd_h" = "" ]; then
185		echo >&2 cannot find unistd_64.h
186		exit 1
187	fi
188	mkerrors="$mkerrors -m64"
189	mksysnum="./mksysnum_linux.pl $unistd_h"
190	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
191	;;
192linux_arm)
193	GOOSARCH_in="syscall_linux_arm.go syscall_linux_accept.go"
194	mkerrors="$mkerrors"
195	mksyscall="./mksyscall.pl -l32 -arm"
196	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 -"
197	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
198	;;
199linux_arm64)
200	unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
201	if [ "$unistd_h" = "" ]; then
202		echo >&2 cannot find unistd_64.h
203		exit 1
204	fi
205	mksysnum="./mksysnum_linux.pl $unistd_h"
206	# Let the type of C char be signed to make the bare syscall
207	# API consistent between platforms.
208	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
209	;;
210linux_loong64)
211        GOOSARCH_in=syscall_linux_loong64.go
212        unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
213        if [ "$unistd_h" = "" ]; then
214                echo >&2 cannot find unistd.h
215                exit 1
216        fi
217        mksysnum="./mksysnum_linux.pl $unistd_h"
218        mktypes="GOARCH=$GOARCH go tool cgo -godefs"
219        ;;
220linux_mips)
221	GOOSARCH_in=syscall_linux_mipsx.go
222	unistd_h=/usr/include/asm/unistd.h
223	mksyscall="./mksyscall.pl -b32 -arm"
224	mkerrors="$mkerrors"
225	mksysnum="./mksysnum_linux.pl $unistd_h"
226	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
227	;;
228linux_mipsle)
229	GOOSARCH_in=syscall_linux_mipsx.go
230	unistd_h=/usr/include/asm/unistd.h
231	mksyscall="./mksyscall.pl -l32 -arm"
232	mkerrors="$mkerrors"
233	mksysnum="./mksysnum_linux.pl $unistd_h"
234	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
235	;;
236linux_mips64)
237	GOOSARCH_in=syscall_linux_mips64x.go
238	unistd_h=/usr/include/asm/unistd.h
239	mkerrors="$mkerrors -m64"
240	mksysnum="./mksysnum_linux.pl $unistd_h"
241	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
242	;;
243linux_mips64le)
244	GOOSARCH_in=syscall_linux_mips64x.go
245	unistd_h=/usr/include/asm/unistd.h
246	mkerrors="$mkerrors -m64"
247	mksysnum="./mksysnum_linux.pl $unistd_h"
248	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
249	;;
250linux_ppc64)
251	GOOSARCH_in=syscall_linux_ppc64x.go
252	unistd_h=/usr/include/asm/unistd.h
253	mkerrors="$mkerrors -m64"
254	mksysnum="./mksysnum_linux.pl $unistd_h"
255	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
256	;;
257linux_ppc64le)
258	GOOSARCH_in=syscall_linux_ppc64x.go
259	unistd_h=/usr/include/powerpc64le-linux-gnu/asm/unistd.h
260	mkerrors="$mkerrors -m64"
261	mksysnum="./mksysnum_linux.pl $unistd_h"
262	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
263	;;
264linux_riscv64)
265	unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
266	if [ "$unistd_h" = "" ]; then
267		echo >&2 cannot find unistd_64.h
268		exit 1
269	fi
270	mksysnum="./mksysnum_linux.pl $unistd_h"
271	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
272	;;
273linux_s390x)
274	GOOSARCH_in=syscall_linux_s390x.go
275	unistd_h=/usr/include/asm/unistd.h
276	mkerrors="$mkerrors -m64"
277	mksysnum="./mksysnum_linux.pl $unistd_h"
278	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
279	;;
280netbsd_386)
281	mkerrors="$mkerrors -m32"
282	mksyscall="./mksyscall.pl -l32 -netbsd"
283	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
284	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
285	;;
286netbsd_amd64)
287	mkerrors="$mkerrors -m64"
288	mksyscall="./mksyscall.pl -netbsd"
289	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
290	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
291	;;
292netbsd_arm)
293	mkerrors="$mkerrors -m32"
294	mksyscall="./mksyscall.pl -l32 -netbsd -arm"
295	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
296	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
297	;;
298netbsd_arm64)
299	mkerrors="$mkerrors -m64"
300	mksyscall="./mksyscall.pl -netbsd"
301	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
302	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
303	;;
304openbsd_386)
305	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
306	mkerrors="$mkerrors -m32"
307	mksyscall="./mksyscall.pl -l32 -openbsd -libc"
308	mksysctl="./mksysctl_openbsd.pl"
309	zsysctl="zsysctl_openbsd.go"
310	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
311	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
312	mkasm="go run mkasm.go"
313	;;
314openbsd_amd64)
315	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
316	mkerrors="$mkerrors -m64"
317	mksyscall="./mksyscall.pl -openbsd -libc"
318	mksysctl="./mksysctl_openbsd.pl"
319	zsysctl="zsysctl_openbsd.go"
320	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
321	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
322	mkasm="go run mkasm.go"
323	;;
324openbsd_arm)
325	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
326	mkerrors="$mkerrors"
327	mksyscall="./mksyscall.pl -l32 -openbsd -arm -libc"
328	mksysctl="./mksysctl_openbsd.pl"
329	zsysctl="zsysctl_openbsd.go"
330	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
331	# Let the type of C char be signed to make the bare syscall
332	# API consistent between platforms.
333	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
334	mkasm="go run mkasm.go"
335	;;
336openbsd_arm64)
337	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
338	mkerrors="$mkerrors -m64"
339	mksyscall="./mksyscall.pl -openbsd -libc"
340	mksysctl="./mksysctl_openbsd.pl"
341	zsysctl="zsysctl_openbsd.go"
342	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
343	# Let the type of C char be signed to make the bare syscall
344	# API consistent between platforms.
345	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
346	mkasm="go run mkasm.go"
347	;;
348openbsd_mips64)
349	GOOSARCH_in="syscall_openbsd1.go syscall_openbsd_$GOARCH.go"
350	mkerrors="$mkerrors -m64"
351	mksyscall="./mksyscall.pl -openbsd"
352	mksysctl="./mksysctl_openbsd.pl"
353	zsysctl="zsysctl_openbsd.go"
354	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
355	# Let the type of C char be signed to make the bare syscall
356	# API consistent between platforms.
357	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
358	;;
359openbsd_ppc64)
360	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
361	mkerrors="$mkerrors -m64"
362	mksyscall="./mksyscall.pl -openbsd -libc"
363	mksysctl="./mksysctl_openbsd.pl"
364	zsysctl="zsysctl_openbsd.go"
365	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
366	# Let the type of C char be signed to make the bare syscall
367	# API consistent between platforms.
368	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
369	mkasm="go run mkasm.go"
370	;;
371openbsd_riscv64)
372	GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
373	mkerrors="$mkerrors -m64"
374	mksyscall="./mksyscall.pl -openbsd -libc"
375	mksysctl="./mksysctl_openbsd.pl"
376	zsysctl="zsysctl_openbsd.go"
377	mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
378	# Let the type of C char be signed to make the bare syscall
379	# API consistent between platforms.
380	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
381	mkasm="go run mkasm.go"
382	;;
383plan9_386)
384	mkerrors=
385	mksyscall="./mksyscall.pl -l32 -plan9"
386	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
387	mktypes="XXX"
388	;;
389solaris_amd64)
390	mksyscall="./mksyscall_libc.pl -solaris"
391	mkerrors="$mkerrors -m64"
392	mksysnum=
393	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
394	;;
395windows_*)
396	echo 'run "go generate" instead' 1>&2
397	exit 1
398	;;
399*)
400	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
401	exit 1
402	;;
403esac
404
405(
406	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
407	syscall_goos="syscall_$GOOS.go"
408 	case "$GOOS" in
409	darwin | dragonfly | freebsd | netbsd | openbsd)
410		syscall_goos="syscall_bsd.go $syscall_goos"
411 		;;
412 	esac
413	if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
414	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
415	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
416	if [ -n "$mktypes" ]; then
417		# ztypes_$GOOSARCH.go could be erased before "go run mkpost.go" is called.
418		# Therefore, "go run" tries to recompile syscall package but ztypes is empty and it fails.
419		echo "$mktypes types_$GOOS.go |go run mkpost.go >ztypes_$GOOSARCH.go.NEW && mv ztypes_$GOOSARCH.go.NEW ztypes_$GOOSARCH.go";
420	fi
421	if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
422) | $run
423