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