Source file src/runtime/sys_openbsd2.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  //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"
   300  

View as plain text