From 343bec53c7317e1c780b3faf04aa124f19849b61 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sat, 24 Sep 2016 21:17:34 -0700 Subject: [PATCH] runtime: merge sigpanic_unix.go into signal_unix.go Change-Id: Iba541045b4878405834c637095627631b6559a35 Reviewed-on: https://go-review.googlesource.com/29754 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/runtime/signal_unix.go | 53 ++++++++++++++++++++++++++++++++++++ src/runtime/sigpanic_unix.go | 53 ------------------------------------ 2 files changed, 53 insertions(+), 53 deletions(-) delete mode 100644 src/runtime/sigpanic_unix.go diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index b457c5e265..08e57ca0e5 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -196,6 +196,49 @@ func sigpipe() { dieFromSignal(_SIGPIPE) } +// 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 +// sigpanic, sets the signal's PC value to sigpanic, and returns from +// the signal handler. The effect is that the program will act as +// though the function that got the signal simply called sigpanic +// instead. +func sigpanic() { + g := getg() + if !canpanic(g) { + throw("unexpected signal during runtime execution") + } + + switch g.sig { + case _SIGBUS: + if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault { + panicmem() + } + print("unexpected fault address ", hex(g.sigcode1), "\n") + throw("fault") + case _SIGSEGV: + if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault { + panicmem() + } + print("unexpected fault address ", hex(g.sigcode1), "\n") + throw("fault") + case _SIGFPE: + switch g.sigcode0 { + case _FPE_INTDIV: + panicdivide() + case _FPE_INTOVF: + panicoverflow() + } + panicfloat() + } + + if g.sig >= uint32(len(sigtable)) { + // can't happen: we looked up g.sig in sigtable to decide to call sigpanic + throw("unexpected signal value") + } + panic(errorString(sigtable[g.sig].name)) +} + // dieFromSignal kills the program with a signal. // This provides the expected exit status for the shell. // This is only called with fatal signals expected to kill the process. @@ -473,3 +516,13 @@ func unblocksig(sig int32) { set := sigmaskToSigset(m) sigprocmask(_SIG_UNBLOCK, &set, nil) } + +// setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. +//go:nosplit +func setsigsegv(pc uintptr) { + g := getg() + g.sig = _SIGSEGV + g.sigpc = pc + g.sigcode0 = _SEGV_MAPERR + g.sigcode1 = 0 // TODO: emulate si_addr +} diff --git a/src/runtime/sigpanic_unix.go b/src/runtime/sigpanic_unix.go deleted file mode 100644 index 4cd8615bcc..0000000000 --- a/src/runtime/sigpanic_unix.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 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 darwin dragonfly freebsd linux netbsd openbsd solaris - -package runtime - -func sigpanic() { - g := getg() - if !canpanic(g) { - throw("unexpected signal during runtime execution") - } - - switch g.sig { - case _SIGBUS: - if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault { - panicmem() - } - print("unexpected fault address ", hex(g.sigcode1), "\n") - throw("fault") - case _SIGSEGV: - if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault { - panicmem() - } - print("unexpected fault address ", hex(g.sigcode1), "\n") - throw("fault") - case _SIGFPE: - switch g.sigcode0 { - case _FPE_INTDIV: - panicdivide() - case _FPE_INTOVF: - panicoverflow() - } - panicfloat() - } - - if g.sig >= uint32(len(sigtable)) { - // can't happen: we looked up g.sig in sigtable to decide to call sigpanic - throw("unexpected signal value") - } - panic(errorString(sigtable[g.sig].name)) -} - -// setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. -//go:nosplit -func setsigsegv(pc uintptr) { - g := getg() - g.sig = _SIGSEGV - g.sigpc = pc - g.sigcode0 = _SEGV_MAPERR - g.sigcode1 = 0 // TODO: emulate si_addr -} -- 2.48.1