/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the mingw-w64 runtime package.
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 */

#include <internal.h>
#include <stdlib.h>
#include <windows.h>
#define _DECL_DLLMAIN
#include <process.h>
#include <crtdbg.h>

#ifndef _CRTIMP
#define _CRTIMP __declspec(dllimport)
#endif
#include <sect_attribs.h>
#include <locale.h>

extern void __cdecl __mingw_dll_do_global_ctors (void);
extern void __cdecl __mingw_dll_do_global_dtors (void);
extern void _pei386_runtime_relocator (void);
extern _PIFV __xi_a[];
extern _PIFV __xi_z[];
extern _PVFV __xc_a[];
extern _PVFV __xc_z[];


/* TLS initialization hook.  */
const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback __attribute__((common)); /* tentative */

void (WINAPI *const __w64_mingwthr_callback_ptr)(HANDLE,DWORD,LPVOID) __attribute__((common)); /* tentative */
const int __w64_mingwthr_callback_caller_provider = 1; /* crtdll.c calls __w64_mingwthr_callback_ptr */

WINBOOL (WINAPI *const __mingw_cxa_tls_callback_ptr)(HANDLE,DWORD,LPVOID) __attribute__((common)); /* tentative */
const int __mingw_cxa_tls_callback_caller_provider = 1; /* crtdll.c calls __mingw_cxa_tls_callback_ptr */

int (__cdecl *const __mingw_dll_atexit_table_func_ptr)(int) __attribute__((common)); /* tentative */

static int __proc_attached = 0;

extern int __mingw_app_type;

WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
  if (dwReason == DLL_PROCESS_DETACH)
    {
      if (__proc_attached > 0)
	__proc_attached--;
      else
	return FALSE;
    }
  if (dwReason == DLL_PROCESS_ATTACH)
    {
      void *lock_free = NULL;
      void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase;
      BOOL nested = FALSE;
      int ret = 0;
      
      while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock,
							     fiberid, NULL)) != 0)
	{
	  if (lock_free == fiberid)
	    {
	      nested = TRUE;
	      break;
	    }
	  Sleep(1000);
	}
      if (__native_startup_state != __uninitialized)
	{
	  ret = 1;
	  goto i__leave;
	}
      else
	{
	  __native_startup_state = __initializing;
	  
	  _pei386_runtime_relocator ();
	  if (__w64_mingwthr_callback_ptr != NULL)
	    __w64_mingwthr_callback_ptr (hDllHandle, dwReason, lpreserved);
	  if (__mingw_dll_atexit_table_func_ptr != NULL)
	    {
	      ret = __mingw_dll_atexit_table_func_ptr (0 /*init*/);
	      if (ret != 0)
		goto i__leave;
	    }
	  if (__mingw_cxa_tls_callback_ptr != NULL)
	    {
	      if (! __mingw_cxa_tls_callback_ptr (hDllHandle, dwReason, lpreserved))
		{
		  ret = 1;
		  goto i__leave;
		}
	    }
	  ret = _initterm_e (__xi_a, __xi_z);
	  if (ret != 0)
	    goto i__leave;
	  _initterm (__xc_a, __xc_z);
	  __mingw_dll_do_global_ctors ();

	  __native_startup_state = __initialized;
	}
i__leave:
      if (! nested)
	{
	  (void) InterlockedExchangePointer (&__native_startup_lock, NULL);
	}
      if (ret != 0)
	{
	  if (__mingw_cxa_tls_callback_ptr != NULL)
	    __mingw_cxa_tls_callback_ptr (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
	  return FALSE;
	}
      if (__dyn_tls_init_callback != NULL)
	{
	  __dyn_tls_init_callback (hDllHandle, DLL_THREAD_ATTACH, lpreserved);
	}
      __proc_attached++;
    }
  else if (dwReason == DLL_PROCESS_DETACH)
    {
      void *lock_free = NULL;
      void *fiberid = ((PNT_TIB)NtCurrentTeb ())->StackBase;
      BOOL nested = FALSE;
      BOOL failed = FALSE;

      while ((lock_free = InterlockedCompareExchangePointer (&__native_startup_lock, fiberid, NULL)) != 0)
	{
	  if (lock_free == fiberid)
	    {
	      nested = TRUE;
	      break;
	    }
	  Sleep(1000);
	}
      if (__native_startup_state != __initialized)
	{
	  failed = TRUE;
	}
      else
	{
	  if (__w64_mingwthr_callback_ptr != NULL)
	    __w64_mingwthr_callback_ptr (hDllHandle, dwReason, lpreserved);
	  if (__mingw_cxa_tls_callback_ptr != NULL)
	    __mingw_cxa_tls_callback_ptr (hDllHandle, dwReason, lpreserved);
	  if (__mingw_dll_atexit_table_func_ptr != NULL)
	    __mingw_dll_atexit_table_func_ptr (1 /*execute*/);
	  __mingw_dll_do_global_dtors ();

	  __native_startup_state = __uninitialized;
	}
      if (! nested)
	{
	  (void) InterlockedExchangePointer (&__native_startup_lock, NULL);
	}
      if (failed)
	{
	  return FALSE;
	}
    }
  else if (dwReason == DLL_THREAD_DETACH)
    {
      if (__w64_mingwthr_callback_ptr != NULL)
	 __w64_mingwthr_callback_ptr (hDllHandle, dwReason, lpreserved);
      if (__mingw_cxa_tls_callback_ptr != NULL)
	{
	  if (! __mingw_cxa_tls_callback_ptr (hDllHandle, dwReason, lpreserved))
	    return FALSE;
	}
    }
  return TRUE;
}

WINBOOL WINAPI DllMainCRTStartup (HANDLE, DWORD, LPVOID);

#if defined(__i386__) || defined(_X86_)
/* We need to make sure that we align the stack to 16 bytes for the sake of SSE
   opts in DllMain or in functions called from DllMain.  */
__attribute__((force_align_arg_pointer))
#endif
__attribute__((used)) /* required due to GNU LD bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30300 */
WINBOOL WINAPI
DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
  WINBOOL retcode = TRUE;

  if (dwReason == DLL_PROCESS_ATTACH)
    __mingw_app_type = 0;

  __native_dllmain_reason = dwReason;
  if (dwReason == DLL_PROCESS_DETACH && __proc_attached <= 0)
    {
	retcode = FALSE;
	goto i__leave;
    }

  if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH)
    {
        retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
        if (!retcode)
          goto i__leave;
    }
  retcode = DllMain(hDllHandle,dwReason,lpreserved);
  if (dwReason == DLL_PROCESS_ATTACH && ! retcode)
    {
	DllMain (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
	_CRT_INIT (hDllHandle, DLL_PROCESS_DETACH, lpreserved);
    }
  if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
    {
	retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved);
    }
i__leave:
  __native_dllmain_reason = UINT_MAX;
  return retcode ;
}

/* not available for DLL builds, must be non-tentative to not be overridden */
void (__cdecl *const __mingw_register_thread_local_exe_atexit_callback_ptr)(void) = NULL;
extern const uintptr_t __mingw_register_thread_local_exe_atexit_callback_provider __attribute__((alias("__mingw_register_thread_local_exe_atexit_callback_ptr")));

const char __mingw_module_is_dll = 1;
