Commit d15295c6 authored by Ian Lance Taylor's avatar Ian Lance Taylor

runtime: unify handling of alternate signal stack

Change all Unix systems to use stackt for the alternate signal
stack (some were using sigaltstackt). Add OS-specific setSignalstackSP
function to handle different types for ss_sp field, and unify all
OS-specific signalstack functions into one. Unify handling of alternate
signal stack in OS-specific minit and sigtrampgo functions via new
functions minitSignalstack and setGsignalStack.

Change-Id: Idc316dc69b1dd725717acdf61a1cd8b9f33ed174
Reviewed-on: https://go-review.googlesource.com/29757
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent e6143e17
...@@ -33,7 +33,7 @@ type Fpxreg1 C.struct__fpxreg ...@@ -33,7 +33,7 @@ type Fpxreg1 C.struct__fpxreg
type Xmmreg1 C.struct__xmmreg type Xmmreg1 C.struct__xmmreg
type Fpstate1 C.struct__fpstate type Fpstate1 C.struct__fpstate
type Fpreg1 C.struct__fpreg type Fpreg1 C.struct__fpreg
type SigaltstackT C.struct_sigaltstack type StackT C.stack_t
type Mcontext C.mcontext_t type Mcontext C.mcontext_t
type Ucontext C.ucontext_t type Ucontext C.ucontext_t
type Sigcontext C.struct_sigcontext type Sigcontext C.struct_sigcontext
...@@ -83,12 +83,6 @@ const ( ...@@ -83,12 +83,6 @@ const (
_EVFILT_WRITE = 0x1 _EVFILT_WRITE = 0x1
) )
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -83,13 +83,6 @@ const ( ...@@ -83,13 +83,6 @@ const (
_EVFILT_WRITE = 0x1 _EVFILT_WRITE = 0x1
) )
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -83,12 +83,6 @@ const ( ...@@ -83,12 +83,6 @@ const (
_EVFILT_WRITE = 0x1 _EVFILT_WRITE = 0x1
) )
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -110,20 +110,13 @@ type semt struct { ...@@ -110,20 +110,13 @@ type semt struct {
sem_pad2 [2]uint64 sem_pad2 [2]uint64
} }
type sigaltstackt struct {
ss_sp *byte
ss_size uint64
ss_flags int32
pad_cgo_0 [4]byte
}
type sigset struct { type sigset struct {
__sigbits [4]uint32 __sigbits [4]uint32
} }
type stackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_size uint64 ss_size uintptr
ss_flags int32 ss_flags int32
pad_cgo_0 [4]byte pad_cgo_0 [4]byte
} }
......
...@@ -139,7 +139,7 @@ type Timespec C.struct_timespec ...@@ -139,7 +139,7 @@ type Timespec C.struct_timespec
type Timeval C.struct_timeval type Timeval C.struct_timeval
type Sigaction C.struct_kernel_sigaction type Sigaction C.struct_kernel_sigaction
type Siginfo C.siginfo_t type Siginfo C.siginfo_t
type SigaltstackT C.struct_sigaltstack type StackT C.stack_t
type Sigcontext C.struct_sigcontext type Sigcontext C.struct_sigcontext
type Ucontext C.struct_ucontext type Ucontext C.struct_ucontext
type Itimerval C.struct_itimerval type Itimerval C.struct_itimerval
......
...@@ -35,7 +35,7 @@ type Gregset C.elf_gregset_t ...@@ -35,7 +35,7 @@ type Gregset C.elf_gregset_t
type FPregset C.elf_fpregset_t type FPregset C.elf_fpregset_t
type Vreg C.elf_vrreg_t type Vreg C.elf_vrreg_t
type SigaltstackT C.struct_sigaltstack type StackT C.stack_t
// PPC64 uses sigcontext in place of mcontext in ucontext. // PPC64 uses sigcontext in place of mcontext in ucontext.
// see http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/include/uapi/asm/ucontext.h // see http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/include/uapi/asm/ucontext.h
......
...@@ -115,7 +115,7 @@ const ( ...@@ -115,7 +115,7 @@ const (
) )
type Timespec C.struct_timespec type Timespec C.struct_timespec
type SigaltstackT C.struct_sigaltstack type StackT C.stack_t
type Sigcontext C.struct_sigcontext type Sigcontext C.struct_sigcontext
type Ucontext C.struct_ucontext type Ucontext C.struct_ucontext
type Timeval C.struct_timeval type Timeval C.struct_timeval
......
...@@ -109,7 +109,6 @@ const ( ...@@ -109,7 +109,6 @@ const (
type Rtprio C.struct_rtprio type Rtprio C.struct_rtprio
type Lwpparams C.struct_lwp_params type Lwpparams C.struct_lwp_params
type SigaltstackT C.struct_sigaltstack
type Sigset C.struct___sigset type Sigset C.struct___sigset
type StackT C.stack_t type StackT C.stack_t
......
...@@ -99,13 +99,6 @@ type lwpparams struct { ...@@ -99,13 +99,6 @@ type lwpparams struct {
tid2 unsafe.Pointer // *int32 tid2 unsafe.Pointer // *int32
} }
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -117,7 +117,6 @@ const ( ...@@ -117,7 +117,6 @@ const (
type Rtprio C.struct_rtprio type Rtprio C.struct_rtprio
type ThrParam C.struct_thr_param type ThrParam C.struct_thr_param
type SigaltstackT C.struct_sigaltstack
type Sigset C.struct___sigset type Sigset C.struct___sigset
type StackT C.stack_t type StackT C.stack_t
......
...@@ -109,12 +109,6 @@ type thrparam struct { ...@@ -109,12 +109,6 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type sigaltstackt struct {
ss_sp *int8
ss_size uint32
ss_flags int32
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -110,13 +110,6 @@ type thrparam struct { ...@@ -110,13 +110,6 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type sigaltstackt struct {
ss_sp *int8
ss_size uint64
ss_flags int32
pad_cgo_0 [4]byte
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -109,12 +109,6 @@ type thrparam struct { ...@@ -109,12 +109,6 @@ type thrparam struct {
spare [3]uintptr spare [3]uintptr
} }
type sigaltstackt struct {
ss_sp *uint8
ss_size uint32
ss_flags int32
}
type sigset struct { type sigset struct {
__bits [4]uint32 __bits [4]uint32
} }
......
...@@ -168,7 +168,7 @@ type siginfo struct { ...@@ -168,7 +168,7 @@ type siginfo struct {
si_addr uint32 si_addr uint32
} }
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
ss_size uintptr ss_size uintptr
...@@ -208,7 +208,7 @@ type sigcontext struct { ...@@ -208,7 +208,7 @@ type sigcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint32 uc_flags uint32
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_mcontext sigcontext uc_mcontext sigcontext
uc_sigmask uint32 uc_sigmask uint32
} }
......
...@@ -205,7 +205,7 @@ type fpreg1 struct { ...@@ -205,7 +205,7 @@ type fpreg1 struct {
exponent uint16 exponent uint16
} }
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
pad_cgo_0 [4]byte pad_cgo_0 [4]byte
...@@ -221,7 +221,7 @@ type mcontext struct { ...@@ -221,7 +221,7 @@ type mcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint64 uc_flags uint64
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_mcontext mcontext uc_mcontext mcontext
uc_sigmask usigset uc_sigmask usigset
__fpregs_mem fpstate __fpregs_mem fpstate
......
...@@ -101,7 +101,7 @@ func (ts *timespec) set_nsec(x int32) { ...@@ -101,7 +101,7 @@ func (ts *timespec) set_nsec(x int32) {
ts.tv_nsec = x ts.tv_nsec = x
} }
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
ss_size uintptr ss_size uintptr
...@@ -134,7 +134,7 @@ type sigcontext struct { ...@@ -134,7 +134,7 @@ type sigcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint32 uc_flags uint32
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_mcontext sigcontext uc_mcontext sigcontext
uc_sigmask uint32 uc_sigmask uint32
__unused [31]int32 __unused [31]int32
......
...@@ -153,7 +153,7 @@ type usigset struct { ...@@ -153,7 +153,7 @@ type usigset struct {
__val [16]uint64 __val [16]uint64
} }
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
pad_cgo_0 [4]byte pad_cgo_0 [4]byte
...@@ -179,7 +179,7 @@ type sockaddr_un struct { ...@@ -179,7 +179,7 @@ type sockaddr_un struct {
type ucontext struct { type ucontext struct {
uc_flags uint64 uc_flags uint64
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_sigmask uint64 uc_sigmask uint64
_pad [(1024 - 64) / 8]byte _pad [(1024 - 64) / 8]byte
_pad2 [8]byte // sigcontext must be aligned to 16-byte _pad2 [8]byte // sigcontext must be aligned to 16-byte
......
...@@ -150,7 +150,7 @@ const ( ...@@ -150,7 +150,7 @@ const (
_SA_RESTORER = 0 _SA_RESTORER = 0
) )
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_size uintptr ss_size uintptr
ss_flags int32 ss_flags int32
...@@ -177,7 +177,7 @@ type sigcontext struct { ...@@ -177,7 +177,7 @@ type sigcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint64 uc_flags uint64
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_mcontext sigcontext uc_mcontext sigcontext
uc_sigmask uint64 uc_sigmask uint64
} }
...@@ -170,7 +170,7 @@ type vreg struct { ...@@ -170,7 +170,7 @@ type vreg struct {
u [4]uint32 u [4]uint32
} }
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
pad_cgo_0 [4]byte pad_cgo_0 [4]byte
...@@ -193,7 +193,7 @@ type sigcontext struct { ...@@ -193,7 +193,7 @@ type sigcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint64 uc_flags uint64
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_sigmask uint64 uc_sigmask uint64
__unused [15]uint64 __unused [15]uint64
uc_mcontext sigcontext uc_mcontext sigcontext
......
...@@ -170,7 +170,7 @@ type vreg struct { ...@@ -170,7 +170,7 @@ type vreg struct {
u [4]uint32 u [4]uint32
} }
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
pad_cgo_0 [4]byte pad_cgo_0 [4]byte
...@@ -193,7 +193,7 @@ type sigcontext struct { ...@@ -193,7 +193,7 @@ type sigcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint64 uc_flags uint64
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_sigmask uint64 uc_sigmask uint64
__unused [15]uint64 __unused [15]uint64
uc_mcontext sigcontext uc_mcontext sigcontext
......
...@@ -143,7 +143,7 @@ const ( ...@@ -143,7 +143,7 @@ const (
_SA_RESTORER = 0 _SA_RESTORER = 0
) )
type sigaltstackt struct { type stackt struct {
ss_sp *byte ss_sp *byte
ss_flags int32 ss_flags int32
ss_size uintptr ss_size uintptr
...@@ -161,7 +161,7 @@ type sigcontext struct { ...@@ -161,7 +161,7 @@ type sigcontext struct {
type ucontext struct { type ucontext struct {
uc_flags uint64 uc_flags uint64
uc_link *ucontext uc_link *ucontext
uc_stack sigaltstackt uc_stack stackt
uc_mcontext sigcontext uc_mcontext sigcontext
uc_sigmask uint64 uc_sigmask uint64
} }
...@@ -109,7 +109,6 @@ const ( ...@@ -109,7 +109,6 @@ const (
EVFILT_WRITE = C.EVFILT_WRITE EVFILT_WRITE = C.EVFILT_WRITE
) )
type SigaltstackT C.struct_sigaltstack
type Sigset C.sigset_t type Sigset C.sigset_t
type Siginfo C.struct__ksiginfo type Siginfo C.struct__ksiginfo
......
...@@ -106,7 +106,6 @@ const ( ...@@ -106,7 +106,6 @@ const (
type TforkT C.struct___tfork type TforkT C.struct___tfork
type SigaltstackT C.struct_sigaltstack
type Sigcontext C.struct_sigcontext type Sigcontext C.struct_sigcontext
type Siginfo C.siginfo_t type Siginfo C.siginfo_t
type Sigset C.sigset_t type Sigset C.sigset_t
......
...@@ -90,12 +90,6 @@ type tforkt struct { ...@@ -90,12 +90,6 @@ type tforkt struct {
tf_stack uintptr tf_stack uintptr
} }
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
}
type sigcontext struct { type sigcontext struct {
sc_gs uint32 sc_gs uint32
sc_fs uint32 sc_fs uint32
......
...@@ -90,13 +90,6 @@ type tforkt struct { ...@@ -90,13 +90,6 @@ type tforkt struct {
tf_stack uintptr tf_stack uintptr
} }
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}
type sigcontext struct { type sigcontext struct {
sc_rdi uint64 sc_rdi uint64
sc_rsi uint64 sc_rsi uint64
......
...@@ -90,12 +90,6 @@ type tforkt struct { ...@@ -90,12 +90,6 @@ type tforkt struct {
tf_stack uintptr tf_stack uintptr
} }
type sigaltstackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
}
type sigcontext struct { type sigcontext struct {
__sc_unused int32 __sc_unused int32
sc_mask int32 sc_mask int32
......
...@@ -133,7 +133,6 @@ const ( ...@@ -133,7 +133,6 @@ const (
type SemT C.sem_t type SemT C.sem_t
type SigaltstackT C.struct_sigaltstack
type Sigset C.sigset_t type Sigset C.sigset_t
type StackT C.stack_t type StackT C.stack_t
......
...@@ -209,22 +209,8 @@ func miniterrno() ...@@ -209,22 +209,8 @@ func miniterrno()
func minit() { func minit() {
_g_ := getg() _g_ := getg()
asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno)) asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno))
// Initialize signal handling
var st sigaltstackt minitSignalStack()
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_g_.m.gsignal.stack.lo = stsp
_g_.m.gsignal.stack.hi = stsp + uintptr(st.ss_size)
_g_.m.gsignal.stackguard0 = stsp + _StackGuard
_g_.m.gsignal.stackguard1 = stsp + _StackGuard
_g_.m.gsignal.stackAlloc = uintptr(st.ss_size)
_g_.m.newSigstack = false
}
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask nmask := _g_.m.sigmask
...@@ -318,17 +304,10 @@ func getsig(i int32) uintptr { ...@@ -318,17 +304,10 @@ func getsig(i int32) uintptr {
return *((*uintptr)(unsafe.Pointer(&sa._funcptr))) return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st sigaltstackt s.ss_sp = (*byte)(unsafe.Pointer(sp))
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = (*byte)(unsafe.Pointer(s.lo))
st.ss_size = uint64(s.hi - s.lo)
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
//go:nosplit //go:nosplit
...@@ -539,7 +518,7 @@ func sigaction(sig int32, act *sigactiont, oact *sigactiont) /* int32 */ { ...@@ -539,7 +518,7 @@ func sigaction(sig int32, act *sigactiont, oact *sigactiont) /* int32 */ {
//go:nosplit //go:nosplit
//go:nowritebarrierrec //go:nowritebarrierrec
func sigaltstack(ss *sigaltstackt, oss *sigaltstackt) /* int32 */ { func sigaltstack(ss *stackt, oss *stackt) /* int32 */ {
sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss))) sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss)))
} }
......
...@@ -183,21 +183,7 @@ func minit() { ...@@ -183,21 +183,7 @@ func minit() {
// The signal handler handles it directly. // The signal handler handles it directly.
// The sigaltstack assembly function does nothing. // The sigaltstack assembly function does nothing.
if GOARCH != "arm" && GOARCH != "arm64" { if GOARCH != "arm" && GOARCH != "arm64" {
var st stackt minitSignalStack()
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_g_.m.gsignal.stack.lo = stsp
_g_.m.gsignal.stack.hi = stsp + st.ss_size
_g_.m.gsignal.stackguard0 = stsp + _StackGuard
_g_.m.gsignal.stackguard1 = stsp + _StackGuard
_g_.m.gsignal.stackAlloc = st.ss_size
_g_.m.newSigstack = false
}
} }
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
...@@ -563,17 +549,10 @@ func getsig(i int32) uintptr { ...@@ -563,17 +549,10 @@ func getsig(i int32) uintptr {
return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u)) return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u))
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st stackt s.ss_sp = (*byte)(unsafe.Pointer(sp))
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = (*byte)(unsafe.Pointer(s.lo))
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
//go:nosplit //go:nosplit
......
...@@ -22,7 +22,7 @@ type mOS struct{} ...@@ -22,7 +22,7 @@ type mOS struct{}
func lwp_create(param *lwpparams) int32 func lwp_create(param *lwpparams) int32
//go:noescape //go:noescape
func sigaltstack(new, old *sigaltstackt) func sigaltstack(new, old *stackt)
//go:noescape //go:noescape
func sigaction(sig int32, new, old *sigactiont) func sigaction(sig int32, new, old *sigactiont)
...@@ -185,22 +185,7 @@ func minit() { ...@@ -185,22 +185,7 @@ func minit() {
// m.procid is a uint64, but lwp_start writes an int32. Fix it up. // m.procid is a uint64, but lwp_start writes an int32. Fix it up.
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid))) _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
// Initialize signal handling. minitSignalStack()
var st sigaltstackt
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_g_.m.gsignal.stack.lo = stsp
_g_.m.gsignal.stack.hi = stsp + st.ss_size
_g_.m.gsignal.stackguard0 = stsp + _StackGuard
_g_.m.gsignal.stackguard1 = stsp + _StackGuard
_g_.m.gsignal.stackAlloc = st.ss_size
_g_.m.newSigstack = false
}
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask nmask := _g_.m.sigmask
...@@ -292,17 +277,10 @@ func getsig(i int32) uintptr { ...@@ -292,17 +277,10 @@ func getsig(i int32) uintptr {
return sa.sa_sigaction return sa.sa_sigaction
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st sigaltstackt s.ss_sp = sp
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = s.lo
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
//go:nosplit //go:nosplit
......
...@@ -175,22 +175,7 @@ func minit() { ...@@ -175,22 +175,7 @@ func minit() {
_g_.m.procid = uint64(*(*uint32)(unsafe.Pointer(&_g_.m.procid))) _g_.m.procid = uint64(*(*uint32)(unsafe.Pointer(&_g_.m.procid)))
} }
// Initialize signal handling. minitSignalStack()
var st stackt
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_g_.m.gsignal.stack.lo = stsp
_g_.m.gsignal.stack.hi = stsp + st.ss_size
_g_.m.gsignal.stackguard0 = stsp + _StackGuard
_g_.m.gsignal.stackguard1 = stsp + _StackGuard
_g_.m.gsignal.stackAlloc = st.ss_size
_g_.m.newSigstack = false
}
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask nmask := _g_.m.sigmask
...@@ -282,17 +267,10 @@ func getsig(i int32) uintptr { ...@@ -282,17 +267,10 @@ func getsig(i int32) uintptr {
return sa.sa_handler return sa.sa_handler
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st stackt s.ss_sp = sp
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = s.lo
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
//go:nosplit //go:nosplit
......
...@@ -260,21 +260,7 @@ func minit() { ...@@ -260,21 +260,7 @@ func minit() {
// Initialize signal handling. // Initialize signal handling.
_g_ := getg() _g_ := getg()
var st sigaltstackt minitSignalStack()
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_g_.m.gsignal.stack.lo = stsp
_g_.m.gsignal.stack.hi = stsp + st.ss_size
_g_.m.gsignal.stackguard0 = stsp + _StackGuard
_g_.m.gsignal.stackguard1 = stsp + _StackGuard
_g_.m.gsignal.stackAlloc = st.ss_size
_g_.m.newSigstack = false
}
// for debuggers, in case cgo created the thread // for debuggers, in case cgo created the thread
_g_.m.procid = uint64(gettid()) _g_.m.procid = uint64(gettid())
...@@ -341,7 +327,7 @@ func cgoSigtramp() ...@@ -341,7 +327,7 @@ func cgoSigtramp()
func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32 func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
//go:noescape //go:noescape
func sigaltstack(new, old *sigaltstackt) func sigaltstack(new, old *stackt)
//go:noescape //go:noescape
func setitimer(mode int32, new, old *itimerval) func setitimer(mode int32, new, old *itimerval)
...@@ -419,15 +405,8 @@ func getsig(i int32) uintptr { ...@@ -419,15 +405,8 @@ func getsig(i int32) uintptr {
return sa.sa_handler return sa.sa_handler
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st sigaltstackt s.ss_sp = (*byte)(unsafe.Pointer(sp))
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = (*byte)(unsafe.Pointer(s.lo))
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
...@@ -35,7 +35,7 @@ func setitimer(mode int32, new, old *itimerval) ...@@ -35,7 +35,7 @@ func setitimer(mode int32, new, old *itimerval)
func sigaction(sig int32, new, old *sigactiont) func sigaction(sig int32, new, old *sigactiont)
//go:noescape //go:noescape
func sigaltstack(new, old *sigaltstackt) func sigaltstack(new, old *stackt)
//go:noescape //go:noescape
func sigprocmask(how int32, new, old *sigset) func sigprocmask(how int32, new, old *sigset)
...@@ -303,17 +303,10 @@ func getsig(i int32) uintptr { ...@@ -303,17 +303,10 @@ func getsig(i int32) uintptr {
return sa.sa_sigaction return sa.sa_sigaction
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st sigaltstackt s.ss_sp = sp
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = s.lo
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
//go:nosplit //go:nosplit
......
...@@ -218,22 +218,7 @@ func minit() { ...@@ -218,22 +218,7 @@ func minit() {
// m.procid is a uint64, but tfork writes an int32. Fix it up. // m.procid is a uint64, but tfork writes an int32. Fix it up.
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid))) _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
// Initialize signal handling minitSignalStack()
var st stackt
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_g_.m.gsignal.stack.lo = stsp
_g_.m.gsignal.stack.hi = stsp + st.ss_size
_g_.m.gsignal.stackguard0 = stsp + _StackGuard
_g_.m.gsignal.stackguard1 = stsp + _StackGuard
_g_.m.gsignal.stackAlloc = st.ss_size
_g_.m.newSigstack = false
}
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask nmask := _g_.m.sigmask
...@@ -298,17 +283,10 @@ func getsig(i int32) uintptr { ...@@ -298,17 +283,10 @@ func getsig(i int32) uintptr {
return sa.sa_sigaction return sa.sa_sigaction
} }
// setSignaltstackSP sets the ss_sp field of a stackt.
//go:nosplit //go:nosplit
func signalstack(s *stack) { func setSignalstackSP(s *stackt, sp uintptr) {
var st stackt s.ss_sp = sp
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
st.ss_sp = s.lo
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
} }
//go:nosplit //go:nosplit
......
...@@ -77,11 +77,7 @@ func sigtrampgo(fn uintptr, infostyle, sig uint32, info *siginfo, ctx unsafe.Poi ...@@ -77,11 +77,7 @@ func sigtrampgo(fn uintptr, infostyle, sig uint32, info *siginfo, ctx unsafe.Poi
setg(nil) setg(nil)
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
} }
g.m.gsignal.stack.lo = stsp setGsignalStack(&st)
g.m.gsignal.stack.hi = stsp + st.ss_size
g.m.gsignal.stackguard0 = stsp + _StackGuard
g.m.gsignal.stackguard1 = stsp + _StackGuard
g.m.gsignal.stackAlloc = st.ss_size
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
} }
......
...@@ -73,11 +73,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { ...@@ -73,11 +73,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
setg(nil) setg(nil)
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
} }
g.m.gsignal.stack.lo = stsp setGsignalStack(&st)
g.m.gsignal.stack.hi = stsp + st.ss_size
g.m.gsignal.stackguard0 = stsp + _StackGuard
g.m.gsignal.stackguard1 = stsp + _StackGuard
g.m.gsignal.stackAlloc = st.ss_size
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
} }
......
...@@ -73,11 +73,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { ...@@ -73,11 +73,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
setg(nil) setg(nil)
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
} }
g.m.gsignal.stack.lo = stsp setGsignalStack(&st)
g.m.gsignal.stack.hi = stsp + st.ss_size
g.m.gsignal.stackguard0 = stsp + _StackGuard
g.m.gsignal.stackguard1 = stsp + _StackGuard
g.m.gsignal.stackAlloc = st.ss_size
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
} }
......
...@@ -33,7 +33,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { ...@@ -33,7 +33,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
// If some non-Go code called sigaltstack, adjust. // If some non-Go code called sigaltstack, adjust.
sp := uintptr(unsafe.Pointer(&sig)) sp := uintptr(unsafe.Pointer(&sig))
if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi { if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
var st sigaltstackt var st stackt
sigaltstack(nil, &st) sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 { if st.ss_flags&_SS_DISABLE != 0 {
setg(nil) setg(nil)
...@@ -44,11 +44,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { ...@@ -44,11 +44,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
setg(nil) setg(nil)
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
} }
g.m.gsignal.stack.lo = stsp setGsignalStack(&st)
g.m.gsignal.stack.hi = stsp + st.ss_size
g.m.gsignal.stackguard0 = stsp + _StackGuard
g.m.gsignal.stackguard1 = stsp + _StackGuard
g.m.gsignal.stackAlloc = st.ss_size
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
} }
......
...@@ -525,6 +525,58 @@ func unblocksig(sig int32) { ...@@ -525,6 +525,58 @@ func unblocksig(sig int32) {
sigprocmask(_SIG_UNBLOCK, &set, nil) sigprocmask(_SIG_UNBLOCK, &set, nil)
} }
// minitSignalStack is called when initializing a new m to set the
// alternate signal stack. If the alternate signal stack is not set
// for the thread (the normal case) then set the alternate signal
// stack to the gsignal stack. If the alternate signal stack is set
// for the thread (the case when a non-Go thread sets the alternate
// signal stack and then calls a Go function) then set the gsignal
// stack to the alternate signal stack. Record which choice was made
// in newSigstack, so that it can be undone in unminit.
func minitSignalStack() {
_g_ := getg()
var st stackt
sigaltstack(nil, &st)
if st.ss_flags&_SS_DISABLE != 0 {
signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true
} else {
setGsignalStack(&st)
_g_.m.newSigstack = false
}
}
// setGsignalStack sets the gsignal stack of the current m to an
// alternate signal stack returned from the sigaltstack system call.
// This is used when handling a signal if non-Go code has set the
// alternate signal stack.
//go:nosplit
//go:nowritebarrierrec
func setGsignalStack(st *stackt) {
g := getg()
stsp := uintptr(unsafe.Pointer(st.ss_sp))
g.m.gsignal.stack.lo = stsp
g.m.gsignal.stack.hi = stsp + st.ss_size
g.m.gsignal.stackguard0 = stsp + _StackGuard
g.m.gsignal.stackguard1 = stsp + _StackGuard
g.m.gsignal.stackAlloc = st.ss_size
}
// signalstack sets the current thread's alternate signal stack to s.
// If s is nil, the current thread's alternate signal stack is disabled.
//go:nosplit
func signalstack(s *stack) {
var st stackt
if s == nil {
st.ss_flags = _SS_DISABLE
} else {
setSignalstackSP(&st, s.lo)
st.ss_size = s.hi - s.lo
st.ss_flags = 0
}
sigaltstack(&st, nil)
}
// setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault.
//go:nosplit //go:nosplit
func setsigsegv(pc uintptr) { func setsigsegv(pc uintptr) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment