mirror of
https://github.com/frida/tinycc
synced 2024-12-25 22:46:49 +03:00
win32: register SEH in startup code (i386 only)
Needed to handle signal() etc. with msvcrt
This commit is contained in:
parent
036d94112d
commit
9228842fa7
@ -70,11 +70,13 @@
|
|||||||
#define __x86_64 1
|
#define __x86_64 1
|
||||||
#define USE_MINGW_SETJMP_TWO_ARGS
|
#define USE_MINGW_SETJMP_TWO_ARGS
|
||||||
#define mingw_getsp tinyc_getbp
|
#define mingw_getsp tinyc_getbp
|
||||||
|
#define __TRY__
|
||||||
#else
|
#else
|
||||||
#define __stdcall __attribute__((__stdcall__))
|
#define __stdcall __attribute__((__stdcall__))
|
||||||
#define _X86_ 1
|
#define _X86_ 1
|
||||||
#define WIN32 1
|
#define WIN32 1
|
||||||
#define _USE_32BIT_TIME_T
|
#define _USE_32BIT_TIME_T
|
||||||
|
#define __TRY__ void __try__(void**), *_sehrec[6]; __try__(_sehrec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* in stddef.h */
|
/* in stddef.h */
|
||||||
|
@ -75,3 +75,125 @@ t1:
|
|||||||
/* ---------------------------------------------- */
|
/* ---------------------------------------------- */
|
||||||
#endif
|
#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
|
||||||
|
/* ---------------------------------------------- */
|
||||||
|
@ -15,11 +15,11 @@ typedef struct
|
|||||||
} _startupinfo;
|
} _startupinfo;
|
||||||
|
|
||||||
void __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*);
|
void __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*);
|
||||||
|
|
||||||
int main(int argc, char **argv, char **env);
|
int main(int argc, char **argv, char **env);
|
||||||
|
|
||||||
int _start(void)
|
int _start(void)
|
||||||
{
|
{
|
||||||
|
__TRY__
|
||||||
int argc; char **argv; char **env; int ret;
|
int argc; char **argv; char **env; int ret;
|
||||||
_startupinfo start_info = {0};
|
_startupinfo start_info = {0};
|
||||||
|
|
||||||
@ -32,4 +32,3 @@ int _start(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ void _controlfp(unsigned a, unsigned b);
|
|||||||
|
|
||||||
int _winstart(void)
|
int _winstart(void)
|
||||||
{
|
{
|
||||||
|
__TRY__
|
||||||
char *szCmd;
|
char *szCmd;
|
||||||
STARTUPINFO startinfo;
|
STARTUPINFO startinfo;
|
||||||
int fShow;
|
int fShow;
|
||||||
|
Loading…
Reference in New Issue
Block a user