| /** |
| * 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 void __cdecl thread_func(void *data) |
| { |
| void **thread_args = data; |
| _beginthread_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); |
| start_address(arglist); |
| __writefsdword(0, (DWORD)exception_record.Next); |
| } |
| |
| uintptr_t __cdecl __msvcrt_beginthread(_beginthread_proc_type start_address, unsigned stack_size, void *arglist); |
| uintptr_t __cdecl _beginthread(_beginthread_proc_type start_address, unsigned stack_size, void *arglist) |
| { |
| 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; |
| ret = __msvcrt_beginthread(thread_func, stack_size, thread_args); |
| if (ret == (uintptr_t)-1) |
| free(thread_args); |
| return ret; |
| } |
| uintptr_t (__cdecl *__MINGW_IMP_SYMBOL(_beginthread))(_beginthread_proc_type, unsigned, void *) = _beginthread; |
| |
| #endif |