gcc/libgo/go/runtime/signal_gccgo.go
A. Wilcox 208b7d85d7 runtime: add special handling for signal 34
The musl libc uses signal 34 internally for setgid (similar to how glibc
uses signal 32 and signal 33).  For this reason, special handling is
needed for this signal in the runtime. The gc implementation already
handles the signal accordingly.  As such, this commit intends to
simply copy the behavior of the Google Go implementation to libgo.

See https://go.dev/issues/39343

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/400594
2022-04-18 15:16:35 -07:00

143 lines
3.4 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 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-sysinfo sigaction
func sigaction(signum uint32, act *_sigaction, oact *_sigaction) int32
//go:noescape
//extern-sysinfo sigprocmask
func sigprocmask(how int32, set *sigset, oldset *sigset) int32
//go:noescape
//extern-sysinfo sigfillset
func sigfillset(set *sigset) int32
//go:noescape
//extern-sysinfo sigemptyset
func sigemptyset(set *sigset) int32
//go:noescape
//extern-sysinfo sigaddset
func c_sigaddset(set *sigset, signum uint32) int32
//go:noescape
//extern-sysinfo sigdelset
func c_sigdelset(set *sigset, signum uint32) int32
//go:noescape
//extern-sysinfo sigaltstack
func sigaltstack(ss *_stack_t, oss *_stack_t) int32
//extern-sysinfo raise
func raise(sig uint32) int32
//extern-sysinfo getpid
func getpid() _pid_t
//extern-sysinfo kill
func kill(pid _pid_t, sig uint32) int32
//go:noescape
//extern-sysinfo 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).
// On musl signal 34 (SIGSYNCCALL) also needs to be treated accordingly.
if GOOS == "linux" && (i == 32 || i == 33 || i == 34) {
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))
}