--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+/* TODO(bernhard): use {u,}int* types */
+
+#define __USE_GNU
+// Note by hs: my signal.h includes sys/uconctext which conflicts with
+// asm/ucontext - this hack kinda solves the problem for me ;-)
+// so feel free to blame me for that s**t
+#if defined __USE_XOPEN2K8
+#undef __USE_XOPEN2K8
+#define RESTORE
+#warning hs-hack: undefining __USE_XOPEN2K8 for signal.h
+#endif
+#include <signal.h>
+#ifdef RESTORE
+#define __USE_XOPEN2K8
+#endif
+
+#include <sys/ucontext.h>
+
+#include "prototypes.h"
+
+void trap(int nSignal, siginfo_t *info, void *ctx)
+{
+ printf("sig: %d\n", nSignal);
+
+ mcontext_t *mctx = &((ucontext_t *) ctx)->uc_mcontext;
+ unsigned int from = (unsigned int) mctx->gregs[REG_EIP];
+
+ mateTrapHandler(nSignal, info, ctx, from);
+
+ printf("from: 0x%08x\n", from);
+ exit(0);
+}
+
+void registerSignalHandlers(void)
+{
+ printf("registering\n");
+ struct sigaction illaction;
+ illaction.sa_sigaction = trap;
+ sigemptyset(&illaction.sa_mask);
+ illaction.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
+ sigaction(SIGILL, &illaction, NULL);
+
+
+/*
+ struct sigaction segvaction;
+ segvaction.sa_sigaction = trap;
+ sigemptyset(&segvaction.sa_mask);
+ segvaction.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
+ sigaction(SIGSEGV, &segvaction, NULL);
+*/
+}
+
+
+void registerSignalHandlers2(void (*f)(int, siginfo_t*,void*))
+{
+ printf("registering2\n");
+ struct sigaction illaction;
+ illaction.sa_sigaction = f;
+ sigemptyset(&illaction.sa_mask);
+ illaction.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
+ sigaction(SIGILL, &illaction, NULL);
+}
+
--- /dev/null
+{-#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 safe "prototypes.h"
+ registerSignalHandlers :: IO ()
+
+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 ()
+
+foreign export ccall
+ mateTrapHandler :: CUInt -> Ptr SigInfo -> Ptr Context -> CUInt -> 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))
+
+
+mateTrapHandler :: CUInt -> Ptr SigInfo -> Ptr Context -> CUInt -> IO ()
+mateTrapHandler signal sigInfo ctx eip = do
+ putStr "mateTrapHandler says: "
+ let eip' = (fromIntegral eip) :: Int
+ printf "source, eip: 0x%08x" eip'
+ print eip'
+
+