diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright (c) <2009>, <Maurício C. Antunes>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the author nor the names of contributors
+    may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,6 @@
+#!/usr/bin/env runhaskell
+
+module Main (main) where
+import Distribution.Simple
+
+main = defaultMain
diff --git a/bindings-libffi.cabal b/bindings-libffi.cabal
new file mode 100644
--- /dev/null
+++ b/bindings-libffi.cabal
@@ -0,0 +1,34 @@
+cabal-version: >= 1.2.3
+name: bindings-libffi
+homepage: http://bitbucket.org/mauricio/bindings
+synopsis:
+  Check bindings-common package for directions.
+version: 0.0.1
+license: BSD3
+license-file: LICENSE
+maintainer: Maurício C. Antunes
+author: Maurício C. Antunes
+build-type: Simple
+category: FFI
+library
+  hs-source-dirs: src
+  extensions:
+    ForeignFunctionInterface
+    TypeSynonymInstances
+    ScopedTypeVariables
+    EmptyDataDecls
+    TypeFamilies
+  build-depends: base >= 3 && <5, bindings-common
+  exposed-modules:
+    Bindings.Libffi
+  other-modules:
+    LibffiConstants
+    LibffiTypes
+    LibffiFunctions
+-- This has to be commented out so that hackage
+-- won't complain about a missing library.
+--c-sources:
+--  src/constants.c
+--  src/types.c
+--pkgconfig-depends:
+--  libffi >= 3.0
diff --git a/src/Bindings/Libffi.hs b/src/Bindings/Libffi.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/Libffi.hs
@@ -0,0 +1,62 @@
+-- | See <http://sourceware.org/libffi>.
+
+module Bindings.Libffi (
+
+    -- * The basics
+
+    ffi_prep_cif,
+    ffi_call,
+    Ffi_cif,
+    Ffi_status,
+    _FFI_OK,
+    _FFI_BAD_TYPEDEF,
+    _FFI_BAD_ABI,
+
+    -- * Types
+
+    -- ** Primitive Types
+
+    ffi_type_void,
+    ffi_type_uint8,
+    ffi_type_sint8,
+    ffi_type_uint16,
+    ffi_type_sint16,
+    ffi_type_uint32,
+    ffi_type_sint32,
+    ffi_type_uint64,
+    ffi_type_sint64,
+    ffi_type_float,
+    ffi_type_double,
+    ffi_type_uchar,
+    ffi_type_schar,
+    ffi_type_ushort,
+    ffi_type_sshort,
+    ffi_type_uint,
+    ffi_type_sint,
+    ffi_type_ulong,
+    ffi_type_slong,
+    ffi_type_pointer,
+
+    -- ** Structures
+
+    Ffi_type,
+
+    -- * Multiple ABIs
+
+    Ffi_abi,
+    _FFI_FIRST_ABI,
+    _FFI_DEFAULT_ABI,
+
+    -- * The Closure API
+
+    _FFI_CLOSURES,
+    ffi_closure_alloc,
+    ffi_closure_free,
+    ffi_prep_closure_loc,
+    Ffi_closure
+
+ ) where
+
+import LibffiConstants
+import LibffiTypes
+import LibffiFunctions
diff --git a/src/LibffiConstants.hs b/src/LibffiConstants.hs
new file mode 100644
--- /dev/null
+++ b/src/LibffiConstants.hs
@@ -0,0 +1,83 @@
+module LibffiConstants where
+import Foreign
+import Foreign.C
+import LibffiTypes
+
+foreign import ccall "_ffi_type_uchar" ffi_type_uchar
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_schar" ffi_type_schar
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_ushort" ffi_type_ushort
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_sshort" ffi_type_sshort
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_uint" ffi_type_uint
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_sint" ffi_type_sint
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_ulong" ffi_type_ulong
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_slong" ffi_type_slong
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_void" ffi_type_void
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_uint8" ffi_type_uint8
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_sint8" ffi_type_sint8
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_uint16" ffi_type_uint16
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_sint16" ffi_type_sint16
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_uint32" ffi_type_uint32
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_sint32" ffi_type_sint32
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_uint64" ffi_type_uint64
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_sint64" ffi_type_sint64
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_float" ffi_type_float
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_double" ffi_type_double
+    :: Ptr Ffi_type
+
+foreign import ccall "_ffi_type_pointer" ffi_type_pointer
+    :: Ptr Ffi_type
+
+foreign import ccall "_FFI_OK" _FFI_OK
+    :: Ffi_status
+
+foreign import ccall "_FFI_BAD_TYPEDEF" _FFI_BAD_TYPEDEF
+    :: Ffi_status
+
+foreign import ccall "_FFI_BAD_ABI" _FFI_BAD_ABI
+    :: Ffi_status
+
+foreign import ccall "_FFI_CLOSURES" _FFI_CLOSURES
+    :: CInt
+
+foreign import ccall "_FFI_FIRST_ABI" _FFI_FIRST_ABI
+    :: Ffi_abi
+
+foreign import ccall "_FFI_DEFAULT_ABI" _FFI_DEFAULT_ABI
+    :: Ffi_abi
+
diff --git a/src/LibffiFunctions.hs b/src/LibffiFunctions.hs
new file mode 100644
--- /dev/null
+++ b/src/LibffiFunctions.hs
@@ -0,0 +1,24 @@
+module LibffiFunctions where
+import Foreign
+import Foreign.C
+import LibffiTypes
+
+foreign import ccall "ffi_closure_alloc" ffi_closure_alloc
+    :: CSize -> Ptr (Ptr ()) -> IO (Ptr ())
+
+foreign import ccall "ffi_closure_free" ffi_closure_free
+    :: Ptr () -> IO ()
+
+foreign import ccall "ffi_prep_closure_loc" ffi_prep_closure_loc
+    :: Ptr Ffi_closure -> Ptr Ffi_cif -> FunPtr (Ptr Ffi_cif ->
+       Ptr () -> Ptr (Ptr ()) -> Ptr a -> IO ()) -> Ptr a ->
+       Ptr () -> IO Ffi_status
+
+foreign import ccall "ffi_prep_cif" ffi_prep_cif
+    :: Ptr Ffi_cif -> Ffi_abi -> CUInt -> Ptr Ffi_type -> 
+       Ptr (Ptr Ffi_type) -> IO Ffi_status
+
+foreign import ccall "ffi_call" ffi_call
+    :: Ptr Ffi_cif -> FunPtr (IO ()) -> Ptr () -> Ptr (Ptr ()) ->
+       IO ()
+
diff --git a/src/LibffiTypes.hs b/src/LibffiTypes.hs
new file mode 100644
--- /dev/null
+++ b/src/LibffiTypes.hs
@@ -0,0 +1,46 @@
+module LibffiTypes where
+import Foreign
+import Foreign.C
+
+data Ffi_type = Ffi_type {
+    ffi_type'size :: CSize,
+    ffi_type'alignment,
+    ffi_type'type :: CUShort,
+    ffi_type'elements :: Ptr (Ptr Ffi_type)
+   }
+
+instance Storable Ffi_type where
+    sizeOf _ = fromIntegral size_of_ffi_type
+    alignment = sizeOf
+    peek p =
+        with 0 $ \p1 ->
+        with 0 $ \p2 ->
+        with 0 $ \p3 ->
+        with nullPtr $ \p4 ->
+        c2hs_ffi_type p p1 p2 p3 p4 >>
+        peek p1 >>= \v1 ->
+        peek p2 >>= \v2 ->
+        peek p3 >>= \v3 ->
+        peek p4 >>= \v4 ->
+        return $ Ffi_type v1 v2 v3 v4
+    poke p (Ffi_type v1 v2 v3 v4) = hs2c_ffi_type p v1 v2 v3 v4
+
+type Ffi_status = CInt
+
+type Ffi_abi = CInt
+
+data Ffi_cif
+
+data Ffi_closure
+
+foreign import ccall "size_of_ffi_type" size_of_ffi_type
+    :: CInt
+
+foreign import ccall "hs2c_ffi_type" hs2c_ffi_type
+    :: Ptr Ffi_type -> CSize -> CUShort -> CUShort ->
+       Ptr (Ptr Ffi_type) -> IO ()
+
+foreign import ccall "c2hs_ffi_type" c2hs_ffi_type
+    :: Ptr Ffi_type -> Ptr CSize -> Ptr CUShort -> Ptr CUShort ->
+       Ptr (Ptr (Ptr Ffi_type)) -> IO ()
+
diff --git a/src/constants.c b/src/constants.c
new file mode 100644
--- /dev/null
+++ b/src/constants.c
@@ -0,0 +1,131 @@
+#include <ffi.h>
+
+ffi_type *_ffi_type_uchar (void)
+{
+  return &ffi_type_uchar;
+}
+
+ffi_type *_ffi_type_schar (void)
+{
+  return &ffi_type_schar;
+}
+
+ffi_type *_ffi_type_ushort (void)
+{
+  return &ffi_type_ushort;
+}
+
+ffi_type *_ffi_type_sshort (void)
+{
+  return &ffi_type_sshort;
+}
+
+ffi_type *_ffi_type_uint (void)
+{
+  return &ffi_type_uint;
+}
+
+ffi_type *_ffi_type_sint (void)
+{
+  return &ffi_type_sint;
+}
+
+ffi_type *_ffi_type_ulong (void)
+{
+  return &ffi_type_ulong;
+}
+
+ffi_type *_ffi_type_slong (void)
+{
+  return &ffi_type_slong;
+}
+
+ffi_type *_ffi_type_void (void)
+{
+  return &ffi_type_void;
+}
+
+ffi_type *_ffi_type_uint8 (void)
+{
+  return &ffi_type_uint8;
+}
+
+ffi_type *_ffi_type_sint8 (void)
+{
+  return &ffi_type_sint8;
+}
+
+ffi_type *_ffi_type_uint16 (void)
+{
+  return &ffi_type_uint16;
+}
+
+ffi_type *_ffi_type_sint16 (void)
+{
+  return &ffi_type_sint16;
+}
+
+ffi_type *_ffi_type_uint32 (void)
+{
+  return &ffi_type_uint32;
+}
+
+ffi_type *_ffi_type_sint32 (void)
+{
+  return &ffi_type_sint32;
+}
+
+ffi_type *_ffi_type_uint64 (void)
+{
+  return &ffi_type_uint64;
+}
+
+ffi_type *_ffi_type_sint64 (void)
+{
+  return &ffi_type_sint64;
+}
+
+ffi_type *_ffi_type_float (void)
+{
+  return &ffi_type_float;
+}
+
+ffi_type *_ffi_type_double (void)
+{
+  return &ffi_type_double;
+}
+
+ffi_type *_ffi_type_pointer (void)
+{
+  return &ffi_type_pointer;
+}
+
+ffi_status _FFI_OK (void)
+{
+  return FFI_OK;
+}
+
+ffi_status _FFI_BAD_TYPEDEF (void)
+{
+  return FFI_BAD_TYPEDEF;
+}
+
+ffi_status _FFI_BAD_ABI (void)
+{
+  return FFI_BAD_ABI;
+}
+
+int _FFI_CLOSURES (void)
+{
+  return FFI_CLOSURES;
+}
+
+ffi_abi _FFI_FIRST_ABI (void)
+{
+  return FFI_FIRST_ABI;
+}
+
+ffi_abi _FFI_DEFAULT_ABI (void)
+{
+  return FFI_DEFAULT_ABI;
+}
diff --git a/src/types.c b/src/types.c
new file mode 100644
--- /dev/null
+++ b/src/types.c
@@ -0,0 +1,31 @@
+#include <ffi.h>
+
+int size_of_ffi_type (void)
+{
+    return sizeof (ffi_type);
+}
+
+void hs2c_ffi_type (ffi_type *p,
+    size_t v1,
+    unsigned short v2,
+    unsigned short v3,
+    ffi_type **v4)
+{
+    p->size = v1;
+    p->alignment = v2;
+    p->type = v3;
+    p->elements = v4;
+}
+
+void c2hs_ffi_type (ffi_type *p,
+    size_t *p1,
+    unsigned short *p2,
+    unsigned short *p3,
+    ffi_type ***p4)
+{
+    *p1 = p->size;
+    *p2 = p->alignment;
+    *p3 = p->type;
+    *p4 = p->elements;
+}
+
