]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: unify handling of alternate signal stack
authorIan Lance Taylor <iant@golang.org>
Sun, 25 Sep 2016 20:38:54 +0000 (13:38 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 26 Sep 2016 04:07:31 +0000 (04:07 +0000)
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>
40 files changed:
src/runtime/defs1_linux.go
src/runtime/defs1_netbsd_386.go
src/runtime/defs1_netbsd_amd64.go
src/runtime/defs1_netbsd_arm.go
src/runtime/defs1_solaris_amd64.go
src/runtime/defs2_linux.go
src/runtime/defs3_linux.go
src/runtime/defs_arm_linux.go
src/runtime/defs_dragonfly.go
src/runtime/defs_dragonfly_amd64.go
src/runtime/defs_freebsd.go
src/runtime/defs_freebsd_386.go
src/runtime/defs_freebsd_amd64.go
src/runtime/defs_freebsd_arm.go
src/runtime/defs_linux_386.go
src/runtime/defs_linux_amd64.go
src/runtime/defs_linux_arm.go
src/runtime/defs_linux_arm64.go
src/runtime/defs_linux_mips64x.go
src/runtime/defs_linux_ppc64.go
src/runtime/defs_linux_ppc64le.go
src/runtime/defs_linux_s390x.go
src/runtime/defs_netbsd.go
src/runtime/defs_openbsd.go
src/runtime/defs_openbsd_386.go
src/runtime/defs_openbsd_amd64.go
src/runtime/defs_openbsd_arm.go
src/runtime/defs_solaris.go
src/runtime/os3_solaris.go
src/runtime/os_darwin.go
src/runtime/os_dragonfly.go
src/runtime/os_freebsd.go
src/runtime/os_linux.go
src/runtime/os_netbsd.go
src/runtime/os_openbsd.go
src/runtime/signal_darwin.go
src/runtime/signal_freebsd.go
src/runtime/signal_openbsd.go
src/runtime/signal_sigtramp.go
src/runtime/signal_unix.go

index 87c6e02a41c7be5d969e7276ae62e0d226aaf3bd..e136d96e78dacdcb55fea6a333aa2113727de32a 100644 (file)
@@ -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
index f222bed9964eed280e800465ac5406286f215190..66f07ce5a5132d0760b1b58393c5678f851a639c 100644 (file)
@@ -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
 }
index c2bde4dabe12ff40f5efd0054892e82f2b37c7ac..9e314718f3a5d8de666f736fbcdd5414b2d881fd 100644 (file)
@@ -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
 }
index c976351a2709228967d9bd20866cae0003c2ce49..a67dd8ac95f60b5d988f70134e95049b9af55c7d 100644 (file)
@@ -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
 }
index 85a7b4002d364b5b6d6e99e6380e0f3d383aa115..5ee3c3fc275c2baa0a6e10f6b659a56fcb829a8a 100644 (file)
@@ -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
 }
index 9dea6a1f3ab4149729568acba03a459d89135df0..c10dfb86240002607a5d0f9cd413114137decd10 100644 (file)
@@ -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
index 489c130d0fe278e4828c040fb771047a5937135d..6aa3ee4309d8326d21581d20805a9d37a2bb92db 100644 (file)
@@ -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
index afd6897e30a86bb3a05f7724e81cf6a91bf29901..e51dd32b5b26bcac78f3acfc1965bb29f8b72db9 100644 (file)
@@ -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
index c5ebe75bb12f129c2ab42cb539d91813560bc531..ed00be0f443b386da022f02ab9c35bf74c2f976e 100644 (file)
@@ -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
 
index 3ac10b0904d883e018f93f49cfd94bdc290dc6ed..fc70103286c5aa4cac7601e5f4acc827777f33d5 100644 (file)
@@ -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
 }
index 0253685aace7fc0bb8495066a491a51895a17324..089cc0f818131ac6d839c398bc7b542608feac16 100644 (file)
@@ -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
 
index 6938c18736ff65034e434ebb673cd7b161e746d3..fe4499d0e0040d0e882a2dbbfa6341f5869371cc 100644 (file)
@@ -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
 }
index de98e7a3c13485bf62158819a319dd0290f2a918..edaaf66671e1b0475e16011c92489d014aed4a32 100644 (file)
@@ -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
 }
index 744330f4b3e2bf83e14250ea9d27a52a665f9962..9473757cd23bad790042f06fe6051c15bd06ad47 100644 (file)
@@ -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
 }
index 44d2fd1d48313c3c67242bf49075d221e7baef78..a7e435f854fe3f90e5f9c58b41b7da5f2c04b653 100644 (file)
@@ -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
 }
index 19362855e76c2aafb702644790185c4149742d5f..e8c6a212db770ba71f16eb2d9b19b7fb29e3a41c 100644 (file)
@@ -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
index b68b9642a9c1592c5daf2d3e897132723c7bb2ff..62ec8fab5e9b55d9c764b09fccacf128dc186ef0 100644 (file)
@@ -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
index d1b1a3677f5bdce4ff356c527c1adffdc881c22b..c295bc0257520948ffffb38212dadd89d33ae9f9 100644 (file)
@@ -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
index bb3cd9801e882be0e237c40de606da38fc20dc8b..df11cb0965d69c7cb448ddde861c5f2395a7bc8b 100644 (file)
@@ -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
 }
index 317a764a707a95672ffda092648d6a5c7d4948a5..45363d12854becdec3a59dfd2d9ddbfb97f9032e 100644 (file)
@@ -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
index 317a764a707a95672ffda092648d6a5c7d4948a5..45363d12854becdec3a59dfd2d9ddbfb97f9032e 100644 (file)
@@ -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
index 5f55d5a8894c5809144097821f1d62b79f7670f2..ab90723f754858bb2ac64636e85fbd8022f3d04d 100644 (file)
@@ -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
 }
index b27949e423f2e24ef9b9cb3f6840595127863d3e..56db1f015972eb0106313c0ab11f84e04b737616 100644 (file)
@@ -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
 
index 39224c988c4254579ca55a7cc7e412ec86577b8f..7e721504e65601135ea5e8d1793a93306f32cf0e 100644 (file)
@@ -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
index 4b60158115e7e2d3bcad80b5ad495a3eadcda40d..ce08111deab3efa9f4e8a89e488fca6738af4951 100644 (file)
@@ -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
index 3c27c9144fc7c384ebafb1716db2b69bfe79f29a..ea0709809a399560e7ed8222e26af8c38a3c0c87 100644 (file)
@@ -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
index aab9276f144afd47e574f7b30b0c3898b661ef88..b0fb639c72168a8372f2d3e376e7794de4fcfe15 100644 (file)
@@ -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
index ba44e5fd4d774b760374023a1cdce8c5ee04eb7c..0638e0b00ae0c64c79c5d1a5e62299ad07eb9585 100644 (file)
@@ -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
 
index d8390d6b1ef13b7f5b55d2f7520f9361317dbfb3..1b618fd42c9960c791d2138fb624a5aa7427c75b 100644 (file)
@@ -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)))
 }
 
index 5e71dabecd40db2a02add45c32f7a6f6506de3dd..9c00b02341e76cb75d7fa645b6137a9d4ac6400c 100644 (file)
@@ -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
index c71a4b9392636e6cee5c8fe58a969be18fa08a31..0bbe644440f556f06c9f11e40f40ba03723212f0 100644 (file)
@@ -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
index f35cdf3e9bcc32097ecd1ef1ce0dc9b1cedc306e..ae057b86ca84297d15a925e54480d50d87df0eb4 100644 (file)
@@ -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
index 7b3ce71feafce721da4a77bbbe3ff0a89213b2b6..88139ae2fc0a9751c709a1ad5ecdc379598c0980 100644 (file)
@@ -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))
 }
index 3a93d49ae08b27b41a7d70456bf533ff613f6040..81c52324ffac33723c77c5f5bf477b461b2802f8 100644 (file)
@@ -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
index 375c100aeca0ddede8ae14f4c0b3fda45c1c48be..714416fa5bc55c261a32fc266967adf8a9c5c72c 100644 (file)
@@ -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
index fb06de5509bfe4d0effbce24f1151826dd71032f..b75d24d63fd569b0705ca7d8cf324ec402d265b8 100644 (file)
@@ -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))
        }
 
index c6c126983ddedd432df3a14fcab05c6d65d21ee6..180b7bab4bf122242fc07dec1c723014a3af8cd2 100644 (file)
@@ -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))
        }
 
index efe30da5d962678477bdf1848350037e6fde503d..b10686adf38f0af44ea8fe3d3507d1554bc69226 100644 (file)
@@ -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))
        }
 
index dbbbcd0392b1fe252b76a06ce166f2b08926580f..1ada2759a73cda6a305b370806b8820850c96022 100644 (file)
@@ -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))
        }
 
index 31751185727f5d07c89fde49dde52c5f96123b01..c0952d7019ffe953ffe5fd1f6e91c3a8aa865d99 100644 (file)
@@ -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) {