1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 7 package runtime 8 9 func sigpanic() { 10 g := getg() 11 if !canpanic(g) { 12 throw("unexpected signal during runtime execution") 13 } 14 15 switch g.sig { 16 case _SIGBUS: 17 if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault { 18 panicmem() 19 } 20 print("unexpected fault address ", hex(g.sigcode1), "\n") 21 throw("fault") 22 case _SIGSEGV: 23 if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault { 24 panicmem() 25 } 26 print("unexpected fault address ", hex(g.sigcode1), "\n") 27 throw("fault") 28 case _SIGFPE: 29 switch g.sigcode0 { 30 case _FPE_INTDIV: 31 panicdivide() 32 case _FPE_INTOVF: 33 panicoverflow() 34 } 35 panicfloat() 36 } 37 38 if g.sig >= uint32(len(sigtable)) { 39 // can't happen: we looked up g.sig in sigtable to decide to call sigpanic 40 throw("unexpected signal value") 41 } 42 panic(errorString(sigtable[g.sig].name)) 43 } 44 45 // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. 46 //go:nosplit 47 func setsigsegv(pc uintptr) { 48 g := getg() 49 g.sig = _SIGSEGV 50 g.sigpc = pc 51 g.sigcode0 = _SEGV_MAPERR 52 g.sigcode1 = 0 // TODO: emulate si_addr 53 } 54