Commit c2735039 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 1906d93b
......@@ -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)
}
// 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,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
......
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