Home | History | Annotate | Download | only in runtime
      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