// 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.

// Emulation of the Unix signal SIGSEGV.
//
// On iOS, Go tests and apps under development are run by lldb.
// The debugger uses a task-level exception handler to intercept signals.
// Despite having a 'handle' mechanism like gdb, lldb will not allow a
// SIGSEGV to pass to the running program. For Go, this means we cannot
// generate a panic, which cannot be recovered, and so tests fail.
//
// We work around this by registering a thread-level mach exception handler
// and intercepting EXC_BAD_ACCESS. The kernel offers thread handlers a
// chance to resolve exceptions before the task handler, so we can generate
// the panic and avoid lldb's SIGSEGV handler.
//
// The dist tool enables this by build flag when testing.

// +build lldb

#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#include <mach/arm/thread_status.h>
#include <mach/exception_types.h>
#include <mach/mach.h>
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#include <mach/thread_act.h>
#include <mach/thread_status.h>

#include "libcgo.h"
#include "libcgo_unix.h"

void xx_cgo_panicmem(void);
uintptr_t x_cgo_panicmem = (uintptr_t)xx_cgo_panicmem;

static pthread_mutex_t mach_exception_handler_port_set_mu;
static mach_port_t mach_exception_handler_port_set = MACH_PORT_NULL;

kern_return_t
catch_exception_raise(
	mach_port_t exception_port,
	mach_port_t thread,
	mach_port_t task,
	exception_type_t exception,
	exception_data_t code_vector,
	mach_msg_type_number_t code_count)
{
	kern_return_t ret;
	arm_unified_thread_state_t thread_state;
	mach_msg_type_number_t state_count = ARM_UNIFIED_THREAD_STATE_COUNT;

	// Returning KERN_SUCCESS intercepts the exception.
	//
	// Returning KERN_FAILURE lets the exception fall through to the
	// next handler, which is the standard signal emulation code
	// registered on the task port.

	if (exception != EXC_BAD_ACCESS) {
		return KERN_FAILURE;
	}

	ret = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE, (thread_state_t)&thread_state, &state_count);
	if (ret) {
		fprintf(stderr, "runtime/cgo: thread_get_state failed: %d\n", ret);
		abort();
	}

	// 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) {
		fprintf(stderr, "runtime/cgo: thread_set_state failed: %d\n", ret);
		abort();
	}

	return KERN_SUCCESS;
}

void
darwin_arm_init_thread_exception_port()
{
	// Called by each new OS thread to bind its EXC_BAD_ACCESS exception
	// to mach_exception_handler_port_set.
	int ret;
	mach_port_t port = MACH_PORT_NULL;

	ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_allocate failed: %d\n", ret);
		abort();
	}
	ret = mach_port_insert_right(
		mach_task_self(),
		port,
		port,
		MACH_MSG_TYPE_MAKE_SEND);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_insert_right failed: %d\n", ret);
		abort();
	}

	ret = thread_set_exception_ports(
		mach_thread_self(),
		EXC_MASK_BAD_ACCESS,
		port,
		EXCEPTION_DEFAULT,
		THREAD_STATE_NONE);
	if (ret) {
		fprintf(stderr, "runtime/cgo: thread_set_exception_ports failed: %d\n", ret);
		abort();
	}

	ret = pthread_mutex_lock(&mach_exception_handler_port_set_mu);
	if (ret) {
		fprintf(stderr, "runtime/cgo: pthread_mutex_lock failed: %d\n", ret);
		abort();
	}
	ret = mach_port_move_member(
		mach_task_self(),
		port,
		mach_exception_handler_port_set);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_move_member failed: %d\n", ret);
		abort();
	}
	ret = pthread_mutex_unlock(&mach_exception_handler_port_set_mu);
	if (ret) {
		fprintf(stderr, "runtime/cgo: pthread_mutex_unlock failed: %d\n", ret);
		abort();
	}
}

static void*
mach_exception_handler(void *port)
{
	// Calls catch_exception_raise.
	extern boolean_t exc_server();
	mach_msg_server(exc_server, 2048, (mach_port_t)port, 0);
	abort(); // never returns
}

void
darwin_arm_init_mach_exception_handler()
{
	pthread_mutex_init(&mach_exception_handler_port_set_mu, NULL);

	// Called once per process to initialize a mach port server, listening
	// for EXC_BAD_ACCESS thread exceptions.
	int ret;
	pthread_t thr = NULL;
	pthread_attr_t attr;
	sigset_t ign, oset;

	ret = mach_port_allocate(
		mach_task_self(),
		MACH_PORT_RIGHT_PORT_SET,
		&mach_exception_handler_port_set);
	if (ret) {
		fprintf(stderr, "runtime/cgo: mach_port_allocate failed for port_set: %d\n", ret);
		abort();
	}

	// Block all signals to the exception handler thread
	sigfillset(&ign);
	pthread_sigmask(SIG_SETMASK, &ign, &oset);

	// 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 = _cgo_try_pthread_create(&thr, &attr, mach_exception_handler, (void*)port_set);

	pthread_sigmask(SIG_SETMASK, &oset, nil);

	if (ret) {
		fprintf(stderr, "runtime/cgo: pthread_create failed: %d\n", ret);
		abort();
	}
	pthread_attr_destroy(&attr);
}
