
On 16/03/10 23:38, Iavor Diatchki wrote:
Hello,
On Tue, Mar 16, 2010 at 3:22 PM, Simon Marlow
wrote: It seems hard to justify adding this to GHC, since it's really just syntactic convenience for a particular case. Traditionally syntactic sugar for FFI declarations has been implemented in the preprocessing tools: c2hs and hsc2hs, whereas the FFI extension itself is purposefully minimal.
The fact that, at present, all GHC-compiled programs require an executable data segment is a fairly significant problem. For example, SE Linux policies need to be adjusted for all GHC-compiled programs, even if run-time code generation never actually happens.
GHC-compiled programs don't need an executable data segment. There are two features that require dynamically-allocated executable memory: the GHCi linker, and foreign import "wrapper". However, you don't have to use either! As noted earlier in this thread, you can use foreign export to do the same thing that static_wrapper provides, so we're not getting any new functionality here. Regarding SELinux, we use libffi which works around the SELinux restrictions using a double-mmaping trick. GHC executables do not require an SELinux exception - I've tried this on our Fedora systems with SE Linux enabled. It was fixed in 6.10.1: http://hackage.haskell.org/trac/ghc/ticket/738
I decided to implement this as a GHC patch because it seems more primitive then the "wrapper" imports: it is a simpler feature which---if it was available---would have been sufficient in all the situations where I have needed to use a "wrapper" import.
But as pointed out earlier, you don't need this extenstion to do what you wanted. It's just a syntactic convenience - that's the substance of our objection to adding it.
Furthermore, the code that is called by the adjustor thunks is essentially the function that we are exposing in a "static_wrapper" import, so it seems plausible that "wrapper" imports can be implemented on top of this, although I have not done this.
Probably you could, yes.
I thought of implementing the feature as a preprocessor but it did not seem very easy to do because we need to parse Haskell types. Of course, I could have either hacked up a simple parser, or used some kind of a Haskell parsing library but that seemed very heavy-weight. Also, preprocessors tend to complicate the build system, result in confusing error messages, and make it difficult to work with modules in GHCi.
I don't disagree with the second point - but for better or worse we already have this split between low-level FFI code and preprocessors, and adding syntactic sugar to FFI declarations seems to be going against the grain.
As far as I can see, the notation that I used does not conflict with anything, except possibly importing a C function named "static_wrapper" without specifying a header file, which is already a problem with "wrapper" imports. This would not be the case if we used something which is not a valid C identifier (e.g., "static"). This seems like a small enough change to not require a separate flag. If we decided to use Tyson's suggested syntax, then we should probably add a flag.
Extensions always require a flag, because the extension is by definition not universally supported, so code that uses it has to indicate that. We started being strict about this a while ago, it would be wrong to start introducing exceptions (albeit minor ones).
In any case, I think that moving away from executable data is important enough that I'd be happy with an extra flag. Thoughts?
If that were the case then yes I'd agree, but I don't think it is. Cheers, Simon
-Iavor
So at the moment we're slightly inclined not to put it in - but feel free to make a compelling case. Note that as an extension in its own right it would need its own flag, documentation etc.
Cheers, Simon
-Iavor
On Mon, Mar 15, 2010 at 3:56 PM, Tyson Whitehead
wrote: On March 15, 2010 12:48:02 Iavor Diatchki wrote:
I have implemented a small extension to the FFI which allows for "static_wrapper" imports. These are a variation on "wrapper" imports that do not use run-time code generation. This is important in security sensitive contexts because it avoids executable data. While "static_wrapper" imports are less general then "wrapper" imports, they can be used to install Haskell handlers in many C libraries where callbacks have an extra "user-data" parameter (e.g., GTK signal handlers).
Hi Iavor,
Would not the following also do what you want
foreign export ccall "haskellCIntCInt" \ cbind :: CInt -> StablePtr (CInt -> IO CInt) -> IO CInt
cbind :: a -> StablePtr (a-> IO b) -> IO b cbind x f = deRefStablePtr f>>= (\f_ -> f_ x)
On the C side you would then have something like
register_callback(haskellCIntInt,<wrapped haskell closure>)
where<wrapped haskell closure> would be a stable pointer of type StablePtr (CInt -> IO CInt) generated on the haskell side via
newStablePtr<haskell closure>
and passed to the C code.
Cheers! -Tyson
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users