mirror of
https://github.com/frida/tinycc
synced 2025-02-18 00:03:59 +03:00
tccrun: win32: improve exception handler
This commit is contained in:
parent
08083ddb21
commit
d483ab322f
57
tccrun.c
57
tccrun.c
@ -76,6 +76,7 @@ int tcc_relocate(TCCState *s1)
|
|||||||
int tcc_run(TCCState *s1, int argc, char **argv)
|
int tcc_run(TCCState *s1, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int (*prog_main)(int, char **);
|
int (*prog_main)(int, char **);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (tcc_relocate(s1) < 0)
|
if (tcc_relocate(s1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -83,38 +84,30 @@ int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
prog_main = tcc_get_symbol_err(s1, "main");
|
prog_main = tcc_get_symbol_err(s1, "main");
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
#ifdef CONFIG_TCC_BACKTRACE
|
||||||
if (s1->do_debug)
|
if (s1->do_debug) {
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
rt_prog_main = prog_main;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (s1->do_bounds_check) {
|
if (s1->do_bounds_check) {
|
||||||
void (*bound_init)(void);
|
void (*bound_init)(void);
|
||||||
void (*bound_exit)(void);
|
void (*bound_exit)(void);
|
||||||
int ret;
|
|
||||||
/* set error function */
|
/* set error function */
|
||||||
rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
|
rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
|
||||||
rt_prog_main = prog_main;
|
|
||||||
/* XXX: use .init section so that it also work in binary ? */
|
/* XXX: use .init section so that it also work in binary ? */
|
||||||
bound_init = tcc_get_symbol_err(s1, "__bound_init");
|
bound_init = tcc_get_symbol_err(s1, "__bound_init");
|
||||||
bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
|
bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
|
||||||
bound_init();
|
bound_init();
|
||||||
ret = (*prog_main)(argc, argv);
|
ret = (*prog_main)(argc, argv);
|
||||||
bound_exit();
|
bound_exit();
|
||||||
return ret;
|
} else
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
ret = (*prog_main)(argc, argv);
|
||||||
#ifdef TCC_TARGET_PE
|
return ret;
|
||||||
{
|
|
||||||
unsigned char *p = tcc_get_symbol(s1, "tinyc_no_getbp");
|
|
||||||
if (p) *p = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return (*prog_main)(argc, argv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* relocate code. Return -1 on error, required size if ptr is NULL,
|
/* relocate code. Return -1 on error, required size if ptr is NULL,
|
||||||
otherwise copy code into buffer passed by the caller */
|
otherwise copy code into buffer passed by the caller */
|
||||||
static int tcc_relocate_ex(TCCState *s1, void *ptr)
|
static int tcc_relocate_ex(TCCState *s1, void *ptr)
|
||||||
@ -370,9 +363,10 @@ static void rt_error(ucontext_t *uc, const char *fmt, ...)
|
|||||||
uplong pc;
|
uplong pc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
fprintf(stderr, "Runtime error: ");
|
fprintf(stderr, "Runtime error: ");
|
||||||
|
va_start(ap, fmt);
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
for(i=0;i<num_callers;i++) {
|
for(i=0;i<num_callers;i++) {
|
||||||
@ -382,8 +376,6 @@ static void rt_error(ucontext_t *uc, const char *fmt, ...)
|
|||||||
if (pc == (uplong)rt_prog_main && pc)
|
if (pc == (uplong)rt_prog_main && pc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exit(255);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
@ -581,18 +573,27 @@ static int rt_get_caller_pc(unsigned long *paddr,
|
|||||||
|
|
||||||
static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
|
static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
|
||||||
{
|
{
|
||||||
CONTEXT *uc = ex_info->ContextRecord;
|
|
||||||
/*
|
|
||||||
EXCEPTION_RECORD *er = ex_info->ExceptionRecord;
|
EXCEPTION_RECORD *er = ex_info->ExceptionRecord;
|
||||||
printf("CPU exception: code=%08lx addr=%p\n",
|
CONTEXT *uc = ex_info->ContextRecord;
|
||||||
er->ExceptionCode, er->ExceptionAddress);
|
switch (er->ExceptionCode) {
|
||||||
*/
|
case EXCEPTION_ACCESS_VIOLATION:
|
||||||
if (rt_bound_error_msg && *rt_bound_error_msg)
|
if (rt_bound_error_msg && *rt_bound_error_msg)
|
||||||
rt_error(uc, *rt_bound_error_msg);
|
rt_error(uc, *rt_bound_error_msg);
|
||||||
else
|
else
|
||||||
rt_error(uc, "dereferencing invalid pointer");
|
rt_error(uc, "access violation");
|
||||||
exit(255);
|
break;
|
||||||
//return EXCEPTION_CONTINUE_SEARCH;
|
case EXCEPTION_STACK_OVERFLOW:
|
||||||
|
rt_error(uc, "stack overflow");
|
||||||
|
break;
|
||||||
|
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||||
|
rt_error(uc, "division by zero");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rt_error(uc, "exception caught");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
exit(-1);
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a stack backtrace when a CPU exception occurs. */
|
/* Generate a stack backtrace when a CPU exception occurs. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user