github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/runtime/sys_openbsd2.go (about) 1 // Copyright 2020 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 //go:build openbsd && !mips64 6 7 package runtime 8 9 import ( 10 "internal/abi" 11 "unsafe" 12 ) 13 14 // This is exported via linkname to assembly in runtime/cgo. 15 //go:linkname exit 16 //go:nosplit 17 //go:cgo_unsafe_args 18 func exit(code int32) { 19 libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code)) 20 } 21 func exit_trampoline() 22 23 //go:nosplit 24 //go:cgo_unsafe_args 25 func getthrid() (tid int32) { 26 libcCall(unsafe.Pointer(abi.FuncPCABI0(getthrid_trampoline)), unsafe.Pointer(&tid)) 27 return 28 } 29 func getthrid_trampoline() 30 31 //go:nosplit 32 //go:cgo_unsafe_args 33 func raiseproc(sig uint32) { 34 libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig)) 35 } 36 func raiseproc_trampoline() 37 38 //go:nosplit 39 //go:cgo_unsafe_args 40 func thrkill(tid int32, sig int) { 41 libcCall(unsafe.Pointer(abi.FuncPCABI0(thrkill_trampoline)), unsafe.Pointer(&tid)) 42 } 43 func thrkill_trampoline() 44 45 // mmap is used to do low-level memory allocation via mmap. Don't allow stack 46 // splits, since this function (used by sysAlloc) is called in a lot of low-level 47 // parts of the runtime and callers often assume it won't acquire any locks. 48 //go:nosplit 49 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) { 50 args := struct { 51 addr unsafe.Pointer 52 n uintptr 53 prot, flags, fd int32 54 off uint32 55 ret1 unsafe.Pointer 56 ret2 int 57 }{addr, n, prot, flags, fd, off, nil, 0} 58 libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args)) 59 KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address. 60 return args.ret1, args.ret2 61 } 62 func mmap_trampoline() 63 64 //go:nosplit 65 //go:cgo_unsafe_args 66 func munmap(addr unsafe.Pointer, n uintptr) { 67 libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr)) 68 KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address. 69 } 70 func munmap_trampoline() 71 72 //go:nosplit 73 //go:cgo_unsafe_args 74 func madvise(addr unsafe.Pointer, n uintptr, flags int32) { 75 libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr)) 76 KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address. 77 } 78 func madvise_trampoline() 79 80 //go:nosplit 81 //go:cgo_unsafe_args 82 func open(name *byte, mode, perm int32) (ret int32) { 83 ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name)) 84 KeepAlive(name) 85 return 86 } 87 func open_trampoline() 88 89 //go:nosplit 90 //go:cgo_unsafe_args 91 func closefd(fd int32) int32 { 92 return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd)) 93 } 94 func close_trampoline() 95 96 //go:nosplit 97 //go:cgo_unsafe_args 98 func read(fd int32, p unsafe.Pointer, n int32) int32 { 99 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd)) 100 KeepAlive(p) 101 return ret 102 } 103 func read_trampoline() 104 105 //go:nosplit 106 //go:cgo_unsafe_args 107 func write1(fd uintptr, p unsafe.Pointer, n int32) int32 { 108 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd)) 109 KeepAlive(p) 110 return ret 111 } 112 func write_trampoline() 113 114 func pipe() (r, w int32, errno int32) { 115 return pipe2(0) 116 } 117 118 func pipe2(flags int32) (r, w int32, errno int32) { 119 var p [2]int32 120 args := struct { 121 p unsafe.Pointer 122 flags int32 123 }{noescape(unsafe.Pointer(&p)), flags} 124 errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe2_trampoline)), unsafe.Pointer(&args)) 125 return p[0], p[1], errno 126 } 127 func pipe2_trampoline() 128 129 //go:nosplit 130 //go:cgo_unsafe_args 131 func setitimer(mode int32, new, old *itimerval) { 132 libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode)) 133 KeepAlive(new) 134 KeepAlive(old) 135 } 136 func setitimer_trampoline() 137 138 //go:nosplit 139 //go:cgo_unsafe_args 140 func usleep(usec uint32) { 141 libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec)) 142 } 143 func usleep_trampoline() 144 145 //go:nosplit 146 //go:cgo_unsafe_args 147 func usleep_no_g(usec uint32) { 148 asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec)) 149 } 150 151 //go:nosplit 152 //go:cgo_unsafe_args 153 func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 { 154 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib)) 155 KeepAlive(mib) 156 KeepAlive(out) 157 KeepAlive(size) 158 KeepAlive(dst) 159 return ret 160 } 161 func sysctl_trampoline() 162 163 //go:nosplit 164 //go:cgo_unsafe_args 165 func fcntl(fd, cmd, arg int32) int32 { 166 return libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&fd)) 167 } 168 func fcntl_trampoline() 169 170 //go:nosplit 171 func nanotime1() int64 { 172 var ts timespec 173 args := struct { 174 clock_id int32 175 tp unsafe.Pointer 176 }{_CLOCK_MONOTONIC, unsafe.Pointer(&ts)} 177 if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 { 178 // Avoid growing the nosplit stack. 179 systemstack(func() { 180 println("runtime: errno", -errno) 181 throw("clock_gettime failed") 182 }) 183 } 184 return ts.tv_sec*1e9 + int64(ts.tv_nsec) 185 } 186 func clock_gettime_trampoline() 187 188 //go:nosplit 189 func walltime() (int64, int32) { 190 var ts timespec 191 args := struct { 192 clock_id int32 193 tp unsafe.Pointer 194 }{_CLOCK_REALTIME, unsafe.Pointer(&ts)} 195 if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 { 196 // Avoid growing the nosplit stack. 197 systemstack(func() { 198 println("runtime: errno", -errno) 199 throw("clock_gettime failed") 200 }) 201 } 202 return ts.tv_sec, int32(ts.tv_nsec) 203 } 204 205 //go:nosplit 206 //go:cgo_unsafe_args 207 func kqueue() int32 { 208 return libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil) 209 } 210 func kqueue_trampoline() 211 212 //go:nosplit 213 //go:cgo_unsafe_args 214 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 { 215 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq)) 216 KeepAlive(ch) 217 KeepAlive(ev) 218 KeepAlive(ts) 219 return ret 220 } 221 func kevent_trampoline() 222 223 //go:nosplit 224 //go:cgo_unsafe_args 225 func sigaction(sig uint32, new *sigactiont, old *sigactiont) { 226 libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig)) 227 KeepAlive(new) 228 KeepAlive(old) 229 } 230 func sigaction_trampoline() 231 232 //go:nosplit 233 //go:cgo_unsafe_args 234 func sigprocmask(how uint32, new *sigset, old *sigset) { 235 // sigprocmask is called from sigsave, which is called from needm. 236 // As such, we have to be able to run with no g here. 237 asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how)) 238 KeepAlive(new) 239 KeepAlive(old) 240 } 241 func sigprocmask_trampoline() 242 243 //go:nosplit 244 //go:cgo_unsafe_args 245 func sigaltstack(new *stackt, old *stackt) { 246 libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new)) 247 KeepAlive(new) 248 KeepAlive(old) 249 } 250 func sigaltstack_trampoline() 251 252 // Not used on OpenBSD, but must be defined. 253 func exitThread(wait *uint32) { 254 } 255 256 //go:nosplit 257 func closeonexec(fd int32) { 258 fcntl(fd, _F_SETFD, _FD_CLOEXEC) 259 } 260 261 //go:nosplit 262 func setNonblock(fd int32) { 263 flags := fcntl(fd, _F_GETFL, 0) 264 fcntl(fd, _F_SETFL, flags|_O_NONBLOCK) 265 } 266 267 // Tell the linker that the libc_* functions are to be found 268 // in a system library, with the libc_ prefix missing. 269 270 //go:cgo_import_dynamic libc_errno __errno "libc.so" 271 //go:cgo_import_dynamic libc_exit exit "libc.so" 272 //go:cgo_import_dynamic libc_getthrid getthrid "libc.so" 273 //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so" 274 //go:cgo_import_dynamic libc_thrkill thrkill "libc.so" 275 276 //go:cgo_import_dynamic libc_mmap mmap "libc.so" 277 //go:cgo_import_dynamic libc_munmap munmap "libc.so" 278 //go:cgo_import_dynamic libc_madvise madvise "libc.so" 279 280 //go:cgo_import_dynamic libc_open open "libc.so" 281 //go:cgo_import_dynamic libc_close close "libc.so" 282 //go:cgo_import_dynamic libc_read read "libc.so" 283 //go:cgo_import_dynamic libc_write write "libc.so" 284 //go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so" 285 286 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so" 287 //go:cgo_import_dynamic libc_setitimer setitimer "libc.so" 288 //go:cgo_import_dynamic libc_usleep usleep "libc.so" 289 //go:cgo_import_dynamic libc_sysctl sysctl "libc.so" 290 //go:cgo_import_dynamic libc_fcntl fcntl "libc.so" 291 //go:cgo_import_dynamic libc_getpid getpid "libc.so" 292 //go:cgo_import_dynamic libc_kill kill "libc.so" 293 //go:cgo_import_dynamic libc_kqueue kqueue "libc.so" 294 //go:cgo_import_dynamic libc_kevent kevent "libc.so" 295 296 //go:cgo_import_dynamic libc_sigaction sigaction "libc.so" 297 //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so" 298 299 //go:cgo_import_dynamic _ _ "libc.so"