X-Git-Url: https://pd.if.org/git/?p=pdclib;a=blobdiff_plain;f=platform%2Fwin32%2Fcrt0.c;h=471e42c094fb199b39549dcc3911e4e649537e17;hp=fcdee084eec3362453825028447a6443d564e463;hb=da0f3f353d417fed71f358a48d5d5394145e460d;hpb=d8928b5f31bbdac23f9ec296ef28b4b10efa31d5 diff --git a/platform/win32/crt0.c b/platform/win32/crt0.c index fcdee08..471e42c 100644 --- a/platform/win32/crt0.c +++ b/platform/win32/crt0.c @@ -1,7 +1,13 @@ -#include #include #include #include +#include +#include +#include // Watcom bug: winnt.h assumes string.h defines wchar_t +#include +#include "_PDCLIB_io.h" +#include "_PDCLIB_locale.h" +#include "_PDCLIB_clocale.h" static char ** argvToAnsi( wchar_t ** wargv, int argc ) { @@ -21,6 +27,7 @@ static char ** argvToAnsi( wchar_t ** wargv, int argc ) if(rv != sz) { fputs("Error in C runtime initialization: " "size mismatch during character set conversion", stderr); + abort(); } } return argv; @@ -40,18 +47,96 @@ static void freeArgs( void ) LocalFree( wargv ); } +extern void (*_PDCLIB_sigfpe)( int ); +extern void (*_PDCLIB_sigill)( int ); +extern void (*_PDCLIB_sigsegv)( int ); + +static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; +static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo ) +{ + int sig; + void (*handler)( int ); + + switch( exInfo->ExceptionRecord->ExceptionCode ) { + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_GUARD_PAGE: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_STACK_OVERFLOW: + sig = SIGSEGV; + handler = _PDCLIB_sigsegv; + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + sig = SIGILL; + handler = _PDCLIB_sigill; + break; + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: + sig = SIGFPE; + handler = _PDCLIB_sigfpe; + break; + + default: + return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER; + } + + if(handler == SIG_DFL) { + return EXCEPTION_EXECUTE_HANDLER; + } else if(handler == SIG_IGN) { + return EXCEPTION_CONTINUE_EXECUTION; + } else { + handler( sig ); + return EXCEPTION_CONTINUE_EXECUTION; + } +} + extern int main( int argc, char ** argv, char ** envp ); -_PDCLIB_noreturn void mainCRTStartup( void ) + +void __cdecl mainCRTStartup( void ); + +void __cdecl mainCRTStartup( void ) { - stdin->handle = GetStdHandle(STD_INPUT_HANDLE); - stdout->handle = GetStdHandle(STD_OUTPUT_HANDLE); - stderr->handle = GetStdHandle(STD_ERROR_HANDLE); + stdin->handle.pointer = GetStdHandle(STD_INPUT_HANDLE); + stdout->handle.pointer = GetStdHandle(STD_OUTPUT_HANDLE); + stderr->handle.pointer = GetStdHandle(STD_ERROR_HANDLE); + + oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter ); cl = GetCommandLineW(); wargv = CommandLineToArgvW(cl, &argc); argv = argvToAnsi(wargv, argc); + + _PDCLIB_initclocale( &_PDCLIB_global_locale ); + + if(tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale) + != thrd_success) { + fputs( "Error during C runtime initialization: " + "Unable to allocate locale TLS", stderr ); + exit( EXIT_FAILURE ); + } + + if( mtx_init(&stdin->lock, mtx_recursive) != thrd_success + || mtx_init(&stdout->lock, mtx_recursive) != thrd_success + || mtx_init(&stderr->lock, mtx_recursive) != thrd_success ) { + fputs( "Error during C runtime initialization: " + "Unable to allocate stdio mutex", stderr ); + exit( EXIT_FAILURE ); + } + atexit(freeArgs); int exitStatus = main(argc, argv, NULL); + exit(exitStatus); -} +} \ No newline at end of file