type TrapPatcher = CPtrdiff -> CodeGen () () CPtrdiff
type TrapPatcherEax = CPtrdiff -> CPtrdiff -> CodeGen () () CPtrdiff
+type TrapPatcherEsp = TrapPatcherEax
data TrapCause
= StaticMethod TrapPatcher -- for static calls
| VirtualCall Bool MethodInfo (IO NativeWord) -- for invoke{interface,virtual}
| InstanceOf TrapPatcherEax
+ | ThrowException TrapPatcherEsp
| NewObject TrapPatcher
| StaticField StaticFieldInfo
| ObjectField TrapPatcher
return reip
return $ Just (trapaddr, NewObject patcher)
+ emit' ATHROW = do
+ trapaddr <- emitSigIllTrap 2
+ let patcher resp reip = do
+ emitSigIllTrap 2
+ return reip
+ return $ Just (trapaddr, ThrowException patcher)
+
emit' insn = emit insn >> return Nothing
emit :: J.Instruction -> CodeGen e s ()
push eax -- push ref again
emit (CHECKCAST _) = nop -- TODO(bernhard): ...
- emit ATHROW = -- TODO(bernhard): ...
- emit32 (0xffffffff :: Word32)
emit I2C = do
pop eax
and eax (0x000000ff :: Word32)
emitSigIllTrap :: Int -> CodeGen e s NativeWord
emitSigIllTrap traplen = do
+ when (traplen < 2) (error "emitSigIllTrap: trap len too short")
trapaddr <- getCurrentOffset
-- 0xffff causes SIGILL
emit8 (0xff :: Word8); emit8 (0xff :: Word8)
foreign import ccall "register_signal"
register_signal :: IO ()
-foreign export ccall mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
-mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
-mateHandler reip reax rebx resi = do
+foreign export ccall mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
+mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
+mateHandler reip reax rebx resi resp = do
tmap <- getTrapMap
let reipw32 = fromIntegral reip
(deleteMe, ret_nreip) <- case M.lookup reipw32 tmap of
patchWithHarpy patcher reip >>= delTrue
(Just (InstanceOf patcher)) ->
patchWithHarpy (patcher reax) reip >>= delFalse
+ (Just (ThrowException patcher)) ->
+ patchWithHarpy (patcher resp) reip >>= delFalse
(Just (NewObject patcher)) ->
patchWithHarpy patcher reip >>= delTrue
(Just (VirtualCall False mi io_offset)) ->
#include <sys/ucontext.h>
-ptrdiff_t mateHandler(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t);
+ptrdiff_t mateHandler(ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t);
#ifdef DBG_TRAP
#define dprintf(args...) do { printf (args); } while (0);
"esp 0x%08x, *esp 0x%08x, *(ebp+8) 0x%08x\n", nSignal, eip,
eax, ebx, esp, *(ptrdiff_t*) esp, *(ptrdiff_t *) (ebp + 8));
- ptrdiff_t ret = mateHandler(eip, eax, ebx, esi);
+ ptrdiff_t ret = mateHandler(eip, eax, ebx, esi, esp);
if (ret == -1) {
dprintf("regdump @ EIP: 0x%08x\n", regs[REG_EIP]);
dprintf("\tEAX: 0x%08lx EBX: 0x%08lx ECX: 0x%08lx EDX: 0x%08lx\n",