5 typedef unsigned char UBYTE;
7 #ifndef UNW_FLAG_EHANDLER
8 const UBYTE UNW_FLAG_EHANDLER = 0x1;
16 UBYTE FrameRegister : 4;
17 UBYTE FrameOffset : 4;
18 ULONG ExceptionHandler;
19 ULONG ExceptionData[1];
23 UNWIND_INFO unwind_info;
24 RUNTIME_FUNCTION func;
28 void factor_vm::c_to_factor_toplevel(cell quot) {
29 // The annoying thing about Win64 SEH is that the offsets in
30 // function tables are 32-bit integers, and the exception handler
31 // itself must reside between the start and end pointers, so
32 // we stick everything at the beginning of the code heap and
33 // generate a small trampoline that jumps to the real
36 seh_data* seh_area = (seh_data*)code->seh_area;
37 cell base = code->seg->start;
39 // Should look at generating this with the Factor assembler
42 seh_area->handler[0] = 0x48;
43 seh_area->handler[1] = 0xb8;
44 seh_area->handler[2] = 0x0;
45 seh_area->handler[3] = 0x0;
46 seh_area->handler[4] = 0x0;
47 seh_area->handler[5] = 0x0;
48 seh_area->handler[6] = 0x0;
49 seh_area->handler[7] = 0x0;
50 seh_area->handler[8] = 0x0;
51 seh_area->handler[9] = 0x0;
54 seh_area->handler[10] = 0x48;
55 seh_area->handler[11] = 0xff;
56 seh_area->handler[12] = 0xe0;
58 // Store address of exception handler in the operand of the 'mov'
59 cell handler = (cell)&factor::exception_handler;
60 memcpy(&seh_area->handler[2], &handler, sizeof(cell));
62 UNWIND_INFO* unwind_info = &seh_area->unwind_info;
63 unwind_info->Version = 1;
64 unwind_info->Flags = UNW_FLAG_EHANDLER;
65 unwind_info->SizeOfProlog = 0;
66 unwind_info->CountOfCodes = 0;
67 unwind_info->FrameRegister = 0;
68 unwind_info->FrameOffset = 0;
69 unwind_info->ExceptionHandler = (DWORD)((cell)&seh_area->handler[0] - base);
70 unwind_info->ExceptionData[0] = 0;
72 RUNTIME_FUNCTION* func = &seh_area->func;
73 func->BeginAddress = 0;
74 func->EndAddress = (DWORD)(code->seg->end - base);
75 func->UnwindData = (DWORD)((cell)&seh_area->unwind_info - base);
77 if (!RtlAddFunctionTable(func, 1, base))
78 fatal_error("RtlAddFunctionTable() failed", 0);
82 if (!RtlDeleteFunctionTable(func))
83 fatal_error("RtlDeleteFunctionTable() failed", 0);