1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import "unsafe"
// This file handles some syscalls from the syscall package
// Especially, syscalls use during forkAndExecInChild which must not split the stack
//go:cgo_import_dynamic libc_chdir chdir "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_chroot chroot "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_dup2 dup2 "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_execve execve "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_fcntl fcntl "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_fork fork "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_ioctl ioctl "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_setgid setgid "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_setgroups setgroups "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_setsid setsid "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_setuid setuid "libc.a/shr_64.o"
//go:cgo_import_dynamic libc_setpgid setpgid "libc.a/shr_64.o"
//go:linkname libc_chdir libc_chdir
//go:linkname libc_chroot libc_chroot
//go:linkname libc_dup2 libc_dup2
//go:linkname libc_execve libc_execve
//go:linkname libc_fcntl libc_fcntl
//go:linkname libc_fork libc_fork
//go:linkname libc_ioctl libc_ioctl
//go:linkname libc_setgid libc_setgid
//go:linkname libc_setgroups libc_setgroups
//go:linkname libc_setrlimit libc_setrlimit
//go:linkname libc_setsid libc_setsid
//go:linkname libc_setuid libc_setuid
//go:linkname libc_setpgid libc_setpgid
var (
libc_chdir,
libc_chroot,
libc_dup2,
libc_execve,
libc_fcntl,
libc_fork,
libc_ioctl,
libc_setgid,
libc_setgroups,
libc_setrlimit,
libc_setsid,
libc_setuid,
libc_setpgid libFunc
)
// In syscall_syscall6 and syscall_rawsyscall6, r2 is always 0
// as it's never used on AIX
// TODO: remove r2 from zsyscall_aix_$GOARCH.go
// Syscall is needed because some packages (like net) need it too.
// The best way is to return EINVAL and let Golang handles its failure
// If the syscall can't fail, this function can redirect it to a real syscall.
//
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit
//go:linkname syscall_Syscall
func syscall_Syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
return 0, 0, _EINVAL
}
// This is syscall.RawSyscall, it exists to satisfy some build dependency,
// but it doesn't work.
//
// This is exported via linkname to assembly in the syscall package.
//
//go:linkname syscall_RawSyscall
func syscall_RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
panic("RawSyscall not available on AIX")
}
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit
//go:cgo_unsafe_args
//go:linkname syscall_syscall6
func syscall_syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
c := libcall{
fn: fn,
n: nargs,
args: uintptr(unsafe.Pointer(&a1)),
}
entersyscallblock()
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))
exitsyscall()
return c.r1, 0, c.err
}
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit
//go:cgo_unsafe_args
//go:linkname syscall_rawSyscall6
func syscall_rawSyscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
c := libcall{
fn: fn,
n: nargs,
args: uintptr(unsafe.Pointer(&a1)),
}
asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))
return c.r1, 0, c.err
}
//go:linkname syscall_chdir syscall.chdir
//go:nosplit
func syscall_chdir(path uintptr) (err uintptr) {
_, err = syscall1(&libc_chdir, path)
return
}
//go:linkname syscall_chroot1 syscall.chroot1
//go:nosplit
func syscall_chroot1(path uintptr) (err uintptr) {
_, err = syscall1(&libc_chroot, path)
return
}
// like close, but must not split stack, for fork.
//
//go:linkname syscall_closeFD syscall.closeFD
//go:nosplit
func syscall_closeFD(fd int32) int32 {
_, err := syscall1(&libc_close, uintptr(fd))
return int32(err)
}
//go:linkname syscall_dup2child syscall.dup2child
//go:nosplit
func syscall_dup2child(old, new uintptr) (val, err uintptr) {
val, err = syscall2(&libc_dup2, old, new)
return
}
//go:linkname syscall_execve syscall.execve
//go:nosplit
func syscall_execve(path, argv, envp uintptr) (err uintptr) {
_, err = syscall3(&libc_execve, path, argv, envp)
return
}
// like exit, but must not split stack, for fork.
//
//go:linkname syscall_exit syscall.exit
//go:nosplit
func syscall_exit(code uintptr) {
syscall1(&libc_exit, code)
}
//go:linkname syscall_fcntl1 syscall.fcntl1
//go:nosplit
func syscall_fcntl1(fd, cmd, arg uintptr) (val, err uintptr) {
val, err = syscall3(&libc_fcntl, fd, cmd, arg)
return
}
//go:linkname syscall_forkx syscall.forkx
//go:nosplit
func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
pid, err = syscall1(&libc_fork, flags)
return
}
//go:linkname syscall_getpid syscall.getpid
//go:nosplit
func syscall_getpid() (pid, err uintptr) {
pid, err = syscall0(&libc_getpid)
return
}
//go:linkname syscall_ioctl syscall.ioctl
//go:nosplit
func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
_, err = syscall3(&libc_ioctl, fd, req, arg)
return
}
//go:linkname syscall_setgid syscall.setgid
//go:nosplit
func syscall_setgid(gid uintptr) (err uintptr) {
_, err = syscall1(&libc_setgid, gid)
return
}
//go:linkname syscall_setgroups1 syscall.setgroups1
//go:nosplit
func syscall_setgroups1(ngid, gid uintptr) (err uintptr) {
_, err = syscall2(&libc_setgroups, ngid, gid)
return
}
//go:linkname syscall_setrlimit1 syscall.setrlimit1
//go:nosplit
func syscall_setrlimit1(which uintptr, lim unsafe.Pointer) (err uintptr) {
_, err = syscall2(&libc_setrlimit, which, uintptr(lim))
return
}
//go:linkname syscall_setsid syscall.setsid
//go:nosplit
func syscall_setsid() (pid, err uintptr) {
pid, err = syscall0(&libc_setsid)
return
}
//go:linkname syscall_setuid syscall.setuid
//go:nosplit
func syscall_setuid(uid uintptr) (err uintptr) {
_, err = syscall1(&libc_setuid, uid)
return
}
//go:linkname syscall_setpgid syscall.setpgid
//go:nosplit
func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
_, err = syscall2(&libc_setpgid, pid, pgid)
return
}
//go:linkname syscall_write1 syscall.write1
//go:nosplit
func syscall_write1(fd, buf, nbyte uintptr) (n, err uintptr) {
n, err = syscall3(&libc_write, fd, buf, nbyte)
return
}
|