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

#ifdef __CYGWIN__
#error "don't use the cygwin compiler to build native Windows programs; use MinGW instead"
#endif

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>

#include "libcgo.h"

#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800
// With modern mingw, we can use the normal struct:
//
// const IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
// 	.Size = sizeof(_load_config_used),
// 	.GuardFlags = IMAGE_GUARD_SECURITY_COOKIE_UNUSED
// };
//
// But we support older toolchains, so instead, fix the offsets:
#ifdef _WIN64
const ULONGLONG _load_config_used[40] = {
	sizeof(_load_config_used),
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	IMAGE_GUARD_SECURITY_COOKIE_UNUSED
};
#else
const DWORD _load_config_used[48] = {
	sizeof(_load_config_used),
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	IMAGE_GUARD_SECURITY_COOKIE_UNUSED
};
#endif

static volatile LONG runtime_init_once_gate = 0;
static volatile LONG runtime_init_once_done = 0;

static CRITICAL_SECTION runtime_init_cs;

static HANDLE runtime_init_wait;
static int runtime_init_done;

// No pthreads on Windows, these are always zero.
uintptr_t x_cgo_pthread_key_created;
void (*x_crosscall2_ptr)(void (*fn)(void *), void *, int, size_t);
void (*_cgo_init)(G*, void (*)(void*), void **, void **);
void (*_cgo_thread_start)(ThreadStart *);
void (*_cgo_sys_thread_create)(void* (*func)(void*));
void (*_cgo_getstackbound)(uintptr[2]);
void (*_cgo_bindm)(void*);

// Pre-initialize the runtime synchronization objects
void
_cgo_preinit_init() {
	 runtime_init_wait = CreateEvent(NULL, TRUE, FALSE, NULL);
	 if (runtime_init_wait == NULL) {
		fprintf(stderr, "runtime: failed to create runtime initialization wait event.\n");
		abort();
	 }

	 InitializeCriticalSection(&runtime_init_cs);
}

// Make sure that the preinit sequence has run.
void
_cgo_maybe_run_preinit() {
	 if (!InterlockedExchangeAdd(&runtime_init_once_done, 0)) {
			if (InterlockedIncrement(&runtime_init_once_gate) == 1) {
				 _cgo_preinit_init();
				 InterlockedIncrement(&runtime_init_once_done);
			} else {
				 // Decrement to avoid overflow.
				 InterlockedDecrement(&runtime_init_once_gate);
				 while(!InterlockedExchangeAdd(&runtime_init_once_done, 0)) {
						Sleep(0);
				 }
			}
	 }
}

int
_cgo_is_runtime_initialized() {
	 int status;

	 EnterCriticalSection(&runtime_init_cs);
	 status = runtime_init_done;
	 LeaveCriticalSection(&runtime_init_cs);
	 return status;
}

uintptr_t
_cgo_wait_runtime_init_done(void) {
	void (*pfn)(struct cgoContextArg*);

	 _cgo_maybe_run_preinit();
	while (!_cgo_is_runtime_initialized()) {
			WaitForSingleObject(runtime_init_wait, INFINITE);
	}
	pfn = _cgo_get_context_function();
	if (pfn != nil) {
		struct cgoContextArg arg;

		arg.Context = 0;
		(*pfn)(&arg);
		return arg.Context;
	}
	return 0;
}

void
x_cgo_notify_runtime_init_done(void* dummy) {
	 _cgo_maybe_run_preinit();

	 EnterCriticalSection(&runtime_init_cs);
	runtime_init_done = 1;
	 LeaveCriticalSection(&runtime_init_cs);

	 if (!SetEvent(runtime_init_wait)) {
		fprintf(stderr, "runtime: failed to signal runtime initialization complete.\n");
		abort();
	}
}

// The traceback function, used when tracing C calls.
static void (*cgo_traceback_function)(struct cgoTracebackArg*);

// The context function, used when tracing back C calls into Go.
static void (*cgo_context_function)(struct cgoContextArg*);

// The symbolizer function, used when symbolizing C frames.
static void (*cgo_symbolizer_function)(struct cgoSymbolizerArg*);

// Sets the traceback, context, and symbolizer functions. Called from
// runtime.SetCgoTraceback.
void x_cgo_set_traceback_functions(struct cgoSetTracebackFunctionsArg* arg) {
	EnterCriticalSection(&runtime_init_cs);
	cgo_traceback_function = arg->Traceback;
	cgo_context_function = arg->Context;
	cgo_symbolizer_function = arg->Symbolizer;
	LeaveCriticalSection(&runtime_init_cs);
}

// Gets the traceback function to call to trace C calls.
void (*(_cgo_get_traceback_function(void)))(struct cgoTracebackArg*) {
	void (*ret)(struct cgoTracebackArg*);

	EnterCriticalSection(&runtime_init_cs);
	ret = cgo_traceback_function;
	LeaveCriticalSection(&runtime_init_cs);
	return ret;
}

// Call the traceback function registered with x_cgo_set_traceback_functions.
//
// On other platforms, this coordinates with C/C++ TSAN. On Windows, there is
// no C/C++ TSAN.
void x_cgo_call_traceback_function(struct cgoTracebackArg* arg) {
	void (*pfn)(struct cgoTracebackArg*);

	pfn = _cgo_get_traceback_function();
	if (pfn == nil) {
		return;
	}

	(*pfn)(arg);
}

// Gets the context function to call to record the traceback context
// when calling a Go function from C code.
void (*(_cgo_get_context_function(void)))(struct cgoContextArg*) {
	void (*ret)(struct cgoContextArg*);

	EnterCriticalSection(&runtime_init_cs);
	ret = cgo_context_function;
	LeaveCriticalSection(&runtime_init_cs);
	return ret;
}

// Gets the symbolizer function to call to symbolize C frames.
void (*(_cgo_get_symbolizer_function(void)))(struct cgoSymbolizerArg*) {
	void (*ret)(struct cgoSymbolizerArg*);

	EnterCriticalSection(&runtime_init_cs);
	ret = cgo_symbolizer_function;
	LeaveCriticalSection(&runtime_init_cs);
	return ret;
}

// Call the symbolizer function registered with x_cgo_set_symbolizer_functions.
//
// On other platforms, this coordinates with C/C++ TSAN. On Windows, there is
// no C/C++ TSAN.
void x_cgo_call_symbolizer_function(struct cgoSymbolizerArg* arg) {
	void (*pfn)(struct cgoSymbolizerArg*);

	pfn = _cgo_get_symbolizer_function();
	if (pfn == nil) {
		return;
	}

	(*pfn)(arg);
}
