blob: ae1f334365bcea366f8e7a075199d71dd745560c [file] [log] [blame]
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +02001// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package runtime
6
7import "unsafe"
8
9var (
10 libc_chdir,
11 libc_chroot,
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020012 libc_execve,
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020013 libc_fcntl,
14 libc_forkx,
15 libc_gethostname,
Michael MacInnisf7befa42015-02-17 22:23:16 -050016 libc_getpid,
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020017 libc_ioctl,
18 libc_pipe,
19 libc_setgid,
20 libc_setgroups,
21 libc_setsid,
22 libc_setuid,
23 libc_setpgid,
24 libc_syscall,
25 libc_wait4,
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020026 pipe1 libcFunc
27)
28
29//go:nosplit
30func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
31 call := libcall{
Russ Cox6c59cdc2014-09-14 22:20:01 -040032 fn: fn,
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020033 n: nargs,
Russ Cox6c59cdc2014-09-14 22:20:01 -040034 args: uintptr(unsafe.Pointer(&a1)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020035 }
Aram Hăvărneanue088e162014-11-13 16:07:10 +010036 entersyscallblock(0)
Alex Brainman9d968cb2015-04-27 17:32:23 +100037 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanue088e162014-11-13 16:07:10 +010038 exitsyscall(0)
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020039 return call.r1, call.r2, call.err
40}
41
42//go:nosplit
43func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
44 call := libcall{
Russ Cox6c59cdc2014-09-14 22:20:01 -040045 fn: fn,
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020046 n: nargs,
Russ Cox6c59cdc2014-09-14 22:20:01 -040047 args: uintptr(unsafe.Pointer(&a1)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020048 }
Alex Brainman9d968cb2015-04-27 17:32:23 +100049 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020050 return call.r1, call.r2, call.err
51}
52
53// TODO(aram): Once we remove all instances of C calling sysvicallN, make
54// sysvicallN return errors and replace the body of the following functions
55// with calls to sysvicallN.
56
57//go:nosplit
58func syscall_chdir(path uintptr) (err uintptr) {
59 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +020060 fn: uintptr(unsafe.Pointer(&libc_chdir)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020061 n: 1,
Russ Cox6c59cdc2014-09-14 22:20:01 -040062 args: uintptr(unsafe.Pointer(&path)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020063 }
Alex Brainman9d968cb2015-04-27 17:32:23 +100064 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020065 return call.err
66}
67
68//go:nosplit
69func syscall_chroot(path uintptr) (err uintptr) {
70 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +020071 fn: uintptr(unsafe.Pointer(&libc_chroot)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020072 n: 1,
Russ Cox6c59cdc2014-09-14 22:20:01 -040073 args: uintptr(unsafe.Pointer(&path)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020074 }
Alex Brainman9d968cb2015-04-27 17:32:23 +100075 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020076 return call.err
77}
78
79// like close, but must not split stack, for forkx.
80//go:nosplit
81func syscall_close(fd int32) int32 {
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +020082 return int32(sysvicall1(&libc_close, uintptr(fd)))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020083}
84
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020085//go:nosplit
86func syscall_execve(path, argv, envp uintptr) (err uintptr) {
87 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +020088 fn: uintptr(unsafe.Pointer(&libc_execve)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020089 n: 3,
Russ Cox6c59cdc2014-09-14 22:20:01 -040090 args: uintptr(unsafe.Pointer(&path)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020091 }
Alex Brainman9d968cb2015-04-27 17:32:23 +100092 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +020093 return call.err
94}
95
96// like exit, but must not split stack, for forkx.
97//go:nosplit
98func syscall_exit(code uintptr) {
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +020099 sysvicall1(&libc_exit, code)
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200100}
101
102//go:nosplit
103func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
104 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200105 fn: uintptr(unsafe.Pointer(&libc_fcntl)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200106 n: 3,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400107 args: uintptr(unsafe.Pointer(&fd)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200108 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000109 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200110 return call.r1, call.err
111}
112
113//go:nosplit
114func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
115 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200116 fn: uintptr(unsafe.Pointer(&libc_forkx)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200117 n: 1,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400118 args: uintptr(unsafe.Pointer(&flags)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200119 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000120 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200121 return call.r1, call.err
122}
123
124func syscall_gethostname() (name string, err uintptr) {
125 cname := new([_MAXHOSTNAMELEN]byte)
126 var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN}
127 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200128 fn: uintptr(unsafe.Pointer(&libc_gethostname)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200129 n: 2,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400130 args: uintptr(unsafe.Pointer(&args[0])),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200131 }
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100132 entersyscallblock(0)
Alex Brainman9d968cb2015-04-27 17:32:23 +1000133 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100134 exitsyscall(0)
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200135 if call.r1 != 0 {
136 return "", call.err
137 }
138 cname[_MAXHOSTNAMELEN-1] = 0
139 return gostringnocopy(&cname[0]), 0
140}
141
142//go:nosplit
Michael MacInnisf7befa42015-02-17 22:23:16 -0500143func syscall_getpid() (pid, err uintptr) {
144 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200145 fn: uintptr(unsafe.Pointer(&libc_getpid)),
Michael MacInnisf7befa42015-02-17 22:23:16 -0500146 n: 0,
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200147 args: uintptr(unsafe.Pointer(&libc_getpid)), // it's unused but must be non-nil, otherwise crashes
Michael MacInnisf7befa42015-02-17 22:23:16 -0500148 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000149 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Michael MacInnisf7befa42015-02-17 22:23:16 -0500150 return call.r1, call.err
151}
152
153//go:nosplit
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200154func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
155 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200156 fn: uintptr(unsafe.Pointer(&libc_ioctl)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200157 n: 3,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400158 args: uintptr(unsafe.Pointer(&fd)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200159 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000160 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200161 return call.err
162}
163
164func syscall_pipe() (r, w, err uintptr) {
165 call := libcall{
Russ Cox6c59cdc2014-09-14 22:20:01 -0400166 fn: uintptr(unsafe.Pointer(&pipe1)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200167 n: 0,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400168 args: uintptr(unsafe.Pointer(&pipe1)), // it's unused but must be non-nil, otherwise crashes
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200169 }
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100170 entersyscallblock(0)
Alex Brainman9d968cb2015-04-27 17:32:23 +1000171 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100172 exitsyscall(0)
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200173 return call.r1, call.r2, call.err
174}
175
176// This is syscall.RawSyscall, it exists to satisfy some build dependency,
177// but it doesn't work correctly.
178//
179// DO NOT USE!
180//
181// TODO(aram): make this panic once we stop calling fcntl(2) in net using it.
182func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
183 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200184 fn: uintptr(unsafe.Pointer(&libc_syscall)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200185 n: 4,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400186 args: uintptr(unsafe.Pointer(&trap)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200187 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000188 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200189 return call.r1, call.r2, call.err
190}
191
192//go:nosplit
193func syscall_setgid(gid uintptr) (err uintptr) {
194 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200195 fn: uintptr(unsafe.Pointer(&libc_setgid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200196 n: 1,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400197 args: uintptr(unsafe.Pointer(&gid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200198 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000199 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200200 return call.err
201}
202
203//go:nosplit
204func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
205 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200206 fn: uintptr(unsafe.Pointer(&libc_setgroups)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200207 n: 2,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400208 args: uintptr(unsafe.Pointer(&ngid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200209 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000210 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200211 return call.err
212}
213
214//go:nosplit
215func syscall_setsid() (pid, err uintptr) {
216 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200217 fn: uintptr(unsafe.Pointer(&libc_setsid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200218 n: 0,
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200219 args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200220 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000221 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200222 return call.r1, call.err
223}
224
225//go:nosplit
226func syscall_setuid(uid uintptr) (err uintptr) {
227 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200228 fn: uintptr(unsafe.Pointer(&libc_setuid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200229 n: 1,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400230 args: uintptr(unsafe.Pointer(&uid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200231 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000232 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200233 return call.err
234}
235
236//go:nosplit
237func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
238 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200239 fn: uintptr(unsafe.Pointer(&libc_setpgid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200240 n: 2,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400241 args: uintptr(unsafe.Pointer(&pid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200242 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000243 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200244 return call.err
245}
246
247// This is syscall.Syscall, it exists to satisfy some build dependency,
248// but it doesn't work correctly.
249//
250// DO NOT USE!
251//
252// TODO(aram): make this panic once we stop calling fcntl(2) in net using it.
253func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
254 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200255 fn: uintptr(unsafe.Pointer(&libc_syscall)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200256 n: 4,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400257 args: uintptr(unsafe.Pointer(&trap)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200258 }
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100259 entersyscallblock(0)
Alex Brainman9d968cb2015-04-27 17:32:23 +1000260 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100261 exitsyscall(0)
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200262 return call.r1, call.r2, call.err
263}
264
265func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) {
266 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200267 fn: uintptr(unsafe.Pointer(&libc_wait4)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200268 n: 4,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400269 args: uintptr(unsafe.Pointer(&pid)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200270 }
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100271 entersyscallblock(0)
Alex Brainman9d968cb2015-04-27 17:32:23 +1000272 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanue088e162014-11-13 16:07:10 +0100273 exitsyscall(0)
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200274 return int(call.r1), call.err
275}
276
277//go:nosplit
278func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) {
279 call := libcall{
Aram Hăvărneanuc94f1f72015-03-30 13:52:07 +0200280 fn: uintptr(unsafe.Pointer(&libc_write)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200281 n: 3,
Russ Cox6c59cdc2014-09-14 22:20:01 -0400282 args: uintptr(unsafe.Pointer(&fd)),
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200283 }
Alex Brainman9d968cb2015-04-27 17:32:23 +1000284 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
Aram Hăvărneanub4c28d92014-09-06 19:35:46 +0200285 return call.r1, call.err
286}