]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: signal forwarding for darwin/amd64
authorDavid Crawshaw <crawshaw@golang.org>
Fri, 24 Apr 2015 16:47:46 +0000 (12:47 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Sun, 26 Apr 2015 13:46:13 +0000 (13:46 +0000)
Follows the linux signal forwarding semantics from
http://golang.org/cl/8712, sharing the implementation of sigfwdgo.
Forwarding for 386, arm, and arm64 will follow.

Change-Id: I6bf30d563d19da39b6aec6900c7fe12d82ed4f62
Reviewed-on: https://go-review.googlesource.com/9302
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/runtime/os_dragonfly.go
src/runtime/os_freebsd.go
src/runtime/os_nacl.go
src/runtime/os_netbsd.go
src/runtime/os_openbsd.go
src/runtime/os_solaris.go
src/runtime/signal_darwin.go
src/runtime/signal_linux.go
src/runtime/signal_unix.go
src/runtime/sys_darwin_amd64.s

index 8cffd2b9fdd2cf8034febdf2ca75f444bb109367..60234bbdea60d17df9e1d966326ac183be689146 100644 (file)
@@ -12,6 +12,9 @@ func lwp_create(param *lwpparams) int32
 //go:noescape
 func sigaltstack(new, old *sigaltstackt)
 
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+
 //go:noescape
 func sigaction(sig int32, new, old *sigactiont)
 
index c274b39d927d8c216c94ac4dbe0f45e2378406eb..b2b5cd1f3f459758a68eda94f7d3a2d3e2b034b3 100644 (file)
@@ -12,6 +12,9 @@ func thr_new(param *thrparam, size int32)
 //go:noescape
 func sigaltstack(new, old *stackt)
 
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+
 //go:noescape
 func sigaction(sig int32, new, old *sigactiont)
 
index efa8fa12b911fdf7db82b866223a2a8b8c64799f..3b4c13606fb90ac435a17d1c586c5be1729f1c93 100644 (file)
@@ -50,6 +50,10 @@ func sigpanic() {
        panicmem()
 }
 
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) {
+       throw("sigfwd not implemented")
+}
+
 func raiseproc(sig int32) {
 }
 
index 4fa4a416bdc70aab9d9c3754e7fc052264343181..b542b41b92310a2195ea12415f8dd1063635fc47 100644 (file)
@@ -15,6 +15,11 @@ func sigaction(sig int32, new, old *sigactiont)
 //go:noescape
 func sigaltstack(new, old *sigaltstackt)
 
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) {
+       throw("sigfwd not implemented")
+}
+
 //go:noescape
 func sigprocmask(mode int32, new, old *sigset)
 
index 8a97a738f770ece34a450391e7a5af36609bd519..f94b490285d89d01ea64384ab6d3fcf6988c0c71 100644 (file)
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "unsafe"
+
 //go:noescape
 func setitimer(mode int32, new, old *itimerval)
 
@@ -13,6 +15,9 @@ func sigaction(sig int32, new, old *sigactiont)
 //go:noescape
 func sigaltstack(new, old *stackt)
 
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+
 //go:noescape
 func sigprocmask(mode int32, new uint32) uint32
 
index 6864ef9383482006528551d35495dbbbc0b05e90..b30270eee370f80d6efd810e470e41f9b6cdd930 100644 (file)
@@ -10,6 +10,9 @@ type libcFunc uintptr
 
 var asmsysvicall6 libcFunc
 
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+
 //go:nosplit
 func sysvicall0(fn libcFunc) uintptr {
        libcall := &getg().m.libcall
index 122648bc334072a458a6bee8b82708898bb26a16..32ecce0d7dfbf006ad00cb159960ecd63ddac7d4 100644 (file)
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "unsafe"
+
 type sigTabT struct {
        flags int32
        name  string
@@ -43,3 +45,27 @@ var sigtable = [...]sigTabT{
        /* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
        /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
 }
+
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+
+//go:noescape
+func sigreturn(ctx unsafe.Pointer, infostyle uint32)
+
+//go:nosplit
+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))
+               sigreturn(ctx, infostyle)
+               return
+       }
+       setg(g.m.gsignal)
+       sighandler(sig, info, ctx, g)
+       setg(g)
+       sigreturn(ctx, infostyle)
+}
index 1ab4e9ec7156b5efd77785c6d1aaa5f483403c79..f8250b9fa1111eaaabb30dfc904937fa3920c8f3 100644 (file)
@@ -79,40 +79,6 @@ var sigtable = [...]sigTabT{
        /* 64 */ {_SigNotify, "signal 64"},
 }
 
-// Determines if the signal should be handled by Go and if not, forwards the
-// signal to the handler that was installed before Go's.  Returns whether the
-// signal was forwarded.
-//go:nosplit
-func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
-       g := getg()
-       c := &sigctxt{info, ctx}
-       if sig >= uint32(len(sigtable)) {
-               return false
-       }
-       fwdFn := fwdSig[sig]
-       flags := sigtable[sig].flags
-
-       // If there is no handler to forward to, no need to forward.
-       if fwdFn == _SIG_DFL {
-               return false
-       }
-       // Only forward synchronous signals.
-       if c.sigcode() == _SI_USER || flags&_SigPanic == 0 {
-               return false
-       }
-       // Determine if the signal occurred inside Go code.  We test that:
-       //   (1) we were in a goroutine (i.e., m.curg != nil), and
-       //   (2) we weren't in CGO (i.e., m.curg.syscallsp == 0).
-       if g != nil && g.m != nil && g.m.curg != nil && g.m.curg.syscallsp == 0 {
-               return false
-       }
-       // Signal not handled by Go, forward it.
-       if fwdFn != _SIG_IGN {
-               sigfwd(fwdFn, sig, info, ctx)
-       }
-       return true
-}
-
 // Continuation of the (assembly) sigtramp() logic.
 //go:nosplit
 func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
index 8834e51f4b41b4b1d7ec818afc2c0fccf44be7b4..ad3ab31c01c2c66ed57deccdc6ef08d3fd5cb361 100644 (file)
@@ -6,9 +6,43 @@
 
 package runtime
 
-import _ "unsafe" // for go:linkname
+import "unsafe"
 
 //go:linkname os_sigpipe os.sigpipe
 func os_sigpipe() {
        systemstack(sigpipe)
 }
+
+// Determines if the signal should be handled by Go and if not, forwards the
+// signal to the handler that was installed before Go's.  Returns whether the
+// signal was forwarded.
+//go:nosplit
+func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
+       g := getg()
+       c := &sigctxt{info, ctx}
+       if sig >= uint32(len(sigtable)) {
+               return false
+       }
+       fwdFn := fwdSig[sig]
+       flags := sigtable[sig].flags
+
+       // If there is no handler to forward to, no need to forward.
+       if fwdFn == _SIG_DFL {
+               return false
+       }
+       // Only forward synchronous signals.
+       if c.sigcode() == _SI_USER || flags&_SigPanic == 0 {
+               return false
+       }
+       // Determine if the signal occurred inside Go code.  We test that:
+       //   (1) we were in a goroutine (i.e., m.curg != nil), and
+       //   (2) we weren't in CGO (i.e., m.curg.syscallsp == 0).
+       if g != nil && g.m != nil && g.m.curg != nil && g.m.curg.syscallsp == 0 {
+               return false
+       }
+       // Signal not handled by Go, forward it.
+       if fwdFn != _SIG_IGN {
+               sigfwd(fwdFn, sig, info, ctx)
+       }
+       return true
+}
index bcb752a2103365a7ac74a7e4b009aba877fde791..692dbca580e84022b4b4f31d415ef8f372e222f8 100644 (file)
@@ -200,7 +200,7 @@ TEXT runtime·sigprocmask(SB),NOSPLIT,$0
        MOVL    $0xf1, 0xf1  // crash
        RET
 
-TEXT runtime·sigaction(SB),NOSPLIT,$0
+TEXT runtime·sigaction(SB),NOSPLIT,$0-24
        MOVL    mode+0(FP), DI          // arg 1 sig
        MOVQ    new+8(FP), SI           // arg 2 act
        MOVQ    old+16(FP), DX          // arg 3 oact
@@ -212,48 +212,29 @@ TEXT runtime·sigaction(SB),NOSPLIT,$0
        MOVL    $0xf1, 0xf1  // crash
        RET
 
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-       get_tls(BX)
-
-       MOVQ    R8, 32(SP)      // save ucontext
-       MOVQ    SI, 40(SP)      // save infostyle
-
-       // check that g exists
-       MOVQ    g(BX), R10
-       CMPQ    R10, $0
-       JNE     5(PC)
-       MOVL    DX, 0(SP)
-       MOVQ    $runtime·badsignal(SB), AX
-       CALL    AX
-       JMP     ret
-
-       // save g
-       MOVQ    R10, 48(SP)
-
-       // g = m->gsignal
-       MOVQ    g_m(R10), BP
-       MOVQ    m_gsignal(BP), BP
-       MOVQ    BP, g(BX)
-
-       MOVL    DX, 0(SP)
-       MOVQ    CX, 8(SP)
-       MOVQ    R8, 16(SP)
-       MOVQ    R10, 24(SP)
-
-       CALL    DI
-
-       // restore g
-       get_tls(BX)
-       MOVQ    48(SP), R10
-       MOVQ    R10, g(BX)
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+       MOVQ fn+0(FP),    AX
+       MOVQ sig+8(FP),   DI
+       MOVQ info+16(FP), SI
+       MOVQ ctx+24(FP),  DX
+       CALL AX
+       RET
 
-ret:
-       // call sigreturn
-       MOVL    $(0x2000000+184), AX    // sigreturn(ucontext, infostyle)
-       MOVQ    32(SP), DI      // saved ucontext
-       MOVQ    40(SP), SI      // saved infostyle
+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
+       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
 
 TEXT runtime·mmap(SB),NOSPLIT,$0
        MOVQ    addr+0(FP), DI          // arg 1 addr