-- TODO(bernhard): implement `emit' as function which accepts a list of
-- instructions, so we can use patterns for optimizations
where
+ forceRegDump :: CodeGen e s ()
+ forceRegDump = do
+ push esi
+ mov esi (0x13371234 :: Word32)
+ mov esi (Addr 0)
+ pop esi
+
getCurrentOffset :: CodeGen e s Word32
getCurrentOffset = do
ep <- getEntryPoint
sete al
movzxb eax al
push eax
+ forceRegDump
return $ Just (trapaddr, InstanceOf $ buildClassID cls cpidx)
emit' insn = emit insn >> return Nothing
| VirtualMethodCall Bool
| InterfaceMethodCall Bool
| InstanceOfMiss B.ByteString
+ | NoKnownTrap String
getTrapType :: TrapMap -> CPtrdiff -> CPtrdiff -> TrapType
getTrapType tmap signal_from from2 =
(Just (StaticMethod _)) -> StaticMethodCall
(Just (StaticField _)) -> StaticFieldAccess
(Just (InstanceOf cn)) -> InstanceOfMiss cn
- (Just _) -> error "getTrapMap: doesn't happen"
+ (Just _) -> NoKnownTrap "getTrapMap: doesn't happen"
-- maybe we've a hit on the second `from' value
Nothing -> case M.lookup (fromIntegral from2) tmap of
(Just (VirtualMethod imm8 _)) -> VirtualMethodCall imm8
(Just (InterfaceMethod imm8 _)) -> InterfaceMethodCall imm8
- (Just _) -> error "getTrapType: abort #1 :-("
- Nothing -> error $ "getTrapType: abort #2 :-(" ++ show signal_from ++ ", " ++ show from2 ++ ", " ++ show tmap
+ (Just _) -> NoKnownTrap "getTrapType: abort #1 :-("
+ Nothing -> NoKnownTrap $ "getTrapType: abort #2 :-(" ++ show signal_from ++ ", " ++ show from2 ++ ", " ++ show tmap
-foreign export ccall mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
-mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
-mateHandler eip eax ebx esp = do
+foreign export ccall mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
+mateHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> CPtrdiff -> IO CPtrdiff
+mateHandler eip eax ebx esp esi = do
callerAddr <- callerAddrFromStack esp
tmap <- getTrapMap
case getTrapType tmap eip callerAddr of
(InstanceOfMiss cn) -> instanceOfMissHandler eip cn
VirtualMethodCall imm8 -> invokeHandler eax eax esp imm8
InterfaceMethodCall imm8 -> invokeHandler eax ebx esp imm8
+ NoKnownTrap err ->
+ case esi of
+ 0x13371234 -> return (-1)
+ _ -> error err
staticCallHandler :: CPtrdiff -> IO CPtrdiff
staticCallHandler eip = do
#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);
void chandler(int nSignal, siginfo_t *info, void *ctx)
{
mcontext_t *mctx = &((ucontext_t *) ctx)->uc_mcontext;
+ greg_t *regs = mctx->gregs;
- ptrdiff_t eip = (ptrdiff_t) mctx->gregs[REG_EIP];
- ptrdiff_t eax = (ptrdiff_t) mctx->gregs[REG_EAX];
- ptrdiff_t ebx = (ptrdiff_t) mctx->gregs[REG_EBX];
- ptrdiff_t esp = (ptrdiff_t) mctx->gregs[REG_ESP];
+ ptrdiff_t eip = (ptrdiff_t) regs[REG_EIP];
+ ptrdiff_t eax = (ptrdiff_t) regs[REG_EAX];
+ ptrdiff_t ebx = (ptrdiff_t) regs[REG_EBX];
+ ptrdiff_t esp = (ptrdiff_t) regs[REG_ESP];
+ ptrdiff_t esi = (ptrdiff_t) regs[REG_ESI];
dprintf("trap: type %d, eip 0x%08x, eax 0x%08x, ebx 0x%08x, "
"esp 0x%08x, *esp 0x%08x\n", nSignal, eip,
eax, ebx, esp, *(ptrdiff_t*) esp);
- mctx->gregs[REG_EIP] = mateHandler(eip, eax, ebx, esp);
+ ptrdiff_t ret = mateHandler(eip, eax, ebx, esp, esi);
+ 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",
+ regs[REG_EAX], regs[REG_EBX], regs[REG_ECX], regs[REG_EDX]);
+ dprintf("\tESI: 0x%08lx EDI: 0x%08lx EBP: 0x%08lx ESP: 0x%08lx\n",
+ regs[REG_ESI], regs[REG_EDI], regs[REG_EBP], regs[REG_ESP]);
+ mctx->gregs[REG_EIP] = eip + 6;
+ } else {
+ mctx->gregs[REG_EIP] = ret;
+ }
}
void register_signal(void)