mirror of
https://github.com/golang/go
synced 2024-11-19 23:04:40 -07:00
runtime/cgo: EXC_BAD_ACCESS handler for arm64
Change-Id: Ia9ff9c0d381fad43fc5d3e5972dd6e66503733a5 Reviewed-on: https://go-review.googlesource.com/8815 Reviewed-by: Minux Ma <minux@golang.org>
This commit is contained in:
parent
4c1ee3ea88
commit
989f0ee80a
@ -20,9 +20,9 @@
|
||||
//
|
||||
// go test -tags lldb -installsuffix lldb
|
||||
|
||||
// +build darwin,arm,!lldb
|
||||
|
||||
// TODO(crawshaw): darwin,arm64,!lldb
|
||||
// +build !lldb
|
||||
// +build darwin
|
||||
// +build arm arm64
|
||||
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
@ -77,9 +77,31 @@ catch_exception_raise(
|
||||
|
||||
// Bounce call to sigpanic through asm that makes it look like
|
||||
// we call sigpanic directly from the faulting code.
|
||||
#ifdef __arm64__
|
||||
thread_state.ts_64.__x[1] = thread_state.ts_64.__lr;
|
||||
thread_state.ts_64.__x[2] = thread_state.ts_64.__pc;
|
||||
thread_state.ts_64.__pc = x_cgo_panicmem;
|
||||
#else
|
||||
thread_state.ts_32.__r[1] = thread_state.ts_32.__lr;
|
||||
thread_state.ts_32.__r[2] = thread_state.ts_32.__pc;
|
||||
thread_state.ts_32.__pc = x_cgo_panicmem;
|
||||
#endif
|
||||
|
||||
if (0) {
|
||||
// Useful debugging logic when panicmem is broken.
|
||||
//
|
||||
// Sends the first SIGSEGV and lets lldb catch the
|
||||
// second one, avoiding a loop that locks up iOS
|
||||
// devices requiring a hard reboot.
|
||||
fprintf(stderr, "runtime/cgo: caught exc_bad_access\n");
|
||||
fprintf(stderr, "__lr = %llx\n", thread_state.ts_64.__lr);
|
||||
fprintf(stderr, "__pc = %llx\n", thread_state.ts_64.__pc);
|
||||
static int pass1 = 0;
|
||||
if (pass1) {
|
||||
return KERN_FAILURE;
|
||||
}
|
||||
pass1 = 1;
|
||||
}
|
||||
|
||||
ret = thread_set_state(thread, ARM_UNIFIED_THREAD_STATE, (thread_state_t)&thread_state, state_count);
|
||||
if (ret) {
|
||||
@ -174,9 +196,10 @@ darwin_arm_init_mach_exception_handler()
|
||||
}
|
||||
|
||||
// Start a thread to handle exceptions.
|
||||
uintptr_t port_set = (uintptr_t)mach_exception_handler_port_set;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
ret = pthread_create(&thr, &attr, mach_exception_handler, (void*)mach_exception_handler_port_set);
|
||||
ret = pthread_create(&thr, &attr, mach_exception_handler, (void*)port_set);
|
||||
if (ret) {
|
||||
fprintf(stderr, "runtime/cgo: pthread_create failed: %d\n", ret);
|
||||
abort();
|
||||
|
42
src/runtime/cgo/signal_darwin_arm64.s
Normal file
42
src/runtime/cgo/signal_darwin_arm64.s
Normal file
@ -0,0 +1,42 @@
|
||||
// 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"
|
||||
|
||||
// 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 panicmem.
|
||||
//
|
||||
// R1 - LR at moment of fault
|
||||
// R2 - PC at moment of fault
|
||||
TEXT ·panicmem(SB),NOSPLIT,$-8
|
||||
// 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
|
||||
MOVW $139, R1
|
||||
MOVW R1, (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.
|
||||
STP.W (R1, R2), -16(RSP)
|
||||
BL runtime·setsigsegv(SB)
|
||||
LDP.P 16(RSP), (R1, R2)
|
||||
|
||||
MOVD R1, 8(RSP)
|
||||
MOVD R2, R30 // link register
|
||||
B runtime·sigpanic(SB)
|
Loading…
Reference in New Issue
Block a user