blob: 1ae00d13f307a5375abd78d39d6344d84155dc2f [file] [log] [blame]
// Copyright 2015 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.
#include "textflag.h"
// xx_cgo_panicmem is the entrypoint for SIGSEGV as intercepted via a
// mach thread port as EXC_BAD_ACCESS. As the segfault may have happened
// in C code, we first need to load_g then call xx_cgo_panicmem.
//
// R1 - LR at moment of fault
// R2 - PC at moment of fault
TEXT xx_cgo_panicmem(SB),NOSPLIT|NOFRAME,$0
// If in external C code, we need to load the g register.
BL runtime·load_g(SB)
CMP $0, g
BNE ongothread
// On a foreign thread.
// TODO(crawshaw): call badsignal
MOVD.W $0, -16(RSP)
MOVW $139, R1
MOVW R1, 8(RSP)
B runtime·exit(SB)
ongothread:
// Trigger a SIGSEGV panic.
//
// The goal is to arrange the stack so it looks like the runtime
// function sigpanic was called from the PC that faulted. It has
// to be sigpanic, as the stack unwinding code in traceback.go
// looks explicitly for it.
//
// To do this we call into runtime·setsigsegv, which sets the
// appropriate state inside the g object. We give it the faulting
// PC on the stack, then put it in the LR before calling sigpanic.
// Build a 32-byte stack frame for us for this call.
// Saved LR (none available) is at the bottom,
// then the PC argument for setsigsegv,
// then a copy of the LR for us to restore.
MOVD.W $0, -32(RSP)
MOVD R1, 8(RSP)
MOVD R2, 16(RSP)
BL runtime·setsigsegv(SB)
MOVD 8(RSP), R1
MOVD 16(RSP), R2
// Build a 16-byte stack frame for the simulated
// call to sigpanic, by taking 16 bytes away from the
// 32-byte stack frame above.
// The saved LR in this frame is the LR at time of fault,
// and the LR on entry to sigpanic is the PC at time of fault.
MOVD.W R1, 16(RSP)
MOVD R2, R30
B runtime·sigpanic(SB)