From: Ian Lance Taylor Date: Mon, 26 Sep 2016 04:33:27 +0000 (-0700) Subject: runtime: unify sigtrampgo X-Git-Tag: go1.8beta1~1163 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c2735039f3ea4e44a3c1df6ef6715e83bc5257b1;p=gostls13.git runtime: unify sigtrampgo Combine the various versions of sigtrampgo into a single function in signal_unix.go. This requires defining a fixsigcode method on sigctxt for all operating systems; it only does something on Darwin. This also requires changing the darwin/amd64 signal handler to call sigreturn itself, rather than relying on sigtrampgo to call sigreturn for it. We can then drop the Darwin sigreturn function, as it is no longer used. Change-Id: I5a0b9d2d2c141957e151b41e694efeb20e4b4b9a Reviewed-on: https://go-review.googlesource.com/29761 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go index 1b618fd42c..dc300cbc94 100644 --- a/src/runtime/os3_solaris.go +++ b/src/runtime/os3_solaris.go @@ -318,6 +318,9 @@ func sigmaskToSigset(m sigmask) sigset { return set } +func (c *sigctxt) fixsigcode(sig uint32) { +} + //go:nosplit func semacreate(mp *m) { if mp.waitsema != 0 { diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go index 0bbe644440..96e6cb9c31 100644 --- a/src/runtime/os_dragonfly.go +++ b/src/runtime/os_dragonfly.go @@ -290,3 +290,6 @@ func sigmaskToSigset(m sigmask) sigset { copy(set.__bits[:], m[:]) return set } + +func (c *sigctxt) fixsigcode(sig uint32) { +} diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go index ae057b86ca..fade93acd9 100644 --- a/src/runtime/os_freebsd.go +++ b/src/runtime/os_freebsd.go @@ -280,3 +280,6 @@ func sigmaskToSigset(m sigmask) sigset { copy(set.__bits[:], m[:]) return set } + +func (c *sigctxt) fixsigcode(sig uint32) { +} diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go index 88139ae2fc..bc0d9f2027 100644 --- a/src/runtime/os_linux.go +++ b/src/runtime/os_linux.go @@ -410,3 +410,6 @@ func getsig(i int32) uintptr { func setSignalstackSP(s *stackt, sp uintptr) { s.ss_sp = (*byte)(unsafe.Pointer(sp)) } + +func (c *sigctxt) fixsigcode(sig uint32) { +} diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go index 81c52324ff..79d684217a 100644 --- a/src/runtime/os_netbsd.go +++ b/src/runtime/os_netbsd.go @@ -316,3 +316,6 @@ func sigmaskToSigset(m sigmask) sigset { copy(set.__bits[:], m[:]) return set } + +func (c *sigctxt) fixsigcode(sig uint32) { +} diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go index 714416fa5b..19055bd9c3 100644 --- a/src/runtime/os_openbsd.go +++ b/src/runtime/os_openbsd.go @@ -294,3 +294,6 @@ func setSignalstackSP(s *stackt, sp uintptr) { func sigmaskToSigset(m sigmask) sigset { return sigset(m[0]) } + +func (c *sigctxt) fixsigcode(sig uint32) { +} diff --git a/src/runtime/signal_darwin.go b/src/runtime/signal_darwin.go index b75d24d63f..0c5481a2ef 100644 --- a/src/runtime/signal_darwin.go +++ b/src/runtime/signal_darwin.go @@ -4,8 +4,6 @@ package runtime -import "unsafe" - type sigTabT struct { flags int32 name string @@ -45,46 +43,3 @@ var sigtable = [...]sigTabT{ /* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"}, /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"}, } - -//go:noescape -func sigreturn(ctx unsafe.Pointer, infostyle uint32) - -//go:nosplit -//go:nowritebarrierrec -func sigtrampgo(fn uintptr, infostyle, sig uint32, info *siginfo, ctx unsafe.Pointer) { - if sigfwdgo(sig, info, ctx) { - sigreturn(ctx, infostyle) - return - } - g := getg() - if g == nil { - badsignal(uintptr(sig), &sigctxt{info, ctx}) - sigreturn(ctx, infostyle) - return - } - - // 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 stackt - sigaltstack(nil, &st) - if st.ss_flags&_SS_DISABLE != 0 { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - stsp := uintptr(unsafe.Pointer(st.ss_sp)) - if sp < stsp || sp >= stsp+st.ss_size { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - setGsignalStack(&st) - g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) - } - - setg(g.m.gsignal) - c := &sigctxt{info, ctx} - c.fixsigcode(sig) - sighandler(sig, info, ctx, g) - setg(g) - sigreturn(ctx, infostyle) -} diff --git a/src/runtime/signal_freebsd.go b/src/runtime/signal_freebsd.go index 180b7bab4b..7ce7217e07 100644 --- a/src/runtime/signal_freebsd.go +++ b/src/runtime/signal_freebsd.go @@ -4,8 +4,6 @@ package runtime -import "unsafe" - type sigTabT struct { flags int32 name string @@ -46,38 +44,3 @@ var sigtable = [...]sigTabT{ /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"}, /* 32 */ {_SigNotify, "SIGTHR: reserved"}, } - -//go:nosplit -//go:nowritebarrierrec -func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { - if sigfwdgo(sig, info, ctx) { - return - } - g := getg() - if g == nil { - badsignal(uintptr(sig), &sigctxt{info, ctx}) - return - } - - // 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 stackt - sigaltstack(nil, &st) - if st.ss_flags&_SS_DISABLE != 0 { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - stsp := uintptr(unsafe.Pointer(st.ss_sp)) - if sp < stsp || sp >= stsp+st.ss_size { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - setGsignalStack(&st) - g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) - } - - setg(g.m.gsignal) - sighandler(sig, info, ctx, g) - setg(g) -} diff --git a/src/runtime/signal_openbsd.go b/src/runtime/signal_openbsd.go index b10686adf3..30a3b8e1a9 100644 --- a/src/runtime/signal_openbsd.go +++ b/src/runtime/signal_openbsd.go @@ -4,8 +4,6 @@ package runtime -import "unsafe" - type sigTabT struct { flags int32 name string @@ -46,38 +44,3 @@ var sigtable = [...]sigTabT{ /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"}, /* 32 */ {_SigNotify, "SIGTHR: reserved"}, } - -//go:nosplit -//go:nowritebarrierrec -func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { - if sigfwdgo(sig, info, ctx) { - return - } - g := getg() - if g == nil { - badsignal(uintptr(sig), &sigctxt{info, ctx}) - return - } - - // 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 stackt - sigaltstack(nil, &st) - if st.ss_flags&_SS_DISABLE != 0 { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - stsp := uintptr(unsafe.Pointer(st.ss_sp)) - if sp < stsp || sp >= stsp+st.ss_size { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - setGsignalStack(&st) - g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) - } - - setg(g.m.gsignal) - sighandler(sig, info, ctx, g) - setg(g) -} diff --git a/src/runtime/signal_sigtramp.go b/src/runtime/signal_sigtramp.go deleted file mode 100644 index 1ada2759a7..0000000000 --- a/src/runtime/signal_sigtramp.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build dragonfly linux netbsd - -package runtime - -import "unsafe" - -// Continuation of the (assembly) sigtramp() logic. -// This may be called with the world stopped. -//go:nosplit -//go:nowritebarrierrec -func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { - if sigfwdgo(sig, info, ctx) { - return - } - g := getg() - if g == nil { - if sig == _SIGPROF { - // Ignore profiling signals that arrive on - // non-Go threads. On some systems they will - // be handled directly by the signal handler, - // by calling sigprofNonGo, in which case we won't - // get here anyhow. - return - } - badsignal(uintptr(sig), &sigctxt{info, ctx}) - return - } - - // 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 stackt - sigaltstack(nil, &st) - if st.ss_flags&_SS_DISABLE != 0 { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - stsp := uintptr(unsafe.Pointer(st.ss_sp)) - if sp < stsp || sp >= stsp+st.ss_size { - setg(nil) - cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) - } - setGsignalStack(&st) - g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) - } - - setg(g.m.gsignal) - sighandler(sig, info, ctx, g) - setg(g) -} diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index c0952d7019..013271ba43 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -196,6 +196,54 @@ func sigpipe() { dieFromSignal(_SIGPIPE) } +// sigtrampgo is called from the signal handler function, sigtramp, +// written in assembly code. +// This is called by the signal handler, and the world may be stopped. +//go:nosplit +//go:nowritebarrierrec +func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { + if sigfwdgo(sig, info, ctx) { + return + } + g := getg() + if g == nil { + if sig == _SIGPROF { + // Ignore profiling signals that arrive on + // non-Go threads. On some systems they will + // be handled directly by the signal handler, + // by calling sigprofNonGo, in which case we won't + // get here anyhow. + return + } + badsignal(uintptr(sig), &sigctxt{info, ctx}) + return + } + + // 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 stackt + sigaltstack(nil, &st) + if st.ss_flags&_SS_DISABLE != 0 { + setg(nil) + cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) + } + stsp := uintptr(unsafe.Pointer(st.ss_sp)) + if sp < stsp || sp >= stsp+st.ss_size { + setg(nil) + cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) + } + setGsignalStack(&st) + g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig)) + } + + setg(g.m.gsignal) + c := &sigctxt{info, ctx} + c.fixsigcode(sig) + sighandler(sig, info, ctx, g) + setg(g) +} + // sigpanic turns a synchronous signal into a run-time panic. // If the signal handler sees a synchronous panic, it arranges the // stack to look like the function where the signal occurred called diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s index d19e56317c..9cffe3e424 100644 --- a/src/runtime/sys_darwin_386.s +++ b/src/runtime/sys_darwin_386.s @@ -265,17 +265,6 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 MOVL AX, SP RET -TEXT runtime·sigreturn(SB),NOSPLIT,$12-8 - MOVL ctx+0(FP), CX - MOVL infostyle+4(FP), BX - MOVL $0, 0(SP) // "caller PC" - ignored - MOVL CX, 4(SP) - MOVL BX, 8(SP) - MOVL $184, AX // sigreturn(ucontext, infostyle) - INT $0x80 - MOVL $0xf1, 0xf1 // crash - RET - // Sigtramp's job is to call the actual signal handler. // It is called with the following arguments on the stack: // 0(SP) "return address" - ignored @@ -285,16 +274,12 @@ TEXT runtime·sigreturn(SB),NOSPLIT,$12-8 // 16(SP) siginfo // 20(SP) context TEXT runtime·sigtramp(SB),NOSPLIT,$20 - MOVL fn+0(FP), BX - MOVL BX, 0(SP) - MOVL infostyle+4(FP), BX - MOVL BX, 4(SP) MOVL sig+8(FP), BX - MOVL BX, 8(SP) + MOVL BX, 0(SP) MOVL info+12(FP), BX - MOVL BX, 12(SP) + MOVL BX, 4(SP) MOVL ctx+16(FP), BX - MOVL BX, 16(SP) + MOVL BX, 8(SP) CALL runtime·sigtrampgo(SB) // call sigreturn diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s index 69cee55299..8d1b9b11d9 100644 --- a/src/runtime/sys_darwin_amd64.s +++ b/src/runtime/sys_darwin_amd64.s @@ -230,22 +230,18 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 MOVQ BP, SP RET -TEXT runtime·sigreturn(SB),NOSPLIT,$0-12 - MOVQ ctx+0(FP), DI - MOVL infostyle+8(FP), SI - MOVL $(0x2000000+184), AX - SYSCALL - INT $3 // not reached - TEXT runtime·sigtramp(SB),NOSPLIT,$32 - MOVQ DI, 0(SP) // fn - MOVL SI, 8(SP) // infostyle - MOVL DX, 12(SP) // sig - MOVQ CX, 16(SP) // info - MOVQ R8, 24(SP) // ctx + MOVL SI, 24(SP) // save infostyle for sigreturn below + MOVL DX, 0(SP) // sig + MOVQ CX, 8(SP) // info + MOVQ R8, 16(SP) // ctx MOVQ $runtime·sigtrampgo(SB), AX CALL AX - INT $3 // not reached (see issue 16453) + MOVQ 16(SP), DI // ctx + MOVL 24(SP), SI // infostyle + MOVL $(0x2000000+184), AX + SYSCALL + INT $3 // not reached TEXT runtime·mmap(SB),NOSPLIT,$0 MOVQ addr+0(FP), DI // arg 1 addr