blob: de5a07c27c76d31445135c6a10cff06b420930ab [file]
/**
* 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.
*/
#if defined(__i386__)
#include <stdlib.h>
#include <errno.h>
#include <process.h>
#include <windows.h>
#include "i386_sse_float_exception_handler.h"
#if defined(__i386__)
/* We need to make sure that we align the stack to 16 bytes for the sake of SSE */
__attribute__((force_align_arg_pointer))
#endif
static unsigned __stdcall thread_func(void *data)
{
unsigned ret;
void **thread_args = data;
_beginthreadex_proc_type start_address = thread_args[0];
void *arglist = thread_args[1];
free(thread_args);
EXCEPTION_REGISTRATION_RECORD exception_record = {
.Next = (EXCEPTION_REGISTRATION_RECORD *)__readfsdword(0),
.Handler = (PEXCEPTION_ROUTINE)(INT_PTR)sse_float_exception_handler,
};
__writefsdword(0, (DWORD)&exception_record);
ret = start_address(arglist);
__writefsdword(0, (DWORD)exception_record.Next);
return ret;
}
uintptr_t __cdecl __msvcrt_beginthreadex(void *security, unsigned stack_size, _beginthreadex_proc_type start_address, void *arglist, unsigned initflag, unsigned *thrdaddr);
uintptr_t __cdecl _beginthreadex(void *security, unsigned stack_size, _beginthreadex_proc_type start_address, void *arglist, unsigned initflag, unsigned *thrdaddr)
{
uintptr_t ret;
void **thread_args = malloc(2 * sizeof(void *));
if (!thread_args) {
errno = ENOMEM;
return 0;
}
thread_args[0] = (void *)start_address;
thread_args[1] = arglist;
/* pre-msvcr70 versions of _beginthreadex do not change NULL thrdaddr to dummy stack value */
ret = __msvcrt_beginthreadex(security, stack_size, thread_func, thread_args, initflag, thrdaddr ?: &(unsigned){0});
if (!ret)
free(thread_args);
return ret;
}
uintptr_t (__cdecl *__MINGW_IMP_SYMBOL(_beginthreadex))(void *, unsigned, _beginthreadex_proc_type, void *, unsigned, unsigned *) = _beginthreadex;
#endif