Initial commit

This commit is contained in:
Anthony Green
2009-10-04 08:11:33 -04:00
commit c6dddbd02b
492 changed files with 157766 additions and 0 deletions

18
.gitignore vendored Normal file
View File

@@ -0,0 +1,18 @@
.libs
.deps
*.o
*.lo
.dirstamp
*.la
Makefile
config.log
config.status
*~
fficonfig.h
include/ffi.h
include/ffitarget.h
libffi.pc
libtool
stamp-h1
libffi*gz
autom4te.cache

5
.svn/dir-prop-base Normal file
View File

@@ -0,0 +1,5 @@
K 10
svn:ignore
V 14
autom4te.cache
END

488
.svn/entries Normal file
View File

@@ -0,0 +1,488 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi
svn://gcc.gnu.org/svn/gcc
2009-09-28T22:26:25.100883Z
152256
ktietz
has-props
138bc75d-0d04-0410-961f-82ee72b054a4
ChangeLog.libgcj
file
2009-04-24T17:46:15.000000Z
fbbc216bc25d759a72ea3e6d734af56b
2004-01-15T03:41:49.000000Z
75901
kcook
1103
configure
file
cd4e90cc5d56f8ef96e9cd66c53aa460
2009-08-22T13:22:20.806489Z
151014
rwild
has-props
LICENSE
file
2009-04-24T17:46:15.000000Z
085f9917800070e791f49bf4733e23fa
2003-10-21T19:01:58.000000Z
72766
andreast
1060
Makefile.in
file
2009-09-10T17:50:58.000000Z
3285bb69fbb854e151b9ce811fdb175e
2009-08-22T13:41:50.702364Z
151015
rwild
58245
include
dir
fficonfig.h.in
file
2009-09-10T17:50:58.000000Z
2e89b398801168fb8a810c6ed80d732d
2009-08-22T13:22:20.806489Z
151014
rwild
4881
ChangeLog
file
2009-09-29T17:13:25.000000Z
470af163ecd8e1e845a906d450abdef5
2009-09-28T22:26:25.100883Z
152256
ktietz
139238
libtool-version
file
2009-04-24T17:46:15.000000Z
fea69bf0c254aa8f860a0b0ed487546d
2004-06-26T20:37:03.000000Z
83717
doko
249
src
dir
testsuite
dir
README
file
2009-06-20T15:53:38.000000Z
9efa71073aa58fdb2c19a776d48572df
2009-06-12T15:57:58.721771Z
148433
aph
10453
configure.host
file
2009-04-24T17:46:15.000000Z
bec544523f8f7f3d5136f67598cf609a
2004-08-30T15:43:03.000000Z
86779
green
267
configure.ac
file
0e7dc11ac340ede683b3c9e65b800432
2009-08-24T19:08:51.161283Z
151059
rwild
doc
dir
acinclude.m4
file
2009-04-24T17:46:15.000000Z
0ec3418e6c2e6b89c24cffd4322b6368
2004-11-23T04:11:31.000000Z
91073
kcook
3273
Makefile.am
file
3c417dcb90ddc78845c01bbbacbe0c29
2009-08-22T13:41:50.702364Z
151015
rwild
man
dir
ChangeLog.v1
file
2009-04-24T17:46:15.000000Z
d946d2b97454ad50a1dbfbf48923c5be
1999-08-08T13:27:18.000000Z
28593
green
23008
aclocal.m4
file
2009-09-10T17:50:58.000000Z
8ed70e462d8e9ec1a90d35a26bab62fc
2009-08-22T13:22:20.806489Z
151014
rwild
38152
stamp-h.in
file
2009-04-24T17:46:16.000000Z
1ded054093de910d9786c62bc4fe8cc6
1999-08-08T13:27:18.000000Z
28593
green
10

View File

@@ -0,0 +1,5 @@
K 14
svn:executable
V 1
*
END

View File

@@ -0,0 +1,40 @@
2004-01-14 Kelley Cook <kcook@gcc.gnu.org>
* configure.in: Add in AC_PREREQ(2.13)
2003-02-20 Alexandre Oliva <aoliva@redhat.com>
* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
config.status.
* configure: Rebuilt.
2002-01-27 Alexandre Oliva <aoliva@redhat.com>
* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
Remove USE_LIBDIR conditional.
* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
* Makefile.in, configure: Rebuilt.
Mon Aug 9 18:33:38 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* include/Makefile.in: Rebuilt.
* Makefile.in: Rebuilt
* Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native
builds.
Use USE_LIBDIR.
* configure: Rebuilt.
* configure.in (USE_LIBDIR): Define for native builds.
Use lowercase in configure --help explanations.
1999-08-08 Anthony Green <green@cygnus.com>
* include/ffi.h.in (FFI_FN): Remove `...'.
1999-08-08 Anthony Green <green@cygnus.com>
* Makefile.in: Rebuilt.
* Makefile.am (AM_CFLAGS): Compile with -fexceptions.
* src/x86/sysv.S: Add exception handling metadata.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,764 @@
The libffi version 1 ChangeLog archive.
Version 1 of libffi had per-directory ChangeLogs. Current and future
versions have a single ChangeLog file in the root directory. The
version 1 ChangeLogs have all been concatonated into this file for
future reference only.
--- libffi ----------------------------------------------------------------
Mon Oct 5 02:17:50 1998 Anthony Green <green@cygnus.com>
* configure.in: Boosted rev.
* configure, Makefile.in, aclocal.m4: Rebuilt.
* README: Boosted rev and updated release notes.
Mon Oct 5 01:03:03 1998 Anthony Green <green@cygnus.com>
* configure.in: Boosted rev.
* configure, Makefile.in, aclocal.m4: Rebuilt.
* README: Boosted rev and updated release notes.
1998-07-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags.
Correctly handle small structures.
(ffi_prep_args): Also handle small structures.
(ffi_call): Pass size of return type to ffi_call_SYSV.
* m68k/sysv.S: Adjust for above changes. Correctly align small
structures in the return value.
* types.c (uint64, sint64) [M68K]: Change alignment to 4.
Fri Apr 17 17:26:58 1998 Anthony Green <green@hoser.cygnus.com>
* configure.in: Boosted rev.
* configure,Makefile.in,aclocal.m4: Rebuilt.
* README: Boosted rev and added release notes.
Sun Feb 22 00:50:41 1998 Geoff Keating <geoffk@ozemail.com.au>
* configure.in: Add PowerPC config bits.
1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* configure.in: Add m68k config bits. Change AC_CANONICAL_SYSTEM
to AC_CANONICAL_HOST, this is not a compiler. Use $host instead
of $target. Remove AC_CHECK_SIZEOF(char), we already know the
result. Fix argument of AC_ARG_ENABLE.
* configure, fficonfig.h.in: Rebuilt.
Tue Feb 10 20:53:40 1998 Richard Henderson <rth@cygnus.com>
* configure.in: Add Alpha config bits.
Tue May 13 13:39:20 1997 Anthony Green <green@hoser.cygnus.com>
* README: Updated dates and reworded Irix comments.
* configure.in: Removed AC_PROG_RANLIB.
* Makefile.in, aclocal.m4, config.guess, config.sub, configure,
ltmain.sh, */Makefile.in: libtoolized again and rebuilt with
automake and autoconf.
Sat May 10 18:44:50 1997 Tom Tromey <tromey@cygnus.com>
* configure, aclocal.m4: Rebuilt.
* configure.in: Don't compute EXTRADIST; now handled in
src/Makefile.in. Removed macros implied by AM_INIT_AUTOMAKE.
Don't run AM_MAINTAINER_MODE.
Thu May 8 14:34:05 1997 Anthony Green <green@hoser.cygnus.com>
* missing, ltmain.sh, ltconfig.sh: Created. These are new files
required by automake and libtool.
* README: Boosted rev to 1.14. Added notes.
* acconfig.h: Moved PACKAGE and VERSION for new automake.
* configure.in: Changes for libtool.
* Makefile.am (check): make test now make check. Uses libtool now.
* Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt.
Thu May 1 16:27:07 1997 Anthony Green <green@hoser.cygnus.com>
* missing: Added file required by new automake.
Tue Nov 26 14:10:42 1996 Anthony Green <green@csk3.cygnus.com>
* acconfig.h: Added USING_PURIFY flag. This is defined when
--enable-purify-safety was used at configure time.
* configure.in (allsources): Added --enable-purify-safety switch.
(VERSION): Boosted rev to 1.13.
* configure: Rebuilt.
Fri Nov 22 06:46:12 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in (VERSION): Boosted rev to 1.12.
Removed special CFLAGS hack for gcc.
* configure: Rebuilt.
* README: Boosted rev to 1.12. Added notes.
* Many files: Cygnus Support changed to Cygnus Solutions.
Wed Oct 30 11:15:25 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in (VERSION): Boosted rev to 1.11.
* configure: Rebuilt.
* README: Boosted rev to 1.11. Added notes about GNU make.
Tue Oct 29 12:25:12 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in: Fixed -Wall trick.
(VERSION): Boosted rev.
* configure: Rebuilt
* acconfig.h: Needed for --enable-debug configure switch.
* README: Boosted rev to 1.09. Added more notes on building
libffi, and LCLint.
* configure.in: Added --enable-debug switch. Boosted rev to
1.09.
* configure: Rebuilt
Tue Oct 15 13:11:28 1996 Anthony Green <green@hoser.cygnus.com>
* configure.in (VERSION): Boosted rev to 1.08
* configure: Rebuilt.
* README: Added n32 bug fix notes.
* Makefile.am: Added "make lint" production.
* Makefile.in: Rebuilt.
Mon Oct 14 10:54:46 1996 Anthony Green <green@rtl.cygnus.com>
* README: Added web page reference.
* configure.in, README: Boosted rev to 1.05
* configure: Rebuilt.
* README: Fixed n32 sample code.
Fri Oct 11 17:09:28 1996 Anthony Green <green@rtl.cygnus.com>
* README: Added sparc notes.
* configure.in, README: Boosted rev to 1.04.
* configure: Rebuilt.
Thu Oct 10 10:31:03 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in, README: Boosted rev to 1.03.
* configure: Rebuilt.
* README: Added struct notes.
* Makefile.am (EXTRA_DIST): Added LICENSE to distribution.
* Makefile.in: Rebuilt.
* README: Removed Linux section. No special notes now
because aggregates arg/return types work.
Wed Oct 9 16:16:42 1996 Anthony Green <green@rtl.cygnus.com>
* README, configure.in (VERSION): Boosted rev to 1.02
* configure: Rebuilt.
Tue Oct 8 11:56:33 1996 Anthony Green <green@rtl.cygnus.com>
* README (NOTE): Added n32 notes.
* Makefile.am: Added test production.
* Makefile: Rebuilt
* README: spell checked!
* configure.in (VERSION): Boosted rev to 1.01
* configure: Rebuilt.
Mon Oct 7 15:50:22 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in: Added nasty bit to support SGI tools.
* configure: Rebuilt.
* README: Added SGI notes. Added note about automake bug.
Mon Oct 7 11:00:28 1996 Anthony Green <green@hoser.cygnus.com>
* README: Rewrote intro, and fixed examples.
Fri Oct 4 10:19:55 1996 Anthony Green <green@hoser.cygnus.com>
* configure.in: -D$TARGET is no longer used as a compiler switch.
It is now inserted into ffi.h at configure time.
* configure: Rebuilt.
* FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status.
Thu Oct 3 13:47:34 1996 Anthony Green <green@hoser.cygnus.com>
* README, LICENSE: Created. Wrote some docs.
* configure.in: Don't barf on i586-unknown-linuxaout.
Added EXTRADIST code for "make dist".
* configure: Rebuilt.
* */Makefile.in: Rebuilt with patched automake.
Tue Oct 1 17:12:25 1996 Anthony Green <green@rtl.cygnus.com>
* Makefile.am, aclocal.m4, config.guess, config.sub,
configure.in, fficonfig.h.in, install-sh, mkinstalldirs,
stamp-h.in: Created
* Makefile.in, configure: Generated
--- libffi/include --------------------------------------------------------
Tue Feb 24 13:09:36 1998 Anthony Green <green@gerbil.cygnus.com>
* ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on
ffi.h.in changes. This is a work-around for SGI's "simple"
assembler.
Sun Feb 22 00:51:55 1998 Geoff Keating <geoffk@ozemail.com.au>
* ffi.h.in: PowerPC support.
1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* ffi.h.in: Add m68k support.
(FFI_TYPE_LONGDOUBLE): Make it a separate value.
Tue Feb 10 20:55:16 1998 Richard Henderson <rth@cygnus.com>
* ffi.h.in (SIZEOF_ARG): Use a pointer type by default.
* ffi.h.in: Alpha support.
Fri Nov 22 06:48:45 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions.
Wed Nov 20 22:31:01 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: Added ffi_type_void definition.
Tue Oct 29 12:22:40 1996 Anthony Green <green@rtl.cygnus.com>
* Makefile.am (hack_DATA): Always install ffi_mips.h.
* ffi.h.in: Removed FFI_DEBUG. It's now in the correct
place (acconfig.h).
Added #include <stddef.h> for size_t definition.
Tue Oct 15 17:23:35 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in, ffi_common.h, ffi_mips.h: More clean up.
Commented out #define of FFI_DEBUG.
Tue Oct 15 13:01:06 1996 Anthony Green <green@rtl.cygnus.com>
* ffi_common.h: Added bool definition.
* ffi.h.in, ffi_common.h: Clean up based on LCLint output.
Added funny /*@...@*/ comments to annotate source.
Mon Oct 14 12:29:23 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in: Interface changes based on feedback from Jim
Blandy.
Fri Oct 11 16:49:35 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in: Small change for sparc support.
Thu Oct 10 14:53:37 1996 Anthony Green <green@rtl.cygnus.com>
* ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for
special structure return types.
Wed Oct 9 13:55:57 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in: Added SIZEOF_ARG definition for X86
Tue Oct 8 11:40:36 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings.
Use it to case your function pointers to the proper type.
* ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug.
* Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST.
* Makefile: Rebuilt.
* ffi_mips.h: Created. Moved all common mips definitions here.
Mon Oct 7 10:58:12 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: The SGI assember is very picky about parens. Redefined
some macros to avoid problems.
* ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added
externs for pointer, and 64bit integral ffi_types.
Fri Oct 4 09:51:37 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: Added FFI_ABI member to ffi_cif and changed
function prototypes accordingly.
Added #define @TARGET@. Now programs including ffi.h don't
have to specify this themselves.
Thu Oct 3 15:36:44 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: Changed ffi_prep_cif's values from void* to void**
* Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist"
to work.
* Makefile.in: Regenerated.
Wed Oct 2 10:16:59 1996 Anthony Green <green@hoser.cygnus.com>
* Makefile.am: Created
* Makefile.in: Generated
* ffi_common.h: Added rcsid comment
Tue Oct 1 17:13:51 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in, ffi_common.h: Created
--- libffi/src ------------------------------------------------------------
Mon Oct 5 02:17:50 1998 Anthony Green <green@cygnus.com>
* arm/ffi.c, arm/sysv.S: Created.
* Makefile.am: Added arm files.
* Makefile.in: Rebuilt.
Mon Oct 5 01:41:38 1998 Anthony Green <green@rtl.cygnus.com>
* Makefile.am (libffi_la_LDFLAGS): Incremented revision.
Sun Oct 4 16:27:17 1998 Anthony Green <green@cygnus.com>
* alpha/osf.S (ffi_call_osf): Patch for DU assembler.
* ffitest.c (main): long long and long double return values work
for x86.
Fri Apr 17 11:50:58 1998 Anthony Green <green@hoser.cygnus.com>
* Makefile.in: Rebuilt.
* ffitest.c (main): Floating point tests not executed for systems
with broken lond double (SunOS 4 w/ GCC).
* types.c: Fixed x86 alignment info for long long types.
Thu Apr 16 07:15:28 1998 Anthony Green <green@ada.cygnus.com>
* ffitest.c: Added more notes about GCC bugs under Irix 6.
Wed Apr 15 08:42:22 1998 Anthony Green <green@hoser.cygnus.com>
* ffitest.c (struct5): New test function.
(main): New test with struct5.
Thu Mar 5 10:48:11 1998 Anthony Green <green@tootie.to.cygnus.com>
* prep_cif.c (initialize_aggregate): Fix assertion for
nested structures.
Tue Feb 24 16:33:41 1998 Anthony Green <green@hoser.cygnus.com>
* prep_cif.c (ffi_prep_cif): Added long double support for sparc.
Sun Feb 22 00:52:18 1998 Geoff Keating <geoffk@ozemail.com.au>
* powerpc/asm.h: New file.
* powerpc/ffi.c: New file.
* powerpc/sysv.S: New file.
* Makefile.am: PowerPC port.
* ffitest.c (main): Allow all tests to run even in presence of gcc
bug on PowerPC.
1998-02-17 Anthony Green <green@hoser.cygnus.com>
* mips/ffi.c: Fixed comment typo.
* x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat):
Fixed x86 long double return handling.
* types.c: Fixed x86 long double alignment info.
1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* types.c: Add m68k support.
* ffitest.c (floating): Add long double parameter.
(return_ll, ldblit): New functions to test long long and long
double return value.
(main): Fix type error in assignment of ts[1-4]_type.elements.
Add tests for long long and long double arguments and return
values.
* prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for
struct value pointer.
* m68k/ffi.c, m68k/sysv.S: New files.
* Makefile.am: Add bits for m68k port. Add kludge to work around
automake deficiency.
(test): Don't require "." in $PATH.
* Makefile.in: Rebuilt.
Wed Feb 11 07:36:50 1998 Anthony Green <green@hoser.cygnus.com>
* Makefile.in: Rebuilt.
Tue Feb 10 20:56:00 1998 Richard Henderson <rth@cygnus.com>
* alpha/ffi.c, alpha/osf.S: New files.
* Makefile.am: Alpha port.
Tue Nov 18 14:12:07 1997 Anthony Green <green@hoser.cygnus.com>
* mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag
for n32.
Tue Jun 3 17:18:20 1997 Anthony Green <green@hoser.cygnus.com>
* ffitest.c (main): Added hack to get structure tests working
correctly.
Sat May 10 19:06:42 1997 Tom Tromey <tromey@cygnus.com>
* Makefile.in: Rebuilt.
* Makefile.am (EXTRA_DIST): Explicitly list all distributable
files in subdirs.
(VERSION, CC): Removed.
Thu May 8 17:19:01 1997 Anthony Green <green@hoser.cygnus.com>
* Makefile.am: Many changes for new automake and libtool.
* Makefile.in: Rebuilt.
Fri Nov 22 06:57:56 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c (main): Fixed test case for non mips machines.
Wed Nov 20 22:31:59 1996 Anthony Green <green@hoser.cygnus.com>
* types.c: Added ffi_type_void declaration.
Tue Oct 29 13:07:19 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c (main): Fixed character constants.
(main): Emit warning for structure test 3 failure on Sun.
* Makefile.am (VPATH): Fixed VPATH def'n so automake won't
strip it out.
Moved distdir hack from libffi to automake.
(ffitest): Added missing -c for $(COMPILE) (change in automake).
* Makefile.in: Rebuilt.
Tue Oct 15 13:08:20 1996 Anthony Green <green@hoser.cygnus.com>
* Makefile.am: Added "make lint" production.
* Makefile.in: Rebuilt.
* prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro.
Clean up based on LCLint output. Added funny /*@...@*/ comments to
annotate source.
* ffitest.c, debug.c: Cleaned up code.
Mon Oct 14 12:26:56 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c: Changes based on interface changes.
* prep_cif.c (ffi_prep_cif): Cleaned up interface based on
feedback from Jim Blandy.
Fri Oct 11 15:53:18 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c: Reordered tests while porting to sparc.
Made changes to handle lame structure passing for sparc.
Removed calls to fflush().
* prep_cif.c (ffi_prep_cif): Added special case for sparc
aggregate type arguments.
Thu Oct 10 09:56:51 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c (main): Added structure passing/returning tests.
* prep_cif.c (ffi_prep_cif): Perform proper initialization
of structure return types if needed.
(initialize_aggregate): Bug fix
Wed Oct 9 16:04:20 1996 Anthony Green <green@rtl.cygnus.com>
* types.c: Added special definitions for x86 (double doesn't
need double word alignment).
* ffitest.c: Added many tests
Tue Oct 8 09:19:22 1996 Anthony Green <green@rtl.cygnus.com>
* prep_cif.c (ffi_prep_cif): Fixed assertion.
* debug.c (ffi_assert): Must return a non void now.
* Makefile.am: Added test production.
* Makefile: Rebuilt.
* ffitest.c (main): Created.
* types.c: Created. Stripped common code out of */ffi.c.
* prep_cif.c: Added missing stdlib.h include.
* debug.c (ffi_type_test): Used "a" to eliminate compiler
warnings in non-debug builds. Included ffi_common.h.
Mon Oct 7 15:36:42 1996 Anthony Green <green@rtl.cygnus.com>
* Makefile.am: Added a rule for .s -> .o
This is required by the SGI compiler.
* Makefile: Rebuilt.
Fri Oct 4 09:51:08 1996 Anthony Green <green@hoser.cygnus.com>
* prep_cif.c (initialize_aggregate): Moved abi specification
to ffi_prep_cif().
Thu Oct 3 15:37:37 1996 Anthony Green <green@hoser.cygnus.com>
* prep_cif.c (ffi_prep_cif): Changed values from void* to void**.
(initialize_aggregate): Fixed aggregate type initialization.
* Makefile.am (EXTRA_DIST): Added support code for "make dist".
* Makefile.in: Regenerated.
Wed Oct 2 11:41:57 1996 Anthony Green <green@hoser.cygnus.com>
* debug.c, prep_cif: Created.
* Makefile.am: Added debug.o and prep_cif.o to OBJ.
* Makefile.in: Regenerated.
* Makefile.am (INCLUDES): Added missing -I../include
* Makefile.in: Regenerated.
Tue Oct 1 17:11:51 1996 Anthony Green <green@rtl.cygnus.com>
* error.c, Makefile.am: Created.
* Makefile.in: Generated.
--- libffi/src/x86 --------------------------------------------------------
Sun Oct 4 16:27:17 1998 Anthony Green <green@cygnus.com>
* sysv.S (retlongdouble): Fixed long long return value support.
* ffi.c (ffi_prep_cif_machdep): Ditto.
Wed May 13 04:30:33 1998 Anthony Green <green@raft.ppp.tsoft.net>
* ffi.c (ffi_prep_cif_machdep): Fixed long double return value
support.
Wed Apr 15 08:43:20 1998 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_prep_args): small struct support was missing.
Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
* objects.mak: Removed.
Mon Dec 2 15:12:58 1996 Tom Tromey <tromey@cygnus.com>
* sysv.S: Use .balign, for a.out Linux boxes.
Tue Oct 15 13:06:50 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c: Clean up based on LCLint output.
Added funny /*@...@*/ comments to annotate source.
Fri Oct 11 16:43:38 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (ffi_call): Added assertion for bad ABIs.
Wed Oct 9 13:57:27 1996 Anthony Green <green@rtl.cygnus.com>
* sysv.S (retdouble): Fixed double return problems.
* ffi.c (ffi_call): Corrected fn arg definition.
(ffi_prep_cif_machdep): Fixed double return problems
Tue Oct 8 12:12:49 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c: Moved ffi_type definitions to types.c.
(ffi_prep_args): Fixed type promotion bug.
Mon Oct 7 15:53:06 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
Fri Oct 4 09:54:53 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
remaining args.
Wed Oct 2 10:07:05 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c, sysv.S, objects.mak: Created.
(ffi_prep_cif): cif->rvalue no longer initialized to NULL.
(ffi_prep_cif_machdep): Moved machine independent cif processing
to src/prep_cif.c. Introduced ffi_prep_cif_machdep().
--- libffi/src/mips -------------------------------------------------------
Tue Feb 17 17:18:07 1998 Anthony Green <green@hoser.cygnus.com>
* o32.S: Fixed typo in comment.
* ffi.c (ffi_prep_cif_machdep): Fixed argument processing.
Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
* o32.s, n32.s: Wrappers for SGI tool support.
* objects.mak: Removed.
Tue Oct 29 14:37:45 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (ffi_prep_args): Changed int z to size_t z.
Tue Oct 15 13:17:25 1996 Anthony Green <green@hoser.cygnus.com>
* n32.S: Fixed bad stack munging.
* ffi.c: Moved prototypes for ffi_call_?32() to here from
ffi_mips.h because extended_cif is not defined in ffi_mips.h.
Mon Oct 14 12:42:02 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c: Interface changes based on feedback from Jim Blandy.
Thu Oct 10 11:22:16 1996 Anthony Green <green@rtl.cygnus.com>
* n32.S, ffi.c: Lots of changes to support passing and
returning structures with the n32 calling convention.
* n32.S: Fixed fn pointer bug.
* ffi.c (ffi_prep_cif_machdep): Fix for o32 structure
return values.
(ffi_prep_args): Fixed n32 structure passing when structures
partially fit in registers.
Wed Oct 9 13:49:25 1996 Anthony Green <green@rtl.cygnus.com>
* objects.mak: Added n32.o.
* n32.S: Created.
* ffi.c (ffi_prep_args): Added magic to support proper
n32 processing.
Tue Oct 8 10:37:35 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c: Moved ffi_type definitions to types.c.
(ffi_prep_args): Fixed type promotion bug.
* o32.S: This code is only built for o32 compiles.
A lot of the #define cruft has moved to ffi_mips.h.
* ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg
is only processed if the first is either a float or double.
Mon Oct 7 15:33:59 1996 Anthony Green <green@rtl.cygnus.com>
* o32.S: Modified to compile under each of o32, n32 and n64.
* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
Fri Oct 4 09:53:25 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
remaining args.
Wed Oct 2 17:41:22 1996 Anthony Green <green@rtl.cygnus.com>
* o32.S: Removed crufty definitions.
Wed Oct 2 12:53:42 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
(ffi_prep_cif_machdep): Moved all machine independent cif processing
to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types
of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT.
Tue Oct 1 17:11:02 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c, o32.S, object.mak: Created
--- libffi/src/sparc ------------------------------------------------------
Tue Feb 24 16:33:18 1998 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_prep_args): Added long double support.
Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
* objects.mak: Removed.
Thu May 1 16:07:56 1997 Anthony Green <green@hoser.cygnus.com>
* v8.S: Fixed minor portability problem reported by
Russ McManus <mcmanr@eq.gs.com>.
Tue Nov 26 14:12:43 1996 Anthony Green <green@csk3.cygnus.com>
* v8.S: Used STACKFRAME define elsewhere.
* ffi.c (ffi_prep_args): Zero out space when USING_PURIFY
is set.
(ffi_prep_cif_machdep): Allocate the correct stack frame
space for functions with < 6 args.
Tue Oct 29 15:08:55 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (ffi_prep_args): int z is now size_t z.
Mon Oct 14 13:31:24 1996 Anthony Green <green@rtl.cygnus.com>
* v8.S (ffi_call_V8): Gordon rewrites this again. It looks
great now.
* ffi.c (ffi_call): The comment about hijacked registers
is no longer valid after gordoni hacked v8.S.
* v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler.
* v8.S, ffi.c: ffi_call() had changed to accept more than
two args, so v8.S had to change (because it hijacks incoming
arg registers).
* ffi.c: Interface changes based on feedback from Jim Blandy.
Thu Oct 10 17:48:16 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c, v8.S, objects.mak: Created.

View File

@@ -0,0 +1,20 @@
libffi - Copyright (c) 1996-2003 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,178 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/ia64/unix.S \
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
src/mips/ffitarget.h \
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
src/powerpc/ffi.c src/powerpc/sysv.S \
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
src/powerpc/ppc_closure.S src/powerpc/asm.h \
src/powerpc/aix.S src/powerpc/darwin.S \
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c src/x86/darwin64.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c
## ################################################################
##
## This section is for make and multilib madness.
##
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
"AR_FLAGS=$(AR_FLAGS)" \
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
"CFLAGS=$(CFLAGS)" \
"CXXFLAGS=$(CXXFLAGS)" \
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
"INSTALL=$(INSTALL)" \
"INSTALL_DATA=$(INSTALL_DATA)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
"JC1FLAGS=$(JC1FLAGS)" \
"LDFLAGS=$(LDFLAGS)" \
"LIBCFLAGS=$(LIBCFLAGS)" \
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
"MAKE=$(MAKE)" \
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
"PICFLAG=$(PICFLAG)" \
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
"SHELL=$(SHELL)" \
"exec_prefix=$(exec_prefix)" \
"infodir=$(infodir)" \
"libdir=$(libdir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
"CC=$(CC)" \
"CXX=$(CXX)" \
"LD=$(LD)" \
"NM=$(NM)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES=
toolexeclib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/closures.c
nodist_libffi_la_SOURCES =
if MIPS
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
endif
if X86
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
endif
if X86_FREEBSD
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
endif
if X86_WIN32
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
endif
if X86_WIN64
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
endif
if X86_DARWIN
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
endif
if SPARC
nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
endif
if ALPHA
nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
endif
if IA64
nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
endif
if M32R
nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
endif
if M68K
nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
endif
if POWERPC
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
endif
if POWERPC_AIX
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
endif
if POWERPC_DARWIN
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
endif
if POWERPC_FREEBSD
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
endif
if ARM
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
endif
if LIBFFI_CRIS
nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
endif
if FRV
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
endif
if S390
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
endif
if X86_64
nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
endif
if SH
nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
endif
if SH64
nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
endif
if PA_LINUX
nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
endif
if PA_HPUX
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
endif
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
AM_CCASFLAGS = $(AM_CPPFLAGS)
# Multilib support. Automake should provide these on its own.
all-recursive: all-multi
install-recursive: install-multi
mostlyclean-recursive: mostlyclean-multi
clean-recursive: clean-multi
distclean-recursive: distclean-multi
maintainer-clean-recursive: maintainer-clean-multi

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,340 @@
This directory contains the libffi package, which is not part of GCC but
shipped with GCC as convenience.
Status
======
libffi-3.0.8 was released on December 19, 2008. Check the libffi web
page for updates: <URL:http://sourceware.org/libffi/>.
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 essentially 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.
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.
Supported Platforms
===================
Libffi has been ported to many different platforms, although this
release was only tested on:
arm oabi linux
arm eabi linux
hppa linux
mips o32 linux (little endian)
powerpc darwin
powerpc freebsd
powerpc64 linux
sparc solaris
sparc64 freebsd
sparc64 solaris
x86 cygwin
x86 darwin
x86 freebsd
x86 linux
x86 openbsd
x86 solaris
x86-64 mingw
x86-64 darwin
x86-64 linux
x86-64 OS X
x86-64 freebsd
x86-64 solaris
Please send additional platform test results to
libffi-discuss@sourceware.org.
Installing libffi
=================
[Note: before actually performing any of these installation steps,
you may wish to read the "Platform Specific Notes" below.]
First you must configure the distribution for your particular
system. Go to the directory you wish to build libffi in and run the
"configure" program found in the root directory of the libffi source
distribution.
You may want to tell configure where to install the libffi library and
header files. To do that, use the --prefix configure switch. Libffi
will install under /usr/local by default.
If you want to enable extra run-time debugging checks use the the
--enable-debug configure switch. This is useful when your program dies
mysteriously while using libffi.
Another useful configure switch is --enable-purify-safety. Using this
will add some extra code which will suppress certain warnings when you
are using Purify with libffi. Only use this switch when using
Purify, as it will slow down the library.
Configure has many other options. Use "configure --help" to see them all.
Once configure has finished, type "make". Note that you must be using
GNU make. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
To ensure that libffi is working as advertised, type "make check".
This will require that you have DejaGNU installed.
To install the library and header files, type "make install".
Platform Specific Notes
=======================
MIPS - Irix 5.3 & 6.x
---------------------
Irix 6.2 and better supports three different calling conventions: o32,
n32 and n64. Currently, libffi only supports both o32 and n32 under
Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
configured for whichever calling convention it was built for.
By default, the configure script will try to build libffi with the GNU
development tools. To build libffi with the SGI development tools, set
the environment variable CC to either "cc -32" or "cc -n32" before
running configure under Irix 6.x (depending on whether you want an o32
or n32 library), or just "cc" for Irix 5.3.
With the n32 calling convention, when returning structures smaller
than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
Here's one way of forcing this:
double struct_storage[2];
my_small_struct *s = (my_small_struct *) struct_storage;
/* Use s for RVALUE */
If you don't do this you are liable to get spurious bus errors.
"long long" values are not supported yet.
You must use GNU Make to build libffi on SGI platforms.
PowerPC System V ABI
--------------------
There are two `System V ABI's which libffi implements for PowerPC.
They differ only in how small structures are returned from functions.
In the FFI_SYSV version, structures that are 8 bytes or smaller are
returned in registers. This is what GCC does when it is configured
for solaris, and is what the System V ABI I have (dated September
1995) says.
In the FFI_GCC_SYSV version, all structures are returned the same way:
by passing a pointer as the first argument to the function. This is
what GCC does when it is configured for linux or a generic sysv
target.
EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
inconsistency with the SysV ABI: When a procedure is called with many
floating-point arguments, some of them get put on the stack. They are
all supposed to be stored in double-precision format, even if they are
only single-precision, but EGCS stores single-precision arguments as
single-precision anyway. This causes one test to fail (the `many
arguments' test).
History
=======
3.0.7 Nov-11-08
Fix for ppc FreeBSD.
(thanks to Andreas Tobler)
3.0.6 Jul-17-08
Fix for closures on sh.
Mark the sh/sh64 stack as non-executable.
(both thanks to Kaz Kojima)
3.0.5 Apr-3-08
Fix libffi.pc file.
Fix #define ARM for IcedTea users.
Fix x86 closure bug.
3.0.4 Feb-24-08
Fix x86 OpenBSD configury.
3.0.3 Feb-22-08
Enable x86 OpenBSD thanks to Thomas Heller, and
x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
Clean up test instruction in README.
3.0.2 Feb-21-08
Improved x86 FreeBSD support.
Thanks to Björn König.
3.0.1 Feb-15-08
Fix instruction cache flushing bug on MIPS.
Thanks to David Daney.
3.0.0 Feb-15-08
Many changes, mostly thanks to the GCC project.
Cygnus Solutions is now Red Hat.
[10 years go by...]
1.20 Oct-5-98
Raffaele Sena produces ARM port.
1.19 Oct-5-98
Fixed x86 long double and long long return support.
m68k bug fixes from Andreas Schwab.
Patch for DU assembler compatibility for the Alpha from Richard
Henderson.
1.18 Apr-17-98
Bug fixes and MIPS configuration changes.
1.17 Feb-24-98
Bug fixes and m68k port from Andreas Schwab. PowerPC port from
Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
1.16 Feb-11-98
Richard Henderson produces Alpha port.
1.15 Dec-4-97
Fixed an n32 ABI bug. New libtool, auto* support.
1.14 May-13-97
libtool is now used to generate shared and static libraries.
Fixed a minor portability problem reported by Russ McManus
<mcmanr@eq.gs.com>.
1.13 Dec-2-96
Added --enable-purify-safety to keep Purify from complaining
about certain low level code.
Sparc fix for calling functions with < 6 args.
Linux x86 a.out fix.
1.12 Nov-22-96
Added missing ffi_type_void, needed for supporting void return
types. Fixed test case for non MIPS machines. Cygnus Support
is now Cygnus Solutions.
1.11 Oct-30-96
Added notes about GNU make.
1.10 Oct-29-96
Added configuration fix for non GNU compilers.
1.09 Oct-29-96
Added --enable-debug configure switch. Clean-ups based on LCLint
feedback. ffi_mips.h is always installed. Many configuration
fixes. Fixed ffitest.c for sparc builds.
1.08 Oct-15-96
Fixed n32 problem. Many clean-ups.
1.07 Oct-14-96
Gordon Irlam rewrites v8.S again. Bug fixes.
1.06 Oct-14-96
Gordon Irlam improved the sparc port.
1.05 Oct-14-96
Interface changes based on feedback.
1.04 Oct-11-96
Sparc port complete (modulo struct passing bug).
1.03 Oct-10-96
Passing struct args, and returning struct values works for
all architectures/calling conventions. Expanded tests.
1.02 Oct-9-96
Added SGI n32 support. Fixed bugs in both o32 and Linux support.
Added "make test".
1.01 Oct-8-96
Fixed float passing bug in mips version. Restructured some
of the code. Builds cleanly with SGI tools.
1.00 Oct-7-96
First release. No public announcement.
Authors & Credits
=================
libffi was originally written by Anthony Green <green@redhat.com>.
The developers of the GNU Compiler Collection project have made
innumerable valuable contributions. See the ChangeLog file for
details.
Some of the ideas behind libffi were inspired by Gianni Mariani's free
gencall library for Silicon Graphics machines.
The closure mechanism was designed and implemented by Kresten Krab
Thorup.
Major processor architecture ports were contributed by the following
developers:
alpha Richard Henderson
arm Raffaele Sena
cris Simon Posnjak, Hans-Peter Nilsson
frv Anthony Green
ia64 Hans Boehm
m32r Kazuhiro Inaoka
m68k Andreas Schwab
mips Anthony Green, Casey Marshall
mips64 David Daney
pa Randolph Chung, Dave Anglin, Andreas Tobler
powerpc Geoffrey Keating, Andreas Tobler,
David Edelsohn, John Hornkvist
powerpc64 Jakub Jelinek
s390 Gerhard Tonn, Ulrich Weigand
sh Kaz Kojima
sh64 Kaz Kojima
sparc Anthony Green, Gordon Irlam
x86 Anthony Green, Jon Beniston
x86-64 Bo Thorsen
Jesper Skov and Andrew Haley both did more than their fair share of
stepping through the code and tracking down bugs.
Thanks also to Tom Tromey for bug fixes, documentation and
configuration help.
Thanks to Jim Blandy, who provided some useful feedback on the libffi
interface.
Andreas Tobler has done a tremendous amount of work on the testsuite.
Alex Oliva solved the executable page problem for SElinux.
The list above is almost certainly incomplete and inaccurate. I'm
happy to make corrections or additions upon request.
If you have a problem, or have found a bug, please send a note to
green@redhat.com.

View File

@@ -0,0 +1,92 @@
# mmap(2) blacklisting. Some platforms provide the mmap library routine
# but don't support all of the features we need from it.
AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
[
AC_CHECK_HEADER([sys/mman.h],
[libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
if test "$libffi_header_sys_mman_h" != yes \
|| test "$libffi_func_mmap" != yes; then
ac_cv_func_mmap_file=no
ac_cv_func_mmap_dev_zero=no
ac_cv_func_mmap_anon=no
else
AC_CACHE_CHECK([whether read-only mmap of a plain file works],
ac_cv_func_mmap_file,
[# Add a system to this blacklist if
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
# memory area containing the same data that you'd get if you applied
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
vms* | ultrix*)
ac_cv_func_mmap_file=no ;;
*)
ac_cv_func_mmap_file=yes;;
esac])
AC_CACHE_CHECK([whether mmap from /dev/zero works],
ac_cv_func_mmap_dev_zero,
[# Add a system to this blacklist if it has mmap() but /dev/zero
# does not exist, or if mmapping /dev/zero does not give anonymous
# zeroed pages with both the following properties:
# 1. If you map N consecutive pages in with one call, and then
# unmap any subset of those pages, the pages that were not
# explicitly unmapped remain accessible.
# 2. If you map two adjacent blocks of memory and then unmap them
# both at once, they must both go away.
# Systems known to be in this category are Windows (all variants),
# VMS, and Darwin.
case "$host_os" in
vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
ac_cv_func_mmap_dev_zero=no ;;
*)
ac_cv_func_mmap_dev_zero=yes;;
esac])
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
[AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
],
[int n = MAP_ANONYMOUS;],
ac_cv_decl_map_anon=yes,
ac_cv_decl_map_anon=no)])
if test $ac_cv_decl_map_anon = no; then
ac_cv_func_mmap_anon=no
else
AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
ac_cv_func_mmap_anon,
[# Add a system to this blacklist if it has mmap() and MAP_ANON or
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
# doesn't give anonymous zeroed pages with the same properties listed
# above for use of /dev/zero.
# Systems known to be in this category are Windows, VMS, and SCO Unix.
case "$host_os" in
vms* | cygwin* | pe | mingw* | sco* | udk* )
ac_cv_func_mmap_anon=no ;;
*)
ac_cv_func_mmap_anon=yes;;
esac])
fi
fi
if test $ac_cv_func_mmap_file = yes; then
AC_DEFINE(HAVE_MMAP_FILE, 1,
[Define if read-only mmap of a plain file works.])
fi
if test $ac_cv_func_mmap_dev_zero = yes; then
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
[Define if mmap of /dev/zero works.])
fi
if test $ac_cv_func_mmap_anon = yes; then
AC_DEFINE(HAVE_MMAP_ANON, 1,
[Define if mmap with MAP_ANON(YMOUS) works.])
fi
])

1037
.svn/text-base/aclocal.m4.svn-base vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,386 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.64)
AC_INIT([libffi], [3.0.8], [http://gcc.gnu.org/bugs.html])
AC_CONFIG_HEADERS([fficonfig.h])
AM_ENABLE_MULTILIB(, ..)
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AM_INIT_AUTOMAKE
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AM_MAINTAINER_MODE
AC_CHECK_HEADERS(sys/mman.h)
AC_CHECK_FUNCS(mmap)
AC_FUNC_MMAP_BLACKLIST
dnl The -no-testsuite modules omit the test subdir.
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
TARGETDIR="unknown"
case "$host" in
alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
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
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS; TARGETDIR=mips
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[[34]]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
if test $TARGETDIR = unknown; then
AC_MSG_ERROR(["libffi has not been ported to $host."])
fi
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_WIN64, test x$TARGET = xX86_WIN64)
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
AM_CONDITIONAL(SH, test x$TARGET = xSH)
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
AC_HEADER_STDC
AC_CHECK_FUNCS(memcpy)
AC_FUNC_ALLOCA
AC_CHECK_SIZEOF(double)
AC_CHECK_SIZEOF(long double)
# Also AC_SUBST this variable for ffi.h.
if test -z "$HAVE_LONG_DOUBLE"; then
HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
if test $ac_cv_sizeof_long_double != 0; then
HAVE_LONG_DOUBLE=1
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
fi
fi
fi
AC_SUBST(HAVE_LONG_DOUBLE)
AC_C_BIGENDIAN
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
libffi_cv_as_cfi_pseudo_op, [
libffi_cv_as_cfi_pseudo_op=unknown
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
[libffi_cv_as_cfi_pseudo_op=yes],
[libffi_cv_as_cfi_pseudo_op=no])
])
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
[Define if your assembler supports .cfi_* directives.])
fi
if test x$TARGET = xSPARC; then
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
libffi_cv_as_sparc_ua_pcrel, [
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
CFLAGS="$CFLAGS -fpic"
LDFLAGS="$LDFLAGS -shared"
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
[libffi_cv_as_sparc_ua_pcrel=yes],
[libffi_cv_as_sparc_ua_pcrel=no])
CFLAGS="$save_CFLAGS"
LDFLAGS="$save_LDFLAGS"])
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
[Define if your assembler and linker support unaligned PC relative relocs.])
fi
AC_CACHE_CHECK([assembler .register pseudo-op support],
libffi_cv_as_register_pseudo_op, [
libffi_cv_as_register_pseudo_op=unknown
# Check if we have .register
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
[libffi_cv_as_register_pseudo_op=yes],
[libffi_cv_as_register_pseudo_op=no])
])
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
[Define if your assembler supports .register.])
fi
fi
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports pc related relocs],
libffi_cv_as_x86_pcrel, [
libffi_cv_as_x86_pcrel=yes
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_pcrel=no
fi
])
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
[Define if your assembler supports PC relative relocs.])
fi
fi
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
libffi_cv_ro_eh_frame, [
libffi_cv_ro_eh_frame=no
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
libffi_cv_ro_eh_frame=yes
elif grep '.section.*eh_frame.*#alloc' conftest.c \
| grep -v '#write' > /dev/null; then
libffi_cv_ro_eh_frame=yes
fi
fi
rm -f conftest.*
])
if test "x$libffi_cv_ro_eh_frame" = xyes; then
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
[Define if .eh_frame sections should be read-only.])
AC_DEFINE(EH_FRAME_FLAGS, "a",
[Define to the flags needed for the .section .eh_frame directive.])
else
AC_DEFINE(EH_FRAME_FLAGS, "aw",
[Define to the flags needed for the .section .eh_frame directive.])
fi
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
libffi_cv_hidden_visibility_attribute, [
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
libffi_cv_hidden_visibility_attribute=no
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
if grep '\.hidden.*foo' conftest.s >/dev/null; then
libffi_cv_hidden_visibility_attribute=yes
fi
fi
rm -f conftest.*
])
if test $libffi_cv_hidden_visibility_attribute = yes; then
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
[Define if __attribute__((visibility("hidden"))) is supported.])
fi
AH_BOTTOM([
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name) .hidden name
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
])
AC_SUBST(TARGET)
AC_SUBST(TARGETDIR)
AC_SUBST(SHELL)
AC_ARG_ENABLE(debug,
[ --enable-debug debugging mode],
if test "$enable_debug" = "yes"; then
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
fi)
AC_ARG_ENABLE(structs,
[ --disable-structs omit code for struct support],
if test "$enable_structs" = "no"; then
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
fi)
AC_ARG_ENABLE(raw-api,
[ --disable-raw-api make the raw api unavailable],
if test "$enable_raw_api" = "no"; then
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
fi)
AC_ARG_ENABLE(purify-safety,
[ --enable-purify-safety purify-safe mode],
if test "$enable_purify_safety" = "yes"; then
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
fi)
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
toolexecdir='$(exec_prefix)/$(target_alias)'
toolexeclibdir='$(toolexecdir)/lib'
else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
multi_os_directory=`$CC -print-multi-os-directory`
case $multi_os_directory in
.) ;; # Avoid trailing /.
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
esac
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
multilib_arg=
fi
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
AC_CONFIG_COMMANDS(src, [
test -d src || mkdir src
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
], [TARGETDIR="$TARGETDIR"])
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile)
AC_OUTPUT

View File

@@ -0,0 +1,11 @@
# configure.host
#
# This shell script handles all host based configuration for libffi.
#
# THIS TABLE IS SORTED. KEEP IT THAT WAY.
case "${host}" in
frv*-elf)
LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/
;;
esac

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,181 @@
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to the flags needed for the .section .eh_frame directive. */
#undef EH_FRAME_FLAGS
/* Define this if you want extra debugging. */
#undef FFI_DEBUG
/* Define this is you do not want support for the raw API. */
#undef FFI_NO_RAW_API
/* Define this is you do not want support for aggregate types. */
#undef FFI_NO_STRUCTS
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define if your assembler supports .cfi_* directives. */
#undef HAVE_AS_CFI_PSEUDO_OP
/* Define if your assembler supports .register. */
#undef HAVE_AS_REGISTER_PSEUDO_OP
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
#undef HAVE_AS_SPARC_UA_PCREL
/* Define if your assembler supports PC relative relocs. */
#undef HAVE_AS_X86_PCREL
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if __attribute__((visibility("hidden"))) is supported. */
#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if you have the long double type and it is bigger than a double */
#undef HAVE_LONG_DOUBLE
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define if mmap with MAP_ANON(YMOUS) works. */
#undef HAVE_MMAP_ANON
/* Define if mmap of /dev/zero works. */
#undef HAVE_MMAP_DEV_ZERO
/* Define if read-only mmap of a plain file works. */
#undef HAVE_MMAP_FILE
/* Define if .eh_frame sections should be read-only. */
#undef HAVE_RO_EH_FRAME
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of `double', as computed by sizeof. */
#undef SIZEOF_DOUBLE
/* The size of `long double', as computed by sizeof. */
#undef SIZEOF_LONG_DOUBLE
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define this if you are using Purify and want to suppress spurious messages.
*/
#undef USING_PURIFY
/* Version number of package */
#undef VERSION
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name) .hidden name
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif

View File

@@ -0,0 +1,6 @@
# This file is used to maintain libtool version info for libffi. See
# the libtool manual to understand the meaning of the fields. This is
# a separate file so that version updates don't involve re-running
# automake.
# CURRENT:REVISION:AGE
4:1:0

View File

@@ -0,0 +1 @@
timestamp

182
.svn/tmp/Makefile.am.tmp Normal file
View File

@@ -0,0 +1,182 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/ia64/unix.S \
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
src/mips/ffitarget.h \
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
src/powerpc/ffi.c src/powerpc/sysv.S \
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
src/powerpc/ppc_closure.S src/powerpc/asm.h \
src/powerpc/aix.S src/powerpc/darwin.S \
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c src/x86/darwin64.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \
src/moxie/ffi.c src/moxie/eabi.S
## ################################################################
##
## This section is for make and multilib madness.
##
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
"AR_FLAGS=$(AR_FLAGS)" \
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
"CFLAGS=$(CFLAGS)" \
"CXXFLAGS=$(CXXFLAGS)" \
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
"INSTALL=$(INSTALL)" \
"INSTALL_DATA=$(INSTALL_DATA)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
"JC1FLAGS=$(JC1FLAGS)" \
"LDFLAGS=$(LDFLAGS)" \
"LIBCFLAGS=$(LIBCFLAGS)" \
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
"MAKE=$(MAKE)" \
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
"PICFLAG=$(PICFLAG)" \
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
"SHELL=$(SHELL)" \
"exec_prefix=$(exec_prefix)" \
"infodir=$(infodir)" \
"libdir=$(libdir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
"CC=$(CC)" \
"CXX=$(CXX)" \
"LD=$(LD)" \
"NM=$(NM)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES=
toolexeclib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/closures.c
nodist_libffi_la_SOURCES =
if MIPS
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
endif
if X86
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
endif
if X86_FREEBSD
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
endif
if X86_WIN32
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
endif
if X86_WIN64
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
endif
if X86_DARWIN
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
endif
if SPARC
nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
endif
if ALPHA
nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
endif
if IA64
nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
endif
if M32R
nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
endif
if M68K
nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
endif
if POWERPC
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
endif
if POWERPC_AIX
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
endif
if POWERPC_DARWIN
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
endif
if POWERPC_FREEBSD
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
endif
if ARM
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
endif
if LIBFFI_CRIS
nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
endif
if FRV
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
endif
if MOXIE
nodist_libffi_la_SOURCES += src/moxie/eabi.S src/moxie/ffi.c
endif
if S390
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
endif
if X86_64
nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
endif
if SH
nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
endif
if SH64
nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
endif
if PA_LINUX
nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
endif
if PA_HPUX
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
endif
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
AM_CCASFLAGS = $(AM_CPPFLAGS)
# Multilib support. Automake should provide these on its own.
all-recursive: all-multi
install-recursive: install-multi
mostlyclean-recursive: mostlyclean-multi
clean-recursive: clean-multi
distclean-recursive: distclean-multi
maintainer-clean-recursive: maintainer-clean-multi

390
.svn/tmp/configure.ac.tmp Normal file
View File

@@ -0,0 +1,390 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.64)
AC_INIT([libffi], [3.0.8], [http://gcc.gnu.org/bugs.html])
AC_CONFIG_HEADERS([fficonfig.h])
AM_ENABLE_MULTILIB(, ..)
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AM_INIT_AUTOMAKE
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AM_MAINTAINER_MODE
AC_CHECK_HEADERS(sys/mman.h)
AC_CHECK_FUNCS(mmap)
AC_FUNC_MMAP_BLACKLIST
dnl The -no-testsuite modules omit the test subdir.
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
TARGETDIR="unknown"
case "$host" in
alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
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
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[[34]]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
if test $TARGETDIR = unknown; then
AC_MSG_ERROR(["libffi has not been ported to $host."])
fi
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_WIN64, test x$TARGET = xX86_WIN64)
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
AM_CONDITIONAL(SH, test x$TARGET = xSH)
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
AC_HEADER_STDC
AC_CHECK_FUNCS(memcpy)
AC_FUNC_ALLOCA
AC_CHECK_SIZEOF(double)
AC_CHECK_SIZEOF(long double)
# Also AC_SUBST this variable for ffi.h.
if test -z "$HAVE_LONG_DOUBLE"; then
HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
if test $ac_cv_sizeof_long_double != 0; then
HAVE_LONG_DOUBLE=1
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
fi
fi
fi
AC_SUBST(HAVE_LONG_DOUBLE)
AC_C_BIGENDIAN
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
libffi_cv_as_cfi_pseudo_op, [
libffi_cv_as_cfi_pseudo_op=unknown
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
[libffi_cv_as_cfi_pseudo_op=yes],
[libffi_cv_as_cfi_pseudo_op=no])
])
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
[Define if your assembler supports .cfi_* directives.])
fi
if test x$TARGET = xSPARC; then
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
libffi_cv_as_sparc_ua_pcrel, [
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
CFLAGS="$CFLAGS -fpic"
LDFLAGS="$LDFLAGS -shared"
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
[libffi_cv_as_sparc_ua_pcrel=yes],
[libffi_cv_as_sparc_ua_pcrel=no])
CFLAGS="$save_CFLAGS"
LDFLAGS="$save_LDFLAGS"])
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
[Define if your assembler and linker support unaligned PC relative relocs.])
fi
AC_CACHE_CHECK([assembler .register pseudo-op support],
libffi_cv_as_register_pseudo_op, [
libffi_cv_as_register_pseudo_op=unknown
# Check if we have .register
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
[libffi_cv_as_register_pseudo_op=yes],
[libffi_cv_as_register_pseudo_op=no])
])
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
[Define if your assembler supports .register.])
fi
fi
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports pc related relocs],
libffi_cv_as_x86_pcrel, [
libffi_cv_as_x86_pcrel=yes
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_pcrel=no
fi
])
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
[Define if your assembler supports PC relative relocs.])
fi
fi
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
libffi_cv_ro_eh_frame, [
libffi_cv_ro_eh_frame=no
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
libffi_cv_ro_eh_frame=yes
elif grep '.section.*eh_frame.*#alloc' conftest.c \
| grep -v '#write' > /dev/null; then
libffi_cv_ro_eh_frame=yes
fi
fi
rm -f conftest.*
])
if test "x$libffi_cv_ro_eh_frame" = xyes; then
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
[Define if .eh_frame sections should be read-only.])
AC_DEFINE(EH_FRAME_FLAGS, "a",
[Define to the flags needed for the .section .eh_frame directive.])
else
AC_DEFINE(EH_FRAME_FLAGS, "aw",
[Define to the flags needed for the .section .eh_frame directive.])
fi
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
libffi_cv_hidden_visibility_attribute, [
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
libffi_cv_hidden_visibility_attribute=no
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
if grep '\.hidden.*foo' conftest.s >/dev/null; then
libffi_cv_hidden_visibility_attribute=yes
fi
fi
rm -f conftest.*
])
if test $libffi_cv_hidden_visibility_attribute = yes; then
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
[Define if __attribute__((visibility("hidden"))) is supported.])
fi
AH_BOTTOM([
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name) .hidden name
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
])
AC_SUBST(TARGET)
AC_SUBST(TARGETDIR)
AC_SUBST(SHELL)
AC_ARG_ENABLE(debug,
[ --enable-debug debugging mode],
if test "$enable_debug" = "yes"; then
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
fi)
AC_ARG_ENABLE(structs,
[ --disable-structs omit code for struct support],
if test "$enable_structs" = "no"; then
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
fi)
AC_ARG_ENABLE(raw-api,
[ --disable-raw-api make the raw api unavailable],
if test "$enable_raw_api" = "no"; then
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
fi)
AC_ARG_ENABLE(purify-safety,
[ --enable-purify-safety purify-safe mode],
if test "$enable_purify_safety" = "yes"; then
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
fi)
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
toolexecdir='$(exec_prefix)/$(target_alias)'
toolexeclibdir='$(toolexecdir)/lib'
else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
multi_os_directory=`$CC -print-multi-os-directory`
case $multi_os_directory in
.) ;; # Avoid trailing /.
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
esac
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
multilib_arg=
fi
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
AC_CONFIG_COMMANDS(src, [
test -d src || mkdir src
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
], [TARGETDIR="$TARGETDIR"])
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile)
AC_OUTPUT

14927
.svn/tmp/configure.tmp Normal file

File diff suppressed because it is too large Load Diff

3878
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

40
ChangeLog.libgcj Normal file
View File

@@ -0,0 +1,40 @@
2004-01-14 Kelley Cook <kcook@gcc.gnu.org>
* configure.in: Add in AC_PREREQ(2.13)
2003-02-20 Alexandre Oliva <aoliva@redhat.com>
* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
config.status.
* configure: Rebuilt.
2002-01-27 Alexandre Oliva <aoliva@redhat.com>
* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
Remove USE_LIBDIR conditional.
* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
* Makefile.in, configure: Rebuilt.
Mon Aug 9 18:33:38 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* include/Makefile.in: Rebuilt.
* Makefile.in: Rebuilt
* Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native
builds.
Use USE_LIBDIR.
* configure: Rebuilt.
* configure.in (USE_LIBDIR): Define for native builds.
Use lowercase in configure --help explanations.
1999-08-08 Anthony Green <green@cygnus.com>
* include/ffi.h.in (FFI_FN): Remove `...'.
1999-08-08 Anthony Green <green@cygnus.com>
* Makefile.in: Rebuilt.
* Makefile.am (AM_CFLAGS): Compile with -fexceptions.
* src/x86/sysv.S: Add exception handling metadata.

764
ChangeLog.v1 Normal file
View File

@@ -0,0 +1,764 @@
The libffi version 1 ChangeLog archive.
Version 1 of libffi had per-directory ChangeLogs. Current and future
versions have a single ChangeLog file in the root directory. The
version 1 ChangeLogs have all been concatonated into this file for
future reference only.
--- libffi ----------------------------------------------------------------
Mon Oct 5 02:17:50 1998 Anthony Green <green@cygnus.com>
* configure.in: Boosted rev.
* configure, Makefile.in, aclocal.m4: Rebuilt.
* README: Boosted rev and updated release notes.
Mon Oct 5 01:03:03 1998 Anthony Green <green@cygnus.com>
* configure.in: Boosted rev.
* configure, Makefile.in, aclocal.m4: Rebuilt.
* README: Boosted rev and updated release notes.
1998-07-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags.
Correctly handle small structures.
(ffi_prep_args): Also handle small structures.
(ffi_call): Pass size of return type to ffi_call_SYSV.
* m68k/sysv.S: Adjust for above changes. Correctly align small
structures in the return value.
* types.c (uint64, sint64) [M68K]: Change alignment to 4.
Fri Apr 17 17:26:58 1998 Anthony Green <green@hoser.cygnus.com>
* configure.in: Boosted rev.
* configure,Makefile.in,aclocal.m4: Rebuilt.
* README: Boosted rev and added release notes.
Sun Feb 22 00:50:41 1998 Geoff Keating <geoffk@ozemail.com.au>
* configure.in: Add PowerPC config bits.
1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* configure.in: Add m68k config bits. Change AC_CANONICAL_SYSTEM
to AC_CANONICAL_HOST, this is not a compiler. Use $host instead
of $target. Remove AC_CHECK_SIZEOF(char), we already know the
result. Fix argument of AC_ARG_ENABLE.
* configure, fficonfig.h.in: Rebuilt.
Tue Feb 10 20:53:40 1998 Richard Henderson <rth@cygnus.com>
* configure.in: Add Alpha config bits.
Tue May 13 13:39:20 1997 Anthony Green <green@hoser.cygnus.com>
* README: Updated dates and reworded Irix comments.
* configure.in: Removed AC_PROG_RANLIB.
* Makefile.in, aclocal.m4, config.guess, config.sub, configure,
ltmain.sh, */Makefile.in: libtoolized again and rebuilt with
automake and autoconf.
Sat May 10 18:44:50 1997 Tom Tromey <tromey@cygnus.com>
* configure, aclocal.m4: Rebuilt.
* configure.in: Don't compute EXTRADIST; now handled in
src/Makefile.in. Removed macros implied by AM_INIT_AUTOMAKE.
Don't run AM_MAINTAINER_MODE.
Thu May 8 14:34:05 1997 Anthony Green <green@hoser.cygnus.com>
* missing, ltmain.sh, ltconfig.sh: Created. These are new files
required by automake and libtool.
* README: Boosted rev to 1.14. Added notes.
* acconfig.h: Moved PACKAGE and VERSION for new automake.
* configure.in: Changes for libtool.
* Makefile.am (check): make test now make check. Uses libtool now.
* Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt.
Thu May 1 16:27:07 1997 Anthony Green <green@hoser.cygnus.com>
* missing: Added file required by new automake.
Tue Nov 26 14:10:42 1996 Anthony Green <green@csk3.cygnus.com>
* acconfig.h: Added USING_PURIFY flag. This is defined when
--enable-purify-safety was used at configure time.
* configure.in (allsources): Added --enable-purify-safety switch.
(VERSION): Boosted rev to 1.13.
* configure: Rebuilt.
Fri Nov 22 06:46:12 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in (VERSION): Boosted rev to 1.12.
Removed special CFLAGS hack for gcc.
* configure: Rebuilt.
* README: Boosted rev to 1.12. Added notes.
* Many files: Cygnus Support changed to Cygnus Solutions.
Wed Oct 30 11:15:25 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in (VERSION): Boosted rev to 1.11.
* configure: Rebuilt.
* README: Boosted rev to 1.11. Added notes about GNU make.
Tue Oct 29 12:25:12 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in: Fixed -Wall trick.
(VERSION): Boosted rev.
* configure: Rebuilt
* acconfig.h: Needed for --enable-debug configure switch.
* README: Boosted rev to 1.09. Added more notes on building
libffi, and LCLint.
* configure.in: Added --enable-debug switch. Boosted rev to
1.09.
* configure: Rebuilt
Tue Oct 15 13:11:28 1996 Anthony Green <green@hoser.cygnus.com>
* configure.in (VERSION): Boosted rev to 1.08
* configure: Rebuilt.
* README: Added n32 bug fix notes.
* Makefile.am: Added "make lint" production.
* Makefile.in: Rebuilt.
Mon Oct 14 10:54:46 1996 Anthony Green <green@rtl.cygnus.com>
* README: Added web page reference.
* configure.in, README: Boosted rev to 1.05
* configure: Rebuilt.
* README: Fixed n32 sample code.
Fri Oct 11 17:09:28 1996 Anthony Green <green@rtl.cygnus.com>
* README: Added sparc notes.
* configure.in, README: Boosted rev to 1.04.
* configure: Rebuilt.
Thu Oct 10 10:31:03 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in, README: Boosted rev to 1.03.
* configure: Rebuilt.
* README: Added struct notes.
* Makefile.am (EXTRA_DIST): Added LICENSE to distribution.
* Makefile.in: Rebuilt.
* README: Removed Linux section. No special notes now
because aggregates arg/return types work.
Wed Oct 9 16:16:42 1996 Anthony Green <green@rtl.cygnus.com>
* README, configure.in (VERSION): Boosted rev to 1.02
* configure: Rebuilt.
Tue Oct 8 11:56:33 1996 Anthony Green <green@rtl.cygnus.com>
* README (NOTE): Added n32 notes.
* Makefile.am: Added test production.
* Makefile: Rebuilt
* README: spell checked!
* configure.in (VERSION): Boosted rev to 1.01
* configure: Rebuilt.
Mon Oct 7 15:50:22 1996 Anthony Green <green@rtl.cygnus.com>
* configure.in: Added nasty bit to support SGI tools.
* configure: Rebuilt.
* README: Added SGI notes. Added note about automake bug.
Mon Oct 7 11:00:28 1996 Anthony Green <green@hoser.cygnus.com>
* README: Rewrote intro, and fixed examples.
Fri Oct 4 10:19:55 1996 Anthony Green <green@hoser.cygnus.com>
* configure.in: -D$TARGET is no longer used as a compiler switch.
It is now inserted into ffi.h at configure time.
* configure: Rebuilt.
* FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status.
Thu Oct 3 13:47:34 1996 Anthony Green <green@hoser.cygnus.com>
* README, LICENSE: Created. Wrote some docs.
* configure.in: Don't barf on i586-unknown-linuxaout.
Added EXTRADIST code for "make dist".
* configure: Rebuilt.
* */Makefile.in: Rebuilt with patched automake.
Tue Oct 1 17:12:25 1996 Anthony Green <green@rtl.cygnus.com>
* Makefile.am, aclocal.m4, config.guess, config.sub,
configure.in, fficonfig.h.in, install-sh, mkinstalldirs,
stamp-h.in: Created
* Makefile.in, configure: Generated
--- libffi/include --------------------------------------------------------
Tue Feb 24 13:09:36 1998 Anthony Green <green@gerbil.cygnus.com>
* ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on
ffi.h.in changes. This is a work-around for SGI's "simple"
assembler.
Sun Feb 22 00:51:55 1998 Geoff Keating <geoffk@ozemail.com.au>
* ffi.h.in: PowerPC support.
1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* ffi.h.in: Add m68k support.
(FFI_TYPE_LONGDOUBLE): Make it a separate value.
Tue Feb 10 20:55:16 1998 Richard Henderson <rth@cygnus.com>
* ffi.h.in (SIZEOF_ARG): Use a pointer type by default.
* ffi.h.in: Alpha support.
Fri Nov 22 06:48:45 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions.
Wed Nov 20 22:31:01 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: Added ffi_type_void definition.
Tue Oct 29 12:22:40 1996 Anthony Green <green@rtl.cygnus.com>
* Makefile.am (hack_DATA): Always install ffi_mips.h.
* ffi.h.in: Removed FFI_DEBUG. It's now in the correct
place (acconfig.h).
Added #include <stddef.h> for size_t definition.
Tue Oct 15 17:23:35 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in, ffi_common.h, ffi_mips.h: More clean up.
Commented out #define of FFI_DEBUG.
Tue Oct 15 13:01:06 1996 Anthony Green <green@rtl.cygnus.com>
* ffi_common.h: Added bool definition.
* ffi.h.in, ffi_common.h: Clean up based on LCLint output.
Added funny /*@...@*/ comments to annotate source.
Mon Oct 14 12:29:23 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in: Interface changes based on feedback from Jim
Blandy.
Fri Oct 11 16:49:35 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in: Small change for sparc support.
Thu Oct 10 14:53:37 1996 Anthony Green <green@rtl.cygnus.com>
* ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for
special structure return types.
Wed Oct 9 13:55:57 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in: Added SIZEOF_ARG definition for X86
Tue Oct 8 11:40:36 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings.
Use it to case your function pointers to the proper type.
* ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug.
* Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST.
* Makefile: Rebuilt.
* ffi_mips.h: Created. Moved all common mips definitions here.
Mon Oct 7 10:58:12 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: The SGI assember is very picky about parens. Redefined
some macros to avoid problems.
* ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added
externs for pointer, and 64bit integral ffi_types.
Fri Oct 4 09:51:37 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: Added FFI_ABI member to ffi_cif and changed
function prototypes accordingly.
Added #define @TARGET@. Now programs including ffi.h don't
have to specify this themselves.
Thu Oct 3 15:36:44 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.h.in: Changed ffi_prep_cif's values from void* to void**
* Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist"
to work.
* Makefile.in: Regenerated.
Wed Oct 2 10:16:59 1996 Anthony Green <green@hoser.cygnus.com>
* Makefile.am: Created
* Makefile.in: Generated
* ffi_common.h: Added rcsid comment
Tue Oct 1 17:13:51 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.h.in, ffi_common.h: Created
--- libffi/src ------------------------------------------------------------
Mon Oct 5 02:17:50 1998 Anthony Green <green@cygnus.com>
* arm/ffi.c, arm/sysv.S: Created.
* Makefile.am: Added arm files.
* Makefile.in: Rebuilt.
Mon Oct 5 01:41:38 1998 Anthony Green <green@rtl.cygnus.com>
* Makefile.am (libffi_la_LDFLAGS): Incremented revision.
Sun Oct 4 16:27:17 1998 Anthony Green <green@cygnus.com>
* alpha/osf.S (ffi_call_osf): Patch for DU assembler.
* ffitest.c (main): long long and long double return values work
for x86.
Fri Apr 17 11:50:58 1998 Anthony Green <green@hoser.cygnus.com>
* Makefile.in: Rebuilt.
* ffitest.c (main): Floating point tests not executed for systems
with broken lond double (SunOS 4 w/ GCC).
* types.c: Fixed x86 alignment info for long long types.
Thu Apr 16 07:15:28 1998 Anthony Green <green@ada.cygnus.com>
* ffitest.c: Added more notes about GCC bugs under Irix 6.
Wed Apr 15 08:42:22 1998 Anthony Green <green@hoser.cygnus.com>
* ffitest.c (struct5): New test function.
(main): New test with struct5.
Thu Mar 5 10:48:11 1998 Anthony Green <green@tootie.to.cygnus.com>
* prep_cif.c (initialize_aggregate): Fix assertion for
nested structures.
Tue Feb 24 16:33:41 1998 Anthony Green <green@hoser.cygnus.com>
* prep_cif.c (ffi_prep_cif): Added long double support for sparc.
Sun Feb 22 00:52:18 1998 Geoff Keating <geoffk@ozemail.com.au>
* powerpc/asm.h: New file.
* powerpc/ffi.c: New file.
* powerpc/sysv.S: New file.
* Makefile.am: PowerPC port.
* ffitest.c (main): Allow all tests to run even in presence of gcc
bug on PowerPC.
1998-02-17 Anthony Green <green@hoser.cygnus.com>
* mips/ffi.c: Fixed comment typo.
* x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat):
Fixed x86 long double return handling.
* types.c: Fixed x86 long double alignment info.
1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* types.c: Add m68k support.
* ffitest.c (floating): Add long double parameter.
(return_ll, ldblit): New functions to test long long and long
double return value.
(main): Fix type error in assignment of ts[1-4]_type.elements.
Add tests for long long and long double arguments and return
values.
* prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for
struct value pointer.
* m68k/ffi.c, m68k/sysv.S: New files.
* Makefile.am: Add bits for m68k port. Add kludge to work around
automake deficiency.
(test): Don't require "." in $PATH.
* Makefile.in: Rebuilt.
Wed Feb 11 07:36:50 1998 Anthony Green <green@hoser.cygnus.com>
* Makefile.in: Rebuilt.
Tue Feb 10 20:56:00 1998 Richard Henderson <rth@cygnus.com>
* alpha/ffi.c, alpha/osf.S: New files.
* Makefile.am: Alpha port.
Tue Nov 18 14:12:07 1997 Anthony Green <green@hoser.cygnus.com>
* mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag
for n32.
Tue Jun 3 17:18:20 1997 Anthony Green <green@hoser.cygnus.com>
* ffitest.c (main): Added hack to get structure tests working
correctly.
Sat May 10 19:06:42 1997 Tom Tromey <tromey@cygnus.com>
* Makefile.in: Rebuilt.
* Makefile.am (EXTRA_DIST): Explicitly list all distributable
files in subdirs.
(VERSION, CC): Removed.
Thu May 8 17:19:01 1997 Anthony Green <green@hoser.cygnus.com>
* Makefile.am: Many changes for new automake and libtool.
* Makefile.in: Rebuilt.
Fri Nov 22 06:57:56 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c (main): Fixed test case for non mips machines.
Wed Nov 20 22:31:59 1996 Anthony Green <green@hoser.cygnus.com>
* types.c: Added ffi_type_void declaration.
Tue Oct 29 13:07:19 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c (main): Fixed character constants.
(main): Emit warning for structure test 3 failure on Sun.
* Makefile.am (VPATH): Fixed VPATH def'n so automake won't
strip it out.
Moved distdir hack from libffi to automake.
(ffitest): Added missing -c for $(COMPILE) (change in automake).
* Makefile.in: Rebuilt.
Tue Oct 15 13:08:20 1996 Anthony Green <green@hoser.cygnus.com>
* Makefile.am: Added "make lint" production.
* Makefile.in: Rebuilt.
* prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro.
Clean up based on LCLint output. Added funny /*@...@*/ comments to
annotate source.
* ffitest.c, debug.c: Cleaned up code.
Mon Oct 14 12:26:56 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c: Changes based on interface changes.
* prep_cif.c (ffi_prep_cif): Cleaned up interface based on
feedback from Jim Blandy.
Fri Oct 11 15:53:18 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c: Reordered tests while porting to sparc.
Made changes to handle lame structure passing for sparc.
Removed calls to fflush().
* prep_cif.c (ffi_prep_cif): Added special case for sparc
aggregate type arguments.
Thu Oct 10 09:56:51 1996 Anthony Green <green@rtl.cygnus.com>
* ffitest.c (main): Added structure passing/returning tests.
* prep_cif.c (ffi_prep_cif): Perform proper initialization
of structure return types if needed.
(initialize_aggregate): Bug fix
Wed Oct 9 16:04:20 1996 Anthony Green <green@rtl.cygnus.com>
* types.c: Added special definitions for x86 (double doesn't
need double word alignment).
* ffitest.c: Added many tests
Tue Oct 8 09:19:22 1996 Anthony Green <green@rtl.cygnus.com>
* prep_cif.c (ffi_prep_cif): Fixed assertion.
* debug.c (ffi_assert): Must return a non void now.
* Makefile.am: Added test production.
* Makefile: Rebuilt.
* ffitest.c (main): Created.
* types.c: Created. Stripped common code out of */ffi.c.
* prep_cif.c: Added missing stdlib.h include.
* debug.c (ffi_type_test): Used "a" to eliminate compiler
warnings in non-debug builds. Included ffi_common.h.
Mon Oct 7 15:36:42 1996 Anthony Green <green@rtl.cygnus.com>
* Makefile.am: Added a rule for .s -> .o
This is required by the SGI compiler.
* Makefile: Rebuilt.
Fri Oct 4 09:51:08 1996 Anthony Green <green@hoser.cygnus.com>
* prep_cif.c (initialize_aggregate): Moved abi specification
to ffi_prep_cif().
Thu Oct 3 15:37:37 1996 Anthony Green <green@hoser.cygnus.com>
* prep_cif.c (ffi_prep_cif): Changed values from void* to void**.
(initialize_aggregate): Fixed aggregate type initialization.
* Makefile.am (EXTRA_DIST): Added support code for "make dist".
* Makefile.in: Regenerated.
Wed Oct 2 11:41:57 1996 Anthony Green <green@hoser.cygnus.com>
* debug.c, prep_cif: Created.
* Makefile.am: Added debug.o and prep_cif.o to OBJ.
* Makefile.in: Regenerated.
* Makefile.am (INCLUDES): Added missing -I../include
* Makefile.in: Regenerated.
Tue Oct 1 17:11:51 1996 Anthony Green <green@rtl.cygnus.com>
* error.c, Makefile.am: Created.
* Makefile.in: Generated.
--- libffi/src/x86 --------------------------------------------------------
Sun Oct 4 16:27:17 1998 Anthony Green <green@cygnus.com>
* sysv.S (retlongdouble): Fixed long long return value support.
* ffi.c (ffi_prep_cif_machdep): Ditto.
Wed May 13 04:30:33 1998 Anthony Green <green@raft.ppp.tsoft.net>
* ffi.c (ffi_prep_cif_machdep): Fixed long double return value
support.
Wed Apr 15 08:43:20 1998 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_prep_args): small struct support was missing.
Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
* objects.mak: Removed.
Mon Dec 2 15:12:58 1996 Tom Tromey <tromey@cygnus.com>
* sysv.S: Use .balign, for a.out Linux boxes.
Tue Oct 15 13:06:50 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c: Clean up based on LCLint output.
Added funny /*@...@*/ comments to annotate source.
Fri Oct 11 16:43:38 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (ffi_call): Added assertion for bad ABIs.
Wed Oct 9 13:57:27 1996 Anthony Green <green@rtl.cygnus.com>
* sysv.S (retdouble): Fixed double return problems.
* ffi.c (ffi_call): Corrected fn arg definition.
(ffi_prep_cif_machdep): Fixed double return problems
Tue Oct 8 12:12:49 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c: Moved ffi_type definitions to types.c.
(ffi_prep_args): Fixed type promotion bug.
Mon Oct 7 15:53:06 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
Fri Oct 4 09:54:53 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
remaining args.
Wed Oct 2 10:07:05 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c, sysv.S, objects.mak: Created.
(ffi_prep_cif): cif->rvalue no longer initialized to NULL.
(ffi_prep_cif_machdep): Moved machine independent cif processing
to src/prep_cif.c. Introduced ffi_prep_cif_machdep().
--- libffi/src/mips -------------------------------------------------------
Tue Feb 17 17:18:07 1998 Anthony Green <green@hoser.cygnus.com>
* o32.S: Fixed typo in comment.
* ffi.c (ffi_prep_cif_machdep): Fixed argument processing.
Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
* o32.s, n32.s: Wrappers for SGI tool support.
* objects.mak: Removed.
Tue Oct 29 14:37:45 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (ffi_prep_args): Changed int z to size_t z.
Tue Oct 15 13:17:25 1996 Anthony Green <green@hoser.cygnus.com>
* n32.S: Fixed bad stack munging.
* ffi.c: Moved prototypes for ffi_call_?32() to here from
ffi_mips.h because extended_cif is not defined in ffi_mips.h.
Mon Oct 14 12:42:02 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c: Interface changes based on feedback from Jim Blandy.
Thu Oct 10 11:22:16 1996 Anthony Green <green@rtl.cygnus.com>
* n32.S, ffi.c: Lots of changes to support passing and
returning structures with the n32 calling convention.
* n32.S: Fixed fn pointer bug.
* ffi.c (ffi_prep_cif_machdep): Fix for o32 structure
return values.
(ffi_prep_args): Fixed n32 structure passing when structures
partially fit in registers.
Wed Oct 9 13:49:25 1996 Anthony Green <green@rtl.cygnus.com>
* objects.mak: Added n32.o.
* n32.S: Created.
* ffi.c (ffi_prep_args): Added magic to support proper
n32 processing.
Tue Oct 8 10:37:35 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c: Moved ffi_type definitions to types.c.
(ffi_prep_args): Fixed type promotion bug.
* o32.S: This code is only built for o32 compiles.
A lot of the #define cruft has moved to ffi_mips.h.
* ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg
is only processed if the first is either a float or double.
Mon Oct 7 15:33:59 1996 Anthony Green <green@rtl.cygnus.com>
* o32.S: Modified to compile under each of o32, n32 and n64.
* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
Fri Oct 4 09:53:25 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
remaining args.
Wed Oct 2 17:41:22 1996 Anthony Green <green@rtl.cygnus.com>
* o32.S: Removed crufty definitions.
Wed Oct 2 12:53:42 1996 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
(ffi_prep_cif_machdep): Moved all machine independent cif processing
to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types
of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT.
Tue Oct 1 17:11:02 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c, o32.S, object.mak: Created
--- libffi/src/sparc ------------------------------------------------------
Tue Feb 24 16:33:18 1998 Anthony Green <green@hoser.cygnus.com>
* ffi.c (ffi_prep_args): Added long double support.
Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
* objects.mak: Removed.
Thu May 1 16:07:56 1997 Anthony Green <green@hoser.cygnus.com>
* v8.S: Fixed minor portability problem reported by
Russ McManus <mcmanr@eq.gs.com>.
Tue Nov 26 14:12:43 1996 Anthony Green <green@csk3.cygnus.com>
* v8.S: Used STACKFRAME define elsewhere.
* ffi.c (ffi_prep_args): Zero out space when USING_PURIFY
is set.
(ffi_prep_cif_machdep): Allocate the correct stack frame
space for functions with < 6 args.
Tue Oct 29 15:08:55 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c (ffi_prep_args): int z is now size_t z.
Mon Oct 14 13:31:24 1996 Anthony Green <green@rtl.cygnus.com>
* v8.S (ffi_call_V8): Gordon rewrites this again. It looks
great now.
* ffi.c (ffi_call): The comment about hijacked registers
is no longer valid after gordoni hacked v8.S.
* v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler.
* v8.S, ffi.c: ffi_call() had changed to accept more than
two args, so v8.S had to change (because it hijacks incoming
arg registers).
* ffi.c: Interface changes based on feedback from Jim Blandy.
Thu Oct 10 17:48:16 1996 Anthony Green <green@rtl.cygnus.com>
* ffi.c, v8.S, objects.mak: Created.

20
LICENSE Normal file
View File

@@ -0,0 +1,20 @@
libffi - Copyright (c) 1996-2003 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

182
Makefile.am Normal file
View File

@@ -0,0 +1,182 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/ia64/unix.S \
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
src/mips/ffitarget.h \
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
src/powerpc/ffi.c src/powerpc/sysv.S \
src/powerpc/linux64.S src/powerpc/linux64_closure.S \
src/powerpc/ppc_closure.S src/powerpc/asm.h \
src/powerpc/aix.S src/powerpc/darwin.S \
src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \
src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \
src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c src/x86/darwin64.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c \
src/moxie/ffi.c src/moxie/eabi.S
## ################################################################
##
## This section is for make and multilib madness.
##
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
"AR_FLAGS=$(AR_FLAGS)" \
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
"CFLAGS=$(CFLAGS)" \
"CXXFLAGS=$(CXXFLAGS)" \
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
"INSTALL=$(INSTALL)" \
"INSTALL_DATA=$(INSTALL_DATA)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
"JC1FLAGS=$(JC1FLAGS)" \
"LDFLAGS=$(LDFLAGS)" \
"LIBCFLAGS=$(LIBCFLAGS)" \
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
"MAKE=$(MAKE)" \
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
"PICFLAG=$(PICFLAG)" \
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
"SHELL=$(SHELL)" \
"exec_prefix=$(exec_prefix)" \
"infodir=$(infodir)" \
"libdir=$(libdir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
"CC=$(CC)" \
"CXX=$(CXX)" \
"LD=$(LD)" \
"NM=$(NM)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES=
toolexeclib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/closures.c
nodist_libffi_la_SOURCES =
if MIPS
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
endif
if X86
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
endif
if X86_FREEBSD
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
endif
if X86_WIN32
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
endif
if X86_WIN64
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
endif
if X86_DARWIN
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
endif
if SPARC
nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
endif
if ALPHA
nodist_libffi_la_SOURCES += src/alpha/ffi.c src/alpha/osf.S
endif
if IA64
nodist_libffi_la_SOURCES += src/ia64/ffi.c src/ia64/unix.S
endif
if M32R
nodist_libffi_la_SOURCES += src/m32r/sysv.S src/m32r/ffi.c
endif
if M68K
nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
endif
if POWERPC
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
endif
if POWERPC_AIX
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
endif
if POWERPC_DARWIN
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
endif
if POWERPC_FREEBSD
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
endif
if ARM
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
endif
if LIBFFI_CRIS
nodist_libffi_la_SOURCES += src/cris/sysv.S src/cris/ffi.c
endif
if FRV
nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi.c
endif
if MOXIE
nodist_libffi_la_SOURCES += src/moxie/eabi.S src/moxie/ffi.c
endif
if S390
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
endif
if X86_64
nodist_libffi_la_SOURCES += src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
endif
if SH
nodist_libffi_la_SOURCES += src/sh/sysv.S src/sh/ffi.c
endif
if SH64
nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
endif
if PA_LINUX
nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
endif
if PA_HPUX
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
endif
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
AM_CCASFLAGS = $(AM_CPPFLAGS)
# Multilib support. Automake should provide these on its own.
all-recursive: all-multi
install-recursive: install-multi
mostlyclean-recursive: mostlyclean-multi
clean-recursive: clean-multi
distclean-recursive: distclean-multi
maintainer-clean-recursive: maintainer-clean-multi

1516
Makefile.in Normal file

File diff suppressed because it is too large Load Diff

340
README Normal file
View File

@@ -0,0 +1,340 @@
This directory contains the libffi package, which is not part of GCC but
shipped with GCC as convenience.
Status
======
libffi-3.0.8 was released on December 19, 2008. Check the libffi web
page for updates: <URL:http://sourceware.org/libffi/>.
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 essentially 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.
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.
Supported Platforms
===================
Libffi has been ported to many different platforms, although this
release was only tested on:
arm oabi linux
arm eabi linux
hppa linux
mips o32 linux (little endian)
powerpc darwin
powerpc freebsd
powerpc64 linux
sparc solaris
sparc64 freebsd
sparc64 solaris
x86 cygwin
x86 darwin
x86 freebsd
x86 linux
x86 openbsd
x86 solaris
x86-64 mingw
x86-64 darwin
x86-64 linux
x86-64 OS X
x86-64 freebsd
x86-64 solaris
Please send additional platform test results to
libffi-discuss@sourceware.org.
Installing libffi
=================
[Note: before actually performing any of these installation steps,
you may wish to read the "Platform Specific Notes" below.]
First you must configure the distribution for your particular
system. Go to the directory you wish to build libffi in and run the
"configure" program found in the root directory of the libffi source
distribution.
You may want to tell configure where to install the libffi library and
header files. To do that, use the --prefix configure switch. Libffi
will install under /usr/local by default.
If you want to enable extra run-time debugging checks use the the
--enable-debug configure switch. This is useful when your program dies
mysteriously while using libffi.
Another useful configure switch is --enable-purify-safety. Using this
will add some extra code which will suppress certain warnings when you
are using Purify with libffi. Only use this switch when using
Purify, as it will slow down the library.
Configure has many other options. Use "configure --help" to see them all.
Once configure has finished, type "make". Note that you must be using
GNU make. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
To ensure that libffi is working as advertised, type "make check".
This will require that you have DejaGNU installed.
To install the library and header files, type "make install".
Platform Specific Notes
=======================
MIPS - Irix 5.3 & 6.x
---------------------
Irix 6.2 and better supports three different calling conventions: o32,
n32 and n64. Currently, libffi only supports both o32 and n32 under
Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
configured for whichever calling convention it was built for.
By default, the configure script will try to build libffi with the GNU
development tools. To build libffi with the SGI development tools, set
the environment variable CC to either "cc -32" or "cc -n32" before
running configure under Irix 6.x (depending on whether you want an o32
or n32 library), or just "cc" for Irix 5.3.
With the n32 calling convention, when returning structures smaller
than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
Here's one way of forcing this:
double struct_storage[2];
my_small_struct *s = (my_small_struct *) struct_storage;
/* Use s for RVALUE */
If you don't do this you are liable to get spurious bus errors.
"long long" values are not supported yet.
You must use GNU Make to build libffi on SGI platforms.
PowerPC System V ABI
--------------------
There are two `System V ABI's which libffi implements for PowerPC.
They differ only in how small structures are returned from functions.
In the FFI_SYSV version, structures that are 8 bytes or smaller are
returned in registers. This is what GCC does when it is configured
for solaris, and is what the System V ABI I have (dated September
1995) says.
In the FFI_GCC_SYSV version, all structures are returned the same way:
by passing a pointer as the first argument to the function. This is
what GCC does when it is configured for linux or a generic sysv
target.
EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
inconsistency with the SysV ABI: When a procedure is called with many
floating-point arguments, some of them get put on the stack. They are
all supposed to be stored in double-precision format, even if they are
only single-precision, but EGCS stores single-precision arguments as
single-precision anyway. This causes one test to fail (the `many
arguments' test).
History
=======
3.0.7 Nov-11-08
Fix for ppc FreeBSD.
(thanks to Andreas Tobler)
3.0.6 Jul-17-08
Fix for closures on sh.
Mark the sh/sh64 stack as non-executable.
(both thanks to Kaz Kojima)
3.0.5 Apr-3-08
Fix libffi.pc file.
Fix #define ARM for IcedTea users.
Fix x86 closure bug.
3.0.4 Feb-24-08
Fix x86 OpenBSD configury.
3.0.3 Feb-22-08
Enable x86 OpenBSD thanks to Thomas Heller, and
x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
Clean up test instruction in README.
3.0.2 Feb-21-08
Improved x86 FreeBSD support.
Thanks to Björn König.
3.0.1 Feb-15-08
Fix instruction cache flushing bug on MIPS.
Thanks to David Daney.
3.0.0 Feb-15-08
Many changes, mostly thanks to the GCC project.
Cygnus Solutions is now Red Hat.
[10 years go by...]
1.20 Oct-5-98
Raffaele Sena produces ARM port.
1.19 Oct-5-98
Fixed x86 long double and long long return support.
m68k bug fixes from Andreas Schwab.
Patch for DU assembler compatibility for the Alpha from Richard
Henderson.
1.18 Apr-17-98
Bug fixes and MIPS configuration changes.
1.17 Feb-24-98
Bug fixes and m68k port from Andreas Schwab. PowerPC port from
Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
1.16 Feb-11-98
Richard Henderson produces Alpha port.
1.15 Dec-4-97
Fixed an n32 ABI bug. New libtool, auto* support.
1.14 May-13-97
libtool is now used to generate shared and static libraries.
Fixed a minor portability problem reported by Russ McManus
<mcmanr@eq.gs.com>.
1.13 Dec-2-96
Added --enable-purify-safety to keep Purify from complaining
about certain low level code.
Sparc fix for calling functions with < 6 args.
Linux x86 a.out fix.
1.12 Nov-22-96
Added missing ffi_type_void, needed for supporting void return
types. Fixed test case for non MIPS machines. Cygnus Support
is now Cygnus Solutions.
1.11 Oct-30-96
Added notes about GNU make.
1.10 Oct-29-96
Added configuration fix for non GNU compilers.
1.09 Oct-29-96
Added --enable-debug configure switch. Clean-ups based on LCLint
feedback. ffi_mips.h is always installed. Many configuration
fixes. Fixed ffitest.c for sparc builds.
1.08 Oct-15-96
Fixed n32 problem. Many clean-ups.
1.07 Oct-14-96
Gordon Irlam rewrites v8.S again. Bug fixes.
1.06 Oct-14-96
Gordon Irlam improved the sparc port.
1.05 Oct-14-96
Interface changes based on feedback.
1.04 Oct-11-96
Sparc port complete (modulo struct passing bug).
1.03 Oct-10-96
Passing struct args, and returning struct values works for
all architectures/calling conventions. Expanded tests.
1.02 Oct-9-96
Added SGI n32 support. Fixed bugs in both o32 and Linux support.
Added "make test".
1.01 Oct-8-96
Fixed float passing bug in mips version. Restructured some
of the code. Builds cleanly with SGI tools.
1.00 Oct-7-96
First release. No public announcement.
Authors & Credits
=================
libffi was originally written by Anthony Green <green@redhat.com>.
The developers of the GNU Compiler Collection project have made
innumerable valuable contributions. See the ChangeLog file for
details.
Some of the ideas behind libffi were inspired by Gianni Mariani's free
gencall library for Silicon Graphics machines.
The closure mechanism was designed and implemented by Kresten Krab
Thorup.
Major processor architecture ports were contributed by the following
developers:
alpha Richard Henderson
arm Raffaele Sena
cris Simon Posnjak, Hans-Peter Nilsson
frv Anthony Green
ia64 Hans Boehm
m32r Kazuhiro Inaoka
m68k Andreas Schwab
mips Anthony Green, Casey Marshall
mips64 David Daney
pa Randolph Chung, Dave Anglin, Andreas Tobler
powerpc Geoffrey Keating, Andreas Tobler,
David Edelsohn, John Hornkvist
powerpc64 Jakub Jelinek
s390 Gerhard Tonn, Ulrich Weigand
sh Kaz Kojima
sh64 Kaz Kojima
sparc Anthony Green, Gordon Irlam
x86 Anthony Green, Jon Beniston
x86-64 Bo Thorsen
Jesper Skov and Andrew Haley both did more than their fair share of
stepping through the code and tracking down bugs.
Thanks also to Tom Tromey for bug fixes, documentation and
configuration help.
Thanks to Jim Blandy, who provided some useful feedback on the libffi
interface.
Andreas Tobler has done a tremendous amount of work on the testsuite.
Alex Oliva solved the executable page problem for SElinux.
The list above is almost certainly incomplete and inaccurate. I'm
happy to make corrections or additions upon request.
If you have a problem, or have found a bug, please send a note to
green@redhat.com.

92
acinclude.m4 Normal file
View File

@@ -0,0 +1,92 @@
# mmap(2) blacklisting. Some platforms provide the mmap library routine
# but don't support all of the features we need from it.
AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
[
AC_CHECK_HEADER([sys/mman.h],
[libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
if test "$libffi_header_sys_mman_h" != yes \
|| test "$libffi_func_mmap" != yes; then
ac_cv_func_mmap_file=no
ac_cv_func_mmap_dev_zero=no
ac_cv_func_mmap_anon=no
else
AC_CACHE_CHECK([whether read-only mmap of a plain file works],
ac_cv_func_mmap_file,
[# Add a system to this blacklist if
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
# memory area containing the same data that you'd get if you applied
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
vms* | ultrix*)
ac_cv_func_mmap_file=no ;;
*)
ac_cv_func_mmap_file=yes;;
esac])
AC_CACHE_CHECK([whether mmap from /dev/zero works],
ac_cv_func_mmap_dev_zero,
[# Add a system to this blacklist if it has mmap() but /dev/zero
# does not exist, or if mmapping /dev/zero does not give anonymous
# zeroed pages with both the following properties:
# 1. If you map N consecutive pages in with one call, and then
# unmap any subset of those pages, the pages that were not
# explicitly unmapped remain accessible.
# 2. If you map two adjacent blocks of memory and then unmap them
# both at once, they must both go away.
# Systems known to be in this category are Windows (all variants),
# VMS, and Darwin.
case "$host_os" in
vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
ac_cv_func_mmap_dev_zero=no ;;
*)
ac_cv_func_mmap_dev_zero=yes;;
esac])
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
[AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
],
[int n = MAP_ANONYMOUS;],
ac_cv_decl_map_anon=yes,
ac_cv_decl_map_anon=no)])
if test $ac_cv_decl_map_anon = no; then
ac_cv_func_mmap_anon=no
else
AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
ac_cv_func_mmap_anon,
[# Add a system to this blacklist if it has mmap() and MAP_ANON or
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
# doesn't give anonymous zeroed pages with the same properties listed
# above for use of /dev/zero.
# Systems known to be in this category are Windows, VMS, and SCO Unix.
case "$host_os" in
vms* | cygwin* | pe | mingw* | sco* | udk* )
ac_cv_func_mmap_anon=no ;;
*)
ac_cv_func_mmap_anon=yes;;
esac])
fi
fi
if test $ac_cv_func_mmap_file = yes; then
AC_DEFINE(HAVE_MMAP_FILE, 1,
[Define if read-only mmap of a plain file works.])
fi
if test $ac_cv_func_mmap_dev_zero = yes; then
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
[Define if mmap of /dev/zero works.])
fi
if test $ac_cv_func_mmap_anon = yes; then
AC_DEFINE(HAVE_MMAP_ANON, 1,
[Define if mmap with MAP_ANON(YMOUS) works.])
fi
])

1037
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

14927
configure vendored Executable file

File diff suppressed because it is too large Load Diff

390
configure.ac Normal file
View File

@@ -0,0 +1,390 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.64)
AC_INIT([libffi], [3.0.8], [http://gcc.gnu.org/bugs.html])
AC_CONFIG_HEADERS([fficonfig.h])
AM_ENABLE_MULTILIB(, ..)
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AM_INIT_AUTOMAKE
# The same as in boehm-gc and libstdc++. Have to borrow it from there.
# We must force CC to /not/ be precious variables; otherwise
# the wrong, non-multilib-adjusted value will be used in multilibs.
# As a side effect, we have to subst CFLAGS ourselves.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
AC_PROG_CC
m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AM_MAINTAINER_MODE
AC_CHECK_HEADERS(sys/mman.h)
AC_CHECK_FUNCS(mmap)
AC_FUNC_MMAP_BLACKLIST
dnl The -no-testsuite modules omit the test subdir.
AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
TARGETDIR="unknown"
case "$host" in
alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
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
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[[34]]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
if test $TARGETDIR = unknown; then
AC_MSG_ERROR(["libffi has not been ported to $host."])
fi
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_WIN64, test x$TARGET = xX86_WIN64)
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
AM_CONDITIONAL(SH, test x$TARGET = xSH)
AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
AC_HEADER_STDC
AC_CHECK_FUNCS(memcpy)
AC_FUNC_ALLOCA
AC_CHECK_SIZEOF(double)
AC_CHECK_SIZEOF(long double)
# Also AC_SUBST this variable for ffi.h.
if test -z "$HAVE_LONG_DOUBLE"; then
HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
if test $ac_cv_sizeof_long_double != 0; then
HAVE_LONG_DOUBLE=1
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
fi
fi
fi
AC_SUBST(HAVE_LONG_DOUBLE)
AC_C_BIGENDIAN
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
libffi_cv_as_cfi_pseudo_op, [
libffi_cv_as_cfi_pseudo_op=unknown
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
[libffi_cv_as_cfi_pseudo_op=yes],
[libffi_cv_as_cfi_pseudo_op=no])
])
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
[Define if your assembler supports .cfi_* directives.])
fi
if test x$TARGET = xSPARC; then
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
libffi_cv_as_sparc_ua_pcrel, [
save_CFLAGS="$CFLAGS"
save_LDFLAGS="$LDFLAGS"
CFLAGS="$CFLAGS -fpic"
LDFLAGS="$LDFLAGS -shared"
AC_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
[libffi_cv_as_sparc_ua_pcrel=yes],
[libffi_cv_as_sparc_ua_pcrel=no])
CFLAGS="$save_CFLAGS"
LDFLAGS="$save_LDFLAGS"])
if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
[Define if your assembler and linker support unaligned PC relative relocs.])
fi
AC_CACHE_CHECK([assembler .register pseudo-op support],
libffi_cv_as_register_pseudo_op, [
libffi_cv_as_register_pseudo_op=unknown
# Check if we have .register
AC_TRY_COMPILE([asm (".register %g2, #scratch");],,
[libffi_cv_as_register_pseudo_op=yes],
[libffi_cv_as_register_pseudo_op=no])
])
if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
[Define if your assembler supports .register.])
fi
fi
if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports pc related relocs],
libffi_cv_as_x86_pcrel, [
libffi_cv_as_x86_pcrel=yes
echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_pcrel=no
fi
])
if test "x$libffi_cv_as_x86_pcrel" = xyes; then
AC_DEFINE(HAVE_AS_X86_PCREL, 1,
[Define if your assembler supports PC relative relocs.])
fi
fi
AC_CACHE_CHECK([whether .eh_frame section should be read-only],
libffi_cv_ro_eh_frame, [
libffi_cv_ro_eh_frame=no
echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then
if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then
libffi_cv_ro_eh_frame=yes
elif grep '.section.*eh_frame.*#alloc' conftest.c \
| grep -v '#write' > /dev/null; then
libffi_cv_ro_eh_frame=yes
fi
fi
rm -f conftest.*
])
if test "x$libffi_cv_ro_eh_frame" = xyes; then
AC_DEFINE(HAVE_RO_EH_FRAME, 1,
[Define if .eh_frame sections should be read-only.])
AC_DEFINE(EH_FRAME_FLAGS, "a",
[Define to the flags needed for the .section .eh_frame directive.])
else
AC_DEFINE(EH_FRAME_FLAGS, "aw",
[Define to the flags needed for the .section .eh_frame directive.])
fi
AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
libffi_cv_hidden_visibility_attribute, [
echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c
libffi_cv_hidden_visibility_attribute=no
if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
if grep '\.hidden.*foo' conftest.s >/dev/null; then
libffi_cv_hidden_visibility_attribute=yes
fi
fi
rm -f conftest.*
])
if test $libffi_cv_hidden_visibility_attribute = yes; then
AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,
[Define if __attribute__((visibility("hidden"))) is supported.])
fi
AH_BOTTOM([
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name) .hidden name
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
])
AC_SUBST(TARGET)
AC_SUBST(TARGETDIR)
AC_SUBST(SHELL)
AC_ARG_ENABLE(debug,
[ --enable-debug debugging mode],
if test "$enable_debug" = "yes"; then
AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
fi)
AC_ARG_ENABLE(structs,
[ --disable-structs omit code for struct support],
if test "$enable_structs" = "no"; then
AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.])
fi)
AC_ARG_ENABLE(raw-api,
[ --disable-raw-api make the raw api unavailable],
if test "$enable_raw_api" = "no"; then
AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.])
fi)
AC_ARG_ENABLE(purify-safety,
[ --enable-purify-safety purify-safe mode],
if test "$enable_purify_safety" = "yes"; then
AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])
fi)
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
toolexecdir='$(exec_prefix)/$(target_alias)'
toolexeclibdir='$(toolexecdir)/lib'
else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
multi_os_directory=`$CC -print-multi-os-directory`
case $multi_os_directory in
.) ;; # Avoid trailing /.
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
esac
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
multilib_arg=
fi
AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
AC_CONFIG_COMMANDS(src, [
test -d src || mkdir src
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
], [TARGETDIR="$TARGETDIR"])
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile)
AC_OUTPUT

11
configure.host Normal file
View File

@@ -0,0 +1,11 @@
# configure.host
#
# This shell script handles all host based configuration for libffi.
#
# THIS TABLE IS SORTED. KEEP IT THAT WAY.
case "${host}" in
frv*-elf)
LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/
;;
esac

164
doc/.svn/entries Normal file
View File

@@ -0,0 +1,164 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/doc
svn://gcc.gnu.org/svn/gcc
2009-06-09T10:21:19.356122Z
148309
aph
138bc75d-0d04-0410-961f-82ee72b054a4
libffi.texi
file
2009-06-10T05:25:05.000000Z
2c36d1d9259ed7b885ff66784a65d3a0
2009-06-09T10:21:19.356122Z
148309
aph
15350
stamp-vti
file
2009-06-10T05:25:05.000000Z
7123a892595757886f0ee120347f9565
2009-06-09T10:21:19.356122Z
148309
aph
101
libffi.info
file
2009-06-10T05:25:05.000000Z
5f18f2f020ebe104a830fecfe6f6bb22
2009-06-09T10:21:19.356122Z
148309
aph
18511
version.texi
file
2009-06-10T05:25:05.000000Z
7123a892595757886f0ee120347f9565
2009-06-09T10:21:19.356122Z
148309
aph
101

View File

@@ -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]
* Menu:
* : Structures. (line 12)
* ABI: Introduction. (line 13)
* Application Binary Interface: Introduction. (line 13)
* calling convention: Introduction. (line 13)
* cif: The Basics. (line 14)
* closure API: The Closure API. (line 13)
* closures: The Closure API. (line 13)
* FFI: Introduction. (line 31)
* ffi_call: The Basics. (line 41)
* ffi_closure_alloca: The Closure API. (line 19)
* ffi_closure_free: The Closure API. (line 26)
* FFI_CLOSURES: The Closure API. (line 13)
* ffi_prep_cif: The Basics. (line 16)
* ffi_prep_closure_loc: The Closure API. (line 34)
* ffi_status <1>: The Closure API. (line 37)
* ffi_status: The Basics. (line 18)
* ffi_type: Structures. (line 11)
* ffi_type_double: Primitive Types. (line 41)
* ffi_type_float: Primitive Types. (line 38)
* ffi_type_longdouble: Primitive Types. (line 71)
* ffi_type_pointer: Primitive Types. (line 75)
* ffi_type_schar: Primitive Types. (line 47)
* ffi_type_sint: Primitive Types. (line 62)
* ffi_type_sint16: Primitive Types. (line 23)
* ffi_type_sint32: Primitive Types. (line 29)
* ffi_type_sint64: Primitive Types. (line 35)
* ffi_type_sint8: Primitive Types. (line 17)
* ffi_type_slong: Primitive Types. (line 68)
* ffi_type_sshort: Primitive Types. (line 56)
* ffi_type_uchar: Primitive Types. (line 44)
* ffi_type_uint: Primitive Types. (line 59)
* ffi_type_uint16: Primitive Types. (line 20)
* ffi_type_uint32: Primitive Types. (line 26)
* ffi_type_uint64: Primitive Types. (line 32)
* ffi_type_uint8: Primitive Types. (line 14)
* ffi_type_ulong: Primitive Types. (line 65)
* ffi_type_ushort: Primitive Types. (line 53)
* ffi_type_void: Primitive Types. (line 10)
* Foreign Function Interface: Introduction. (line 31)
* void <1>: The Closure API. (line 20)
* void: The Basics. (line 43)

Tag Table:
Node: Top670
Node: Introduction1406
Node: Using libffi3042
Node: The Basics3477
Node: Simple Example6084
Node: Types7111
Node: Primitive Types7394
Node: Structures9214
Node: Type Example10074
Node: Multiple ABIs11297
Node: The Closure API11668
Node: Missing Features14588
Node: Index15081

End Tag Table

View File

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

View File

@@ -0,0 +1,4 @@
@set UPDATED 14 February 2008
@set UPDATED-MONTH February 2008
@set EDITION 3.0.8
@set VERSION 3.0.8

View File

@@ -0,0 +1,4 @@
@set UPDATED 14 February 2008
@set UPDATED-MONTH February 2008
@set EDITION 3.0.8
@set VERSION 3.0.8

533
doc/libffi.info Normal file
View File

@@ -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]
* Menu:
* : Structures. (line 12)
* ABI: Introduction. (line 13)
* Application Binary Interface: Introduction. (line 13)
* calling convention: Introduction. (line 13)
* cif: The Basics. (line 14)
* closure API: The Closure API. (line 13)
* closures: The Closure API. (line 13)
* FFI: Introduction. (line 31)
* ffi_call: The Basics. (line 41)
* ffi_closure_alloca: The Closure API. (line 19)
* ffi_closure_free: The Closure API. (line 26)
* FFI_CLOSURES: The Closure API. (line 13)
* ffi_prep_cif: The Basics. (line 16)
* ffi_prep_closure_loc: The Closure API. (line 34)
* ffi_status <1>: The Closure API. (line 37)
* ffi_status: The Basics. (line 18)
* ffi_type: Structures. (line 11)
* ffi_type_double: Primitive Types. (line 41)
* ffi_type_float: Primitive Types. (line 38)
* ffi_type_longdouble: Primitive Types. (line 71)
* ffi_type_pointer: Primitive Types. (line 75)
* ffi_type_schar: Primitive Types. (line 47)
* ffi_type_sint: Primitive Types. (line 62)
* ffi_type_sint16: Primitive Types. (line 23)
* ffi_type_sint32: Primitive Types. (line 29)
* ffi_type_sint64: Primitive Types. (line 35)
* ffi_type_sint8: Primitive Types. (line 17)
* ffi_type_slong: Primitive Types. (line 68)
* ffi_type_sshort: Primitive Types. (line 56)
* ffi_type_uchar: Primitive Types. (line 44)
* ffi_type_uint: Primitive Types. (line 59)
* ffi_type_uint16: Primitive Types. (line 20)
* ffi_type_uint32: Primitive Types. (line 26)
* ffi_type_uint64: Primitive Types. (line 32)
* ffi_type_uint8: Primitive Types. (line 14)
* ffi_type_ulong: Primitive Types. (line 65)
* ffi_type_ushort: Primitive Types. (line 53)
* ffi_type_void: Primitive Types. (line 10)
* Foreign Function Interface: Introduction. (line 31)
* void <1>: The Closure API. (line 20)
* void: The Basics. (line 43)

Tag Table:
Node: Top670
Node: Introduction1406
Node: Using libffi3042
Node: The Basics3477
Node: Simple Example6084
Node: Types7111
Node: Primitive Types7394
Node: Structures9214
Node: Type Example10074
Node: Multiple ABIs11297
Node: The Closure API11668
Node: Missing Features14588
Node: Index15081

End Tag Table

541
doc/libffi.texi Normal file
View File

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

4
doc/stamp-vti Normal file
View File

@@ -0,0 +1,4 @@
@set UPDATED 14 February 2008
@set UPDATED-MONTH February 2008
@set EDITION 3.0.8
@set VERSION 3.0.8

4
doc/version.texi Normal file
View File

@@ -0,0 +1,4 @@
@set UPDATED 14 February 2008
@set UPDATED-MONTH February 2008
@set EDITION 3.0.8
@set VERSION 3.0.8

181
fficonfig.h.in Normal file
View File

@@ -0,0 +1,181 @@
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to the flags needed for the .section .eh_frame directive. */
#undef EH_FRAME_FLAGS
/* Define this if you want extra debugging. */
#undef FFI_DEBUG
/* Define this is you do not want support for the raw API. */
#undef FFI_NO_RAW_API
/* Define this is you do not want support for aggregate types. */
#undef FFI_NO_STRUCTS
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define if your assembler supports .cfi_* directives. */
#undef HAVE_AS_CFI_PSEUDO_OP
/* Define if your assembler supports .register. */
#undef HAVE_AS_REGISTER_PSEUDO_OP
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
#undef HAVE_AS_SPARC_UA_PCREL
/* Define if your assembler supports PC relative relocs. */
#undef HAVE_AS_X86_PCREL
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if __attribute__((visibility("hidden"))) is supported. */
#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if you have the long double type and it is bigger than a double */
#undef HAVE_LONG_DOUBLE
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define if mmap with MAP_ANON(YMOUS) works. */
#undef HAVE_MMAP_ANON
/* Define if mmap of /dev/zero works. */
#undef HAVE_MMAP_DEV_ZERO
/* Define if read-only mmap of a plain file works. */
#undef HAVE_MMAP_FILE
/* Define if .eh_frame sections should be read-only. */
#undef HAVE_RO_EH_FRAME
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of `double', as computed by sizeof. */
#undef SIZEOF_DOUBLE
/* The size of `long double', as computed by sizeof. */
#undef SIZEOF_LONG_DOUBLE
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define this if you are using Purify and want to suppress spurious messages.
*/
#undef USING_PURIFY
/* Version number of package */
#undef VERSION
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name) .hidden name
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif

164
include/.svn/entries Normal file
View File

@@ -0,0 +1,164 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/include
svn://gcc.gnu.org/svn/gcc
2009-08-22T13:22:20.806489Z
151014
rwild
138bc75d-0d04-0410-961f-82ee72b054a4
ffi.h.in
file
2009-06-20T15:53:35.000000Z
ec6d4ca2bd2cdaa6a515412cedd717a1
2009-06-12T15:57:58.721771Z
148433
aph
10882
Makefile.in
file
2009-09-10T17:50:58.000000Z
519b93a77f732942ff2c6e947e00ec9d
2009-08-22T13:22:20.806489Z
151014
rwild
14583
ffi_common.h
file
2009-06-20T15:53:35.000000Z
5bffed11a81aed973aeec1041d96e2bc
2009-06-12T15:57:58.721771Z
148433
aph
2904
Makefile.am
file
2009-04-24T17:46:15.000000Z
f165b6fb33a20fdd5f1eeffbafa83d78
2006-09-12T16:51:43.967870Z
116893
daney
368

View File

@@ -0,0 +1,12 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS=foreign
DISTCLEANFILES=ffitarget.h
EXTRA_DIST=ffi.h.in ffi_common.h
# Where generated headers like ffitarget.h get installed.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
toollibffi_HEADERS = ffi.h ffitarget.h

View File

@@ -0,0 +1,481 @@
# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = include
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/ffi.h.in $(toollibffi_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES = ffi.h ffitarget.h
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(toollibffidir)"
HEADERS = $(toollibffi_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
DISTCLEANFILES = ffitarget.h
EXTRA_DIST = ffi.h.in ffi_common.h
# Where generated headers like ffitarget.h get installed.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
toollibffi_HEADERS = ffi.h ffitarget.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
ffi.h: $(top_builddir)/config.status $(srcdir)/ffi.h.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-toollibffiHEADERS: $(toollibffi_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(toollibffidir)" || $(MKDIR_P) "$(DESTDIR)$(toollibffidir)"
@list='$(toollibffi_HEADERS)'; test -n "$(toollibffidir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(toollibffidir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(toollibffidir)" || exit $$?; \
done
uninstall-toollibffiHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(toollibffi_HEADERS)'; test -n "$(toollibffidir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(toollibffidir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(toollibffidir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(toollibffidir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-toollibffiHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-toollibffiHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags distclean distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip \
install-toollibffiHEADERS installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags uninstall uninstall-am \
uninstall-toollibffiHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,395 @@
/* -----------------------------------------------------------------*-C-*-
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
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
The basic API is described in the README file.
The raw API is designed to bypass some of the argument packing
and unpacking on architectures for which it can be avoided.
The closure API allows interpreted functions to be packaged up
inside a C function pointer, so that they can be called as C functions,
with no understanding on the client side that they are interpreted.
It can also be used in other cases in which it is necessary to package
up a user specified parameter and a function pointer as a single
function pointer.
The closure API must be implemented in order to get its functionality,
e.g. for use by gij. Routines are provided to emulate the raw API
if the underlying platform doesn't allow faster implementation.
More details on the raw and cloure API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Specify which architecture libffi is configured for. */
#define @TARGET@
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#ifdef _MSC_VER
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t */
/* can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != 9223372036854775807
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != 9223372036854775807
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == 9223372036854775807
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c */
extern ffi_type ffi_type_void;
extern ffi_type ffi_type_uint8;
extern ffi_type ffi_type_sint8;
extern ffi_type ffi_type_uint16;
extern ffi_type ffi_type_sint16;
extern ffi_type ffi_type_uint32;
extern ffi_type ffi_type_sint32;
extern ffi_type ffi_type_uint64;
extern ffi_type ffi_type_sint64;
extern ffi_type ffi_type_float;
extern ffi_type ffi_type_double;
extern ffi_type ffi_type_pointer;
#if @HAVE_LONG_DOUBLE@
extern ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum {
FFI_OK = 0,
FFI_BAD_TYPEDEF,
FFI_BAD_ABI
} ffi_status;
typedef unsigned FFI_TYPE;
typedef struct {
ffi_abi abi;
unsigned nargs;
ffi_type **arg_types;
ffi_type *rtype;
unsigned bytes;
unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == 9223372036854775807
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef union {
ffi_sarg sint;
ffi_arg uint;
float flt;
char data[FFI_SIZEOF_ARG];
void* ptr;
} ffi_raw;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef union {
signed int sint;
unsigned int uint;
float flt;
char data[FFI_SIZEOF_JAVA_RAW];
void* ptr;
} ffi_java_raw;
#else
typedef ffi_raw ffi_java_raw;
#endif
void ffi_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter */
/* packing, even on 64-bit machines. I.e. on 64-bit machines */
/* longs and doubles are followed by an empty 64-bit word. */
void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue);
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
} ffi_closure __attribute__((aligned (8)));
void *ffi_closure_alloc (size_t size, void **code);
void ffi_closure_free (void *);
ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data);
ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void*codeloc);
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* if this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
void *user_data;
} ffi_raw_closure;
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* if this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
void *user_data;
} ffi_java_raw_closure;
ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data);
ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc);
#endif /* FFI_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
ffi_type *rtype,
ffi_type **atypes);
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue);
/* Useful for eliminating compiler warnings */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if @HAVE_LONG_DOUBLE@
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
/* This should always refer to the last type code (for sanity checks) */
#define FFI_TYPE_LAST FFI_TYPE_POINTER
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,116 @@
/* -----------------------------------------------------------------------
ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Common internal definitions and macros. Only necessary for building
libffi.
----------------------------------------------------------------------- */
#ifndef FFI_COMMON_H
#define FFI_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include <fficonfig.h>
/* Do not move this. Some versions of AIX are very picky about where
this is positioned. */
#ifdef __GNUC__
/* mingw64 defines this already in malloc.h. */
#ifndef alloca
# define alloca __builtin_alloca
#endif
# define MAYBE_UNUSED __attribute__((__unused__))
#else
# define MAYBE_UNUSED
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
# ifdef _MSC_VER
# define alloca _alloca
# else
char *alloca ();
# endif
# endif
# endif
# endif
#endif
/* Check for the existence of memcpy. */
#if STDC_HEADERS
# include <string.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#if defined(FFI_DEBUG)
#include <stdio.h>
#endif
#ifdef FFI_DEBUG
void ffi_assert(char *expr, char *file, int line);
void ffi_stop_here(void);
void ffi_type_test(ffi_type *a, char *file, int line);
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
#else
#define FFI_ASSERT(x)
#define FFI_ASSERT_AT(x, f, l)
#define FFI_ASSERT_VALID_TYPE(x)
#endif
#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
/* Extended cif, used in callback from assembly routine */
typedef struct
{
ffi_cif *cif;
void *rvalue;
void **avalue;
} extended_cif;
/* Terse sized type definitions. */
#ifdef _MSC_VER
typedef unsigned char UINT8;
typedef signed char SINT8;
typedef unsigned short UINT16;
typedef signed short SINT16;
typedef unsigned int UINT32;
typedef signed int SINT32;
typedef unsigned __int64 UINT64;
typedef signed __int64 SINT64;
#else
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
typedef signed int SINT16 __attribute__((__mode__(__HI__)));
typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
#endif
typedef float FLOAT32;
#ifdef __cplusplus
}
#endif
#endif

12
include/Makefile.am Normal file
View File

@@ -0,0 +1,12 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS=foreign
DISTCLEANFILES=ffitarget.h
EXTRA_DIST=ffi.h.in ffi_common.h
# Where generated headers like ffitarget.h get installed.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
toollibffi_HEADERS = ffi.h ffitarget.h

481
include/Makefile.in Normal file
View File

@@ -0,0 +1,481 @@
# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = include
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/ffi.h.in $(toollibffi_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES = ffi.h ffitarget.h
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(toollibffidir)"
HEADERS = $(toollibffi_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
DISTCLEANFILES = ffitarget.h
EXTRA_DIST = ffi.h.in ffi_common.h
# Where generated headers like ffitarget.h get installed.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
toollibffi_HEADERS = ffi.h ffitarget.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
ffi.h: $(top_builddir)/config.status $(srcdir)/ffi.h.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-toollibffiHEADERS: $(toollibffi_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(toollibffidir)" || $(MKDIR_P) "$(DESTDIR)$(toollibffidir)"
@list='$(toollibffi_HEADERS)'; test -n "$(toollibffidir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(toollibffidir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(toollibffidir)" || exit $$?; \
done
uninstall-toollibffiHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(toollibffi_HEADERS)'; test -n "$(toollibffidir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(toollibffidir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(toollibffidir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(toollibffidir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-toollibffiHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-toollibffiHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags distclean distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip \
install-toollibffiHEADERS installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags uninstall uninstall-am \
uninstall-toollibffiHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

395
include/ffi.h.in Normal file
View File

@@ -0,0 +1,395 @@
/* -----------------------------------------------------------------*-C-*-
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
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
The basic API is described in the README file.
The raw API is designed to bypass some of the argument packing
and unpacking on architectures for which it can be avoided.
The closure API allows interpreted functions to be packaged up
inside a C function pointer, so that they can be called as C functions,
with no understanding on the client side that they are interpreted.
It can also be used in other cases in which it is necessary to package
up a user specified parameter and a function pointer as a single
function pointer.
The closure API must be implemented in order to get its functionality,
e.g. for use by gij. Routines are provided to emulate the raw API
if the underlying platform doesn't allow faster implementation.
More details on the raw and cloure API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Specify which architecture libffi is configured for. */
#define @TARGET@
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#ifdef _MSC_VER
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t */
/* can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != 9223372036854775807
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != 9223372036854775807
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == 9223372036854775807
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c */
extern ffi_type ffi_type_void;
extern ffi_type ffi_type_uint8;
extern ffi_type ffi_type_sint8;
extern ffi_type ffi_type_uint16;
extern ffi_type ffi_type_sint16;
extern ffi_type ffi_type_uint32;
extern ffi_type ffi_type_sint32;
extern ffi_type ffi_type_uint64;
extern ffi_type ffi_type_sint64;
extern ffi_type ffi_type_float;
extern ffi_type ffi_type_double;
extern ffi_type ffi_type_pointer;
#if @HAVE_LONG_DOUBLE@
extern ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum {
FFI_OK = 0,
FFI_BAD_TYPEDEF,
FFI_BAD_ABI
} ffi_status;
typedef unsigned FFI_TYPE;
typedef struct {
ffi_abi abi;
unsigned nargs;
ffi_type **arg_types;
ffi_type *rtype;
unsigned bytes;
unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == 9223372036854775807
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef union {
ffi_sarg sint;
ffi_arg uint;
float flt;
char data[FFI_SIZEOF_ARG];
void* ptr;
} ffi_raw;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef union {
signed int sint;
unsigned int uint;
float flt;
char data[FFI_SIZEOF_JAVA_RAW];
void* ptr;
} ffi_java_raw;
#else
typedef ffi_raw ffi_java_raw;
#endif
void ffi_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter */
/* packing, even on 64-bit machines. I.e. on 64-bit machines */
/* longs and doubles are followed by an empty 64-bit word. */
void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue);
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
} ffi_closure __attribute__((aligned (8)));
void *ffi_closure_alloc (size_t size, void **code);
void ffi_closure_free (void *);
ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data);
ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void*codeloc);
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* if this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
void *user_data;
} ffi_raw_closure;
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* if this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
void *user_data;
} ffi_java_raw_closure;
ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data);
ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc);
#endif /* FFI_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
ffi_type *rtype,
ffi_type **atypes);
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue);
/* Useful for eliminating compiler warnings */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if @HAVE_LONG_DOUBLE@
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
/* This should always refer to the last type code (for sanity checks) */
#define FFI_TYPE_LAST FFI_TYPE_POINTER
#ifdef __cplusplus
}
#endif
#endif

116
include/ffi_common.h Normal file
View File

@@ -0,0 +1,116 @@
/* -----------------------------------------------------------------------
ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Common internal definitions and macros. Only necessary for building
libffi.
----------------------------------------------------------------------- */
#ifndef FFI_COMMON_H
#define FFI_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include <fficonfig.h>
/* Do not move this. Some versions of AIX are very picky about where
this is positioned. */
#ifdef __GNUC__
/* mingw64 defines this already in malloc.h. */
#ifndef alloca
# define alloca __builtin_alloca
#endif
# define MAYBE_UNUSED __attribute__((__unused__))
#else
# define MAYBE_UNUSED
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
# ifdef _MSC_VER
# define alloca _alloca
# else
char *alloca ();
# endif
# endif
# endif
# endif
#endif
/* Check for the existence of memcpy. */
#if STDC_HEADERS
# include <string.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#if defined(FFI_DEBUG)
#include <stdio.h>
#endif
#ifdef FFI_DEBUG
void ffi_assert(char *expr, char *file, int line);
void ffi_stop_here(void);
void ffi_type_test(ffi_type *a, char *file, int line);
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
#else
#define FFI_ASSERT(x)
#define FFI_ASSERT_AT(x, f, l)
#define FFI_ASSERT_VALID_TYPE(x)
#endif
#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
/* Extended cif, used in callback from assembly routine */
typedef struct
{
ffi_cif *cif;
void *rvalue;
void **avalue;
} extended_cif;
/* Terse sized type definitions. */
#ifdef _MSC_VER
typedef unsigned char UINT8;
typedef signed char SINT8;
typedef unsigned short UINT16;
typedef signed short SINT16;
typedef unsigned int UINT32;
typedef signed int SINT32;
typedef unsigned __int64 UINT64;
typedef signed __int64 SINT64;
#else
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
typedef signed int SINT16 __attribute__((__mode__(__HI__)));
typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
#endif
typedef float FLOAT32;
#ifdef __cplusplus
}
#endif
#endif

6
libtool-version Normal file
View File

@@ -0,0 +1,6 @@
# This file is used to maintain libtool version info for libffi. See
# the libtool manual to understand the meaning of the fields. This is
# a separate file so that version updates don't involve re-running
# automake.
# CURRENT:REVISION:AGE
4:1:0

198
man/.svn/entries Normal file
View File

@@ -0,0 +1,198 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/man
svn://gcc.gnu.org/svn/gcc
2009-08-22T13:22:20.806489Z
151014
rwild
138bc75d-0d04-0410-961f-82ee72b054a4
ffi_call.3
file
2009-06-20T15:53:37.000000Z
77a8c0a182b31529309b91d3aa9d7a35
2009-06-12T15:57:58.721771Z
148433
aph
2337
Makefile.in
file
2009-09-10T17:50:58.000000Z
87172890fb72428d6e5110dda6aaabf2
2009-08-22T13:22:20.806489Z
151014
rwild
13776
ffi.3
file
2009-06-10T05:25:05.000000Z
0bf19cd396787816bfd443fe9f6b0097
2009-06-09T10:21:19.356122Z
148309
aph
648
Makefile.am
file
2009-06-10T05:25:05.000000Z
c391cfc49d2e85ab3b248011c21038cd
2009-06-09T10:21:19.356122Z
148309
aph
169
ffi_prep_cif.3
file
2009-06-10T05:25:05.000000Z
ba320392aee6dfa2e896e6deb7205815
2009-06-09T10:21:19.356122Z
148309
aph
1053

View File

@@ -0,0 +1,8 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS=foreign
EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3

View File

@@ -0,0 +1,456 @@
# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
man3dir = $(mandir)/man3
am__installdirs = "$(DESTDIR)$(man3dir)"
NROFF = nroff
MANS = $(man_MANS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign man/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man3: $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
@list=''; test -n "$(man3dir)" || exit 0; \
{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.3[a-z]*$$/p'; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
done; }
uninstall-man3:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man3dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.3[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
test -z "$$files" || { \
echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@list='$(MANS)'; if test -n "$$list"; then \
list=`for p in $$list; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
if test -n "$$list" && \
grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
echo " typically \`make maintainer-clean' will remove them" >&2; \
exit 1; \
else :; fi; \
else :; fi
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
installdirs:
for dir in "$(DESTDIR)$(man3dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man: install-man3
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-man
uninstall-man: uninstall-man3
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-man3 \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-man uninstall-man3
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,31 @@
.Dd February 15, 2008
.Dt FFI 3
.Sh NAME
.Nm FFI
.Nd Foreign Function Interface
.Sh LIBRARY
libffi, -lffi
.Sh SYNOPSIS
.In ffi.h
.Ft ffi_status
.Fo ffi_prep_cif
.Fa "ffi_cif *cif"
.Fa "ffi_abi abi"
.Fa "unsigned int nargs"
.Fa "ffi_type *rtype"
.Fa "ffi_type **atypes"
.Fc
.Ft void
.Fo ffi_call
.Fa "ffi_cif *cif"
.Fa "void (*fn)(void)"
.Fa "void *rvalue"
.Fa "void **avalue"
.Fc
.Sh DESCRIPTION
The foreign function interface provides a mechanism by which a function can
generate a call to another function at runtime without requiring knowledge of
the called function's interface at compile time.
.Sh SEE ALSO
.Xr ffi_prep_cif 3 ,
.Xr ffi_call 3

View File

@@ -0,0 +1,103 @@
.Dd February 15, 2008
.Dt ffi_call 3
.Sh NAME
.Nm ffi_call
.Nd Invoke a foreign function.
.Sh SYNOPSIS
.In ffi.h
.Ft void
.Fo ffi_call
.Fa "ffi_cif *cif"
.Fa "void (*fn)(void)"
.Fa "void *rvalue"
.Fa "void **avalue"
.Fc
.Sh DESCRIPTION
The
.Nm ffi_call
function provides a simple mechanism for invoking a function without
requiring knowledge of the function's interface at compile time.
.Fa fn
is called with the values retrieved from the pointers in the
.Fa avalue
array. The return value from
.Fa fn
is placed in storage pointed to by
.Fa rvalue .
.Fa cif
contains information describing the data types, sizes and alignments of the
arguments to and return value from
.Fa fn ,
and must be initialized with
.Nm ffi_prep_cif
before it is used with
.Nm ffi_call .
.Pp
.Fa rvalue
must point to storage that is sizeof(ffi_arg) or larger for non-floating point
types. For smaller-sized return value types, the
.Nm ffi_arg
or
.Nm ffi_sarg
integral type must be used to hold
the return value.
.Sh EXAMPLES
.Bd -literal
#include <ffi/ffi.h>
#include <stdio.h>
unsigned char
foo(unsigned int, float);
int
main(int argc, const char **argv)
{
ffi_cif cif;
ffi_type *arg_types[2];
void *arg_values[2];
ffi_status status;
// Because the return value from foo() is smaller than sizeof(long), it
// must be passed as ffi_arg or ffi_sarg.
ffi_arg result;
// Specify the data type of each argument. Available types are defined
// in <ffi/ffi.h>.
arg_types[0] = &ffi_type_uint;
arg_types[1] = &ffi_type_float;
// Prepare the ffi_cif structure.
if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
2, &ffi_type_uint8, arg_types)) != FFI_OK)
{
// Handle the ffi_status error.
}
// Specify the values of each argument.
unsigned int arg1 = 42;
float arg2 = 5.1;
arg_values[0] = &arg1;
arg_values[1] = &arg2;
// Invoke the function.
ffi_call(&cif, FFI_FN(foo), &result, arg_values);
// The ffi_arg 'result' now contains the unsigned char returned from foo(),
// which can be accessed by a typecast.
printf("result is %hhu", (unsigned char)result);
return 0;
}
// The target function.
unsigned char
foo(unsigned int x, float y)
{
unsigned char result = x - y;
return result;
}
.Ed
.Sh SEE ALSO
.Xr ffi 3 ,
.Xr ffi_prep_cif 3

View File

@@ -0,0 +1,66 @@
.Dd February 15, 2008
.Dt ffi_prep_cif 3
.Sh NAME
.Nm ffi_prep_cif
.Nd Prepare a
.Nm ffi_cif
structure for use with
.Nm ffi_call
.
.Sh SYNOPSIS
.In ffi.h
.Ft ffi_status
.Fo ffi_prep_cif
.Fa "ffi_cif *cif"
.Fa "ffi_abi abi"
.Fa "unsigned int nargs"
.Fa "ffi_type *rtype"
.Fa "ffi_type **atypes"
.Fc
.Sh DESCRIPTION
The
.Nm ffi_prep_cif
function prepares a
.Nm ffi_cif
structure for use with
.Nm ffi_call
.
.Fa abi
specifies a set of calling conventions to use.
.Fa atypes
is an array of
.Fa nargs
pointers to
.Nm ffi_type
structs that describe the data type, size and alignment of each argument.
.Fa rtype
points to an
.Nm ffi_type
that describes the data type, size and alignment of the
return value.
.Sh RETURN VALUES
Upon successful completion,
.Nm ffi_prep_cif
returns
.Nm FFI_OK .
It will return
.Nm FFI_BAD_TYPEDEF
if
.Fa cif
is
.Nm NULL
or
.Fa atypes
or
.Fa rtype
is malformed. If
.Fa abi
does not refer to a valid ABI,
.Nm FFI_BAD_ABI
will be returned. Available ABIs are
defined in
.Nm <ffitarget.h>
.
.Sh SEE ALSO
.Xr ffi 3 ,
.Xr ffi_call 3

8
man/Makefile.am Normal file
View File

@@ -0,0 +1,8 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS=foreign
EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3

456
man/Makefile.in Normal file
View File

@@ -0,0 +1,456 @@
# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
man3dir = $(mandir)/man3
am__installdirs = "$(DESTDIR)$(man3dir)"
NROFF = nroff
MANS = $(man_MANS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TARGET = @TARGET@
TARGETDIR = @TARGETDIR@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign man/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man3: $(man_MANS)
@$(NORMAL_INSTALL)
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
@list=''; test -n "$(man3dir)" || exit 0; \
{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.3[a-z]*$$/p'; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
done; }
uninstall-man3:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man3dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.3[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
test -z "$$files" || { \
echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@list='$(MANS)'; if test -n "$$list"; then \
list=`for p in $$list; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
if test -n "$$list" && \
grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
echo " typically \`make maintainer-clean' will remove them" >&2; \
exit 1; \
else :; fi; \
else :; fi
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
installdirs:
for dir in "$(DESTDIR)$(man3dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-man
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man: install-man3
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-man
uninstall-man: uninstall-man3
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-man3 \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am uninstall-man uninstall-man3
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

31
man/ffi.3 Normal file
View File

@@ -0,0 +1,31 @@
.Dd February 15, 2008
.Dt FFI 3
.Sh NAME
.Nm FFI
.Nd Foreign Function Interface
.Sh LIBRARY
libffi, -lffi
.Sh SYNOPSIS
.In ffi.h
.Ft ffi_status
.Fo ffi_prep_cif
.Fa "ffi_cif *cif"
.Fa "ffi_abi abi"
.Fa "unsigned int nargs"
.Fa "ffi_type *rtype"
.Fa "ffi_type **atypes"
.Fc
.Ft void
.Fo ffi_call
.Fa "ffi_cif *cif"
.Fa "void (*fn)(void)"
.Fa "void *rvalue"
.Fa "void **avalue"
.Fc
.Sh DESCRIPTION
The foreign function interface provides a mechanism by which a function can
generate a call to another function at runtime without requiring knowledge of
the called function's interface at compile time.
.Sh SEE ALSO
.Xr ffi_prep_cif 3 ,
.Xr ffi_call 3

103
man/ffi_call.3 Normal file
View File

@@ -0,0 +1,103 @@
.Dd February 15, 2008
.Dt ffi_call 3
.Sh NAME
.Nm ffi_call
.Nd Invoke a foreign function.
.Sh SYNOPSIS
.In ffi.h
.Ft void
.Fo ffi_call
.Fa "ffi_cif *cif"
.Fa "void (*fn)(void)"
.Fa "void *rvalue"
.Fa "void **avalue"
.Fc
.Sh DESCRIPTION
The
.Nm ffi_call
function provides a simple mechanism for invoking a function without
requiring knowledge of the function's interface at compile time.
.Fa fn
is called with the values retrieved from the pointers in the
.Fa avalue
array. The return value from
.Fa fn
is placed in storage pointed to by
.Fa rvalue .
.Fa cif
contains information describing the data types, sizes and alignments of the
arguments to and return value from
.Fa fn ,
and must be initialized with
.Nm ffi_prep_cif
before it is used with
.Nm ffi_call .
.Pp
.Fa rvalue
must point to storage that is sizeof(ffi_arg) or larger for non-floating point
types. For smaller-sized return value types, the
.Nm ffi_arg
or
.Nm ffi_sarg
integral type must be used to hold
the return value.
.Sh EXAMPLES
.Bd -literal
#include <ffi/ffi.h>
#include <stdio.h>
unsigned char
foo(unsigned int, float);
int
main(int argc, const char **argv)
{
ffi_cif cif;
ffi_type *arg_types[2];
void *arg_values[2];
ffi_status status;
// Because the return value from foo() is smaller than sizeof(long), it
// must be passed as ffi_arg or ffi_sarg.
ffi_arg result;
// Specify the data type of each argument. Available types are defined
// in <ffi/ffi.h>.
arg_types[0] = &ffi_type_uint;
arg_types[1] = &ffi_type_float;
// Prepare the ffi_cif structure.
if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
2, &ffi_type_uint8, arg_types)) != FFI_OK)
{
// Handle the ffi_status error.
}
// Specify the values of each argument.
unsigned int arg1 = 42;
float arg2 = 5.1;
arg_values[0] = &arg1;
arg_values[1] = &arg2;
// Invoke the function.
ffi_call(&cif, FFI_FN(foo), &result, arg_values);
// The ffi_arg 'result' now contains the unsigned char returned from foo(),
// which can be accessed by a typecast.
printf("result is %hhu", (unsigned char)result);
return 0;
}
// The target function.
unsigned char
foo(unsigned int x, float y)
{
unsigned char result = x - y;
return result;
}
.Ed
.Sh SEE ALSO
.Xr ffi 3 ,
.Xr ffi_prep_cif 3

66
man/ffi_prep_cif.3 Normal file
View File

@@ -0,0 +1,66 @@
.Dd February 15, 2008
.Dt ffi_prep_cif 3
.Sh NAME
.Nm ffi_prep_cif
.Nd Prepare a
.Nm ffi_cif
structure for use with
.Nm ffi_call
.
.Sh SYNOPSIS
.In ffi.h
.Ft ffi_status
.Fo ffi_prep_cif
.Fa "ffi_cif *cif"
.Fa "ffi_abi abi"
.Fa "unsigned int nargs"
.Fa "ffi_type *rtype"
.Fa "ffi_type **atypes"
.Fc
.Sh DESCRIPTION
The
.Nm ffi_prep_cif
function prepares a
.Nm ffi_cif
structure for use with
.Nm ffi_call
.
.Fa abi
specifies a set of calling conventions to use.
.Fa atypes
is an array of
.Fa nargs
pointers to
.Nm ffi_type
structs that describe the data type, size and alignment of each argument.
.Fa rtype
points to an
.Nm ffi_type
that describes the data type, size and alignment of the
return value.
.Sh RETURN VALUES
Upon successful completion,
.Nm ffi_prep_cif
returns
.Nm FFI_OK .
It will return
.Nm FFI_BAD_TYPEDEF
if
.Fa cif
is
.Nm NULL
or
.Fa atypes
or
.Fa rtype
is malformed. If
.Fa abi
does not refer to a valid ABI,
.Nm FFI_BAD_ABI
will be returned. Available ABIs are
defined in
.Nm <ffitarget.h>
.
.Sh SEE ALSO
.Xr ffi 3 ,
.Xr ffi_call 3

311
src/.svn/entries Normal file
View File

@@ -0,0 +1,311 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/src
svn://gcc.gnu.org/svn/gcc
2009-09-28T22:26:25.100883Z
152256
ktietz
138bc75d-0d04-0410-961f-82ee72b054a4
arm
dir
powerpc
dir
closures.c
file
2009-09-10T17:50:58.000000Z
3c6816c5a57dc7a877a092b6c1403929
2009-07-24T10:12:16.542948Z
150042
davek
16348
m32r
dir
sh64
dir
x86
dir
alpha
dir
m68k
dir
types.c
file
2009-06-10T05:25:03.000000Z
50ac67d061e9312c64b3ed7662b64e13
2009-06-04T15:11:12.475454Z
148171
aph
2904
frv
dir
s390
dir
cris
dir
pa
dir
ia64
dir
raw_api.c
file
2009-06-10T05:25:03.000000Z
a9086fc5c1b5440f02dcbc425f093ae5
2009-06-04T15:43:03.499507Z
148172
aph
6067
java_raw_api.c
file
2009-09-16T16:25:59.000000Z
797fe5e8686ab2b9f496e7c991ad685e
2009-09-15T17:15:33.045042Z
151726
daney
8473
debug.c
file
2009-06-10T05:25:03.000000Z
02e0fc4e091091ebd2f78437bfd37d1b
2009-06-04T15:11:12.475454Z
148171
aph
2233
sparc
dir
mips
dir
prep_cif.c
file
2009-06-10T05:25:03.000000Z
38a061bf43e144832f0aa2542dab6efb
2009-06-04T15:11:12.475454Z
148171
aph
5318
dlmalloc.c
file
2009-06-20T15:53:35.000000Z
f5cc93a1921927f21dc08d81a631981d
2009-06-12T15:57:58.721771Z
148433
aph
181631
sh
dir

View File

@@ -0,0 +1,610 @@
/* -----------------------------------------------------------------------
closures.c - Copyright (c) 2007 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Code to allocate and deallocate memory for closures.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#if defined __linux__ && !defined _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <ffi.h>
#include <ffi_common.h>
#ifndef FFI_MMAP_EXEC_WRIT
# if __gnu_linux__
/* This macro indicates it may be forbidden to map anonymous memory
with both write and execute permission. Code compiled when this
option is defined will attempt to map such pages once, but if it
fails, it falls back to creating a temporary file in a writable and
executable filesystem and mapping pages from it into separate
locations in the virtual memory space, one location writable and
another executable. */
# define FFI_MMAP_EXEC_WRIT 1
# define HAVE_MNTENT 1
# endif
# if defined(X86_WIN32) || defined(X86_WIN64)
/* Windows systems may have Data Execution Protection (DEP) enabled,
which requires the use of VirtualMalloc/VirtualFree to alloc/free
executable memory. */
# define FFI_MMAP_EXEC_WRIT 1
# endif
#endif
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
# ifdef __linux__
/* When defined to 1 check for SELinux and if SELinux is active,
don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
might cause audit messages. */
# define FFI_MMAP_EXEC_SELINUX 1
# endif
#endif
#if FFI_CLOSURES
# if FFI_MMAP_EXEC_WRIT
#define USE_LOCKS 1
#define USE_DL_PREFIX 1
#ifdef __GNUC__
#ifndef USE_BUILTIN_FFS
#define USE_BUILTIN_FFS 1
#endif
#endif
/* We need to use mmap, not sbrk. */
#define HAVE_MORECORE 0
/* We could, in theory, support mremap, but it wouldn't buy us anything. */
#define HAVE_MREMAP 0
/* We have no use for this, so save some code and data. */
#define NO_MALLINFO 1
/* We need all allocations to be in regular segments, otherwise we
lose track of the corresponding code address. */
#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
/* Don't allocate more than a page unless needed. */
#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
#if FFI_CLOSURE_TEST
/* Don't release single pages, to avoid a worst-case scenario of
continuously allocating and releasing single pages, but release
pairs of pages, which should do just as well given that allocations
are likely to be small. */
#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#if !defined(X86_WIN32) && !defined(X86_WIN64)
#ifdef HAVE_MNTENT
#include <mntent.h>
#endif /* HAVE_MNTENT */
#include <sys/param.h>
#include <pthread.h>
/* We don't want sys/mman.h to be included after we redefine mmap and
dlmunmap. */
#include <sys/mman.h>
#define LACKS_SYS_MMAN_H 1
#if FFI_MMAP_EXEC_SELINUX
#include <sys/statfs.h>
#include <stdlib.h>
static int selinux_enabled = -1;
static int
selinux_enabled_check (void)
{
struct statfs sfs;
FILE *f;
char *buf = NULL;
size_t len = 0;
if (statfs ("/selinux", &sfs) >= 0
&& (unsigned int) sfs.f_type == 0xf97cff8cU)
return 1;
f = fopen ("/proc/mounts", "r");
if (f == NULL)
return 0;
while (getline (&buf, &len, f) >= 0)
{
char *p = strchr (buf, ' ');
if (p == NULL)
break;
p = strchr (p + 1, ' ');
if (p == NULL)
break;
if (strncmp (p + 1, "selinuxfs ", 10) != 0)
{
free (buf);
fclose (f);
return 1;
}
}
free (buf);
fclose (f);
return 0;
}
#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
: (selinux_enabled = selinux_enabled_check ()))
#else
#define is_selinux_enabled() 0
#endif /* !FFI_MMAP_EXEC_SELINUX */
#elif defined (__CYGWIN__)
#include <sys/mman.h>
/* Cygwin is Linux-like, but not quite that Linux-like. */
#define is_selinux_enabled() 0
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Declare all functions defined in dlmalloc.c as static. */
static void *dlmalloc(size_t);
static void dlfree(void*);
static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
static void *dlvalloc(size_t) MAYBE_UNUSED;
static int dlmallopt(int, int) MAYBE_UNUSED;
static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
static void *dlpvalloc(size_t) MAYBE_UNUSED;
static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
#define mmap dlmmap
#define munmap dlmunmap
#include "dlmalloc.c"
#undef mmap
#undef munmap
#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
/* A file descriptor of a temporary file from which we'll map
executable pages. */
static int execfd = -1;
/* The amount of space already allocated from the temporary file. */
static size_t execsize = 0;
/* Open a temporary file name, and immediately unlink it. */
static int
open_temp_exec_file_name (char *name)
{
int fd = mkstemp (name);
if (fd != -1)
unlink (name);
return fd;
}
/* Open a temporary file in the named directory. */
static int
open_temp_exec_file_dir (const char *dir)
{
static const char suffix[] = "/ffiXXXXXX";
int lendir = strlen (dir);
char *tempname = __builtin_alloca (lendir + sizeof (suffix));
if (!tempname)
return -1;
memcpy (tempname, dir, lendir);
memcpy (tempname + lendir, suffix, sizeof (suffix));
return open_temp_exec_file_name (tempname);
}
/* Open a temporary file in the directory in the named environment
variable. */
static int
open_temp_exec_file_env (const char *envvar)
{
const char *value = getenv (envvar);
if (!value)
return -1;
return open_temp_exec_file_dir (value);
}
#ifdef HAVE_MNTENT
/* Open a temporary file in an executable and writable mount point
listed in the mounts file. Subsequent calls with the same mounts
keep searching for mount points in the same file. Providing NULL
as the mounts file closes the file. */
static int
open_temp_exec_file_mnt (const char *mounts)
{
static const char *last_mounts;
static FILE *last_mntent;
if (mounts != last_mounts)
{
if (last_mntent)
endmntent (last_mntent);
last_mounts = mounts;
if (mounts)
last_mntent = setmntent (mounts, "r");
else
last_mntent = NULL;
}
if (!last_mntent)
return -1;
for (;;)
{
int fd;
struct mntent mnt;
char buf[MAXPATHLEN * 3];
if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)))
return -1;
if (hasmntopt (&mnt, "ro")
|| hasmntopt (&mnt, "noexec")
|| access (mnt.mnt_dir, W_OK))
continue;
fd = open_temp_exec_file_dir (mnt.mnt_dir);
if (fd != -1)
return fd;
}
}
#endif /* HAVE_MNTENT */
/* Instructions to look for a location to hold a temporary file that
can be mapped in for execution. */
static struct
{
int (*func)(const char *);
const char *arg;
int repeat;
} open_temp_exec_file_opts[] = {
{ open_temp_exec_file_env, "TMPDIR", 0 },
{ open_temp_exec_file_dir, "/tmp", 0 },
{ open_temp_exec_file_dir, "/var/tmp", 0 },
{ open_temp_exec_file_dir, "/dev/shm", 0 },
{ open_temp_exec_file_env, "HOME", 0 },
#ifdef HAVE_MNTENT
{ open_temp_exec_file_mnt, "/etc/mtab", 1 },
{ open_temp_exec_file_mnt, "/proc/mounts", 1 },
#endif /* HAVE_MNTENT */
};
/* Current index into open_temp_exec_file_opts. */
static int open_temp_exec_file_opts_idx = 0;
/* Reset a current multi-call func, then advances to the next entry.
If we're at the last, go back to the first and return nonzero,
otherwise return zero. */
static int
open_temp_exec_file_opts_next (void)
{
if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
open_temp_exec_file_opts_idx++;
if (open_temp_exec_file_opts_idx
== (sizeof (open_temp_exec_file_opts)
/ sizeof (*open_temp_exec_file_opts)))
{
open_temp_exec_file_opts_idx = 0;
return 1;
}
return 0;
}
/* Return a file descriptor of a temporary zero-sized file in a
writable and exexutable filesystem. */
static int
open_temp_exec_file (void)
{
int fd;
do
{
fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
|| fd == -1)
{
if (open_temp_exec_file_opts_next ())
break;
}
}
while (fd == -1);
return fd;
}
/* Map in a chunk of memory from the temporary exec file into separate
locations in the virtual memory address space, one writable and one
executable. Returns the address of the writable portion, after
storing an offset to the corresponding executable portion at the
last word of the requested chunk. */
static void *
dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
{
void *ptr;
if (execfd == -1)
{
open_temp_exec_file_opts_idx = 0;
retry_open:
execfd = open_temp_exec_file ();
if (execfd == -1)
return MFAIL;
}
offset = execsize;
if (ftruncate (execfd, offset + length))
return MFAIL;
flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
flags |= MAP_SHARED;
ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
flags, execfd, offset);
if (ptr == MFAIL)
{
if (!offset)
{
close (execfd);
goto retry_open;
}
ftruncate (execfd, offset);
return MFAIL;
}
else if (!offset
&& open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
open_temp_exec_file_opts_next ();
start = mmap (start, length, prot, flags, execfd, offset);
if (start == MFAIL)
{
munmap (ptr, length);
ftruncate (execfd, offset);
return start;
}
mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
execsize += length;
return start;
}
/* Map in a writable and executable chunk of memory if possible.
Failing that, fall back to dlmmap_locked. */
static void *
dlmmap (void *start, size_t length, int prot,
int flags, int fd, off_t offset)
{
void *ptr;
assert (start == NULL && length % malloc_getpagesize == 0
&& prot == (PROT_READ | PROT_WRITE)
&& flags == (MAP_PRIVATE | MAP_ANONYMOUS)
&& fd == -1 && offset == 0);
#if FFI_CLOSURE_TEST
printf ("mapping in %zi\n", length);
#endif
if (execfd == -1 && !is_selinux_enabled ())
{
ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
/* Cool, no need to mess with separate segments. */
return ptr;
/* If MREMAP_DUP is ever introduced and implemented, try mmap
with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
MREMAP_DUP and prot at this point. */
}
if (execsize == 0 || execfd == -1)
{
pthread_mutex_lock (&open_temp_exec_file_mutex);
ptr = dlmmap_locked (start, length, prot, flags, offset);
pthread_mutex_unlock (&open_temp_exec_file_mutex);
return ptr;
}
return dlmmap_locked (start, length, prot, flags, offset);
}
/* Release memory at the given address, as well as the corresponding
executable page if it's separate. */
static int
dlmunmap (void *start, size_t length)
{
/* We don't bother decreasing execsize or truncating the file, since
we can't quite tell whether we're unmapping the end of the file.
We don't expect frequent deallocation anyway. If we did, we
could locate pages in the file by writing to the pages being
deallocated and checking that the file contents change.
Yuck. */
msegmentptr seg = segment_holding (gm, start);
void *code;
#if FFI_CLOSURE_TEST
printf ("unmapping %zi\n", length);
#endif
if (seg && (code = add_segment_exec_offset (start, seg)) != start)
{
int ret = munmap (code, length);
if (ret)
return ret;
}
return munmap (start, length);
}
#if FFI_CLOSURE_FREE_CODE
/* Return segment holding given code address. */
static msegmentptr
segment_holding_code (mstate m, char* addr)
{
msegmentptr sp = &m->seg;
for (;;) {
if (addr >= add_segment_exec_offset (sp->base, sp)
&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
return sp;
if ((sp = sp->next) == 0)
return 0;
}
}
#endif
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
corresponding virtual address. */
void *
ffi_closure_alloc (size_t size, void **code)
{
void *ptr;
if (!code)
return NULL;
ptr = dlmalloc (size);
if (ptr)
{
msegmentptr seg = segment_holding (gm, ptr);
*code = add_segment_exec_offset (ptr, seg);
}
return ptr;
}
/* Release a chunk of memory allocated with ffi_closure_alloc. If
FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
writable or the executable address given. Otherwise, only the
writable address can be provided here. */
void
ffi_closure_free (void *ptr)
{
#if FFI_CLOSURE_FREE_CODE
msegmentptr seg = segment_holding_code (gm, ptr);
if (seg)
ptr = sub_segment_exec_offset (ptr, seg);
#endif
dlfree (ptr);
}
#if FFI_CLOSURE_TEST
/* Do some internal sanity testing to make sure allocation and
deallocation of pages are working as intended. */
int main ()
{
void *p[3];
#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
GET (0, malloc_getpagesize / 2);
GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
PUT (1);
GET (1, 2 * malloc_getpagesize);
GET (2, malloc_getpagesize / 2);
PUT (1);
PUT (0);
PUT (2);
return 0;
}
#endif /* FFI_CLOSURE_TEST */
# else /* ! FFI_MMAP_EXEC_WRIT */
/* On many systems, memory returned by malloc is writable and
executable, so just use it. */
#include <stdlib.h>
void *
ffi_closure_alloc (size_t size, void **code)
{
if (!code)
return NULL;
return *code = malloc (size);
}
void
ffi_closure_free (void *ptr)
{
free (ptr);
}
# endif /* ! FFI_MMAP_EXEC_WRIT */
#endif /* FFI_CLOSURES */

View File

@@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------
debug.c - Copyright (c) 1996 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#include <stdio.h>
/* General debugging routines */
void ffi_stop_here(void)
{
/* This function is only useful for debugging purposes.
Place a breakpoint on ffi_stop_here to be notified of
significant events. */
}
/* This function should only be called via the FFI_ASSERT() macro */
void ffi_assert(char *expr, char *file, int line)
{
fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);
ffi_stop_here();
abort();
}
/* Perform a sanity check on an ffi_type structure */
void ffi_type_test(ffi_type *a, char *file, int line)
{
FFI_ASSERT_AT(a != NULL, file, line);
FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,356 @@
/* -----------------------------------------------------------------------
java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
Cloned from raw_api.c
Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
$Id $
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* This defines a Java- and 64-bit specific variant of the raw API. */
/* It assumes that "raw" argument blocks look like Java stacks on a */
/* 64-bit machine. Arguments that can be stored in a single stack */
/* stack slots (longs, doubles) occupy 128 bits, but only the first */
/* 64 bits are actually used. */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
size_t
ffi_java_raw_size (ffi_cif *cif)
{
size_t result = 0;
int i;
ffi_type **at = cif->arg_types;
for (i = cif->nargs-1; i >= 0; i--, at++)
{
switch((*at) -> type) {
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE:
result += 2 * FFI_SIZEOF_JAVA_RAW;
break;
case FFI_TYPE_STRUCT:
/* No structure parameters in Java. */
abort();
default:
result += FFI_SIZEOF_JAVA_RAW;
}
}
return result;
}
void
ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
{
unsigned i;
ffi_type **tp = cif->arg_types;
#if WORDS_BIGENDIAN
for (i = 0; i < cif->nargs; i++, tp++, args++)
{
switch ((*tp)->type)
{
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
*args = (void*) ((char*)(raw++) + 3);
break;
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
*args = (void*) ((char*)(raw++) + 2);
break;
#if FFI_SIZEOF_JAVA_RAW == 8
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE:
*args = (void *)raw;
raw += 2;
break;
#endif
case FFI_TYPE_POINTER:
*args = (void*) &(raw++)->ptr;
break;
default:
*args = raw;
raw +=
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
}
}
#else /* WORDS_BIGENDIAN */
#if !PDP
/* then assume little endian */
for (i = 0; i < cif->nargs; i++, tp++, args++)
{
#if FFI_SIZEOF_JAVA_RAW == 8
switch((*tp)->type) {
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE:
*args = (void*) raw;
raw += 2;
break;
default:
*args = (void*) raw++;
}
#else /* FFI_SIZEOF_JAVA_RAW != 8 */
*args = (void*) raw;
raw +=
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
#endif /* FFI_SIZEOF_JAVA_RAW == 8 */
}
#else
#error "pdp endian not supported"
#endif /* ! PDP */
#endif /* WORDS_BIGENDIAN */
}
void
ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
{
unsigned i;
ffi_type **tp = cif->arg_types;
for (i = 0; i < cif->nargs; i++, tp++, args++)
{
switch ((*tp)->type)
{
case FFI_TYPE_UINT8:
#if WORDS_BIGENDIAN
*(UINT32*)(raw++) = *(UINT8*) (*args);
#else
(raw++)->uint = *(UINT8*) (*args);
#endif
break;
case FFI_TYPE_SINT8:
#if WORDS_BIGENDIAN
*(SINT32*)(raw++) = *(SINT8*) (*args);
#else
(raw++)->sint = *(SINT8*) (*args);
#endif
break;
case FFI_TYPE_UINT16:
#if WORDS_BIGENDIAN
*(UINT32*)(raw++) = *(UINT16*) (*args);
#else
(raw++)->uint = *(UINT16*) (*args);
#endif
break;
case FFI_TYPE_SINT16:
#if WORDS_BIGENDIAN
*(SINT32*)(raw++) = *(SINT16*) (*args);
#else
(raw++)->sint = *(SINT16*) (*args);
#endif
break;
case FFI_TYPE_UINT32:
#if WORDS_BIGENDIAN
*(UINT32*)(raw++) = *(UINT32*) (*args);
#else
(raw++)->uint = *(UINT32*) (*args);
#endif
break;
case FFI_TYPE_SINT32:
#if WORDS_BIGENDIAN
*(SINT32*)(raw++) = *(SINT32*) (*args);
#else
(raw++)->sint = *(SINT32*) (*args);
#endif
break;
case FFI_TYPE_FLOAT:
(raw++)->flt = *(FLOAT32*) (*args);
break;
#if FFI_SIZEOF_JAVA_RAW == 8
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE:
raw->uint = *(UINT64*) (*args);
raw += 2;
break;
#endif
case FFI_TYPE_POINTER:
(raw++)->ptr = **(void***) args;
break;
default:
#if FFI_SIZEOF_JAVA_RAW == 8
FFI_ASSERT(0); /* Should have covered all cases */
#else
memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
raw +=
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
#endif
}
}
}
#if !FFI_NATIVE_RAW_API
static void
ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
{
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
switch (cif->rtype->type)
{
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_UINT32:
*(UINT64 *)rvalue <<= 32;
break;
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_INT:
#if FFI_SIZEOF_JAVA_RAW == 4
case FFI_TYPE_POINTER:
#endif
*(SINT64 *)rvalue <<= 32;
break;
default:
break;
}
#endif
}
static void
ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
{
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
switch (cif->rtype->type)
{
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_UINT32:
*(UINT64 *)rvalue >>= 32;
break;
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_INT:
*(SINT64 *)rvalue >>= 32;
break;
default:
break;
}
#endif
}
/* This is a generic definition of ffi_raw_call, to be used if the
* native system does not provide a machine-specific implementation.
* Having this, allows code to be written for the raw API, without
* the need for system-specific code to handle input in that format;
* these following couple of functions will handle the translation forth
* and back automatically. */
void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
ffi_java_raw *raw)
{
void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
ffi_java_raw_to_ptrarray (cif, raw, avalue);
ffi_call (cif, fn, rvalue, avalue);
ffi_java_rvalue_to_raw (cif, rvalue);
}
#if FFI_CLOSURES /* base system provides closures */
static void
ffi_java_translate_args (ffi_cif *cif, void *rvalue,
void **avalue, void *user_data)
{
ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
ffi_java_ptrarray_to_raw (cif, avalue, raw);
(*cl->fun) (cif, rvalue, raw, cl->user_data);
ffi_java_raw_to_rvalue (cif, rvalue);
}
ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc)
{
ffi_status status;
status = ffi_prep_closure_loc ((ffi_closure*) cl,
cif,
&ffi_java_translate_args,
codeloc,
codeloc);
if (status == FFI_OK)
{
cl->fun = fun;
cl->user_data = user_data;
}
return status;
}
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data)
{
return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
}
#endif /* FFI_CLOSURES */
#endif /* !FFI_NATIVE_RAW_API */
#endif /* !FFI_NO_RAW_API */

View File

@@ -0,0 +1,174 @@
/* -----------------------------------------------------------------------
prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* Round up to FFI_SIZEOF_ARG. */
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
/* Perform machine independent initialization of aggregate type
specifications. */
static ffi_status initialize_aggregate(ffi_type *arg)
{
ffi_type **ptr;
FFI_ASSERT(arg != NULL);
FFI_ASSERT(arg->elements != NULL);
FFI_ASSERT(arg->size == 0);
FFI_ASSERT(arg->alignment == 0);
ptr = &(arg->elements[0]);
while ((*ptr) != NULL)
{
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
/* Perform a sanity check on the argument type */
FFI_ASSERT_VALID_TYPE(*ptr);
arg->size = ALIGN(arg->size, (*ptr)->alignment);
arg->size += (*ptr)->size;
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
ptr++;
}
/* Structure size includes tail padding. This is important for
structures that fit in one register on ABIs like the PowerPC64
Linux ABI that right justify small structs in a register.
It's also needed for nested structure layout, for example
struct A { long a; char b; }; struct B { struct A x; char y; };
should find y at an offset of 2*sizeof(long) and result in a
total size of 3*sizeof(long). */
arg->size = ALIGN (arg->size, arg->alignment);
if (arg->size == 0)
return FFI_BAD_TYPEDEF;
else
return FFI_OK;
}
#ifndef __CRIS__
/* The CRIS ABI specifies structure elements to have byte
alignment only, so it completely overrides this functions,
which assumes "natural" alignment and padding. */
/* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */
ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
ffi_type *rtype, ffi_type **atypes)
{
unsigned bytes = 0;
unsigned int i;
ffi_type **ptr;
FFI_ASSERT(cif != NULL);
FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
cif->abi = abi;
cif->arg_types = atypes;
cif->nargs = nargs;
cif->rtype = rtype;
cif->flags = 0;
/* Initialize the return type if necessary */
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
return FFI_BAD_TYPEDEF;
/* Perform a sanity check on the return type */
FFI_ASSERT_VALID_TYPE(cif->rtype);
/* x86-64 and s390 stack space allocation is handled in prep_machdep. */
#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
/* Make space for the return structure pointer */
if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif
#ifdef X86_DARWIN
&& (cif->rtype->size > 8)
#endif
)
bytes = STACK_ARG_SIZE(sizeof(void*));
#endif
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
/* Initialize any uninitialized aggregate type definitions */
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
/* Perform a sanity check on the argument type, do this
check after the initialization. */
FFI_ASSERT_VALID_TYPE(*ptr);
#if !defined __x86_64__ && !defined S390 && !defined PA
#ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|| ((*ptr)->type == FFI_TYPE_LONGDOUBLE
&& cif->abi != FFI_V9))
bytes += sizeof(void*);
else
#endif
{
/* Add any padding if necessary */
if (((*ptr)->alignment - 1) & bytes)
bytes = ALIGN(bytes, (*ptr)->alignment);
bytes += STACK_ARG_SIZE((*ptr)->size);
}
#endif
}
cif->bytes = bytes;
/* Perform machine dependent cif processing */
return ffi_prep_cif_machdep(cif);
}
#endif /* not __CRIS__ */
#if FFI_CLOSURES
ffi_status
ffi_prep_closure (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data)
{
return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
}
#endif

View File

@@ -0,0 +1,254 @@
/* -----------------------------------------------------------------------
raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
Author: Kresten Krab Thorup <krab@gnu.org>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* This file defines generic functions for use with the raw api. */
#include <ffi.h>
#include <ffi_common.h>
#if !FFI_NO_RAW_API
size_t
ffi_raw_size (ffi_cif *cif)
{
size_t result = 0;
int i;
ffi_type **at = cif->arg_types;
for (i = cif->nargs-1; i >= 0; i--, at++)
{
#if !FFI_NO_STRUCTS
if ((*at)->type == FFI_TYPE_STRUCT)
result += ALIGN (sizeof (void*), FFI_SIZEOF_ARG);
else
#endif
result += ALIGN ((*at)->size, FFI_SIZEOF_ARG);
}
return result;
}
void
ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
{
unsigned i;
ffi_type **tp = cif->arg_types;
#if WORDS_BIGENDIAN
for (i = 0; i < cif->nargs; i++, tp++, args++)
{
switch ((*tp)->type)
{
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
*args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);
break;
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
*args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);
break;
#if FFI_SIZEOF_ARG >= 4
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
*args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);
break;
#endif
#if !FFI_NO_STRUCTS
case FFI_TYPE_STRUCT:
*args = (raw++)->ptr;
break;
#endif
case FFI_TYPE_POINTER:
*args = (void*) &(raw++)->ptr;
break;
default:
*args = raw;
raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
}
}
#else /* WORDS_BIGENDIAN */
#if !PDP
/* then assume little endian */
for (i = 0; i < cif->nargs; i++, tp++, args++)
{
#if !FFI_NO_STRUCTS
if ((*tp)->type == FFI_TYPE_STRUCT)
{
*args = (raw++)->ptr;
}
else
#endif
{
*args = (void*) raw;
raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
}
}
#else
#error "pdp endian not supported"
#endif /* ! PDP */
#endif /* WORDS_BIGENDIAN */
}
void
ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
{
unsigned i;
ffi_type **tp = cif->arg_types;
for (i = 0; i < cif->nargs; i++, tp++, args++)
{
switch ((*tp)->type)
{
case FFI_TYPE_UINT8:
(raw++)->uint = *(UINT8*) (*args);
break;
case FFI_TYPE_SINT8:
(raw++)->sint = *(SINT8*) (*args);
break;
case FFI_TYPE_UINT16:
(raw++)->uint = *(UINT16*) (*args);
break;
case FFI_TYPE_SINT16:
(raw++)->sint = *(SINT16*) (*args);
break;
#if FFI_SIZEOF_ARG >= 4
case FFI_TYPE_UINT32:
(raw++)->uint = *(UINT32*) (*args);
break;
case FFI_TYPE_SINT32:
(raw++)->sint = *(SINT32*) (*args);
break;
#endif
#if !FFI_NO_STRUCTS
case FFI_TYPE_STRUCT:
(raw++)->ptr = *args;
break;
#endif
case FFI_TYPE_POINTER:
(raw++)->ptr = **(void***) args;
break;
default:
memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
}
}
}
#if !FFI_NATIVE_RAW_API
/* This is a generic definition of ffi_raw_call, to be used if the
* native system does not provide a machine-specific implementation.
* Having this, allows code to be written for the raw API, without
* the need for system-specific code to handle input in that format;
* these following couple of functions will handle the translation forth
* and back automatically. */
void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
{
void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
ffi_raw_to_ptrarray (cif, raw, avalue);
ffi_call (cif, fn, rvalue, avalue);
}
#if FFI_CLOSURES /* base system provides closures */
static void
ffi_translate_args (ffi_cif *cif, void *rvalue,
void **avalue, void *user_data)
{
ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
ffi_ptrarray_to_raw (cif, avalue, raw);
(*cl->fun) (cif, rvalue, raw, cl->user_data);
}
ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc)
{
ffi_status status;
status = ffi_prep_closure_loc ((ffi_closure*) cl,
cif,
&ffi_translate_args,
codeloc,
codeloc);
if (status == FFI_OK)
{
cl->fun = fun;
cl->user_data = user_data;
}
return status;
}
#endif /* FFI_CLOSURES */
#endif /* !FFI_NATIVE_RAW_API */
#if FFI_CLOSURES
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status
ffi_prep_raw_closure (ffi_raw_closure* cl,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data)
{
return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
}
#endif /* FFI_CLOSURES */
#endif /* !FFI_NO_RAW_API */

View File

@@ -0,0 +1,77 @@
/* -----------------------------------------------------------------------
types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
Predefined ffi_types needed by libffi.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* Hide the basic type definitions from the header file, so that we
can redefine them here as "const". */
#define LIBFFI_HIDE_BASIC_TYPES
#include <ffi.h>
#include <ffi_common.h>
/* Type definitions */
#define FFI_TYPEDEF(name, type, id) \
struct struct_align_##name { \
char c; \
type x; \
}; \
const ffi_type ffi_type_##name = { \
sizeof(type), \
offsetof(struct struct_align_##name, x), \
id, NULL \
}
/* Size and alignment are fake here. They must not be 0. */
const ffi_type ffi_type_void = {
1, 1, FFI_TYPE_VOID, NULL
};
FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8);
FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8);
FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16);
FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16);
FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32);
FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32);
FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64);
FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64);
FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER);
FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT);
FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
#ifdef __alpha__
/* Even if we're not configured to default to 128-bit long double,
maintain binary compatibility, as -mlong-double-128 can be used
at any time. */
/* Validate the hard-coded number below. */
# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
#endif

130
src/alpha/.svn/entries Normal file
View File

@@ -0,0 +1,130 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/src/alpha
svn://gcc.gnu.org/svn/gcc
2009-06-04T15:43:03.499507Z
148172
aph
138bc75d-0d04-0410-961f-82ee72b054a4
ffitarget.h
file
2009-06-10T05:25:01.000000Z
d8ebc1ade0e8f0fa0cd86048ad927b6c
2009-06-04T15:11:12.475454Z
148171
aph
1771
ffi.c
file
2009-06-10T05:25:01.000000Z
6c0cd4327058ec8585b09041f1501c2c
2009-06-04T15:43:03.499507Z
148172
aph
7379
osf.S
file
2009-06-10T05:25:01.000000Z
1c2284340e3ec316407056831adf7780
2009-06-04T15:43:03.499507Z
148172
aph
7792

View File

@@ -0,0 +1,284 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc.
Alpha Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
all further uses in this file will refer to the 128-bit type. */
#if defined(__LONG_DOUBLE_128__)
# if FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
#else
# undef FFI_TYPE_LONGDOUBLE
# define FFI_TYPE_LONGDOUBLE 4
#endif
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
FFI_HIDDEN;
extern void ffi_closure_osf(void) FFI_HIDDEN;
ffi_status
ffi_prep_cif_machdep(ffi_cif *cif)
{
/* Adjust cif->bytes to represent a minimum 6 words for the temporary
register argument loading area. */
if (cif->bytes < 6*FFI_SIZEOF_ARG)
cif->bytes = 6*FFI_SIZEOF_ARG;
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
cif->flags = cif->rtype->type;
break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is returned in memory, like a struct. */
cif->flags = FFI_TYPE_STRUCT;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
unsigned long *stack, *argp;
long i, avn;
ffi_type **arg_types;
/* If the return value is a struct and we don't have a return
value address then we need to make one. */
if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
rvalue = alloca(cif->rtype->size);
/* Allocate the space for the arguments, plus 4 words of temp
space for ffi_call_osf. */
argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
if (cif->flags == FFI_TYPE_STRUCT)
*(void **) argp++ = rvalue;
i = 0;
avn = cif->nargs;
arg_types = cif->arg_types;
while (i < avn)
{
size_t size = (*arg_types)->size;
switch ((*arg_types)->type)
{
case FFI_TYPE_SINT8:
*(SINT64 *) argp = *(SINT8 *)(* avalue);
break;
case FFI_TYPE_UINT8:
*(SINT64 *) argp = *(UINT8 *)(* avalue);
break;
case FFI_TYPE_SINT16:
*(SINT64 *) argp = *(SINT16 *)(* avalue);
break;
case FFI_TYPE_UINT16:
*(SINT64 *) argp = *(UINT16 *)(* avalue);
break;
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
/* Note that unsigned 32-bit quantities are sign extended. */
*(SINT64 *) argp = *(SINT32 *)(* avalue);
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
case FFI_TYPE_POINTER:
*(UINT64 *) argp = *(UINT64 *)(* avalue);
break;
case FFI_TYPE_FLOAT:
if (argp - stack < 6)
{
/* Note the conversion -- all the fp regs are loaded as
doubles. The in-register format is the same. */
*(double *) argp = *(float *)(* avalue);
}
else
*(float *) argp = *(float *)(* avalue);
break;
case FFI_TYPE_DOUBLE:
*(double *) argp = *(double *)(* avalue);
break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
*(long double **) argp = (long double *)(* avalue);
size = sizeof (long double *);
break;
case FFI_TYPE_STRUCT:
memcpy(argp, *avalue, (*arg_types)->size);
break;
default:
FFI_ASSERT(0);
}
argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++, arg_types++, avalue++;
}
ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
}
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data,
void *codeloc)
{
unsigned int *tramp;
tramp = (unsigned int *) &closure->tramp[0];
tramp[0] = 0x47fb0401; /* mov $27,$1 */
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */
tramp[3] = 0x47ff041f; /* nop */
*(void **) &tramp[4] = ffi_closure_osf;
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
/* Flush the Icache.
Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
instead, since both Compaq as and gas can handle it.
0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>. */
asm volatile ("call_pal 0x86" : : : "memory");
return FFI_OK;
}
long FFI_HIDDEN
ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
{
ffi_cif *cif;
void **avalue;
ffi_type **arg_types;
long i, avn, argn;
cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *));
argn = 0;
/* Copy the caller's structure return address to that the closure
returns the data directly to the caller. */
if (cif->flags == FFI_TYPE_STRUCT)
{
rvalue = (void *) argp[0];
argn = 1;
}
i = 0;
avn = cif->nargs;
arg_types = cif->arg_types;
/* Grab the addresses of the arguments from the stack frame. */
while (i < avn)
{
size_t size = arg_types[i]->size;
switch (arg_types[i]->type)
{
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
case FFI_TYPE_POINTER:
case FFI_TYPE_STRUCT:
avalue[i] = &argp[argn];
break;
case FFI_TYPE_FLOAT:
if (argn < 6)
{
/* Floats coming from registers need conversion from double
back to float format. */
*(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
avalue[i] = &argp[argn - 6];
}
else
avalue[i] = &argp[argn];
break;
case FFI_TYPE_DOUBLE:
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
avalue[i] = (long double *) argp[argn];
size = sizeof (long double *);
break;
default:
abort ();
}
argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++;
}
/* Invoke the closure. */
closure->fun (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_osf how to perform return type promotions. */
return cif->rtype->type;
}

View File

@@ -0,0 +1,48 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for Alpha.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_OSF,
FFI_LAST_ABI,
FFI_DEFAULT_ABI = FFI_OSF
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#endif

View File

@@ -0,0 +1,366 @@
/* -----------------------------------------------------------------------
osf.S - Copyright (c) 1998, 2001, 2007, 2008 Red Hat
Alpha/OSF Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
.arch ev6
.text
/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
void *raddr, void (*fnaddr)(void));
Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
for this function. This has been allocated by ffi_call. We also
deallocate some of the stack that has been alloca'd. */
.align 3
.globl ffi_call_osf
.ent ffi_call_osf
FFI_HIDDEN(ffi_call_osf)
ffi_call_osf:
.frame $15, 32, $26, 0
.mask 0x4008000, -32
$LFB1:
addq $16,$17,$1
mov $16, $30
stq $26, 0($1)
stq $15, 8($1)
stq $18, 16($1)
mov $1, $15
$LCFI1:
.prologue 0
stq $19, 24($1)
mov $20, $27
# Load up all of the (potential) argument registers.
ldq $16, 0($30)
ldt $f16, 0($30)
ldt $f17, 8($30)
ldq $17, 8($30)
ldt $f18, 16($30)
ldq $18, 16($30)
ldt $f19, 24($30)
ldq $19, 24($30)
ldt $f20, 32($30)
ldq $20, 32($30)
ldt $f21, 40($30)
ldq $21, 40($30)
# Deallocate the register argument area.
lda $30, 48($30)
jsr $26, ($27), 0
ldgp $29, 0($26)
# If the return value pointer is NULL, assume no return value.
ldq $19, 24($15)
ldq $18, 16($15)
ldq $26, 0($15)
$LCFI2:
beq $19, $noretval
# Store the return value out in the proper type.
cmpeq $18, FFI_TYPE_INT, $1
bne $1, $retint
cmpeq $18, FFI_TYPE_FLOAT, $2
bne $2, $retfloat
cmpeq $18, FFI_TYPE_DOUBLE, $3
bne $3, $retdouble
.align 3
$noretval:
ldq $15, 8($15)
ret
.align 4
$retint:
stq $0, 0($19)
nop
ldq $15, 8($15)
ret
.align 4
$retfloat:
sts $f0, 0($19)
nop
ldq $15, 8($15)
ret
.align 4
$retdouble:
stt $f0, 0($19)
nop
ldq $15, 8($15)
ret
$LFE1:
.end ffi_call_osf
/* ffi_closure_osf(...)
Receives the closure argument in $1. */
.align 3
.globl ffi_closure_osf
.ent ffi_closure_osf
FFI_HIDDEN(ffi_closure_osf)
ffi_closure_osf:
.frame $30, 16*8, $26, 0
.mask 0x4000000, -16*8
$LFB2:
ldgp $29, 0($27)
subq $30, 16*8, $30
$LCFI5:
stq $26, 0($30)
$LCFI6:
.prologue 1
# Store all of the potential argument registers in va_list format.
stt $f16, 4*8($30)
stt $f17, 5*8($30)
stt $f18, 6*8($30)
stt $f19, 7*8($30)
stt $f20, 8*8($30)
stt $f21, 9*8($30)
stq $16, 10*8($30)
stq $17, 11*8($30)
stq $18, 12*8($30)
stq $19, 13*8($30)
stq $20, 14*8($30)
stq $21, 15*8($30)
# Call ffi_closure_osf_inner to do the bulk of the work.
mov $1, $16
lda $17, 2*8($30)
lda $18, 10*8($30)
jsr $26, ffi_closure_osf_inner
ldgp $29, 0($26)
ldq $26, 0($30)
# Load up the return value in the proper type.
lda $1, $load_table
s4addq $0, $1, $1
ldl $1, 0($1)
addq $1, $29, $1
jmp $31, ($1), $load_32
.align 4
$load_none:
addq $30, 16*8, $30
ret
.align 4
$load_float:
lds $f0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_double:
ldt $f0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_u8:
#ifdef __alpha_bwx__
ldbu $0, 16($30)
nop
#else
ldq $0, 16($30)
and $0, 255, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_s8:
#ifdef __alpha_bwx__
ldbu $0, 16($30)
sextb $0, $0
#else
ldq $0, 16($30)
sll $0, 56, $0
sra $0, 56, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_u16:
#ifdef __alpha_bwx__
ldwu $0, 16($30)
nop
#else
ldq $0, 16($30)
zapnot $0, 3, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_s16:
#ifdef __alpha_bwx__
ldwu $0, 16($30)
sextw $0, $0
#else
ldq $0, 16($30)
sll $0, 48, $0
sra $0, 48, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_32:
ldl $0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_64:
ldq $0, 16($30)
nop
addq $30, 16*8, $30
ret
$LFE2:
.end ffi_closure_osf
#ifdef __ELF__
.section .rodata
#else
.rdata
#endif
$load_table:
.gprel32 $load_none # FFI_TYPE_VOID
.gprel32 $load_32 # FFI_TYPE_INT
.gprel32 $load_float # FFI_TYPE_FLOAT
.gprel32 $load_double # FFI_TYPE_DOUBLE
.gprel32 $load_none # FFI_TYPE_LONGDOUBLE
.gprel32 $load_u8 # FFI_TYPE_UINT8
.gprel32 $load_s8 # FFI_TYPE_SINT8
.gprel32 $load_u16 # FFI_TYPE_UINT16
.gprel32 $load_s16 # FFI_TYPE_SINT16
.gprel32 $load_32 # FFI_TYPE_UINT32
.gprel32 $load_32 # FFI_TYPE_SINT32
.gprel32 $load_64 # FFI_TYPE_UINT64
.gprel32 $load_64 # FFI_TYPE_SINT64
.gprel32 $load_none # FFI_TYPE_STRUCT
.gprel32 $load_64 # FFI_TYPE_POINTER
/* Assert that the table above is in sync with ffi.h. */
#if FFI_TYPE_FLOAT != 2 \
|| FFI_TYPE_DOUBLE != 3 \
|| FFI_TYPE_UINT8 != 5 \
|| FFI_TYPE_SINT8 != 6 \
|| FFI_TYPE_UINT16 != 7 \
|| FFI_TYPE_SINT16 != 8 \
|| FFI_TYPE_UINT32 != 9 \
|| FFI_TYPE_SINT32 != 10 \
|| FFI_TYPE_UINT64 != 11 \
|| FFI_TYPE_SINT64 != 12 \
|| FFI_TYPE_STRUCT != 13 \
|| FFI_TYPE_POINTER != 14 \
|| FFI_TYPE_LAST != 14
#error "osf.S out of sync with ffi.h"
#endif
#ifdef __ELF__
.section .eh_frame,EH_FRAME_FLAGS,@progbits
__FRAME_BEGIN__:
.4byte $LECIE1-$LSCIE1 # Length of Common Information Entry
$LSCIE1:
.4byte 0x0 # CIE Identifier Tag
.byte 0x1 # CIE Version
.ascii "zR\0" # CIE Augmentation
.byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
.byte 0x78 # sleb128 -8; CIE Data Alignment Factor
.byte 26 # CIE RA Column
.byte 0x1 # uleb128 0x1; Augmentation size
.byte 0x1b # FDE Encoding (pcrel sdata4)
.byte 0xc # DW_CFA_def_cfa
.byte 30 # uleb128 column 30
.byte 0 # uleb128 offset 0
.align 3
$LECIE1:
$LSFDE1:
.4byte $LEFDE1-$LASFDE1 # FDE Length
$LASFDE1:
.4byte $LASFDE1-__FRAME_BEGIN__ # FDE CIE offset
.4byte $LFB1-. # FDE initial location
.4byte $LFE1-$LFB1 # FDE address range
.byte 0x0 # uleb128 0x0; Augmentation size
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI1-$LFB1
.byte 0x9a # DW_CFA_offset, column 26
.byte 4 # uleb128 4*-8
.byte 0x8f # DW_CFA_offset, column 15
.byte 0x3 # uleb128 3*-8
.byte 0xc # DW_CFA_def_cfa
.byte 15 # uleb128 column 15
.byte 32 # uleb128 offset 32
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI2-$LCFI1
.byte 0xda # DW_CFA_restore, column 26
.align 3
$LEFDE1:
$LSFDE3:
.4byte $LEFDE3-$LASFDE3 # FDE Length
$LASFDE3:
.4byte $LASFDE3-__FRAME_BEGIN__ # FDE CIE offset
.4byte $LFB2-. # FDE initial location
.4byte $LFE2-$LFB2 # FDE address range
.byte 0x0 # uleb128 0x0; Augmentation size
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI5-$LFB2
.byte 0xe # DW_CFA_def_cfa_offset
.byte 0x80,0x1 # uleb128 128
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI6-$LCFI5
.byte 0x9a # DW_CFA_offset, column 26
.byte 16 # uleb128 offset 16*-8
.align 3
$LEFDE3:
#ifdef __linux__
.section .note.GNU-stack,"",@progbits
#endif
#endif

284
src/alpha/ffi.c Normal file
View File

@@ -0,0 +1,284 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc.
Alpha Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
all further uses in this file will refer to the 128-bit type. */
#if defined(__LONG_DOUBLE_128__)
# if FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
#else
# undef FFI_TYPE_LONGDOUBLE
# define FFI_TYPE_LONGDOUBLE 4
#endif
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
FFI_HIDDEN;
extern void ffi_closure_osf(void) FFI_HIDDEN;
ffi_status
ffi_prep_cif_machdep(ffi_cif *cif)
{
/* Adjust cif->bytes to represent a minimum 6 words for the temporary
register argument loading area. */
if (cif->bytes < 6*FFI_SIZEOF_ARG)
cif->bytes = 6*FFI_SIZEOF_ARG;
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
cif->flags = cif->rtype->type;
break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is returned in memory, like a struct. */
cif->flags = FFI_TYPE_STRUCT;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
unsigned long *stack, *argp;
long i, avn;
ffi_type **arg_types;
/* If the return value is a struct and we don't have a return
value address then we need to make one. */
if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
rvalue = alloca(cif->rtype->size);
/* Allocate the space for the arguments, plus 4 words of temp
space for ffi_call_osf. */
argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
if (cif->flags == FFI_TYPE_STRUCT)
*(void **) argp++ = rvalue;
i = 0;
avn = cif->nargs;
arg_types = cif->arg_types;
while (i < avn)
{
size_t size = (*arg_types)->size;
switch ((*arg_types)->type)
{
case FFI_TYPE_SINT8:
*(SINT64 *) argp = *(SINT8 *)(* avalue);
break;
case FFI_TYPE_UINT8:
*(SINT64 *) argp = *(UINT8 *)(* avalue);
break;
case FFI_TYPE_SINT16:
*(SINT64 *) argp = *(SINT16 *)(* avalue);
break;
case FFI_TYPE_UINT16:
*(SINT64 *) argp = *(UINT16 *)(* avalue);
break;
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
/* Note that unsigned 32-bit quantities are sign extended. */
*(SINT64 *) argp = *(SINT32 *)(* avalue);
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
case FFI_TYPE_POINTER:
*(UINT64 *) argp = *(UINT64 *)(* avalue);
break;
case FFI_TYPE_FLOAT:
if (argp - stack < 6)
{
/* Note the conversion -- all the fp regs are loaded as
doubles. The in-register format is the same. */
*(double *) argp = *(float *)(* avalue);
}
else
*(float *) argp = *(float *)(* avalue);
break;
case FFI_TYPE_DOUBLE:
*(double *) argp = *(double *)(* avalue);
break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
*(long double **) argp = (long double *)(* avalue);
size = sizeof (long double *);
break;
case FFI_TYPE_STRUCT:
memcpy(argp, *avalue, (*arg_types)->size);
break;
default:
FFI_ASSERT(0);
}
argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++, arg_types++, avalue++;
}
ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
}
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data,
void *codeloc)
{
unsigned int *tramp;
tramp = (unsigned int *) &closure->tramp[0];
tramp[0] = 0x47fb0401; /* mov $27,$1 */
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */
tramp[3] = 0x47ff041f; /* nop */
*(void **) &tramp[4] = ffi_closure_osf;
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
/* Flush the Icache.
Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal
instead, since both Compaq as and gas can handle it.
0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>. */
asm volatile ("call_pal 0x86" : : : "memory");
return FFI_OK;
}
long FFI_HIDDEN
ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
{
ffi_cif *cif;
void **avalue;
ffi_type **arg_types;
long i, avn, argn;
cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *));
argn = 0;
/* Copy the caller's structure return address to that the closure
returns the data directly to the caller. */
if (cif->flags == FFI_TYPE_STRUCT)
{
rvalue = (void *) argp[0];
argn = 1;
}
i = 0;
avn = cif->nargs;
arg_types = cif->arg_types;
/* Grab the addresses of the arguments from the stack frame. */
while (i < avn)
{
size_t size = arg_types[i]->size;
switch (arg_types[i]->type)
{
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
case FFI_TYPE_POINTER:
case FFI_TYPE_STRUCT:
avalue[i] = &argp[argn];
break;
case FFI_TYPE_FLOAT:
if (argn < 6)
{
/* Floats coming from registers need conversion from double
back to float format. */
*(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
avalue[i] = &argp[argn - 6];
}
else
avalue[i] = &argp[argn];
break;
case FFI_TYPE_DOUBLE:
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
avalue[i] = (long double *) argp[argn];
size = sizeof (long double *);
break;
default:
abort ();
}
argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++;
}
/* Invoke the closure. */
closure->fun (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_osf how to perform return type promotions. */
return cif->rtype->type;
}

48
src/alpha/ffitarget.h Normal file
View File

@@ -0,0 +1,48 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for Alpha.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_OSF,
FFI_LAST_ABI,
FFI_DEFAULT_ABI = FFI_OSF
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#endif

366
src/alpha/osf.S Normal file
View File

@@ -0,0 +1,366 @@
/* -----------------------------------------------------------------------
osf.S - Copyright (c) 1998, 2001, 2007, 2008 Red Hat
Alpha/OSF Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
.arch ev6
.text
/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
void *raddr, void (*fnaddr)(void));
Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
for this function. This has been allocated by ffi_call. We also
deallocate some of the stack that has been alloca'd. */
.align 3
.globl ffi_call_osf
.ent ffi_call_osf
FFI_HIDDEN(ffi_call_osf)
ffi_call_osf:
.frame $15, 32, $26, 0
.mask 0x4008000, -32
$LFB1:
addq $16,$17,$1
mov $16, $30
stq $26, 0($1)
stq $15, 8($1)
stq $18, 16($1)
mov $1, $15
$LCFI1:
.prologue 0
stq $19, 24($1)
mov $20, $27
# Load up all of the (potential) argument registers.
ldq $16, 0($30)
ldt $f16, 0($30)
ldt $f17, 8($30)
ldq $17, 8($30)
ldt $f18, 16($30)
ldq $18, 16($30)
ldt $f19, 24($30)
ldq $19, 24($30)
ldt $f20, 32($30)
ldq $20, 32($30)
ldt $f21, 40($30)
ldq $21, 40($30)
# Deallocate the register argument area.
lda $30, 48($30)
jsr $26, ($27), 0
ldgp $29, 0($26)
# If the return value pointer is NULL, assume no return value.
ldq $19, 24($15)
ldq $18, 16($15)
ldq $26, 0($15)
$LCFI2:
beq $19, $noretval
# Store the return value out in the proper type.
cmpeq $18, FFI_TYPE_INT, $1
bne $1, $retint
cmpeq $18, FFI_TYPE_FLOAT, $2
bne $2, $retfloat
cmpeq $18, FFI_TYPE_DOUBLE, $3
bne $3, $retdouble
.align 3
$noretval:
ldq $15, 8($15)
ret
.align 4
$retint:
stq $0, 0($19)
nop
ldq $15, 8($15)
ret
.align 4
$retfloat:
sts $f0, 0($19)
nop
ldq $15, 8($15)
ret
.align 4
$retdouble:
stt $f0, 0($19)
nop
ldq $15, 8($15)
ret
$LFE1:
.end ffi_call_osf
/* ffi_closure_osf(...)
Receives the closure argument in $1. */
.align 3
.globl ffi_closure_osf
.ent ffi_closure_osf
FFI_HIDDEN(ffi_closure_osf)
ffi_closure_osf:
.frame $30, 16*8, $26, 0
.mask 0x4000000, -16*8
$LFB2:
ldgp $29, 0($27)
subq $30, 16*8, $30
$LCFI5:
stq $26, 0($30)
$LCFI6:
.prologue 1
# Store all of the potential argument registers in va_list format.
stt $f16, 4*8($30)
stt $f17, 5*8($30)
stt $f18, 6*8($30)
stt $f19, 7*8($30)
stt $f20, 8*8($30)
stt $f21, 9*8($30)
stq $16, 10*8($30)
stq $17, 11*8($30)
stq $18, 12*8($30)
stq $19, 13*8($30)
stq $20, 14*8($30)
stq $21, 15*8($30)
# Call ffi_closure_osf_inner to do the bulk of the work.
mov $1, $16
lda $17, 2*8($30)
lda $18, 10*8($30)
jsr $26, ffi_closure_osf_inner
ldgp $29, 0($26)
ldq $26, 0($30)
# Load up the return value in the proper type.
lda $1, $load_table
s4addq $0, $1, $1
ldl $1, 0($1)
addq $1, $29, $1
jmp $31, ($1), $load_32
.align 4
$load_none:
addq $30, 16*8, $30
ret
.align 4
$load_float:
lds $f0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_double:
ldt $f0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_u8:
#ifdef __alpha_bwx__
ldbu $0, 16($30)
nop
#else
ldq $0, 16($30)
and $0, 255, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_s8:
#ifdef __alpha_bwx__
ldbu $0, 16($30)
sextb $0, $0
#else
ldq $0, 16($30)
sll $0, 56, $0
sra $0, 56, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_u16:
#ifdef __alpha_bwx__
ldwu $0, 16($30)
nop
#else
ldq $0, 16($30)
zapnot $0, 3, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_s16:
#ifdef __alpha_bwx__
ldwu $0, 16($30)
sextw $0, $0
#else
ldq $0, 16($30)
sll $0, 48, $0
sra $0, 48, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_32:
ldl $0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_64:
ldq $0, 16($30)
nop
addq $30, 16*8, $30
ret
$LFE2:
.end ffi_closure_osf
#ifdef __ELF__
.section .rodata
#else
.rdata
#endif
$load_table:
.gprel32 $load_none # FFI_TYPE_VOID
.gprel32 $load_32 # FFI_TYPE_INT
.gprel32 $load_float # FFI_TYPE_FLOAT
.gprel32 $load_double # FFI_TYPE_DOUBLE
.gprel32 $load_none # FFI_TYPE_LONGDOUBLE
.gprel32 $load_u8 # FFI_TYPE_UINT8
.gprel32 $load_s8 # FFI_TYPE_SINT8
.gprel32 $load_u16 # FFI_TYPE_UINT16
.gprel32 $load_s16 # FFI_TYPE_SINT16
.gprel32 $load_32 # FFI_TYPE_UINT32
.gprel32 $load_32 # FFI_TYPE_SINT32
.gprel32 $load_64 # FFI_TYPE_UINT64
.gprel32 $load_64 # FFI_TYPE_SINT64
.gprel32 $load_none # FFI_TYPE_STRUCT
.gprel32 $load_64 # FFI_TYPE_POINTER
/* Assert that the table above is in sync with ffi.h. */
#if FFI_TYPE_FLOAT != 2 \
|| FFI_TYPE_DOUBLE != 3 \
|| FFI_TYPE_UINT8 != 5 \
|| FFI_TYPE_SINT8 != 6 \
|| FFI_TYPE_UINT16 != 7 \
|| FFI_TYPE_SINT16 != 8 \
|| FFI_TYPE_UINT32 != 9 \
|| FFI_TYPE_SINT32 != 10 \
|| FFI_TYPE_UINT64 != 11 \
|| FFI_TYPE_SINT64 != 12 \
|| FFI_TYPE_STRUCT != 13 \
|| FFI_TYPE_POINTER != 14 \
|| FFI_TYPE_LAST != 14
#error "osf.S out of sync with ffi.h"
#endif
#ifdef __ELF__
.section .eh_frame,EH_FRAME_FLAGS,@progbits
__FRAME_BEGIN__:
.4byte $LECIE1-$LSCIE1 # Length of Common Information Entry
$LSCIE1:
.4byte 0x0 # CIE Identifier Tag
.byte 0x1 # CIE Version
.ascii "zR\0" # CIE Augmentation
.byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
.byte 0x78 # sleb128 -8; CIE Data Alignment Factor
.byte 26 # CIE RA Column
.byte 0x1 # uleb128 0x1; Augmentation size
.byte 0x1b # FDE Encoding (pcrel sdata4)
.byte 0xc # DW_CFA_def_cfa
.byte 30 # uleb128 column 30
.byte 0 # uleb128 offset 0
.align 3
$LECIE1:
$LSFDE1:
.4byte $LEFDE1-$LASFDE1 # FDE Length
$LASFDE1:
.4byte $LASFDE1-__FRAME_BEGIN__ # FDE CIE offset
.4byte $LFB1-. # FDE initial location
.4byte $LFE1-$LFB1 # FDE address range
.byte 0x0 # uleb128 0x0; Augmentation size
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI1-$LFB1
.byte 0x9a # DW_CFA_offset, column 26
.byte 4 # uleb128 4*-8
.byte 0x8f # DW_CFA_offset, column 15
.byte 0x3 # uleb128 3*-8
.byte 0xc # DW_CFA_def_cfa
.byte 15 # uleb128 column 15
.byte 32 # uleb128 offset 32
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI2-$LCFI1
.byte 0xda # DW_CFA_restore, column 26
.align 3
$LEFDE1:
$LSFDE3:
.4byte $LEFDE3-$LASFDE3 # FDE Length
$LASFDE3:
.4byte $LASFDE3-__FRAME_BEGIN__ # FDE CIE offset
.4byte $LFB2-. # FDE initial location
.4byte $LFE2-$LFB2 # FDE address range
.byte 0x0 # uleb128 0x0; Augmentation size
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI5-$LFB2
.byte 0xe # DW_CFA_def_cfa_offset
.byte 0x80,0x1 # uleb128 128
.byte 0x4 # DW_CFA_advance_loc4
.4byte $LCFI6-$LCFI5
.byte 0x9a # DW_CFA_offset, column 26
.byte 16 # uleb128 offset 16*-8
.align 3
$LEFDE3:
#ifdef __linux__
.section .note.GNU-stack,"",@progbits
#endif
#endif

130
src/arm/.svn/entries Normal file
View File

@@ -0,0 +1,130 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/src/arm
svn://gcc.gnu.org/svn/gcc
2009-09-23T14:50:35.044390Z
152075
doko
138bc75d-0d04-0410-961f-82ee72b054a4
ffitarget.h
file
2009-06-10T05:25:00.000000Z
7d755bdfcc6115d45d2547cf7a149df4
2009-06-04T15:11:12.475454Z
148171
aph
1794
ffi.c
file
2009-06-10T05:25:00.000000Z
a0ee6e86ca97fcdd084efc21500ebccd
2009-06-04T15:43:03.499507Z
148172
aph
7974
sysv.S
file
2009-09-27T03:30:26.000000Z
4d876a004cbf93486edab24a0c84a4d8
2009-09-23T14:50:35.044390Z
152075
doko
6925

View File

@@ -0,0 +1,309 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998, 2008 Red Hat, Inc.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
void ffi_prep_args(char *stack, extended_cif *ecif)
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
*(void **) argp = ecif->rvalue;
argp += 4;
}
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0);
i--, p_arg++)
{
size_t z;
/* Align if necessary */
if (((*p_arg)->alignment - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
}
if ((*p_arg)->type == FFI_TYPE_STRUCT)
argp = (char *) ALIGN(argp, 4);
z = (*p_arg)->size;
if (z < sizeof(int))
{
z = sizeof(int);
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
break;
case FFI_TYPE_UINT8:
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
break;
case FFI_TYPE_SINT16:
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
break;
case FFI_TYPE_UINT16:
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
break;
case FFI_TYPE_STRUCT:
memcpy(argp, *p_argv, (*p_arg)->size);
break;
default:
FFI_ASSERT(0);
}
}
else if (z == sizeof(int))
{
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
}
else
{
memcpy(argp, *p_argv, z);
}
p_argv++;
argp += z;
}
return;
}
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
/* Round the stack up to a multiple of 8 bytes. This isn't needed
everywhere, but it is on some platforms, and it doesn't harm anything
when it isn't needed. */
cif->bytes = (cif->bytes + 7) & ~7;
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
cif->flags = (unsigned) FFI_TYPE_SINT64;
break;
case FFI_TYPE_STRUCT:
if (cif->rtype->size <= 4)
/* A Composite Type not larger than 4 bytes is returned in r0. */
cif->flags = (unsigned)FFI_TYPE_INT;
else
/* A Composite Type larger than 4 bytes, or whose size cannot
be determined statically ... is stored in memory at an
address passed [in r0]. */
cif->flags = (unsigned)FFI_TYPE_STRUCT;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
int small_struct = (cif->flags == FFI_TYPE_INT
&& cif->rtype->type == FFI_TYPE_STRUCT);
ecif.cif = cif;
ecif.avalue = avalue;
unsigned int temp;
/* If the return value is a struct and we don't have a return */
/* value address then we need to make one */
if ((rvalue == NULL) &&
(cif->flags == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
else if (small_struct)
ecif.rvalue = &temp;
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
fn);
break;
default:
FFI_ASSERT(0);
break;
}
if (small_struct)
memcpy (rvalue, &temp, cif->rtype->size);
}
/** private members **/
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
void ffi_closure_SYSV (ffi_closure *);
/* This function is jumped to by the trampoline */
unsigned int
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
{
// our various things...
ffi_cif *cif;
void **arg_area;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
/* this call will initialize ARG_AREA, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
* a structure, it will re-set RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
(closure->fun) (cif, *respp, arg_area, closure->user_data);
return cif->flags;
}
/*@-exportheader@*/
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
void **avalue, ffi_cif *cif)
/*@=exportheader@*/
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( cif->flags == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
argp += 4;
}
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
size_t alignment = (*p_arg)->alignment;
if (alignment < 4)
alignment = 4;
/* Align if necessary */
if ((alignment - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, alignment);
}
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
p_argv++;
argp += z;
}
return;
}
/* How to make a trampoline. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
*(unsigned int*) &__tramp[12] = __ctx; \
*(unsigned int*) &__tramp[16] = __fun; \
__clear_cache((&__tramp[0]), (&__tramp[19])); \
})
/* the cif must already be prep'ed */
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
&ffi_closure_SYSV, \
codeloc);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}

View File

@@ -0,0 +1,49 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for ARM.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_SYSV,
FFI_DEFAULT_ABI = FFI_SYSV,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 20
#define FFI_NATIVE_RAW_API 0
#endif

View File

@@ -0,0 +1,306 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
#ifdef HAVE_MACHINE_ASM_H
#include <machine/asm.h>
#else
#ifdef __USER_LABEL_PREFIX__
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
/* Use the right prefix for global labels. */
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
#else
#define CNAME(x) x
#endif
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
#endif
#ifdef __ELF__
#define LSYM(x) .x
#else
#define LSYM(x) x
#endif
/* We need a better way of testing for this, but for now, this is all
we can do. */
@ This selects the minimum architecture level required.
#define __ARM_ARCH__ 3
#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 4
#endif
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|| defined(__ARM_ARCH_5TEJ__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 5
#endif
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|| defined(__ARM_ARCH_6M__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 6
#endif
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 7
#endif
#if __ARM_ARCH__ >= 5
# define call_reg(x) blx x
#elif defined (__ARM_ARCH_4T__)
# define call_reg(x) mov lr, pc ; bx x
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
# define __INTERWORKING__
# endif
#else
# define call_reg(x) mov lr, pc ; mov pc, x
#endif
/* Conditionally compile unwinder directives. */
#ifdef __ARM_EABI__
#define UNWIND
#else
#define UNWIND @
#endif
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
.macro ARM_FUNC_START name
.text
.align 0
.thumb
.thumb_func
ENTRY(\name)
bx pc
nop
.arm
UNWIND .fnstart
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
directly from other local arm routines. */
_L__\name:
.endm
#else
.macro ARM_FUNC_START name
.text
.align 0
.arm
ENTRY(\name)
UNWIND .fnstart
.endm
#endif
.macro RETLDM regs=, cond=, dirn=ia
#if defined (__INTERWORKING__)
.ifc "\regs",""
ldr\cond lr, [sp], #4
.else
ldm\cond\dirn sp!, {\regs, lr}
.endif
bx\cond lr
#else
.ifc "\regs",""
ldr\cond pc, [sp], #4
.else
ldm\cond\dirn sp!, {\regs, pc}
.endif
#endif
.endm
@ r0: ffi_prep_args
@ r1: &ecif
@ r2: cif->bytes
@ r3: fig->flags
@ sp+0: ecif.rvalue
@ sp+4: fn
@ This assumes we are using gas.
ARM_FUNC_START ffi_call_SYSV
@ Save registers
stmfd sp!, {r0-r3, fp, lr}
UNWIND .save {r0-r3, fp, lr}
mov fp, sp
UNWIND .setfp fp, sp
@ Make room for all of the new args.
sub sp, fp, r2
@ Place all of the ffi_prep_args in position
mov ip, r0
mov r0, sp
@ r1 already set
@ Call ffi_prep_args(stack, &ecif)
call_reg(ip)
@ move first 4 parameters in registers
ldmia sp, {r0-r3}
@ and adjust stack
ldr ip, [fp, #8]
cmp ip, #16
movhs ip, #16
add sp, sp, ip
@ call (fn) (...)
ldr ip, [fp, #28]
call_reg(ip)
@ Remove the space we pushed for the args
mov sp, fp
@ Load r2 with the pointer to storage for the return value
ldr r2, [sp, #24]
@ Load r3 with the return type code
ldr r3, [sp, #12]
@ If the return value pointer is NULL, assume no return value.
cmp r2, #0
beq LSYM(Lepilogue)
@ return INT
cmp r3, #FFI_TYPE_INT
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
cmpne r3, #FFI_TYPE_FLOAT
#endif
streq r0, [r2]
beq LSYM(Lepilogue)
@ return INT64
cmp r3, #FFI_TYPE_SINT64
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
cmpne r3, #FFI_TYPE_DOUBLE
#endif
stmeqia r2, {r0, r1}
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
beq LSYM(Lepilogue)
@ return FLOAT
cmp r3, #FFI_TYPE_FLOAT
stfeqs f0, [r2]
beq LSYM(Lepilogue)
@ return DOUBLE or LONGDOUBLE
cmp r3, #FFI_TYPE_DOUBLE
stfeqd f0, [r2]
#endif
LSYM(Lepilogue):
RETLDM "r0-r3,fp"
.ffi_call_SYSV_end:
UNWIND .fnend
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
/*
unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
*/
ARM_FUNC_START ffi_closure_SYSV
UNWIND .pad #16
add ip, sp, #16
stmfd sp!, {ip, lr}
UNWIND .save {r0, lr}
add r2, sp, #8
.pad #16
sub sp, sp, #16
str sp, [sp, #8]
add r1, sp, #8
bl ffi_closure_SYSV_inner
cmp r0, #FFI_TYPE_INT
beq .Lretint
cmp r0, #FFI_TYPE_FLOAT
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
beq .Lretint
#else
beq .Lretfloat
#endif
cmp r0, #FFI_TYPE_DOUBLE
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
beq .Lretlonglong
#else
beq .Lretdouble
#endif
cmp r0, #FFI_TYPE_LONGDOUBLE
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
beq .Lretlonglong
#else
beq .Lretlongdouble
#endif
cmp r0, #FFI_TYPE_SINT64
beq .Lretlonglong
.Lclosure_epilogue:
add sp, sp, #16
ldmfd sp, {sp, pc}
.Lretint:
ldr r0, [sp]
b .Lclosure_epilogue
.Lretlonglong:
ldr r0, [sp]
ldr r1, [sp, #4]
b .Lclosure_epilogue
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
.Lretfloat:
ldfs f0, [sp]
b .Lclosure_epilogue
.Lretdouble:
ldfd f0, [sp]
b .Lclosure_epilogue
.Lretlongdouble:
ldfd f0, [sp]
b .Lclosure_epilogue
#endif
.ffi_closure_SYSV_end:
UNWIND .fnend
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits
#endif

309
src/arm/ffi.c Normal file
View File

@@ -0,0 +1,309 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998, 2008 Red Hat, Inc.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
void ffi_prep_args(char *stack, extended_cif *ecif)
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
*(void **) argp = ecif->rvalue;
argp += 4;
}
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0);
i--, p_arg++)
{
size_t z;
/* Align if necessary */
if (((*p_arg)->alignment - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
}
if ((*p_arg)->type == FFI_TYPE_STRUCT)
argp = (char *) ALIGN(argp, 4);
z = (*p_arg)->size;
if (z < sizeof(int))
{
z = sizeof(int);
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
break;
case FFI_TYPE_UINT8:
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
break;
case FFI_TYPE_SINT16:
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
break;
case FFI_TYPE_UINT16:
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
break;
case FFI_TYPE_STRUCT:
memcpy(argp, *p_argv, (*p_arg)->size);
break;
default:
FFI_ASSERT(0);
}
}
else if (z == sizeof(int))
{
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
}
else
{
memcpy(argp, *p_argv, z);
}
p_argv++;
argp += z;
}
return;
}
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
/* Round the stack up to a multiple of 8 bytes. This isn't needed
everywhere, but it is on some platforms, and it doesn't harm anything
when it isn't needed. */
cif->bytes = (cif->bytes + 7) & ~7;
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
cif->flags = (unsigned) FFI_TYPE_SINT64;
break;
case FFI_TYPE_STRUCT:
if (cif->rtype->size <= 4)
/* A Composite Type not larger than 4 bytes is returned in r0. */
cif->flags = (unsigned)FFI_TYPE_INT;
else
/* A Composite Type larger than 4 bytes, or whose size cannot
be determined statically ... is stored in memory at an
address passed [in r0]. */
cif->flags = (unsigned)FFI_TYPE_STRUCT;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
int small_struct = (cif->flags == FFI_TYPE_INT
&& cif->rtype->type == FFI_TYPE_STRUCT);
ecif.cif = cif;
ecif.avalue = avalue;
unsigned int temp;
/* If the return value is a struct and we don't have a return */
/* value address then we need to make one */
if ((rvalue == NULL) &&
(cif->flags == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
else if (small_struct)
ecif.rvalue = &temp;
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
fn);
break;
default:
FFI_ASSERT(0);
break;
}
if (small_struct)
memcpy (rvalue, &temp, cif->rtype->size);
}
/** private members **/
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
void ffi_closure_SYSV (ffi_closure *);
/* This function is jumped to by the trampoline */
unsigned int
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
{
// our various things...
ffi_cif *cif;
void **arg_area;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
/* this call will initialize ARG_AREA, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
* a structure, it will re-set RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
(closure->fun) (cif, *respp, arg_area, closure->user_data);
return cif->flags;
}
/*@-exportheader@*/
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
void **avalue, ffi_cif *cif)
/*@=exportheader@*/
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( cif->flags == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
argp += 4;
}
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
size_t alignment = (*p_arg)->alignment;
if (alignment < 4)
alignment = 4;
/* Align if necessary */
if ((alignment - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, alignment);
}
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
p_argv++;
argp += z;
}
return;
}
/* How to make a trampoline. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
*(unsigned int*) &__tramp[12] = __ctx; \
*(unsigned int*) &__tramp[16] = __fun; \
__clear_cache((&__tramp[0]), (&__tramp[19])); \
})
/* the cif must already be prep'ed */
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
&ffi_closure_SYSV, \
codeloc);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}

49
src/arm/ffitarget.h Normal file
View File

@@ -0,0 +1,49 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for ARM.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_SYSV,
FFI_DEFAULT_ABI = FFI_SYSV,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 20
#define FFI_NATIVE_RAW_API 0
#endif

306
src/arm/sysv.S Normal file
View File

@@ -0,0 +1,306 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
#ifdef HAVE_MACHINE_ASM_H
#include <machine/asm.h>
#else
#ifdef __USER_LABEL_PREFIX__
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
/* Use the right prefix for global labels. */
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
#else
#define CNAME(x) x
#endif
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
#endif
#ifdef __ELF__
#define LSYM(x) .x
#else
#define LSYM(x) x
#endif
/* We need a better way of testing for this, but for now, this is all
we can do. */
@ This selects the minimum architecture level required.
#define __ARM_ARCH__ 3
#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 4
#endif
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|| defined(__ARM_ARCH_5TEJ__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 5
#endif
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|| defined(__ARM_ARCH_6M__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 6
#endif
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
# undef __ARM_ARCH__
# define __ARM_ARCH__ 7
#endif
#if __ARM_ARCH__ >= 5
# define call_reg(x) blx x
#elif defined (__ARM_ARCH_4T__)
# define call_reg(x) mov lr, pc ; bx x
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
# define __INTERWORKING__
# endif
#else
# define call_reg(x) mov lr, pc ; mov pc, x
#endif
/* Conditionally compile unwinder directives. */
#ifdef __ARM_EABI__
#define UNWIND
#else
#define UNWIND @
#endif
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
.macro ARM_FUNC_START name
.text
.align 0
.thumb
.thumb_func
ENTRY(\name)
bx pc
nop
.arm
UNWIND .fnstart
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
directly from other local arm routines. */
_L__\name:
.endm
#else
.macro ARM_FUNC_START name
.text
.align 0
.arm
ENTRY(\name)
UNWIND .fnstart
.endm
#endif
.macro RETLDM regs=, cond=, dirn=ia
#if defined (__INTERWORKING__)
.ifc "\regs",""
ldr\cond lr, [sp], #4
.else
ldm\cond\dirn sp!, {\regs, lr}
.endif
bx\cond lr
#else
.ifc "\regs",""
ldr\cond pc, [sp], #4
.else
ldm\cond\dirn sp!, {\regs, pc}
.endif
#endif
.endm
@ r0: ffi_prep_args
@ r1: &ecif
@ r2: cif->bytes
@ r3: fig->flags
@ sp+0: ecif.rvalue
@ sp+4: fn
@ This assumes we are using gas.
ARM_FUNC_START ffi_call_SYSV
@ Save registers
stmfd sp!, {r0-r3, fp, lr}
UNWIND .save {r0-r3, fp, lr}
mov fp, sp
UNWIND .setfp fp, sp
@ Make room for all of the new args.
sub sp, fp, r2
@ Place all of the ffi_prep_args in position
mov ip, r0
mov r0, sp
@ r1 already set
@ Call ffi_prep_args(stack, &ecif)
call_reg(ip)
@ move first 4 parameters in registers
ldmia sp, {r0-r3}
@ and adjust stack
ldr ip, [fp, #8]
cmp ip, #16
movhs ip, #16
add sp, sp, ip
@ call (fn) (...)
ldr ip, [fp, #28]
call_reg(ip)
@ Remove the space we pushed for the args
mov sp, fp
@ Load r2 with the pointer to storage for the return value
ldr r2, [sp, #24]
@ Load r3 with the return type code
ldr r3, [sp, #12]
@ If the return value pointer is NULL, assume no return value.
cmp r2, #0
beq LSYM(Lepilogue)
@ return INT
cmp r3, #FFI_TYPE_INT
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
cmpne r3, #FFI_TYPE_FLOAT
#endif
streq r0, [r2]
beq LSYM(Lepilogue)
@ return INT64
cmp r3, #FFI_TYPE_SINT64
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
cmpne r3, #FFI_TYPE_DOUBLE
#endif
stmeqia r2, {r0, r1}
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
beq LSYM(Lepilogue)
@ return FLOAT
cmp r3, #FFI_TYPE_FLOAT
stfeqs f0, [r2]
beq LSYM(Lepilogue)
@ return DOUBLE or LONGDOUBLE
cmp r3, #FFI_TYPE_DOUBLE
stfeqd f0, [r2]
#endif
LSYM(Lepilogue):
RETLDM "r0-r3,fp"
.ffi_call_SYSV_end:
UNWIND .fnend
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
/*
unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
*/
ARM_FUNC_START ffi_closure_SYSV
UNWIND .pad #16
add ip, sp, #16
stmfd sp!, {ip, lr}
UNWIND .save {r0, lr}
add r2, sp, #8
.pad #16
sub sp, sp, #16
str sp, [sp, #8]
add r1, sp, #8
bl ffi_closure_SYSV_inner
cmp r0, #FFI_TYPE_INT
beq .Lretint
cmp r0, #FFI_TYPE_FLOAT
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
beq .Lretint
#else
beq .Lretfloat
#endif
cmp r0, #FFI_TYPE_DOUBLE
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
beq .Lretlonglong
#else
beq .Lretdouble
#endif
cmp r0, #FFI_TYPE_LONGDOUBLE
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
beq .Lretlonglong
#else
beq .Lretlongdouble
#endif
cmp r0, #FFI_TYPE_SINT64
beq .Lretlonglong
.Lclosure_epilogue:
add sp, sp, #16
ldmfd sp, {sp, pc}
.Lretint:
ldr r0, [sp]
b .Lclosure_epilogue
.Lretlonglong:
ldr r0, [sp]
ldr r1, [sp, #4]
b .Lclosure_epilogue
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
.Lretfloat:
ldfs f0, [sp]
b .Lclosure_epilogue
.Lretdouble:
ldfd f0, [sp]
b .Lclosure_epilogue
.Lretlongdouble:
ldfd f0, [sp]
b .Lclosure_epilogue
#endif
.ffi_closure_SYSV_end:
UNWIND .fnend
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits
#endif

610
src/closures.c Normal file
View File

@@ -0,0 +1,610 @@
/* -----------------------------------------------------------------------
closures.c - Copyright (c) 2007 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Code to allocate and deallocate memory for closures.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#if defined __linux__ && !defined _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <ffi.h>
#include <ffi_common.h>
#ifndef FFI_MMAP_EXEC_WRIT
# if __gnu_linux__
/* This macro indicates it may be forbidden to map anonymous memory
with both write and execute permission. Code compiled when this
option is defined will attempt to map such pages once, but if it
fails, it falls back to creating a temporary file in a writable and
executable filesystem and mapping pages from it into separate
locations in the virtual memory space, one location writable and
another executable. */
# define FFI_MMAP_EXEC_WRIT 1
# define HAVE_MNTENT 1
# endif
# if defined(X86_WIN32) || defined(X86_WIN64)
/* Windows systems may have Data Execution Protection (DEP) enabled,
which requires the use of VirtualMalloc/VirtualFree to alloc/free
executable memory. */
# define FFI_MMAP_EXEC_WRIT 1
# endif
#endif
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
# ifdef __linux__
/* When defined to 1 check for SELinux and if SELinux is active,
don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
might cause audit messages. */
# define FFI_MMAP_EXEC_SELINUX 1
# endif
#endif
#if FFI_CLOSURES
# if FFI_MMAP_EXEC_WRIT
#define USE_LOCKS 1
#define USE_DL_PREFIX 1
#ifdef __GNUC__
#ifndef USE_BUILTIN_FFS
#define USE_BUILTIN_FFS 1
#endif
#endif
/* We need to use mmap, not sbrk. */
#define HAVE_MORECORE 0
/* We could, in theory, support mremap, but it wouldn't buy us anything. */
#define HAVE_MREMAP 0
/* We have no use for this, so save some code and data. */
#define NO_MALLINFO 1
/* We need all allocations to be in regular segments, otherwise we
lose track of the corresponding code address. */
#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
/* Don't allocate more than a page unless needed. */
#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
#if FFI_CLOSURE_TEST
/* Don't release single pages, to avoid a worst-case scenario of
continuously allocating and releasing single pages, but release
pairs of pages, which should do just as well given that allocations
are likely to be small. */
#define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#if !defined(X86_WIN32) && !defined(X86_WIN64)
#ifdef HAVE_MNTENT
#include <mntent.h>
#endif /* HAVE_MNTENT */
#include <sys/param.h>
#include <pthread.h>
/* We don't want sys/mman.h to be included after we redefine mmap and
dlmunmap. */
#include <sys/mman.h>
#define LACKS_SYS_MMAN_H 1
#if FFI_MMAP_EXEC_SELINUX
#include <sys/statfs.h>
#include <stdlib.h>
static int selinux_enabled = -1;
static int
selinux_enabled_check (void)
{
struct statfs sfs;
FILE *f;
char *buf = NULL;
size_t len = 0;
if (statfs ("/selinux", &sfs) >= 0
&& (unsigned int) sfs.f_type == 0xf97cff8cU)
return 1;
f = fopen ("/proc/mounts", "r");
if (f == NULL)
return 0;
while (getline (&buf, &len, f) >= 0)
{
char *p = strchr (buf, ' ');
if (p == NULL)
break;
p = strchr (p + 1, ' ');
if (p == NULL)
break;
if (strncmp (p + 1, "selinuxfs ", 10) != 0)
{
free (buf);
fclose (f);
return 1;
}
}
free (buf);
fclose (f);
return 0;
}
#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
: (selinux_enabled = selinux_enabled_check ()))
#else
#define is_selinux_enabled() 0
#endif /* !FFI_MMAP_EXEC_SELINUX */
#elif defined (__CYGWIN__)
#include <sys/mman.h>
/* Cygwin is Linux-like, but not quite that Linux-like. */
#define is_selinux_enabled() 0
#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Declare all functions defined in dlmalloc.c as static. */
static void *dlmalloc(size_t);
static void dlfree(void*);
static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
static void *dlvalloc(size_t) MAYBE_UNUSED;
static int dlmallopt(int, int) MAYBE_UNUSED;
static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
static void *dlpvalloc(size_t) MAYBE_UNUSED;
static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
#define mmap dlmmap
#define munmap dlmunmap
#include "dlmalloc.c"
#undef mmap
#undef munmap
#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
/* A file descriptor of a temporary file from which we'll map
executable pages. */
static int execfd = -1;
/* The amount of space already allocated from the temporary file. */
static size_t execsize = 0;
/* Open a temporary file name, and immediately unlink it. */
static int
open_temp_exec_file_name (char *name)
{
int fd = mkstemp (name);
if (fd != -1)
unlink (name);
return fd;
}
/* Open a temporary file in the named directory. */
static int
open_temp_exec_file_dir (const char *dir)
{
static const char suffix[] = "/ffiXXXXXX";
int lendir = strlen (dir);
char *tempname = __builtin_alloca (lendir + sizeof (suffix));
if (!tempname)
return -1;
memcpy (tempname, dir, lendir);
memcpy (tempname + lendir, suffix, sizeof (suffix));
return open_temp_exec_file_name (tempname);
}
/* Open a temporary file in the directory in the named environment
variable. */
static int
open_temp_exec_file_env (const char *envvar)
{
const char *value = getenv (envvar);
if (!value)
return -1;
return open_temp_exec_file_dir (value);
}
#ifdef HAVE_MNTENT
/* Open a temporary file in an executable and writable mount point
listed in the mounts file. Subsequent calls with the same mounts
keep searching for mount points in the same file. Providing NULL
as the mounts file closes the file. */
static int
open_temp_exec_file_mnt (const char *mounts)
{
static const char *last_mounts;
static FILE *last_mntent;
if (mounts != last_mounts)
{
if (last_mntent)
endmntent (last_mntent);
last_mounts = mounts;
if (mounts)
last_mntent = setmntent (mounts, "r");
else
last_mntent = NULL;
}
if (!last_mntent)
return -1;
for (;;)
{
int fd;
struct mntent mnt;
char buf[MAXPATHLEN * 3];
if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)))
return -1;
if (hasmntopt (&mnt, "ro")
|| hasmntopt (&mnt, "noexec")
|| access (mnt.mnt_dir, W_OK))
continue;
fd = open_temp_exec_file_dir (mnt.mnt_dir);
if (fd != -1)
return fd;
}
}
#endif /* HAVE_MNTENT */
/* Instructions to look for a location to hold a temporary file that
can be mapped in for execution. */
static struct
{
int (*func)(const char *);
const char *arg;
int repeat;
} open_temp_exec_file_opts[] = {
{ open_temp_exec_file_env, "TMPDIR", 0 },
{ open_temp_exec_file_dir, "/tmp", 0 },
{ open_temp_exec_file_dir, "/var/tmp", 0 },
{ open_temp_exec_file_dir, "/dev/shm", 0 },
{ open_temp_exec_file_env, "HOME", 0 },
#ifdef HAVE_MNTENT
{ open_temp_exec_file_mnt, "/etc/mtab", 1 },
{ open_temp_exec_file_mnt, "/proc/mounts", 1 },
#endif /* HAVE_MNTENT */
};
/* Current index into open_temp_exec_file_opts. */
static int open_temp_exec_file_opts_idx = 0;
/* Reset a current multi-call func, then advances to the next entry.
If we're at the last, go back to the first and return nonzero,
otherwise return zero. */
static int
open_temp_exec_file_opts_next (void)
{
if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
open_temp_exec_file_opts_idx++;
if (open_temp_exec_file_opts_idx
== (sizeof (open_temp_exec_file_opts)
/ sizeof (*open_temp_exec_file_opts)))
{
open_temp_exec_file_opts_idx = 0;
return 1;
}
return 0;
}
/* Return a file descriptor of a temporary zero-sized file in a
writable and exexutable filesystem. */
static int
open_temp_exec_file (void)
{
int fd;
do
{
fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
|| fd == -1)
{
if (open_temp_exec_file_opts_next ())
break;
}
}
while (fd == -1);
return fd;
}
/* Map in a chunk of memory from the temporary exec file into separate
locations in the virtual memory address space, one writable and one
executable. Returns the address of the writable portion, after
storing an offset to the corresponding executable portion at the
last word of the requested chunk. */
static void *
dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
{
void *ptr;
if (execfd == -1)
{
open_temp_exec_file_opts_idx = 0;
retry_open:
execfd = open_temp_exec_file ();
if (execfd == -1)
return MFAIL;
}
offset = execsize;
if (ftruncate (execfd, offset + length))
return MFAIL;
flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
flags |= MAP_SHARED;
ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
flags, execfd, offset);
if (ptr == MFAIL)
{
if (!offset)
{
close (execfd);
goto retry_open;
}
ftruncate (execfd, offset);
return MFAIL;
}
else if (!offset
&& open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
open_temp_exec_file_opts_next ();
start = mmap (start, length, prot, flags, execfd, offset);
if (start == MFAIL)
{
munmap (ptr, length);
ftruncate (execfd, offset);
return start;
}
mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
execsize += length;
return start;
}
/* Map in a writable and executable chunk of memory if possible.
Failing that, fall back to dlmmap_locked. */
static void *
dlmmap (void *start, size_t length, int prot,
int flags, int fd, off_t offset)
{
void *ptr;
assert (start == NULL && length % malloc_getpagesize == 0
&& prot == (PROT_READ | PROT_WRITE)
&& flags == (MAP_PRIVATE | MAP_ANONYMOUS)
&& fd == -1 && offset == 0);
#if FFI_CLOSURE_TEST
printf ("mapping in %zi\n", length);
#endif
if (execfd == -1 && !is_selinux_enabled ())
{
ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
/* Cool, no need to mess with separate segments. */
return ptr;
/* If MREMAP_DUP is ever introduced and implemented, try mmap
with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
MREMAP_DUP and prot at this point. */
}
if (execsize == 0 || execfd == -1)
{
pthread_mutex_lock (&open_temp_exec_file_mutex);
ptr = dlmmap_locked (start, length, prot, flags, offset);
pthread_mutex_unlock (&open_temp_exec_file_mutex);
return ptr;
}
return dlmmap_locked (start, length, prot, flags, offset);
}
/* Release memory at the given address, as well as the corresponding
executable page if it's separate. */
static int
dlmunmap (void *start, size_t length)
{
/* We don't bother decreasing execsize or truncating the file, since
we can't quite tell whether we're unmapping the end of the file.
We don't expect frequent deallocation anyway. If we did, we
could locate pages in the file by writing to the pages being
deallocated and checking that the file contents change.
Yuck. */
msegmentptr seg = segment_holding (gm, start);
void *code;
#if FFI_CLOSURE_TEST
printf ("unmapping %zi\n", length);
#endif
if (seg && (code = add_segment_exec_offset (start, seg)) != start)
{
int ret = munmap (code, length);
if (ret)
return ret;
}
return munmap (start, length);
}
#if FFI_CLOSURE_FREE_CODE
/* Return segment holding given code address. */
static msegmentptr
segment_holding_code (mstate m, char* addr)
{
msegmentptr sp = &m->seg;
for (;;) {
if (addr >= add_segment_exec_offset (sp->base, sp)
&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
return sp;
if ((sp = sp->next) == 0)
return 0;
}
}
#endif
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
corresponding virtual address. */
void *
ffi_closure_alloc (size_t size, void **code)
{
void *ptr;
if (!code)
return NULL;
ptr = dlmalloc (size);
if (ptr)
{
msegmentptr seg = segment_holding (gm, ptr);
*code = add_segment_exec_offset (ptr, seg);
}
return ptr;
}
/* Release a chunk of memory allocated with ffi_closure_alloc. If
FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
writable or the executable address given. Otherwise, only the
writable address can be provided here. */
void
ffi_closure_free (void *ptr)
{
#if FFI_CLOSURE_FREE_CODE
msegmentptr seg = segment_holding_code (gm, ptr);
if (seg)
ptr = sub_segment_exec_offset (ptr, seg);
#endif
dlfree (ptr);
}
#if FFI_CLOSURE_TEST
/* Do some internal sanity testing to make sure allocation and
deallocation of pages are working as intended. */
int main ()
{
void *p[3];
#define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
#define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
GET (0, malloc_getpagesize / 2);
GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
PUT (1);
GET (1, 2 * malloc_getpagesize);
GET (2, malloc_getpagesize / 2);
PUT (1);
PUT (0);
PUT (2);
return 0;
}
#endif /* FFI_CLOSURE_TEST */
# else /* ! FFI_MMAP_EXEC_WRIT */
/* On many systems, memory returned by malloc is writable and
executable, so just use it. */
#include <stdlib.h>
void *
ffi_closure_alloc (size_t size, void **code)
{
if (!code)
return NULL;
return *code = malloc (size);
}
void
ffi_closure_free (void *ptr)
{
free (ptr);
}
# endif /* ! FFI_MMAP_EXEC_WRIT */
#endif /* FFI_CLOSURES */

130
src/cris/.svn/entries Normal file
View File

@@ -0,0 +1,130 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/src/cris
svn://gcc.gnu.org/svn/gcc
2009-06-04T15:11:12.475454Z
148171
aph
138bc75d-0d04-0410-961f-82ee72b054a4
ffitarget.h
file
2009-06-10T05:25:02.000000Z
b0de7e4f36e492338d0076bd66610cd0
2009-06-04T15:11:12.475454Z
148171
aph
1963
ffi.c
file
2009-04-24T17:46:15.000000Z
5d7af3480697d2ceab7f4ec35baa9d26
2007-03-07T07:27:25.150115Z
122652
aoliva
9658
sysv.S
file
2009-04-24T17:46:15.000000Z
b17e59bf6ba716c77cd9ca7a4e39e672
2005-04-18T17:08:58.000000Z
98332
hp
5479

View File

@@ -0,0 +1,383 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Cygnus Solutions
Copyright (c) 2004 Simon Posnjak
Copyright (c) 2005 Axis Communications AB
Copyright (C) 2007 Free Software Foundation, Inc.
CRIS Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
static ffi_status
initialize_aggregate_packed_struct (ffi_type * arg)
{
ffi_type **ptr;
FFI_ASSERT (arg != NULL);
FFI_ASSERT (arg->elements != NULL);
FFI_ASSERT (arg->size == 0);
FFI_ASSERT (arg->alignment == 0);
ptr = &(arg->elements[0]);
while ((*ptr) != NULL)
{
if (((*ptr)->size == 0)
&& (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
FFI_ASSERT (ffi_type_test ((*ptr)));
arg->size += (*ptr)->size;
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
ptr++;
}
if (arg->size == 0)
return FFI_BAD_TYPEDEF;
else
return FFI_OK;
}
int
ffi_prep_args (char *stack, extended_cif * ecif)
{
unsigned int i;
unsigned int struct_count = 0;
void **p_argv;
char *argp;
ffi_type **p_arg;
argp = stack;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0); i--, p_arg++)
{
size_t z;
switch ((*p_arg)->type)
{
case FFI_TYPE_STRUCT:
{
z = (*p_arg)->size;
if (z <= 4)
{
memcpy (argp, *p_argv, z);
z = 4;
}
else if (z <= 8)
{
memcpy (argp, *p_argv, z);
z = 8;
}
else
{
unsigned int uiLocOnStack;
z = sizeof (void *);
uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
struct_count = struct_count + (*p_arg)->size;
*(unsigned int *) argp =
(unsigned int) (UINT32 *) (stack + uiLocOnStack);
memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
}
break;
}
default:
z = (*p_arg)->size;
if (z < sizeof (int))
{
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
break;
case FFI_TYPE_UINT8:
*(unsigned int *) argp =
(unsigned int) *(UINT8 *) (*p_argv);
break;
case FFI_TYPE_SINT16:
*(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
break;
case FFI_TYPE_UINT16:
*(unsigned int *) argp =
(unsigned int) *(UINT16 *) (*p_argv);
break;
default:
FFI_ASSERT (0);
}
z = sizeof (int);
}
else if (z == sizeof (int))
*(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
else
memcpy (argp, *p_argv, z);
break;
}
p_argv++;
argp += z;
}
return (struct_count);
}
ffi_status
ffi_prep_cif (ffi_cif * cif,
ffi_abi abi, unsigned int nargs,
ffi_type * rtype, ffi_type ** atypes)
{
unsigned bytes = 0;
unsigned int i;
ffi_type **ptr;
FFI_ASSERT (cif != NULL);
FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
cif->abi = abi;
cif->arg_types = atypes;
cif->nargs = nargs;
cif->rtype = rtype;
cif->flags = 0;
if ((cif->rtype->size == 0)
&& (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
return FFI_BAD_TYPEDEF;
FFI_ASSERT_VALID_TYPE (cif->rtype);
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
if (((*ptr)->size == 0)
&& (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
FFI_ASSERT_VALID_TYPE (*ptr);
if (((*ptr)->alignment - 1) & bytes)
bytes = ALIGN (bytes, (*ptr)->alignment);
if ((*ptr)->type == FFI_TYPE_STRUCT)
{
if ((*ptr)->size > 8)
{
bytes += (*ptr)->size;
bytes += sizeof (void *);
}
else
{
if ((*ptr)->size > 4)
bytes += 8;
else
bytes += 4;
}
}
else
bytes += STACK_ARG_SIZE ((*ptr)->size);
}
cif->bytes = bytes;
return ffi_prep_cif_machdep (cif);
}
ffi_status
ffi_prep_cif_machdep (ffi_cif * cif)
{
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
cif->flags = (unsigned) cif->rtype->type;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
extended_cif *,
unsigned, unsigned, unsigned *, void (*fn) ())
__attribute__ ((__visibility__ ("hidden")));
void
ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca (cif->rtype->size);
}
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
break;
default:
FFI_ASSERT (0);
break;
}
}
/* Because the following variables are not exported outside libffi, we
mark them hidden. */
/* Assembly code for the jump stub. */
extern const char ffi_cris_trampoline_template[]
__attribute__ ((__visibility__ ("hidden")));
/* Offset into ffi_cris_trampoline_template of where to put the
ffi_prep_closure_inner function. */
extern const int ffi_cris_trampoline_fn_offset
__attribute__ ((__visibility__ ("hidden")));
/* Offset into ffi_cris_trampoline_template of where to put the
closure data. */
extern const int ffi_cris_trampoline_closure_offset
__attribute__ ((__visibility__ ("hidden")));
/* This function is sibling-called (jumped to) by the closure
trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
PARAMS[4] to simplify handling of a straddling parameter. A copy
of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are
put at the appropriate place in CLOSURE which is then executed and
the return value is passed back to the caller. */
static unsigned long long
ffi_prep_closure_inner (void **params, ffi_closure* closure)
{
char *register_args = (char *) params;
void *struct_ret = params[5];
char *stack_args = params[6];
char *ptr = register_args;
ffi_cif *cif = closure->cif;
ffi_type **arg_types = cif->arg_types;
/* Max room needed is number of arguments as 64-bit values. */
void **avalue = alloca (closure->cif->nargs * sizeof(void *));
int i;
int doing_regs;
long long llret = 0;
/* Find the address of each argument. */
for (i = 0, doing_regs = 1; i < cif->nargs; i++)
{
/* Types up to and including 8 bytes go by-value. */
if (arg_types[i]->size <= 4)
{
avalue[i] = ptr;
ptr += 4;
}
else if (arg_types[i]->size <= 8)
{
avalue[i] = ptr;
ptr += 8;
}
else
{
FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
/* Passed by-reference, so copy the pointer. */
avalue[i] = *(void **) ptr;
ptr += 4;
}
/* If we've handled more arguments than fit in registers, start
looking at the those passed on the stack. Step over the
first one if we had a straddling parameter. */
if (doing_regs && ptr >= register_args + 4*4)
{
ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
doing_regs = 0;
}
}
/* Invoke the closure. */
(closure->fun) (cif,
cif->rtype->type == FFI_TYPE_STRUCT
/* The caller allocated space for the return
structure, and passed a pointer to this space in
R9. */
? struct_ret
/* We take advantage of being able to ignore that
the high part isn't set if the return value is
not in R10:R11, but in R10 only. */
: (void *) &llret,
avalue, closure->user_data);
return llret;
}
/* API function: Prepare the trampoline. */
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif *, void *, void **, void*),
void *user_data,
void *codeloc)
{
void *innerfn = ffi_prep_closure_inner;
FFI_ASSERT (cif->abi == FFI_SYSV);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
memcpy (closure->tramp, ffi_cris_trampoline_template,
FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
&innerfn, sizeof (void *));
memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
&codeloc, sizeof (void *));
return FFI_OK;
}

View File

@@ -0,0 +1,51 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for CRIS.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_SYSV,
FFI_DEFAULT_ABI = FFI_SYSV,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36
#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)
#define FFI_TRAMPOLINE_SIZE \
(FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)
#define FFI_NATIVE_RAW_API 0
#endif

View File

@@ -0,0 +1,215 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 2004 Simon Posnjak
Copyright (c) 2005 Axis Communications AB
CRIS Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <ffi.h>
#define CONCAT(x,y) x ## y
#define XCONCAT(x,y) CONCAT (x, y)
#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)
.text
;; OK, when we get called we should have this (according to
;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).
;;
;; R10: ffi_prep_args (func. pointer)
;; R11: &ecif
;; R12: cif->bytes
;; R13: fig->flags
;; sp+0: ecif.rvalue
;; sp+4: fn (function pointer to the function that we need to call)
.globl L(ffi_call_SYSV)
.type L(ffi_call_SYSV),@function
.hidden L(ffi_call_SYSV)
L(ffi_call_SYSV):
;; Save the regs to the stack.
push $srp
;; Used for stack pointer saving.
push $r6
;; Used for function address pointer.
push $r7
;; Used for stack pointer saving.
push $r8
;; We save fig->flags to stack we will need them after we
;; call The Function.
push $r13
;; Saving current stack pointer.
move.d $sp,$r8
move.d $sp,$r6
;; Move address of ffi_prep_args to r13.
move.d $r10,$r13
;; Make room on the stack for the args of fn.
sub.d $r12,$sp
;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:
;; r10 <-- stack pointer
;; r11 <-- &ecif (already there)
move.d $sp,$r10
;; Call the function.
jsr $r13
;; Save the size of the structures which are passed on stack.
move.d $r10,$r7
;; Move first four args in to r10..r13.
move.d [$sp+0],$r10
move.d [$sp+4],$r11
move.d [$sp+8],$r12
move.d [$sp+12],$r13
;; Adjust the stack and check if any parameters are given on stack.
addq 16,$sp
sub.d $r7,$r6
cmp.d $sp,$r6
bpl go_on
nop
go_on_no_params_on_stack:
move.d $r6,$sp
go_on:
;; Discover if we need to put rval address in to r9.
move.d [$r8+0],$r7
cmpq FFI_TYPE_STRUCT,$r7
bne call_now
nop
;; Move rval address to $r9.
move.d [$r8+20],$r9
call_now:
;; Move address of The Function in to r7.
move.d [$r8+24],$r7
;; Call The Function.
jsr $r7
;; Reset stack.
move.d $r8,$sp
;; Load rval type (fig->flags) in to r13.
pop $r13
;; Detect rval type.
cmpq FFI_TYPE_VOID,$r13
beq epilogue
cmpq FFI_TYPE_STRUCT,$r13
beq epilogue
cmpq FFI_TYPE_DOUBLE,$r13
beq return_double_or_longlong
cmpq FFI_TYPE_UINT64,$r13
beq return_double_or_longlong
cmpq FFI_TYPE_SINT64,$r13
beq return_double_or_longlong
nop
;; Just return the 32 bit value.
ba return
nop
return_double_or_longlong:
;; Load half of the rval to r10 and the other half to r11.
move.d [$sp+16],$r13
move.d $r10,[$r13]
addq 4,$r13
move.d $r11,[$r13]
ba epilogue
nop
return:
;; Load the rval to r10.
move.d [$sp+16],$r13
move.d $r10,[$r13]
epilogue:
pop $r8
pop $r7
pop $r6
Jump [$sp+]
.size ffi_call_SYSV,.-ffi_call_SYSV
/* Save R10..R13 into an array, somewhat like varargs. Copy the next
argument too, to simplify handling of any straddling parameter.
Save R9 and SP after those. Jump to function handling the rest.
Since this is a template, copied and the main function filled in by
the user. */
.globl L(ffi_cris_trampoline_template)
.type L(ffi_cris_trampoline_template),@function
.hidden L(ffi_cris_trampoline_template)
L(ffi_cris_trampoline_template):
0:
/* The value we get for "PC" is right after the prefix instruction,
two bytes from the beginning, i.e. 0b+2. */
move.d $r10,[$pc+2f-(0b+2)]
move.d $pc,$r10
1:
addq 2f-1b+4,$r10
move.d $r11,[$r10+]
move.d $r12,[$r10+]
move.d $r13,[$r10+]
move.d [$sp],$r11
move.d $r11,[$r10+]
move.d $r9,[$r10+]
move.d $sp,[$r10+]
subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10
move.d 0,$r11
3:
jump 0
2:
.size ffi_cris_trampoline_template,.-0b
/* This macro create a constant usable as "extern const int \name" in
C from within libffi, when \name has no prefix decoration. */
.macro const name,value
.globl \name
.type \name,@object
.hidden \name
\name:
.dword \value
.size \name,4
.endm
/* Constants for offsets within the trampoline. We could do this with
just symbols, avoiding memory contents and memory accesses, but the
C usage code would look a bit stranger. */
const L(ffi_cris_trampoline_fn_offset),2b-4-0b
const L(ffi_cris_trampoline_closure_offset),3b-4-0b

383
src/cris/ffi.c Normal file
View File

@@ -0,0 +1,383 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Cygnus Solutions
Copyright (c) 2004 Simon Posnjak
Copyright (c) 2005 Axis Communications AB
Copyright (C) 2007 Free Software Foundation, Inc.
CRIS Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
static ffi_status
initialize_aggregate_packed_struct (ffi_type * arg)
{
ffi_type **ptr;
FFI_ASSERT (arg != NULL);
FFI_ASSERT (arg->elements != NULL);
FFI_ASSERT (arg->size == 0);
FFI_ASSERT (arg->alignment == 0);
ptr = &(arg->elements[0]);
while ((*ptr) != NULL)
{
if (((*ptr)->size == 0)
&& (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
FFI_ASSERT (ffi_type_test ((*ptr)));
arg->size += (*ptr)->size;
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
ptr++;
}
if (arg->size == 0)
return FFI_BAD_TYPEDEF;
else
return FFI_OK;
}
int
ffi_prep_args (char *stack, extended_cif * ecif)
{
unsigned int i;
unsigned int struct_count = 0;
void **p_argv;
char *argp;
ffi_type **p_arg;
argp = stack;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0); i--, p_arg++)
{
size_t z;
switch ((*p_arg)->type)
{
case FFI_TYPE_STRUCT:
{
z = (*p_arg)->size;
if (z <= 4)
{
memcpy (argp, *p_argv, z);
z = 4;
}
else if (z <= 8)
{
memcpy (argp, *p_argv, z);
z = 8;
}
else
{
unsigned int uiLocOnStack;
z = sizeof (void *);
uiLocOnStack = 4 * ecif->cif->nargs + struct_count;
struct_count = struct_count + (*p_arg)->size;
*(unsigned int *) argp =
(unsigned int) (UINT32 *) (stack + uiLocOnStack);
memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);
}
break;
}
default:
z = (*p_arg)->size;
if (z < sizeof (int))
{
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);
break;
case FFI_TYPE_UINT8:
*(unsigned int *) argp =
(unsigned int) *(UINT8 *) (*p_argv);
break;
case FFI_TYPE_SINT16:
*(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);
break;
case FFI_TYPE_UINT16:
*(unsigned int *) argp =
(unsigned int) *(UINT16 *) (*p_argv);
break;
default:
FFI_ASSERT (0);
}
z = sizeof (int);
}
else if (z == sizeof (int))
*(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);
else
memcpy (argp, *p_argv, z);
break;
}
p_argv++;
argp += z;
}
return (struct_count);
}
ffi_status
ffi_prep_cif (ffi_cif * cif,
ffi_abi abi, unsigned int nargs,
ffi_type * rtype, ffi_type ** atypes)
{
unsigned bytes = 0;
unsigned int i;
ffi_type **ptr;
FFI_ASSERT (cif != NULL);
FFI_ASSERT ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
cif->abi = abi;
cif->arg_types = atypes;
cif->nargs = nargs;
cif->rtype = rtype;
cif->flags = 0;
if ((cif->rtype->size == 0)
&& (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))
return FFI_BAD_TYPEDEF;
FFI_ASSERT_VALID_TYPE (cif->rtype);
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
if (((*ptr)->size == 0)
&& (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
FFI_ASSERT_VALID_TYPE (*ptr);
if (((*ptr)->alignment - 1) & bytes)
bytes = ALIGN (bytes, (*ptr)->alignment);
if ((*ptr)->type == FFI_TYPE_STRUCT)
{
if ((*ptr)->size > 8)
{
bytes += (*ptr)->size;
bytes += sizeof (void *);
}
else
{
if ((*ptr)->size > 4)
bytes += 8;
else
bytes += 4;
}
}
else
bytes += STACK_ARG_SIZE ((*ptr)->size);
}
cif->bytes = bytes;
return ffi_prep_cif_machdep (cif);
}
ffi_status
ffi_prep_cif_machdep (ffi_cif * cif)
{
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
cif->flags = (unsigned) cif->rtype->type;
break;
default:
cif->flags = FFI_TYPE_INT;
break;
}
return FFI_OK;
}
extern void ffi_call_SYSV (int (*)(char *, extended_cif *),
extended_cif *,
unsigned, unsigned, unsigned *, void (*fn) ())
__attribute__ ((__visibility__ ("hidden")));
void
ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca (cif->rtype->size);
}
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
break;
default:
FFI_ASSERT (0);
break;
}
}
/* Because the following variables are not exported outside libffi, we
mark them hidden. */
/* Assembly code for the jump stub. */
extern const char ffi_cris_trampoline_template[]
__attribute__ ((__visibility__ ("hidden")));
/* Offset into ffi_cris_trampoline_template of where to put the
ffi_prep_closure_inner function. */
extern const int ffi_cris_trampoline_fn_offset
__attribute__ ((__visibility__ ("hidden")));
/* Offset into ffi_cris_trampoline_template of where to put the
closure data. */
extern const int ffi_cris_trampoline_closure_offset
__attribute__ ((__visibility__ ("hidden")));
/* This function is sibling-called (jumped to) by the closure
trampoline. We get R10..R13 at PARAMS[0..3] and a copy of [SP] at
PARAMS[4] to simplify handling of a straddling parameter. A copy
of R9 is at PARAMS[5] and SP at PARAMS[6]. These parameters are
put at the appropriate place in CLOSURE which is then executed and
the return value is passed back to the caller. */
static unsigned long long
ffi_prep_closure_inner (void **params, ffi_closure* closure)
{
char *register_args = (char *) params;
void *struct_ret = params[5];
char *stack_args = params[6];
char *ptr = register_args;
ffi_cif *cif = closure->cif;
ffi_type **arg_types = cif->arg_types;
/* Max room needed is number of arguments as 64-bit values. */
void **avalue = alloca (closure->cif->nargs * sizeof(void *));
int i;
int doing_regs;
long long llret = 0;
/* Find the address of each argument. */
for (i = 0, doing_regs = 1; i < cif->nargs; i++)
{
/* Types up to and including 8 bytes go by-value. */
if (arg_types[i]->size <= 4)
{
avalue[i] = ptr;
ptr += 4;
}
else if (arg_types[i]->size <= 8)
{
avalue[i] = ptr;
ptr += 8;
}
else
{
FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);
/* Passed by-reference, so copy the pointer. */
avalue[i] = *(void **) ptr;
ptr += 4;
}
/* If we've handled more arguments than fit in registers, start
looking at the those passed on the stack. Step over the
first one if we had a straddling parameter. */
if (doing_regs && ptr >= register_args + 4*4)
{
ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);
doing_regs = 0;
}
}
/* Invoke the closure. */
(closure->fun) (cif,
cif->rtype->type == FFI_TYPE_STRUCT
/* The caller allocated space for the return
structure, and passed a pointer to this space in
R9. */
? struct_ret
/* We take advantage of being able to ignore that
the high part isn't set if the return value is
not in R10:R11, but in R10 only. */
: (void *) &llret,
avalue, closure->user_data);
return llret;
}
/* API function: Prepare the trampoline. */
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif *, void *, void **, void*),
void *user_data,
void *codeloc)
{
void *innerfn = ffi_prep_closure_inner;
FFI_ASSERT (cif->abi == FFI_SYSV);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
memcpy (closure->tramp, ffi_cris_trampoline_template,
FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);
memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
&innerfn, sizeof (void *));
memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
&codeloc, sizeof (void *));
return FFI_OK;
}

51
src/cris/ffitarget.h Normal file
View File

@@ -0,0 +1,51 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for CRIS.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
FFI_SYSV,
FFI_DEFAULT_ABI = FFI_SYSV,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36
#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)
#define FFI_TRAMPOLINE_SIZE \
(FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)
#define FFI_NATIVE_RAW_API 0
#endif

215
src/cris/sysv.S Normal file
View File

@@ -0,0 +1,215 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 2004 Simon Posnjak
Copyright (c) 2005 Axis Communications AB
CRIS Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <ffi.h>
#define CONCAT(x,y) x ## y
#define XCONCAT(x,y) CONCAT (x, y)
#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)
.text
;; OK, when we get called we should have this (according to
;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).
;;
;; R10: ffi_prep_args (func. pointer)
;; R11: &ecif
;; R12: cif->bytes
;; R13: fig->flags
;; sp+0: ecif.rvalue
;; sp+4: fn (function pointer to the function that we need to call)
.globl L(ffi_call_SYSV)
.type L(ffi_call_SYSV),@function
.hidden L(ffi_call_SYSV)
L(ffi_call_SYSV):
;; Save the regs to the stack.
push $srp
;; Used for stack pointer saving.
push $r6
;; Used for function address pointer.
push $r7
;; Used for stack pointer saving.
push $r8
;; We save fig->flags to stack we will need them after we
;; call The Function.
push $r13
;; Saving current stack pointer.
move.d $sp,$r8
move.d $sp,$r6
;; Move address of ffi_prep_args to r13.
move.d $r10,$r13
;; Make room on the stack for the args of fn.
sub.d $r12,$sp
;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:
;; r10 <-- stack pointer
;; r11 <-- &ecif (already there)
move.d $sp,$r10
;; Call the function.
jsr $r13
;; Save the size of the structures which are passed on stack.
move.d $r10,$r7
;; Move first four args in to r10..r13.
move.d [$sp+0],$r10
move.d [$sp+4],$r11
move.d [$sp+8],$r12
move.d [$sp+12],$r13
;; Adjust the stack and check if any parameters are given on stack.
addq 16,$sp
sub.d $r7,$r6
cmp.d $sp,$r6
bpl go_on
nop
go_on_no_params_on_stack:
move.d $r6,$sp
go_on:
;; Discover if we need to put rval address in to r9.
move.d [$r8+0],$r7
cmpq FFI_TYPE_STRUCT,$r7
bne call_now
nop
;; Move rval address to $r9.
move.d [$r8+20],$r9
call_now:
;; Move address of The Function in to r7.
move.d [$r8+24],$r7
;; Call The Function.
jsr $r7
;; Reset stack.
move.d $r8,$sp
;; Load rval type (fig->flags) in to r13.
pop $r13
;; Detect rval type.
cmpq FFI_TYPE_VOID,$r13
beq epilogue
cmpq FFI_TYPE_STRUCT,$r13
beq epilogue
cmpq FFI_TYPE_DOUBLE,$r13
beq return_double_or_longlong
cmpq FFI_TYPE_UINT64,$r13
beq return_double_or_longlong
cmpq FFI_TYPE_SINT64,$r13
beq return_double_or_longlong
nop
;; Just return the 32 bit value.
ba return
nop
return_double_or_longlong:
;; Load half of the rval to r10 and the other half to r11.
move.d [$sp+16],$r13
move.d $r10,[$r13]
addq 4,$r13
move.d $r11,[$r13]
ba epilogue
nop
return:
;; Load the rval to r10.
move.d [$sp+16],$r13
move.d $r10,[$r13]
epilogue:
pop $r8
pop $r7
pop $r6
Jump [$sp+]
.size ffi_call_SYSV,.-ffi_call_SYSV
/* Save R10..R13 into an array, somewhat like varargs. Copy the next
argument too, to simplify handling of any straddling parameter.
Save R9 and SP after those. Jump to function handling the rest.
Since this is a template, copied and the main function filled in by
the user. */
.globl L(ffi_cris_trampoline_template)
.type L(ffi_cris_trampoline_template),@function
.hidden L(ffi_cris_trampoline_template)
L(ffi_cris_trampoline_template):
0:
/* The value we get for "PC" is right after the prefix instruction,
two bytes from the beginning, i.e. 0b+2. */
move.d $r10,[$pc+2f-(0b+2)]
move.d $pc,$r10
1:
addq 2f-1b+4,$r10
move.d $r11,[$r10+]
move.d $r12,[$r10+]
move.d $r13,[$r10+]
move.d [$sp],$r11
move.d $r11,[$r10+]
move.d $r9,[$r10+]
move.d $sp,[$r10+]
subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10
move.d 0,$r11
3:
jump 0
2:
.size ffi_cris_trampoline_template,.-0b
/* This macro create a constant usable as "extern const int \name" in
C from within libffi, when \name has no prefix decoration. */
.macro const name,value
.globl \name
.type \name,@object
.hidden \name
\name:
.dword \value
.size \name,4
.endm
/* Constants for offsets within the trampoline. We could do this with
just symbols, avoiding memory contents and memory accesses, but the
C usage code would look a bit stranger. */
const L(ffi_cris_trampoline_fn_offset),2b-4-0b
const L(ffi_cris_trampoline_closure_offset),3b-4-0b

59
src/debug.c Normal file
View File

@@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------
debug.c - Copyright (c) 1996 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#include <stdio.h>
/* General debugging routines */
void ffi_stop_here(void)
{
/* This function is only useful for debugging purposes.
Place a breakpoint on ffi_stop_here to be notified of
significant events. */
}
/* This function should only be called via the FFI_ASSERT() macro */
void ffi_assert(char *expr, char *file, int line)
{
fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);
ffi_stop_here();
abort();
}
/* Perform a sanity check on an ffi_type structure */
void ffi_type_test(ffi_type *a, char *file, int line)
{
FFI_ASSERT_AT(a != NULL, file, line);
FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
}

5099
src/dlmalloc.c Normal file

File diff suppressed because it is too large Load Diff

130
src/frv/.svn/entries Normal file
View File

@@ -0,0 +1,130 @@
10
dir
152280
svn://gcc.gnu.org/svn/gcc/trunk/libffi/src/frv
svn://gcc.gnu.org/svn/gcc
2009-06-04T15:43:03.499507Z
148172
aph
138bc75d-0d04-0410-961f-82ee72b054a4
eabi.S
file
2009-04-24T17:46:15.000000Z
b9ecce87980cf9448d35f168d0b12575
2007-04-13T07:21:04.913930Z
123776
bonzini
3414
ffitarget.h
file
2009-06-10T05:25:02.000000Z
7e0905257934522b5eacfc1bbf5bb459
2009-06-04T15:11:12.475454Z
148171
aph
2066
ffi.c
file
2009-06-10T05:25:02.000000Z
cd95ee2906582020737463464ea8806b
2009-06-04T15:43:03.499507Z
148172
aph
8448

View File

@@ -0,0 +1,128 @@
/* -----------------------------------------------------------------------
eabi.S - Copyright (c) 2004 Anthony Green
FR-V Assembly glue.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
.globl ffi_prep_args_EABI
.text
.p2align 4
.globl ffi_call_EABI
.type ffi_call_EABI, @function
# gr8 : ffi_prep_args
# gr9 : &ecif
# gr10: cif->bytes
# gr11: fig->flags
# gr12: ecif.rvalue
# gr13: fn
ffi_call_EABI:
addi sp, #-80, sp
sti fp, @(sp, #24)
addi sp, #24, fp
movsg lr, gr5
/* Make room for the new arguments. */
/* subi sp, fp, gr10 */
/* Store return address and incoming args on stack. */
sti gr5, @(fp, #8)
sti gr8, @(fp, #-4)
sti gr9, @(fp, #-8)
sti gr10, @(fp, #-12)
sti gr11, @(fp, #-16)
sti gr12, @(fp, #-20)
sti gr13, @(fp, #-24)
sub sp, gr10, sp
/* Call ffi_prep_args. */
ldi @(fp, #-4), gr4
addi sp, #0, gr8
ldi @(fp, #-8), gr9
#ifdef __FRV_FDPIC__
ldd @(gr4, gr0), gr14
calll @(gr14, gr0)
#else
calll @(gr4, gr0)
#endif
/* ffi_prep_args returns the new stack pointer. */
mov gr8, gr4
ldi @(sp, #0), gr8
ldi @(sp, #4), gr9
ldi @(sp, #8), gr10
ldi @(sp, #12), gr11
ldi @(sp, #16), gr12
ldi @(sp, #20), gr13
/* Always copy the return value pointer into the hidden
parameter register. This is only strictly necessary
when we're returning an aggregate type, but it doesn't
hurt to do this all the time, and it saves a branch. */
ldi @(fp, #-20), gr3
/* Use the ffi_prep_args return value for the new sp. */
mov gr4, sp
/* Call the target function. */
ldi @(fp, -24), gr4
#ifdef __FRV_FDPIC__
ldd @(gr4, gr0), gr14
calll @(gr14, gr0)
#else
calll @(gr4, gr0)
#endif
/* Store the result. */
ldi @(fp, #-16), gr10 /* fig->flags */
ldi @(fp, #-20), gr4 /* ecif.rvalue */
/* Is the return value stored in two registers? */
cmpi gr10, #8, icc0
bne icc0, 0, .L2
/* Yes, save them. */
sti gr8, @(gr4, #0)
sti gr9, @(gr4, #4)
bra .L3
.L2:
/* Is the return value a structure? */
cmpi gr10, #-1, icc0
beq icc0, 0, .L3
/* No, save a 4 byte return value. */
sti gr8, @(gr4, #0)
.L3:
/* Restore the stack, and return. */
ldi @(fp, 8), gr5
ld @(fp, gr0), fp
addi sp,#80,sp
jmpl @(gr5,gr0)
.size ffi_call_EABI, .-ffi_call_EABI

View File

@@ -0,0 +1,292 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (C) 2004 Anthony Green
Copyright (C) 2007 Free Software Foundation, Inc.
Copyright (C) 2008 Red Hat, Inc.
FR-V Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */
void *ffi_prep_args(char *stack, extended_cif *ecif)
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
register int count = 0;
p_argv = ecif->avalue;
argp = stack;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0);
i--, p_arg++)
{
size_t z;
z = (*p_arg)->size;
if ((*p_arg)->type == FFI_TYPE_STRUCT)
{
z = sizeof(void*);
*(void **) argp = *p_argv;
}
/* if ((*p_arg)->type == FFI_TYPE_FLOAT)
{
if (count > 24)
{
// This is going on the stack. Turn it into a double.
*(double *) argp = (double) *(float*)(* p_argv);
z = sizeof(double);
}
else
*(void **) argp = *(void **)(* p_argv);
} */
else if (z < sizeof(int))
{
z = sizeof(int);
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
break;
case FFI_TYPE_UINT8:
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
break;
case FFI_TYPE_SINT16:
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
break;
case FFI_TYPE_UINT16:
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
break;
default:
FFI_ASSERT(0);
}
}
else if (z == sizeof(int))
{
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
}
else
{
memcpy(argp, *p_argv, z);
}
p_argv++;
argp += z;
count += z;
}
return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
}
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
if (cif->rtype->type == FFI_TYPE_STRUCT)
cif->flags = -1;
else
cif->flags = cif->rtype->size;
cif->bytes = ALIGN (cif->bytes, 8);
return FFI_OK;
}
extern void ffi_call_EABI(void *(*)(char *, extended_cif *),
extended_cif *,
unsigned, unsigned,
unsigned *,
void (*fn)(void));
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
/* If the return value is a struct and we don't have a return */
/* value address then we need to make one */
if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_EABI:
ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
break;
default:
FFI_ASSERT(0);
break;
}
}
void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
unsigned arg4, unsigned arg5, unsigned arg6)
{
/* This function is called by a trampoline. The trampoline stows a
pointer to the ffi_closure object in gr7. We must save this
pointer in a place that will persist while we do our work. */
register ffi_closure *creg __asm__ ("gr7");
ffi_closure *closure = creg;
/* Arguments that don't fit in registers are found on the stack
at a fixed offset above the current frame pointer. */
register char *frame_pointer __asm__ ("fp");
char *stack_args = frame_pointer + 16;
/* Lay the register arguments down in a continuous chunk of memory. */
unsigned register_args[6] =
{ arg1, arg2, arg3, arg4, arg5, arg6 };
ffi_cif *cif = closure->cif;
ffi_type **arg_types = cif->arg_types;
void **avalue = alloca (cif->nargs * sizeof(void *));
char *ptr = (char *) register_args;
int i;
/* Find the address of each argument. */
for (i = 0; i < cif->nargs; i++)
{
switch (arg_types[i]->type)
{
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
avalue[i] = ptr + 3;
break;
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT16:
avalue[i] = ptr + 2;
break;
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32:
case FFI_TYPE_FLOAT:
avalue[i] = ptr;
break;
case FFI_TYPE_STRUCT:
avalue[i] = *(void**)ptr;
break;
default:
/* This is an 8-byte value. */
avalue[i] = ptr;
ptr += 4;
break;
}
ptr += 4;
/* If we've handled more arguments than fit in registers,
start looking at the those passed on the stack. */
if (ptr == ((char *)register_args + (6*4)))
ptr = stack_args;
}
/* Invoke the closure. */
if (cif->rtype->type == FFI_TYPE_STRUCT)
{
/* The caller allocates space for the return structure, and
passes a pointer to this space in gr3. Use this value directly
as the return value. */
register void *return_struct_ptr __asm__("gr3");
(closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
}
else
{
/* Allocate space for the return value and call the function. */
long long rvalue;
(closure->fun) (cif, &rvalue, avalue, closure->user_data);
/* Functions return 4-byte or smaller results in gr8. 8-byte
values also use gr9. We fill the both, even for small return
values, just to avoid a branch. */
asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue));
asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
}
}
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data,
void *codeloc)
{
unsigned int *tramp = (unsigned int *) &closure->tramp[0];
unsigned long fn = (long) ffi_closure_eabi;
unsigned long cls = (long) codeloc;
#ifdef __FRV_FDPIC__
register void *got __asm__("gr15");
#endif
int i;
fn = (unsigned long) ffi_closure_eabi;
#ifdef __FRV_FDPIC__
tramp[0] = &((unsigned int *)codeloc)[2];
tramp[1] = got;
tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
tramp[4] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
tramp[5] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
tramp[6] = 0x9cc86000; /* ldi @(gr6, #0), gr14 */
tramp[7] = 0x8030e000; /* jmpl @(gr14, gr0) */
#else
tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */
#endif
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
/* Cache flushing. */
for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
__asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),
"r" (codeloc));
return FFI_OK;
}

Some files were not shown because too many files have changed in this diff Show More