scratch: sync sketch code for FFI,Signal...
authorHarald Steinlechner <haraldsteinlechner@gmail.com>
Thu, 17 May 2012 16:25:49 +0000 (18:25 +0200)
committerHarald Steinlechner <haraldsteinlechner@gmail.com>
Thu, 17 May 2012 16:25:49 +0000 (18:25 +0200)
scratch/ffiTest/Makefile [new file with mode: 0644]
scratch/ffiTest/mate_support.c [new file with mode: 0644]
scratch/ffiTest/prototypes.h [new file with mode: 0644]
scratch/ffiTest/trapTest.hs [new file with mode: 0644]

diff --git a/scratch/ffiTest/Makefile b/scratch/ffiTest/Makefile
new file mode 100644 (file)
index 0000000..1dde1e4
--- /dev/null
@@ -0,0 +1,9 @@
+all: mate_support.c trapTest.hs
+       ghc -c mate_support.c
+       ghc --make trapTest.hs mate_support.o
+
+ghci: all
+       ghci -package containers -package random trapTest.o mate_support.o trapTest_stub.o trapTest.hs
+
+clean:
+       rm *.o *.hi trapTest trapTest_stub.c trapTest_stub.h
diff --git a/scratch/ffiTest/mate_support.c b/scratch/ffiTest/mate_support.c
new file mode 100644 (file)
index 0000000..7ca8919
--- /dev/null
@@ -0,0 +1,66 @@
+#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);
+}
+
diff --git a/scratch/ffiTest/prototypes.h b/scratch/ffiTest/prototypes.h
new file mode 100644 (file)
index 0000000..55b7903
--- /dev/null
@@ -0,0 +1,8 @@
+extern void registerSignalHandlers(void);
+extern void mateTrapHandler(unsigned int signal,
+                            siginfo_t *sigInfo,
+                            void *ctx,
+                            unsigned int eip);
+
+
+extern void registerSignalHandlers2(void (*f)(int, siginfo_t*,void*));
diff --git a/scratch/ffiTest/trapTest.hs b/scratch/ffiTest/trapTest.hs
new file mode 100644 (file)
index 0000000..409c9a3
--- /dev/null
@@ -0,0 +1,107 @@
+{-#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'
+
+