mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			145 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
// 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 darwin dragonfly freebsd 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.
 | 
						|
 | 
						|
//extern sigaction
 | 
						|
func sigaction(signum uint32, act *_sigaction, oact *_sigaction) int32
 | 
						|
 | 
						|
//extern sigprocmask
 | 
						|
func sigprocmask(how int32, set *sigset, oldset *sigset) int32
 | 
						|
 | 
						|
//extern sigfillset
 | 
						|
func sigfillset(set *sigset) int32
 | 
						|
 | 
						|
//extern sigemptyset
 | 
						|
func sigemptyset(set *sigset) int32
 | 
						|
 | 
						|
//extern sigaddset
 | 
						|
func c_sigaddset(set *sigset, signum uint32) int32
 | 
						|
 | 
						|
//extern sigdelset
 | 
						|
func c_sigdelset(set *sigset, signum uint32) int32
 | 
						|
 | 
						|
//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
 | 
						|
 | 
						|
//extern setitimer
 | 
						|
func setitimer(which int32, new *_itimerval, old *_itimerval) int32
 | 
						|
 | 
						|
type sigTabT struct {
 | 
						|
	flags int32
 | 
						|
	name  string
 | 
						|
}
 | 
						|
 | 
						|
type sigctxt struct {
 | 
						|
	info *_siginfo_t
 | 
						|
	ctxt unsafe.Pointer
 | 
						|
}
 | 
						|
 | 
						|
func (c *sigctxt) sigcode() uint64 {
 | 
						|
	if c.info == nil {
 | 
						|
		// This can happen on Solaris 10.  We don't know the
 | 
						|
		// code, just avoid a misleading value.
 | 
						|
		return _SI_USER + 1
 | 
						|
	}
 | 
						|
	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))
 | 
						|
}
 |