
On Wed, Aug 29, 2007 at 01:03:56PM -0700, Stefan O'Rear wrote:
So it is not clear if GHC does really need this PROT_EXEC. Can someone familiar with GHC internals answer why PROT_EXEC is used in getMBlocks?
It's not possible to correctly implement 'foreign import ccall "wrapper"' without self-modifying code on any mainstream computer architecture. Does this program work on your no-PROT_EXEC ghc? :
{-# OPTIONS_GHC -ffi #-} import Foreign
foreign import ccall "wrapper" wrap :: IO () -> IO (FunPtr (IO ())) foreign import ccall "dynamic" call :: FunPtr (IO ()) -> IO ()
main = call =<< wrap (print "hi!")
Thanks, that is exactly what I asked for. This program compiles with my no-PROT_EXEC ghc, but doesn't work: $ ghc -o 1 1.hs $ ./1 1: internal error: makeExecutable: failed to protect 0x0x2b115597e000 (GHC version 6.6.1 for x86_64_unknown_linux) Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug Aborted $ The errors comes from rts/posix/OSMem.c, function setExecutable which tries to mprotect block of memory with PROT_EXEC and PROT_WRITE. What is so special about wrapper and dynamic functions? I've never used Haskell FFI, but I've heavily used Python-C interface and Ocaml-C interface, calling both C from Ocaml and Ocaml from C and even Ocaml from Python via C and etc. It all worked fine without any runtime code generation or self-modifying code. Can you please give some ideas how self-modifying code can be used in FFI implementation? With best regards, Alexander.