// 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(getSiginfoCode(c.info))
}

//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))
}
