diff --git a/win32/include/_mingw.h b/win32/include/_mingw.h index 7a1891cd..e8e95614 100644 --- a/win32/include/_mingw.h +++ b/win32/include/_mingw.h @@ -70,11 +70,13 @@ #define __x86_64 1 #define USE_MINGW_SETJMP_TWO_ARGS #define mingw_getsp tinyc_getbp +#define __TRY__ #else #define __stdcall __attribute__((__stdcall__)) #define _X86_ 1 #define WIN32 1 #define _USE_32BIT_TIME_T +#define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec); #endif /* in stddef.h */ diff --git a/win32/lib/chkstk.S b/win32/lib/chkstk.S index a757b161..5791aaa4 100644 --- a/win32/lib/chkstk.S +++ b/win32/lib/chkstk.S @@ -75,3 +75,125 @@ t1: /* ---------------------------------------------- */ #endif /* ---------------------------------------------- */ + + +/* ---------------------------------------------- */ +#ifndef TCC_TARGET_X86_64 +/* ---------------------------------------------- */ + +/* + int _except_handler3( + PEXCEPTION_RECORD exception_record, + PEXCEPTION_REGISTRATION registration, + PCONTEXT context, + PEXCEPTION_REGISTRATION dispatcher + ); + + int __cdecl _XcptFilter( + unsigned long xcptnum, + PEXCEPTION_POINTERS pxcptinfoptrs + ); + + struct _sehrec { + void *esp; // 0 + void *exception_pointers; // 1 + void *prev; // 2 + void *handler; // 3 + void *scopetable; // 4 + int trylevel; // 5 + void *ebp // 6 + }; + + // this is what the assembler code below means: + __try + { + // ... + } + __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation())) + { + exit(GetExceptionCode()); + } +*/ + +.globl _exception_info +_exception_info: + mov 1*4-24(%ebp),%eax + ret + +.globl _exception_code +_exception_code: + call _exception_info + mov (%eax),%eax + mov (%eax),%eax + ret + +seh_filter: + call _exception_info + push %eax + call _exception_code + push %eax + call _XcptFilter + add $ 8,%esp + ret + +seh_except: + mov 0*4-24(%ebp),%esp + call _exception_code + push %eax + call _exit + +// msvcrt wants scopetables aligned and in read-only segment (using .text) +.align 4 +seh_scopetable: + .long -1 + .long seh_filter + .long seh_except + +seh_handler: + jmp _except_handler3 + +.globl __try__ +__try__: + push %ebp + mov 8(%esp),%ebp + +// void *esp; + lea 12(%esp),%eax + mov %eax,0*4(%ebp) + +// void *exception_pointers; + xor %eax,%eax + mov %eax,1*4(%ebp) + +// void *prev; + mov %fs:0,%eax + mov %eax,2*4(%ebp) + +// void *handler; + mov $ seh_handler,%eax + mov %eax,3*4(%ebp) + +// void *scopetable; + mov $ seh_scopetable,%eax + mov %eax,4*4(%ebp) + +// int trylevel; + xor %eax,%eax + mov %eax,5*4(%ebp) + +// register new SEH + lea 2*4(%ebp),%eax + mov %eax,%fs:0 + + pop %ebp + ret + +/* ---------------------------------------------- */ +#else +/* ---------------------------------------------- */ + +/* SEH on x86-64 not implemented */ + +/* ---------------------------------------------- */ +#endif +/* ---------------------------------------------- */ diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c index 2e18c2b6..3e1d17ff 100644 --- a/win32/lib/crt1.c +++ b/win32/lib/crt1.c @@ -15,11 +15,11 @@ typedef struct } _startupinfo; void __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*); - int main(int argc, char **argv, char **env); int _start(void) { + __TRY__ int argc; char **argv; char **env; int ret; _startupinfo start_info = {0}; @@ -32,4 +32,3 @@ int _start(void) } // ============================================= - diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c index 212f9d47..0466da91 100644 --- a/win32/lib/wincrt1.c +++ b/win32/lib/wincrt1.c @@ -10,6 +10,7 @@ void _controlfp(unsigned a, unsigned b); int _winstart(void) { + __TRY__ char *szCmd; STARTUPINFO startinfo; int fShow;