-instanceOfMissHandler :: CPtrdiff -> B.ByteString -> IO CPtrdiff
-instanceOfMissHandler eip classname = do
- -- first byte is going to be the opcode
- let insn_ptr = intPtrToPtr (fromIntegral eip) :: Ptr CUChar
- -- the next four bytes are the immediate
- let imm_ptr = intPtrToPtr (fromIntegral (eip + 1)) :: Ptr CPtrdiff
- checkMe <- peek imm_ptr
- if checkMe == 0x909090ff then -- safety check...
- do
- mtable <- getMethodTable classname
- poke imm_ptr (fromIntegral mtable)
- poke insn_ptr 0xba -- `mov edx' opcode
- return eip
- else error "instanceOfMissHandler: something is wrong here. abort.\n"
-
-invokeHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> Bool -> IO CPtrdiff
-invokeHandler method_table table2patch esp imm8 = do
- -- table2patch: note, that can be a method-table or a interface-table
- callerAddr <- callerAddrFromStack esp
- offset <- if imm8 then offsetOfCallInsn8 esp else offsetOfCallInsn32 esp
- entryAddr <- getMethodEntry callerAddr method_table
- let call_insn = intPtrToPtr (fromIntegral $ table2patch + fromIntegral offset)
- poke call_insn entryAddr
- return entryAddr
-
-
-callerAddrFromStack :: CPtrdiff -> IO CPtrdiff
-callerAddrFromStack = peek . intPtrToPtr . fromIntegral
-
-offsetOfCallInsn8 :: CPtrdiff -> IO CPtrdiff
-offsetOfCallInsn8 esp = do
- let ret_ptr = intPtrToPtr (fromIntegral esp) :: Ptr CPtrdiff
- ret <- peek ret_ptr
- retval <- peek (intPtrToPtr (fromIntegral (ret - 1)) :: Ptr CUChar)
- return $ fromIntegral retval
-
-offsetOfCallInsn32 :: CPtrdiff -> IO CPtrdiff
-offsetOfCallInsn32 esp = do
- let ret_ptr = intPtrToPtr (fromIntegral esp) :: Ptr CPtrdiff
- ret <- peek ret_ptr
- peek (intPtrToPtr $ fromIntegral (ret - 4))
+patchInvoke :: MethodInfo -> CPtrdiff -> CPtrdiff -> IO NativeWord -> CPtrdiff -> CodeGen e s CPtrdiff
+patchInvoke (MethodInfo methname _ msig) method_table table2patch io_offset reip = do
+ vmap <- liftIO getVirtualMap
+ let newmi = MethodInfo methname (vmap M.! fromIntegral method_table) msig
+ offset <- liftIO io_offset
+ (entryAddr, _) <- liftIO $ getMethodEntry newmi
+ call32Eax (Disp offset)
+ -- patch entry in table
+ let call_insn = intPtrToPtr . fromIntegral $ table2patch + fromIntegral offset
+ liftIO $ poke call_insn entryAddr
+ return reip