diff options
Diffstat (limited to 'tinyc/win32/lib/chkstk.S')
-rw-r--r-- | tinyc/win32/lib/chkstk.S | 208 |
1 files changed, 185 insertions, 23 deletions
diff --git a/tinyc/win32/lib/chkstk.S b/tinyc/win32/lib/chkstk.S index 837d8af2b..ec5c07ff8 100644 --- a/tinyc/win32/lib/chkstk.S +++ b/tinyc/win32/lib/chkstk.S @@ -1,29 +1,191 @@ -// ================================================= -// chkstk.s +/* ---------------------------------------------- */ +/* chkstk86.s */ + +/* ---------------------------------------------- */ +#ifndef __x86_64__ +/* ---------------------------------------------- */ -.text .globl __chkstk __chkstk: - xchg (%esp), %ebp // store ebp, get ret.addr - push %ebp // push ret.addr - lea 4(%esp), %ebp // setup frame ptr - push %ecx // save ecx - mov %ebp, %ecx + xchg (%esp),%ebp /* store ebp, get ret.addr */ + push %ebp /* push ret.addr */ + lea 4(%esp),%ebp /* setup frame ptr */ + push %ecx /* save ecx */ + mov %ebp,%ecx P0: - sub $4096,%ecx - test %eax,(%ecx) - sub $4096,%eax - cmp $4096,%eax - jge P0 - - sub %eax,%ecx - mov %esp,%eax - test %eax,(%ecx) - mov %ecx,%esp - - mov (%eax),%ecx // restore ecx - mov 4(%eax),%eax - push %eax - ret + sub $4096,%ecx + test %eax,(%ecx) + sub $4096,%eax + cmp $4096,%eax + jge P0 + sub %eax,%ecx + test %eax,(%ecx) + + mov %esp,%eax + mov %ecx,%esp + mov (%eax),%ecx /* restore ecx */ + jmp *4(%eax) + +/* ---------------------------------------------- */ +#else +/* ---------------------------------------------- */ + +.globl __chkstk + +__chkstk: + xchg (%rsp),%rbp /* store ebp, get ret.addr */ + push %rbp /* push ret.addr */ + lea 8(%rsp),%rbp /* setup frame ptr */ + push %rcx /* save ecx */ + mov %rbp,%rcx + movslq %eax,%rax +P0: + sub $4096,%rcx + test %rax,(%rcx) + sub $4096,%rax + cmp $4096,%rax + jge P0 + sub %rax,%rcx + test %rax,(%rcx) + + mov %rsp,%rax + mov %rcx,%rsp + mov (%rax),%rcx /* restore ecx */ + jmp *8(%rax) + +/* ---------------------------------------------- */ +/* setjmp/longjmp support */ + +.globl tinyc_getbp +tinyc_getbp: + mov %rbp,%rax + ret + +/* ---------------------------------------------- */ +#endif +/* ---------------------------------------------- */ + + +/* ---------------------------------------------- */ +#ifndef __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__: +.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 +/* ---------------------------------------------- */ |