mirror of
https://github.com/golang/go.git
synced 2025-05-19 06:14:40 +00:00
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: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
e6143e17d3
commit
d15295c679
@ -33,7 +33,7 @@ type Fpxreg1 C.struct__fpxreg
|
||||
type Xmmreg1 C.struct__xmmreg
|
||||
type Fpstate1 C.struct__fpstate
|
||||
type Fpreg1 C.struct__fpreg
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type StackT C.stack_t
|
||||
type Mcontext C.mcontext_t
|
||||
type Ucontext C.ucontext_t
|
||||
type Sigcontext C.struct_sigcontext
|
||||
|
@ -83,12 +83,6 @@ const (
|
||||
_EVFILT_WRITE = 0x1
|
||||
)
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -83,13 +83,6 @@ const (
|
||||
_EVFILT_WRITE = 0x1
|
||||
)
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -83,12 +83,6 @@ const (
|
||||
_EVFILT_WRITE = 0x1
|
||||
)
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -110,20 +110,13 @@ type semt struct {
|
||||
sem_pad2 [2]uint64
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp *byte
|
||||
ss_size uint64
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__sigbits [4]uint32
|
||||
}
|
||||
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_size uint64
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ type Timespec C.struct_timespec
|
||||
type Timeval C.struct_timeval
|
||||
type Sigaction C.struct_kernel_sigaction
|
||||
type Siginfo C.siginfo_t
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type StackT C.stack_t
|
||||
type Sigcontext C.struct_sigcontext
|
||||
type Ucontext C.struct_ucontext
|
||||
type Itimerval C.struct_itimerval
|
||||
|
@ -35,7 +35,7 @@ type Gregset C.elf_gregset_t
|
||||
type FPregset C.elf_fpregset_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.
|
||||
// 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 (
|
||||
)
|
||||
|
||||
type Timespec C.struct_timespec
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type StackT C.stack_t
|
||||
type Sigcontext C.struct_sigcontext
|
||||
type Ucontext C.struct_ucontext
|
||||
type Timeval C.struct_timeval
|
||||
|
@ -109,7 +109,6 @@ const (
|
||||
|
||||
type Rtprio C.struct_rtprio
|
||||
type Lwpparams C.struct_lwp_params
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type Sigset C.struct___sigset
|
||||
type StackT C.stack_t
|
||||
|
||||
|
@ -99,13 +99,6 @@ type lwpparams struct {
|
||||
tid2 unsafe.Pointer // *int32
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -117,7 +117,6 @@ const (
|
||||
|
||||
type Rtprio C.struct_rtprio
|
||||
type ThrParam C.struct_thr_param
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type Sigset C.struct___sigset
|
||||
type StackT C.stack_t
|
||||
|
||||
|
@ -109,12 +109,6 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp *int8
|
||||
ss_size uint32
|
||||
ss_flags int32
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -110,13 +110,6 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp *int8
|
||||
ss_size uint64
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -109,12 +109,6 @@ type thrparam struct {
|
||||
spare [3]uintptr
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp *uint8
|
||||
ss_size uint32
|
||||
ss_flags int32
|
||||
}
|
||||
|
||||
type sigset struct {
|
||||
__bits [4]uint32
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ type siginfo struct {
|
||||
si_addr uint32
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
ss_size uintptr
|
||||
@ -208,7 +208,7 @@ type sigcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint32
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_mcontext sigcontext
|
||||
uc_sigmask uint32
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ type fpreg1 struct {
|
||||
exponent uint16
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
@ -221,7 +221,7 @@ type mcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_mcontext mcontext
|
||||
uc_sigmask usigset
|
||||
__fpregs_mem fpstate
|
||||
|
@ -101,7 +101,7 @@ func (ts *timespec) set_nsec(x int32) {
|
||||
ts.tv_nsec = x
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
ss_size uintptr
|
||||
@ -134,7 +134,7 @@ type sigcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint32
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_mcontext sigcontext
|
||||
uc_sigmask uint32
|
||||
__unused [31]int32
|
||||
|
@ -153,7 +153,7 @@ type usigset struct {
|
||||
__val [16]uint64
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
@ -179,7 +179,7 @@ type sockaddr_un struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_sigmask uint64
|
||||
_pad [(1024 - 64) / 8]byte
|
||||
_pad2 [8]byte // sigcontext must be aligned to 16-byte
|
||||
|
@ -150,7 +150,7 @@ const (
|
||||
_SA_RESTORER = 0
|
||||
)
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
@ -177,7 +177,7 @@ type sigcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_mcontext sigcontext
|
||||
uc_sigmask uint64
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ type vreg struct {
|
||||
u [4]uint32
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
@ -193,7 +193,7 @@ type sigcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_sigmask uint64
|
||||
__unused [15]uint64
|
||||
uc_mcontext sigcontext
|
||||
|
@ -170,7 +170,7 @@ type vreg struct {
|
||||
u [4]uint32
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
@ -193,7 +193,7 @@ type sigcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_sigmask uint64
|
||||
__unused [15]uint64
|
||||
uc_mcontext sigcontext
|
||||
|
@ -143,7 +143,7 @@ const (
|
||||
_SA_RESTORER = 0
|
||||
)
|
||||
|
||||
type sigaltstackt struct {
|
||||
type stackt struct {
|
||||
ss_sp *byte
|
||||
ss_flags int32
|
||||
ss_size uintptr
|
||||
@ -161,7 +161,7 @@ type sigcontext struct {
|
||||
type ucontext struct {
|
||||
uc_flags uint64
|
||||
uc_link *ucontext
|
||||
uc_stack sigaltstackt
|
||||
uc_stack stackt
|
||||
uc_mcontext sigcontext
|
||||
uc_sigmask uint64
|
||||
}
|
||||
|
@ -109,7 +109,6 @@ const (
|
||||
EVFILT_WRITE = C.EVFILT_WRITE
|
||||
)
|
||||
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type Sigset C.sigset_t
|
||||
type Siginfo C.struct__ksiginfo
|
||||
|
||||
|
@ -106,7 +106,6 @@ const (
|
||||
|
||||
type TforkT C.struct___tfork
|
||||
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type Sigcontext C.struct_sigcontext
|
||||
type Siginfo C.siginfo_t
|
||||
type Sigset C.sigset_t
|
||||
|
@ -90,12 +90,6 @@ type tforkt struct {
|
||||
tf_stack uintptr
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
}
|
||||
|
||||
type sigcontext struct {
|
||||
sc_gs uint32
|
||||
sc_fs uint32
|
||||
|
@ -90,13 +90,6 @@ type tforkt struct {
|
||||
tf_stack uintptr
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
pad_cgo_0 [4]byte
|
||||
}
|
||||
|
||||
type sigcontext struct {
|
||||
sc_rdi uint64
|
||||
sc_rsi uint64
|
||||
|
@ -90,12 +90,6 @@ type tforkt struct {
|
||||
tf_stack uintptr
|
||||
}
|
||||
|
||||
type sigaltstackt struct {
|
||||
ss_sp uintptr
|
||||
ss_size uintptr
|
||||
ss_flags int32
|
||||
}
|
||||
|
||||
type sigcontext struct {
|
||||
__sc_unused int32
|
||||
sc_mask int32
|
||||
|
@ -133,7 +133,6 @@ const (
|
||||
|
||||
type SemT C.sem_t
|
||||
|
||||
type SigaltstackT C.struct_sigaltstack
|
||||
type Sigset C.sigset_t
|
||||
type StackT C.stack_t
|
||||
|
||||
|
@ -209,22 +209,8 @@ func miniterrno()
|
||||
func minit() {
|
||||
_g_ := getg()
|
||||
asmcgocall(unsafe.Pointer(funcPC(miniterrno)), unsafe.Pointer(&libc____errno))
|
||||
// Initialize signal handling
|
||||
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 + 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
|
||||
}
|
||||
|
||||
minitSignalStack()
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := _g_.m.sigmask
|
||||
@ -318,17 +304,10 @@ func getsig(i int32) uintptr {
|
||||
return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st sigaltstackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = (*byte)(unsafe.Pointer(sp))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
@ -539,7 +518,7 @@ func sigaction(sig int32, act *sigactiont, oact *sigactiont) /* int32 */ {
|
||||
|
||||
//go:nosplit
|
||||
//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)))
|
||||
}
|
||||
|
||||
|
@ -183,21 +183,7 @@ func minit() {
|
||||
// The signal handler handles it directly.
|
||||
// The sigaltstack assembly function does nothing.
|
||||
if GOARCH != "arm" && GOARCH != "arm64" {
|
||||
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
|
||||
}
|
||||
minitSignalStack()
|
||||
}
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
@ -563,17 +549,10 @@ func getsig(i int32) uintptr {
|
||||
return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u))
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st stackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = (*byte)(unsafe.Pointer(sp))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -22,7 +22,7 @@ type mOS struct{}
|
||||
func lwp_create(param *lwpparams) int32
|
||||
|
||||
//go:noescape
|
||||
func sigaltstack(new, old *sigaltstackt)
|
||||
func sigaltstack(new, old *stackt)
|
||||
|
||||
//go:noescape
|
||||
func sigaction(sig int32, new, old *sigactiont)
|
||||
@ -185,22 +185,7 @@ func minit() {
|
||||
// m.procid is a uint64, but lwp_start writes an int32. Fix it up.
|
||||
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
|
||||
|
||||
// Initialize signal handling.
|
||||
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
|
||||
}
|
||||
minitSignalStack()
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := _g_.m.sigmask
|
||||
@ -292,17 +277,10 @@ func getsig(i int32) uintptr {
|
||||
return sa.sa_sigaction
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st sigaltstackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = sp
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -175,22 +175,7 @@ func minit() {
|
||||
_g_.m.procid = uint64(*(*uint32)(unsafe.Pointer(&_g_.m.procid)))
|
||||
}
|
||||
|
||||
// Initialize signal handling.
|
||||
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
|
||||
}
|
||||
minitSignalStack()
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := _g_.m.sigmask
|
||||
@ -282,17 +267,10 @@ func getsig(i int32) uintptr {
|
||||
return sa.sa_handler
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st stackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = sp
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -260,21 +260,7 @@ func minit() {
|
||||
// Initialize signal handling.
|
||||
_g_ := getg()
|
||||
|
||||
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
|
||||
}
|
||||
minitSignalStack()
|
||||
|
||||
// for debuggers, in case cgo created the thread
|
||||
_g_.m.procid = uint64(gettid())
|
||||
@ -341,7 +327,7 @@ func cgoSigtramp()
|
||||
func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
|
||||
|
||||
//go:noescape
|
||||
func sigaltstack(new, old *sigaltstackt)
|
||||
func sigaltstack(new, old *stackt)
|
||||
|
||||
//go:noescape
|
||||
func setitimer(mode int32, new, old *itimerval)
|
||||
@ -419,15 +405,8 @@ func getsig(i int32) uintptr {
|
||||
return sa.sa_handler
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st sigaltstackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = (*byte)(unsafe.Pointer(sp))
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func setitimer(mode int32, new, old *itimerval)
|
||||
func sigaction(sig int32, new, old *sigactiont)
|
||||
|
||||
//go:noescape
|
||||
func sigaltstack(new, old *sigaltstackt)
|
||||
func sigaltstack(new, old *stackt)
|
||||
|
||||
//go:noescape
|
||||
func sigprocmask(how int32, new, old *sigset)
|
||||
@ -303,17 +303,10 @@ func getsig(i int32) uintptr {
|
||||
return sa.sa_sigaction
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st sigaltstackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = sp
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -218,22 +218,7 @@ func minit() {
|
||||
// m.procid is a uint64, but tfork writes an int32. Fix it up.
|
||||
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
|
||||
|
||||
// Initialize signal handling
|
||||
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
|
||||
}
|
||||
minitSignalStack()
|
||||
|
||||
// restore signal mask from m.sigmask and unblock essential signals
|
||||
nmask := _g_.m.sigmask
|
||||
@ -298,17 +283,10 @@ func getsig(i int32) uintptr {
|
||||
return sa.sa_sigaction
|
||||
}
|
||||
|
||||
// setSignaltstackSP sets the ss_sp field of a stackt.
|
||||
//go:nosplit
|
||||
func signalstack(s *stack) {
|
||||
var st stackt
|
||||
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)
|
||||
func setSignalstackSP(s *stackt, sp uintptr) {
|
||||
s.ss_sp = sp
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -77,11 +77,7 @@ func sigtrampgo(fn uintptr, infostyle, sig uint32, info *siginfo, ctx unsafe.Poi
|
||||
setg(nil)
|
||||
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
|
||||
}
|
||||
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
|
||||
setGsignalStack(&st)
|
||||
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
|
||||
}
|
||||
|
||||
|
@ -73,11 +73,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||
setg(nil)
|
||||
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
|
||||
}
|
||||
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
|
||||
setGsignalStack(&st)
|
||||
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
|
||||
}
|
||||
|
||||
|
@ -73,11 +73,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||
setg(nil)
|
||||
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
|
||||
}
|
||||
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
|
||||
setGsignalStack(&st)
|
||||
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||
// If some non-Go code called sigaltstack, adjust.
|
||||
sp := uintptr(unsafe.Pointer(&sig))
|
||||
if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
|
||||
var st sigaltstackt
|
||||
var st stackt
|
||||
sigaltstack(nil, &st)
|
||||
if st.ss_flags&_SS_DISABLE != 0 {
|
||||
setg(nil)
|
||||
@ -44,11 +44,7 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||
setg(nil)
|
||||
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
|
||||
}
|
||||
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
|
||||
setGsignalStack(&st)
|
||||
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
|
||||
}
|
||||
|
||||
|
@ -525,6 +525,58 @@ func unblocksig(sig int32) {
|
||||
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.
|
||||
//go:nosplit
|
||||
func setsigsegv(pc uintptr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user