{-#LANGUAGE ForeignFunctionInterface #-} module Main where import qualified Data.Map as M import Data.Word import Text.Printf import Foreign import Foreign.C.Types import Data.IORef import System.Random foreign import ccall "dynamic" code_void :: FunPtr (IO ()) -> (IO ()) foreign import ccall "static sys/mman.h" mprotect :: CUInt -> CUInt -> Int -> IO () foreign import ccall "static stdlib.h" memalign :: CUInt -> CUInt -> IO (Ptr a) foreign import ccall "wrapper" wrap :: (CUInt -> Ptr SigInfo -> Ptr Context -> IO ()) -> IO (FunPtr (CUInt -> Ptr SigInfo -> Ptr Context -> IO ())) foreign import ccall "prototypes.h" registerSignalHandlers2 :: FunPtr (CUInt -> Ptr SigInfo -> Ptr Context -> IO ()) -> IO () type SigInfo = () type Context = () data MateExecutionCtx = Ctx { compiledMethods :: M.Map Int Int } emptyCtx :: MateExecutionCtx emptyCtx = Ctx { compiledMethods = M.empty } type AppDomain = () -- classpath etc -- add AppDomain to MateExecutionCtx in order to get linear access runMateKernel :: AppDomain -> IO () runMateKernel _ = do compileAndRun -- use FFI to unpack sigInfo and ctx.... handler mateCtx signal sigInfo ctx = do putStr "handler got me." print signal putStr "content of code cache: " actualCtx <- readIORef mateCtx let methods = compiledMethods actualCtx random <- senseless print methods -- write back new compiled stuff writeIORef mateCtx (Ctx {compiledMethods = M.insert random random methods}) _ <- getChar compileAndRun -- tail main :: IO () main = do -- load application context (classpath etc) let appDomain = undefined ctx <- newIORef emptyCtx -- curry context into handler actualHandler <- wrap (handler ctx) -- perform global setup registerSignalHandlers2 actualHandler runMateKernel appDomain compileAndRun :: IO () compileAndRun = do entryPtr <- memalign 0x1000 0x2 poke entryPtr (0xffff9090 :: Word32) -- SIGILL --poke entryPtr (0xc390 :: Word16) -- nop (0x90); ret(0xc3) (little endian order) let i_entry = (fromIntegral $ ptrToIntPtr entryPtr) :: Int -- 0x7 = PROT_{READ,WRITE,EXEC} mprotect (fromIntegral i_entry) 2 0x7 _ <- printf "entry point: 0x%08x\n" i_entry code_void $ castPtrToFunPtr entryPtr putStrLn "welcome back" senseless :: IO Int senseless = getStdRandom (randomR (1,100))