Commit ea90a3a9a1

Andrew Kelley <andrew@ziglang.org>
2019-07-10 20:13:00
mingw: building and linking mingw32.lib
1 parent 1c7f218
libc/include/any-windows-any/_mingw.h
@@ -224,7 +224,7 @@ limitations in handling dllimport attribute.  */
 
 #ifndef __MSVCRT_VERSION__
 /*  High byte is the major version, low byte is the minor. */
-# define __MSVCRT_VERSION__ 0x1400
+# define __MSVCRT_VERSION__ 0x700
 #endif
 
 
libc/mingw/crt/_newmode.c
@@ -0,0 +1,7 @@
+/**
+ * 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.
+ */
+
+int _newmode = 0;
libc/mingw/crt/charmax.c
@@ -0,0 +1,22 @@
+/**
+ * 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 <crtdefs.h>
+#include <sect_attribs.h>
+#include <corecrt_startup.h>
+
+__declspec(dllimport) int __lconv_init (void);
+
+int mingw_initcharmax = 0;
+
+int _charmax = 255;
+
+static int my_lconv_init(void)
+{
+  return __lconv_init();
+}
+
+_CRTALLOC(".CRT$XIC") _PIFV __mingw_pinit = my_lconv_init;
libc/mingw/crt/cinitexe.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <sect_attribs.h>
+
+#ifdef _MSC_VER
+#pragma comment(linker, "/merge:.CRT=.rdata")
+#endif
+
+typedef void (__cdecl *_PVFV)(void);
+
+_CRTALLOC(".CRT$XIA") _PVFV __xi_a[] = { NULL };
+_CRTALLOC(".CRT$XIZ") _PVFV __xi_z[] = { NULL };
+_CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL };
+_CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = { NULL };
libc/mingw/crt/crt0_c.c
@@ -0,0 +1,20 @@
+/**
+ * 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 <windows.h>
+
+extern HINSTANCE __mingw_winmain_hInstance;
+extern LPSTR __mingw_winmain_lpCmdLine;
+extern DWORD __mingw_winmain_nShowCmd;
+
+/*ARGSUSED*/
+int main (int     __UNUSED_PARAM(flags),
+	  char ** __UNUSED_PARAM(cmdline),
+	  char ** __UNUSED_PARAM(inst))
+{
+  return (int) WinMain (__mingw_winmain_hInstance, NULL,
+			__mingw_winmain_lpCmdLine, __mingw_winmain_nShowCmd);
+}
libc/mingw/crt/crt0_w.c
@@ -0,0 +1,25 @@
+/**
+ * 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 <windows.h>
+
+/* Do the UNICODE prototyping of WinMain.  Be aware that in winbase.h WinMain is a macro
+   defined to wWinMain.  */
+int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nShowCmd);
+
+extern HINSTANCE __mingw_winmain_hInstance;
+extern LPWSTR __mingw_winmain_lpCmdLine;
+extern DWORD __mingw_winmain_nShowCmd;
+
+int wmain (int, wchar_t **, wchar_t **);
+
+/*ARGSUSED*/
+int wmain (int        __UNUSED_PARAM(flags),
+	   wchar_t ** __UNUSED_PARAM(cmdline),
+	   wchar_t ** __UNUSED_PARAM(inst))
+{
+  return (int) wWinMain (__mingw_winmain_hInstance, NULL,
+			__mingw_winmain_lpCmdLine, __mingw_winmain_nShowCmd);
+}
libc/mingw/crt/CRT_fp10.c
@@ -0,0 +1,32 @@
+/**
+ * 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.
+ */
+
+void _fpreset (void);
+
+void _fpreset (void)
+{
+#if defined(_ARM_) || defined(__arm__)
+  __asm__ __volatile__ (
+    "vmsr	fpscr, %0\n\t" : : "r"(0 /* INITIAL_FPSCR */));
+#elif defined(_ARM64_) || defined(__aarch64__)
+  __asm__ __volatile__ (
+    "msr	fpcr, %0\n\t" : : "r"(0LL /* INITIAL_FPSCR */));
+#else
+#ifdef __GNUC__
+  __asm__ ("fninit");
+#else /* msvc: */
+  __asm fninit;
+#endif
+#endif
+}
+
+#ifdef __GNUC__
+void __attribute__ ((alias ("_fpreset"))) fpreset(void);
+#else
+void fpreset(void) {
+    _fpreset();
+}
+#endif
libc/mingw/crt/crt_handler.c
@@ -0,0 +1,290 @@
+/**
+ * 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 <windows.h>
+#include <excpt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <signal.h>
+#include <stdio.h>
+
+#if defined (_WIN64) && defined (__ia64__)
+#error FIXME: Unsupported __ImageBase implementation.
+#else
+#ifndef _MSC_VER
+#define __ImageBase __MINGW_LSYMBOL(_image_base__)
+#endif
+/* This symbol is defined by the linker.  */
+extern IMAGE_DOS_HEADER __ImageBase;
+#endif
+
+#pragma pack(push,1)
+typedef struct _UNWIND_INFO {
+  BYTE VersionAndFlags;
+  BYTE PrologSize;
+  BYTE CountOfUnwindCodes;
+  BYTE FrameRegisterAndOffset;
+  ULONG AddressOfExceptionHandler;
+} UNWIND_INFO,*PUNWIND_INFO;
+#pragma pack(pop)
+
+PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
+PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
+PBYTE _GetPEImageBase (void);
+
+int __mingw_init_ehandler (void);
+extern void _fpreset (void);
+
+#if defined(__x86_64__) && !defined(_MSC_VER)
+EXCEPTION_DISPOSITION __mingw_SEH_error_handler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
+
+#define MAX_PDATA_ENTRIES 32
+static RUNTIME_FUNCTION emu_pdata[MAX_PDATA_ENTRIES];
+static UNWIND_INFO emu_xdata[MAX_PDATA_ENTRIES];
+
+int
+__mingw_init_ehandler (void)
+{
+  static int was_here = 0;
+  size_t e = 0;
+  PIMAGE_SECTION_HEADER pSec;
+  PBYTE _ImageBase = _GetPEImageBase ();
+  
+  if (was_here || !_ImageBase)
+    return was_here;
+  was_here = 1;
+  if (_FindPESectionByName (".pdata") != NULL)
+    return 1;
+
+  /* Allocate # of e tables and entries.  */
+  memset (emu_pdata, 0, sizeof (RUNTIME_FUNCTION) * MAX_PDATA_ENTRIES);
+  memset (emu_xdata, 0, sizeof (UNWIND_INFO) * MAX_PDATA_ENTRIES);
+    
+  e = 0;
+  /* Fill tables and entries.  */
+  while (e < MAX_PDATA_ENTRIES && (pSec = _FindPESectionExec (e)) != NULL)
+    {
+      emu_xdata[e].VersionAndFlags = 9; /* UNW_FLAG_EHANDLER | UNW_VERSION */
+      emu_xdata[e].AddressOfExceptionHandler =
+	(DWORD)(size_t) ((LPBYTE)__mingw_SEH_error_handler - _ImageBase);
+      emu_pdata[e].BeginAddress = pSec->VirtualAddress;
+      emu_pdata[e].EndAddress = pSec->VirtualAddress + pSec->Misc.VirtualSize;
+      emu_pdata[e].UnwindData =
+	(DWORD)(size_t)((LPBYTE)&emu_xdata[e] - _ImageBase);
+      ++e;
+    }
+#ifdef _DEBUG_CRT
+  if (!e || e > MAX_PDATA_ENTRIES)
+    abort ();
+#endif
+  /* RtlAddFunctionTable.  */
+  if (e != 0)
+    RtlAddFunctionTable (emu_pdata, e, (DWORD64)_ImageBase);
+  return 1;
+}
+
+extern void _fpreset (void);
+
+EXCEPTION_DISPOSITION
+__mingw_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
+			   void *EstablisherFrame  __attribute__ ((unused)),
+			   struct _CONTEXT* ContextRecord __attribute__ ((unused)),
+			   void *DispatcherContext __attribute__ ((unused)))
+{
+  EXCEPTION_DISPOSITION action = ExceptionContinueSearch; /* EXCEPTION_CONTINUE_SEARCH; */
+  void (*old_handler) (int);
+  int reset_fpu = 0;
+
+  switch (ExceptionRecord->ExceptionCode)
+    {
+    case EXCEPTION_ACCESS_VIOLATION:
+      /* test if the user has set SIGSEGV */
+      old_handler = signal (SIGSEGV, SIG_DFL);
+      if (old_handler == SIG_IGN)
+	{
+	  /* this is undefined if the signal was raised by anything other
+	     than raise ().  */
+	  signal (SIGSEGV, SIG_IGN);
+	  action = 0; //EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else if (old_handler != SIG_DFL)
+	{
+	  /* This means 'old' is a user defined function. Call it */
+	  (*old_handler) (SIGSEGV);
+	  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else
+        action = 4; /* EXCEPTION_EXECUTE_HANDLER; */
+      break;
+    case EXCEPTION_ILLEGAL_INSTRUCTION:
+    case EXCEPTION_PRIV_INSTRUCTION:
+      /* test if the user has set SIGILL */
+      old_handler = signal (SIGILL, SIG_DFL);
+      if (old_handler == SIG_IGN)
+	{
+	  /* this is undefined if the signal was raised by anything other
+	     than raise ().  */
+	  signal (SIGILL, SIG_IGN);
+	  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else if (old_handler != SIG_DFL)
+	{
+	  /* This means 'old' is a user defined function. Call it */
+	  (*old_handler) (SIGILL);
+	  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else
+        action = 4; /* EXCEPTION_EXECUTE_HANDLER;*/
+      break;
+    case EXCEPTION_FLT_INVALID_OPERATION:
+    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+    case EXCEPTION_FLT_DENORMAL_OPERAND:
+    case EXCEPTION_FLT_OVERFLOW:
+    case EXCEPTION_FLT_UNDERFLOW:
+    case EXCEPTION_FLT_INEXACT_RESULT:
+      reset_fpu = 1;
+      /* fall through. */
+
+    case EXCEPTION_INT_DIVIDE_BY_ZERO:
+      /* test if the user has set SIGFPE */
+      old_handler = signal (SIGFPE, SIG_DFL);
+      if (old_handler == SIG_IGN)
+	{
+	  signal (SIGFPE, SIG_IGN);
+	  if (reset_fpu)
+	    _fpreset ();
+	  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else if (old_handler != SIG_DFL)
+	{
+	  /* This means 'old' is a user defined function. Call it */
+	  (*old_handler) (SIGFPE);
+	  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
+	}
+      break;
+    case EXCEPTION_DATATYPE_MISALIGNMENT:
+    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+    case EXCEPTION_FLT_STACK_CHECK:
+    case EXCEPTION_INT_OVERFLOW:
+    case EXCEPTION_INVALID_HANDLE:
+    /*case EXCEPTION_POSSIBLE_DEADLOCK: */
+      action = 0; // EXCEPTION_CONTINUE_EXECUTION;
+      break;
+    default:
+      break;
+    }
+  return action;
+}
+
+#endif
+
+LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler = NULL;
+
+long CALLBACK
+_gnu_exception_handler (EXCEPTION_POINTERS *exception_data);
+
+#define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C' | (1U << 29))
+
+long CALLBACK
+_gnu_exception_handler (EXCEPTION_POINTERS *exception_data)
+{
+  void (*old_handler) (int);
+  long action = EXCEPTION_CONTINUE_SEARCH;
+  int reset_fpu = 0;
+
+#ifdef __SEH__
+  if ((exception_data->ExceptionRecord->ExceptionCode & 0x20ffffff) == GCC_MAGIC)
+    {
+      if ((exception_data->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == 0)
+        return EXCEPTION_CONTINUE_EXECUTION;
+    }
+#endif
+
+  switch (exception_data->ExceptionRecord->ExceptionCode)
+    {
+    case EXCEPTION_ACCESS_VIOLATION:
+      /* test if the user has set SIGSEGV */
+      old_handler = signal (SIGSEGV, SIG_DFL);
+      if (old_handler == SIG_IGN)
+	{
+	  /* this is undefined if the signal was raised by anything other
+	     than raise ().  */
+	  signal (SIGSEGV, SIG_IGN);
+	  action = EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else if (old_handler != SIG_DFL)
+	{
+	  /* This means 'old' is a user defined function. Call it */
+	  (*old_handler) (SIGSEGV);
+	  action = EXCEPTION_CONTINUE_EXECUTION;
+	}
+      break;
+
+    case EXCEPTION_ILLEGAL_INSTRUCTION:
+    case EXCEPTION_PRIV_INSTRUCTION:
+      /* test if the user has set SIGILL */
+      old_handler = signal (SIGILL, SIG_DFL);
+      if (old_handler == SIG_IGN)
+	{
+	  /* this is undefined if the signal was raised by anything other
+	     than raise ().  */
+	  signal (SIGILL, SIG_IGN);
+	  action = EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else if (old_handler != SIG_DFL)
+	{
+	  /* This means 'old' is a user defined function. Call it */
+	  (*old_handler) (SIGILL);
+	  action = EXCEPTION_CONTINUE_EXECUTION;
+	}
+      break;
+
+    case EXCEPTION_FLT_INVALID_OPERATION:
+    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+    case EXCEPTION_FLT_DENORMAL_OPERAND:
+    case EXCEPTION_FLT_OVERFLOW:
+    case EXCEPTION_FLT_UNDERFLOW:
+    case EXCEPTION_FLT_INEXACT_RESULT:
+      reset_fpu = 1;
+      /* fall through. */
+
+    case EXCEPTION_INT_DIVIDE_BY_ZERO:
+      /* test if the user has set SIGFPE */
+      old_handler = signal (SIGFPE, SIG_DFL);
+      if (old_handler == SIG_IGN)
+	{
+	  signal (SIGFPE, SIG_IGN);
+	  if (reset_fpu)
+	    _fpreset ();
+	  action = EXCEPTION_CONTINUE_EXECUTION;
+	}
+      else if (old_handler != SIG_DFL)
+	{
+	  /* This means 'old' is a user defined function. Call it */
+	  (*old_handler) (SIGFPE);
+	  action = EXCEPTION_CONTINUE_EXECUTION;
+	}
+      break;
+#ifdef _WIN64
+    case EXCEPTION_DATATYPE_MISALIGNMENT:
+    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+    case EXCEPTION_FLT_STACK_CHECK:
+    case EXCEPTION_INT_OVERFLOW:
+    case EXCEPTION_INVALID_HANDLE:
+    /*case EXCEPTION_POSSIBLE_DEADLOCK: */
+      action = EXCEPTION_CONTINUE_EXECUTION;
+      break;
+#endif
+    default:
+      break;
+    }
+
+  if (action == EXCEPTION_CONTINUE_SEARCH && __mingw_oldexcpt_handler)
+    action = (*__mingw_oldexcpt_handler)(exception_data);
+  return action;
+}
libc/mingw/crt/cxa_atexit.c
@@ -0,0 +1,151 @@
+/**
+ * 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 <sect_attribs.h>
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <corecrt_startup.h>
+#include <process.h>
+
+
+typedef void (__thiscall * dtor_fn)(void*);
+int __cxa_atexit(dtor_fn dtor, void *obj, void *dso);
+int __cxa_thread_atexit(dtor_fn dtor, void *obj, void *dso);
+
+typedef struct dtor_obj dtor_obj;
+struct dtor_obj {
+  dtor_fn dtor;
+  void *obj;
+  dtor_obj *next;
+};
+
+HANDLE __dso_handle;
+extern char __mingw_module_is_dll;
+
+static CRITICAL_SECTION lock;
+static int inited = 0;
+static dtor_obj *global_dtors = NULL;
+static __thread dtor_obj *tls_dtors = NULL;
+
+int __cxa_atexit(dtor_fn dtor, void *obj, void *dso) {
+  if (!inited)
+    return 1;
+  assert(!dso || dso == &__dso_handle);
+  dtor_obj *handler = (dtor_obj *) calloc(1, sizeof(*handler));
+  if (!handler)
+    return 1;
+  handler->dtor = dtor;
+  handler->obj = obj;
+  EnterCriticalSection(&lock);
+  handler->next = global_dtors;
+  global_dtors = handler;
+  LeaveCriticalSection(&lock);
+  return 0;
+}
+
+static void run_dtor_list(dtor_obj **ptr) {
+  dtor_obj *list = *ptr;
+  while (list) {
+    list->dtor(list->obj);
+    dtor_obj *next = list->next;
+    free(list);
+    list = next;
+  }
+  *ptr = NULL;
+}
+
+int __cxa_thread_atexit(dtor_fn dtor, void *obj, void *dso) {
+  if (!inited)
+    return 1;
+  assert(!dso || dso == &__dso_handle);
+  dtor_obj *handler = (dtor_obj *) calloc(1, sizeof(*handler));
+  if (!handler)
+    return 1;
+  handler->dtor = dtor;
+  handler->obj = obj;
+  handler->next = tls_dtors;
+  tls_dtors = handler;
+  return 0;
+}
+
+static void WINAPI tls_atexit_callback(HANDLE __UNUSED_PARAM(hDllHandle), DWORD dwReason, LPVOID __UNUSED_PARAM(lpReserved)) {
+  if (dwReason == DLL_PROCESS_DETACH) {
+    run_dtor_list(&tls_dtors);
+    run_dtor_list(&global_dtors);
+  }
+}
+
+static void WINAPI tls_callback(HANDLE hDllHandle, DWORD dwReason, LPVOID __UNUSED_PARAM(lpReserved)) {
+  switch (dwReason) {
+  case DLL_PROCESS_ATTACH:
+    if (inited == 0) {
+      InitializeCriticalSection(&lock);
+      __dso_handle = hDllHandle;
+      /*
+       * We can only call _register_thread_local_exe_atexit_callback once
+       * in a process; if we call it a second time the process terminates.
+       * When DLLs are unloaded, this callback is invoked before we run the
+       * _onexit tables, but for exes, we need to ask this to be called before
+       * all other registered atexit functions.
+       * Since we are registered as a normal TLS callback, we will be called
+       * another time later as well, but that doesn't matter, it's safe to
+       * invoke this with DLL_PROCESS_DETACH twice.
+       */
+      if (!__mingw_module_is_dll)
+        _register_thread_local_exe_atexit_callback(tls_atexit_callback);
+    }
+    inited = 1;
+    break;
+  case DLL_PROCESS_DETACH:
+    /*
+     * If there are other threads still running that haven't been detached,
+     * we don't attempt to run their destructors (MSVC doesn't either), but
+     * simply leak the destructor list and whatever resources the destructors
+     * would have released.
+     *
+     * From Vista onwards, we could have used FlsAlloc to get a TLS key that
+     * runs a destructor on each thread that has a value attached ot it, but
+     * since MSVC doesn't run destructors on other threads in this case,
+     * users shouldn't assume it and we don't attempt to do anything potentially
+     * risky about it. TL;DR, threads with pending TLS destructors for a DLL
+     * need to be joined before unloading the DLL.
+     *
+     * This gets called both when exiting cleanly (via exit or returning from
+     * main, or when a DLL is unloaded), and when exiting bypassing some of
+     * the cleanup, by calling _exit or ExitProcess. In the latter cases,
+     * destructors (both TLS and global) in loaded DLLs still get called,
+     * but only TLS destructors get called for the main executable, global
+     * variables' destructors don't run. (This matches what MSVC does with
+     * a dynamically linked CRT.)
+     */
+    run_dtor_list(&tls_dtors);
+    if (__mingw_module_is_dll) {
+      /* For DLLs, run dtors when detached. For EXEs, run dtors via the
+       * thread local atexit callback, to make sure they don't run when
+       * exiting the process with _exit or ExitProcess. */
+      run_dtor_list(&global_dtors);
+    }
+    if (inited == 1) {
+      inited = 0;
+      DeleteCriticalSection(&lock);
+    }
+    break;
+  case DLL_THREAD_ATTACH:
+    break;
+  case DLL_THREAD_DETACH:
+    run_dtor_list(&tls_dtors);
+    break;
+  }
+}
+
+_CRTALLOC(".CRT$XLE") PIMAGE_TLS_CALLBACK __xl_e = (PIMAGE_TLS_CALLBACK) tls_callback;
libc/mingw/crt/dll_argv.c
@@ -0,0 +1,25 @@
+/**
+ * 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.
+ */
+
+#ifdef CRTDLL
+#undef CRTDLL
+#endif
+
+#include <internal.h>
+
+extern int _dowildcard;
+
+#ifdef WPRFLAG
+int __CRTDECL
+__wsetargv (void)
+#else
+int __CRTDECL
+__setargv (void)
+#endif
+{
+  _dowildcard = 1;
+  return 0;
+}
libc/mingw/crt/dllargv.c
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+#ifdef CRTDLL
+#undef CRTDLL
+#endif
+
+#include <internal.h>
+
+#ifdef WPRFLAG
+int __CRTDECL
+_wsetargv (void)
+#else
+int __CRTDECL
+_setargv (void)
+#endif
+{
+  return 0;
+}
libc/mingw/crt/gccmain.c
@@ -0,0 +1,85 @@
+/**
+ * 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 <windows.h>
+#include <stdlib.h>
+#include <setjmp.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+typedef void (*func_ptr) (void);
+extern func_ptr __CTOR_LIST__[];
+extern func_ptr __DTOR_LIST__[];
+
+void __do_global_dtors (void);
+void __do_global_ctors (void);
+void __main (void);
+
+void
+__do_global_dtors (void)
+{
+  static func_ptr *p = __DTOR_LIST__ + 1;
+
+  while (*p)
+    {
+      (*(p)) ();
+      p++;
+    }
+}
+
+#ifndef HAVE_CTOR_LIST
+// If the linker didn't provide __CTOR_LIST__, we provided it ourselves,
+// and then we also know we have __CTOR_END__ available.
+extern func_ptr __CTOR_END__[];
+extern func_ptr __DTOR_END__[];
+
+void __do_global_ctors (void)
+{
+  static func_ptr *p = __CTOR_END__ - 1;
+  while (*p != (func_ptr) -1) {
+    (*(p))();
+    p--;
+  }
+  atexit (__do_global_dtors);
+}
+
+#else
+// old method that iterates the list twice because old linker scripts do not have __CTOR_END__
+
+void
+__do_global_ctors (void)
+{
+  unsigned long nptrs = (unsigned long) (ptrdiff_t) __CTOR_LIST__[0];
+  unsigned long i;
+
+  if (nptrs == (unsigned long) -1)
+    {
+      for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++);
+    }
+
+  for (i = nptrs; i >= 1; i--)
+    {
+      __CTOR_LIST__[i] ();
+    }
+
+  atexit (__do_global_dtors);
+}
+
+#endif
+
+static int initialized = 0;
+
+void
+__main (void)
+{
+  if (!initialized)
+    {
+      initialized = 1;
+      __do_global_ctors ();
+    }
+}
libc/mingw/crt/gs_support.c
@@ -0,0 +1,154 @@
+/**
+ * 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.
+ */
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#define WIN32_NO_STATUS
+#include <stdlib.h>	/* abort () */
+#include <windows.h>
+#undef  WIN32_NO_STATUS
+#include <ntstatus.h>	/* STATUS macros */
+#ifdef _WIN64
+#include <intrin.h>
+#endif
+
+#ifdef _WIN64
+#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
+#else
+#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
+#endif
+
+/* Externals.  */
+
+typedef LONG NTSTATUS;	/* same as in ntdef.h / winternl.h */
+
+#define UNW_FLAG_NHANDLER   0x0
+
+typedef union
+{
+  unsigned __int64 ft_scalar;
+  FILETIME ft_struct;
+} FT;
+
+static EXCEPTION_RECORD GS_ExceptionRecord;
+static CONTEXT GS_ContextRecord;
+
+static const EXCEPTION_POINTERS GS_ExceptionPointers = {
+  &GS_ExceptionRecord,&GS_ContextRecord
+};
+
+DECLSPEC_SELECTANY UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;
+DECLSPEC_SELECTANY UINT_PTR __security_cookie_complement = ~(DEFAULT_SECURITY_COOKIE);
+
+void __cdecl __security_init_cookie (void);
+
+void __cdecl
+__security_init_cookie (void)
+{
+  UINT_PTR cookie;
+  FT systime = { 0, };
+  LARGE_INTEGER perfctr;
+
+  if (__security_cookie != DEFAULT_SECURITY_COOKIE)
+    {
+      __security_cookie_complement = ~__security_cookie;
+      return;
+    }
+
+  GetSystemTimeAsFileTime (&systime.ft_struct);
+#ifdef _WIN64
+  cookie = systime.ft_scalar;
+#else
+  cookie = systime.ft_struct.dwLowDateTime;
+  cookie ^= systime.ft_struct.dwHighDateTime;
+#endif
+
+  cookie ^= GetCurrentProcessId ();
+  cookie ^= GetCurrentThreadId ();
+  cookie ^= GetTickCount ();
+
+  QueryPerformanceCounter (&perfctr);
+#ifdef _WIN64
+  cookie ^= perfctr.QuadPart;
+#else
+  cookie ^= perfctr.LowPart;
+  cookie ^= perfctr.HighPart;
+#endif
+
+#ifdef _WIN64
+  cookie &= 0x0000ffffffffffffll;
+#endif
+
+  if (cookie == DEFAULT_SECURITY_COOKIE)
+    cookie = DEFAULT_SECURITY_COOKIE + 1;
+  __security_cookie = cookie;
+  __security_cookie_complement = ~cookie;
+}
+
+
+#if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */
+#undef  _ReturnAddress
+#undef  _AddressOfReturnAddress
+#define _ReturnAddress()		__builtin_return_address(0)
+#define _AddressOfReturnAddress()	__builtin_frame_address (0)
+#endif /* __GNUC__ */
+
+__declspec(noreturn) void __cdecl __report_gsfailure (ULONG_PTR);
+
+#define UNUSED_PARAM(x) { x = x; }
+__declspec(noreturn) void __cdecl
+__report_gsfailure (ULONG_PTR StackCookie)
+{
+  volatile UINT_PTR cookie[2] __MINGW_ATTRIB_UNUSED;
+#if defined(_WIN64) && !defined(__aarch64__)
+  ULONG64 controlPC, imgBase, establisherFrame;
+  PRUNTIME_FUNCTION fctEntry;
+  PVOID hndData;
+
+  RtlCaptureContext (&GS_ContextRecord);
+  controlPC = GS_ContextRecord.Rip;
+  fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
+  if (fctEntry != NULL)
+    {
+      RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
+			&GS_ContextRecord, &hndData, &establisherFrame, NULL);
+    }
+  else
+#endif /* _WIN64 */
+    {
+#if defined(__x86_64__) || defined(_AMD64_)
+      GS_ContextRecord.Rip = (ULONGLONG) _ReturnAddress();
+      GS_ContextRecord.Rsp = (ULONGLONG) _AddressOfReturnAddress() + 8;
+#elif defined(__i386__) || defined(_X86_)
+      GS_ContextRecord.Eip = (DWORD) _ReturnAddress();
+      GS_ContextRecord.Esp = (DWORD) _AddressOfReturnAddress() + 4;
+#elif defined(__arm__) || defined(_ARM_)
+      GS_ContextRecord.Pc = (DWORD) _ReturnAddress();
+      GS_ContextRecord.Sp = (DWORD) _AddressOfReturnAddress() + 4;
+#endif /* _WIN64 */
+    }
+
+#if defined(__x86_64__) || defined(_AMD64_)
+  GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Rip;
+  GS_ContextRecord.Rcx = StackCookie;
+#elif defined(__i386__) || defined(_X86_)
+  GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Eip;
+  GS_ContextRecord.Ecx = StackCookie;
+#elif defined(__arm__) || defined(_ARM_)
+  GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Pc;
+  UNUSED_PARAM(StackCookie);
+#endif /* _WIN64 */
+  GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+  GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+  cookie[0] = __security_cookie;
+  cookie[1] = __security_cookie_complement;
+  SetUnhandledExceptionFilter (NULL);
+  UnhandledExceptionFilter ((EXCEPTION_POINTERS *) &GS_ExceptionPointers);
+  TerminateProcess (GetCurrentProcess (), STATUS_STACK_BUFFER_OVERRUN);
+  abort();
+}
+
libc/mingw/crt/merr.c
@@ -0,0 +1,76 @@
+/**
+ * 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 <math.h>
+#include <stdio.h>
+
+typedef int (__cdecl *fUserMathErr)(struct _exception *);
+static fUserMathErr stUserMathErr;
+
+void __mingw_raise_matherr (int typ, const char *name, double a1, double a2,
+			    double rslt)
+{
+  struct _exception ex;
+  if (!stUserMathErr)
+    return;
+  ex.type = typ;
+  ex.name = (char*)name;
+  ex.arg1 = a1;
+  ex.arg2 = a2;
+  ex.retval = rslt;
+  (*stUserMathErr)(&ex);
+}
+
+#undef __setusermatherr
+
+void __mingw_setusermatherr (int (__cdecl *f)(struct _exception *))
+{
+  stUserMathErr = f;
+  __setusermatherr (f);
+}
+
+int __CRTDECL
+_matherr (struct _exception *pexcept)
+{
+  const char * type;
+
+  switch(pexcept->type)
+    {
+      case _DOMAIN:
+	type = "Argument domain error (DOMAIN)";
+	break;
+
+      case _SING:
+	type = "Argument singularity (SIGN)";
+	break;
+
+      case _OVERFLOW:
+	type = "Overflow range error (OVERFLOW)";
+	break;
+
+      case _PLOSS:
+	type = "Partial loss of significance (PLOSS)";
+	break;
+
+      case _TLOSS:
+	type = "Total loss of significance (TLOSS)";
+	break;
+
+      case _UNDERFLOW:
+	type = "The result is too small to be represented (UNDERFLOW)";
+	break;
+
+      default:
+	type = "Unknown error";
+	break;
+    }
+
+  fprintf (stderr, "_matherr(): %s in %s(%g, %g)  (retval=%g)\n", 
+	  type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval);
+  return 0;
+}
+
libc/mingw/crt/mingw_helpers.c
@@ -0,0 +1,31 @@
+/**
+ * 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 <oscalls.h>
+#include <internal.h>
+#include <process.h>
+#include <math.h>
+#include <stdlib.h>
+#include <tchar.h>
+#include <sect_attribs.h>
+#include <locale.h>
+
+extern const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback;
+
+void * __cdecl
+_decode_pointer (void *codedptr)
+{
+  return (void *) codedptr;
+}
+
+void * __cdecl
+_encode_pointer (void *ptr)
+{
+  return ptr;
+}
+
+/* 0:console, 1:windows.  */
+int mingw_app_type = 0;
libc/mingw/crt/natstart.c
@@ -0,0 +1,14 @@
+/**
+ * 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 <crtdefs.h>
+#include <internal.h>
+
+_PGLOBAL
+volatile unsigned int __native_dllmain_reason = UINT_MAX;
+volatile unsigned int __native_vcclrit_reason = UINT_MAX;
+volatile __enative_startup_state __native_startup_state;
+volatile void *__native_startup_lock;
libc/mingw/crt/pesect.c
@@ -0,0 +1,230 @@
+/**
+ * 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 <windows.h>
+#include <string.h>
+
+#if defined (_WIN64) && defined (__ia64__)
+#error FIXME: Unsupported __ImageBase implementation.
+#else
+#ifdef __GNUC__
+/* Hack, for bug in ld.  Will be removed soon.  */
+#define __ImageBase __MINGW_LSYMBOL(_image_base__)
+#endif
+/* This symbol is defined by the linker.  */
+extern IMAGE_DOS_HEADER __ImageBase;
+#endif
+
+WINBOOL _ValidateImageBase (PBYTE);
+
+WINBOOL
+_ValidateImageBase (PBYTE pImageBase)
+{
+  PIMAGE_DOS_HEADER pDOSHeader;
+  PIMAGE_NT_HEADERS pNTHeader;
+  PIMAGE_OPTIONAL_HEADER pOptHeader;
+
+  pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase;
+  if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
+    return FALSE;
+  pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew);
+  if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
+    return FALSE;
+  pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader;
+  if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
+    return FALSE;
+  return TRUE;
+}
+
+PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR);
+
+PIMAGE_SECTION_HEADER
+_FindPESection (PBYTE pImageBase, DWORD_PTR rva)
+{
+  PIMAGE_NT_HEADERS pNTHeader;
+  PIMAGE_SECTION_HEADER pSection;
+  unsigned int iSection;
+
+  pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
+
+  for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
+    iSection < pNTHeader->FileHeader.NumberOfSections;
+    ++iSection,++pSection)
+    {
+      if (rva >= pSection->VirtualAddress
+	  && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize)
+	return pSection;
+    }
+  return NULL;
+}
+
+PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
+
+PIMAGE_SECTION_HEADER
+_FindPESectionByName (const char *pName)
+{
+  PBYTE pImageBase;
+  PIMAGE_NT_HEADERS pNTHeader;
+  PIMAGE_SECTION_HEADER pSection;
+  unsigned int iSection;
+
+  /* Long names aren't supported.  */
+  if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME)
+    return NULL;
+
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return NULL;
+
+  pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
+
+  for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
+    iSection < pNTHeader->FileHeader.NumberOfSections;
+    ++iSection,++pSection)
+    {
+      if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME))
+	return pSection;
+    }
+  return NULL;
+}
+
+int __mingw_GetSectionCount (void);
+PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p);
+
+PIMAGE_SECTION_HEADER
+__mingw_GetSectionForAddress (LPVOID p)
+{
+  PBYTE pImageBase;
+  DWORD_PTR rva;
+
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return NULL;
+
+  rva = (DWORD_PTR) (((PBYTE) p) - pImageBase);
+  return _FindPESection (pImageBase, rva);
+}
+
+int
+__mingw_GetSectionCount (void)
+{
+  PBYTE pImageBase;
+  PIMAGE_NT_HEADERS pNTHeader;
+
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return 0;
+
+  pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
+
+  return (int) pNTHeader->FileHeader.NumberOfSections;
+}
+
+
+PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
+
+PIMAGE_SECTION_HEADER
+_FindPESectionExec (size_t eNo)
+{
+  PBYTE pImageBase;
+  PIMAGE_NT_HEADERS pNTHeader;
+  PIMAGE_SECTION_HEADER pSection;
+  unsigned int iSection;
+
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return NULL;
+
+  pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
+
+  for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
+    iSection < pNTHeader->FileHeader.NumberOfSections;
+    ++iSection,++pSection)
+    {
+      if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
+      {
+	if (!eNo)
+	  return pSection;
+	--eNo;
+      }
+    }
+  return NULL;
+}
+
+PBYTE _GetPEImageBase (void);
+
+PBYTE
+_GetPEImageBase (void)
+{
+  PBYTE pImageBase;
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return NULL;
+  return pImageBase;
+}
+
+WINBOOL _IsNonwritableInCurrentImage (PBYTE);
+
+WINBOOL
+_IsNonwritableInCurrentImage (PBYTE pTarget)
+{
+  PBYTE pImageBase;
+  DWORD_PTR rvaTarget;
+  PIMAGE_SECTION_HEADER pSection;
+
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return FALSE;
+  rvaTarget = pTarget - pImageBase;
+  pSection = _FindPESection (pImageBase, rvaTarget);
+  if (pSection == NULL)
+    return FALSE;
+  return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
+}
+
+const char *
+__mingw_enum_import_library_names (int);
+
+const char *
+__mingw_enum_import_library_names (int i)
+{
+  PBYTE pImageBase;
+  PIMAGE_NT_HEADERS pNTHeader;
+  PIMAGE_IMPORT_DESCRIPTOR importDesc;
+  PIMAGE_SECTION_HEADER pSection;
+  DWORD importsStartRVA;
+
+  pImageBase = (PBYTE) &__ImageBase;
+  if (! _ValidateImageBase (pImageBase))
+    return NULL;
+
+  pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
+  
+  importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
+  if (!importsStartRVA)
+    return NULL;
+
+  pSection = _FindPESection (pImageBase, importsStartRVA);
+  if (!pSection)
+      return NULL;
+
+  importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (pImageBase + importsStartRVA);
+  if (!importDesc)
+    return NULL;
+            
+  for (;;)
+    {
+      if (importDesc->TimeDateStamp == 0 && importDesc->Name == 0)
+        break;
+
+      if (i <= 0)
+       return (char *) (pImageBase + importDesc->Name);
+      --i;
+      importDesc++;
+    }
+
+  return NULL;
+}
libc/mingw/crt/pseudo-reloc-list.c
@@ -0,0 +1,8 @@
+/**
+ * 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.
+ */
+
+char __RUNTIME_PSEUDO_RELOC_LIST_END__ = 0;
+char __RUNTIME_PSEUDO_RELOC_LIST__ = 0;
libc/mingw/crt/pseudo-reloc.c
@@ -0,0 +1,487 @@
+/* pseudo-reloc.c
+
+   Contributed by Egor Duda  <deo@logos-m.ru>
+   Modified by addition of runtime_pseudo_reloc version 2
+   by Kai Tietz  <kai.tietz@onevision.com>
+	
+   THIS SOFTWARE IS NOT COPYRIGHTED
+
+   This source code is offered for use in the public domain. You may
+   use, modify or distribute it freely.
+
+   This code is distributed in the hope that it will be useful but
+   WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+   DISCLAMED. This includes but is not limited to warrenties of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <memory.h>
+#include <internal.h>
+
+#if defined(__CYGWIN__)
+#include <wchar.h>
+#include <ntdef.h>
+#include <sys/cygwin.h>
+/* copied from winsup.h */
+# define NO_COPY __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy")))
+/* custom status code: */
+#define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269)
+#define SHORT_MSG_BUF_SZ 128
+#else
+# define NO_COPY
+#endif
+
+#ifdef __GNUC__
+#define ATTRIBUTE_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTRIBUTE_NORETURN
+#endif
+
+#ifndef __MINGW_LSYMBOL
+#define __MINGW_LSYMBOL(sym) sym
+#endif
+
+extern char __RUNTIME_PSEUDO_RELOC_LIST__;
+extern char __RUNTIME_PSEUDO_RELOC_LIST_END__;
+extern char __MINGW_LSYMBOL(_image_base__);
+
+void _pei386_runtime_relocator (void);
+
+/* v1 relocation is basically:
+ *   *(base + .target) += .addend
+ * where (base + .target) is always assumed to point
+ * to a DWORD (4 bytes).
+ */
+typedef struct {
+  DWORD addend;
+  DWORD target;
+} runtime_pseudo_reloc_item_v1;
+
+/* v2 relocation is more complex. In effect, it is
+ *    *(base + .target) += *(base + .sym) - (base + .sym)
+ * with care taken in both reading, sign extension, and writing
+ * because .flags may indicate that (base + .target) may point
+ * to a BYTE, WORD, DWORD, or QWORD (w64).
+ */
+typedef struct {
+  DWORD sym;
+  DWORD target;
+  DWORD flags;
+} runtime_pseudo_reloc_item_v2;
+
+typedef struct {
+  DWORD magic1;
+  DWORD magic2;
+  DWORD version;
+} runtime_pseudo_reloc_v2;
+
+static void ATTRIBUTE_NORETURN
+__report_error (const char *msg, ...)
+{
+#ifdef __CYGWIN__
+  /* This function is used to print short error messages
+   * to stderr, which may occur during DLL initialization
+   * while fixing up 'pseudo' relocations. This early, we
+   * may not be able to use cygwin stdio functions, so we
+   * use the win32 WriteFile api. This should work with both
+   * normal win32 console IO handles, redirected ones, and
+   * cygwin ptys.
+   */
+  char buf[SHORT_MSG_BUF_SZ];
+  wchar_t module[PATH_MAX];
+  char * posix_module = NULL;
+  static const char   UNKNOWN_MODULE[] = "<unknown module>: ";
+  static const size_t UNKNOWN_MODULE_LEN = sizeof (UNKNOWN_MODULE) - 1;
+  static const char   CYGWIN_FAILURE_MSG[] = "Cygwin runtime failure: ";
+  static const size_t CYGWIN_FAILURE_MSG_LEN = sizeof (CYGWIN_FAILURE_MSG) - 1;
+  DWORD len;
+  DWORD done;
+  va_list args;
+  HANDLE errh = GetStdHandle (STD_ERROR_HANDLE);
+  ssize_t modulelen = GetModuleFileNameW (NULL, module, PATH_MAX);
+
+  if (errh == INVALID_HANDLE_VALUE)
+    cygwin_internal (CW_EXIT_PROCESS,
+                     STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION,
+                     1);
+
+  if (modulelen > 0)
+    posix_module = cygwin_create_path (CCP_WIN_W_TO_POSIX, module);
+
+  va_start (args, msg);
+  len = (DWORD) vsnprintf (buf, SHORT_MSG_BUF_SZ, msg, args);
+  va_end (args);
+  buf[SHORT_MSG_BUF_SZ-1] = '\0'; /* paranoia */
+
+  if (posix_module)
+    {
+      WriteFile (errh, (PCVOID)CYGWIN_FAILURE_MSG,
+                 CYGWIN_FAILURE_MSG_LEN, &done, NULL);
+      WriteFile (errh, (PCVOID)posix_module,
+                 strlen(posix_module), &done, NULL);
+      WriteFile (errh, (PCVOID)": ", 2, &done, NULL);
+      WriteFile (errh, (PCVOID)buf, len, &done, NULL);
+      free (posix_module);
+    }
+  else
+    {
+      WriteFile (errh, (PCVOID)CYGWIN_FAILURE_MSG,
+                 CYGWIN_FAILURE_MSG_LEN, &done, NULL);
+      WriteFile (errh, (PCVOID)UNKNOWN_MODULE,
+                 UNKNOWN_MODULE_LEN, &done, NULL);
+      WriteFile (errh, (PCVOID)buf, len, &done, NULL);
+    }
+  WriteFile (errh, (PCVOID)"\n", 1, &done, NULL);
+
+  cygwin_internal (CW_EXIT_PROCESS,
+                   STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION,
+                   1);
+  /* not reached, but silences noreturn warning */
+  abort ();
+#else
+  va_list argp;
+  va_start (argp, msg);
+# ifdef __MINGW64_VERSION_MAJOR
+  fprintf (stderr, "Mingw-w64 runtime failure:\n");
+  vfprintf (stderr, msg, argp);
+# else
+  fprintf (stderr, "Mingw runtime failure:\n");
+  vfprintf (stderr, msg, argp);
+#endif
+  va_end (argp);
+  abort ();
+#endif
+}
+
+/* For mingw-w64 we have additional helpers to get image information
+   on runtime.  This allows us to cache for pseudo-relocation pass
+   the temporary access of code/read-only sections.
+   This step speeds up pseudo-relocation pass.  */
+#ifdef __MINGW64_VERSION_MAJOR
+extern int __mingw_GetSectionCount (void);
+extern PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p);
+extern PBYTE _GetPEImageBase (void);
+
+typedef struct sSecInfo {
+  /* Keeps altered section flags, or zero if nothing was changed.  */
+  DWORD old_protect;
+  PVOID base_address;
+  SIZE_T region_size;
+  PBYTE sec_start;
+  PIMAGE_SECTION_HEADER hash;
+} sSecInfo;
+
+static sSecInfo *the_secs = NULL;
+static int maxSections = 0;
+
+static void
+mark_section_writable (LPVOID addr)
+{
+  MEMORY_BASIC_INFORMATION b;
+  PIMAGE_SECTION_HEADER h;
+  int i;
+
+  for (i = 0; i < maxSections; i++)
+    {
+      if (the_secs[i].sec_start <= ((LPBYTE) addr)
+          && ((LPBYTE) addr) < (the_secs[i].sec_start + the_secs[i].hash->Misc.VirtualSize))
+        return;
+    }
+  h = __mingw_GetSectionForAddress (addr);
+  if (!h)
+    {
+      __report_error ("Address %p has no image-section", addr);
+      return;
+    }
+  the_secs[i].hash = h;
+  the_secs[i].old_protect = 0;
+  the_secs[i].sec_start = _GetPEImageBase () + h->VirtualAddress;
+
+  if (!VirtualQuery (the_secs[i].sec_start, &b, sizeof(b)))
+    {
+      __report_error ("  VirtualQuery failed for %d bytes at address %p",
+		      (int) h->Misc.VirtualSize, the_secs[i].sec_start);
+      return;
+    }
+
+  if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE
+      && b.Protect != PAGE_EXECUTE_WRITECOPY && b.Protect != PAGE_WRITECOPY)
+    {
+      the_secs[i].base_address = b.BaseAddress;
+      the_secs[i].region_size = b.RegionSize;
+      if (!VirtualProtect (b.BaseAddress, b.RegionSize,
+			   PAGE_EXECUTE_READWRITE,
+			   &the_secs[i].old_protect))
+	__report_error ("  VirtualProtect failed with code 0x%x",
+	  (int) GetLastError ());
+    }
+  ++maxSections;
+  return;
+}
+
+static void
+restore_modified_sections (void)
+{
+  int i;
+  DWORD oldprot;
+
+  for (i = 0; i < maxSections; i++)
+    {
+      if (the_secs[i].old_protect == 0)
+        continue;
+      VirtualProtect (the_secs[i].base_address, the_secs[i].region_size,
+                      the_secs[i].old_protect, &oldprot);
+    }
+}
+
+#endif /* __MINGW64_VERSION_MAJOR */
+
+/* This function temporarily marks the page containing addr
+ * writable, before copying len bytes from *src to *addr, and
+ * then restores the original protection settings to the page.
+ *
+ * Using this function eliminates the requirement with older
+ * pseudo-reloc implementations, that sections containing
+ * pseudo-relocs (such as .text and .rdata) be permanently
+ * marked writable. This older behavior sabotaged any memory
+ * savings achieved by shared libraries on win32 -- and was
+ * slower, too.  However, on cygwin as of binutils 2.20 the
+ * .text section is still marked writable, and the .rdata section
+ * is folded into the (writable) .data when --enable-auto-import.
+ */
+static void
+__write_memory (void *addr, const void *src, size_t len)
+{
+  if (!len)
+    return;
+
+#ifdef __MINGW64_VERSION_MAJOR
+  /* Mark the section writable once, and unset it in
+   * restore_modified_sections */
+  mark_section_writable ((LPVOID) addr);
+#else
+  MEMORY_BASIC_INFORMATION b;
+  DWORD oldprot = 0;
+  int call_unprotect = 0;
+
+  if (!VirtualQuery (addr, &b, sizeof(b)))
+    {
+      __report_error ("  VirtualQuery failed for %d bytes at address %p",
+		      (int) sizeof(b), addr);
+    }
+
+  /* Temporarily allow write access to read-only protected memory.  */
+  if (b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE
+      && b.Protect != PAGE_WRITECOPY && b.Protect != PAGE_EXECUTE_WRITECOPY)
+    {
+      call_unprotect = 1;
+      VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,
+		      &oldprot);
+    }
+#endif
+
+  /* write the data. */
+  memcpy (addr, src, len);
+
+#ifndef __MINGW64_VERSION_MAJOR
+  /* Restore original protection. */
+  if (call_unprotect
+      && b.Protect != PAGE_EXECUTE_READWRITE && b.Protect != PAGE_READWRITE
+      && b.Protect != PAGE_WRITECOPY && b.Protect != PAGE_EXECUTE_WRITECOPY)
+    VirtualProtect (b.BaseAddress, b.RegionSize, oldprot, &oldprot);
+#endif
+}
+
+#define RP_VERSION_V1 0
+#define RP_VERSION_V2 1
+
+static void
+do_pseudo_reloc (void * start, void * end, void * base)
+{
+  ptrdiff_t addr_imp, reldata;
+  ptrdiff_t reloc_target = (ptrdiff_t) ((char *)end - (char*)start);
+  runtime_pseudo_reloc_v2 *v2_hdr = (runtime_pseudo_reloc_v2 *) start;
+  runtime_pseudo_reloc_item_v2 *r;
+
+  /* A valid relocation list will contain at least one entry, and
+   * one v1 data structure (the smallest one) requires two DWORDs.
+   * So, if the relocation list is smaller than 8 bytes, bail.
+   */
+  if (reloc_target < 8)
+    return;
+
+  /* Check if this is the old pseudo relocation version.  */
+  /* There are two kinds of v1 relocation lists:
+   *   1) With a (v2-style) version header. In this case, the
+   *      first entry in the list is a 3-DWORD structure, with
+   *      value:
+   *         { 0, 0, RP_VERSION_V1 }
+   *      In this case, we skip to the next entry in the list,
+   *      knowing that all elements after the head item can
+   *      be cast to runtime_pseudo_reloc_item_v1.
+   *   2) Without a (v2-style) version header. In this case, the
+   *      first element in the list IS an actual v1 relocation
+   *      record, which is two DWORDs.  Because there will never
+   *      be a case where a v1 relocation record has both
+   *      addend == 0 and target == 0, this case will not be
+   *      confused with the prior one.
+   * All current binutils, when generating a v1 relocation list,
+   * use the second (e.g. original) form -- that is, without the
+   * v2-style version header.
+   */
+  if (reloc_target >= 12
+      && v2_hdr->magic1 == 0 && v2_hdr->magic2 == 0
+      && v2_hdr->version == RP_VERSION_V1)
+    {
+      /* We have a list header item indicating that the rest
+       * of the list contains v1 entries.  Move the pointer to
+       * the first true v1 relocation record.  By definition,
+       * that v1 element will not have both addend == 0 and
+       * target == 0 (and thus, when interpreted as a
+       * runtime_pseudo_reloc_v2, it will not have both
+       * magic1 == 0 and magic2 == 0).
+       */
+      v2_hdr++;
+    }
+
+  if (v2_hdr->magic1 != 0 || v2_hdr->magic2 != 0)
+    {
+      /*************************
+       * Handle v1 relocations *
+       *************************/
+      runtime_pseudo_reloc_item_v1 * o;
+      for (o = (runtime_pseudo_reloc_item_v1 *) v2_hdr;
+	   o < (runtime_pseudo_reloc_item_v1 *)end;
+           o++)
+	{
+	  DWORD newval;
+	  reloc_target = (ptrdiff_t) base + o->target;
+	  newval = (*((DWORD*) reloc_target)) + o->addend;
+	  __write_memory ((void *) reloc_target, &newval, sizeof(DWORD));
+	}
+      return;
+    }
+
+  /* If we got this far, then we have relocations of version 2 or newer */
+
+  /* Check if this is a known version.  */
+  if (v2_hdr->version != RP_VERSION_V2)
+    {
+      __report_error ("  Unknown pseudo relocation protocol version %d.\n",
+		      (int) v2_hdr->version);
+      return;
+    }
+
+  /*************************
+   * Handle v2 relocations *
+   *************************/
+
+  /* Walk over header. */
+  r = (runtime_pseudo_reloc_item_v2 *) &v2_hdr[1];
+
+  for (; r < (runtime_pseudo_reloc_item_v2 *) end; r++)
+    {
+      /* location where new address will be written */
+      reloc_target = (ptrdiff_t) base + r->target;
+
+      /* get sym pointer. It points either to the iat entry
+       * of the referenced element, or to the stub function.
+       */
+      addr_imp = (ptrdiff_t) base + r->sym;
+      addr_imp = *((ptrdiff_t *) addr_imp);
+
+      /* read existing relocation value from image, casting to the
+       * bitsize indicated by the 8 LSBs of flags. If the value is
+       * negative, manually sign-extend to ptrdiff_t width. Raise an
+       * error if the bitsize indicated by the 8 LSBs of flags is not
+       * supported.
+       */
+      switch ((r->flags & 0xff))
+        {
+          case 8:
+	    reldata = (ptrdiff_t) (*((unsigned char *)reloc_target));
+	    if ((reldata & 0x80) != 0)
+	      reldata |= ~((ptrdiff_t) 0xff);
+	    break;
+	  case 16:
+	    reldata = (ptrdiff_t) (*((unsigned short *)reloc_target));
+	    if ((reldata & 0x8000) != 0)
+	      reldata |= ~((ptrdiff_t) 0xffff);
+	    break;
+	  case 32:
+	    reldata = (ptrdiff_t) (*((unsigned int *)reloc_target));
+#ifdef _WIN64
+	    if ((reldata & 0x80000000) != 0)
+	      reldata |= ~((ptrdiff_t) 0xffffffff);
+#endif
+	    break;
+#ifdef _WIN64
+	  case 64:
+	    reldata = (ptrdiff_t) (*((unsigned long long *)reloc_target));
+	    break;
+#endif
+	  default:
+	    reldata=0;
+	    __report_error ("  Unknown pseudo relocation bit size %d.\n",
+		    (int) (r->flags & 0xff));
+	    break;
+        }
+
+      /* Adjust the relocation value */
+      reldata -= ((ptrdiff_t) base + r->sym);
+      reldata += addr_imp;
+
+      /* Write the new relocation value back to *reloc_target */
+      switch ((r->flags & 0xff))
+	{
+         case 8:
+           __write_memory ((void *) reloc_target, &reldata, 1);
+	   break;
+	 case 16:
+           __write_memory ((void *) reloc_target, &reldata, 2);
+	   break;
+	 case 32:
+           __write_memory ((void *) reloc_target, &reldata, 4);
+	   break;
+#ifdef _WIN64
+	 case 64:
+           __write_memory ((void *) reloc_target, &reldata, 8);
+	   break;
+#endif
+	}
+     }
+}
+
+void
+_pei386_runtime_relocator (void)
+{
+  static NO_COPY int was_init = 0;
+#ifdef __MINGW64_VERSION_MAJOR
+  int mSecs;
+#endif /* __MINGW64_VERSION_MAJOR */
+
+  if (was_init)
+    return;
+  ++was_init;
+#ifdef __MINGW64_VERSION_MAJOR
+  mSecs = __mingw_GetSectionCount ();
+  the_secs = (sSecInfo *) alloca (sizeof (sSecInfo) * (size_t) mSecs);
+  maxSections = 0;
+#endif /* __MINGW64_VERSION_MAJOR */
+
+  do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
+		   &__RUNTIME_PSEUDO_RELOC_LIST_END__,
+#ifdef __GNUC__
+		   &__MINGW_LSYMBOL(_image_base__)
+#else
+		   &__ImageBase
+#endif
+		   );
+#ifdef __MINGW64_VERSION_MAJOR
+  restore_modified_sections ();
+#endif /* __MINGW64_VERSION_MAJOR */
+}
libc/mingw/crt/tlsmcrt.c
@@ -0,0 +1,13 @@
+/**
+ * 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.
+ *
+ * Written by Kai Tietz  <kai.tietz@onevision.com>
+ */
+
+/* We support TLS cleanup code in any case. If shared version of libgcc is used _CRT_MT has value 1,
+ otherwise
+   we do tls cleanup in runtime and _CRT_MT has value 2.  */
+int _CRT_MT = 2;
+
libc/mingw/crt/tlsmthread.c
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ *
+ * Written by Kai Tietz  <kai.tietz@onevision.com>
+ */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <stdlib.h>
+
+int __mingwthr_key_dtor (DWORD key, void (*dtor)(void *));
+int __mingwthr_remove_key_dtor (DWORD key);
+
+extern int ___w64_mingwthr_remove_key_dtor (DWORD key);
+extern int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
+
+int
+__mingwthr_remove_key_dtor (DWORD key)
+{
+   return ___w64_mingwthr_remove_key_dtor (key);
+}
+
+int
+__mingwthr_key_dtor (DWORD key, void (*dtor)(void *))
+{
+  if (dtor)
+    return ___w64_mingwthr_add_key_dtor (key, dtor);
+
+  return 0;
+}
libc/mingw/crt/tlssup.c
@@ -0,0 +1,175 @@
+/**
+ * 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.
+ *
+ * Written by Kai Tietz  <kai.tietz@onevision.com>
+ */
+
+#ifdef CRTDLL
+#undef CRTDLL
+#endif
+
+#include <sect_attribs.h>
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+#include <stdio.h>
+#include <memory.h>
+#include <malloc.h>
+#include <corecrt_startup.h>
+
+extern WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
+
+#define FUNCS_PER_NODE 30
+
+typedef struct TlsDtorNode {
+  int count;
+  struct TlsDtorNode *next;
+  _PVFV funcs[FUNCS_PER_NODE];
+} TlsDtorNode;
+
+ULONG _tls_index = 0;
+
+/* TLS raw template data start and end. 
+   We use here pointer-types for start/end so that tls-data remains
+   aligned on pointer-size-width.  This seems to be required for
+   pe-loader. */
+_CRTALLOC(".tls") char *_tls_start = NULL;
+_CRTALLOC(".tls$ZZZ") char *_tls_end = NULL;
+
+_CRTALLOC(".CRT$XLA") PIMAGE_TLS_CALLBACK __xl_a = 0;
+_CRTALLOC(".CRT$XLZ") PIMAGE_TLS_CALLBACK __xl_z = 0;
+
+const IMAGE_TLS_DIRECTORY _tls_used = {
+  (ULONG_PTR) &_tls_start, (ULONG_PTR) &_tls_end,
+  (ULONG_PTR) &_tls_index, (ULONG_PTR) (&__xl_a+1),
+  (ULONG) 0, (ULONG) 0
+};
+
+#ifndef __CRT_THREAD
+#ifdef HAVE_ATTRIBUTE_THREAD
+#define __CRT_THREAD	__declspec(thread)
+#else
+#define __CRT_THREAD    __thread
+#endif
+#endif
+
+#define DISABLE_MS_TLS 1
+
+static _CRTALLOC(".CRT$XDA") _PVFV __xd_a = 0;
+static _CRTALLOC(".CRT$XDZ") _PVFV __xd_z = 0;
+
+#if !defined (DISABLE_MS_TLS)
+static __CRT_THREAD TlsDtorNode *dtor_list;
+static __CRT_THREAD TlsDtorNode dtor_list_head;
+#endif
+
+extern int _CRT_MT;
+
+BOOL WINAPI __dyn_tls_init (HANDLE, DWORD, LPVOID);
+
+BOOL WINAPI
+__dyn_tls_init (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
+{
+  _PVFV *pfunc;
+  uintptr_t ps;
+
+  /* We don't let us trick here.  */
+  if (_CRT_MT != 2)
+   _CRT_MT = 2;
+
+  if (dwReason != DLL_THREAD_ATTACH)
+    {
+      if (dwReason == DLL_PROCESS_ATTACH)
+        __mingw_TLScallback (hDllHandle, dwReason, lpreserved);
+      return TRUE;
+    }
+
+  ps = (uintptr_t) &__xd_a;
+  ps += sizeof (uintptr_t);
+  for ( ; ps != (uintptr_t) &__xd_z; ps += sizeof (uintptr_t))
+    {
+      pfunc = (_PVFV *) ps;
+      if (*pfunc != NULL)
+	(*pfunc)();
+    }
+  return TRUE;
+}
+
+const PIMAGE_TLS_CALLBACK __dyn_tls_init_callback = (const PIMAGE_TLS_CALLBACK) __dyn_tls_init;
+_CRTALLOC(".CRT$XLC") PIMAGE_TLS_CALLBACK __xl_c = (PIMAGE_TLS_CALLBACK) __dyn_tls_init;
+
+int __cdecl __tlregdtor (_PVFV);
+
+int __cdecl
+__tlregdtor (_PVFV func)
+{
+  if (!func)
+    return 0;
+#if !defined (DISABLE_MS_TLS)
+  if (dtor_list == NULL)
+    {
+      dtor_list = &dtor_list_head;
+      dtor_list_head.count = 0;
+    }
+    else if (dtor_list->count == FUNCS_PER_NODE)
+    {
+      TlsDtorNode *pnode = (TlsDtorNode *) malloc (sizeof (TlsDtorNode));
+      if (pnode == NULL)
+	return -1;
+      pnode->count = 0;
+      pnode->next = dtor_list;
+      dtor_list = pnode;
+
+      dtor_list->count = 0;
+    }
+  dtor_list->funcs[dtor_list->count++] = func;
+#endif
+  return 0;
+}
+
+static BOOL WINAPI
+__dyn_tls_dtor (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
+{
+#if !defined (DISABLE_MS_TLS)
+  TlsDtorNode *pnode, *pnext;
+  int i;
+#endif
+
+  if (dwReason != DLL_THREAD_DETACH && dwReason != DLL_PROCESS_DETACH)
+    return TRUE;
+  /* As TLS variables are detroyed already by DLL_THREAD_DETACH
+     call, we have to avoid access on the possible DLL_PROCESS_DETACH
+     call the already destroyed TLS vars.
+     TODO: The used local thread based variables have to be handled
+     manually, so that we can control their lifetime here.  */
+#if !defined (DISABLE_MS_TLS)
+  if (dwReason != DLL_PROCESS_DETACH)
+    {
+      for (pnode = dtor_list; pnode != NULL; pnode = pnext)
+        {
+          for (i = pnode->count - 1; i >= 0; --i)
+	    {
+	      if (pnode->funcs[i] != NULL)
+	        (*pnode->funcs[i])();
+	    }
+          pnext = pnode->next;
+          if (pnext != NULL)
+	    free ((void *) pnode);
+        }
+    }
+#endif
+  __mingw_TLScallback (hDllHandle, dwReason, lpreserved);
+  return TRUE;
+}
+
+_CRTALLOC(".CRT$XLD") PIMAGE_TLS_CALLBACK __xl_d = (PIMAGE_TLS_CALLBACK) __dyn_tls_dtor;
+
+
+int mingw_initltsdrot_force = 0;
+int mingw_initltsdyn_force = 0;
+int mingw_initltssuo_force = 0;
libc/mingw/crt/tlsthrd.c
@@ -0,0 +1,158 @@
+/**
+ * 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.
+ *
+ * Written by Kai Tietz  <kai.tietz@onevision.com>
+ *
+ * This file is used by if gcc is built with --enable-threads=win32.
+ *
+ * Based on version created by Mumit Khan  <khan@nanotech.wisc.edu>
+ *
+ */
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <stdlib.h>
+
+extern void __cdecl __MINGW_NOTHROW _fpreset (void);
+WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
+int ___w64_mingwthr_remove_key_dtor (DWORD key);
+int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
+
+/* To protect the thread/key association data structure modifications. */
+static CRITICAL_SECTION __mingwthr_cs;
+static volatile int __mingwthr_cs_init = 0;
+
+typedef struct __mingwthr_key __mingwthr_key_t;
+
+/* The list of threads active with key/dtor pairs. */
+struct __mingwthr_key {
+  DWORD key;
+  void (*dtor)(void *);
+  __mingwthr_key_t volatile *next;
+};
+
+
+static __mingwthr_key_t volatile *key_dtor_list;
+
+int
+___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
+{
+  __mingwthr_key_t *new_key;
+
+  if (__mingwthr_cs_init == 0)
+    return 0;
+  new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
+  if (new_key == NULL)
+    return -1;
+
+  new_key->key = key;
+  new_key->dtor = dtor;
+
+  EnterCriticalSection (&__mingwthr_cs);
+
+  new_key->next = key_dtor_list;
+  key_dtor_list = new_key;
+
+  LeaveCriticalSection (&__mingwthr_cs);
+  return 0;
+}
+
+int
+___w64_mingwthr_remove_key_dtor (DWORD key)
+{
+  __mingwthr_key_t volatile *prev_key;
+  __mingwthr_key_t volatile *cur_key;
+
+  if (__mingwthr_cs_init == 0)
+    return 0;
+
+  EnterCriticalSection (&__mingwthr_cs);
+
+  prev_key = NULL;
+  cur_key = key_dtor_list;
+
+  while (cur_key != NULL)
+    {
+      if ( cur_key->key == key)
+        {
+          if (prev_key == NULL)
+            key_dtor_list = cur_key->next;
+          else
+            prev_key->next = cur_key->next;
+
+          free ((void*)cur_key);
+          break;
+        }
+      prev_key = cur_key;
+      cur_key = cur_key->next;
+    }
+
+  LeaveCriticalSection (&__mingwthr_cs);
+  return 0;
+}
+
+static void
+__mingwthr_run_key_dtors (void)
+{
+  __mingwthr_key_t volatile *keyp;
+
+  if (__mingwthr_cs_init == 0)
+    return;
+  EnterCriticalSection (&__mingwthr_cs);
+
+  for (keyp = key_dtor_list; keyp; )
+    {
+      LPVOID value = TlsGetValue (keyp->key);
+      if (GetLastError () == ERROR_SUCCESS)
+        {
+          if (value)
+            (*keyp->dtor) (value);
+        }
+      keyp = keyp->next;
+    }
+
+  LeaveCriticalSection (&__mingwthr_cs);
+}
+
+WINBOOL
+__mingw_TLScallback (HANDLE __UNUSED_PARAM(hDllHandle),
+		     DWORD reason,
+		     LPVOID __UNUSED_PARAM(reserved))
+{
+  switch (reason)
+    {
+    case DLL_PROCESS_ATTACH:
+      if (__mingwthr_cs_init == 0)
+        InitializeCriticalSection (&__mingwthr_cs);
+      __mingwthr_cs_init = 1;
+      break;
+    case DLL_PROCESS_DETACH:
+      __mingwthr_run_key_dtors();
+      if (__mingwthr_cs_init == 1)
+        {
+          __mingwthr_key_t volatile *keyp, *t;
+          for (keyp = key_dtor_list; keyp; )
+          {
+            t = keyp->next;
+            free((void *)keyp);
+            keyp = t;
+          }
+          key_dtor_list = NULL;
+          __mingwthr_cs_init = 0;
+          DeleteCriticalSection (&__mingwthr_cs);
+        }
+      break;
+    case DLL_THREAD_ATTACH:
+      _fpreset();
+      break;
+    case DLL_THREAD_DETACH:
+      __mingwthr_run_key_dtors();
+      break;
+    }
+  return TRUE;
+}
+
libc/mingw/crt/udll_argv.c
@@ -0,0 +1,16 @@
+/**
+ * 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.
+ */
+
+#ifndef UNICODE
+#define UNICODE
+#endif
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#define WPRFLAG 1
+
+#include "dll_argv.c"
+
libc/mingw/crt/udllargc.c
@@ -0,0 +1,16 @@
+/**
+ * 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.
+ */
+
+#ifndef UNICODE
+#define UNICODE
+#endif
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#define WPRFLAG 1
+
+#include "dllargv.c"
+
libc/mingw/crt/wildcard.c
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ */
+
+/* _dowildcard is an int that controls the globbing of the command line.
+ * If _dowildcard is non-zero, the command line will be globbed:  *.*
+ * will be expanded to be all files in the startup directory.
+ *
+ * In the mingw-w64 library the _dowildcard variable is defined as being
+ * 0, therefore command line globbing is DISABLED by default. To turn it
+ * on and to leave wildcard command line processing MS's globbing code,
+ * include a line in one of your source modules defining _dowildcard and
+ * setting it to -1, like so:
+ * int _dowildcard = -1;
+ *
+ * Alternatively, the mingw-w64 library can be configured using the
+ * --enable-wildcard option and compiled thusly upon which the resulting
+ * library will have _dowildcard as -1 and command line globbing will be
+ * enabled by default.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef __ENABLE_GLOBBING
+#define __ENABLE_GLOBBING 0 /* -1 */
+#endif
+
+int _dowildcard = __ENABLE_GLOBBING;
+
libc/mingw/crt/xncommod.c
@@ -0,0 +1,7 @@
+/**
+ * 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.
+ */
+
+int _commode = 0;
libc/mingw/crt/xthdloc.c
@@ -0,0 +1,7 @@
+/**
+ * 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.
+ */
+
+int __globallocalestatus = ~0x1;
libc/mingw/crt/xtxtmode.c
@@ -0,0 +1,6 @@
+/**
+ * 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.
+ */
+int _fmode = 0;
libc/mingw/def-include/func.def.in
@@ -0,0 +1,57 @@
+// F32         - function available on all 32 bit architectures
+// F64         - function available on all 64 bit architectures
+// F_X86_ANY   - function available on i386 and x86_64
+// F_I386      - function available only on i386
+// F_X64       - function available only on x86_64
+// F_ARM32     - function available only on arm32
+// F_ARM64     - function available only on arm64
+// F_ARM_ANY   - function available on 32 and 64 bit arm
+// F_NON_I386  - function available on everything but i386
+#if defined(DEF_X64)
+#define F64(x) x
+#define F_X64(x) x
+#define F_X86_ANY(x) x
+#define F_NON_I386(x) x
+#elif defined(DEF_I386)
+#define F32(x) x
+#define F_I386(x) x
+#define F_X86_ANY(x) x
+#elif defined(DEF_ARM32)
+#define F32(x) x
+#define F_ARM32(x) x
+#define F_ARM_ANY(x) x
+#define F_NON_I386(x) x
+#elif defined(DEF_ARM64)
+#define F64(x) x
+#define F_ARM64(x) x
+#define F_ARM_ANY(x) x
+#define F_NON_I386(x) x
+#endif
+
+#ifndef F32
+#define F32(x)
+#endif
+#ifndef F64
+#define F64(x)
+#endif
+#ifndef F_X86_ANY
+#define F_X86_ANY(x)
+#endif
+#ifndef F_I386
+#define F_I386(x)
+#endif
+#ifndef F_X64
+#define F_X64(x)
+#endif
+#ifndef F_ARM_ANY
+#define F_ARM_ANY(x)
+#endif
+#ifndef F_ARM32
+#define F_ARM32(x)
+#endif
+#ifndef F_ARM64
+#define F_ARM64(x)
+#endif
+#ifndef F_NON_I386
+#define F_NON_I386(x)
+#endif
libc/mingw/def-include/msvcrt-common.def.in
@@ -0,0 +1,145 @@
+#define ADD_UNDERSCORE(symbol) symbol == _ ## symbol
+#define ADD_DOUBLE_UNDERSCORE(symbol) symbol == __ ## symbol
+
+ADD_DOUBLE_UNDERSCORE(iscsymf)
+ADD_DOUBLE_UNDERSCORE(iscsym)
+ADD_DOUBLE_UNDERSCORE(isascii)
+ADD_DOUBLE_UNDERSCORE(toascii)
+
+wcscmpi == _wcsicmp
+strcasecmp == _stricmp
+strncasecmp == _strnicmp
+
+ADD_UNDERSCORE(access)
+ADD_UNDERSCORE(chdir)
+ADD_UNDERSCORE(chmod)
+ADD_UNDERSCORE(chsize)
+ADD_UNDERSCORE(close)
+ADD_UNDERSCORE(creat)
+ADD_UNDERSCORE(cwait)
+ADD_UNDERSCORE(dup)
+ADD_UNDERSCORE(dup2)
+ADD_UNDERSCORE(ecvt)
+ADD_UNDERSCORE(eof)
+ADD_UNDERSCORE(execl)
+ADD_UNDERSCORE(execle)
+ADD_UNDERSCORE(execlp)
+ADD_UNDERSCORE(execlpe)
+ADD_UNDERSCORE(execv)
+ADD_UNDERSCORE(execve)
+ADD_UNDERSCORE(execvp)
+ADD_UNDERSCORE(execvpe)
+ADD_UNDERSCORE(fcvt)
+ADD_UNDERSCORE(fdopen)
+ADD_UNDERSCORE(fgetchar)
+ADD_UNDERSCORE(fgetwchar)
+ADD_UNDERSCORE(filelength)
+ADD_UNDERSCORE(fileno)
+; fpreset)
+ADD_UNDERSCORE(fputchar)
+ADD_UNDERSCORE(fputwchar)
+;fstat)
+;ftime)
+ADD_UNDERSCORE(gcvt)
+ADD_UNDERSCORE(getch)
+ADD_UNDERSCORE(getche)
+ADD_UNDERSCORE(getcwd)
+ADD_UNDERSCORE(getpid)
+ADD_UNDERSCORE(getw)
+ADD_UNDERSCORE(heapwalk)
+ADD_UNDERSCORE(isatty)
+ADD_UNDERSCORE(itoa)
+ADD_UNDERSCORE(kbhit)
+ADD_UNDERSCORE(lfind)
+ADD_UNDERSCORE(lsearch)
+ADD_UNDERSCORE(lseek)
+ADD_UNDERSCORE(ltoa)
+ADD_UNDERSCORE(memccpy)
+ADD_UNDERSCORE(memicmp)
+ADD_UNDERSCORE(mkdir)
+ADD_UNDERSCORE(mktemp)
+ADD_UNDERSCORE(open)
+ADD_UNDERSCORE(pclose)
+ADD_UNDERSCORE(popen)
+ADD_UNDERSCORE(putch)
+ADD_UNDERSCORE(putenv)
+ADD_UNDERSCORE(putw)
+ADD_UNDERSCORE(read)
+ADD_UNDERSCORE(rmdir)
+ADD_UNDERSCORE(rmtmp)
+ADD_UNDERSCORE(searchenv)
+ADD_UNDERSCORE(setmode)
+ADD_UNDERSCORE(sopen)
+ADD_UNDERSCORE(spawnl)
+ADD_UNDERSCORE(spawnle)
+ADD_UNDERSCORE(spawnlp)
+ADD_UNDERSCORE(spawnlpe)
+ADD_UNDERSCORE(spawnv)
+ADD_UNDERSCORE(spawnve)
+ADD_UNDERSCORE(spawnvp)
+ADD_UNDERSCORE(spawnvpe)
+;stat)
+#ifndef UCRTBASE
+ADD_UNDERSCORE(strcmpi)
+#endif
+ADD_UNDERSCORE(strdup)
+ADD_UNDERSCORE(stricmp)
+ADD_UNDERSCORE(stricoll)
+ADD_UNDERSCORE(strlwr)
+ADD_UNDERSCORE(strnicmp)
+ADD_UNDERSCORE(strnset)
+ADD_UNDERSCORE(strrev)
+ADD_UNDERSCORE(strset)
+ADD_UNDERSCORE(strupr)
+ADD_UNDERSCORE(swab)
+ADD_UNDERSCORE(tell)
+ADD_UNDERSCORE(tempnam)
+#ifndef UCRTBASE
+ADD_UNDERSCORE(tzset)
+#endif
+ADD_UNDERSCORE(umask)
+ADD_UNDERSCORE(ungetch)
+ADD_UNDERSCORE(unlink)
+#ifndef UCRTBASE
+ADD_UNDERSCORE(utime)
+#endif
+ADD_UNDERSCORE(wcsdup)
+ADD_UNDERSCORE(wcsicmp)
+ADD_UNDERSCORE(wcsicoll)
+ADD_UNDERSCORE(wcslwr)
+ADD_UNDERSCORE(wcsnicmp)
+ADD_UNDERSCORE(wcsnset)
+ADD_UNDERSCORE(wcsrev)
+ADD_UNDERSCORE(wcsset)
+ADD_UNDERSCORE(wcsupr)
+ADD_UNDERSCORE(wpopen)
+ADD_UNDERSCORE(write)
+; non-ANSI functions declared in math.h
+ADD_UNDERSCORE(j0)
+ADD_UNDERSCORE(j1)
+ADD_UNDERSCORE(jn)
+ADD_UNDERSCORE(y0)
+ADD_UNDERSCORE(y1)
+ADD_UNDERSCORE(yn)
+ADD_UNDERSCORE(chgsign)
+;scalb
+ADD_UNDERSCORE(finite)
+ADD_UNDERSCORE(fpclass)
+; C99 functions
+;cabs
+ADD_UNDERSCORE(hypot)
+;logb
+ADD_UNDERSCORE(nextafter)
+
+#ifndef UCRTBASE
+_daylight DATA
+_timezone DATA
+_tzname DATA
+ADD_UNDERSCORE(daylight)
+ADD_UNDERSCORE(timezone)
+ADD_UNDERSCORE(tzname)
+
+ADD_UNDERSCORE(vsnprintf_s)
+
+longjmp DATA
+#endif
libc/mingw/include/config.h
@@ -0,0 +1,74 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Whether the linker provides __CTOR_LIST__ */
+/* #undef HAVE_CTOR_LIST */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "mingw-w64-runtime"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "mingw-w64-public@lists.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "mingw-w64-runtime"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "mingw-w64-runtime 4.0b"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "mingw-w64-runtime"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "4.0b"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "4.0b"
+
+/* Build DFP support */
+/* #undef __ENABLE_DFP */
+
+/* Define as -1 to enable command line globbing or 0 to disable it. */
+#define __ENABLE_GLOBBING 0
+
+/* Build DFP support */
+/* #undef __ENABLE_PRINTF128 */
+
+/* Build DFP support */
+/* #undef __ENABLE_REGISTEREDPRINTF */
+
+/* Build softmath routines */
+/* #undef __ENABLE_SOFTMATH */
libc/mingw/lib-common/msvcrt.def.in
@@ -0,0 +1,1577 @@
+LIBRARY "msvcrt.dll"
+EXPORTS
+
+#include "func.def.in"
+#include "msvcrt-common.def.in"
+
+#ifdef DEF_I386
+_CIacos
+_CIasin
+_CIatan
+_CIatan2
+_CIcos
+_CIcosh
+_CIexp
+_CIfmod
+_CIlog
+_CIlog10
+_CIpow
+_CIsin
+_CIsinh
+_CIsqrt
+_CItan
+_CItanh
+#endif
+
+#ifdef DEF_X64
+$I10_OUTPUT
+; public: __cdecl __non_rtti_object::__non_rtti_object(class __non_rtti_object const & __ptr64) __ptr64
+; GCC = __ZN17__non_rtti_objectC2ERKS_
+??0__non_rtti_object@@QEAA@AEBV0@@Z
+; public: __cdecl __non_rtti_object::__non_rtti_object(char const * __ptr64) __ptr64
+; GCC = __ZN17__non_rtti_objectC1ERKS_
+??0__non_rtti_object@@QEAA@PEBD@Z
+; private: __cdecl bad_cast::bad_cast(char const * __ptr64 const * __ptr64) __ptr64
+??0bad_cast@@AEAA@PEBQEBD@Z
+; public: __cdecl bad_cast::bad_cast(char const * __ptr64 const & __ptr64) __ptr64
+??0bad_cast@@QEAA@AEBQEBD@Z
+; public: __cdecl bad_cast::bad_cast(class bad_cast const & __ptr64) __ptr64
+??0bad_cast@@QEAA@AEBV0@@Z
+; public: __cdecl bad_cast::bad_cast(char const * __ptr64) __ptr64
+??0bad_cast@@QEAA@PEBD@Z
+; public: __cdecl bad_typeid::bad_typeid(class bad_typeid const & __ptr64) __ptr64
+??0bad_typeid@@QEAA@AEBV0@@Z
+; public: __cdecl bad_typeid::bad_typeid(char const * __ptr64) __ptr64
+??0bad_typeid@@QEAA@PEBD@Z
+; public: __cdecl exception::exception(char const * __ptr64 const & __ptr64) __ptr64
+??0exception@@QEAA@AEBQEBD@Z
+; public: __cdecl exception::exception(char const * __ptr64 const & __ptr64,int) __ptr64
+??0exception@@QEAA@AEBQEBDH@Z
+; public: __cdecl exception::exception(class exception const & __ptr64) __ptr64
+??0exception@@QEAA@AEBV0@@Z
+; public: __cdecl exception::exception(void) __ptr64
+??0exception@@QEAA@XZ
+; public: virtual __cdecl __non_rtti_object::~__non_rtti_object(void) __ptr64
+??1__non_rtti_object@@UEAA@XZ
+; public: virtual __cdecl bad_cast::~bad_cast(void) __ptr64
+??1bad_cast@@UEAA@XZ
+; public: virtual __cdecl bad_typeid::~bad_typeid(void) __ptr64
+??1bad_typeid@@UEAA@XZ
+; public: virtual __cdecl exception::~exception(void) __ptr64
+??1exception@@UEAA@XZ
+; public: virtual __cdecl type_info::~type_info(void) __ptr64
+??1type_info@@UEAA@XZ
+; void * __ptr64 __cdecl operator new(unsigned __int64)
+; GCC = __Znwy
+??2@YAPEAX_K@Z
+; void __cdecl operator delete(void * __ptr64)
+; GCC = __ZdlPv
+??3@YAXPEAX@Z
+; public: class __non_rtti_object & __ptr64 __cdecl __non_rtti_object::operator=(class __non_rtti_object const & __ptr64) __ptr64
+??4__non_rtti_object@@QEAAAEAV0@AEBV0@@Z
+; public: class bad_cast & __ptr64 __cdecl bad_cast::operator=(class bad_cast const & __ptr64) __ptr64
+??4bad_cast@@QEAAAEAV0@AEBV0@@Z
+; public: class bad_typeid & __ptr64 __cdecl bad_typeid::operator=(class bad_typeid const & __ptr64) __ptr64
+??4bad_typeid@@QEAAAEAV0@AEBV0@@Z
+; public: class exception & __ptr64 __cdecl exception::operator=(class exception const & __ptr64) __ptr64
+??4exception@@QEAAAEAV0@AEBV0@@Z
+; public: int __cdecl type_info::operator==(class type_info const & __ptr64)const  __ptr64
+??8type_info@@QEBAHAEBV0@@Z
+; public: int __cdecl type_info::operator!=(class type_info const & __ptr64)const  __ptr64
+??9type_info@@QEBAHAEBV0@@Z
+; const  __non_rtti_object::`vftable'
+??_7__non_rtti_object@@6B@
+; const  bad_cast::`vftable'
+??_7bad_cast@@6B@
+; const  bad_typeid::`vftable'
+??_7bad_typeid@@6B@
+; const  exception::`vftable'
+??_7exception@@6B@
+; public: void __cdecl bad_cast::`default constructor closure'(void) __ptr64
+??_Fbad_cast@@QEAAXXZ
+; public: void __cdecl bad_typeid::`default constructor closure'(void) __ptr64
+??_Fbad_typeid@@QEAAXXZ
+; void * __ptr64 __cdecl operator new[](unsigned __int64)
+; GNU = __Znay
+??_U@YAPEAX_K@Z
+; void __cdecl operator delete[](void * __ptr64)
+; GNU = __ZdaPv
+??_V@YAXPEAX@Z
+; int (__cdecl*__cdecl _query_new_handler(void))(unsigned __int64)
+; GNU = __Z18_query_new_handlerv
+?_query_new_handler@@YAP6AH_K@ZXZ
+; int __cdecl _query_new_mode(void)
+; GNU = __Z15_query_new_modev
+?_query_new_mode@@YAHXZ
+; int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned __int64)))(unsigned __int64)
+; GNU = __Z16_set_new_handlerPFiyE
+?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z
+; int __cdecl _set_new_mode(int)
+; GNU = __Z13_set_new_modei
+?_set_new_mode@@YAHH@Z
+; void (__cdecl*__cdecl _set_se_translator(void (__cdecl*)(unsigned int,struct _EXCEPTION_POINTERS * __ptr64)))(unsigned int,struct _EXCEPTION_POINTERS * __ptr64)
+; GNU = __Z18_set_se_translatorPFvjP19_EXCEPTION_POINTERSE
+?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
+; public: int __cdecl type_info::before(class type_info const & __ptr64)const  __ptr64
+?before@type_info@@QEBAHAEBV1@@Z
+; public: char const * __ptr64 __cdecl type_info::name(void)const  __ptr64
+?name@type_info@@QEBAPEBDXZ
+; public: char const * __ptr64 __cdecl type_info::raw_name(void)const  __ptr64
+?raw_name@type_info@@QEBAPEBDXZ
+; void (__cdecl*__cdecl set_new_handler(void (__cdecl*)(void)))(void)
+; GNU = __Z15set_new_handlerPFvvE
+?set_new_handler@@YAP6AXXZP6AXXZ@Z
+; void (__cdecl*__cdecl set_terminate(void (__cdecl*)(void)))(void)
+; GNU = __Z13set_terminatePFvvE
+?set_terminate@@YAP6AXXZP6AXXZ@Z
+; void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void)
+; GNU = __Z14set_unexpectedPFvvE
+?set_unexpected@@YAP6AXXZP6AXXZ@Z
+; void __cdecl terminate(void)
+; GNU = __Z9terminatev
+?terminate@@YAXXZ
+; void __cdecl unexpected(void)
+; GNU = __Z10unexpectedv
+?unexpected@@YAXXZ
+; public: virtual char const * __ptr64 __cdecl exception::what(void)const  __ptr64
+?what@exception@@UEBAPEBDXZ
+#endif
+
+#ifdef DEF_ARM32
+??0__non_rtti_object@@QAA@ABV0@@Z
+??0__non_rtti_object@@QAA@PBD@Z
+??0bad_cast@@AAA@PBQBD@Z
+??0bad_cast@@QAA@ABV0@@Z
+??0bad_cast@@QAA@PBD@Z
+??0bad_typeid@@QAA@ABV0@@Z
+??0bad_typeid@@QAA@PBD@Z
+??0exception@@QAA@ABQBD@Z
+??0exception@@QAA@ABQBDH@Z
+??0exception@@QAA@ABV0@@Z
+??0exception@@QAA@XZ
+??1__non_rtti_object@@UAA@XZ
+??1bad_cast@@UAA@XZ
+??1bad_typeid@@UAA@XZ
+??1exception@@UAA@XZ
+??1type_info@@UAA@XZ
+??2@YAPAXI@Z
+??2@YAPAXIHPBDH@Z
+??3@YAXPAX@Z
+??4__non_rtti_object@@QAAAAV0@ABV0@@Z
+??4bad_cast@@QAAAAV0@ABV0@@Z
+??4bad_typeid@@QAAAAV0@ABV0@@Z
+??4exception@@QAAAAV0@ABV0@@Z
+??8type_info@@QBAHABV0@@Z
+??9type_info@@QBAHABV0@@Z
+??_7__non_rtti_object@@6B@ DATA
+??_7bad_cast@@6B@ DATA
+??_7bad_typeid@@6B@ DATA
+??_7exception@@6B@ DATA
+??_Fbad_cast@@QAAXXZ
+??_Fbad_typeid@@QAAXXZ
+??_U@YAPAXI@Z
+??_U@YAPAXIHPBDH@Z
+??_V@YAXPAX@Z
+_CallMemberFunction0
+_CallMemberFunction1
+_CallMemberFunction2
+__ExceptionPtrAssign
+__ExceptionPtrCompare
+__ExceptionPtrCopy
+__ExceptionPtrCopyException
+__ExceptionPtrCreate
+__ExceptionPtrCurrentException
+__ExceptionPtrDestroy
+__ExceptionPtrRethrow
+__ExceptionPtrSwap
+__ExceptionPtrToBool
+?_query_new_handler@@YAP6AHI@ZXZ
+?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
+?_set_new_mode@@YAHH@Z
+?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
+?before@type_info@@QBAHABV1@@Z
+?name@type_info@@QBAPBDXZ
+?raw_name@type_info@@QBAPBDXZ
+?set_terminate@@YAP6AXXZP6AXXZ@Z
+?set_unexpected@@YAP6AXXZP6AXXZ@Z
+?terminate@@YAXXZ
+?unexpected@@YAXXZ
+?what@exception@@UBAPBDXZ
+#endif
+
+#ifdef DEF_ARM32
+_CrtCheckMemory
+_CrtDbgBreak
+_CrtDbgReport
+_CrtDbgReportV
+_CrtDbgReportW
+_CrtDbgReportWV
+_CrtDoForAllClientObjects
+_CrtDumpMemoryLeaks
+_CrtIsMemoryBlock
+_CrtIsValidHeapPointer
+_CrtIsValidPointer
+_CrtMemCheckpoint
+_CrtMemDifference
+_CrtMemDumpAllObjectsSince
+_CrtMemDumpStatistics
+_CrtReportBlockType
+_CrtSetAllocHook
+_CrtSetBreakAlloc
+_CrtSetDbgBlockType
+_CrtSetDbgFlag
+_CrtSetDumpClient
+_CrtSetReportFile
+_CrtSetReportHook
+_CrtSetReportHook2
+_CrtSetReportMode
+#endif
+_CxxThrowException
+F_I386(_EH_prolog)
+_Getdays
+_Getmonths
+_Gettnames
+_HUGE DATA
+_Strftime
+F_ARM_ANY(_W_Getdays)
+F_ARM_ANY(_W_Getmonths)
+F_ARM_ANY(_W_Gettnames)
+F_ARM_ANY(_Wcsftime)
+_XcptFilter
+F_ARM_ANY(__AdjustPointer)
+F_NON_I386(__C_specific_handler)
+__CppXcptFilter
+F_I386(__CxxCallUnwindDtor)
+F_I386(__CxxCallUnwindVecDtor)
+F_I386(__CxxDetectRethrow)
+F_I386(__CxxExceptionFilter)
+__CxxFrameHandler
+F_ARM_ANY(__CxxFrameHandler3)
+F_I386(__CxxLongjmpUnwind)
+F_I386(__CxxQueryExceptionSize)
+F_I386(__CxxRegisterExceptionObject)
+F_I386(__CxxUnregisterExceptionObject)
+__DestructExceptionObject
+__RTCastToVoid
+__RTDynamicCast
+__RTtypeid
+__STRINGTOLD
+F_NON_I386(___lc_codepage_func)
+___lc_collate_cp_func
+___lc_handle_func
+___mb_cur_max_func
+___setlc_active_func
+___unguarded_readlc_active_add_func
+__argc DATA
+__argv DATA
+__badioinfo DATA
+F_I386(__buffer_overrun)
+__crtCompareStringA
+__crtCompareStringW
+__crtGetLocaleInfoW
+__crtGetStringTypeW
+__crtLCMapStringA
+__crtLCMapStringW
+F_ARM_ANY(__daylight)
+__dllonexit
+__doserrno
+F_ARM_ANY(__dstbias)
+__fpecode
+__getmainargs
+F_X86_ANY(__initenv DATA)
+__iob_func
+__isascii
+__iscsym
+__iscsymf
+F_I386(__lc_clike)
+__lc_codepage DATA
+__lc_collate_cp DATA
+__lc_handle DATA
+__lconv_init
+__mb_cur_max DATA
+#ifdef DEF_I386
+__p___argc
+__p___argv
+__p___initenv
+__p___mb_cur_max
+__p___wargv
+__p___winitenv
+__p__acmdln
+__p__amblksiz
+__p__commode
+__p__daylight
+__p__dstbias
+__p__environ
+__p__fileinfo
+__p__fmode
+__p__iob
+__p__mbcasemap
+__p__mbctype
+__p__osver
+__p__pctype
+__p__pgmptr
+__p__pwctype
+__p__timezone
+__p__tzname
+__p__wcmdln
+__p__wenviron
+__p__winmajor
+__p__winminor
+__p__winver
+__p__wpgmptr
+#endif
+__pctype_func
+__pioinfo DATA
+__pwctype_func
+__pxcptinfoptrs
+F_I386(__security_error_handler)
+__set_app_type
+F_I386(__set_buffer_overrun_handler)
+__setlc_active DATA
+__setusermatherr
+F_ARM_ANY(__strncnt)
+__threadhandle
+__threadid
+__toascii
+__uncaught_exception
+__unDName
+__unDNameEx
+__unguarded_readlc_active DATA
+__wargv DATA
+__wcserror
+F_NON_I386(__wcserror_s)
+F_ARM_ANY(__wcsncnt)
+__wgetmainargs
+F_X86_ANY(__winitenv DATA)
+F_I386(_abnormal_termination)
+F_NON_I386(_abs64)
+_access
+; _access_s Replaced by emu
+_acmdln DATA
+#ifdef DEF_I386
+_adj_fdiv_m16i
+_adj_fdiv_m32
+_adj_fdiv_m32i
+_adj_fdiv_m64
+_adj_fdiv_r
+_adj_fdivr_m16i
+_adj_fdivr_m32
+_adj_fdivr_m32i
+_adj_fdivr_m64
+_adj_fpatan
+_adj_fprem
+_adj_fprem1
+_adj_fptan
+_adjust_fdiv DATA
+#endif
+_aexit_rtn DATA
+_aligned_free
+F_ARM_ANY(_aligned_free_dbg)
+_aligned_malloc
+F_ARM_ANY(_aligned_malloc_dbg)
+_aligned_offset_malloc
+F_ARM_ANY(_aligned_offset_malloc_dbg)
+_aligned_offset_realloc
+F_ARM_ANY(_aligned_offset_realloc_dbg)
+_aligned_realloc
+F_ARM_ANY(_aligned_realloc_dbg)
+_amsg_exit
+_assert DATA
+_atodbl
+_atodbl_l
+_atof_l
+_atoflt_l
+_atoi64
+_atoi64_l
+_atoi_l
+_atol_l
+_atoldbl
+F_NON_I386(_atoldbl_l)
+_beep
+_beginthread
+_beginthreadex
+_c_exit
+_cabs DATA
+_callnewh
+F_ARM_ANY(_calloc_dbg)
+_cexit
+_cgets
+; _cgets_s replaced by emu
+_cgetws
+; _cgetws_s replaced by emu
+_chdir
+_chdrive
+_chgsign
+F_NON_I386(_chgsignf)
+_chmod
+F_I386(_chkesp)
+_chsize
+; _chsize_s replaced by emu
+F_ARM_ANY(_chvalidator)
+F_ARM_ANY(_chvalidator_l)
+_clearfp
+_close
+_commit
+_commode DATA
+_control87
+_controlfp
+; _controlfp_s replaced by emu
+_copysign
+F_NON_I386(_copysignf)
+_cprintf
+_cprintf_l
+_cprintf_p
+_cprintf_p_l
+; _cprintf_s Replaced by emu
+; _cprintf_s_l likewise.
+_cputs
+_cputws
+F_I386(_CRT_RTC_INIT)
+_creat
+_create_locale
+F_ARM32(_crtAssertBusy)
+F_ARM32(_crtBreakAlloc)
+F_ARM32(_crtDbgFlag)
+_cscanf
+_cscanf_l
+_cscanf_s
+_cscanf_s_l
+F_ARM_ANY(_ctime32)
+F_I386(_ctime32 == ctime)
+; _ctime32_s replaced by emu
+_ctime64
+; _ctime64_s replaced by emu
+_ctype F_I386(DATA)
+_cwait
+_cwprintf
+_cwprintf_l
+_cwprintf_p
+_cwprintf_p_l
+; _cwprintf_s Replaced by emu
+; _cwprintf_s_l Likewise.
+_cwscanf
+_cwscanf_l
+_cwscanf_s
+_cwscanf_s_l
+_dstbias DATA
+F_ARM_ANY(_daylight DATA)
+F_ARM_ANY(_difftime32)
+F_ARM_ANY(_difftime64)
+_dup
+_dup2
+_ecvt
+_ecvt_s
+_endthread
+_endthreadex
+F_X86_ANY(_environ DATA)
+_eof
+_errno
+F_I386(_except_handler2)
+F_I386(_except_handler3)
+_execl
+_execle
+_execlp
+_execlpe
+_execv
+_execve
+_execvp
+_execvpe
+_exit
+_expand
+F_ARM_ANY(_expand_dbg)
+_fcloseall
+_fcvt
+_fcvt_s
+_fdopen
+_fgetchar
+_fgetwchar
+_filbuf
+F_X86_ANY(_fileinfo DATA)
+_filelength
+_filelengthi64
+_fileno
+_findclose
+_findfirst
+F32(_findfirst32 == _findfirst)
+_findfirst64
+_findfirsti64
+F32(_findfirst32i64 == _findfirsti64)
+F64(_findfirst64i32 == _findfirst)
+_findnext
+F32(_findnext32 == _findnext)
+_findnext64
+_findnexti64
+F32(_findnext32i64 == _findnexti64)
+F64(_findnext64i32 == _findnext)
+_finite
+F_NON_I386(_finitef)
+_flsbuf
+_flushall
+_fmode DATA
+_fpclass
+F_X64(_fpclassf)
+F_I386(_fpieee_flt)
+F_ARM_ANY(_fpieee_flt)
+_fpreset DATA
+_fprintf_l
+_fprintf_p
+_fprintf_p_l
+_fprintf_s_l
+_fputchar
+_fputwchar
+F_ARM_ANY(_free_dbg)
+_free_locale
+F_ARM_ANY(_freea)
+F_NON_I386(_fscanf_l)
+F_NON_I386(_fscanf_s_l)
+F_ARM_ANY(_fseeki64)
+_fsopen
+_fstat
+F32(_fstat32 == _fstat)
+_fstat64
+_fstati64
+F64(_fstat64i32 == _fstat)
+_ftime
+F_ARM_ANY(_ftime32)
+_ftime32_s
+_ftime64
+_ftime64_s
+F32(_ftime_s == _ftime32_s)
+F64(_ftime_s == _ftime64_s)
+F_I386(_ftol)
+_fullpath
+F_ARM_ANY(_fullpath_dbg)
+_futime
+F_ARM_ANY(_futime32)
+_futime64
+_fwprintf_l
+_fwprintf_p
+_fwprintf_p_l
+_fwprintf_s_l
+_fwscanf_l
+_fwscanf_s_l
+_gcvt
+_gcvt_s
+F_ARM_ANY(_get_current_locale)
+F_ARM_ANY(_get_doserrno)
+F_ARM_ANY(_get_environ)
+F_ARM_ANY(_get_errno)
+F_ARM_ANY(_get_fileinfo)
+F_ARM_ANY(_get_fmode)
+_get_heap_handle
+_get_osfhandle
+;_get_output_format provided by emu
+_get_sbh_threshold
+F_ARM_ANY(_get_wenviron)
+_getch
+_getche
+_getcwd
+_getdcwd
+_getdiskfree
+_getdllprocaddr
+_getdrive
+_getdrives
+_getmaxstdio
+_getmbcp
+_getpid
+_getsystime
+_getw
+_getwch
+_getwche
+_getws
+F_I386(_global_unwind2)
+_gmtime32 F_I386(== gmtime)
+; _gmtime32_s replaced by emu
+_gmtime64
+; _gmtime64_s replaced by emu
+_heapadd
+_heapchk
+_heapmin
+_heapset
+_heapused
+_heapwalk
+_hypot
+F_NON_I386(_hypotf)
+_i64toa
+_i64toa_s
+_i64tow
+_i64tow_s
+_initterm
+F_ARM_ANY(_initterm_e)
+F_I386(_inp)
+F_I386(_inpd)
+F_I386(_inpw)
+F_ARM_ANY(_invalid_parameter)
+_iob DATA
+_isalnum_l
+_isalpha_l
+_isatty
+_iscntrl_l
+_isctype
+_isctype_l
+_isdigit_l
+_isgraph_l
+_isleadbyte_l
+_islower_l
+_ismbbalnum
+_ismbbalnum_l
+_ismbbalpha
+_ismbbalpha_l
+_ismbbgraph
+_ismbbgraph_l
+_ismbbkalnum
+_ismbbkalnum_l
+_ismbbkana
+_ismbbkana_l
+_ismbbkprint
+_ismbbkprint_l
+_ismbbkpunct
+_ismbbkpunct_l
+_ismbblead
+_ismbblead_l
+_ismbbprint
+_ismbbprint_l
+_ismbbpunct
+_ismbbpunct_l
+_ismbbtrail
+_ismbbtrail_l
+_ismbcalnum
+_ismbcalnum_l
+_ismbcalpha
+_ismbcalpha_l
+_ismbcdigit
+_ismbcdigit_l
+_ismbcgraph
+_ismbcgraph_l
+_ismbchira
+_ismbchira_l
+_ismbckata
+_ismbckata_l
+_ismbcl0
+_ismbcl0_l
+_ismbcl1
+_ismbcl1_l
+_ismbcl2
+_ismbcl2_l
+_ismbclegal
+_ismbclegal_l
+_ismbclower
+_ismbclower_l
+_ismbcprint
+_ismbcprint_l
+_ismbcpunct
+_ismbcpunct_l
+_ismbcspace
+_ismbcspace_l
+_ismbcsymbol
+_ismbcsymbol_l
+_ismbcupper
+_ismbcupper_l
+_ismbslead
+_ismbslead_l
+_ismbstrail
+_ismbstrail_l
+_isnan
+F_X64(_isnanf)
+_isprint_l
+_isspace_l
+_isupper_l
+_iswalnum_l
+_iswalpha_l
+_iswcntrl_l
+_iswctype_l
+_iswdigit_l
+_iswgraph_l
+_iswlower_l
+_iswprint_l
+_iswpunct_l
+_iswspace_l
+_iswupper_l
+_iswxdigit_l
+_isxdigit_l
+_itoa
+_itoa_s
+_itow
+_itow_s
+_j0
+_j1
+_jn
+_kbhit
+_lfind
+_loaddll
+F_NON_I386(_lfind_s)
+F_X64(_local_unwind)
+F_I386(_local_unwind2)
+_localtime32 F_I386(== localtime)
+; _localtime32_s replaced by emu
+_localtime64
+; _localtime64_s replaced by emu
+_lock
+_locking
+_logb
+F_NON_I386(_logbf)
+F_I386(_longjmpex)
+_lrotl
+_lrotr
+_lsearch
+F_NON_I386(_lsearch_s)
+_lseek
+_lseeki64
+_ltoa
+F_NON_I386(_ltoa_s)
+_ltow
+F_NON_I386(_ltow_s)
+_makepath
+_makepath_s
+F_ARM_ANY(_malloc_dbg)
+_mbbtombc
+_mbbtombc_l
+_mbbtype
+_mbcasemap F_NON_I386(DATA)
+_mbccpy
+_mbccpy_l
+_mbccpy_s
+_mbccpy_s_l
+_mbcjistojms
+_mbcjistojms_l
+_mbcjmstojis
+_mbcjmstojis_l
+_mbclen
+_mbclen_l
+_mbctohira
+_mbctohira_l
+_mbctokata
+_mbctokata_l
+_mbctolower
+_mbctolower_l
+_mbctombb
+_mbctombb_l
+_mbctoupper
+_mbctoupper_l
+_mbctype DATA
+_mblen_l
+_mbsbtype
+_mbsbtype_l
+_mbscat
+_mbscat_s
+_mbscat_s_l
+_mbschr
+_mbschr_l
+_mbscmp
+_mbscmp_l
+_mbscoll
+_mbscoll_l
+_mbscpy
+_mbscpy_s
+_mbscpy_s_l
+_mbscspn
+_mbscspn_l
+_mbsdec
+_mbsdec_l
+_mbsdup
+_mbsicmp
+_mbsicmp_l
+_mbsicoll
+_mbsicoll_l
+_mbsinc
+_mbsinc_l
+_mbslen
+_mbslen_l
+_mbslwr
+_mbslwr_l
+_mbslwr_s
+_mbslwr_s_l
+_mbsnbcat
+_mbsnbcat_l
+_mbsnbcat_s
+_mbsnbcat_s_l
+_mbsnbcmp
+_mbsnbcmp_l
+_mbsnbcnt
+_mbsnbcnt_l
+_mbsnbcoll
+_mbsnbcoll_l
+_mbsnbcpy
+_mbsnbcpy_l
+_mbsnbcpy_s
+_mbsnbcpy_s_l
+_mbsnbicmp
+_mbsnbicmp_l
+_mbsnbicoll
+_mbsnbicoll_l
+_mbsnbset
+_mbsnbset_l
+_mbsnbset_s
+_mbsnbset_s_l
+_mbsncat
+_mbsncat_l
+_mbsncat_s
+_mbsncat_s_l
+_mbsnccnt
+_mbsnccnt_l
+_mbsncmp
+_mbsncmp_l
+_mbsncoll
+_mbsncoll_l
+_mbsncpy
+_mbsncpy_l
+_mbsncpy_s
+_mbsncpy_s_l
+_mbsnextc
+_mbsnextc_l
+_mbsnicmp
+_mbsnicmp_l
+_mbsnicoll
+_mbsnicoll_l
+_mbsninc
+_mbsninc_l
+_mbsnlen
+_mbsnlen_l
+_mbsnset
+_mbsnset_l
+_mbsnset_s
+_mbsnset_s_l
+_mbspbrk
+_mbspbrk_l
+_mbsrchr
+_mbsrchr_l
+_mbsrev
+_mbsrev_l
+_mbsset
+_mbsset_l
+_mbsset_s
+_mbsset_s_l
+_mbsspn
+_mbsspn_l
+_mbsspnp
+_mbsspnp_l
+_mbsstr
+_mbsstr_l
+_mbstok
+_mbstok_l
+_mbstok_s
+_mbstok_s_l
+_mbstowcs_l
+_mbstowcs_s_l
+_mbstrlen
+_mbstrlen_l
+_mbstrnlen
+_mbstrnlen_l
+_mbsupr
+_mbsupr_l
+_mbsupr_s
+_mbsupr_s_l
+_mbtowc_l
+_memccpy
+F_ARM_ANY(_memcpy_strict_align)
+_memicmp
+_memicmp_l
+_mkdir
+_mkgmtime
+F_I386(_mkgmtime32)
+F_ARM_ANY(_mkgmtime32)
+F_NON_I386(_mkgmtime64)
+_mktemp
+; _mktemp_s replaced by emu
+F_I386(_mktime32 == mktime)
+F_ARM_ANY(_mktime32)
+_mktime64
+_msize
+F_ARM_ANY(_msize_dbg)
+_nextafter
+F_X64(_nextafterf)
+_onexit
+_open
+_open_osfhandle
+_osplatform DATA
+_osver DATA
+F_I386(_outp)
+F_I386(_outpd)
+F_I386(_outpw)
+_pclose
+_pctype DATA
+_pgmptr DATA
+_pipe
+_popen
+_printf_l
+_printf_p
+_printf_p_l
+_printf_s_l
+_purecall
+_putch
+_putenv
+_putenv_s
+_putw
+_putwch
+_putws
+_pwctype DATA
+_read
+F_ARM_ANY(_realloc_dbg)
+_resetstkoflw
+_rmdir
+_rmtmp
+_rotl
+F_NON_I386(_rotl64)
+_rotr
+F_NON_I386(_rotr64)
+#ifdef DEF_I386
+_safe_fdiv
+_safe_fdivr
+_safe_fprem
+_safe_fprem1
+#endif
+_scalb
+F_X64(_scalbf)
+_scanf_l
+_scanf_s_l
+_scprintf
+_scprintf_l
+_scprintf_p_l
+_scwprintf
+_scwprintf_l
+_scwprintf_p_l
+_searchenv
+_searchenv_s
+F_I386(_seh_longjmp_unwind)
+F_ARM_ANY(_set_controlfp)
+F_ARM_ANY(_set_doserrno)
+F_ARM_ANY(_set_errno)
+_set_error_mode
+F_ARM_ANY(_set_fileinfo)
+F_ARM_ANY(_set_fmode)
+; Does not seem to present even on Win7 msvcrt
+;_set_purecall_handler
+_set_sbh_threshold
+; _set_output_format provided by emu
+F_I386(_set_SSE2_enable)
+F_I386(_set_security_error_handler)
+_seterrormode
+_setjmp
+F_I386(_setjmp3)
+F_NON_I386(_setjmpex)
+_setmaxstdio
+_setmbcp
+_setmode
+_setsystime
+_sleep
+_snprintf
+_snprintf_c
+_snprintf_c_l
+_snprintf_l
+_snprintf_s
+_snprintf_s_l
+_snscanf
+_snscanf_l
+_snscanf_s
+_snscanf_s_l
+_snwprintf
+snwprintf == _snwprintf
+_snwprintf_l
+_snwprintf_s
+_snwprintf_s_l
+_snwscanf
+_snwscanf_l
+_snwscanf_s
+_snwscanf_s_l
+_sopen
+; _sopen_s replaced by emu
+_spawnl
+_spawnle
+_spawnlp
+_spawnlpe
+_spawnv
+_spawnve
+_spawnvp
+_spawnvpe
+_splitpath
+_splitpath_s
+_sprintf_l
+_sprintf_p_l
+_sprintf_s_l
+_sscanf_l
+_sscanf_s_l
+_stat
+_stat64
+_stati64
+F32(_stat32 == _stat)
+F64(_stat64i32 == _stat)
+_statusfp
+_strcmpi
+_strcoll_l
+_strdate
+; _strdate_s replaced by emu
+_strdup
+F_ARM_ANY(_strdup_dbg)
+_strerror
+_strerror_s
+_stricmp
+_stricmp_l
+_stricoll
+_stricoll_l
+_strlwr
+_strlwr_l
+_strlwr_s
+_strlwr_s_l
+_strncoll
+_strncoll_l
+_strnicmp
+_strnicmp_l
+_strnicoll
+_strnicoll_l
+_strnset
+_strnset_s
+_strrev
+_strset
+_strset_s
+_strtime
+; _strtime_s replaced by emu
+_strtod_l
+_strtoi64
+_strtoi64_l
+_strtol_l
+_strtoui64
+_strtoui64_l
+_strtoul_l
+_strupr
+_strupr_l
+_strupr_s
+_strupr_s_l
+_strxfrm_l
+_swab
+_swprintf == swprintf
+F_NON_I386(_swprintf_c)
+_swprintf_c_l
+_swprintf_p_l
+_swprintf_s_l
+_swscanf_l
+_swscanf_s_l
+_sys_errlist DATA
+_sys_nerr DATA
+_tell
+_telli64
+_tempnam
+F_ARM_ANY(_tempnam_dbg)
+F_I386(_time32 == time)
+F_ARM_ANY(_time32)
+_time64
+_tolower
+_tolower_l
+_toupper
+_toupper_l
+_towlower_l
+_towupper_l
+_tzset
+_ui64toa
+_ui64toa_s
+_ui64tow
+_ui64tow_s
+_ultoa
+_ultoa_s
+_ultow
+_ultow_s
+_umask
+; _umask_s replaced by emu
+_ungetch
+_ungetwch
+_unlink
+_unloaddll
+_unlock
+_utime
+F_ARM_ANY(_utime32)
+_utime64
+_vcprintf
+_vcprintf_l
+_vcprintf_p
+_vcprintf_p_l
+; _vcprintf_s Replaced by emu
+; _vcprintf_s_l Likewise.
+_vcwprintf
+_vcwprintf_l
+_vcwprintf_p
+_vcwprintf_p_l
+; _vcwprintf_s Replaced by emu
+; _vcwprintf_s_l Likewise.
+_vfprintf_l
+_vfprintf_p
+_vfprintf_p_l
+_vfprintf_s_l
+_vfwprintf_l
+_vfwprintf_p
+_vfwprintf_p_l
+_vfwprintf_s_l
+_vprintf_l
+_vprintf_p
+_vprintf_p_l
+_vprintf_s_l
+_vscprintf
+_vscprintf_l
+_vscprintf_p_l
+_vscwprintf
+_vscwprintf_l
+_vscwprintf_p_l
+_vsnprintf
+_vsnprintf_c
+_vsnprintf_c_l
+_vsnprintf_l
+_vsnprintf_s
+_vsnprintf_s_l
+_vsnwprintf
+vsnwprintf == _vsnwprintf
+_vsnwprintf_l
+_vsnwprintf_s
+_vsnwprintf_s_l
+_vsprintf_l
+_vsprintf_p
+_vsprintf_p_l
+_vsprintf_s_l
+_vswprintf F_I386(== vswprintf)
+_vswprintf_c
+_vswprintf_c_l
+_vswprintf_l
+_vswprintf_p_l
+_vswprintf_s_l
+_vwprintf_l
+_vwprintf_p
+_vwprintf_p_l
+_vwprintf_s_l
+_waccess
+; _waccess_s Replaced by emu
+_wasctime
+; _wasctime_s Replaced by emu
+F_ARM_ANY(_wassert)
+_wchdir
+_wchmod
+_wcmdln DATA
+_wcreat
+_wcscoll_l
+_wcsdup
+F_ARM_ANY(_wcsdup_dbg)
+_wcserror
+_wcserror_s
+_wcsftime_l
+_wcsicmp
+_wcsicmp_l
+_wcsicoll
+_wcsicoll_l
+_wcslwr
+_wcslwr_l
+_wcslwr_s
+_wcslwr_s_l
+_wcsncoll
+_wcsncoll_l
+_wcsnicmp
+_wcsnicmp_l
+_wcsnicoll
+_wcsnicoll_l
+_wcsnset
+_wcsnset_s
+_wcsrev
+_wcsset
+_wcsset_s
+F_ARM_ANY(_wcstod_l)
+_wcstoi64
+_wcstoi64_l
+_wcstol_l
+_wcstombs_l
+_wcstombs_s_l
+_wcstoui64
+_wcstoui64_l
+_wcstoul_l
+_wcsupr
+_wcsupr_l
+_wcsupr_s
+_wcsupr_s_l
+_wcsxfrm_l
+_wctime
+F_I386(_wctime32 == _wctime)
+F_ARM_ANY(_wctime32)
+; _wctime32_s replaced by emu
+_wctime64
+; _wctime64_s replaced by emu
+_wctomb_l
+_wctomb_s_l
+_wctype
+F_X86_ANY(_wenviron DATA)
+_wexecl
+_wexecle
+_wexeclp
+_wexeclpe
+_wexecv
+_wexecve
+_wexecvp
+_wexecvpe
+_wfdopen
+_wfindfirst
+F32(_wfindfirst32 == _wfindfirst)
+_wfindfirst64
+_wfindfirsti64
+F32(_wfindfirst32i64 == _wfindfirsti64)
+F64(_wfindfirst64i32 == _wfindfirst)
+_wfindnext
+F32(_wfindnext32 == _wfindnext)
+_wfindnext64
+_wfindnexti64
+F32(_wfindnext32i64 == _wfindnexti64)
+F64(_wfindnext64i32 == _wfindnext)
+_wfopen
+_wfopen_s
+_wfreopen
+_wfreopen_s
+_wfsopen
+_wfullpath
+F_ARM_ANY(_wfullpath_dbg)
+_wgetcwd
+_wgetdcwd
+_wgetenv
+_wgetenv_s
+_winmajor DATA
+_winminor DATA
+_winput_s
+_winver DATA
+_wmakepath
+_wmakepath_s
+_wmkdir
+_wmktemp
+; _wmktemp_s replaced by emu
+_wopen
+_woutput_s
+_wperror
+_wpgmptr DATA
+_wpopen
+_wprintf_l
+_wprintf_p
+_wprintf_p_l
+_wprintf_s_l
+_wputenv
+_wputenv_s
+_wremove
+_wrename
+_write
+_wrmdir
+_wscanf_l
+_wscanf_s_l
+_wsearchenv
+_wsearchenv_s
+_wsetlocale
+_wsopen
+_wsopen_s
+_wspawnl
+_wspawnle
+_wspawnlp
+_wspawnlpe
+_wspawnv
+_wspawnve
+_wspawnvp
+_wspawnvpe
+_wsplitpath
+_wsplitpath_s
+_wstat
+_wstat64
+_wstati64
+F32(_wstat32 == _wstat)
+F64(_wstat64i32 == _wstat)
+_wstrdate
+; _wstrdate_s replaced by emu
+_wstrtime
+; _wstrtime_s replaced by emu
+_wsystem
+_wtempnam
+F_ARM_ANY(_wtempnam_dbg)
+_wtmpnam
+_wtmpnam_s
+_wtof
+_wtof_l
+_wtoi
+_wtoi64
+_wtoi64_l
+_wtoi_l
+_wtol
+_wtol_l
+_wunlink
+_wutime
+F_ARM_ANY(_wutime32)
+_wutime64
+_y0
+_y1
+_yn
+abort
+abs
+acos
+F_NON_I386(acosf F_X86_ANY(DATA))
+asctime
+; asctime_s replaced by emu
+asin
+F_NON_I386(asinf F_X86_ANY(DATA))
+atan
+atan2 F_X86_ANY(DATA)
+F_NON_I386(atan2f F_X86_ANY(DATA))
+F_NON_I386(atanf F_X86_ANY(DATA))
+atexit DATA
+atof
+atoi
+atol
+bsearch
+bsearch_s
+F_ARM_ANY(btowc)
+calloc
+ceil DATA
+F_NON_I386(ceilf DATA)
+clearerr
+clearerr_s
+clock
+cos F_X86_ANY(DATA)
+F_NON_I386(cosf F_X86_ANY(DATA))
+cosh
+F_NON_I386(coshf DATA)
+ctime
+difftime
+div
+exit
+exp F_X86_ANY(DATA)
+F_NON_I386(expf F_X86_ANY(DATA))
+fabs DATA
+F_ARM_ANY(fabsf)
+fclose
+feof
+ferror
+fflush
+fgetc
+fgetpos
+fgets
+fgetwc
+fgetws
+floor DATA
+F_NON_I386(floorf DATA)
+fmod F_X86_ANY(DATA)
+F_NON_I386(fmodf F_X86_ANY(DATA))
+fopen
+fopen_s
+fprintf
+fprintf_s
+fputc
+fputs
+fputwc
+fputws
+fread
+free
+freopen
+freopen_s
+; If we implement frexp, we can set it to DATA only.
+frexp
+fscanf
+fscanf_s
+fseek
+fsetpos
+ftell
+fwprintf
+__ms_fwprintf == fwprintf
+fwprintf_s
+fwrite
+fwscanf
+fwscanf_s
+getc
+getchar
+getenv
+getenv_s
+gets
+getwc
+getwchar
+gmtime
+is_wctype
+isalnum
+isalpha
+iscntrl
+isdigit
+isgraph
+isleadbyte
+islower
+isprint
+ispunct
+isspace
+isupper
+iswalnum
+iswalpha
+iswascii
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
+isxdigit
+labs
+ldexp F_X86_ANY(DATA)
+ldiv
+localeconv
+localtime
+log F_X86_ANY(DATA)
+log10
+F_NON_I386(log10f F_X86_ANY(DATA))
+F_NON_I386(logf F_X86_ANY(DATA))
+F_ARM_ANY(longjmp)
+malloc
+mblen
+F_ARM_ANY(mbrlen)
+F_ARM_ANY(mbrtowc)
+F_ARM_ANY(mbsdup_dbg)
+F_ARM_ANY(mbsrtowcs)
+mbsrtowcs_s
+mbstowcs
+mbstowcs_s
+mbtowc
+memchr
+memcmp
+memcpy
+; memcpy_s replaced by emu
+memmove
+; memmove_s replaced by emu
+memset
+mktime
+modf DATA
+F_NON_I386(modff DATA)
+perror
+pow F_X86_ANY(DATA)
+F_NON_I386(powf F_X86_ANY(DATA))
+printf
+printf_s
+putc
+putchar
+puts
+putwc
+putwchar
+qsort
+qsort_s
+raise
+rand
+; rand_s replaced by emu
+realloc
+remove
+rename
+rewind
+scanf
+scanf_s
+setbuf
+F_NON_I386(setjmp)
+setlocale
+setvbuf
+signal
+sin F_X86_ANY(DATA)
+F_NON_I386(sinf F_X86_ANY(DATA))
+; if we implement sinh, we can set it DATA only.
+sinh
+F_NON_I386(sinhf DATA)
+sprintf
+; sprintf_s replaced by emu
+sqrt DATA
+F_NON_I386(sqrtf DATA)
+srand
+sscanf
+sscanf_s
+strcat
+strcat_s
+strchr
+strcmp
+strcoll
+strcpy
+strcpy_s
+strcspn
+strerror
+; strerror_s replaced by emu
+strftime
+strlen
+strncat
+strncat_s
+strncmp
+strncpy
+strncpy_s
+; strnlen replaced by emu
+strpbrk
+strrchr
+strspn
+strstr
+strtod
+strtok
+strtok_s
+strtol
+strtoul
+strxfrm
+swprintf
+swprintf_s
+swscanf
+swscanf_s
+system
+tan
+F_NON_I386(tanf F_X86_ANY(DATA))
+; if we implement tanh, we can set it to DATA only.
+tanh
+F_ARM_ANY(tanhf)
+time F_NON_I386(== _time64)
+tmpfile
+tmpfile_s
+tmpnam
+tmpnam_s
+tolower
+toupper
+towlower
+towupper
+ungetc
+ungetwc
+F_ARM_ANY(utime)
+vfprintf
+vfprintf_s
+vfwprintf
+vfwprintf_s
+vprintf
+vprintf_s
+vsnprintf == _vsnprintf
+snprintf == _snprintf
+vsprintf
+; vsprintf_s replaced by emu
+vswprintf
+vswprintf_s
+vwprintf
+vwprintf_s
+F_ARM_ANY(wcrtomb)
+wcrtomb_s
+wcscat
+wcscat_s
+wcschr
+wcscmp
+wcscoll
+wcscpy
+wcscpy_s
+wcscspn
+wcsftime
+wcslen
+wcsncat
+wcsncat_s
+wcsncmp
+wcsncpy
+wcsncpy_s
+; We provide replacement implementation in libmingwex
+wcsnlen DATA
+wcspbrk
+wcsrchr
+F_ARM_ANY(wcsrtombs)
+wcsrtombs_s
+wcsspn
+wcsstr
+wcstod
+wcstok
+wcstok_s
+wcstol
+wcstombs
+wcstombs_s
+wcstoul
+wcsxfrm
+F_ARM_ANY(wctob)
+wctomb
+wctomb_s
+wprintf
+wprintf_s
+wscanf
+wscanf_s
src/codegen.cpp
@@ -9698,10 +9698,14 @@ void codegen_build_and_link(CodeGen *g) {
         }
     }
 
+    codegen_release_caches(g);
+    codegen_add_time_event(g, "Done");
+}
+
+void codegen_release_caches(CodeGen *g) {
     while (g->caches_to_release.length != 0) {
         cache_release(g->caches_to_release.pop());
     }
-    codegen_add_time_event(g, "Done");
 }
 
 ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path,
src/codegen.hpp
@@ -61,4 +61,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g);
 
 TargetSubsystem detect_subsystem(CodeGen *g);
 
+void codegen_release_caches(CodeGen *codegen);
+
 #endif
src/link.cpp
@@ -573,17 +573,18 @@ static const char *build_musl(CodeGen *parent) {
 
 static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
     if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {
-        if (strcmp(file, "crt2u.obj") == 0) {
+        if (strcmp(file, "crt2.obj") == 0) {
             CFile *c_file = allocate<CFile>(1);
             c_file->source_path = buf_ptr(buf_sprintf(
                 "%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "crt" OS_SEP "crtexe.c", buf_ptr(parent->zig_lib_dir)));
             mingw_add_cc_args(parent, c_file);
             c_file->args.append("-U__CRTDLL__");
             c_file->args.append("-D__MSVCRT__");
-            c_file->args.append("-DUNICODE");
-            c_file->args.append("-D_UNICODE");
-            c_file->args.append("-DWPRFLAG=1");
-            return build_libc_object(parent, "crt2u", c_file);
+            // Uncomment these 3 things for crtu
+            //c_file->args.append("-DUNICODE");
+            //c_file->args.append("-D_UNICODE");
+            //c_file->args.append("-DWPRFLAG=1");
+            return build_libc_object(parent, "crt2", c_file);
         } else if (strcmp(file, "dllcrt2.obj") == 0) {
             CFile *c_file = allocate<CFile>(1);
             c_file->source_path = buf_ptr(buf_sprintf(
@@ -592,6 +593,64 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
             c_file->args.append("-U__CRTDLL__");
             c_file->args.append("-D__MSVCRT__");
             return build_libc_object(parent, "dllcrt2", c_file);
+        } else if (strcmp(file, "mingw32.lib") == 0) {
+            CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
+            codegen_set_out_name(child_gen, buf_create_from_str("mingw32"));
+
+            static const char *deps[] = {
+                "mingw" OS_SEP "crt" OS_SEP "crt0_c.c",
+                "mingw" OS_SEP "crt" OS_SEP "dll_argv.c",
+                "mingw" OS_SEP "crt" OS_SEP "gccmain.c",
+                "mingw" OS_SEP "crt" OS_SEP "natstart.c",
+                "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc-list.c",
+                "mingw" OS_SEP "crt" OS_SEP "wildcard.c",
+                "mingw" OS_SEP "crt" OS_SEP "charmax.c",
+                "mingw" OS_SEP "crt" OS_SEP "crt0_w.c",
+                "mingw" OS_SEP "crt" OS_SEP "dllargv.c",
+                "mingw" OS_SEP "crt" OS_SEP "gs_support.c",
+                "mingw" OS_SEP "crt" OS_SEP "_newmode.c",
+                "mingw" OS_SEP "crt" OS_SEP "tlssup.c",
+                "mingw" OS_SEP "crt" OS_SEP "xncommod.c",
+                "mingw" OS_SEP "crt" OS_SEP "cinitexe.c",
+                "mingw" OS_SEP "crt" OS_SEP "merr.c",
+                "mingw" OS_SEP "crt" OS_SEP "pesect.c",
+                "mingw" OS_SEP "crt" OS_SEP "udllargc.c",
+                "mingw" OS_SEP "crt" OS_SEP "xthdloc.c",
+                "mingw" OS_SEP "crt" OS_SEP "CRT_fp10.c",
+                "mingw" OS_SEP "crt" OS_SEP "mingw_helpers.c",
+                "mingw" OS_SEP "crt" OS_SEP "pseudo-reloc.c",
+                "mingw" OS_SEP "crt" OS_SEP "udll_argv.c",
+                "mingw" OS_SEP "crt" OS_SEP "xtxtmode.c",
+                "mingw" OS_SEP "crt" OS_SEP "crt_handler.c",
+                "mingw" OS_SEP "crt" OS_SEP "tlsthrd.c",
+                "mingw" OS_SEP "crt" OS_SEP "tlsmthread.c",
+                "mingw" OS_SEP "crt" OS_SEP "tlsmcrt.c",
+                "mingw" OS_SEP "crt" OS_SEP "cxa_atexit.c",
+            };
+            for (size_t i = 0; i < array_length(deps); i += 1) {
+                CFile *c_file = allocate<CFile>(1);
+                c_file->source_path = path_from_libc(parent, deps[i]);
+                c_file->args.append("-DHAVE_CONFIG_H");
+                c_file->args.append("-D_SYSCRT=1");
+                c_file->args.append("-DCRTDLL=1");
+
+                c_file->args.append("-isystem");
+                c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any"));
+
+                c_file->args.append("-I");
+                c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include" OS_SEP));
+
+                c_file->args.append("-std=gnu99");
+                c_file->args.append("-D_CRTBLD");
+                c_file->args.append("-D_WIN32_WINNT=0x0f00");
+                c_file->args.append("-D__MSVCRT_VERSION__=0x700");
+                c_file->args.append("-g");
+                c_file->args.append("-O2");
+
+                child_gen->c_source_files.append(c_file);
+            }
+            codegen_build_and_link(child_gen);
+            return buf_ptr(&child_gen->output_file_path);
         } else {
             zig_unreachable();
         }
@@ -1154,8 +1213,12 @@ static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
         list->append("-MACHINE:X86");
     } else if (g->zig_target->arch == ZigLLVM_x86_64) {
         list->append("-MACHINE:X64");
-    } else if (g->zig_target->arch == ZigLLVM_arm) {
-        list->append("-MACHINE:ARM");
+    } else if (target_is_arm(g->zig_target)) {
+        if (target_arch_pointer_bit_width(g->zig_target->arch) == 32) {
+            list->append("-MACHINE:ARM");
+        } else {
+            list->append("-MACHINE:ARM64");
+        }
     }
 }
 
@@ -1223,9 +1286,150 @@ static const char *get_libc_static_file(ZigLibCInstallation *lib, const char *fi
     return buf_ptr(out_buf);
 }
 
+static void print_zig_cc_cmd(const char *zig_exe, ZigList<const char *> *args) {
+    fprintf(stderr, "%s", zig_exe);
+    for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) {
+        fprintf(stderr, " %s", args->at(arg_i));
+    }
+    fprintf(stderr, "\n");
+}
+
+static const char *get_def_lib(CodeGen *parent, const char *name, const char *def_in_rel_path) {
+    Error err;
+
+    Buf *self_exe_path = buf_alloc();
+    if ((err = os_self_exe_path(self_exe_path))) {
+        fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err));
+        exit(1);
+    }
+    Buf *compiler_id;
+    if ((err = get_compiler_id(&compiler_id))) {
+        fprintf(stderr, "Unable to get compiler id: %s\n", err_str(err));
+        exit(1);
+    }
+
+    Buf *cache_dir = get_stage1_cache_path();
+    Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(cache_dir));
+    Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(cache_dir));
+
+    Buf *def_in_file = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s", buf_ptr(parent->zig_lib_dir), def_in_rel_path);
+    Buf *def_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "def-include",
+            buf_ptr(parent->zig_lib_dir));
+
+    CacheHash *cache_hash = allocate<CacheHash>(1);
+    cache_init(cache_hash, manifest_dir);
+
+    cache_buf(cache_hash, compiler_id);
+    cache_file(cache_hash, def_in_file);
+    cache_buf(cache_hash, def_include_dir);
+    cache_int(cache_hash, parent->zig_target->arch);
+
+    Buf digest = BUF_INIT;
+    buf_resize(&digest, 0);
+    if ((err = cache_hit(cache_hash, &digest))) {
+        if (err != ErrorInvalidFormat) {
+            if (err == ErrorCacheUnavailable) {
+                // already printed error
+            } else {
+                fprintf(stderr, "unable to check cache when processing .def.in file: %s\n", err_str(err));
+            }
+            exit(1);
+        }
+    }
+
+    Buf *artifact_dir;
+    Buf *lib_final_path;
+    Buf *final_lib_basename = buf_sprintf("%s.lib", name);
+
+    bool is_cache_miss = (buf_len(&digest) == 0);
+    if (is_cache_miss) {
+        if ((err = cache_final(cache_hash, &digest))) {
+            fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
+            exit(1);
+        }
+        artifact_dir = buf_alloc();
+        os_path_join(o_dir, &digest, artifact_dir);
+        if ((err = os_make_path(artifact_dir))) {
+            fprintf(stderr, "Unable to create output directory '%s': %s",
+                    buf_ptr(artifact_dir), err_str(err));
+            exit(1);
+        }
+        Buf *final_def_basename = buf_sprintf("%s.def", name);
+        Buf *def_final_path = buf_alloc();
+        os_path_join(artifact_dir, final_def_basename, def_final_path);
+
+        ZigList<const char *> args = {};
+        args.append(buf_ptr(self_exe_path));
+        args.append("cc");
+        args.append("-x");
+        args.append("c");
+        args.append(buf_ptr(def_in_file));
+        args.append("-Wp,-w");
+        args.append("-undef");
+        args.append("-P");
+        args.append("-I");
+        args.append(buf_ptr(def_include_dir));
+        if (target_is_arm(parent->zig_target)) {
+            if (target_arch_pointer_bit_width(parent->zig_target->arch) == 32) {
+                args.append("-DDEF_ARM32");
+            } else {
+                args.append("-DDEF_ARM64");
+            }
+        } else if (parent->zig_target->arch == ZigLLVM_x86) {
+            args.append("-DDEF_I386");
+        } else if (parent->zig_target->arch == ZigLLVM_x86_64) {
+            args.append("-DDEF_X64");
+        } else {
+            zig_unreachable();
+        }
+        args.append("-E");
+        args.append("-o");
+        args.append(buf_ptr(def_final_path));
+
+        if (parent->verbose_cc) {
+            print_zig_cc_cmd("zig", &args);
+        }
+        Termination term;
+        os_spawn_process(args, &term);
+        if (term.how != TerminationIdClean || term.code != 0) {
+            fprintf(stderr, "\nThe following command failed:\n");
+            print_zig_cc_cmd(buf_ptr(self_exe_path), &args);
+            exit(1);
+        }
+
+        lib_final_path = buf_alloc();
+        os_path_join(artifact_dir, final_lib_basename, lib_final_path);
+
+        args.resize(0);
+        args.append("link");
+        coff_append_machine_arg(parent, &args);
+
+        args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_final_path))));
+        args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(lib_final_path))));
+
+        Buf diag = BUF_INIT;
+        ZigLLVM_ObjectFormatType target_ofmt = target_object_format(parent->zig_target);
+        if (!zig_lld_link(target_ofmt, args.items, args.length, &diag)) {
+            fprintf(stderr, "%s\n", buf_ptr(&diag));
+            exit(1);
+        }
+    } else {
+        // cache hit
+        artifact_dir = buf_alloc();
+        os_path_join(o_dir, &digest, artifact_dir);
+        lib_final_path = buf_alloc();
+        os_path_join(artifact_dir, final_lib_basename, lib_final_path);
+    }
+    parent->caches_to_release.append(cache_hash);
+
+    return buf_ptr(lib_final_path);
+}
+
 static void add_mingw_link_args(LinkJob *lj, bool is_library) {
     CodeGen *g = lj->codegen;
 
+    lj->args.append("-lldmingw");
+
     bool is_dll = g->out_type == OutTypeLib && g->is_dynamic;
 
     if (g->zig_target->arch == ZigLLVM_x86) {
@@ -1238,8 +1442,11 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {
         if (is_dll) {
             lj->args.append(get_libc_crt_file(g, "dllcrt2.obj"));
         } else {
-            lj->args.append(get_libc_crt_file(g, "crt2u.obj"));
+            lj->args.append(get_libc_crt_file(g, "crt2.obj"));
         }
+
+        lj->args.append(get_libc_crt_file(g, "mingw32.lib"));
+        lj->args.append(get_def_lib(g, "msvcrt", "mingw" OS_SEP "lib-common" OS_SEP "msvcrt.def.in"));
     } else {
         if (is_dll) {
             lj->args.append(get_libc_file(g->libc, "dllcrt2.o"));
@@ -1388,7 +1595,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
     }
 
     if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
-        if (!g->is_dummy_so) {
+        if (g->libc_link_lib == nullptr && !g->is_dummy_so) {
             Buf *libc_a_path = build_c(g, OutTypeLib);
             lj->args.append(buf_ptr(libc_a_path));
         }
@@ -1762,10 +1969,12 @@ void codegen_link(CodeGen *g) {
         }
         os_spawn_process(args, &term);
         if (term.how != TerminationIdClean || term.code != 0) {
+            codegen_release_caches(g);
             exit(1);
         }
     } else if (!zig_lld_link(target_object_format(g->zig_target), lj.args.items, lj.args.length, &diag)) {
         fprintf(stderr, "%s\n", buf_ptr(&diag));
+        codegen_release_caches(g);
         exit(1);
     }
 }
CMakeLists.txt
@@ -7583,11 +7583,45 @@ set(ZIG_LIBC_FILES
     "include/x86_64-linux-musl/bits/user.h"
     "include/wasm32-freestanding-musl/bits/alltypes.h"
     "include/wasm32-freestanding-musl/errno.h"
+    "mingw/crt/CRT_fp10.c"
+    "mingw/crt/_newmode.c"
+    "mingw/crt/charmax.c"
+    "mingw/crt/cinitexe.c"
+    "mingw/crt/crt0_c.c"
+    "mingw/crt/crt0_w.c"
+    "mingw/crt/crt_handler.c"
     "mingw/crt/crtdll.c"
     "mingw/crt/crtexe.c"
+    "mingw/crt/cxa_atexit.c"
+    "mingw/crt/dll_argv.c"
+    "mingw/crt/dllargv.c"
+    "mingw/crt/gccmain.c"
+    "mingw/crt/gs_support.c"
+    "mingw/crt/merr.c"
+    "mingw/crt/mingw_helpers.c"
+    "mingw/crt/natstart.c"
+    "mingw/crt/pesect.c"
+    "mingw/crt/pseudo-reloc-list.c"
+    "mingw/crt/pseudo-reloc.c"
+    "mingw/crt/tlsmcrt.c"
+    "mingw/crt/tlsmthread.c"
+    "mingw/crt/tlssup.c"
+    "mingw/crt/tlsthrd.c"
+    "mingw/crt/udll_argv.c"
+    "mingw/crt/udllargc.c"
+    "mingw/crt/wildcard.c"
+    "mingw/crt/xncommod.c"
+    "mingw/crt/xthdloc.c"
+    "mingw/crt/xtxtmode.c"
+    "mingw/def-include/.func.def.in.swp"
+    "mingw/def-include/.msvcrt-common.def.in.swp"
+    "mingw/def-include/func.def.in"
+    "mingw/def-include/msvcrt-common.def.in"
+    "mingw/include/config.h"
     "mingw/include/internal.h"
     "mingw/include/oscalls.h"
     "mingw/include/sect_attribs.h"
+    "mingw/lib-common/msvcrt.def.in"
     "musl/arch/aarch64/atomic_arch.h"
     "musl/arch/aarch64/bits/alltypes.h.in"
     "musl/arch/aarch64/bits/endian.h"