This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libffi merge


Merge docs and configury from libffi to cc.  Bump libffi version.

Andrew.

2009-06-08  Andrew Haley  <aph@redhat.com>

	Import from libffi 3.0.8:

	* doc/libffi.texi: New file.
	* doc/libffi.info: Likewise.
	* doc/stamp-vti: Likewise.
	* man/Makefile.am: New file.
	* man/ffi_call.3: New file.

	* Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S,
	src/dlmalloc.c.
	(nodist_libffi_la_SOURCES): Add X86_FREEBSD.

	* configure.ac: Bump version to 3.0.8.
	parisc*-*-linux*: Add.
	i386-*-freebsd* | i386-*-openbsd*: Add.
	powerpc-*-beos*: Add.
	AM_CONDITIONAL X86_FREEBSD: Add.
	AC_CONFIG_FILES: Add man/Makefile.

	* include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void).

2Index: include/ffi.h.in
===================================================================
--- include/ffi.h.in	(revision 148173)
+++ include/ffi.h.in	(working copy)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------*-C-*-
-   libffi @VERSION@ - Copyright (c) 1996-2003, 2007  Red Hat, Inc.
+   libffi @VERSION@ - Copyright (c) 1996-2003, 2007, 2008  Red Hat, Inc.

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -354,7 +354,7 @@
 	      void **avalue);

 /* Useful for eliminating compiler warnings */
-#define FFI_FN(f) ((void (*)())f)
+#define FFI_FN(f) ((void (*)(void))f)

 /* ---- Definitions shared with assembly code ---------------------------- */

Index: configure.ac
===================================================================
--- configure.ac	(revision 148170)
+++ configure.ac	(working copy)
@@ -2,7 +2,7 @@

 AC_PREREQ(2.59)

-AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html])
+AC_INIT([libffi], [3.0.8], [http://gcc.gnu.org/bugs.html])
 AC_CONFIG_HEADERS([fficonfig.h])

 AM_ENABLE_MULTILIB(, ..)
@@ -63,7 +63,7 @@
 	TARGET=FRV; TARGETDIR=frv
 	;;

-  hppa*-*-linux*)
+  hppa*-*-linux* | parisc*-*-linux*)
 	TARGET=PA_LINUX; TARGETDIR=pa
 	;;
   hppa*64-*-hpux*)
@@ -73,6 +73,9 @@
 	TARGET=PA_HPUX; TARGETDIR=pa
 	;;

+  i386-*-freebsd* | i386-*-openbsd*)
+	TARGET=X86_FREEBSD; TARGETDIR=x86
+	;;
   i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
 	TARGET=X86_WIN32; TARGETDIR=x86
 	;;
@@ -105,7 +108,10 @@
 	TARGET=MIPS; TARGETDIR=mips
 	;;

-  powerpc*-*-linux*)
+  powerpc*-*-linux* | powerpc-*-sysv*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-beos*)
 	TARGET=POWERPC; TARGETDIR=powerpc
 	;;
   powerpc-*-darwin*)
@@ -155,6 +161,7 @@
 AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
 AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
 AM_CONDITIONAL(X86, test x$TARGET = xX86)
+AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
 AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
 AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
 AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
@@ -370,6 +377,6 @@

 AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)

-AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile)
+AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile)

 AC_OUTPUT
Index: doc/libffi.texi
===================================================================
--- doc/libffi.texi	(revision 0)
+++ doc/libffi.texi	(revision 0)
@@ -0,0 +1,541 @@
+\input texinfo   @c -*-texinfo-*-
+@c %**start of header
+@setfilename libffi.info
+@settitle libffi
+@setchapternewpage off
+@c %**end of header
+
+@c Merge the standard indexes into a single one.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@include version.texi
+
+@copying
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+Copyright @copyright{} 2008 Red Hat, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.  A copy of the license is included in the
+section entitled ``GNU General Public License''.
+
+@end quotation
+@end copying
+
+@dircategory
+@direntry
+* libffi: (libffi).             Portable foreign-function interface library.
+@end direntry
+
+@titlepage
+@title Libffi
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+
+@ifnottex
+@node Top
+@top libffi
+
+@insertcopying
+
+@menu
+* Introduction::                What is libffi?
+* Using libffi::                How to use libffi.
+* Missing Features::            Things libffi can't do.
+* Index::                       Index.
+@end menu
+
+@end ifnottex
+
+
+@node Introduction
+@chapter What is libffi?
+
+Compilers for high level languages generate code that follow certain
+conventions.  These conventions are necessary, in part, for separate
+compilation to work.  One such convention is the @dfn{calling
+convention}.  The calling convention is a set of assumptions made by
+the compiler about where function arguments will be found on entry to
+a function.  A calling convention also specifies where the return
+value for a function is found.  The calling convention is also
+sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}.
+@cindex calling convention
+@cindex ABI
+@cindex Application Binary Interface
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function.  For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function.  @samp{Libffi} can be used in such programs to
+provide a bridge from the interpreter program to compiled code.
+
+The @samp{libffi} library provides a portable, high level programming
+interface to various calling conventions.  This allows a programmer to
+call any function specified by a call interface description at run
+time.
+
+@acronym{FFI} stands for Foreign Function Interface.  A foreign
+function interface is the popular name for the interface that allows
+code written in one language to call code written in another language.
+The @samp{libffi} library really only provides the lowest, machine
+dependent layer of a fully featured foreign function interface.  A
+layer must exist above @samp{libffi} that handles type conversions for
+values passed between the two languages.
+@cindex FFI
+@cindex Foreign Function Interface
+
+
+@node Using libffi
+@chapter Using libffi
+
+@menu
+* The Basics::                  The basic libffi API.
+* Simple Example::              A simple example.
+* Types::                       libffi type descriptions.
+* Multiple ABIs::               Different passing styles on one platform.
+* The Closure API::             Writing a generic function.
+@end menu
+
+
+@node The Basics
+@section The Basics
+
+@samp{Libffi} assumes that you have a pointer to the function you wish
+to call and that you know the number and types of arguments to pass
+it, as well as the return type of the function.
+
+The first thing you must do is create an @code{ffi_cif} object that
+matches the signature of the function you wish to call.  This is a
+separate step because it is common to make multiple calls using a
+single @code{ffi_cif}.  The @dfn{cif} in @code{ffi_cif} stands for
+Call InterFace.  To prepare a call interface object, use the function
+@code{ffi_prep_cif}.
+@cindex cif
+
+@findex ffi_prep_cif
+@defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
+This initializes @var{cif} according to the given parameters.
+
+@var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what
+you want.  @ref{Multiple ABIs} for more information.
+
+@var{nargs} is the number of arguments that this function accepts.
+@samp{libffi} does not yet handle varargs functions; see @ref{Missing
+Features} for more information.
+
+@var{rtype} is a pointer to an @code{ffi_type} structure that
+describes the return type of the function.  @xref{Types}.
+
+@var{argtypes} is a vector of @code{ffi_type} pointers.
+@var{argtypes} must have @var{nargs} elements.  If @var{nargs} is 0,
+this argument is ignored.
+
+@code{ffi_prep_cif} returns a @code{libffi} status code, of type
+@code{ffi_status}.  This will be either @code{FFI_OK} if everything
+worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type}
+objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter
+is invalid.
+@end defun
+
+
+To call a function using an initialized @code{ffi_cif}, use the
+@code{ffi_call} function:
+
+@findex ffi_call
+@defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues})
+This calls the function @var{fn} according to the description given in
+@var{cif}.  @var{cif} must have already been prepared using
+@code{ffi_prep_cif}.
+
+@var{rvalue} is a pointer to a chunk of memory that will hold the
+result of the function call.  This must be large enough to hold the
+result and must be suitably aligned; it is the caller's responsibility
+to ensure this.  If @var{cif} declares that the function returns
+@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
+ignored.  If @var{rvalue} is @samp{NULL}, then the return value is
+discarded.
+
+@var{avalues} is a vector of @code{void *} pointers that point to the
+memory locations holding the argument values for a call.  If @var{cif}
+declares that the function has no arguments (i.e., @var{nargs} was 0),
+then @var{avalues} is ignored.
+@end defun
+
+
+@node Simple Example
+@section Simple Example
+
+Here is a trivial example that calls @code{puts} a few times.
+
+@example
+#include <stdio.h>
+#include <ffi.h>
+
+int main()
+@{
+  ffi_cif cif;
+  ffi_type *args[1];
+  void *values[1];
+  char *s;
+  int rc;
+
+  /* Initialize the argument info vectors */
+  args[0] = &ffi_type_pointer;
+  values[0] = &s;
+
+  /* Initialize the cif */
+  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+		       &ffi_type_uint, args) == FFI_OK)
+    @{
+      s = "Hello World!";
+      ffi_call(&cif, puts, &rc, values);
+      /* rc now holds the result of the call to puts */
+
+      /* values holds a pointer to the function's arg, so to
+         call puts() again all we need to do is change the
+         value of s */
+      s = "This is cool!";
+      ffi_call(&cif, puts, &rc, values);
+    @}
+
+  return 0;
+@}
+@end example
+
+
+@node Types
+@section Types
+
+@menu
+* Primitive Types::             Built-in types.
+* Structures::                  Structure types.
+* Type Example::                Structure type example.
+@end menu
+
+@node Primitive Types
+@subsection Primitive Types
+
+@code{Libffi} provides a number of built-in type descriptors that can
+be used to describe argument and return types:
+
+@table @code
+@item ffi_type_void
+@tindex ffi_type_void
+The type @code{void}.  This cannot be used for argument types, only
+for return values.
+
+@item ffi_type_uint8
+@tindex ffi_type_uint8
+An unsigned, 8-bit integer type.
+
+@item ffi_type_sint8
+@tindex ffi_type_sint8
+A signed, 8-bit integer type.
+
+@item ffi_type_uint16
+@tindex ffi_type_uint16
+An unsigned, 16-bit integer type.
+
+@item ffi_type_sint16
+@tindex ffi_type_sint16
+A signed, 16-bit integer type.
+
+@item ffi_type_uint32
+@tindex ffi_type_uint32
+An unsigned, 32-bit integer type.
+
+@item ffi_type_sint32
+@tindex ffi_type_sint32
+A signed, 32-bit integer type.
+
+@item ffi_type_uint64
+@tindex ffi_type_uint64
+An unsigned, 64-bit integer type.
+
+@item ffi_type_sint64
+@tindex ffi_type_sint64
+A signed, 64-bit integer type.
+
+@item ffi_type_float
+@tindex ffi_type_float
+The C @code{float} type.
+
+@item ffi_type_double
+@tindex ffi_type_double
+The C @code{double} type.
+
+@item ffi_type_uchar
+@tindex ffi_type_uchar
+The C @code{unsigned char} type.
+
+@item ffi_type_schar
+@tindex ffi_type_schar
+The C @code{signed char} type.  (Note that there is not an exact
+equivalent to the C @code{char} type in @code{libffi}; ordinarily you
+should either use @code{ffi_type_schar} or @code{ffi_type_uchar}
+depending on whether @code{char} is signed.)
+
+@item ffi_type_ushort
+@tindex ffi_type_ushort
+The C @code{unsigned short} type.
+
+@item ffi_type_sshort
+@tindex ffi_type_sshort
+The C @code{short} type.
+
+@item ffi_type_uint
+@tindex ffi_type_uint
+The C @code{unsigned int} type.
+
+@item ffi_type_sint
+@tindex ffi_type_sint
+The C @code{int} type.
+
+@item ffi_type_ulong
+@tindex ffi_type_ulong
+The C @code{unsigned long} type.
+
+@item ffi_type_slong
+@tindex ffi_type_slong
+The C @code{long} type.
+
+@item ffi_type_longdouble
+@tindex ffi_type_longdouble
+On platforms that have a C @code{long double} type, this is defined.
+On other platforms, it is not.
+
+@item ffi_type_pointer
+@tindex ffi_type_pointer
+A generic @code{void *} pointer.  You should use this for all
+pointers, regardless of their real type.
+@end table
+
+Each of these is of type @code{ffi_type}, so you must take the address
+when passing to @code{ffi_prep_cif}.
+
+
+@node Structures
+@subsection Structures
+
+Although @samp{libffi} has no special support for unions or
+bit-fields, it is perfectly happy passing structures back and forth.
+You must first describe the structure to @samp{libffi} by creating a
+new @code{ffi_type} object for it.
+
+@tindex ffi_type
+@deftp ffi_type
+The @code{ffi_type} has the following members:
+@table @code
+@item size_t size
+This is set by @code{libffi}; you should initialize it to zero.
+
+@item unsigned short alignment
+This is set by @code{libffi}; you should initialize it to zero.
+
+@item unsigned short type
+For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
+
+@item ffi_type **elements
+This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
+objects.  There is one element per field of the struct.
+@end table
+@end deftp
+
+
+@node Type Example
+@subsection Type Example
+
+The following example initializes a @code{ffi_type} object
+representing the @code{tm} struct from Linux's @file{time.h}.
+
+Here is how the struct is defined:
+
+@example
+struct tm @{
+    int tm_sec;
+    int tm_min;
+    int tm_hour;
+    int tm_mday;
+    int tm_mon;
+    int tm_year;
+    int tm_wday;
+    int tm_yday;
+    int tm_isdst;
+    /* Those are for future use. */
+    long int __tm_gmtoff__;
+    __const char *__tm_zone__;
+@};
+@end example
+
+Here is the corresponding code to describe this struct to
+@code{libffi}:
+
+@example
+    @{
+      ffi_type tm_type;
+      ffi_type *tm_type_elements[12];
+      int i;
+
+      tm_type.size = tm_type.alignment = 0;
+      tm_type.elements = &tm_type_elements;
+
+      for (i = 0; i < 9; i++)
+          tm_type_elements[i] = &ffi_type_sint;
+
+      tm_type_elements[9] = &ffi_type_slong;
+      tm_type_elements[10] = &ffi_type_pointer;
+      tm_type_elements[11] = NULL;
+
+      /* tm_type can now be used to represent tm argument types and
+	 return types for ffi_prep_cif() */
+    @}
+@end example
+
+
+@node Multiple ABIs
+@section Multiple ABIs
+
+A given platform may provide multiple different ABIs at once.  For
+instance, the x86 platform has both @samp{stdcall} and @samp{fastcall}
+functions.
+
+@code{libffi} provides some support for this.  However, this is
+necessarily platform-specific.
+
+@c FIXME: document the platforms
+
+@node The Closure API
+@section The Closure API
+
+@code{libffi} also provides a way to write a generic function -- a
+function that can accept and decode any combination of arguments.
+This can be useful when writing an interpreter, or to provide wrappers
+for arbitrary functions.
+
+This facility is called the @dfn{closure API}.  Closures are not
+supported on all platforms; you can check the @code{FFI_CLOSURES}
+define to determine whether they are supported on the current
+platform.
+@cindex closures
+@cindex closure API
+@findex FFI_CLOSURES
+
+Because closures work by assembling a tiny function at runtime, they
+require special allocation on platforms that have a non-executable
+heap.  Memory management for closures is handled by a pair of
+functions:
+
+@findex ffi_closure_alloca
+@defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code})
+Allocate a chunk of memory holding @var{size} bytes.  This returns a
+pointer to the writable address, and sets *@var{code} to the
+corresponding executable address.
+
+@var{size} should be sufficient to hold a @code{ffi_closure} object.
+@end defun
+
+@findex ffi_closure_free
+@defun void ffi_closure_free (void *@var{writable})
+Free memory allocated using @code{ffi_closure_alloc}.  The argument is
+the writable address that was returned.
+@end defun
+
+
+Once you have allocated the memory for a closure, you must construct a
+@code{ffi_cif} describing the function call.  Finally you can prepare
+the closure function:
+
+@findex ffi_prep_closure_loc
+@defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
+Prepare a closure function.
+
+@var{closure} is the address of a @code{ffi_closure} object; this is
+the writable address returned by @code{ffi_closure_alloc}.
+
+@var{cif} is the @code{ffi_cif} describing the function parameters.
+
+@var{user_data} is an arbitrary datum that is passed, uninterpreted,
+to your closure function.
+
+@var{codeloc} is the executable address returned by
+@code{ffi_closure_alloc}.
+
+@var{fun} is the function which will be called when the closure is
+invoked.  It is called with the arguments:
+@table @var
+@item cif
+The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
+
+@item ret
+A pointer to the memory used for the function's return value.
+@var{fun} must fill this, unless the function is declared as returning
+@code{void}.
+@c FIXME: is this NULL for void-returning functions?
+
+@item args
+A vector of pointers to memory holding the arguments to the function.
+
+@item user_data
+The same @var{user_data} that was passed to
+@code{ffi_prep_closure_loc}.
+@end table
+
+@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
+went ok, and something else on error.
+@c FIXME: what?
+
+After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
+to the appropriate pointer-to-function type.
+@end defun
+
+@c FIXME: example
+
+You may see old code referring to @code{ffi_prep_closure}.  This
+function is deprecated, as it cannot handle the need for separate
+writable and executable addresses.
+
+
+@node Missing Features
+@chapter Missing Features
+
+@code{libffi} is missing a few features.  We welcome patches to add
+support for these.
+
+@itemize @bullet
+@item
+There is no support for calling varargs functions.  This may work on
+some platforms, depending on how the ABI is defined, but it is not
+reliable.
+
+@item
+There is no support for bit fields in structures.
+
+@item
+The closure API is
+
+@item
+The ``raw'' API is undocumented.
+@c argument promotion?
+@c unions?
+@c anything else?
+@end itemize
+
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
Index: doc/stamp-vti
===================================================================
--- doc/stamp-vti	(revision 0)
+++ doc/stamp-vti	(revision 0)
@@ -0,0 +1,4 @@
+@set UPDATED 14 February 2008
+@set UPDATED-MONTH February 2008
+@set EDITION 3.0.8
+@set VERSION 3.0.8
Index: doc/libffi.info
===================================================================
--- doc/libffi.info	(revision 0)
+++ doc/libffi.info	(revision 0)
@@ -0,0 +1,533 @@
+This is doc/libffi.info, produced by makeinfo version 4.12 from
+./doc/libffi.texi.
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+   Copyright (C) 2008 Red Hat, Inc.
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2, or
+     (at your option) any later version.  A copy of the license is
+     included in the section entitled "GNU General Public License".
+
+
+INFO-DIR-SECTION
+START-INFO-DIR-ENTRY
+* libffi: (libffi).             Portable foreign-function interface library.
+END-INFO-DIR-ENTRY
+
+
+File: libffi.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+libffi
+******
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+   Copyright (C) 2008 Red Hat, Inc.
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2, or
+     (at your option) any later version.  A copy of the license is
+     included in the section entitled "GNU General Public License".
+
+
+* Menu:
+
+* Introduction::                What is libffi?
+* Using libffi::                How to use libffi.
+* Missing Features::            Things libffi can't do.
+* Index::                       Index.
+
+
+File: libffi.info,  Node: Introduction,  Next: Using libffi,  Prev: Top,  Up: Top
+
+1 What is libffi?
+*****************
+
+Compilers for high level languages generate code that follow certain
+conventions.  These conventions are necessary, in part, for separate
+compilation to work.  One such convention is the "calling convention".
+The calling convention is a set of assumptions made by the compiler
+about where function arguments will be found on entry to a function.  A
+calling convention also specifies where the return value for a function
+is found.  The calling convention is also sometimes called the "ABI" or
+"Application Binary Interface".
+
+   Some programs may not know at the time of compilation what arguments
+are to be passed to a function.  For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call a
+given function.  `Libffi' can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+   The `libffi' library provides a portable, high level programming
+interface to various calling conventions.  This allows a programmer to
+call any function specified by a call interface description at run time.
+
+   FFI stands for Foreign Function Interface.  A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language.  The
+`libffi' library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface.  A layer must
+exist above `libffi' that handles type conversions for values passed
+between the two languages.
+
+
+File: libffi.info,  Node: Using libffi,  Next: Missing Features,  Prev: Introduction,  Up: Top
+
+2 Using libffi
+**************
+
+* Menu:
+
+* The Basics::                  The basic libffi API.
+* Simple Example::              A simple example.
+* Types::                       libffi type descriptions.
+* Multiple ABIs::               Different passing styles on one platform.
+* The Closure API::             Writing a generic function.
+
+
+File: libffi.info,  Node: The Basics,  Next: Simple Example,  Up: Using libffi
+
+2.1 The Basics
+==============
+
+`Libffi' assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it, as
+well as the return type of the function.
+
+   The first thing you must do is create an `ffi_cif' object that
+matches the signature of the function you wish to call.  This is a
+separate step because it is common to make multiple calls using a
+single `ffi_cif'.  The "cif" in `ffi_cif' stands for Call InterFace.
+To prepare a call interface object, use the function `ffi_prep_cif'.
+
+ -- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI,
+          unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES)
+     This initializes CIF according to the given parameters.
+
+     ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you
+     want.  *note Multiple ABIs:: for more information.
+
+     NARGS is the number of arguments that this function accepts.
+     `libffi' does not yet handle varargs functions; see *note Missing
+     Features:: for more information.
+
+     RTYPE is a pointer to an `ffi_type' structure that describes the
+     return type of the function.  *Note Types::.
+
+     ARGTYPES is a vector of `ffi_type' pointers.  ARGTYPES must have
+     NARGS elements.  If NARGS is 0, this argument is ignored.
+
+     `ffi_prep_cif' returns a `libffi' status code, of type
+     `ffi_status'.  This will be either `FFI_OK' if everything worked
+     properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is
+     incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid.
+
+   To call a function using an initialized `ffi_cif', use the
+`ffi_call' function:
+
+ -- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void
+          **AVALUES)
+     This calls the function FN according to the description given in
+     CIF.  CIF must have already been prepared using `ffi_prep_cif'.
+
+     RVALUE is a pointer to a chunk of memory that will hold the result
+     of the function call.  This must be large enough to hold the
+     result and must be suitably aligned; it is the caller's
+     responsibility to ensure this.  If CIF declares that the function
+     returns `void' (using `ffi_type_void'), then RVALUE is ignored.
+     If RVALUE is `NULL', then the return value is discarded.
+
+     AVALUES is a vector of `void *' pointers that point to the memory
+     locations holding the argument values for a call.  If CIF declares
+     that the function has no arguments (i.e., NARGS was 0), then
+     AVALUES is ignored.
+
+
+File: libffi.info,  Node: Simple Example,  Next: Types,  Prev: The Basics,  Up: Using libffi
+
+2.2 Simple Example
+==================
+
+Here is a trivial example that calls `puts' a few times.
+
+     #include <stdio.h>
+     #include <ffi.h>
+
+     int main()
+     {
+       ffi_cif cif;
+       ffi_type *args[1];
+       void *values[1];
+       char *s;
+       int rc;
+
+       /* Initialize the argument info vectors */
+       args[0] = &ffi_type_pointer;
+       values[0] = &s;
+
+       /* Initialize the cif */
+       if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+     		       &ffi_type_uint, args) == FFI_OK)
+         {
+           s = "Hello World!";
+           ffi_call(&cif, puts, &rc, values);
+           /* rc now holds the result of the call to puts */
+
+           /* values holds a pointer to the function's arg, so to
+              call puts() again all we need to do is change the
+              value of s */
+           s = "This is cool!";
+           ffi_call(&cif, puts, &rc, values);
+         }
+
+       return 0;
+     }
+
+
+File: libffi.info,  Node: Types,  Next: Multiple ABIs,  Prev: Simple Example,  Up: Using libffi
+
+2.3 Types
+=========
+
+* Menu:
+
+* Primitive Types::             Built-in types.
+* Structures::                  Structure types.
+* Type Example::                Structure type example.
+
+
+File: libffi.info,  Node: Primitive Types,  Next: Structures,  Up: Types
+
+2.3.1 Primitive Types
+---------------------
+
+`Libffi' provides a number of built-in type descriptors that can be
+used to describe argument and return types:
+
+`ffi_type_void'
+     The type `void'.  This cannot be used for argument types, only for
+     return values.
+
+`ffi_type_uint8'
+     An unsigned, 8-bit integer type.
+
+`ffi_type_sint8'
+     A signed, 8-bit integer type.
+
+`ffi_type_uint16'
+     An unsigned, 16-bit integer type.
+
+`ffi_type_sint16'
+     A signed, 16-bit integer type.
+
+`ffi_type_uint32'
+     An unsigned, 32-bit integer type.
+
+`ffi_type_sint32'
+     A signed, 32-bit integer type.
+
+`ffi_type_uint64'
+     An unsigned, 64-bit integer type.
+
+`ffi_type_sint64'
+     A signed, 64-bit integer type.
+
+`ffi_type_float'
+     The C `float' type.
+
+`ffi_type_double'
+     The C `double' type.
+
+`ffi_type_uchar'
+     The C `unsigned char' type.
+
+`ffi_type_schar'
+     The C `signed char' type.  (Note that there is not an exact
+     equivalent to the C `char' type in `libffi'; ordinarily you should
+     either use `ffi_type_schar' or `ffi_type_uchar' depending on
+     whether `char' is signed.)
+
+`ffi_type_ushort'
+     The C `unsigned short' type.
+
+`ffi_type_sshort'
+     The C `short' type.
+
+`ffi_type_uint'
+     The C `unsigned int' type.
+
+`ffi_type_sint'
+     The C `int' type.
+
+`ffi_type_ulong'
+     The C `unsigned long' type.
+
+`ffi_type_slong'
+     The C `long' type.
+
+`ffi_type_longdouble'
+     On platforms that have a C `long double' type, this is defined.
+     On other platforms, it is not.
+
+`ffi_type_pointer'
+     A generic `void *' pointer.  You should use this for all pointers,
+     regardless of their real type.
+
+   Each of these is of type `ffi_type', so you must take the address
+when passing to `ffi_prep_cif'.
+
+
+File: libffi.info,  Node: Structures,  Next: Type Example,  Prev: Primitive Types,  Up: Types
+
+2.3.2 Structures
+----------------
+
+Although `libffi' has no special support for unions or bit-fields, it
+is perfectly happy passing structures back and forth.  You must first
+describe the structure to `libffi' by creating a new `ffi_type' object
+for it.
+
+ -- ffi_type:
+     The `ffi_type' has the following members:
+    `size_t size'
+          This is set by `libffi'; you should initialize it to zero.
+
+    `unsigned short alignment'
+          This is set by `libffi'; you should initialize it to zero.
+
+    `unsigned short type'
+          For a structure, this should be set to `FFI_TYPE_STRUCT'.
+
+    `ffi_type **elements'
+          This is a `NULL'-terminated array of pointers to `ffi_type'
+          objects.  There is one element per field of the struct.
+
+
+File: libffi.info,  Node: Type Example,  Prev: Structures,  Up: Types
+
+2.3.3 Type Example
+------------------
+
+The following example initializes a `ffi_type' object representing the
+`tm' struct from Linux's `time.h'.
+
+   Here is how the struct is defined:
+
+     struct tm {
+         int tm_sec;
+         int tm_min;
+         int tm_hour;
+         int tm_mday;
+         int tm_mon;
+         int tm_year;
+         int tm_wday;
+         int tm_yday;
+         int tm_isdst;
+         /* Those are for future use. */
+         long int __tm_gmtoff__;
+         __const char *__tm_zone__;
+     };
+
+   Here is the corresponding code to describe this struct to `libffi':
+
+         {
+           ffi_type tm_type;
+           ffi_type *tm_type_elements[12];
+           int i;
+
+           tm_type.size = tm_type.alignment = 0;
+           tm_type.elements = &tm_type_elements;
+
+           for (i = 0; i < 9; i++)
+               tm_type_elements[i] = &ffi_type_sint;
+
+           tm_type_elements[9] = &ffi_type_slong;
+           tm_type_elements[10] = &ffi_type_pointer;
+           tm_type_elements[11] = NULL;
+
+           /* tm_type can now be used to represent tm argument types and
+     	 return types for ffi_prep_cif() */
+         }
+
+
+File: libffi.info,  Node: Multiple ABIs,  Next: The Closure API,  Prev: Types,  Up: Using libffi
+
+2.4 Multiple ABIs
+=================
+
+A given platform may provide multiple different ABIs at once.  For
+instance, the x86 platform has both `stdcall' and `fastcall' functions.
+
+   `libffi' provides some support for this.  However, this is
+necessarily platform-specific.
+
+
+File: libffi.info,  Node: The Closure API,  Prev: Multiple ABIs,  Up: Using libffi
+
+2.5 The Closure API
+===================
+
+`libffi' also provides a way to write a generic function - a function
+that can accept and decode any combination of arguments.  This can be
+useful when writing an interpreter, or to provide wrappers for
+arbitrary functions.
+
+   This facility is called the "closure API".  Closures are not
+supported on all platforms; you can check the `FFI_CLOSURES' define to
+determine whether they are supported on the current platform.
+
+   Because closures work by assembling a tiny function at runtime, they
+require special allocation on platforms that have a non-executable
+heap.  Memory management for closures is handled by a pair of functions:
+
+ -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE)
+     Allocate a chunk of memory holding SIZE bytes.  This returns a
+     pointer to the writable address, and sets *CODE to the
+     corresponding executable address.
+
+     SIZE should be sufficient to hold a `ffi_closure' object.
+
+ -- Function: void ffi_closure_free (void *WRITABLE)
+     Free memory allocated using `ffi_closure_alloc'.  The argument is
+     the writable address that was returned.
+
+   Once you have allocated the memory for a closure, you must construct
+a `ffi_cif' describing the function call.  Finally you can prepare the
+closure function:
+
+ -- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE,
+          ffi_cif *CIF, void (*FUN) (ffi_cif *CIF, void *RET, void
+          **ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC)
+     Prepare a closure function.
+
+     CLOSURE is the address of a `ffi_closure' object; this is the
+     writable address returned by `ffi_closure_alloc'.
+
+     CIF is the `ffi_cif' describing the function parameters.
+
+     USER_DATA is an arbitrary datum that is passed, uninterpreted, to
+     your closure function.
+
+     CODELOC is the executable address returned by `ffi_closure_alloc'.
+
+     FUN is the function which will be called when the closure is
+     invoked.  It is called with the arguments:
+    CIF
+          The `ffi_cif' passed to `ffi_prep_closure_loc'.
+
+    RET
+          A pointer to the memory used for the function's return value.
+          FUN must fill this, unless the function is declared as
+          returning `void'.
+
+    ARGS
+          A vector of pointers to memory holding the arguments to the
+          function.
+
+    USER_DATA
+          The same USER_DATA that was passed to `ffi_prep_closure_loc'.
+
+     `ffi_prep_closure_loc' will return `FFI_OK' if everything went ok,
+     and something else on error.
+
+     After calling `ffi_prep_closure_loc', you can cast CODELOC to the
+     appropriate pointer-to-function type.
+
+   You may see old code referring to `ffi_prep_closure'.  This function
+is deprecated, as it cannot handle the need for separate writable and
+executable addresses.
+
+
+File: libffi.info,  Node: Missing Features,  Next: Index,  Prev: Using libffi,  Up: Top
+
+3 Missing Features
+******************
+
+`libffi' is missing a few features.  We welcome patches to add support
+for these.
+
+   * There is no support for calling varargs functions.  This may work
+     on some platforms, depending on how the ABI is defined, but it is
+     not reliable.
+
+   * There is no support for bit fields in structures.
+
+   * The closure API is
+
+   * The "raw" API is undocumented.
+
+
+File: libffi.info,  Node: Index,  Prev: Missing Features,  Up: Top
+
+Index
+*****
+
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]