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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent e6143e17
......@@ -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) {
......
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