1 {-#LANGUAGE ForeignFunctionInterface #-}
5 import qualified Data.Map as M
10 import Foreign.C.Types
16 foreign import ccall "dynamic"
17 code_void :: FunPtr (IO ()) -> (IO ())
19 foreign import ccall "static sys/mman.h"
20 mprotect :: CUInt -> CUInt -> Int -> IO ()
22 foreign import ccall "static stdlib.h"
23 memalign :: CUInt -> CUInt -> IO (Ptr a)
25 foreign import ccall safe "prototypes.h"
26 registerSignalHandlers :: IO ()
28 foreign import ccall "wrapper"
29 wrap :: (CUInt -> Ptr SigInfo -> Ptr Context -> IO ()) -> IO (FunPtr (CUInt -> Ptr SigInfo -> Ptr Context -> IO ()))
31 foreign import ccall "prototypes.h"
32 registerSignalHandlers2 :: FunPtr (CUInt -> Ptr SigInfo -> Ptr Context -> IO ()) -> IO ()
35 mateTrapHandler :: CUInt -> Ptr SigInfo -> Ptr Context -> CUInt -> IO ()
40 data MateExecutionCtx = Ctx { compiledMethods :: M.Map Int Int }
41 emptyCtx :: MateExecutionCtx
42 emptyCtx = Ctx { compiledMethods = M.empty }
44 type AppDomain = () -- classpath etc
46 -- add AppDomain to MateExecutionCtx in order to get linear access
48 runMateKernel :: AppDomain -> IO ()
52 -- use FFI to unpack sigInfo and ctx....
53 handler mateCtx signal sigInfo ctx = do
54 putStr "handler got me."
56 putStr "content of code cache: "
57 actualCtx <- readIORef mateCtx
58 let methods = compiledMethods actualCtx
61 -- write back new compiled stuff
62 writeIORef mateCtx (Ctx {compiledMethods = M.insert random random methods})
69 -- load application context (classpath etc)
70 let appDomain = undefined
72 ctx <- newIORef emptyCtx
74 -- curry context into handler
75 actualHandler <- wrap (handler ctx)
77 -- perform global setup
78 registerSignalHandlers2 actualHandler
80 runMateKernel appDomain
83 compileAndRun :: IO ()
85 entryPtr <- memalign 0x1000 0x2
86 poke entryPtr (0xffff9090 :: Word32) -- SIGILL
87 --poke entryPtr (0xc390 :: Word16) -- nop (0x90); ret(0xc3) (little endian order)
88 let i_entry = (fromIntegral $ ptrToIntPtr entryPtr) :: Int
89 -- 0x7 = PROT_{READ,WRITE,EXEC}
90 mprotect (fromIntegral i_entry) 2 0x7
91 _ <- printf "entry point: 0x%08x\n" i_entry
92 code_void $ castPtrToFunPtr entryPtr
93 putStrLn "welcome back"
97 senseless = getStdRandom (randomR (1,100))
100 mateTrapHandler :: CUInt -> Ptr SigInfo -> Ptr Context -> CUInt -> IO ()
101 mateTrapHandler signal sigInfo ctx eip = do
102 putStr "mateTrapHandler says: "
103 let eip' = (fromIntegral eip) :: Int
104 printf "source, eip: 0x%08x" eip'