From efcf93f38698c9f8043f896007bfb9d40c72f0a5 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Wed, 18 Apr 2012 12:40:14 +0200 Subject: [PATCH] trap: use SIGILL instead of SIGSEGV therefore we can use SIGSEGV for other things (e.g. exception handling) --- Mate/X86CodeGen.hs | 5 +++-- ffi/trap.c | 16 ++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Mate/X86CodeGen.hs b/Mate/X86CodeGen.hs index 270368f..dea2a4b 100644 --- a/Mate/X86CodeGen.hs +++ b/Mate/X86CodeGen.hs @@ -176,8 +176,9 @@ emitFromBB cls hmap = do calladdr <- getCodeOffset let w32_calladdr = w32_ep + (fromIntegral calladdr) :: Word32 newNamedLabel (toString l) >>= defineLabel - -- TODO(bernhard): better try SIGILL instead of SIGSEGV? - mov (Addr 0) eax + -- causes SIGILL. in the signal handler we patch it to the acutal call. + -- place a nop at the end, therefore the disasm doesn't screw up + emit32 (0xffffffff :: Word32) >> emit8 (0x90 :: Word8) -- discard arguments (TODO(bernhard): don't hardcode it) add esp (4 :: Word32) -- push result on stack (TODO(bernhard): if any) diff --git a/ffi/trap.c b/ffi/trap.c index 32e5217..2073dae 100644 --- a/ffi/trap.c +++ b/ffi/trap.c @@ -58,21 +58,17 @@ void callertrap(int nSignal, siginfo_t *info, void *ctx) unsigned int patchme = getMethodEntry(from, method_map, caller_map); printf("callertrap(mctx) by 0x%08x\n", from); - // printf("callertrap(addr) by 0x%08x\n", info->si_addr); - // printf("callertrap(*esp) by 0x%08x\n", * (unsigned int *) uctx->uc_mcontext.esp); - unsigned int *to_patch = (unsigned int *) (uctx->uc_mcontext.eip + 2); - unsigned char *insn = (unsigned char *) (uctx->uc_mcontext.eip); - *insn = 0x90; // nop - insn++; - *insn = 0xe8; // call + unsigned int *to_patch = (unsigned int *) (from + 1); + unsigned char *insn = (unsigned char *) from; + *insn = 0xe8; // call opcode printf(" to_patch: 0x%08x\n", (unsigned int) to_patch); printf("*to_patch: 0x%08x\n", *to_patch); - if (*to_patch != 0x00000000) { + if (*to_patch != 0x90ffffff) { printf("something is wrong here. abort\n"); exit(0); } - *to_patch = (unsigned int) patchme - ((unsigned int) insn + 5); + *to_patch = patchme - (from + 5); printf("*to_patch: 0x%08x\n", *to_patch); uctx->uc_mcontext.eip = (unsigned long) insn; // while (1) ; @@ -84,7 +80,7 @@ void register_signal(void) segvaction.sa_sigaction = callertrap; sigemptyset(&segvaction.sa_mask); segvaction.sa_flags = SA_SIGINFO | SA_RESTART; - sigaction(SIGSEGV, &segvaction, NULL); + sigaction(SIGILL, &segvaction, NULL); } unsigned int getaddr(void) -- 2.25.1