"static_wrapper" imports in the FFI

Simon Marlow marlowsd at gmail.com
Wed Mar 17 05:00:57 EDT 2010

On 16/03/10 23:38, Iavor Diatchki wrote:
> Hello,
> On Tue, Mar 16, 2010 at 3:22 PM, Simon Marlow<marlowsd at gmail.com>  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:


> 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.


> -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<twhitehead at gmail.com>
>>>   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 at haskell.org
>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

More information about the Glasgow-haskell-users mailing list