// Copyright 2016 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.

// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris

package runtime

import (
	"unsafe"
)

// Functions for gccgo to support signal handling. In the gc runtime
// these are written in OS-specific files and in assembler.

//go:noescape
//extern sigaction
func sigaction(signum uint32, act *_sigaction, oact *_sigaction) int32

//go:noescape
//extern sigprocmask
func sigprocmask(how int32, set *sigset, oldset *sigset) int32

//go:noescape
//extern sigfillset
func sigfillset(set *sigset) int32

//go:noescape
//extern sigemptyset
func sigemptyset(set *sigset) int32

//go:noescape
//extern sigaddset
func c_sigaddset(set *sigset, signum uint32) int32

//go:noescape
//extern sigdelset
func c_sigdelset(set *sigset, signum uint32) int32

//go:noescape
//extern sigaltstack
func sigaltstack(ss *_stack_t, oss *_stack_t) int32

//extern raise
func raise(sig uint32) int32

//extern getpid
func getpid() _pid_t

//extern kill
func kill(pid _pid_t, sig uint32) int32

//go:noescape
//extern setitimer
func setitimer(which int32, new *_itimerval, old *_itimerval) int32

type sigctxt struct {
	info *_siginfo_t
	ctxt unsafe.Pointer
}

func (c *sigctxt) sigcode() uint64 {
	return uint64(c.info.si_code)
}

//go:nosplit
//go:nowritebarrierrec
func setsig(i uint32, fn uintptr) {
	var sa _sigaction
	sa.sa_flags = _SA_SIGINFO | _SA_RESTART

	// For gccgo we do not set SA_ONSTACK for a signal that can
	// cause a panic.  Instead, we trust that the split stack has
	// enough room to start the signal handler.  This is because
	// otherwise we have no good way to switch back to the
	// original stack before panicing.
	if sigtable[i].flags&_SigPanic == 0 {
		sa.sa_flags |= _SA_ONSTACK
	}

	sigfillset((*sigset)(unsafe.Pointer(&sa.sa_mask)))
	setSigactionHandler(&sa, fn)
	sigaction(i, &sa, nil)
}

//go:nosplit
//go:nowritebarrierrec
func setsigstack(i uint32) {
	var sa _sigaction
	sigaction(i, nil, &sa)
	handler := getSigactionHandler(&sa)
	if handler == 0 || handler == _SIG_DFL || handler == _SIG_IGN || sa.sa_flags&_SA_ONSTACK != 0 {
		return
	}
	if sigtable[i].flags&_SigPanic != 0 {
		return
	}
	sa.sa_flags |= _SA_ONSTACK
	sigaction(i, &sa, nil)
}

//go:nosplit
//go:nowritebarrierrec
func getsig(i uint32) uintptr {
	var sa _sigaction
	if sigaction(i, nil, &sa) < 0 {
		// On GNU/Linux glibc rejects attempts to call
		// sigaction with signal 32 (SIGCANCEL) or 33 (SIGSETXID).
		if GOOS == "linux" && (i == 32 || i == 33) {
			return _SIG_DFL
		}
		throw("sigaction read failure")
	}
	return getSigactionHandler(&sa)
}

func signalstack(p unsafe.Pointer, n uintptr)

//go:nosplit
//go:nowritebarrierrec
func raiseproc(sig uint32) {
	kill(getpid(), sig)
}

//go:nosplit
//go:nowritebarrierrec
func sigfwd(fn uintptr, sig uint32, info *_siginfo_t, ctx unsafe.Pointer) {
	f1 := [1]uintptr{fn}
	f2 := &f1
	f3 := *(*func(uint32, *_siginfo_t, unsafe.Pointer))(unsafe.Pointer(&f2))
	f3(sig, info, ctx)
}

//go:nosplit
//go:nowritebarrierrec
func sigaddset(mask *sigset, i int) {
	c_sigaddset(mask, uint32(i))
}

func sigdelset(mask *sigset, i int) {
	c_sigdelset(mask, uint32(i))
}
