1 // 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 5 package runtime 6 7 import "unsafe" 8 9 var ( 10 libc_chdir, 11 libc_chroot, 12 libc_execve, 13 libc_fcntl, 14 libc_forkx, 15 libc_gethostname, 16 libc_getpid, 17 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, 26 pipe1 libcFunc 27 ) 28 29 //go:nosplit 30 func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { 31 call := libcall{ 32 fn: fn, 33 n: nargs, 34 args: uintptr(unsafe.Pointer(&a1)), 35 } 36 entersyscallblock(0) 37 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 38 exitsyscall(0) 39 return call.r1, call.r2, call.err 40 } 41 42 //go:nosplit 43 func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { 44 call := libcall{ 45 fn: fn, 46 n: nargs, 47 args: uintptr(unsafe.Pointer(&a1)), 48 } 49 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 50 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 58 func syscall_chdir(path uintptr) (err uintptr) { 59 call := libcall{ 60 fn: uintptr(unsafe.Pointer(&libc_chdir)), 61 n: 1, 62 args: uintptr(unsafe.Pointer(&path)), 63 } 64 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 65 return call.err 66 } 67 68 //go:nosplit 69 func syscall_chroot(path uintptr) (err uintptr) { 70 call := libcall{ 71 fn: uintptr(unsafe.Pointer(&libc_chroot)), 72 n: 1, 73 args: uintptr(unsafe.Pointer(&path)), 74 } 75 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 76 return call.err 77 } 78 79 // like close, but must not split stack, for forkx. 80 //go:nosplit 81 func syscall_close(fd int32) int32 { 82 return int32(sysvicall1(&libc_close, uintptr(fd))) 83 } 84 85 //go:nosplit 86 func syscall_execve(path, argv, envp uintptr) (err uintptr) { 87 call := libcall{ 88 fn: uintptr(unsafe.Pointer(&libc_execve)), 89 n: 3, 90 args: uintptr(unsafe.Pointer(&path)), 91 } 92 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 93 return call.err 94 } 95 96 // like exit, but must not split stack, for forkx. 97 //go:nosplit 98 func syscall_exit(code uintptr) { 99 sysvicall1(&libc_exit, code) 100 } 101 102 //go:nosplit 103 func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) { 104 call := libcall{ 105 fn: uintptr(unsafe.Pointer(&libc_fcntl)), 106 n: 3, 107 args: uintptr(unsafe.Pointer(&fd)), 108 } 109 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 110 return call.r1, call.err 111 } 112 113 //go:nosplit 114 func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) { 115 call := libcall{ 116 fn: uintptr(unsafe.Pointer(&libc_forkx)), 117 n: 1, 118 args: uintptr(unsafe.Pointer(&flags)), 119 } 120 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 121 return call.r1, call.err 122 } 123 124 func 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{ 128 fn: uintptr(unsafe.Pointer(&libc_gethostname)), 129 n: 2, 130 args: uintptr(unsafe.Pointer(&args[0])), 131 } 132 entersyscallblock(0) 133 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 134 exitsyscall(0) 135 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 143 func syscall_getpid() (pid, err uintptr) { 144 call := libcall{ 145 fn: uintptr(unsafe.Pointer(&libc_getpid)), 146 n: 0, 147 args: uintptr(unsafe.Pointer(&libc_getpid)), // it's unused but must be non-nil, otherwise crashes 148 } 149 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 150 return call.r1, call.err 151 } 152 153 //go:nosplit 154 func syscall_ioctl(fd, req, arg uintptr) (err uintptr) { 155 call := libcall{ 156 fn: uintptr(unsafe.Pointer(&libc_ioctl)), 157 n: 3, 158 args: uintptr(unsafe.Pointer(&fd)), 159 } 160 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 161 return call.err 162 } 163 164 func syscall_pipe() (r, w, err uintptr) { 165 call := libcall{ 166 fn: uintptr(unsafe.Pointer(&pipe1)), 167 n: 0, 168 args: uintptr(unsafe.Pointer(&pipe1)), // it's unused but must be non-nil, otherwise crashes 169 } 170 entersyscallblock(0) 171 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 172 exitsyscall(0) 173 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. 182 func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { 183 call := libcall{ 184 fn: uintptr(unsafe.Pointer(&libc_syscall)), 185 n: 4, 186 args: uintptr(unsafe.Pointer(&trap)), 187 } 188 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 189 return call.r1, call.r2, call.err 190 } 191 192 //go:nosplit 193 func syscall_setgid(gid uintptr) (err uintptr) { 194 call := libcall{ 195 fn: uintptr(unsafe.Pointer(&libc_setgid)), 196 n: 1, 197 args: uintptr(unsafe.Pointer(&gid)), 198 } 199 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 200 return call.err 201 } 202 203 //go:nosplit 204 func syscall_setgroups(ngid, gid uintptr) (err uintptr) { 205 call := libcall{ 206 fn: uintptr(unsafe.Pointer(&libc_setgroups)), 207 n: 2, 208 args: uintptr(unsafe.Pointer(&ngid)), 209 } 210 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 211 return call.err 212 } 213 214 //go:nosplit 215 func syscall_setsid() (pid, err uintptr) { 216 call := libcall{ 217 fn: uintptr(unsafe.Pointer(&libc_setsid)), 218 n: 0, 219 args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes 220 } 221 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 222 return call.r1, call.err 223 } 224 225 //go:nosplit 226 func syscall_setuid(uid uintptr) (err uintptr) { 227 call := libcall{ 228 fn: uintptr(unsafe.Pointer(&libc_setuid)), 229 n: 1, 230 args: uintptr(unsafe.Pointer(&uid)), 231 } 232 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 233 return call.err 234 } 235 236 //go:nosplit 237 func syscall_setpgid(pid, pgid uintptr) (err uintptr) { 238 call := libcall{ 239 fn: uintptr(unsafe.Pointer(&libc_setpgid)), 240 n: 2, 241 args: uintptr(unsafe.Pointer(&pid)), 242 } 243 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 244 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. 253 func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { 254 call := libcall{ 255 fn: uintptr(unsafe.Pointer(&libc_syscall)), 256 n: 4, 257 args: uintptr(unsafe.Pointer(&trap)), 258 } 259 entersyscallblock(0) 260 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 261 exitsyscall(0) 262 return call.r1, call.r2, call.err 263 } 264 265 func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) { 266 call := libcall{ 267 fn: uintptr(unsafe.Pointer(&libc_wait4)), 268 n: 4, 269 args: uintptr(unsafe.Pointer(&pid)), 270 } 271 entersyscallblock(0) 272 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 273 exitsyscall(0) 274 return int(call.r1), call.err 275 } 276 277 //go:nosplit 278 func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) { 279 call := libcall{ 280 fn: uintptr(unsafe.Pointer(&libc_write)), 281 n: 3, 282 args: uintptr(unsafe.Pointer(&fd)), 283 } 284 asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) 285 return call.r1, call.err 286 } 287