// 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.
//
// If you want to debug a segfault under lldb, compile the standard library
// with the build tag lldb:
//
//	go test -tags lldb -installsuffix lldb

// +build darwin,arm,!lldb

// TODO(crawshaw): darwin,arm64,!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"

uintptr_t x_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.
	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;

	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;

	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();
	}

	// Start a thread to handle exceptions.
	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);
	if (ret) {
		fprintf(stderr, "runtime/cgo: pthread_create failed: %d\n", ret);
		abort();
	}
	pthread_attr_destroy(&attr);
}
