Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

86 lines (68 sloc) 2.278 kb
#include "master.hpp"
namespace factor {
typedef unsigned char UBYTE;
const UBYTE UNW_FLAG_EHANDLER = 0x1;
struct UNWIND_INFO {
UBYTE Version:3;
UBYTE Flags:5;
UBYTE SizeOfProlog;
UBYTE CountOfCodes;
UBYTE FrameRegister:4;
UBYTE FrameOffset:4;
ULONG ExceptionHandler;
ULONG ExceptionData[1];
};
struct seh_data {
UNWIND_INFO unwind_info;
RUNTIME_FUNCTION func;
UBYTE handler[32];
};
void factor_vm::c_to_factor_toplevel(cell quot)
{
/* The annoying thing about Win64 SEH is that the offsets in
* function tables are 32-bit integers, and the exception handler
* itself must reside between the start and end pointers, so
* we stick everything at the beginning of the code heap and
* generate a small trampoline that jumps to the real
* exception handler. */
seh_data *seh_area = (seh_data *)code->seh_area;
cell base = code->seg->start;
/* Should look at generating this with the Factor assembler */
/* mov rax,0 */
seh_area->handler[0] = 0x48;
seh_area->handler[1] = 0xb8;
seh_area->handler[2] = 0x0;
seh_area->handler[3] = 0x0;
seh_area->handler[4] = 0x0;
seh_area->handler[5] = 0x0;
seh_area->handler[6] = 0x0;
seh_area->handler[7] = 0x0;
seh_area->handler[8] = 0x0;
seh_area->handler[9] = 0x0;
/* jmp rax */
seh_area->handler[10] = 0x48;
seh_area->handler[11] = 0xff;
seh_area->handler[12] = 0xe0;
/* Store address of exception handler in the operand of the 'mov' */
cell handler = (cell)&factor::exception_handler;
memcpy(&seh_area->handler[2],&handler,sizeof(cell));
UNWIND_INFO *unwind_info = &seh_area->unwind_info;
unwind_info->Version = 1;
unwind_info->Flags = UNW_FLAG_EHANDLER;
unwind_info->SizeOfProlog = 0;
unwind_info->CountOfCodes = 0;
unwind_info->FrameRegister = 0;
unwind_info->FrameOffset = 0;
unwind_info->ExceptionHandler = (DWORD)((cell)&seh_area->handler[0] - base);
unwind_info->ExceptionData[0] = 0;
RUNTIME_FUNCTION *func = &seh_area->func;
func->BeginAddress = 0;
func->EndAddress = (DWORD)(code->seg->end - base);
func->UnwindData = (DWORD)((cell)&seh_area->unwind_info - base);
if(!RtlAddFunctionTable(func,1,base))
fatal_error("RtlAddFunctionTable() failed",0);
c_to_factor(quot);
if(!RtlDeleteFunctionTable(func))
fatal_error("RtlDeleteFunctionTable() failed",0);
}
}
Jump to Line
Something went wrong with that request. Please try again.