From 544c2370cf4830250bfca7e2a1eed83ae2598598 Mon Sep 17 00:00:00 2001 From: "U-3ADF\\Administrator" Date: Tue, 25 Sep 2007 10:37:45 +0200 Subject: [PATCH] Fix SEH and USING: errors on windows nt --- extra/io/windows/nt/backend/backend.factor | 3 +- vm/os-windows-nt.c | 67 +++++++++++++--------- vm/os-windows-nt.h | 11 ++++ vm/os-windows.c | 2 +- vm/os-windows.h | 17 +----- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/extra/io/windows/nt/backend/backend.factor b/extra/io/windows/nt/backend/backend.factor index 9ec0a63c40..5eac9d6751 100644 --- a/extra/io/windows/nt/backend/backend.factor +++ b/extra/io/windows/nt/backend/backend.factor @@ -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 ) diff --git a/vm/os-windows-nt.c b/vm/os-windows-nt.c index 6f816f4625..cf40745cdd 100644 --- a/vm/os-windows-nt.c +++ b/vm/os-windows-nt.c @@ -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); } diff --git a/vm/os-windows-nt.h b/vm/os-windows-nt.h index 514da31477..4dc87d0f83 100644 --- a/vm/os-windows-nt.h +++ b/vm/os-windows-nt.h @@ -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); diff --git a/vm/os-windows.c b/vm/os-windows.c index 479f60a4fa..1be3e2a2af 100644 --- a/vm/os-windows.c +++ b/vm/os-windows.c @@ -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; } diff --git a/vm/os-windows.h b/vm/os-windows.h index 04f5c87ac7..ed9b87aa93 100644 --- a/vm/os-windows.h +++ b/vm/os-windows.h @@ -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);