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
|
// 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_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_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_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_close syscall.close
//go:nosplit
func syscall_close(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_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
}
|