From: Harald Steinlechner Date: Thu, 17 May 2012 16:25:49 +0000 (+0200) Subject: scratch: sync sketch code for FFI,Signal... X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mate.git;a=commitdiff_plain;h=7f6c34b263df6917a392d95ace4a13f8ef2c7c48 scratch: sync sketch code for FFI,Signal... --- diff --git a/scratch/ffiTest/Makefile b/scratch/ffiTest/Makefile new file mode 100644 index 0000000..1dde1e4 --- /dev/null +++ b/scratch/ffiTest/Makefile @@ -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 index 0000000..7ca8919 --- /dev/null +++ b/scratch/ffiTest/mate_support.c @@ -0,0 +1,66 @@ +#include +#include + +/* 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 +#ifdef RESTORE +#define __USE_XOPEN2K8 +#endif + +#include + +#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 index 0000000..55b7903 --- /dev/null +++ b/scratch/ffiTest/prototypes.h @@ -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 index 0000000..409c9a3 --- /dev/null +++ b/scratch/ffiTest/trapTest.hs @@ -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' + +