Source file src/runtime/sys_openbsd.go

     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  package runtime
     6  
     7  import (
     8  	"internal/abi"
     9  	"internal/runtime/atomic"
    10  	"unsafe"
    11  )
    12  
    13  // The *_trampoline functions convert from the Go calling convention to the C calling convention
    14  // and then call the underlying libc function. These are defined in sys_openbsd_$ARCH.s.
    15  
    16  //go:nosplit
    17  //go:cgo_unsafe_args
    18  func pthread_attr_init(attr *pthreadattr) int32 {
    19  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
    20  	KeepAlive(attr)
    21  	return ret
    22  }
    23  func pthread_attr_init_trampoline()
    24  
    25  //go:nosplit
    26  //go:cgo_unsafe_args
    27  func pthread_attr_destroy(attr *pthreadattr) int32 {
    28  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_destroy_trampoline)), unsafe.Pointer(&attr))
    29  	KeepAlive(attr)
    30  	return ret
    31  }
    32  func pthread_attr_destroy_trampoline()
    33  
    34  //go:nosplit
    35  //go:cgo_unsafe_args
    36  func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
    37  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
    38  	KeepAlive(attr)
    39  	KeepAlive(size)
    40  	return ret
    41  }
    42  func pthread_attr_getstacksize_trampoline()
    43  
    44  //go:nosplit
    45  //go:cgo_unsafe_args
    46  func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
    47  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
    48  	KeepAlive(attr)
    49  	return ret
    50  }
    51  func pthread_attr_setdetachstate_trampoline()
    52  
    53  //go:nosplit
    54  //go:cgo_unsafe_args
    55  func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
    56  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
    57  	KeepAlive(attr)
    58  	KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
    59  	return ret
    60  }
    61  func pthread_create_trampoline()
    62  
    63  //go:nosplit
    64  //go:cgo_unsafe_args
    65  func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32 {
    66  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(thrsleep_trampoline)), unsafe.Pointer(&ident))
    67  	KeepAlive(tsp)
    68  	KeepAlive(abort)
    69  	return ret
    70  }
    71  func thrsleep_trampoline()
    72  
    73  //go:nosplit
    74  //go:cgo_unsafe_args
    75  func thrwakeup(ident uintptr, n int32) int32 {
    76  	return libcCall(unsafe.Pointer(abi.FuncPCABI0(thrwakeup_trampoline)), unsafe.Pointer(&ident))
    77  }
    78  func thrwakeup_trampoline()
    79  
    80  //go:nosplit
    81  func osyield() {
    82  	libcCall(unsafe.Pointer(abi.FuncPCABI0(sched_yield_trampoline)), unsafe.Pointer(nil))
    83  }
    84  func sched_yield_trampoline()
    85  
    86  //go:nosplit
    87  func osyield_no_g() {
    88  	asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sched_yield_trampoline)), unsafe.Pointer(nil))
    89  }
    90  
    91  // This is exported via linkname to assembly in runtime/cgo.
    92  //
    93  //go:linkname exit
    94  //go:nosplit
    95  //go:cgo_unsafe_args
    96  func exit(code int32) {
    97  	libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code))
    98  }
    99  func exit_trampoline()
   100  
   101  //go:nosplit
   102  //go:cgo_unsafe_args
   103  func getthrid() (tid int32) {
   104  	libcCall(unsafe.Pointer(abi.FuncPCABI0(getthrid_trampoline)), unsafe.Pointer(&tid))
   105  	return
   106  }
   107  func getthrid_trampoline()
   108  
   109  //go:nosplit
   110  //go:cgo_unsafe_args
   111  func raiseproc(sig uint32) {
   112  	libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig))
   113  }
   114  func raiseproc_trampoline()
   115  
   116  //go:nosplit
   117  //go:cgo_unsafe_args
   118  func thrkill(tid int32, sig int) {
   119  	libcCall(unsafe.Pointer(abi.FuncPCABI0(thrkill_trampoline)), unsafe.Pointer(&tid))
   120  }
   121  func thrkill_trampoline()
   122  
   123  // mmap is used to do low-level memory allocation via mmap. Don't allow stack
   124  // splits, since this function (used by sysAlloc) is called in a lot of low-level
   125  // parts of the runtime and callers often assume it won't acquire any locks.
   126  //
   127  //go:nosplit
   128  func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
   129  	args := struct {
   130  		addr            unsafe.Pointer
   131  		n               uintptr
   132  		prot, flags, fd int32
   133  		off             uint32
   134  		ret1            unsafe.Pointer
   135  		ret2            int
   136  	}{addr, n, prot, flags, fd, off, nil, 0}
   137  	libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args))
   138  	KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
   139  	return args.ret1, args.ret2
   140  }
   141  func mmap_trampoline()
   142  
   143  //go:nosplit
   144  //go:cgo_unsafe_args
   145  func munmap(addr unsafe.Pointer, n uintptr) {
   146  	libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
   147  	KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
   148  }
   149  func munmap_trampoline()
   150  
   151  //go:nosplit
   152  //go:cgo_unsafe_args
   153  func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
   154  	libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
   155  	KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
   156  }
   157  func madvise_trampoline()
   158  
   159  //go:nosplit
   160  //go:cgo_unsafe_args
   161  func open(name *byte, mode, perm int32) (ret int32) {
   162  	ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
   163  	KeepAlive(name)
   164  	return
   165  }
   166  func open_trampoline()
   167  
   168  //go:nosplit
   169  //go:cgo_unsafe_args
   170  func closefd(fd int32) int32 {
   171  	return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd))
   172  }
   173  func close_trampoline()
   174  
   175  //go:nosplit
   176  //go:cgo_unsafe_args
   177  func read(fd int32, p unsafe.Pointer, n int32) int32 {
   178  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
   179  	KeepAlive(p)
   180  	return ret
   181  }
   182  func read_trampoline()
   183  
   184  //go:nosplit
   185  //go:cgo_unsafe_args
   186  func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
   187  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
   188  	KeepAlive(p)
   189  	return ret
   190  }
   191  func write_trampoline()
   192  
   193  func pipe2(flags int32) (r, w int32, errno int32) {
   194  	var p [2]int32
   195  	args := struct {
   196  		p     unsafe.Pointer
   197  		flags int32
   198  	}{noescape(unsafe.Pointer(&p)), flags}
   199  	errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe2_trampoline)), unsafe.Pointer(&args))
   200  	return p[0], p[1], errno
   201  }
   202  func pipe2_trampoline()
   203  
   204  //go:nosplit
   205  //go:cgo_unsafe_args
   206  func setitimer(mode int32, new, old *itimerval) {
   207  	libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
   208  	KeepAlive(new)
   209  	KeepAlive(old)
   210  }
   211  func setitimer_trampoline()
   212  
   213  //go:nosplit
   214  //go:cgo_unsafe_args
   215  func usleep(usec uint32) {
   216  	libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
   217  }
   218  func usleep_trampoline()
   219  
   220  //go:nosplit
   221  //go:cgo_unsafe_args
   222  func usleep_no_g(usec uint32) {
   223  	asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
   224  }
   225  
   226  //go:nosplit
   227  //go:cgo_unsafe_args
   228  func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
   229  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
   230  	KeepAlive(mib)
   231  	KeepAlive(out)
   232  	KeepAlive(size)
   233  	KeepAlive(dst)
   234  	return ret
   235  }
   236  func sysctl_trampoline()
   237  
   238  //go:nosplit
   239  //go:cgo_unsafe_args
   240  func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
   241  	args := struct {
   242  		fd, cmd, arg int32
   243  		ret, errno   int32
   244  	}{fd, cmd, arg, 0, 0}
   245  	libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
   246  	return args.ret, args.errno
   247  }
   248  func fcntl_trampoline()
   249  
   250  //go:nosplit
   251  func nanotime1() int64 {
   252  	var ts timespec
   253  	args := struct {
   254  		clock_id int32
   255  		tp       unsafe.Pointer
   256  	}{_CLOCK_MONOTONIC, unsafe.Pointer(&ts)}
   257  	if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 {
   258  		// Avoid growing the nosplit stack.
   259  		systemstack(func() {
   260  			println("runtime: errno", -errno)
   261  			throw("clock_gettime failed")
   262  		})
   263  	}
   264  	return ts.tv_sec*1e9 + int64(ts.tv_nsec)
   265  }
   266  func clock_gettime_trampoline()
   267  
   268  //go:nosplit
   269  func walltime() (int64, int32) {
   270  	var ts timespec
   271  	args := struct {
   272  		clock_id int32
   273  		tp       unsafe.Pointer
   274  	}{_CLOCK_REALTIME, unsafe.Pointer(&ts)}
   275  	if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 {
   276  		// Avoid growing the nosplit stack.
   277  		systemstack(func() {
   278  			println("runtime: errno", -errno)
   279  			throw("clock_gettime failed")
   280  		})
   281  	}
   282  	return ts.tv_sec, int32(ts.tv_nsec)
   283  }
   284  
   285  //go:nosplit
   286  //go:cgo_unsafe_args
   287  func kqueue() int32 {
   288  	return libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil)
   289  }
   290  func kqueue_trampoline()
   291  
   292  //go:nosplit
   293  //go:cgo_unsafe_args
   294  func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
   295  	ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
   296  	KeepAlive(ch)
   297  	KeepAlive(ev)
   298  	KeepAlive(ts)
   299  	return ret
   300  }
   301  func kevent_trampoline()
   302  
   303  //go:nosplit
   304  //go:cgo_unsafe_args
   305  func sigaction(sig uint32, new *sigactiont, old *sigactiont) {
   306  	libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
   307  	KeepAlive(new)
   308  	KeepAlive(old)
   309  }
   310  func sigaction_trampoline()
   311  
   312  //go:nosplit
   313  //go:cgo_unsafe_args
   314  func sigprocmask(how uint32, new *sigset, old *sigset) {
   315  	// sigprocmask is called from sigsave, which is called from needm.
   316  	// As such, we have to be able to run with no g here.
   317  	asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
   318  	KeepAlive(new)
   319  	KeepAlive(old)
   320  }
   321  func sigprocmask_trampoline()
   322  
   323  //go:nosplit
   324  //go:cgo_unsafe_args
   325  func sigaltstack(new *stackt, old *stackt) {
   326  	libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
   327  	KeepAlive(new)
   328  	KeepAlive(old)
   329  }
   330  func sigaltstack_trampoline()
   331  
   332  // Not used on OpenBSD, but must be defined.
   333  func exitThread(wait *atomic.Uint32) {
   334  	throw("exitThread")
   335  }
   336  
   337  //go:nosplit
   338  //go:cgo_unsafe_args
   339  func issetugid() (ret int32) {
   340  	libcCall(unsafe.Pointer(abi.FuncPCABI0(issetugid_trampoline)), unsafe.Pointer(&ret))
   341  	return
   342  }
   343  func issetugid_trampoline()
   344  
   345  // The X versions of syscall expect the libc call to return a 64-bit result.
   346  // Otherwise (the non-X version) expects a 32-bit result.
   347  // This distinction is required because an error is indicated by returning -1,
   348  // and we need to know whether to check 32 or 64 bits of the result.
   349  // (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
   350  
   351  // golang.org/x/sys linknames syscall_syscall
   352  // (in addition to standard package syscall).
   353  // Do not remove or change the type signature.
   354  //
   355  //go:linkname syscall_syscall syscall.syscall
   356  //go:nosplit
   357  //go:cgo_unsafe_args
   358  func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   359  	entersyscall()
   360  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
   361  	exitsyscall()
   362  	return
   363  }
   364  func syscall()
   365  
   366  //go:linkname syscall_syscallX syscall.syscallX
   367  //go:nosplit
   368  //go:cgo_unsafe_args
   369  func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   370  	entersyscall()
   371  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&fn))
   372  	exitsyscall()
   373  	return
   374  }
   375  func syscallX()
   376  
   377  // golang.org/x/sys linknames syscall.syscall6
   378  // (in addition to standard package syscall).
   379  // Do not remove or change the type signature.
   380  //
   381  //go:linkname syscall_syscall6 syscall.syscall6
   382  //go:nosplit
   383  //go:cgo_unsafe_args
   384  func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
   385  	entersyscall()
   386  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
   387  	exitsyscall()
   388  	return
   389  }
   390  func syscall6()
   391  
   392  //go:linkname syscall_syscall6X syscall.syscall6X
   393  //go:nosplit
   394  //go:cgo_unsafe_args
   395  func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
   396  	entersyscall()
   397  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
   398  	exitsyscall()
   399  	return
   400  }
   401  func syscall6X()
   402  
   403  // golang.org/x/sys linknames syscall.syscall10
   404  // (in addition to standard package syscall).
   405  // Do not remove or change the type signature.
   406  //
   407  //go:linkname syscall_syscall10 syscall.syscall10
   408  //go:nosplit
   409  //go:cgo_unsafe_args
   410  func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
   411  	entersyscall()
   412  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10)), unsafe.Pointer(&fn))
   413  	exitsyscall()
   414  	return
   415  }
   416  func syscall10()
   417  
   418  //go:linkname syscall_syscall10X syscall.syscall10X
   419  //go:nosplit
   420  //go:cgo_unsafe_args
   421  func syscall_syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
   422  	entersyscall()
   423  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10X)), unsafe.Pointer(&fn))
   424  	exitsyscall()
   425  	return
   426  }
   427  func syscall10X()
   428  
   429  // golang.org/x/sys linknames syscall_rawSyscall
   430  // (in addition to standard package syscall).
   431  // Do not remove or change the type signature.
   432  //
   433  //go:linkname syscall_rawSyscall syscall.rawSyscall
   434  //go:nosplit
   435  //go:cgo_unsafe_args
   436  func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
   437  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
   438  	return
   439  }
   440  
   441  // golang.org/x/sys linknames syscall_rawSyscall6
   442  // (in addition to standard package syscall).
   443  // Do not remove or change the type signature.
   444  //
   445  //go:linkname syscall_rawSyscall6 syscall.rawSyscall6
   446  //go:nosplit
   447  //go:cgo_unsafe_args
   448  func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
   449  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
   450  	return
   451  }
   452  
   453  //go:linkname syscall_rawSyscall6X syscall.rawSyscall6X
   454  //go:nosplit
   455  //go:cgo_unsafe_args
   456  func syscall_rawSyscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
   457  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
   458  	return
   459  }
   460  
   461  //go:linkname syscall_rawSyscall10X syscall.rawSyscall10X
   462  //go:nosplit
   463  //go:cgo_unsafe_args
   464  func syscall_rawSyscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
   465  	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10X)), unsafe.Pointer(&fn))
   466  	return
   467  }
   468  
   469  // Tell the linker that the libc_* functions are to be found
   470  // in a system library, with the libc_ prefix missing.
   471  
   472  //go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "libpthread.so"
   473  //go:cgo_import_dynamic libc_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
   474  //go:cgo_import_dynamic libc_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
   475  //go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "libpthread.so"
   476  //go:cgo_import_dynamic libc_pthread_create pthread_create "libpthread.so"
   477  //go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "libpthread.so"
   478  
   479  //go:cgo_import_dynamic libc_thrsleep __thrsleep "libc.so"
   480  //go:cgo_import_dynamic libc_thrwakeup __thrwakeup "libc.so"
   481  //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
   482  
   483  //go:cgo_import_dynamic libc_errno __errno "libc.so"
   484  //go:cgo_import_dynamic libc_exit exit "libc.so"
   485  //go:cgo_import_dynamic libc_getthrid getthrid "libc.so"
   486  //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
   487  //go:cgo_import_dynamic libc_thrkill thrkill "libc.so"
   488  
   489  //go:cgo_import_dynamic libc_mmap mmap "libc.so"
   490  //go:cgo_import_dynamic libc_munmap munmap "libc.so"
   491  //go:cgo_import_dynamic libc_madvise madvise "libc.so"
   492  
   493  //go:cgo_import_dynamic libc_open open "libc.so"
   494  //go:cgo_import_dynamic libc_close close "libc.so"
   495  //go:cgo_import_dynamic libc_read read "libc.so"
   496  //go:cgo_import_dynamic libc_write write "libc.so"
   497  //go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
   498  
   499  //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so"
   500  //go:cgo_import_dynamic libc_setitimer setitimer "libc.so"
   501  //go:cgo_import_dynamic libc_usleep usleep "libc.so"
   502  //go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
   503  //go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
   504  //go:cgo_import_dynamic libc_getpid getpid "libc.so"
   505  //go:cgo_import_dynamic libc_kill kill "libc.so"
   506  //go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
   507  //go:cgo_import_dynamic libc_kevent kevent "libc.so"
   508  
   509  //go:cgo_import_dynamic libc_sigaction sigaction "libc.so"
   510  //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so"
   511  
   512  //go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
   513  
   514  //go:cgo_import_dynamic _ _ "libpthread.so"
   515  //go:cgo_import_dynamic _ _ "libc.so"
   516  

View as plain text