]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] runtime: convert power64 signal handlers from C to Go
authorAustin Clements <austin@google.com>
Tue, 18 Nov 2014 20:19:09 +0000 (15:19 -0500)
committerAustin Clements <austin@google.com>
Tue, 18 Nov 2014 20:19:09 +0000 (15:19 -0500)
The power64 equivalent of CL 168500044

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/175280043

src/runtime/signal_linux_power64.h [deleted file]
src/runtime/signal_linux_power64le.h [deleted file]
src/runtime/signal_linux_power64x.go [new file with mode: 0644]
src/runtime/signal_power64x.c [deleted file]
src/runtime/signal_power64x.go [new file with mode: 0644]

diff --git a/src/runtime/signal_linux_power64.h b/src/runtime/signal_linux_power64.h
deleted file mode 100644 (file)
index 8406489..0000000
+++ /dev/null
@@ -1,49 +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.
-
-#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext)->regs)
-
-#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).gpr[0])
-#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).gpr[2])
-#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).gpr[3])
-#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).gpr[4])
-#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).gpr[5])
-#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).gpr[6])
-#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).gpr[7])
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gpr[8])
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gpr[9])
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gpr[10])
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gpr[11])
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gpr[12])
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gpr[13])
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gpr[14])
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gpr[15])
-#define SIG_R16(info, ctxt) (SIG_REGS(ctxt).gpr[16])
-#define SIG_R17(info, ctxt) (SIG_REGS(ctxt).gpr[17])
-#define SIG_R18(info, ctxt) (SIG_REGS(ctxt).gpr[18])
-#define SIG_R19(info, ctxt) (SIG_REGS(ctxt).gpr[19])
-#define SIG_R20(info, ctxt) (SIG_REGS(ctxt).gpr[20])
-#define SIG_R21(info, ctxt) (SIG_REGS(ctxt).gpr[21])
-#define SIG_R22(info, ctxt) (SIG_REGS(ctxt).gpr[22])
-#define SIG_R23(info, ctxt) (SIG_REGS(ctxt).gpr[23])
-#define SIG_R24(info, ctxt) (SIG_REGS(ctxt).gpr[24])
-#define SIG_R25(info, ctxt) (SIG_REGS(ctxt).gpr[25])
-#define SIG_R26(info, ctxt) (SIG_REGS(ctxt).gpr[26])
-#define SIG_R27(info, ctxt) (SIG_REGS(ctxt).gpr[27])
-#define SIG_R28(info, ctxt) (SIG_REGS(ctxt).gpr[28])
-#define SIG_R29(info, ctxt) (SIG_REGS(ctxt).gpr[29])
-#define SIG_R30(info, ctxt) (SIG_REGS(ctxt).gpr[30])
-#define SIG_R31(info, ctxt) (SIG_REGS(ctxt).gpr[31])
-
-#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).nip)
-#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap)
-#define SIG_CTR(info, ctxt) (SIG_REGS(ctxt).ctr)
-#define SIG_LINK(info, ctxt) (SIG_REGS(ctxt).link)
-#define SIG_XER(info, ctxt) (SIG_REGS(ctxt).xer)
-#define SIG_CCR(info, ctxt) (SIG_REGS(ctxt).ccr)
-
-#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
-#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).dar)
diff --git a/src/runtime/signal_linux_power64le.h b/src/runtime/signal_linux_power64le.h
deleted file mode 100644 (file)
index 8406489..0000000
+++ /dev/null
@@ -1,49 +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.
-
-#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext)->regs)
-
-#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).gpr[0])
-#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).gpr[2])
-#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).gpr[3])
-#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).gpr[4])
-#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).gpr[5])
-#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).gpr[6])
-#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).gpr[7])
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gpr[8])
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gpr[9])
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gpr[10])
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gpr[11])
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gpr[12])
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gpr[13])
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gpr[14])
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gpr[15])
-#define SIG_R16(info, ctxt) (SIG_REGS(ctxt).gpr[16])
-#define SIG_R17(info, ctxt) (SIG_REGS(ctxt).gpr[17])
-#define SIG_R18(info, ctxt) (SIG_REGS(ctxt).gpr[18])
-#define SIG_R19(info, ctxt) (SIG_REGS(ctxt).gpr[19])
-#define SIG_R20(info, ctxt) (SIG_REGS(ctxt).gpr[20])
-#define SIG_R21(info, ctxt) (SIG_REGS(ctxt).gpr[21])
-#define SIG_R22(info, ctxt) (SIG_REGS(ctxt).gpr[22])
-#define SIG_R23(info, ctxt) (SIG_REGS(ctxt).gpr[23])
-#define SIG_R24(info, ctxt) (SIG_REGS(ctxt).gpr[24])
-#define SIG_R25(info, ctxt) (SIG_REGS(ctxt).gpr[25])
-#define SIG_R26(info, ctxt) (SIG_REGS(ctxt).gpr[26])
-#define SIG_R27(info, ctxt) (SIG_REGS(ctxt).gpr[27])
-#define SIG_R28(info, ctxt) (SIG_REGS(ctxt).gpr[28])
-#define SIG_R29(info, ctxt) (SIG_REGS(ctxt).gpr[29])
-#define SIG_R30(info, ctxt) (SIG_REGS(ctxt).gpr[30])
-#define SIG_R31(info, ctxt) (SIG_REGS(ctxt).gpr[31])
-
-#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).nip)
-#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap)
-#define SIG_CTR(info, ctxt) (SIG_REGS(ctxt).ctr)
-#define SIG_LINK(info, ctxt) (SIG_REGS(ctxt).link)
-#define SIG_XER(info, ctxt) (SIG_REGS(ctxt).xer)
-#define SIG_CCR(info, ctxt) (SIG_REGS(ctxt).ccr)
-
-#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
-#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).dar)
diff --git a/src/runtime/signal_linux_power64x.go b/src/runtime/signal_linux_power64x.go
new file mode 100644 (file)
index 0000000..8f35703
--- /dev/null
@@ -0,0 +1,71 @@
+// 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 linux
+// +build power64 power64le
+
+package runtime
+
+import "unsafe"
+
+type sigctxt struct {
+       info *siginfo
+       ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *ptregs { return (*ucontext)(c.ctxt).uc_mcontext.regs }
+func (c *sigctxt) r0() uint64    { return c.regs().gpr[0] }
+func (c *sigctxt) r1() uint64    { return c.regs().gpr[1] }
+func (c *sigctxt) r2() uint64    { return c.regs().gpr[2] }
+func (c *sigctxt) r3() uint64    { return c.regs().gpr[3] }
+func (c *sigctxt) r4() uint64    { return c.regs().gpr[4] }
+func (c *sigctxt) r5() uint64    { return c.regs().gpr[5] }
+func (c *sigctxt) r6() uint64    { return c.regs().gpr[6] }
+func (c *sigctxt) r7() uint64    { return c.regs().gpr[7] }
+func (c *sigctxt) r8() uint64    { return c.regs().gpr[8] }
+func (c *sigctxt) r9() uint64    { return c.regs().gpr[9] }
+func (c *sigctxt) r10() uint64   { return c.regs().gpr[10] }
+func (c *sigctxt) r11() uint64   { return c.regs().gpr[11] }
+func (c *sigctxt) r12() uint64   { return c.regs().gpr[12] }
+func (c *sigctxt) r13() uint64   { return c.regs().gpr[13] }
+func (c *sigctxt) r14() uint64   { return c.regs().gpr[14] }
+func (c *sigctxt) r15() uint64   { return c.regs().gpr[15] }
+func (c *sigctxt) r16() uint64   { return c.regs().gpr[16] }
+func (c *sigctxt) r17() uint64   { return c.regs().gpr[17] }
+func (c *sigctxt) r18() uint64   { return c.regs().gpr[18] }
+func (c *sigctxt) r19() uint64   { return c.regs().gpr[19] }
+func (c *sigctxt) r20() uint64   { return c.regs().gpr[20] }
+func (c *sigctxt) r21() uint64   { return c.regs().gpr[21] }
+func (c *sigctxt) r22() uint64   { return c.regs().gpr[22] }
+func (c *sigctxt) r23() uint64   { return c.regs().gpr[23] }
+func (c *sigctxt) r24() uint64   { return c.regs().gpr[24] }
+func (c *sigctxt) r25() uint64   { return c.regs().gpr[25] }
+func (c *sigctxt) r26() uint64   { return c.regs().gpr[26] }
+func (c *sigctxt) r27() uint64   { return c.regs().gpr[27] }
+func (c *sigctxt) r28() uint64   { return c.regs().gpr[28] }
+func (c *sigctxt) r29() uint64   { return c.regs().gpr[29] }
+func (c *sigctxt) r30() uint64   { return c.regs().gpr[30] }
+func (c *sigctxt) r31() uint64   { return c.regs().gpr[31] }
+func (c *sigctxt) sp() uint64    { return c.regs().gpr[1] }
+func (c *sigctxt) pc() uint64    { return c.regs().nip }
+func (c *sigctxt) trap() uint64  { return c.regs().trap }
+func (c *sigctxt) ctr() uint64   { return c.regs().ctr }
+func (c *sigctxt) link() uint64  { return c.regs().link }
+func (c *sigctxt) xer() uint64   { return c.regs().xer }
+func (c *sigctxt) ccr() uint64   { return c.regs().ccr }
+
+func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
+func (c *sigctxt) sigaddr() uint64 { return uint64(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
+func (c *sigctxt) fault() uint64   { return c.regs().dar }
+
+func (c *sigctxt) set_r0(x uint64)   { c.regs().gpr[0] = x }
+func (c *sigctxt) set_r30(x uint64)  { c.regs().gpr[30] = x }
+func (c *sigctxt) set_pc(x uint64)   { c.regs().nip = x }
+func (c *sigctxt) set_sp(x uint64)   { c.regs().gpr[1] = x }
+func (c *sigctxt) set_link(x uint64) { c.regs().link = x }
+
+func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint64) {
+       *(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize)) = uintptr(x)
+}
diff --git a/src/runtime/signal_power64x.c b/src/runtime/signal_power64x.c
deleted file mode 100644 (file)
index c0bf1c4..0000000
+++ /dev/null
@@ -1,137 +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 linux
-// +build power64 power64le
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_GOOS_GOARCH.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Siginfo *info, void *ctxt)
-{
-       USED(info); USED(ctxt);
-       runtime·printf("r0  %X\t", SIG_R0(info, ctxt));
-       runtime·printf("r1  %X\n", SIG_R1(info, ctxt));
-       runtime·printf("r2  %X\t", SIG_R2(info, ctxt));
-       runtime·printf("r3  %X\n", SIG_R3(info, ctxt));
-       runtime·printf("r4  %X\t", SIG_R4(info, ctxt));
-       runtime·printf("r5  %X\n", SIG_R5(info, ctxt));
-       runtime·printf("r6  %X\t", SIG_R6(info, ctxt));
-       runtime·printf("r7  %X\n", SIG_R7(info, ctxt));
-       runtime·printf("r8  %X\t", SIG_R8(info, ctxt));
-       runtime·printf("r9  %X\n", SIG_R9(info, ctxt));
-       runtime·printf("r10  %X\t", SIG_R10(info, ctxt));
-       runtime·printf("r11  %X\n", SIG_R11(info, ctxt));
-       runtime·printf("r12  %X\t", SIG_R12(info, ctxt));
-       runtime·printf("r13  %X\n", SIG_R13(info, ctxt));
-       runtime·printf("r14  %X\t", SIG_R14(info, ctxt));
-       runtime·printf("r15  %X\n", SIG_R15(info, ctxt));
-       runtime·printf("r16  %X\t", SIG_R16(info, ctxt));
-       runtime·printf("r17  %X\n", SIG_R17(info, ctxt));
-       runtime·printf("r18  %X\t", SIG_R18(info, ctxt));
-       runtime·printf("r19  %X\n", SIG_R19(info, ctxt));
-       runtime·printf("r20  %X\t", SIG_R20(info, ctxt));
-       runtime·printf("r21  %X\n", SIG_R21(info, ctxt));
-       runtime·printf("r22  %X\t", SIG_R22(info, ctxt));
-       runtime·printf("r23  %X\n", SIG_R23(info, ctxt));
-       runtime·printf("r24  %X\t", SIG_R24(info, ctxt));
-       runtime·printf("r25  %X\n", SIG_R25(info, ctxt));
-       runtime·printf("r26  %X\t", SIG_R26(info, ctxt));
-       runtime·printf("r27  %X\n", SIG_R27(info, ctxt));
-       runtime·printf("r28  %X\t", SIG_R28(info, ctxt));
-       runtime·printf("r29  %X\n", SIG_R29(info, ctxt));
-       runtime·printf("r30  %X\t", SIG_R30(info, ctxt));
-       runtime·printf("r31  %X\n", SIG_R31(info, ctxt));
-       runtime·printf("pc   %X\t", SIG_PC(info, ctxt));
-       runtime·printf("ctr  %X\n", SIG_CTR(info, ctxt));
-       runtime·printf("link %X\t", SIG_LINK(info, ctxt));
-       runtime·printf("xer  %X\n", SIG_XER(info, ctxt));
-       runtime·printf("ccr  %X\t", SIG_CCR(info, ctxt));
-       runtime·printf("trap %X\n", SIG_TRAP(info, ctxt));
-}
-
-void
-runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
-{
-       SigTab *t;
-       bool crash;
-
-       if(sig == SIGPROF) {
-               runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LINK(info, ctxt), gp, g->m);
-               return;
-       }
-       t = &runtime·sigtab[sig];
-       if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
-               // Make it look like a call to the signal func.
-               // Have to pass arguments out of band since
-               // augmenting the stack frame would break
-               // the unwinding code.
-               gp->sig = sig;
-               gp->sigcode0 = SIG_CODE0(info, ctxt);
-               gp->sigcode1 = SIG_FAULT(info, ctxt);
-               gp->sigpc = SIG_PC(info, ctxt);
-
-               // We arrange link, and pc to pretend the panicking
-               // function calls sigpanic directly.
-               // Always save LINK to stack so that panics in leaf
-               // functions are correctly handled. This smashes
-               // the stack frame but we're not going back there
-               // anyway.
-               SIG_SP(info, ctxt) -= sizeof(uintptr);
-               *(uintptr*)SIG_SP(info, ctxt) = SIG_LINK(info, ctxt);
-               // Don't bother saving PC if it's zero, which is
-               // probably a call to a nil func: the old link register
-               // is more useful in the stack trace.
-               if(gp->sigpc != 0)
-                       SIG_LINK(info, ctxt) = gp->sigpc;
-               // In case we are panicking from external C code
-               SIG_R0(info, ctxt) = 0;
-               SIG_R30(info, ctxt) = (uintptr)gp;
-               SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic;
-               return;
-       }
-
-       if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
-               if(runtime·sigsend(sig))
-                       return;
-       if(t->flags & SigKill)
-               runtime·exit(2);
-       if(!(t->flags & SigThrow))
-               return;
-
-       g->m->throwing = 1;
-       g->m->caughtsig = gp;
-       if(runtime·panicking)  // traceback already printed
-               runtime·exit(2);
-       runtime·panicking = 1;
-
-       if(sig < 0 || sig >= NSIG)
-               runtime·printf("Signal %d\n", sig);
-       else
-               runtime·printf("%s\n", runtime·sigtab[sig].name);
-
-       runtime·printf("PC=%x\n", SIG_PC(info, ctxt));
-       if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
-               runtime·printf("signal arrived during cgo execution\n");
-               gp = g->m->lockedg;
-       }
-       runtime·printf("\n");
-
-       if(runtime·gotraceback(&crash)){
-               runtime·goroutineheader(gp);
-               runtime·tracebacktrap(SIG_PC(info, ctxt), SIG_SP(info, ctxt), SIG_LINK(info, ctxt), gp);
-               runtime·tracebackothers(gp);
-               runtime·printf("\n");
-               runtime·dumpregs(info, ctxt);
-       }
-       
-       if(crash)
-               runtime·crash();
-
-       runtime·exit(2);
-}
diff --git a/src/runtime/signal_power64x.go b/src/runtime/signal_power64x.go
new file mode 100644 (file)
index 0000000..fc83beb
--- /dev/null
@@ -0,0 +1,144 @@
+// 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 linux
+// +build power64 power64le
+
+package runtime
+
+import "unsafe"
+
+func dumpregs(c *sigctxt) {
+       print("r0   ", hex(c.r0()), "\t")
+       print("r1   ", hex(c.r1()), "\n")
+       print("r2   ", hex(c.r2()), "\t")
+       print("r3   ", hex(c.r3()), "\n")
+       print("r4   ", hex(c.r4()), "\t")
+       print("r5   ", hex(c.r5()), "\n")
+       print("r6   ", hex(c.r6()), "\t")
+       print("r7   ", hex(c.r7()), "\n")
+       print("r8   ", hex(c.r8()), "\t")
+       print("r9   ", hex(c.r9()), "\n")
+       print("r10  ", hex(c.r10()), "\t")
+       print("r11  ", hex(c.r11()), "\n")
+       print("r12  ", hex(c.r12()), "\t")
+       print("r13  ", hex(c.r13()), "\n")
+       print("r14  ", hex(c.r14()), "\t")
+       print("r15  ", hex(c.r15()), "\n")
+       print("r16  ", hex(c.r16()), "\t")
+       print("r17  ", hex(c.r17()), "\n")
+       print("r18  ", hex(c.r18()), "\t")
+       print("r19  ", hex(c.r19()), "\n")
+       print("r20  ", hex(c.r20()), "\t")
+       print("r21  ", hex(c.r21()), "\n")
+       print("r22  ", hex(c.r22()), "\t")
+       print("r23  ", hex(c.r23()), "\n")
+       print("r24  ", hex(c.r24()), "\t")
+       print("r25  ", hex(c.r25()), "\n")
+       print("r26  ", hex(c.r26()), "\t")
+       print("r27  ", hex(c.r27()), "\n")
+       print("r28  ", hex(c.r28()), "\t")
+       print("r29  ", hex(c.r29()), "\n")
+       print("r30  ", hex(c.r30()), "\t")
+       print("r31  ", hex(c.r31()), "\n")
+       print("pc   ", hex(c.pc()), "\t")
+       print("ctr  ", hex(c.ctr()), "\n")
+       print("link ", hex(c.link()), "\t")
+       print("xer  ", hex(c.xer()), "\n")
+       print("ccr  ", hex(c.ccr()), "\t")
+       print("trap ", hex(c.trap()), "\n")
+}
+
+func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
+       _g_ := getg()
+       c := &sigctxt{info, ctxt}
+
+       if sig == _SIGPROF {
+               sigprof((*byte)(unsafe.Pointer(uintptr(c.pc()))), (*byte)(unsafe.Pointer(uintptr(c.sp()))), (*byte)(unsafe.Pointer(uintptr(c.link()))), gp, _g_.m)
+               return
+       }
+       flags := int32(_SigThrow)
+       if sig < uint32(len(sigtable)) {
+               flags = sigtable[sig].flags
+       }
+       if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
+               // Make it look like a call to the signal func.
+               // Have to pass arguments out of band since
+               // augmenting the stack frame would break
+               // the unwinding code.
+               gp.sig = sig
+               gp.sigcode0 = uintptr(c.sigcode())
+               gp.sigcode1 = uintptr(c.fault())
+               gp.sigpc = uintptr(c.pc())
+
+               // We arrange link, and pc to pretend the panicking
+               // function calls sigpanic directly.
+               // Always save LINK to stack so that panics in leaf
+               // functions are correctly handled. This smashes
+               // the stack frame but we're not going back there
+               // anyway.
+               sp := c.sp() - ptrSize
+               c.set_sp(sp)
+               *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
+
+               // Don't bother saving PC if it's zero, which is
+               // probably a call to a nil func: the old link register
+               // is more useful in the stack trace.
+               if gp.sigpc != 0 {
+                       c.set_link(uint64(gp.sigpc))
+               }
+
+               // In case we are panicking from external C code
+               c.set_r0(0)
+               c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
+               c.set_pc(uint64(funcPC(sigpanic)))
+               return
+       }
+
+       if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
+               if sigsend(sig) {
+                       return
+               }
+       }
+
+       if flags&_SigKill != 0 {
+               exit(2)
+       }
+
+       if flags&_SigThrow == 0 {
+               return
+       }
+
+       _g_.m.throwing = 1
+       _g_.m.caughtsig = gp
+       startpanic()
+
+       if sig < uint32(len(sigtable)) {
+               print(sigtable[sig].name, "\n")
+       } else {
+               print("Signal ", sig, "\n")
+       }
+
+       print("PC=", hex(c.pc()), "\n")
+       if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+               print("signal arrived during cgo execution\n")
+               gp = _g_.m.lockedg
+       }
+       print("\n")
+
+       var docrash bool
+       if gotraceback(&docrash) > 0 {
+               goroutineheader(gp)
+               tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.link()), gp)
+               tracebackothers(gp)
+               print("\n")
+               dumpregs(c)
+       }
+
+       if docrash {
+               crash()
+       }
+
+       exit(2)
+}