Fix SEH and USING: errors on windows nt
parent
4b7bc7ef6d
commit
544c2370cf
|
@ -1,7 +1,8 @@
|
|||
USING: alien alien.c-types arrays assocs combinators continuations
|
||||
destructors io io.backend io.nonblocking io.windows libc
|
||||
kernel math namespaces sequences threads tuples.lib windows
|
||||
windows.errors windows.kernel32 prettyprint ;
|
||||
windows.errors windows.kernel32 prettyprint strings splitting
|
||||
io.files windows.winsock ;
|
||||
IN: io.windows.nt.backend
|
||||
|
||||
: unicode-prefix ( -- seq )
|
||||
|
|
|
@ -23,40 +23,53 @@ DEFINE_PRIMITIVE(cd)
|
|||
SetCurrentDirectory(unbox_u16_string());
|
||||
}
|
||||
|
||||
long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch)
|
||||
long exception_handler(PEXCEPTION_POINTERS pe)
|
||||
{
|
||||
CONTEXT *c = (CONTEXT*)ctx;
|
||||
void *esp = NULL;
|
||||
PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
|
||||
CONTEXT *c = (CONTEXT*)pe->ContextRecord;
|
||||
void *signal_callstack_top = NULL;
|
||||
|
||||
if(in_code_heap_p(c->Eip))
|
||||
esp = (void*)c->Esp;
|
||||
printf("ExceptionCode = 0x%08x\n", rec->ExceptionCode);
|
||||
printf("AccessViolationCode = 0x%08x\n", EXCEPTION_ACCESS_VIOLATION);
|
||||
printf("DivideByZeroCode1 = 0x%08x\n", EXCEPTION_FLT_DIVIDE_BY_ZERO);
|
||||
printf("DivideByZeroCode2 = 0x%08x\n", EXCEPTION_INT_DIVIDE_BY_ZERO);
|
||||
printf("addr=0x%08x\n", rec->ExceptionInformation[1]);
|
||||
printf("eax=0x%08x\n", c->Eax);
|
||||
printf("eax=0x%08x\n", c->Ebx);
|
||||
printf("eip=0x%08x\n", c->Eip);
|
||||
printf("esp=0x%08x\n", c->Esp);
|
||||
signal_callstack_top = (void*)c->Esp;
|
||||
|
||||
printf("calculated esp: 0x%08x\n", esp);
|
||||
|
||||
if(rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
memory_protection_error(rec->ExceptionInformation[1], esp);
|
||||
else if(rec->ExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO
|
||||
|| rec->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
|
||||
general_error(ERROR_DIVIDE_BY_ZERO,F,F,esp);
|
||||
if(e->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
signal_fault_addr = e->ExceptionInformation[1];
|
||||
c->Eip = (CELL)memory_signal_handler_impl;
|
||||
}
|
||||
else if(e->ExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO
|
||||
|| e->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
|
||||
{
|
||||
signal_number = ERROR_DIVIDE_BY_ZERO;
|
||||
c->Eip = (CELL)divide_by_zero_signal_handler_impl;
|
||||
}
|
||||
else
|
||||
signal_error(11,esp);
|
||||
return -1; /* unreachable */
|
||||
{
|
||||
signal_number = 11;
|
||||
c->Eip = (CELL)misc_signal_handler_impl;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
void c_to_factor_toplevel(CELL quot)
|
||||
{
|
||||
exception_record_t record;
|
||||
asm volatile("mov %%fs:0, %0" : "=r" (record.next_handler));
|
||||
asm volatile("mov %0, %%fs:0" : : "r" (&record));
|
||||
record.handler_func = exception_handler;
|
||||
AddVectoredExceptionHandler(0, (void*)exception_handler);
|
||||
c_to_factor(quot);
|
||||
asm volatile("mov %0, %%fs:0" : "=r" (record.next_handler));
|
||||
RemoveVectoredExceptionHandler((void*)exception_handler);
|
||||
}
|
||||
|
||||
void memory_signal_handler_impl(void)
|
||||
{
|
||||
memory_protection_error(signal_fault_addr,signal_callstack_top);
|
||||
}
|
||||
|
||||
void divide_by_zero_signal_handler_impl(void)
|
||||
{
|
||||
general_error(ERROR_DIVIDE_BY_ZERO,F,F,signal_callstack_top);
|
||||
}
|
||||
|
||||
void misc_signal_handler_impl(void)
|
||||
{
|
||||
signal_error(signal_number,signal_callstack_top);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501 // For AddVectoredExceptionHandler
|
||||
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
@ -10,3 +13,11 @@ typedef char F_SYMBOL;
|
|||
#define FACTOR_OS_STRING "windows"
|
||||
#define FACTOR_DLL L"factor-nt.dll"
|
||||
#define FACTOR_DLL_NAME "factor-nt.dll"
|
||||
|
||||
CELL signal_number;
|
||||
CELL signal_fault_addr;
|
||||
void *signal_callstack_top;
|
||||
|
||||
void memory_signal_handler_impl(void);
|
||||
void divide_by_zero_signal_handler_impl(void);
|
||||
void misc_signal_handler_impl(void);
|
||||
|
|
|
@ -52,7 +52,7 @@ void ffi_dlopen (F_DLL *dll, bool error)
|
|||
dll->dll = NULL;
|
||||
if(error)
|
||||
general_error(ERROR_FFI,F,F,
|
||||
tag_object(get_error_message()));
|
||||
(void*)tag_object(get_error_message()));
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -49,20 +49,5 @@ s64 current_millis(void);
|
|||
|
||||
INLINE void reset_stdio(void) {}
|
||||
|
||||
/* SEH support. Proceed with caution. */
|
||||
typedef long exception_handler_t(
|
||||
PEXCEPTION_RECORD rec, void *frame, void *context, void *dispatch);
|
||||
long exception_handler(PEXCEPTION_POINTERS pe);
|
||||
|
||||
typedef struct exception_record
|
||||
{
|
||||
struct exception_record *next_handler;
|
||||
void *handler_func;
|
||||
} exception_record_t;
|
||||
|
||||
long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch);
|
||||
|
||||
DECLARE_PRIMITIVE(open_file);
|
||||
DECLARE_PRIMITIVE(stat);
|
||||
DECLARE_PRIMITIVE(read_dir);
|
||||
DECLARE_PRIMITIVE(cwd);
|
||||
DECLARE_PRIMITIVE(cd);
|
||||
|
|
Loading…
Reference in New Issue