runtime: remove openbsd/mips64 related code

The openbsd/mips64 port has been broken for many years and it has not
been possible to land the changes needed to unbreak it. As such, this
port is considered dead and can be decommissioned in order to remove
technical debt and allow other changes to be completed.

Updates #61546

Change-Id: I9680eab9fb3aa85b83de47c66e9ebaf8c388a3bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/649659
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Freeman <mark@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Joel Sing 2025-02-15 19:34:08 +11:00 committed by Gopher Robot
parent 64ba72474d
commit d5dc36af45
18 changed files with 493 additions and 1411 deletions

View file

@ -65,7 +65,7 @@ func TestCrashDumpsAllThreads(t *testing.T) {
t.Skipf("skipping; not supported on %v", runtime.GOOS) t.Skipf("skipping; not supported on %v", runtime.GOOS)
} }
if runtime.GOOS == "openbsd" && (runtime.GOARCH == "arm" || runtime.GOARCH == "mips64" || runtime.GOARCH == "ppc64") { if runtime.GOOS == "openbsd" && (runtime.GOARCH == "arm" || runtime.GOARCH == "ppc64") {
// This may be ncpu < 2 related... // This may be ncpu < 2 related...
t.Skipf("skipping; test fails on %s/%s - see issue #42464", runtime.GOOS, runtime.GOARCH) t.Skipf("skipping; test fails on %s/%s - see issue #42464", runtime.GOOS, runtime.GOARCH)
} }

View file

@ -11,7 +11,6 @@ GOARCH=amd64 go tool cgo -godefs defs_openbsd.go
GOARCH=386 go tool cgo -godefs defs_openbsd.go GOARCH=386 go tool cgo -godefs defs_openbsd.go
GOARCH=arm go tool cgo -godefs defs_openbsd.go GOARCH=arm go tool cgo -godefs defs_openbsd.go
GOARCH=arm64 go tool cgo -godefs defs_openbsd.go GOARCH=arm64 go tool cgo -godefs defs_openbsd.go
GOARCH=mips64 go tool cgo -godefs defs_openbsd.go
*/ */
package runtime package runtime

View file

@ -1,171 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Generated from:
//
// GOARCH=mips64 go tool cgo -godefs defs_openbsd.go
//
// Then converted to the form used by the runtime.
package runtime
import "unsafe"
const (
_EINTR = 0x4
_EFAULT = 0xe
_EAGAIN = 0x23
_ETIMEDOUT = 0x3c
_O_WRONLY = 0x1
_O_NONBLOCK = 0x4
_O_CREAT = 0x200
_O_TRUNC = 0x400
_O_CLOEXEC = 0x10000
_PROT_NONE = 0x0
_PROT_READ = 0x1
_PROT_WRITE = 0x2
_PROT_EXEC = 0x4
_MAP_ANON = 0x1000
_MAP_PRIVATE = 0x2
_MAP_FIXED = 0x10
_MAP_STACK = 0x4000
_MADV_DONTNEED = 0x4
_MADV_FREE = 0x6
_SA_SIGINFO = 0x40
_SA_RESTART = 0x2
_SA_ONSTACK = 0x1
_SIGHUP = 0x1
_SIGINT = 0x2
_SIGQUIT = 0x3
_SIGILL = 0x4
_SIGTRAP = 0x5
_SIGABRT = 0x6
_SIGEMT = 0x7
_SIGFPE = 0x8
_SIGKILL = 0x9
_SIGBUS = 0xa
_SIGSEGV = 0xb
_SIGSYS = 0xc
_SIGPIPE = 0xd
_SIGALRM = 0xe
_SIGTERM = 0xf
_SIGURG = 0x10
_SIGSTOP = 0x11
_SIGTSTP = 0x12
_SIGCONT = 0x13
_SIGCHLD = 0x14
_SIGTTIN = 0x15
_SIGTTOU = 0x16
_SIGIO = 0x17
_SIGXCPU = 0x18
_SIGXFSZ = 0x19
_SIGVTALRM = 0x1a
_SIGPROF = 0x1b
_SIGWINCH = 0x1c
_SIGINFO = 0x1d
_SIGUSR1 = 0x1e
_SIGUSR2 = 0x1f
_FPE_INTDIV = 0x1
_FPE_INTOVF = 0x2
_FPE_FLTDIV = 0x3
_FPE_FLTOVF = 0x4
_FPE_FLTUND = 0x5
_FPE_FLTRES = 0x6
_FPE_FLTINV = 0x7
_FPE_FLTSUB = 0x8
_BUS_ADRALN = 0x1
_BUS_ADRERR = 0x2
_BUS_OBJERR = 0x3
_SEGV_MAPERR = 0x1
_SEGV_ACCERR = 0x2
_ITIMER_REAL = 0x0
_ITIMER_VIRTUAL = 0x1
_ITIMER_PROF = 0x2
_EV_ADD = 0x1
_EV_DELETE = 0x2
_EV_CLEAR = 0x20
_EV_ERROR = 0x4000
_EV_EOF = 0x8000
_EVFILT_READ = -0x1
_EVFILT_WRITE = -0x2
)
type tforkt struct {
tf_tcb unsafe.Pointer
tf_tid *int32
tf_stack uintptr
}
type sigcontext struct {
sc_cookie uint64
sc_mask uint64
sc_pc uint64
sc_regs [32]uint64
mullo uint64
mulhi uint64
sc_fpregs [33]uint64
sc_fpused uint64
sc_fpc_eir uint64
_xxx [8]int64
}
type siginfo struct {
si_signo int32
si_code int32
si_errno int32
pad_cgo_0 [4]byte
_data [120]byte
}
type stackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}
type timespec struct {
tv_sec int64
tv_nsec int64
}
//go:nosplit
func (ts *timespec) setNsec(ns int64) {
ts.tv_sec = ns / 1e9
ts.tv_nsec = ns % 1e9
}
type timeval struct {
tv_sec int64
tv_usec int64
}
func (tv *timeval) set_usec(x int32) {
tv.tv_usec = int64(x)
}
type itimerval struct {
it_interval timeval
it_value timeval
}
type keventt struct {
ident uint64
filter int16
flags uint16
fflags uint32
data int64
udata *byte
}

View file

@ -134,6 +134,54 @@ func semawakeup(mp *m) {
} }
} }
// mstart_stub provides glue code to call mstart from pthread_create.
func mstart_stub()
// May run with m.p==nil, so write barriers are not allowed.
//
//go:nowritebarrierrec
func newosproc(mp *m) {
if false {
print("newosproc m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
}
// Initialize an attribute object.
var attr pthreadattr
if err := pthread_attr_init(&attr); err != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
// Find out OS stack size for our own stack guard.
var stacksize uintptr
if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
mp.g0.stack.hi = stacksize // for mstart
// Tell the pthread library we won't join with this thread.
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
// Finally, create the thread. It starts at mstart_stub, which does some low-level
// setup and then calls mstart.
var oset sigset
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
err := retryOnEAGAIN(func() int32 {
return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
})
sigprocmask(_SIG_SETMASK, &oset, nil)
if err != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
pthread_attr_destroy(&attr)
}
func osinit() { func osinit() {
numCPUStartup = getCPUCount() numCPUStartup = getCPUCount()
physPageSize = getPageSize() physPageSize = getPageSize()
@ -160,9 +208,6 @@ func goenvs() {
// Called on the parent thread (main thread in case of bootstrap), can allocate memory. // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
func mpreinit(mp *m) { func mpreinit(mp *m) {
gsignalSize := int32(32 * 1024) gsignalSize := int32(32 * 1024)
if GOARCH == "mips64" {
gsignalSize = int32(64 * 1024)
}
mp.gsignal = malg(gsignalSize) mp.gsignal = malg(gsignalSize)
mp.gsignal.m = mp mp.gsignal.m = mp
} }

View file

@ -1,60 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && !mips64
package runtime
import (
"internal/abi"
"unsafe"
)
// mstart_stub provides glue code to call mstart from pthread_create.
func mstart_stub()
// May run with m.p==nil, so write barriers are not allowed.
//
//go:nowritebarrierrec
func newosproc(mp *m) {
if false {
print("newosproc m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
}
// Initialize an attribute object.
var attr pthreadattr
if err := pthread_attr_init(&attr); err != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
// Find out OS stack size for our own stack guard.
var stacksize uintptr
if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
mp.g0.stack.hi = stacksize // for mstart
// Tell the pthread library we won't join with this thread.
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
// Finally, create the thread. It starts at mstart_stub, which does some low-level
// setup and then calls mstart.
var oset sigset
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
err := retryOnEAGAIN(func() int32 {
return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
})
sigprocmask(_SIG_SETMASK, &oset, nil)
if err != 0 {
writeErrStr(failthreadcreate)
exit(1)
}
pthread_attr_destroy(&attr)
}

View file

@ -1,11 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
//go:nosplit
func cputicks() int64 {
// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
return nanotime()
}

View file

@ -1,51 +0,0 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && mips64
package runtime
import (
"internal/abi"
"internal/goarch"
"unsafe"
)
//go:noescape
func tfork(param *tforkt, psize uintptr, mm *m, gg *g, fn uintptr) int32
// May run with m.p==nil, so write barriers are not allowed.
//
//go:nowritebarrier
func newosproc(mp *m) {
stk := unsafe.Pointer(mp.g0.stack.hi)
if false {
print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
}
// Stack pointer must point inside stack area (as marked with MAP_STACK),
// rather than at the top of it.
param := tforkt{
tf_tcb: unsafe.Pointer(&mp.tls[0]),
tf_tid: nil, // minit will record tid
tf_stack: uintptr(stk) - goarch.PtrSize,
}
var oset sigset
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
ret := retryOnEAGAIN(func() int32 {
errno := tfork(&param, unsafe.Sizeof(param), mp, mp.g0, abi.FuncPCABI0(mstart))
// tfork returns negative errno
return -errno
})
sigprocmask(_SIG_SETMASK, &oset, nil)
if ret != 0 {
print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", ret, ")\n")
if ret == _EAGAIN {
println("runtime: may need to increase max user processes (ulimit -p)")
}
throw("runtime.newosproc")
}
}

View file

@ -1,20 +0,0 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && mips64
package runtime
//go:noescape
func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32
//go:noescape
func thrwakeup(ident uintptr, n int32) int32
func osyield()
//go:nosplit
func osyield_no_g() {
osyield()
}

View file

@ -1,102 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && mips64
package runtime
import (
"internal/runtime/atomic"
"unsafe"
)
//go:noescape
func sigaction(sig uint32, new, old *sigactiont)
func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func raiseproc(sig uint32)
func getthrid() int32
func thrkill(tid int32, sig int)
// read calls the read system call.
// It returns a non-negative number of bytes written or a negative errno value.
func read(fd int32, p unsafe.Pointer, n int32) int32
func closefd(fd int32) int32
func exit(code int32)
func usleep(usec uint32)
//go:nosplit
func usleep_no_g(usec uint32) {
usleep(usec)
}
// write1 calls the write system call.
// It returns a non-negative number of bytes written or a negative errno value.
//
//go:noescape
func write1(fd uintptr, p unsafe.Pointer, n int32) int32
//go:noescape
func open(name *byte, mode, perm int32) int32
// return value is only set on linux to be used in osinit().
func madvise(addr unsafe.Pointer, n uintptr, flags int32) int32
// exitThread terminates the current thread, writing *wait = freeMStack when
// the stack is safe to reclaim.
//
//go:noescape
func exitThread(wait *atomic.Uint32)
//go:noescape
func obsdsigprocmask(how int32, new sigset) sigset
//go:nosplit
//go:nowritebarrierrec
func sigprocmask(how int32, new, old *sigset) {
n := sigset(0)
if new != nil {
n = *new
}
r := obsdsigprocmask(how, n)
if old != nil {
*old = r
}
}
func pipe2(flags int32) (r, w int32, errno int32)
//go:noescape
func setitimer(mode int32, new, old *itimerval)
//go:noescape
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
// mmap calls the mmap system call. It is implemented in assembly.
// We only pass the lower 32 bits of file offset to the
// assembly routine; the higher bits (if required), should be provided
// by the assembly routine as 0.
// The err result is an OS error code such as ENOMEM.
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
// munmap calls the munmap system call. It is implemented in assembly.
func munmap(addr unsafe.Pointer, n uintptr)
func nanotime1() int64
//go:noescape
func sigaltstack(new, old *stackt)
func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
func walltime() (sec int64, nsec int32)
func issetugid() int32

View file

@ -1,36 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "textflag.h"
TEXT _rt0_mips64_openbsd(SB),NOSPLIT,$0
JMP _main<>(SB)
TEXT _rt0_mips64le_openbsd(SB),NOSPLIT,$0
JMP _main<>(SB)
TEXT _main<>(SB),NOSPLIT|NOFRAME,$0
// In a statically linked binary, the stack contains argc,
// argv as argc string pointers followed by a NULL, envv as a
// sequence of string pointers followed by a NULL, and auxv.
// There is no TLS base pointer.
#ifdef GOARCH_mips64
MOVW 4(R29), R4 // argc, big-endian ABI places int32 at offset 4
#else
MOVW 0(R29), R4 // argc
#endif
ADDV $8, R29, R5 // argv
JMP main(SB)
TEXT main(SB),NOSPLIT|NOFRAME,$0
// in external linking, glibc jumps to main with argc in R4
// and argv in R5
// initialize REGSB = PC&0xffffffff00000000
BGEZAL R0, 1(PC)
SRLV $32, R31, RSB
SLLV $32, RSB
MOVV $runtime·rt0_go(SB), R1
JMP (R1)

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (linux || openbsd) && (mips64 || mips64le) //go:build linux && (mips64 || mips64le)
package runtime package runtime

View file

@ -1,78 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import (
"unsafe"
)
type sigctxt struct {
info *siginfo
ctxt unsafe.Pointer
}
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *sigcontext {
return (*sigcontext)(c.ctxt)
}
func (c *sigctxt) r0() uint64 { return c.regs().sc_regs[0] }
func (c *sigctxt) r1() uint64 { return c.regs().sc_regs[1] }
func (c *sigctxt) r2() uint64 { return c.regs().sc_regs[2] }
func (c *sigctxt) r3() uint64 { return c.regs().sc_regs[3] }
func (c *sigctxt) r4() uint64 { return c.regs().sc_regs[4] }
func (c *sigctxt) r5() uint64 { return c.regs().sc_regs[5] }
func (c *sigctxt) r6() uint64 { return c.regs().sc_regs[6] }
func (c *sigctxt) r7() uint64 { return c.regs().sc_regs[7] }
func (c *sigctxt) r8() uint64 { return c.regs().sc_regs[8] }
func (c *sigctxt) r9() uint64 { return c.regs().sc_regs[9] }
func (c *sigctxt) r10() uint64 { return c.regs().sc_regs[10] }
func (c *sigctxt) r11() uint64 { return c.regs().sc_regs[11] }
func (c *sigctxt) r12() uint64 { return c.regs().sc_regs[12] }
func (c *sigctxt) r13() uint64 { return c.regs().sc_regs[13] }
func (c *sigctxt) r14() uint64 { return c.regs().sc_regs[14] }
func (c *sigctxt) r15() uint64 { return c.regs().sc_regs[15] }
func (c *sigctxt) r16() uint64 { return c.regs().sc_regs[16] }
func (c *sigctxt) r17() uint64 { return c.regs().sc_regs[17] }
func (c *sigctxt) r18() uint64 { return c.regs().sc_regs[18] }
func (c *sigctxt) r19() uint64 { return c.regs().sc_regs[19] }
func (c *sigctxt) r20() uint64 { return c.regs().sc_regs[20] }
func (c *sigctxt) r21() uint64 { return c.regs().sc_regs[21] }
func (c *sigctxt) r22() uint64 { return c.regs().sc_regs[22] }
func (c *sigctxt) r23() uint64 { return c.regs().sc_regs[23] }
func (c *sigctxt) r24() uint64 { return c.regs().sc_regs[24] }
func (c *sigctxt) r25() uint64 { return c.regs().sc_regs[25] }
func (c *sigctxt) r26() uint64 { return c.regs().sc_regs[26] }
func (c *sigctxt) r27() uint64 { return c.regs().sc_regs[27] }
func (c *sigctxt) r28() uint64 { return c.regs().sc_regs[28] }
func (c *sigctxt) r29() uint64 { return c.regs().sc_regs[29] }
func (c *sigctxt) r30() uint64 { return c.regs().sc_regs[30] }
func (c *sigctxt) r31() uint64 { return c.regs().sc_regs[31] }
func (c *sigctxt) sp() uint64 { return c.regs().sc_regs[29] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().sc_pc }
func (c *sigctxt) link() uint64 { return c.regs().sc_regs[31] }
func (c *sigctxt) lo() uint64 { return c.regs().mullo }
func (c *sigctxt) hi() uint64 { return c.regs().mulhi }
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
func (c *sigctxt) sigaddr() uint64 {
return *(*uint64)(add(unsafe.Pointer(c.info), 16))
}
func (c *sigctxt) set_r28(x uint64) { c.regs().sc_regs[28] = x }
func (c *sigctxt) set_r30(x uint64) { c.regs().sc_regs[30] = x }
func (c *sigctxt) set_pc(x uint64) { c.regs().sc_pc = x }
func (c *sigctxt) set_sp(x uint64) { c.regs().sc_regs[29] = x }
func (c *sigctxt) set_link(x uint64) { c.regs().sc_regs[31] = x }
func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
func (c *sigctxt) set_sigaddr(x uint64) {
*(*uint64)(add(unsafe.Pointer(c.info), 16)) = x
}

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build darwin || (openbsd && !mips64) //go:build darwin || openbsd
package runtime package runtime

View file

@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build openbsd && !mips64
package runtime package runtime
import ( import (
"internal/abi" "internal/abi"
"internal/runtime/atomic"
"unsafe" "unsafe"
) )
@ -61,6 +60,412 @@ func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32
} }
func pthread_create_trampoline() func pthread_create_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(thrsleep_trampoline)), unsafe.Pointer(&ident))
KeepAlive(tsp)
KeepAlive(abort)
return ret
}
func thrsleep_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func thrwakeup(ident uintptr, n int32) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(thrwakeup_trampoline)), unsafe.Pointer(&ident))
}
func thrwakeup_trampoline()
//go:nosplit
func osyield() {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sched_yield_trampoline)), unsafe.Pointer(nil))
}
func sched_yield_trampoline()
//go:nosplit
func osyield_no_g() {
asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sched_yield_trampoline)), unsafe.Pointer(nil))
}
// This is exported via linkname to assembly in runtime/cgo.
//
//go:linkname exit
//go:nosplit
//go:cgo_unsafe_args
func exit(code int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code))
}
func exit_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func getthrid() (tid int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(getthrid_trampoline)), unsafe.Pointer(&tid))
return
}
func getthrid_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func raiseproc(sig uint32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig))
}
func raiseproc_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func thrkill(tid int32, sig int) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(thrkill_trampoline)), unsafe.Pointer(&tid))
}
func thrkill_trampoline()
// mmap is used to do low-level memory allocation via mmap. Don't allow stack
// splits, since this function (used by sysAlloc) is called in a lot of low-level
// parts of the runtime and callers often assume it won't acquire any locks.
//
//go:nosplit
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
args := struct {
addr unsafe.Pointer
n uintptr
prot, flags, fd int32
off uint32
ret1 unsafe.Pointer
ret2 int
}{addr, n, prot, flags, fd, off, nil, 0}
libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
return args.ret1, args.ret2
}
func mmap_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func munmap(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func munmap_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func madvise_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func open(name *byte, mode, perm int32) (ret int32) {
ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
KeepAlive(name)
return
}
func open_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func closefd(fd int32) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd))
}
func close_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func read_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func write_trampoline()
func pipe2(flags int32) (r, w int32, errno int32) {
var p [2]int32
args := struct {
p unsafe.Pointer
flags int32
}{noescape(unsafe.Pointer(&p)), flags}
errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe2_trampoline)), unsafe.Pointer(&args))
return p[0], p[1], errno
}
func pipe2_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
KeepAlive(new)
KeepAlive(old)
}
func setitimer_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func usleep(usec uint32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
}
func usleep_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func usleep_no_g(usec uint32) {
asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
}
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
KeepAlive(mib)
KeepAlive(out)
KeepAlive(size)
KeepAlive(dst)
return ret
}
func sysctl_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
args := struct {
fd, cmd, arg int32
ret, errno int32
}{fd, cmd, arg, 0, 0}
libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
return args.ret, args.errno
}
func fcntl_trampoline()
//go:nosplit
func nanotime1() int64 {
var ts timespec
args := struct {
clock_id int32
tp unsafe.Pointer
}{_CLOCK_MONOTONIC, unsafe.Pointer(&ts)}
if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 {
// Avoid growing the nosplit stack.
systemstack(func() {
println("runtime: errno", -errno)
throw("clock_gettime failed")
})
}
return ts.tv_sec*1e9 + int64(ts.tv_nsec)
}
func clock_gettime_trampoline()
//go:nosplit
func walltime() (int64, int32) {
var ts timespec
args := struct {
clock_id int32
tp unsafe.Pointer
}{_CLOCK_REALTIME, unsafe.Pointer(&ts)}
if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 {
// Avoid growing the nosplit stack.
systemstack(func() {
println("runtime: errno", -errno)
throw("clock_gettime failed")
})
}
return ts.tv_sec, int32(ts.tv_nsec)
}
//go:nosplit
//go:cgo_unsafe_args
func kqueue() int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil)
}
func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
KeepAlive(ch)
KeepAlive(ev)
KeepAlive(ts)
return ret
}
func kevent_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sigaction(sig uint32, new *sigactiont, old *sigactiont) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
KeepAlive(new)
KeepAlive(old)
}
func sigaction_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sigprocmask(how uint32, new *sigset, old *sigset) {
// sigprocmask is called from sigsave, which is called from needm.
// As such, we have to be able to run with no g here.
asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
KeepAlive(new)
KeepAlive(old)
}
func sigprocmask_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sigaltstack(new *stackt, old *stackt) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
KeepAlive(new)
KeepAlive(old)
}
func sigaltstack_trampoline()
// Not used on OpenBSD, but must be defined.
func exitThread(wait *atomic.Uint32) {
throw("exitThread")
}
//go:nosplit
//go:cgo_unsafe_args
func issetugid() (ret int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(issetugid_trampoline)), unsafe.Pointer(&ret))
return
}
func issetugid_trampoline()
// The X versions of syscall expect the libc call to return a 64-bit result.
// Otherwise (the non-X version) expects a 32-bit result.
// This distinction is required because an error is indicated by returning -1,
// and we need to know whether to check 32 or 64 bits of the result.
// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
// golang.org/x/sys linknames syscall_syscall
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_syscall syscall.syscall
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall()
//go:linkname syscall_syscallX syscall.syscallX
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscallX()
// golang.org/x/sys linknames syscall.syscall6
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_syscall6 syscall.syscall6
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall6()
//go:linkname syscall_syscall6X syscall.syscall6X
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall6X()
// golang.org/x/sys linknames syscall.syscall10
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_syscall10 syscall.syscall10
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall10()
//go:linkname syscall_syscall10X syscall.syscall10X
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10X)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall10X()
// golang.org/x/sys linknames syscall_rawSyscall
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_rawSyscall syscall.rawSyscall
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
return
}
// golang.org/x/sys linknames syscall_rawSyscall6
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
return
}
//go:linkname syscall_rawSyscall6X syscall.rawSyscall6X
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
return
}
//go:linkname syscall_rawSyscall10X syscall.rawSyscall10X
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10X)), unsafe.Pointer(&fn))
return
}
// Tell the linker that the libc_* functions are to be found // Tell the linker that the libc_* functions are to be found
// in a system library, with the libc_ prefix missing. // in a system library, with the libc_ prefix missing.
@ -71,5 +476,40 @@ func pthread_create_trampoline()
//go:cgo_import_dynamic libc_pthread_create pthread_create "libpthread.so" //go:cgo_import_dynamic libc_pthread_create pthread_create "libpthread.so"
//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "libpthread.so" //go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "libpthread.so"
//go:cgo_import_dynamic libc_thrsleep __thrsleep "libc.so"
//go:cgo_import_dynamic libc_thrwakeup __thrwakeup "libc.so"
//go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
//go:cgo_import_dynamic libc_errno __errno "libc.so"
//go:cgo_import_dynamic libc_exit exit "libc.so"
//go:cgo_import_dynamic libc_getthrid getthrid "libc.so"
//go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
//go:cgo_import_dynamic libc_thrkill thrkill "libc.so"
//go:cgo_import_dynamic libc_mmap mmap "libc.so"
//go:cgo_import_dynamic libc_munmap munmap "libc.so"
//go:cgo_import_dynamic libc_madvise madvise "libc.so"
//go:cgo_import_dynamic libc_open open "libc.so"
//go:cgo_import_dynamic libc_close close "libc.so"
//go:cgo_import_dynamic libc_read read "libc.so"
//go:cgo_import_dynamic libc_write write "libc.so"
//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so"
//go:cgo_import_dynamic libc_setitimer setitimer "libc.so"
//go:cgo_import_dynamic libc_usleep usleep "libc.so"
//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
//go:cgo_import_dynamic libc_getpid getpid "libc.so"
//go:cgo_import_dynamic libc_kill kill "libc.so"
//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
//go:cgo_import_dynamic libc_kevent kevent "libc.so"
//go:cgo_import_dynamic libc_sigaction sigaction "libc.so"
//go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so"
//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
//go:cgo_import_dynamic _ _ "libpthread.so" //go:cgo_import_dynamic _ _ "libpthread.so"
//go:cgo_import_dynamic _ _ "libc.so" //go:cgo_import_dynamic _ _ "libc.so"

View file

@ -1,46 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && !mips64
package runtime
import (
"internal/abi"
"unsafe"
)
//go:nosplit
//go:cgo_unsafe_args
func thrsleep(ident uintptr, clock_id int32, tsp *timespec, lock uintptr, abort *uint32) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(thrsleep_trampoline)), unsafe.Pointer(&ident))
KeepAlive(tsp)
KeepAlive(abort)
return ret
}
func thrsleep_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func thrwakeup(ident uintptr, n int32) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(thrwakeup_trampoline)), unsafe.Pointer(&ident))
}
func thrwakeup_trampoline()
//go:nosplit
func osyield() {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sched_yield_trampoline)), unsafe.Pointer(nil))
}
func sched_yield_trampoline()
//go:nosplit
func osyield_no_g() {
asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sched_yield_trampoline)), unsafe.Pointer(nil))
}
//go:cgo_import_dynamic libc_thrsleep __thrsleep "libc.so"
//go:cgo_import_dynamic libc_thrwakeup __thrwakeup "libc.so"
//go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
//go:cgo_import_dynamic _ _ "libc.so"

View file

@ -1,303 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && !mips64
package runtime
import (
"internal/abi"
"internal/runtime/atomic"
"unsafe"
)
// This is exported via linkname to assembly in runtime/cgo.
//
//go:linkname exit
//go:nosplit
//go:cgo_unsafe_args
func exit(code int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code))
}
func exit_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func getthrid() (tid int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(getthrid_trampoline)), unsafe.Pointer(&tid))
return
}
func getthrid_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func raiseproc(sig uint32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig))
}
func raiseproc_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func thrkill(tid int32, sig int) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(thrkill_trampoline)), unsafe.Pointer(&tid))
}
func thrkill_trampoline()
// mmap is used to do low-level memory allocation via mmap. Don't allow stack
// splits, since this function (used by sysAlloc) is called in a lot of low-level
// parts of the runtime and callers often assume it won't acquire any locks.
//
//go:nosplit
func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
args := struct {
addr unsafe.Pointer
n uintptr
prot, flags, fd int32
off uint32
ret1 unsafe.Pointer
ret2 int
}{addr, n, prot, flags, fd, off, nil, 0}
libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
return args.ret1, args.ret2
}
func mmap_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func munmap(addr unsafe.Pointer, n uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func munmap_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
}
func madvise_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func open(name *byte, mode, perm int32) (ret int32) {
ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
KeepAlive(name)
return
}
func open_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func closefd(fd int32) int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd))
}
func close_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func read(fd int32, p unsafe.Pointer, n int32) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func read_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
KeepAlive(p)
return ret
}
func write_trampoline()
func pipe2(flags int32) (r, w int32, errno int32) {
var p [2]int32
args := struct {
p unsafe.Pointer
flags int32
}{noescape(unsafe.Pointer(&p)), flags}
errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe2_trampoline)), unsafe.Pointer(&args))
return p[0], p[1], errno
}
func pipe2_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
KeepAlive(new)
KeepAlive(old)
}
func setitimer_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func usleep(usec uint32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
}
func usleep_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func usleep_no_g(usec uint32) {
asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
}
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
KeepAlive(mib)
KeepAlive(out)
KeepAlive(size)
KeepAlive(dst)
return ret
}
func sysctl_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
args := struct {
fd, cmd, arg int32
ret, errno int32
}{fd, cmd, arg, 0, 0}
libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
return args.ret, args.errno
}
func fcntl_trampoline()
//go:nosplit
func nanotime1() int64 {
var ts timespec
args := struct {
clock_id int32
tp unsafe.Pointer
}{_CLOCK_MONOTONIC, unsafe.Pointer(&ts)}
if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 {
// Avoid growing the nosplit stack.
systemstack(func() {
println("runtime: errno", -errno)
throw("clock_gettime failed")
})
}
return ts.tv_sec*1e9 + int64(ts.tv_nsec)
}
func clock_gettime_trampoline()
//go:nosplit
func walltime() (int64, int32) {
var ts timespec
args := struct {
clock_id int32
tp unsafe.Pointer
}{_CLOCK_REALTIME, unsafe.Pointer(&ts)}
if errno := libcCall(unsafe.Pointer(abi.FuncPCABI0(clock_gettime_trampoline)), unsafe.Pointer(&args)); errno < 0 {
// Avoid growing the nosplit stack.
systemstack(func() {
println("runtime: errno", -errno)
throw("clock_gettime failed")
})
}
return ts.tv_sec, int32(ts.tv_nsec)
}
//go:nosplit
//go:cgo_unsafe_args
func kqueue() int32 {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil)
}
func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
KeepAlive(ch)
KeepAlive(ev)
KeepAlive(ts)
return ret
}
func kevent_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sigaction(sig uint32, new *sigactiont, old *sigactiont) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
KeepAlive(new)
KeepAlive(old)
}
func sigaction_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sigprocmask(how uint32, new *sigset, old *sigset) {
// sigprocmask is called from sigsave, which is called from needm.
// As such, we have to be able to run with no g here.
asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
KeepAlive(new)
KeepAlive(old)
}
func sigprocmask_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sigaltstack(new *stackt, old *stackt) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
KeepAlive(new)
KeepAlive(old)
}
func sigaltstack_trampoline()
// Not used on OpenBSD, but must be defined.
func exitThread(wait *atomic.Uint32) {
throw("exitThread")
}
//go:nosplit
//go:cgo_unsafe_args
func issetugid() (ret int32) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(issetugid_trampoline)), unsafe.Pointer(&ret))
return
}
func issetugid_trampoline()
// Tell the linker that the libc_* functions are to be found
// in a system library, with the libc_ prefix missing.
//go:cgo_import_dynamic libc_errno __errno "libc.so"
//go:cgo_import_dynamic libc_exit exit "libc.so"
//go:cgo_import_dynamic libc_getthrid getthrid "libc.so"
//go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
//go:cgo_import_dynamic libc_thrkill thrkill "libc.so"
//go:cgo_import_dynamic libc_mmap mmap "libc.so"
//go:cgo_import_dynamic libc_munmap munmap "libc.so"
//go:cgo_import_dynamic libc_madvise madvise "libc.so"
//go:cgo_import_dynamic libc_open open "libc.so"
//go:cgo_import_dynamic libc_close close "libc.so"
//go:cgo_import_dynamic libc_read read "libc.so"
//go:cgo_import_dynamic libc_write write "libc.so"
//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
//go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so"
//go:cgo_import_dynamic libc_setitimer setitimer "libc.so"
//go:cgo_import_dynamic libc_usleep usleep "libc.so"
//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
//go:cgo_import_dynamic libc_getpid getpid "libc.so"
//go:cgo_import_dynamic libc_kill kill "libc.so"
//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
//go:cgo_import_dynamic libc_kevent kevent "libc.so"
//go:cgo_import_dynamic libc_sigaction sigaction "libc.so"
//go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so"
//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
//go:cgo_import_dynamic _ _ "libc.so"

View file

@ -1,136 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build openbsd && !mips64
package runtime
import (
"internal/abi"
"unsafe"
)
// The X versions of syscall expect the libc call to return a 64-bit result.
// Otherwise (the non-X version) expects a 32-bit result.
// This distinction is required because an error is indicated by returning -1,
// and we need to know whether to check 32 or 64 bits of the result.
// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
// golang.org/x/sys linknames syscall_syscall
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_syscall syscall.syscall
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall()
//go:linkname syscall_syscallX syscall.syscallX
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscallX()
// golang.org/x/sys linknames syscall.syscall6
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_syscall6 syscall.syscall6
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall6()
//go:linkname syscall_syscall6X syscall.syscall6X
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall6X()
// golang.org/x/sys linknames syscall.syscall10
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_syscall10 syscall.syscall10
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall10()
//go:linkname syscall_syscall10X syscall.syscall10X
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
entersyscall()
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10X)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall10X()
// golang.org/x/sys linknames syscall_rawSyscall
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_rawSyscall syscall.rawSyscall
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&fn))
return
}
// golang.org/x/sys linknames syscall_rawSyscall6
// (in addition to standard package syscall).
// Do not remove or change the type signature.
//
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&fn))
return
}
//go:linkname syscall_rawSyscall6X syscall.rawSyscall6X
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&fn))
return
}
//go:linkname syscall_rawSyscall10X syscall.rawSyscall10X
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall10X)), unsafe.Pointer(&fn))
return
}

View file

@ -1,388 +0,0 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// System calls and other sys.stuff for mips64, OpenBSD
// /usr/src/sys/kern/syscalls.master for syscall numbers.
//
#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"
#define CLOCK_REALTIME $0
#define CLOCK_MONOTONIC $3
// Exit the entire program (like C exit)
TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
MOVW code+0(FP), R4 // arg 1 - status
MOVV $1, R2 // sys_exit
SYSCALL
BEQ R7, 3(PC)
MOVV $0, R2 // crash on syscall failure
MOVV R2, (R2)
RET
// func exitThread(wait *atomic.Uint32)
TEXT runtime·exitThread(SB),NOSPLIT,$0
MOVV wait+0(FP), R4 // arg 1 - notdead
MOVV $302, R2 // sys___threxit
SYSCALL
MOVV $0, R2 // crash on syscall failure
MOVV R2, (R2)
JMP 0(PC)
TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
MOVV name+0(FP), R4 // arg 1 - path
MOVW mode+8(FP), R5 // arg 2 - mode
MOVW perm+12(FP), R6 // arg 3 - perm
MOVV $5, R2 // sys_open
SYSCALL
BEQ R7, 2(PC)
MOVW $-1, R2
MOVW R2, ret+16(FP)
RET
TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
MOVW fd+0(FP), R4 // arg 1 - fd
MOVV $6, R2 // sys_close
SYSCALL
BEQ R7, 2(PC)
MOVW $-1, R2
MOVW R2, ret+8(FP)
RET
TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
MOVW fd+0(FP), R4 // arg 1 - fd
MOVV p+8(FP), R5 // arg 2 - buf
MOVW n+16(FP), R6 // arg 3 - nbyte
MOVV $3, R2 // sys_read
SYSCALL
BEQ R7, 2(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+24(FP)
RET
// func pipe2(flags int32) (r, w int32, errno int32)
TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
MOVV $r+8(FP), R4
MOVW flags+0(FP), R5
MOVV $101, R2 // sys_pipe2
SYSCALL
BEQ R7, 2(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, errno+16(FP)
RET
TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0
MOVV fd+0(FP), R4 // arg 1 - fd
MOVV p+8(FP), R5 // arg 2 - buf
MOVW n+16(FP), R6 // arg 3 - nbyte
MOVV $4, R2 // sys_write
SYSCALL
BEQ R7, 2(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+24(FP)
RET
TEXT runtime·usleep(SB),NOSPLIT,$24-4
MOVWU usec+0(FP), R3
MOVV R3, R5
MOVW $1000000, R4
DIVVU R4, R3
MOVV LO, R3
MOVV R3, 8(R29) // tv_sec
MOVW $1000, R4
MULVU R3, R4
MOVV LO, R4
SUBVU R4, R5
MOVV R5, 16(R29) // tv_nsec
ADDV $8, R29, R4 // arg 1 - rqtp
MOVV $0, R5 // arg 2 - rmtp
MOVV $91, R2 // sys_nanosleep
SYSCALL
RET
TEXT runtime·getthrid(SB),NOSPLIT,$0-4
MOVV $299, R2 // sys_getthrid
SYSCALL
MOVW R2, ret+0(FP)
RET
TEXT runtime·thrkill(SB),NOSPLIT,$0-16
MOVW tid+0(FP), R4 // arg 1 - tid
MOVV sig+8(FP), R5 // arg 2 - signum
MOVW $0, R6 // arg 3 - tcb
MOVV $119, R2 // sys_thrkill
SYSCALL
RET
TEXT runtime·raiseproc(SB),NOSPLIT,$0
MOVV $20, R4 // sys_getpid
SYSCALL
MOVV R2, R4 // arg 1 - pid
MOVW sig+0(FP), R5 // arg 2 - signum
MOVV $122, R2 // sys_kill
SYSCALL
RET
TEXT runtime·mmap(SB),NOSPLIT,$0
MOVV addr+0(FP), R4 // arg 1 - addr
MOVV n+8(FP), R5 // arg 2 - len
MOVW prot+16(FP), R6 // arg 3 - prot
MOVW flags+20(FP), R7 // arg 4 - flags
MOVW fd+24(FP), R8 // arg 5 - fd
MOVW $0, R9 // arg 6 - pad
MOVW off+28(FP), R10 // arg 7 - offset
MOVV $197, R2 // sys_mmap
SYSCALL
MOVV $0, R4
BEQ R7, 3(PC)
MOVV R2, R4 // if error, move to R4
MOVV $0, R2
MOVV R2, p+32(FP)
MOVV R4, err+40(FP)
RET
TEXT runtime·munmap(SB),NOSPLIT,$0
MOVV addr+0(FP), R4 // arg 1 - addr
MOVV n+8(FP), R5 // arg 2 - len
MOVV $73, R2 // sys_munmap
SYSCALL
BEQ R7, 3(PC)
MOVV $0, R2 // crash on syscall failure
MOVV R2, (R2)
RET
TEXT runtime·madvise(SB),NOSPLIT,$0
MOVV addr+0(FP), R4 // arg 1 - addr
MOVV n+8(FP), R5 // arg 2 - len
MOVW flags+16(FP), R6 // arg 2 - flags
MOVV $75, R2 // sys_madvise
SYSCALL
BEQ R7, 2(PC)
MOVW $-1, R2
MOVW R2, ret+24(FP)
RET
TEXT runtime·setitimer(SB),NOSPLIT,$0
MOVW mode+0(FP), R4 // arg 1 - mode
MOVV new+8(FP), R5 // arg 2 - new value
MOVV old+16(FP), R6 // arg 3 - old value
MOVV $69, R2 // sys_setitimer
SYSCALL
RET
// func walltime() (sec int64, nsec int32)
TEXT runtime·walltime(SB), NOSPLIT, $32
MOVW CLOCK_REALTIME, R4 // arg 1 - clock_id
MOVV $8(R29), R5 // arg 2 - tp
MOVV $87, R2 // sys_clock_gettime
SYSCALL
MOVV 8(R29), R4 // sec
MOVV 16(R29), R5 // nsec
MOVV R4, sec+0(FP)
MOVW R5, nsec+8(FP)
RET
// int64 nanotime1(void) so really
// void nanotime1(int64 *nsec)
TEXT runtime·nanotime1(SB),NOSPLIT,$32
MOVW CLOCK_MONOTONIC, R4 // arg 1 - clock_id
MOVV $8(R29), R5 // arg 2 - tp
MOVV $87, R2 // sys_clock_gettime
SYSCALL
MOVV 8(R29), R3 // sec
MOVV 16(R29), R5 // nsec
MOVV $1000000000, R4
MULVU R4, R3
MOVV LO, R3
ADDVU R5, R3
MOVV R3, ret+0(FP)
RET
TEXT runtime·sigaction(SB),NOSPLIT,$0
MOVW sig+0(FP), R4 // arg 1 - signum
MOVV new+8(FP), R5 // arg 2 - new sigaction
MOVV old+16(FP), R6 // arg 3 - old sigaction
MOVV $46, R2 // sys_sigaction
SYSCALL
BEQ R7, 3(PC)
MOVV $3, R2 // crash on syscall failure
MOVV R2, (R2)
RET
TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
MOVW how+0(FP), R4 // arg 1 - mode
MOVW new+4(FP), R5 // arg 2 - new
MOVV $48, R2 // sys_sigprocmask
SYSCALL
BEQ R7, 3(PC)
MOVV $3, R2 // crash on syscall failure
MOVV R2, (R2)
MOVW R2, ret+8(FP)
RET
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
MOVW sig+8(FP), R4
MOVV info+16(FP), R5
MOVV ctx+24(FP), R6
MOVV fn+0(FP), R25 // Must use R25, needed for PIC code.
CALL (R25)
RET
TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$192
// initialize REGSB = PC&0xffffffff00000000
BGEZAL R0, 1(PC)
SRLV $32, R31, RSB
SLLV $32, RSB
// this might be called in external code context,
// where g is not set.
MOVB runtime·iscgo(SB), R1
BEQ R1, 2(PC)
JAL runtime·load_g(SB)
MOVW R4, 8(R29)
MOVV R5, 16(R29)
MOVV R6, 24(R29)
MOVV $runtime·sigtrampgo(SB), R1
JAL (R1)
RET
// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
TEXT runtime·tfork(SB),NOSPLIT,$0
// Copy mp, gp and fn off parent stack for use by child.
MOVV mm+16(FP), R16
MOVV gg+24(FP), R17
MOVV fn+32(FP), R18
MOVV param+0(FP), R4 // arg 1 - param
MOVV psize+8(FP), R5 // arg 2 - psize
MOVV $8, R2 // sys___tfork
SYSCALL
// Return if syscall failed.
BEQ R7, 4(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+40(FP)
RET
// In parent, return.
BEQ R2, 3(PC)
MOVW $0, ret+40(FP)
RET
// Initialise m, g.
MOVV R17, g
MOVV R16, g_m(g)
// Call fn.
CALL (R18)
// fn should never return.
MOVV $2, R8 // crash if reached
MOVV R8, (R8)
RET
TEXT runtime·sigaltstack(SB),NOSPLIT,$0
MOVV new+0(FP), R4 // arg 1 - new sigaltstack
MOVV old+8(FP), R5 // arg 2 - old sigaltstack
MOVV $288, R2 // sys_sigaltstack
SYSCALL
BEQ R7, 3(PC)
MOVV $0, R8 // crash on syscall failure
MOVV R8, (R8)
RET
TEXT runtime·osyield(SB),NOSPLIT,$0
MOVV $298, R2 // sys_sched_yield
SYSCALL
RET
TEXT runtime·thrsleep(SB),NOSPLIT,$0
MOVV ident+0(FP), R4 // arg 1 - ident
MOVW clock_id+8(FP), R5 // arg 2 - clock_id
MOVV tsp+16(FP), R6 // arg 3 - tsp
MOVV lock+24(FP), R7 // arg 4 - lock
MOVV abort+32(FP), R8 // arg 5 - abort
MOVV $94, R2 // sys___thrsleep
SYSCALL
MOVW R2, ret+40(FP)
RET
TEXT runtime·thrwakeup(SB),NOSPLIT,$0
MOVV ident+0(FP), R4 // arg 1 - ident
MOVW n+8(FP), R5 // arg 2 - n
MOVV $301, R2 // sys___thrwakeup
SYSCALL
MOVW R2, ret+16(FP)
RET
TEXT runtime·sysctl(SB),NOSPLIT,$0
MOVV mib+0(FP), R4 // arg 1 - mib
MOVW miblen+8(FP), R5 // arg 2 - miblen
MOVV out+16(FP), R6 // arg 3 - out
MOVV size+24(FP), R7 // arg 4 - size
MOVV dst+32(FP), R8 // arg 5 - dest
MOVV ndst+40(FP), R9 // arg 6 - newlen
MOVV $202, R2 // sys___sysctl
SYSCALL
BEQ R7, 2(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+48(FP)
RET
// int32 runtime·kqueue(void);
TEXT runtime·kqueue(SB),NOSPLIT,$0
MOVV $269, R2 // sys_kqueue
SYSCALL
BEQ R7, 2(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+0(FP)
RET
// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
TEXT runtime·kevent(SB),NOSPLIT,$0
MOVW kq+0(FP), R4 // arg 1 - kq
MOVV ch+8(FP), R5 // arg 2 - changelist
MOVW nch+16(FP), R6 // arg 3 - nchanges
MOVV ev+24(FP), R7 // arg 4 - eventlist
MOVW nev+32(FP), R8 // arg 5 - nevents
MOVV ts+40(FP), R9 // arg 6 - timeout
MOVV $72, R2 // sys_kevent
SYSCALL
BEQ R7, 2(PC)
SUBVU R2, R0, R2 // caller expects negative errno
MOVW R2, ret+48(FP)
RET
// func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVW fd+0(FP), R4 // fd
MOVW cmd+4(FP), R5 // cmd
MOVW arg+8(FP), R6 // arg
MOVV $92, R2 // sys_fcntl
SYSCALL
MOVV $0, R4
BEQ R7, noerr
MOVV R2, R4
MOVW $-1, R2
noerr:
MOVW R2, ret+16(FP)
MOVW R4, errno+20(FP)
RET
// func issetugid() int32
TEXT runtime·issetugid(SB),NOSPLIT,$0
MOVV $253, R2 // sys_issetugid
SYSCALL
MOVW R2, ret+0(FP)
RET