"static_wrapper" imports in the FFI
marlowsd at gmail.com
Wed Mar 17 05:00:57 EDT 2010
On 16/03/10 23:38, Iavor Diatchki wrote:
> 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
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
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
> 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.
>> 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.
>>> On Mon, Mar 15, 2010 at 3:56 PM, Tyson Whitehead<twhitehead at gmail.com>
>>>> 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
>>>> 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
>>>> (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
More information about the Glasgow-haskell-users