mirror of
https://github.com/golang/go
synced 2024-11-23 07:30:05 -07:00
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 <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
1906d93bfd
commit
c2735039f3
@ -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 {
|
||||
|
@ -290,3 +290,6 @@ func sigmaskToSigset(m sigmask) sigset {
|
||||
copy(set.__bits[:], m[:])
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
@ -280,3 +280,6 @@ func sigmaskToSigset(m sigmask) sigset {
|
||||
copy(set.__bits[:], m[:])
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -316,3 +316,6 @@ func sigmaskToSigset(m sigmask) sigset {
|
||||
copy(set.__bits[:], m[:])
|
||||
return set
|
||||
}
|
||||
|
||||
func (c *sigctxt) fixsigcode(sig uint32) {
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -230,23 +230,19 @@ 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
|
||||
TEXT runtime·sigtramp(SB),NOSPLIT,$32
|
||||
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
|
||||
MOVQ 16(SP), DI // ctx
|
||||
MOVL 24(SP), SI // infostyle
|
||||
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
|
||||
MOVQ $runtime·sigtrampgo(SB), AX
|
||||
CALL AX
|
||||
INT $3 // not reached (see issue 16453)
|
||||
|
||||
TEXT runtime·mmap(SB),NOSPLIT,$0
|
||||
MOVQ addr+0(FP), DI // arg 1 addr
|
||||
MOVQ n+8(FP), SI // arg 2 len
|
||||
|
Loading…
Reference in New Issue
Block a user