aboutsummaryrefslogtreecommitdiff
path: root/win32/lib
diff options
context:
space:
mode:
authorgrischka <grischka>2010-10-19 13:15:06 +0200
committergrischka <grischka>2010-10-19 13:15:06 +0200
commit9228842fa75190665241bf1d3bb3f8f74d2ffdbb (patch)
tree6845dc58312bc8a51c33749466273b1039ebaaca /win32/lib
parent036d94112d4f0db6eb82b79bbfd0c9ef2328df34 (diff)
downloadtinycc-9228842fa75190665241bf1d3bb3f8f74d2ffdbb.tar.gz
tinycc-9228842fa75190665241bf1d3bb3f8f74d2ffdbb.tar.bz2
win32: register SEH in startup code (i386 only)
Needed to handle signal() etc. with msvcrt
Diffstat (limited to 'win32/lib')
-rw-r--r--win32/lib/chkstk.S122
-rw-r--r--win32/lib/crt1.c3
-rw-r--r--win32/lib/wincrt1.c1
3 files changed, 124 insertions, 2 deletions
diff --git a/win32/lib/chkstk.S b/win32/lib/chkstk.S
index a757b16..5791aaa 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 2e18c2b..3e1d17f 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 212f9d4..0466da9 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;