Merge with GCC. Eliminate quilt bits.

This commit is contained in:
Anthony Green
2013-01-02 07:34:03 -05:00
parent 61a0549295
commit 981c32ee11
364 changed files with 1431 additions and 379775 deletions

5
.gitignore vendored
View File

@@ -16,8 +16,3 @@ libtool
stamp-h1 stamp-h1
libffi*gz libffi*gz
autom4te.cache autom4te.cache
libffi.xcodeproj/xcuserdata
libffi.xcodeproj/project.xcworkspace
ios/
osx/
build_*/

View File

@@ -1 +0,0 @@
patches

View File

@@ -1 +0,0 @@
series

View File

@@ -1 +0,0 @@
2

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,212 +0,0 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects
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/avr32/ffi.c src/avr32/sysv.S src/avr32/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/win64.S \
src/x86/freebsd.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/bfin/ffi.c \
src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \
src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \
src/tile/ffitarget.h src/tile/tile.S libtool-version \
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \
generate-ios-source-and-headers.py \
generate-osx-source-and-headers.py \
libffi.xcodeproj/project.pbxproj src/arm/trampoline.S
info_TEXINFOS = doc/libffi.texi
## ################################################################
##
## 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)" \
"mandir=$(mandir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
"CC=$(CC)" \
"CXX=$(CXX)" \
"LD=$(LD)" \
"NM=$(NM)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES=
ACLOCAL_AMFLAGS=$(ACLOCAL_AMFLAGS) -I m4
lib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/closures.c
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libffi.pc
nodist_libffi_la_SOURCES =
if FFI_DEBUG
nodist_libffi_la_SOURCES += src/debug.c
endif
if MIPS
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
endif
if BFIN
nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.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
if FFI_EXEC_TRAMPOLINE_TABLE
nodist_libffi_la_SOURCES += src/arm/trampoline.S
endif
endif
if AVR32
nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/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
if TILE
nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c
endif
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -g
if FFI_DEBUG
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
# MSVC, it can link against the debug CRT.
AM_CFLAGS += -DFFI_DEBUG
endif
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src -DFFI_BUILDING
AM_CCASFLAGS = $(AM_CPPFLAGS) -g
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf:

View File

@@ -1,366 +0,0 @@
Status
======
libffi-3.0.12 was released on XXXXXXX. 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.
For specific configuration details and testing status, please
refer to the wiki page here:
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.11
At the time of release, the following basic configurations have been
tested:
|-----------------+------------------|
| Architecture | Operating System |
|-----------------+------------------|
| Alpha | Linux |
| Alpha | Tru64 |
| ARM | Linux |
| ARM | iOS |
| AVR32 | Linux |
| Blackfin | uClinux |
| HPPA | HPUX |
| IA-64 | Linux |
| M68K | FreeMiNT |
| M68K | RTEMS |
| MIPS | IRIX |
| MIPS | Linux |
| MIPS | RTEMS |
| MIPS64 | Linux |
| PowerPC | AMIGA |
| PowerPC | Linux |
| PowerPC | Mac OSX |
| PowerPC | FreeBSD |
| PowerPC64 | Linux |
| S390 | Linux |
| S390X | Linux |
| SPARC | Linux |
| SPARC | Solaris |
| SPARC64 | Linux |
| SPARC64 | FreeBSD |
| TILE-Gx/TILEPro | Linux |
| X86 | FreeBSD |
| X86 | Interix |
| X86 | kFreeBSD |
| X86 | Linux |
| X86 | Mac OSX |
| X86 | OpenBSD |
| X86 | OS/2 |
| X86 | Solaris |
| X86 | Windows/Cygwin |
| X86 | Windows/MingW |
| X86-64 | FreeBSD |
| X86-64 | Linux |
| X86-64 | Linux/x32 |
| X86-64 | OpenBSD |
| X86-64 | Windows/MingW |
|-----------------+------------------|
Please send additional platform test results to
libffi-discuss@sourceware.org and feel free to update the wiki page
above.
Installing libffi
=================
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.
It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
You may also need to specify --build appropriately. When building with MSVC
under a MingW environment, you may need to remove the line in configure
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.)
For iOS builds, the 'libffi.xcodeproj' Xcode project is available.
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".
History
=======
See the ChangeLog files for details.
3.0.12 XXX-XX-XX
Add Blackfin support.
Add TILE-Gx/TILEPro support.
3.0.11 Apr-11-12
Lots of build fixes.
Add Amiga newer MacOS support.
Add support for variadic functions (ffi_prep_cif_var).
Add Linux/x32 support.
Add thiscall, fastcall and MSVC cdecl support on Windows.
Add Amiga and newer MacOS support.
Add m68k FreeMiNT support.
Integration with iOS' xcode build tools.
Fix Octeon and MC68881 support.
Fix code pessimizations.
Lots of build fixes.
3.0.10 Aug-23-11
Add support for Apple's iOS.
Add support for ARM VFP ABI.
Add RTEMS support for MIPS and M68K.
Fix instruction cache clearing problems on
ARM and SPARC.
Fix the N64 build on mips-sgi-irix6.5.
Enable builds with Microsoft's compiler.
Enable x86 builds with Oracle's Solaris compiler.
Fix support for calling code compiled with Oracle's Sparc
Solaris compiler.
Testsuite fixes for Tru64 Unix.
Additional platform support.
3.0.9 Dec-31-09
Add AVR32 and win64 ports. Add ARM softfp support.
Many fixes for AIX, Solaris, HP-UX, *BSD.
Several PowerPC and x86-64 bug fixes.
Build DLL for windows.
3.0.8 Dec-19-08
Add *BSD, BeOS, and PA-Linux support.
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
blackfin Alexandre Keunecke I. de Mendonca
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
tile-gx/tilepro Walter Lee
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 the
author at green@moxielogic.com, or the project mailing list at
libffi-discuss@sourceware.org.

1971
.pc/aarch64/aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

1517
.pc/aarch64/config.guess vendored

File diff suppressed because it is too large Load Diff

1779
.pc/aarch64/config.sub vendored

File diff suppressed because it is too large Load Diff

17366
.pc/aarch64/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,512 +0,0 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.68)
AC_INIT([libffi], [3.0.11], [http://github.com/atgreen/libffi/issues])
AC_CONFIG_HEADERS([fficonfig.h])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AX_ENABLE_BUILDDIR
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.
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
# defaults of its own if none are provided.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
save_CFLAGS=$CFLAGS
AC_PROG_CC
CFLAGS=$save_CFLAGS
m4_undefine([_AC_ARG_VAR_PRECIOUS])
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
AX_CC_MAXOPT
AX_CFLAGS_WARN_ALL
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -fexceptions"
fi
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, changeable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd* | amd64-*-openbsd*)
TARGET=X86_64; TARGETDIR=x86
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
avr32*-*-*)
TARGET=AVR32; TARGETDIR=avr32
;;
bfin*)
TARGET=BFIN; TARGETDIR=bfin
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
TARGET=PA_HPUX; TARGETDIR=pa
;;
i?86-*-freebsd* | i?86-*-openbsd*)
TARGET=X86_FREEBSD; TARGETDIR=x86
;;
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
TARGET=X86_WIN32; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux* | mips*-*-openbsd*)
# Support 128-bit long double for NewABI.
HAVE_LONG_DOUBLE='defined(__mips64)'
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-amigaos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin* | powerpc64-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd* | powerpc-*-openbsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc64-*-freebsd*)
TARGET=POWERPC; 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
;;
tile*-*)
TARGET=TILE; TARGETDIR=tile
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
AC_SUBST(AM_LTLDFLAGS)
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(BFIN, test x$TARGET = xBFIN)
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(MOXIE, test x$TARGET = xMOXIE)
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(AVR32, test x$TARGET = xAVR32)
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)
AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
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
GCC_AS_CFI_PSEUDO_OP
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 | $EGREP -i 'illegal|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
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
libffi_cv_as_ascii_pseudo_op, [
libffi_cv_as_ascii_pseudo_op=unknown
# Check if we have .ascii
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
[libffi_cv_as_ascii_pseudo_op=yes],
[libffi_cv_as_ascii_pseudo_op=no])
])
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
[Define if your assembler supports .ascii.])
fi
AC_CACHE_CHECK([assembler .string pseudo-op support],
libffi_cv_as_string_pseudo_op, [
libffi_cv_as_string_pseudo_op=unknown
# Check if we have .string
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
[libffi_cv_as_string_pseudo_op=yes],
[libffi_cv_as_string_pseudo_op=no])
])
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
[Define if your assembler supports .string.])
fi
fi
if test x$TARGET = xX86_WIN64; then
LT_SYS_SYMBOL_USCORE
if test "x$sys_symbol_underscore" = xyes; then
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
fi
fi
FFI_EXEC_TRAMPOLINE_TABLE=0
case "$target" in
*arm*-apple-darwin*)
FFI_EXEC_TRAMPOLINE_TABLE=1
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
[Cannot use PROT_EXEC on this target, so, we revert to
alternative means])
;;
*-apple-darwin1[[10]]* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
[Cannot use malloc on this target, so, we revert to
alternative means])
;;
esac
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
if test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports unwind section type],
libffi_cv_as_x86_64_unwind_section_type, [
libffi_cv_as_x86_64_unwind_section_type=yes
echo '.section .eh_frame,"a",@unwind' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_64_unwind_section_type=no
fi
])
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
[Define if your assembler supports unwind section type.])
fi
fi
if test "x$GCC" = "xyes"; then
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
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)
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
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)
# These variables are only ever used when we cross-build to X86_WIN32.
# And we only support this with GCC, so...
if test x"$GCC" != x"no"; then
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)
fi
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 libffi.pc)
AC_OUTPUT

View File

@@ -1,350 +0,0 @@
# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
proc load_gcc_lib { filename } {
global srcdir
load_file $srcdir/lib/$filename
}
load_lib dg.exp
load_lib libgloss.exp
load_gcc_lib target-libpath.exp
load_gcc_lib wrapper.exp
# Define libffi callbacks for dg.exp.
proc libffi-dg-test-1 { target_compile prog do_what extra_tool_flags } {
# To get all \n in dg-output test strings to match printf output
# in a system that outputs it as \015\012 (i.e. not just \012), we
# need to change all \n into \r?\n. As there is no dejagnu flag
# or hook to do that, we simply change the text being tested.
# Unfortunately, we have to know that the variable is called
# dg-output-text and lives in the caller of libffi-dg-test, which
# is two calls up. Overriding proc dg-output would be longer and
# would necessarily have the same assumption.
upvar 2 dg-output-text output_match
if { [llength $output_match] > 1 } {
regsub -all "\n" [lindex $output_match 1] "\r?\n" x
set output_match [lreplace $output_match 1 1 $x]
}
# Set up the compiler flags, based on what we're going to do.
set options [list]
switch $do_what {
"compile" {
set compile_type "assembly"
set output_file "[file rootname [file tail $prog]].s"
}
"link" {
set compile_type "executable"
set output_file "[file rootname [file tail $prog]].exe"
# The following line is needed for targets like the i960 where
# the default output file is b.out. Sigh.
}
"run" {
set compile_type "executable"
# FIXME: "./" is to cope with "." not being in $PATH.
# Should this be handled elsewhere?
# YES.
set output_file "./[file rootname [file tail $prog]].exe"
# This is the only place where we care if an executable was
# created or not. If it was, dg.exp will try to run it.
remote_file build delete $output_file;
}
default {
perror "$do_what: not a valid dg-do keyword"
return ""
}
}
if { $extra_tool_flags != "" } {
lappend options "additional_flags=$extra_tool_flags"
}
set comp_output [libffi_target_compile "$prog" "$output_file" "$compile_type" $options];
return [list $comp_output $output_file]
}
proc libffi-dg-test { prog do_what extra_tool_flags } {
return [libffi-dg-test-1 target_compile $prog $do_what $extra_tool_flags]
}
proc libffi-init { args } {
global gluefile wrap_flags;
global srcdir
global blddirffi
global objdir
global TOOL_OPTIONS
global tool
global libffi_include
global libffi_link_flags
global tool_root_dir
global ld_library_path
set blddirffi [pwd]/..
verbose "libffi $blddirffi"
set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
if {$gccdir != ""} {
set gccdir [file dirname $gccdir]
}
verbose "gccdir $gccdir"
set ld_library_path "."
append ld_library_path ":${gccdir}"
set compiler "${gccdir}/xgcc"
if { [is_remote host] == 0 && [which $compiler] != 0 } {
foreach i "[exec $compiler --print-multi-lib]" {
set mldir ""
regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
set mldir [string trimright $mldir "\;@"]
if { "$mldir" == "." } {
continue
}
if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
append ld_library_path ":${gccdir}/${mldir}"
}
}
}
# add the library path for libffi.
append ld_library_path ":${blddirffi}/.libs"
verbose "ld_library_path: $ld_library_path"
# Point to the Libffi headers in libffi.
set libffi_include "${blddirffi}/include"
verbose "libffi_include $libffi_include"
set libffi_dir "${blddirffi}/.libs"
verbose "libffi_dir $libffi_dir"
if { $libffi_dir != "" } {
set libffi_dir [file dirname ${libffi_dir}]
set libffi_link_flags "-L${libffi_dir}/.libs"
}
set_ld_library_path_env_vars
libffi_maybe_build_wrapper "${objdir}/testglue.o"
}
proc libffi_exit { } {
global gluefile;
if [info exists gluefile] {
file_on_build delete $gluefile;
unset gluefile;
}
}
proc libffi_target_compile { source dest type options } {
global gluefile wrap_flags;
global srcdir
global blddirffi
global TOOL_OPTIONS
global libffi_link_flags
global libffi_include
global target_triplet
if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
lappend options "libs=${gluefile}"
lappend options "ldflags=$wrap_flags"
}
# TOOL_OPTIONS must come first, so that it doesn't override testcase
# specific options.
if [info exists TOOL_OPTIONS] {
lappend options [concat "additional_flags=$TOOL_OPTIONS" $options];
}
# search for ffi_mips.h in srcdir, too
lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.."
lappend options "additional_flags=${libffi_link_flags}"
# Darwin needs a stack execution allowed flag.
if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"]
|| [istarget "*-*-darwin2*"] } {
lappend options "additional_flags=-Wl,-allow_stack_execute"
}
# If you're building the compiler with --prefix set to a place
# where it's not yet installed, then the linker won't be able to
# find the libgcc used by libffi.dylib. We could pass the
# -dylib_file option, but that's complicated, and it's much easier
# to just make the linker find libgcc using -L options.
if { [string match "*-*-darwin*" $target_triplet] } {
lappend options "libs= -shared-libgcc"
}
if { [string match "*-*-openbsd*" $target_triplet] } {
lappend options "libs= -lpthread"
}
lappend options "libs= -lffi"
verbose "options: $options"
return [target_compile $source $dest $type $options]
}
# Utility routines.
#
# search_for -- looks for a string match in a file
#
proc search_for { file pattern } {
set fd [open $file r]
while { [gets $fd cur_line]>=0 } {
if [string match "*$pattern*" $cur_line] then {
close $fd
return 1
}
}
close $fd
return 0
}
# Modified dg-runtest that can cycle through a list of optimization options
# as c-torture does.
proc libffi-dg-runtest { testcases default-extra-flags } {
global runtests
foreach test $testcases {
# If we're only testing specific files and this isn't one of
# them, skip it.
if ![runtest_file_p $runtests $test] {
continue
}
# Look for a loop within the source code - if we don't find one,
# don't pass -funroll[-all]-loops.
global torture_with_loops torture_without_loops
if [expr [search_for $test "for*("]+[search_for $test "while*("]] {
set option_list $torture_with_loops
} else {
set option_list $torture_without_loops
}
set nshort [file tail [file dirname $test]]/[file tail $test]
foreach flags $option_list {
verbose "Testing $nshort, $flags" 1
dg-test $test $flags ${default-extra-flags}
}
}
}
# Like check_conditional_xfail, but callable from a dg test.
proc dg-xfail-if { args } {
set args [lreplace $args 0 0]
set selector "target [join [lindex $args 1]]"
if { [dg-process-target $selector] == "S" } {
global compiler_conditional_xfail_data
set compiler_conditional_xfail_data $args
}
}
proc check-flags { args } {
# The args are within another list; pull them out.
set args [lindex $args 0]
# The next two arguments are optional. If they were not specified,
# use the defaults.
if { [llength $args] == 2 } {
lappend $args [list "*"]
}
if { [llength $args] == 3 } {
lappend $args [list ""]
}
# If the option strings are the defaults, or the same as the
# defaults, there is no need to call check_conditional_xfail to
# compare them to the actual options.
if { [string compare [lindex $args 2] "*"] == 0
&& [string compare [lindex $args 3] "" ] == 0 } {
set result 1
} else {
# The target list might be an effective-target keyword, so replace
# the original list with "*-*-*", since we already know it matches.
set result [check_conditional_xfail [lreplace $args 1 1 "*-*-*"]]
}
return $result
}
proc dg-skip-if { args } {
# Verify the number of arguments. The last two are optional.
set args [lreplace $args 0 0]
if { [llength $args] < 2 || [llength $args] > 4 } {
error "dg-skip-if 2: need 2, 3, or 4 arguments"
}
# Don't bother if we're already skipping the test.
upvar dg-do-what dg-do-what
if { [lindex ${dg-do-what} 1] == "N" } {
return
}
set selector [list target [lindex $args 1]]
if { [dg-process-target $selector] == "S" } {
if [check-flags $args] {
upvar dg-do-what dg-do-what
set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
}
}
}
# We need to make sure that additional_files and additional_sources
# are both cleared out after every test. It is not enough to clear
# them out *before* the next test run because gcc-target-compile gets
# run directly from some .exp files (outside of any test). (Those
# uses should eventually be eliminated.)
# Because the DG framework doesn't provide a hook that is run at the
# end of a test, we must replace dg-test with a wrapper.
if { [info procs saved-dg-test] == [list] } {
rename dg-test saved-dg-test
proc dg-test { args } {
global additional_files
global additional_sources
global errorInfo
if { [ catch { eval saved-dg-test $args } errmsg ] } {
set saved_info $errorInfo
set additional_files ""
set additional_sources ""
error $errmsg $saved_info
}
set additional_files ""
set additional_sources ""
}
}
# Local Variables:
# tcl-indent-level:4
# End:

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,457 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
libffi @VERSION@ - Copyright (c) 2011 Anthony Green
- 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. */
#ifndef @TARGET@
#define @TARGET@
#endif
/* ---- 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. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif /* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif /* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# 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 != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#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 == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* Need minimal decorations for DLLs to works on Windows. */
/* GCC has autoimport and autoexport. Rely on Libtool to */
/* help MSVC export from a DLL, but always declare data */
/* to be imported for MSVC clients. This costs an extra */
/* indirection for MSVC clients using the static version */
/* of the library, but don't worry about that. Besides, */
/* as a workaround, they can define FFI_BUILDING if they */
/* *know* they are going to link with the static library. */
#if defined _MSC_VER && !defined FFI_BUILDING
#define FFI_EXTERN extern __declspec(dllimport)
#else
#define FFI_EXTERN extern
#endif
/* These are defined in types.c */
FFI_EXTERN ffi_type ffi_type_void;
FFI_EXTERN ffi_type ffi_type_uint8;
FFI_EXTERN ffi_type ffi_type_sint8;
FFI_EXTERN ffi_type ffi_type_uint16;
FFI_EXTERN ffi_type ffi_type_sint16;
FFI_EXTERN ffi_type ffi_type_uint32;
FFI_EXTERN ffi_type ffi_type_sint32;
FFI_EXTERN ffi_type ffi_type_uint64;
FFI_EXTERN ffi_type ffi_type_sint64;
FFI_EXTERN ffi_type ffi_type_float;
FFI_EXTERN ffi_type ffi_type_double;
FFI_EXTERN ffi_type ffi_type_pointer;
#if @HAVE_LONG_DOUBLE@
FFI_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;
/* Used internally, but overridden by some architectures */
ffi_status ffi_prep_cif_core(ffi_cif *cif,
ffi_abi abi,
unsigned int isvariadic,
unsigned int nfixedargs,
unsigned int ntotalargs,
ffi_type *rtype,
ffi_type **atypes);
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# 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
#ifdef _MSC_VER
__declspec(align(8))
#endif
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
#ifdef __GNUC__
} ffi_closure __attribute__((aligned (8)));
#else
} ffi_closure;
# ifdef __sgi
# pragma pack 0
# endif
#endif
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);
#ifdef __sgi
# pragma pack 8
#endif
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);
ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_abi abi,
unsigned int nfixedargs,
unsigned int ntotalargs,
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

@@ -1,505 +0,0 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
Copyright (c) 2011 Plausible Labs Cooperative, 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
#ifdef __APPLE__
#define ENTRY(x) .globl CNAME(x); CNAME(x):
#else
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
#endif /* __APPLE__ */
#endif
#ifdef __ELF__
#define LSYM(x) .x
#else
#define LSYM(x) x
#endif
/* Use the SOFTFP return value ABI on Mac OS X, as per the iOS ABI
Function Call Guide */
#ifdef __APPLE__
#define __SOFTFP__
#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__) \
|| defined(__ARM_ARCH_7EM__)
# 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
#ifdef __APPLE__
ENTRY($0)
#else
ENTRY(\name)
#endif
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. */
#ifdef __APPLE__
_L__$0:
#else
_L__\name:
#endif
.endm
#else
.macro ARM_FUNC_START name
.text
.align 0
.arm
#ifdef __APPLE__
ENTRY($0)
#else
ENTRY(\name)
#endif
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
@ 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 r0, sp
@ r1 already set
@ Call ffi_prep_args(stack, &ecif)
bl ffi_prep_args
@ move first 4 parameters in registers
ldmia sp, {r0-r3}
@ and adjust stack
sub lr, fp, sp @ cif->bytes == fp - sp
ldr ip, [fp] @ load fn() in advance
cmp lr, #16
movhs lr, #16
add sp, sp, lr
@ call (fn) (...)
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):
#if defined (__INTERWORKING__)
ldmia sp!, {r0-r3,fp, lr}
bx lr
#else
ldmia sp!, {r0-r3,fp, pc}
#endif
.ffi_call_SYSV_end:
UNWIND .fnend
#ifdef __ELF__
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
#endif
/*
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
UNWIND .pad #16
sub sp, sp, #16
str sp, [sp, #8]
add r1, sp, #8
bl CNAME(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
#ifdef __ELF__
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
#endif
/* Below are VFP hard-float ABI call and closure implementations.
Add VFP FPU directive here. This is only compiled into the library
under EABI. */
#ifdef __ARM_EABI__
.fpu vfp
@ r0: fn
@ r1: &ecif
@ r2: cif->bytes
@ r3: fig->flags
@ sp+0: ecif.rvalue
ARM_FUNC_START ffi_call_VFP
@ 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, sp, r2
@ Make room for loading VFP args
sub sp, sp, #64
@ Place all of the ffi_prep_args in position
mov r0, sp
@ r1 already set
sub r2, fp, #64 @ VFP scratch space
@ Call ffi_prep_args(stack, &ecif, vfp_space)
bl ffi_prep_args
@ Load VFP register args if needed
cmp r0, #0
beq LSYM(Lbase_args)
@ Load only d0 if possible
cmp r0, #3
sub ip, fp, #64
flddle d0, [ip]
fldmiadgt ip, {d0-d7}
LSYM(Lbase_args):
@ move first 4 parameters in registers
ldmia sp, {r0-r3}
@ and adjust stack
sub lr, ip, sp @ cif->bytes == (fp - 64) - sp
ldr ip, [fp] @ load fn() in advance
cmp lr, #16
movhs lr, #16
add sp, sp, lr
@ call (fn) (...)
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_vfp)
cmp r3, #FFI_TYPE_INT
streq r0, [r2]
beq LSYM(Lepilogue_vfp)
cmp r3, #FFI_TYPE_SINT64
stmeqia r2, {r0, r1}
beq LSYM(Lepilogue_vfp)
cmp r3, #FFI_TYPE_FLOAT
fstseq s0, [r2]
beq LSYM(Lepilogue_vfp)
cmp r3, #FFI_TYPE_DOUBLE
fstdeq d0, [r2]
beq LSYM(Lepilogue_vfp)
cmp r3, #FFI_TYPE_STRUCT_VFP_FLOAT
cmpne r3, #FFI_TYPE_STRUCT_VFP_DOUBLE
fstmiadeq r2, {d0-d3}
LSYM(Lepilogue_vfp):
RETLDM "r0-r3,fp"
.ffi_call_VFP_end:
UNWIND .fnend
.size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
ARM_FUNC_START ffi_closure_VFP
fstmfdd sp!, {d0-d7}
@ r0-r3, then d0-d7
UNWIND .pad #80
add ip, sp, #80
stmfd sp!, {ip, lr}
UNWIND .save {r0, lr}
add r2, sp, #72
add r3, sp, #8
UNWIND .pad #72
sub sp, sp, #72
str sp, [sp, #64]
add r1, sp, #64
bl ffi_closure_SYSV_inner
cmp r0, #FFI_TYPE_INT
beq .Lretint_vfp
cmp r0, #FFI_TYPE_FLOAT
beq .Lretfloat_vfp
cmp r0, #FFI_TYPE_DOUBLE
cmpne r0, #FFI_TYPE_LONGDOUBLE
beq .Lretdouble_vfp
cmp r0, #FFI_TYPE_SINT64
beq .Lretlonglong_vfp
cmp r0, #FFI_TYPE_STRUCT_VFP_FLOAT
beq .Lretfloat_struct_vfp
cmp r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
beq .Lretdouble_struct_vfp
.Lclosure_epilogue_vfp:
add sp, sp, #72
ldmfd sp, {sp, pc}
.Lretfloat_vfp:
flds s0, [sp]
b .Lclosure_epilogue_vfp
.Lretdouble_vfp:
fldd d0, [sp]
b .Lclosure_epilogue_vfp
.Lretint_vfp:
ldr r0, [sp]
b .Lclosure_epilogue_vfp
.Lretlonglong_vfp:
ldmia sp, {r0, r1}
b .Lclosure_epilogue_vfp
.Lretfloat_struct_vfp:
fldmiad sp, {d0-d1}
b .Lclosure_epilogue_vfp
.Lretdouble_struct_vfp:
fldmiad sp, {d0-d3}
b .Lclosure_epilogue_vfp
.ffi_closure_VFP_end:
UNWIND .fnend
.size CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
#endif
ENTRY(ffi_arm_trampoline)
stmfd sp!, {r0-r3}
ldr r0, [pc]
ldr pc, [pc]
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits
#endif

View File

@@ -1,841 +0,0 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
Copyright (c) 2002 Ranjit Mathew
Copyright (c) 2002 Bo Thorsen
Copyright (c) 2002 Roger Sayle
Copyright (C) 2008, 2010 Free Software Foundation, Inc.
x86 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.
----------------------------------------------------------------------- */
#if !defined(__x86_64__) || defined(_WIN64)
#ifdef _WIN64
#include <windows.h>
#endif
#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;
#ifdef X86_WIN32
size_t p_stack_args[2];
void *p_stack_data[2];
char *argp2 = stack;
int stack_args_count = 0;
int cabi = ecif->cif->abi;
#endif
argp = stack;
if ((ecif->cif->flags == FFI_TYPE_STRUCT
|| ecif->cif->flags == FFI_TYPE_MS_STRUCT)
#ifdef X86_WIN64
&& (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
&& ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
#endif
)
{
*(void **) argp = ecif->rvalue;
#ifdef X86_WIN32
/* For fastcall/thiscall this is first register-passed
argument. */
if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
{
p_stack_args[stack_args_count] = sizeof (void*);
p_stack_data[stack_args_count] = argp;
++stack_args_count;
}
#endif
argp += sizeof(void*);
}
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 ((sizeof(void*) - 1) & (size_t) argp)
argp = (char *) ALIGN(argp, sizeof(void*));
z = (*p_arg)->size;
#ifdef X86_WIN64
if (z > sizeof(ffi_arg)
|| ((*p_arg)->type == FFI_TYPE_STRUCT
&& (z != 1 && z != 2 && z != 4 && z != 8))
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|| ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
#endif
)
{
z = sizeof(ffi_arg);
*(void **)argp = *p_argv;
}
else if ((*p_arg)->type == FFI_TYPE_FLOAT)
{
memcpy(argp, *p_argv, z);
}
else
#endif
if (z < sizeof(ffi_arg))
{
z = sizeof(ffi_arg);
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
break;
case FFI_TYPE_UINT8:
*(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
break;
case FFI_TYPE_SINT16:
*(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
break;
case FFI_TYPE_UINT16:
*(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
break;
case FFI_TYPE_SINT32:
*(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
break;
case FFI_TYPE_UINT32:
*(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
break;
case FFI_TYPE_STRUCT:
*(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
break;
default:
FFI_ASSERT(0);
}
}
else
{
memcpy(argp, *p_argv, z);
}
#ifdef X86_WIN32
/* For thiscall/fastcall convention register-passed arguments
are the first two none-floating-point arguments with a size
smaller or equal to sizeof (void*). */
if ((cabi == FFI_THISCALL && stack_args_count < 1)
|| (cabi == FFI_FASTCALL && stack_args_count < 2))
{
if (z <= 4
&& ((*p_arg)->type != FFI_TYPE_FLOAT
&& (*p_arg)->type != FFI_TYPE_STRUCT))
{
p_stack_args[stack_args_count] = z;
p_stack_data[stack_args_count] = argp;
++stack_args_count;
}
}
#endif
p_argv++;
#ifdef X86_WIN64
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
#else
argp += z;
#endif
}
#ifdef X86_WIN32
/* We need to move the register-passed arguments for thiscall/fastcall
on top of stack, so that those can be moved to registers ecx/edx by
call-handler. */
if (stack_args_count > 0)
{
size_t zz = (p_stack_args[0] + 3) & ~3;
char *h;
/* Move first argument to top-stack position. */
if (p_stack_data[0] != argp2)
{
h = alloca (zz + 1);
memcpy (h, p_stack_data[0], zz);
memmove (argp2 + zz, argp2,
(size_t) ((char *) p_stack_data[0] - (char*)argp2));
memcpy (argp2, h, zz);
}
argp2 += zz;
--stack_args_count;
if (zz > 4)
stack_args_count = 0;
/* If we have a second argument, then move it on top
after the first one. */
if (stack_args_count > 0 && p_stack_data[1] != argp2)
{
zz = p_stack_args[1];
zz = (zz + 3) & ~3;
h = alloca (zz + 1);
h = alloca (zz + 1);
memcpy (h, p_stack_data[1], zz);
memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2));
memcpy (argp2, h, zz);
}
}
#endif
return;
}
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
unsigned int i;
ffi_type **ptr;
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
#ifdef X86_WIN64
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
#endif
case FFI_TYPE_SINT64:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
#ifndef X86_WIN64
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
#endif
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_UINT64:
#ifdef X86_WIN64
case FFI_TYPE_POINTER:
#endif
cif->flags = FFI_TYPE_SINT64;
break;
case FFI_TYPE_STRUCT:
#ifndef X86
if (cif->rtype->size == 1)
{
cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
}
else if (cif->rtype->size == 2)
{
cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
}
else if (cif->rtype->size == 4)
{
#ifdef X86_WIN64
cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
#else
cif->flags = FFI_TYPE_INT; /* same as int type */
#endif
}
else if (cif->rtype->size == 8)
{
cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
}
else
#endif
{
if (cif->abi == FFI_MS_CDECL)
cif->flags = FFI_TYPE_MS_STRUCT;
else
cif->flags = FFI_TYPE_STRUCT;
/* allocate space for return value pointer */
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
}
break;
default:
#ifdef X86_WIN64
cif->flags = FFI_TYPE_SINT64;
break;
case FFI_TYPE_INT:
cif->flags = FFI_TYPE_SINT32;
#else
cif->flags = FFI_TYPE_INT;
#endif
break;
}
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
if (((*ptr)->alignment - 1) & cif->bytes)
cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
}
#ifdef X86_WIN64
/* ensure space for storing four registers */
cif->bytes += 4 * sizeof(ffi_arg);
#endif
#ifdef X86_DARWIN
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
return FFI_OK;
}
#ifdef X86_WIN64
extern int
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#elif defined(X86_WIN32)
extern void
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
#else
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#endif
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 */
#ifdef X86_WIN64
if (rvalue == NULL
&& cif->flags == FFI_TYPE_STRUCT
&& cif->rtype->size != 1 && cif->rtype->size != 2
&& cif->rtype->size != 4 && cif->rtype->size != 8)
{
ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
}
#else
if (rvalue == NULL
&& (cif->flags == FFI_TYPE_STRUCT
|| cif->flags == FFI_TYPE_MS_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
#endif
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
#ifdef X86_WIN64
case FFI_WIN64:
ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
break;
#elif defined(X86_WIN32)
case FFI_SYSV:
case FFI_STDCALL:
case FFI_MS_CDECL:
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
case FFI_THISCALL:
case FFI_FASTCALL:
{
unsigned int abi = cif->abi;
unsigned int i, passed_regs = 0;
if (cif->flags == FFI_TYPE_STRUCT)
++passed_regs;
for (i=0; i < cif->nargs && passed_regs < 2;i++)
{
size_t sz;
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
continue;
sz = (cif->arg_types[i]->size + 3) & ~3;
if (sz == 0 || sz > 4)
continue;
++passed_regs;
}
if (passed_regs < 2 && abi == FFI_FASTCALL)
abi = FFI_THISCALL;
if (passed_regs < 1 && abi == FFI_THISCALL)
abi = FFI_STDCALL;
ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
}
break;
#else
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
fn);
break;
#endif
default:
FFI_ASSERT(0);
break;
}
}
/** private members **/
/* The following __attribute__((regparm(1))) decorations will have no effect
on MSVC - standard cdecl convention applies. */
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
__attribute__ ((regparm(1)));
unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
__attribute__ ((regparm(1)));
#ifdef X86_WIN32
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
__attribute__ ((regparm(1)));
#endif
#ifdef X86_WIN64
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
#endif
/* This function is jumped to by the trampoline */
#ifdef X86_WIN64
void * FFI_HIDDEN
ffi_closure_win64_inner (ffi_closure *closure, void *args) {
ffi_cif *cif;
void **arg_area;
void *result;
void *resp = &result;
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 change RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
(closure->fun) (cif, resp, arg_area, closure->user_data);
/* The result is returned in rax. This does the right thing for
result types except for floats; we have to 'mov xmm0, rax' in the
caller to correct this.
TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
*/
return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
}
#else
unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
ffi_closure_SYSV_inner (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 change 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;
}
#endif /* !X86_WIN64 */
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
ffi_cif *cif)
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
#ifdef X86_WIN64
if (cif->rtype->size > sizeof(ffi_arg)
|| (cif->flags == FFI_TYPE_STRUCT
&& (cif->rtype->size != 1 && cif->rtype->size != 2
&& cif->rtype->size != 4 && cif->rtype->size != 8))) {
*rvalue = *(void **) argp;
argp += sizeof(void *);
}
#else
if ( cif->flags == FFI_TYPE_STRUCT
|| cif->flags == FFI_TYPE_MS_STRUCT ) {
*rvalue = *(void **) argp;
argp += sizeof(void *);
}
#endif
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
/* Align if necessary */
if ((sizeof(void*) - 1) & (size_t) argp) {
argp = (char *) ALIGN(argp, sizeof(void*));
}
#ifdef X86_WIN64
if ((*p_arg)->size > sizeof(ffi_arg)
|| ((*p_arg)->type == FFI_TYPE_STRUCT
&& ((*p_arg)->size != 1 && (*p_arg)->size != 2
&& (*p_arg)->size != 4 && (*p_arg)->size != 8)))
{
z = sizeof(void *);
*p_argv = *(void **)argp;
}
else
#endif
{
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
}
p_argv++;
#ifdef X86_WIN64
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
#else
argp += z;
#endif
}
return;
}
#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
void* __fun = (void*)(FUN); \
void* __ctx = (void*)(CTX); \
*(unsigned char*) &__tramp[0] = 0x41; \
*(unsigned char*) &__tramp[1] = 0xbb; \
*(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
*(unsigned char*) &__tramp[6] = 0x48; \
*(unsigned char*) &__tramp[7] = 0xb8; \
*(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
*(unsigned char *) &__tramp[16] = 0x49; \
*(unsigned char *) &__tramp[17] = 0xba; \
*(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
*(unsigned char *) &__tramp[26] = 0x41; \
*(unsigned char *) &__tramp[27] = 0xff; \
*(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
}
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
#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 __dis = __fun - (__ctx + 10); \
*(unsigned char*) &__tramp[0] = 0xb8; \
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe9; \
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
}
#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - (__ctx + 49); \
unsigned short __size = (unsigned short)(SIZE); \
*(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
*(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
*(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
*(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
*(unsigned char*) &__tramp[13] = 0xb8; \
*(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
*(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
*(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
*(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
*(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
*(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
*(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
*(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
*(unsigned char*) &__tramp[39] = 0xb8; \
*(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[44] = 0xe8; \
*(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
*(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
*(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
}
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - (__ctx + 10); \
unsigned short __size = (unsigned short)(SIZE); \
*(unsigned char*) &__tramp[0] = 0xb8; \
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe8; \
*(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
*(unsigned char *) &__tramp[10] = 0xc2; \
*(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
}
/* 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)
{
#ifdef X86_WIN64
#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
if (cif->abi == FFI_WIN64)
{
int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
&ffi_closure_win64,
codeloc, mask);
/* make sure we can execute here */
}
#else
if (cif->abi == FFI_SYSV)
{
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
&ffi_closure_SYSV,
(void*)codeloc);
}
#ifdef X86_WIN32
else if (cif->abi == FFI_THISCALL)
{
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
&ffi_closure_THISCALL,
(void*)codeloc,
cif->bytes);
}
else if (cif->abi == FFI_STDCALL)
{
FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
&ffi_closure_STDCALL,
(void*)codeloc, cif->bytes);
}
else if (cif->abi == FFI_MS_CDECL)
{
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
&ffi_closure_SYSV,
(void*)codeloc);
}
#endif /* X86_WIN32 */
#endif /* !X86_WIN64 */
else
{
return FFI_BAD_ABI;
}
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}
/* ------- Native raw API support -------------------------------- */
#if !FFI_NO_RAW_API
ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc)
{
int i;
if (cif->abi != FFI_SYSV) {
#ifdef X86_WIN32
if (cif->abi != FFI_THISCALL)
#endif
return FFI_BAD_ABI;
}
/* we currently don't support certain kinds of arguments for raw
closures. This should be implemented by a separate assembly
language routine, since it would require argument processing,
something we don't do now for performance. */
for (i = cif->nargs-1; i >= 0; i--)
{
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
}
#ifdef X86_WIN32
if (cif->abi == FFI_SYSV)
{
#endif
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
codeloc);
#ifdef X86_WIN32
}
else if (cif->abi == FFI_THISCALL)
{
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL,
codeloc, cif->bytes);
}
#endif
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}
static void
ffi_prep_args_raw(char *stack, extended_cif *ecif)
{
memcpy (stack, ecif->avalue, ecif->cif->bytes);
}
/* we borrow this routine from libffi (it must be changed, though, to
* actually call the function passed in the first argument. as of
* libffi-1.20, this is not the case.)
*/
void
ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
{
extended_cif ecif;
void **avalue = (void **)fake_avalue;
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->flags == FFI_TYPE_STRUCT
|| cif->flags == FFI_TYPE_MS_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
#ifdef X86_WIN32
case FFI_SYSV:
case FFI_STDCALL:
case FFI_MS_CDECL:
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
case FFI_THISCALL:
case FFI_FASTCALL:
{
unsigned int abi = cif->abi;
unsigned int i, passed_regs = 0;
if (cif->flags == FFI_TYPE_STRUCT)
++passed_regs;
for (i=0; i < cif->nargs && passed_regs < 2;i++)
{
size_t sz;
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
continue;
sz = (cif->arg_types[i]->size + 3) & ~3;
if (sz == 0 || sz > 4)
continue;
++passed_regs;
}
if (passed_regs < 2 && abi == FFI_FASTCALL)
cif->abi = abi = FFI_THISCALL;
if (passed_regs < 1 && abi == FFI_THISCALL)
cif->abi = abi = FFI_STDCALL;
ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
}
break;
#else
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
#endif
default:
FFI_ASSERT(0);
break;
}
}
#endif
#endif /* !__x86_64__ || X86_WIN64 */

View File

@@ -1,27 +0,0 @@
stand-alone
aix-fix
mint
win32
win32_tests
vararg_float_test_fix
vfp-eabi
msvc-changes
win32-return-sign
apple-fixes
dist-tests
icc128
x32libtool
arm-test-fix
xcode
darwin-missing-semi
xcode-improvements
update-disty
v3_0_11
bfin
ios-fix
mingw-check-fix
whitespace-fix
tile
aarch64
darwin12
emutramp

View File

@@ -1,64 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Test doubles passed in variable argument lists.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-output "" { xfail avr32*-*-* } } */
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
#include "ffitest.h"
static void
cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
char* format = *(char**)args[0];
double doubleValue = *(double*)args[1];
*(ffi_arg*)resp = printf(format, doubleValue);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[3];
ffi_type* arg_types[3];
char* format = "%.1f\n";
double doubleArg = 7;
ffi_arg res = 0;
arg_types[0] = &ffi_type_pointer;
arg_types[1] = &ffi_type_double;
arg_types[2] = NULL;
/* This printf call is variadic */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
arg_types) == FFI_OK);
args[0] = &format;
args[1] = &doubleArg;
args[2] = NULL;
ffi_call(&cif, FFI_FN(printf), &res, args);
// { dg-output "7.0" }
printf("res: %d\n", (int) res);
// { dg-output "\nres: 4" }
/* The call to cls_double_va_fn is static, so have to use a normal prep_cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK);
res = ((int(*)(char*, double))(code))(format, doubleArg);
// { dg-output "\n7.0" }
printf("res: %d\n", (int) res);
// { dg-output "\nres: 4" }
exit(0);
}

View File

@@ -1,65 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Test long doubles passed in variable argument lists.
Limitations: none.
PR: none.
Originator: Blake Chaffin 6/6/2007 */
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
/* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */
/* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */
/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */
#include "ffitest.h"
static void
cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
char* format = *(char**)args[0];
long double ldValue = *(long double*)args[1];
*(ffi_arg*)resp = printf(format, ldValue);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[3];
ffi_type* arg_types[3];
char* format = "%.1Lf\n";
long double ldArg = 7;
ffi_arg res = 0;
arg_types[0] = &ffi_type_pointer;
arg_types[1] = &ffi_type_longdouble;
arg_types[2] = NULL;
/* This printf call is variadic */
CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
arg_types) == FFI_OK);
args[0] = &format;
args[1] = &ldArg;
args[2] = NULL;
ffi_call(&cif, FFI_FN(printf), &res, args);
// { dg-output "7.0" }
printf("res: %d\n", (int) res);
// { dg-output "\nres: 4" }
/* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK);
res = ((int(*)(char*, long double))(code))(format, ldArg);
// { dg-output "\n7.0" }
printf("res: %d\n", (int) res);
// { dg-output "\nres: 4" }
exit(0);
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,205 +0,0 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects
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/avr32/ffi.c src/avr32/sysv.S src/avr32/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/win64.S src/x86/freebsd.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 libtool-version \
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
m4/ltversion.m4 src/arm/gentramp.sh src/debug.c \
msvcc.sh generate-ios-source-and-headers.py \
generate-osx-source-and-headers.py \
libffi.xcodeproj/project.pbxproj \
src/arm/trampoline.S
info_TEXINFOS = doc/libffi.texi
## ################################################################
##
## 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)" \
"mandir=$(mandir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
"CC=$(CC)" \
"CXX=$(CXX)" \
"LD=$(LD)" \
"NM=$(NM)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES=
ACLOCAL_AMFLAGS=$(ACLOCAL_AMFLAGS) -I m4
lib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/closures.c
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libffi.pc
nodist_libffi_la_SOURCES =
if FFI_DEBUG
nodist_libffi_la_SOURCES += src/debug.c
endif
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
if FFI_EXEC_TRAMPOLINE_TABLE
nodist_libffi_la_SOURCES += src/arm/trampoline.S
endif
endif
if AVR32
nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/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 = -g
if FFI_DEBUG
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
# MSVC, it can link against the debug CRT.
AM_CFLAGS += -DFFI_DEBUG
endif
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src -DFFI_BUILDING
AM_CCASFLAGS = $(AM_CPPFLAGS) -g
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf:

File diff suppressed because it is too large Load Diff

View File

@@ -1,359 +0,0 @@
Status
======
libffi-3.0.12 was released on *****************. 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.
For specific configuration details and testing status, please
refer to the wiki page here:
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.11
At the time of release, the following basic configurations have been
tested:
|--------------+------------------|
| Architecture | Operating System |
|--------------+------------------|
| Alpha | Linux |
| Alpha | Tru64 |
| ARM | Linux |
| ARM | iOS |
| AVR32 | Linux |
| HPPA | HPUX |
| IA-64 | Linux |
| M68K | FreeMiNT |
| M68K | RTEMS |
| MIPS | IRIX |
| MIPS | Linux |
| MIPS | RTEMS |
| MIPS64 | Linux |
| PowerPC | AMIGA |
| PowerPC | Linux |
| PowerPC | Mac OSX |
| PowerPC | FreeBSD |
| PowerPC64 | Linux |
| S390 | Linux |
| S390X | Linux |
| SPARC | Linux |
| SPARC | Solaris |
| SPARC64 | Linux |
| SPARC64 | FreeBSD |
| X86 | FreeBSD |
| X86 | Interix |
| X86 | kFreeBSD |
| X86 | Linux |
| X86 | Mac OSX |
| X86 | OpenBSD |
| X86 | OS/2 |
| X86 | Solaris |
| X86 | Windows/Cygwin |
| X86 | Windows/MingW |
| X86-64 | FreeBSD |
| X86-64 | Linux |
| X86-64 | Linux/x32 |
| X86-64 | OpenBSD |
| X86-64 | Windows/MingW |
|--------------+------------------|
Please send additional platform test results to
libffi-discuss@sourceware.org and feel free to update the wiki page
above.
Installing libffi
=================
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.
It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
You may also need to specify --build appropriately. When building with MSVC
under a MingW environment, you may need to remove the line in configure
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.)
For iOS builds, run generate-ios-source-and-headers.py and then
libffi.xcodeproj should work.
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".
History
=======
See the ChangeLog files for details.
3.0.11 MMM-DD-YY
Lots of build fixes.
Add Amiga newer MacOS support.
Add support for variadic functions (ffi_prep_cif_var).
Add Linux/x32 support.
Add thiscall, fastcall and MSVC cdecl support on Windows.
Add Amiga and newer MacOS support.
Add m68k FreeMiNT support.
Integration with iOS' xcode build tools.
Fix Octeon and MC68881 support.
Fix code pessimizations.
Lots of build fixes.
3.0.10 Aug-23-11
Add support for Apple's iOS.
Add support for ARM VFP ABI.
Add RTEMS support for MIPS and M68K.
Fix instruction cache clearing problems on
ARM and SPARC.
Fix the N64 build on mips-sgi-irix6.5.
Enable builds with Microsoft's compiler.
Enable x86 builds with Oracle's Solaris compiler.
Fix support for calling code compiled with Oracle's Sparc
Solaris compiler.
Testsuite fixes for Tru64 Unix.
Additional platform support.
3.0.9 Dec-31-09
Add AVR32 and win64 ports. Add ARM softfp support.
Many fixes for AIX, Solaris, HP-UX, *BSD.
Several PowerPC and x86-64 bug fixes.
Build DLL for windows.
3.0.8 Dec-19-08
Add *BSD, BeOS, and PA-Linux support.
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 the
author at green@moxielogic.com, or the project mailing list at
libffi-discuss@sourceware.org.

17337
.pc/bfin/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,502 +0,0 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.68)
AC_INIT([libffi], [3.0.11], [http://github.com/atgreen/libffi/issues])
AC_CONFIG_HEADERS([fficonfig.h])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AX_ENABLE_BUILDDIR
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.
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
# defaults of its own if none are provided.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
save_CFLAGS=$CFLAGS
AC_PROG_CC
CFLAGS=$save_CFLAGS
m4_undefine([_AC_ARG_VAR_PRECIOUS])
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
AX_CC_MAXOPT
AX_CFLAGS_WARN_ALL
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -fexceptions"
fi
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, changeable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd* | amd64-*-openbsd*)
TARGET=X86_64; TARGETDIR=x86
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
avr32*-*-*)
TARGET=AVR32; TARGETDIR=avr32
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
TARGET=PA_HPUX; TARGETDIR=pa
;;
i?86-*-freebsd* | i?86-*-openbsd*)
TARGET=X86_FREEBSD; TARGETDIR=x86
;;
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
TARGET=X86_WIN32; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux* | mips*-*-openbsd*)
# Support 128-bit long double for NewABI.
HAVE_LONG_DOUBLE='defined(__mips64)'
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-amigaos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin* | powerpc64-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd* | powerpc-*-openbsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc64-*-freebsd*)
TARGET=POWERPC; 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
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
AC_SUBST(AM_LTLDFLAGS)
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(MOXIE, test x$TARGET = xMOXIE)
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(AVR32, test x$TARGET = xAVR32)
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
GCC_AS_CFI_PSEUDO_OP
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 | $EGREP -i 'illegal|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
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
libffi_cv_as_ascii_pseudo_op, [
libffi_cv_as_ascii_pseudo_op=unknown
# Check if we have .ascii
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
[libffi_cv_as_ascii_pseudo_op=yes],
[libffi_cv_as_ascii_pseudo_op=no])
])
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
[Define if your assembler supports .ascii.])
fi
AC_CACHE_CHECK([assembler .string pseudo-op support],
libffi_cv_as_string_pseudo_op, [
libffi_cv_as_string_pseudo_op=unknown
# Check if we have .string
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
[libffi_cv_as_string_pseudo_op=yes],
[libffi_cv_as_string_pseudo_op=no])
])
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
[Define if your assembler supports .string.])
fi
fi
if test x$TARGET = xX86_WIN64; then
LT_SYS_SYMBOL_USCORE
if test "x$sys_symbol_underscore" = xyes; then
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
fi
fi
FFI_EXEC_TRAMPOLINE_TABLE=0
case "$target" in
*arm*-apple-darwin*)
FFI_EXEC_TRAMPOLINE_TABLE=1
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
[Cannot use PROT_EXEC on this target, so, we revert to
alternative means])
;;
*-apple-darwin1[[10]]* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
[Cannot use malloc on this target, so, we revert to
alternative means])
;;
esac
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
if test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports unwind section type],
libffi_cv_as_x86_64_unwind_section_type, [
libffi_cv_as_x86_64_unwind_section_type=yes
echo '.section .eh_frame,"a",@unwind' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_64_unwind_section_type=no
fi
])
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
[Define if your assembler supports unwind section type.])
fi
fi
if test "x$GCC" = "xyes"; then
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
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)
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
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)
# These variables are only ever used when we cross-build to X86_WIN32.
# And we only support this with GCC, so...
if test x"$GCC" != x"no"; then
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)
fi
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 libffi.pc)
AC_OUTPUT

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

17404
.pc/darwin12/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,517 +0,0 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.68)
AC_INIT([libffi], [3.0.11], [http://github.com/atgreen/libffi/issues])
AC_CONFIG_HEADERS([fficonfig.h])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AX_ENABLE_BUILDDIR
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.
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
# defaults of its own if none are provided.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
save_CFLAGS=$CFLAGS
AC_PROG_CC
CFLAGS=$save_CFLAGS
m4_undefine([_AC_ARG_VAR_PRECIOUS])
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
AX_CC_MAXOPT
AX_CFLAGS_WARN_ALL
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -fexceptions"
fi
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
aarch64*-*-*)
TARGET=AARCH64; TARGETDIR=aarch64
;;
alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changeable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd* | amd64-*-openbsd*)
TARGET=X86_64; TARGETDIR=x86
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
avr32*-*-*)
TARGET=AVR32; TARGETDIR=avr32
;;
bfin*)
TARGET=BFIN; TARGETDIR=bfin
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
TARGET=PA_HPUX; TARGETDIR=pa
;;
i?86-*-freebsd* | i?86-*-openbsd*)
TARGET=X86_FREEBSD; TARGETDIR=x86
;;
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
TARGET=X86_WIN32; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux* | mips*-*-openbsd*)
# Support 128-bit long double for NewABI.
HAVE_LONG_DOUBLE='defined(__mips64)'
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-amigaos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin* | powerpc64-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd* | powerpc-*-openbsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc64-*-freebsd*)
TARGET=POWERPC; 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
;;
tile*-*)
TARGET=TILE; TARGETDIR=tile
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
AC_SUBST(AM_LTLDFLAGS)
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(BFIN, test x$TARGET = xBFIN)
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(MOXIE, test x$TARGET = xMOXIE)
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(AARCH64, test x$TARGET = xAARCH64)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
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)
AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
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
GCC_AS_CFI_PSEUDO_OP
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 | $EGREP -i 'illegal|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
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
libffi_cv_as_ascii_pseudo_op, [
libffi_cv_as_ascii_pseudo_op=unknown
# Check if we have .ascii
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
[libffi_cv_as_ascii_pseudo_op=yes],
[libffi_cv_as_ascii_pseudo_op=no])
])
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
[Define if your assembler supports .ascii.])
fi
AC_CACHE_CHECK([assembler .string pseudo-op support],
libffi_cv_as_string_pseudo_op, [
libffi_cv_as_string_pseudo_op=unknown
# Check if we have .string
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
[libffi_cv_as_string_pseudo_op=yes],
[libffi_cv_as_string_pseudo_op=no])
])
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
[Define if your assembler supports .string.])
fi
fi
if test x$TARGET = xX86_WIN64; then
LT_SYS_SYMBOL_USCORE
if test "x$sys_symbol_underscore" = xyes; then
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
fi
fi
FFI_EXEC_TRAMPOLINE_TABLE=0
case "$target" in
*arm*-apple-darwin*)
FFI_EXEC_TRAMPOLINE_TABLE=1
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
[Cannot use PROT_EXEC on this target, so, we revert to
alternative means])
;;
*-apple-darwin1[[10]]* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
[Cannot use malloc on this target, so, we revert to
alternative means])
;;
esac
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
if test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports unwind section type],
libffi_cv_as_x86_64_unwind_section_type, [
libffi_cv_as_x86_64_unwind_section_type=yes
echo '.section .eh_frame,"a",@unwind' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_64_unwind_section_type=no
fi
])
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
[Define if your assembler supports unwind section type.])
fi
fi
if test "x$GCC" = "xyes"; then
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
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)
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
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)
# These variables are only ever used when we cross-build to X86_WIN32.
# And we only support this with GCC, so...
if test x"$GCC" != x"no"; then
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)
fi
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 libffi.pc)
AC_OUTPUT

File diff suppressed because it is too large Load Diff

View File

@@ -1,80 +0,0 @@
## Process this file with automake to produce Makefile.in.
AUTOMAKE_OPTIONS = foreign dejagnu
# Setup the testing framework, if you have one
EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
echo $(top_builddir)/../expect/expect ; \
else echo expect ; fi`
RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
echo $(top_srcdir)/../dejagnu/runtest ; \
else echo runtest; fi`
AM_RUNTESTFLAGS =
CLEANFILES = *.exe core* *.log *.sum
EXTRA_DIST = libffi.special/special.exp \
libffi.special/unwindtest_ffi_call.cc libffi.special/unwindtest.cc \
libffi.special/ffitestcxx.h config/default.exp lib/target-libpath.exp \
lib/libffi.exp lib/wrapper.exp libffi.call/float.c \
libffi.call/cls_multi_schar.c libffi.call/float3.c \
libffi.call/cls_3_1byte.c libffi.call/stret_large2.c \
libffi.call/cls_5_1_byte.c libffi.call/stret_medium.c \
libffi.call/promotion.c libffi.call/cls_dbls_struct.c \
libffi.call/nested_struct.c libffi.call/closure_fn1.c \
libffi.call/cls_4_1byte.c libffi.call/cls_float.c \
libffi.call/cls_2byte.c libffi.call/closure_fn4.c \
libffi.call/return_fl2.c libffi.call/nested_struct7.c \
libffi.call/cls_uint.c libffi.call/cls_align_sint64.c \
libffi.call/float1.c libffi.call/cls_19byte.c \
libffi.call/nested_struct1.c libffi.call/cls_4byte.c \
libffi.call/return_fl1.c libffi.call/cls_align_pointer.c \
libffi.call/nested_struct4.c libffi.call/nested_struct3.c \
libffi.call/struct7.c libffi.call/nested_struct9.c \
libffi.call/cls_sshort.c libffi.call/cls_ulonglong.c \
libffi.call/cls_pointer_stack.c libffi.call/cls_multi_uchar.c \
libffi.call/testclosure.c libffi.call/cls_3byte1.c \
libffi.call/struct6.c libffi.call/return_uc.c libffi.call/return_ll1.c \
libffi.call/cls_ushort.c libffi.call/stret_medium2.c \
libffi.call/cls_multi_ushortchar.c libffi.call/return_dbl2.c \
libffi.call/closure_loc_fn0.c libffi.call/return_sc.c \
libffi.call/nested_struct8.c libffi.call/cls_7_1_byte.c \
libffi.call/return_ll.c libffi.call/cls_pointer.c \
libffi.call/err_bad_abi.c libffi.call/return_dbl1.c \
libffi.call/call.exp libffi.call/ffitest.h libffi.call/strlen.c \
libffi.call/return_sl.c libffi.call/cls_1_1byte.c \
libffi.call/struct1.c libffi.call/cls_64byte.c libffi.call/return_ul.c \
libffi.call/cls_double.c libffi.call/many_win32.c \
libffi.call/cls_16byte.c libffi.call/cls_align_double.c \
libffi.call/cls_align_uint16.c libffi.call/cls_9byte1.c \
libffi.call/cls_multi_sshortchar.c libffi.call/cls_multi_ushort.c \
libffi.call/closure_stdcall.c libffi.call/return_fl.c \
libffi.call/strlen_win32.c libffi.call/return_ldl.c \
libffi.call/cls_align_float.c libffi.call/struct3.c \
libffi.call/cls_uchar.c libffi.call/cls_sint.c libffi.call/float2.c \
libffi.call/cls_align_longdouble_split.c \
libffi.call/cls_longdouble_va.c libffi.call/cls_multi_sshort.c \
libffi.call/stret_large.c libffi.call/cls_align_sint16.c \
libffi.call/nested_struct6.c libffi.call/cls_5byte.c \
libffi.call/return_dbl.c libffi.call/cls_20byte.c \
libffi.call/cls_8byte.c libffi.call/pyobjc-tc.c \
libffi.call/cls_24byte.c libffi.call/cls_align_longdouble_split2.c \
libffi.call/cls_6_1_byte.c libffi.call/cls_schar.c \
libffi.call/cls_18byte.c libffi.call/closure_fn3.c \
libffi.call/err_bad_typedef.c libffi.call/closure_fn2.c \
libffi.call/struct2.c libffi.call/cls_3byte2.c \
libffi.call/cls_align_longdouble.c libffi.call/cls_20byte1.c \
libffi.call/return_fl3.c libffi.call/cls_align_uint32.c \
libffi.call/problem1.c libffi.call/float4.c \
libffi.call/cls_align_uint64.c libffi.call/struct9.c \
libffi.call/closure_fn5.c libffi.call/cls_align_sint32.c \
libffi.call/closure_fn0.c libffi.call/closure_fn6.c \
libffi.call/struct4.c libffi.call/nested_struct2.c \
libffi.call/cls_6byte.c libffi.call/cls_7byte.c libffi.call/many.c \
libffi.call/struct8.c libffi.call/negint.c libffi.call/struct5.c \
libffi.call/cls_12byte.c libffi.call/cls_double_va.c \
libffi.call/cls_longdouble.c libffi.call/cls_9byte2.c \
libffi.call/nested_struct10.c libffi.call/nested_struct5.c \
libffi.call/huge_struct.c

View File

@@ -1,535 +0,0 @@
# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@
am__make_dryrun = \
{ \
am__dry=no; \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
*) \
for am__flg in $$MAKEFLAGS; do \
case $$am__flg in \
*=*|--*) ;; \
*n*) am__dry=yes; break;; \
esac; \
done;; \
esac; \
test $$am__dry = yes; \
}
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 = testsuite
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
$(top_srcdir)/m4/ax_cflags_warn_all.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/m4/ax_configure_args.m4 \
$(top_srcdir)/m4/ax_enable_builddir.m4 \
$(top_srcdir)/m4/ax_gcc_archflag.m4 \
$(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
DEJATOOL = $(PACKAGE)
RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_LTLDFLAGS = @AM_LTLDFLAGS@
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@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
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@
MANIFEST_TOOL = @MANIFEST_TOOL@
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@
PRTDIAG = @PRTDIAG@
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_AR = @ac_ct_AR@
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@
ax_enable_builddir_sed = @ax_enable_builddir_sed@
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@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sys_symbol_underscore = @sys_symbol_underscore@
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 dejagnu
# Setup the testing framework, if you have one
EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
echo $(top_builddir)/../expect/expect ; \
else echo expect ; fi`
RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
echo $(top_srcdir)/../dejagnu/runtest ; \
else echo runtest; fi`
CLEANFILES = *.exe core* *.log *.sum
EXTRA_DIST = libffi.special/special.exp \
libffi.special/unwindtest_ffi_call.cc libffi.special/unwindtest.cc \
libffi.special/ffitestcxx.h config/default.exp lib/target-libpath.exp \
lib/libffi.exp lib/wrapper.exp libffi.call/float.c \
libffi.call/cls_multi_schar.c libffi.call/float3.c \
libffi.call/cls_3_1byte.c libffi.call/stret_large2.c \
libffi.call/cls_5_1_byte.c libffi.call/stret_medium.c \
libffi.call/promotion.c libffi.call/cls_dbls_struct.c \
libffi.call/nested_struct.c libffi.call/closure_fn1.c \
libffi.call/cls_4_1byte.c libffi.call/cls_float.c \
libffi.call/cls_2byte.c libffi.call/closure_fn4.c \
libffi.call/return_fl2.c libffi.call/nested_struct7.c \
libffi.call/cls_uint.c libffi.call/cls_align_sint64.c \
libffi.call/float1.c libffi.call/cls_19byte.c \
libffi.call/nested_struct1.c libffi.call/cls_4byte.c \
libffi.call/return_fl1.c libffi.call/cls_align_pointer.c \
libffi.call/nested_struct4.c libffi.call/nested_struct3.c \
libffi.call/struct7.c libffi.call/nested_struct9.c \
libffi.call/cls_sshort.c libffi.call/cls_ulonglong.c \
libffi.call/cls_pointer_stack.c libffi.call/cls_multi_uchar.c \
libffi.call/testclosure.c libffi.call/cls_3byte1.c \
libffi.call/struct6.c libffi.call/return_uc.c libffi.call/return_ll1.c \
libffi.call/cls_ushort.c libffi.call/stret_medium2.c \
libffi.call/cls_multi_ushortchar.c libffi.call/return_dbl2.c \
libffi.call/closure_loc_fn0.c libffi.call/return_sc.c \
libffi.call/nested_struct8.c libffi.call/cls_7_1_byte.c \
libffi.call/return_ll.c libffi.call/cls_pointer.c \
libffi.call/err_bad_abi.c libffi.call/return_dbl1.c \
libffi.call/call.exp libffi.call/ffitest.h libffi.call/strlen.c \
libffi.call/return_sl.c libffi.call/cls_1_1byte.c \
libffi.call/struct1.c libffi.call/cls_64byte.c libffi.call/return_ul.c \
libffi.call/cls_double.c libffi.call/many_win32.c \
libffi.call/cls_16byte.c libffi.call/cls_align_double.c \
libffi.call/cls_align_uint16.c libffi.call/cls_9byte1.c \
libffi.call/cls_multi_sshortchar.c libffi.call/cls_multi_ushort.c \
libffi.call/closure_stdcall.c libffi.call/return_fl.c \
libffi.call/strlen_win32.c libffi.call/return_ldl.c \
libffi.call/cls_align_float.c libffi.call/struct3.c \
libffi.call/cls_uchar.c libffi.call/cls_sint.c libffi.call/float2.c \
libffi.call/cls_align_longdouble_split.c \
libffi.call/cls_longdouble_va.c libffi.call/cls_multi_sshort.c \
libffi.call/stret_large.c libffi.call/cls_align_sint16.c \
libffi.call/nested_struct6.c libffi.call/cls_5byte.c \
libffi.call/return_dbl.c libffi.call/cls_20byte.c \
libffi.call/cls_8byte.c libffi.call/pyobjc-tc.c \
libffi.call/cls_24byte.c libffi.call/cls_align_longdouble_split2.c \
libffi.call/cls_6_1_byte.c libffi.call/cls_schar.c \
libffi.call/cls_18byte.c libffi.call/closure_fn3.c \
libffi.call/err_bad_typedef.c libffi.call/closure_fn2.c \
libffi.call/struct2.c libffi.call/cls_3byte2.c \
libffi.call/cls_align_longdouble.c libffi.call/cls_20byte1.c \
libffi.call/return_fl3.c libffi.call/cls_align_uint32.c \
libffi.call/problem1.c libffi.call/float4.c \
libffi.call/cls_align_uint64.c libffi.call/struct9.c \
libffi.call/closure_fn5.c libffi.call/cls_align_sint32.c \
libffi.call/closure_fn0.c libffi.call/closure_fn6.c \
libffi.call/struct4.c libffi.call/nested_struct2.c \
libffi.call/cls_6byte.c libffi.call/cls_7byte.c libffi.call/many.c \
libffi.call/struct8.c libffi.call/negint.c libffi.call/struct5.c \
libffi.call/cls_12byte.c libffi.call/cls_double_va.c \
libffi.call/cls_longdouble.c libffi.call/cls_9byte2.c \
libffi.call/nested_struct10.c libffi.call/nested_struct5.c \
libffi.call/huge_struct.c
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 testsuite/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign testsuite/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
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
check-DEJAGNU: site.exp
srcdir='$(srcdir)'; export srcdir; \
EXPECT=$(EXPECT); export EXPECT; \
runtest=$(RUNTEST); \
if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
then :; else exit_status=1; fi; \
done; \
else echo "WARNING: could not find \`runtest'" 1>&2; :;\
fi; \
exit $$exit_status
site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
@echo 'Making a new site.exp file...'
@echo '## these variables are automatically generated by make ##' >site.tmp
@echo '# Do not edit here. If you wish to override these values' >>site.tmp
@echo '# edit the last section' >>site.tmp
@echo 'set srcdir "$(srcdir)"' >>site.tmp
@echo "set objdir `pwd`" >>site.tmp
@echo 'set build_alias "$(build_alias)"' >>site.tmp
@echo 'set build_triplet $(build_triplet)' >>site.tmp
@echo 'set host_alias "$(host_alias)"' >>site.tmp
@echo 'set host_triplet $(host_triplet)' >>site.tmp
@echo 'set target_alias "$(target_alias)"' >>site.tmp
@echo 'set target_triplet $(target_triplet)' >>site.tmp
@list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
echo "## Begin content included from file $$f. Do not modify. ##" \
&& cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
&& echo "## End content included from file $$f. ##" \
|| exit 1; \
done >> site.tmp
@echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
@if test -f site.exp; then \
sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
fi
@-rm -f site.bak
@test ! -f site.exp || mv site.exp site.bak
@mv site.tmp site.exp
distclean-DEJAGNU:
-rm -f site.exp site.bak
-l='$(DEJATOOL)'; for tool in $$l; do \
rm -f $$tool.sum $$tool.log; \
done
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
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
check: check-am
all-am: Makefile
installdirs:
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:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
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-DEJAGNU distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
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:
.MAKE: check-am install-am install-strip
.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
clean-libtool distclean distclean-DEJAGNU 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-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
# 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:

File diff suppressed because it is too large Load Diff

View File

@@ -1,369 +0,0 @@
Status
======
libffi-3.0.12 was released on XXXXXXX. 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.
For specific configuration details and testing status, please
refer to the wiki page here:
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.11
At the time of release, the following basic configurations have been
tested:
|-----------------+------------------|
| Architecture | Operating System |
|-----------------+------------------|
| AArch64 | Linux |
| Alpha | Linux |
| Alpha | Tru64 |
| ARM | Linux |
| ARM | iOS |
| AVR32 | Linux |
| Blackfin | uClinux |
| HPPA | HPUX |
| IA-64 | Linux |
| M68K | FreeMiNT |
| M68K | RTEMS |
| MIPS | IRIX |
| MIPS | Linux |
| MIPS | RTEMS |
| MIPS64 | Linux |
| PowerPC | AMIGA |
| PowerPC | Linux |
| PowerPC | Mac OSX |
| PowerPC | FreeBSD |
| PowerPC64 | Linux |
| S390 | Linux |
| S390X | Linux |
| SPARC | Linux |
| SPARC | Solaris |
| SPARC64 | Linux |
| SPARC64 | FreeBSD |
| TILE-Gx/TILEPro | Linux |
| X86 | FreeBSD |
| X86 | Interix |
| X86 | kFreeBSD |
| X86 | Linux |
| X86 | Mac OSX |
| X86 | OpenBSD |
| X86 | OS/2 |
| X86 | Solaris |
| X86 | Windows/Cygwin |
| X86 | Windows/MingW |
| X86-64 | FreeBSD |
| X86-64 | Linux |
| X86-64 | Linux/x32 |
| X86-64 | OpenBSD |
| X86-64 | Windows/MingW |
|-----------------+------------------|
Please send additional platform test results to
libffi-discuss@sourceware.org and feel free to update the wiki page
above.
Installing libffi
=================
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.
It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
You may also need to specify --build appropriately. When building with MSVC
under a MingW environment, you may need to remove the line in configure
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.)
For iOS builds, the 'libffi.xcodeproj' Xcode project is available.
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".
History
=======
See the ChangeLog files for details.
3.0.12 XXX-XX-XX
Add Blackfin support.
Add TILE-Gx/TILEPro support.
Add AArch64 support.
3.0.11 Apr-11-12
Lots of build fixes.
Add Amiga newer MacOS support.
Add support for variadic functions (ffi_prep_cif_var).
Add Linux/x32 support.
Add thiscall, fastcall and MSVC cdecl support on Windows.
Add Amiga and newer MacOS support.
Add m68k FreeMiNT support.
Integration with iOS' xcode build tools.
Fix Octeon and MC68881 support.
Fix code pessimizations.
Lots of build fixes.
3.0.10 Aug-23-11
Add support for Apple's iOS.
Add support for ARM VFP ABI.
Add RTEMS support for MIPS and M68K.
Fix instruction cache clearing problems on
ARM and SPARC.
Fix the N64 build on mips-sgi-irix6.5.
Enable builds with Microsoft's compiler.
Enable x86 builds with Oracle's Solaris compiler.
Fix support for calling code compiled with Oracle's Sparc
Solaris compiler.
Testsuite fixes for Tru64 Unix.
Additional platform support.
3.0.9 Dec-31-09
Add AVR32 and win64 ports. Add ARM softfp support.
Many fixes for AIX, Solaris, HP-UX, *BSD.
Several PowerPC and x86-64 bug fixes.
Build DLL for windows.
3.0.8 Dec-19-08
Add *BSD, BeOS, and PA-Linux support.
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:
aarch64 Marcus Shawcroft, James Greenhalgh
alpha Richard Henderson
arm Raffaele Sena
blackfin Alexandre Keunecke I. de Mendonca
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
tile-gx/tilepro Walter Lee
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 the
author at green@moxielogic.com, or the project mailing list at
libffi-discuss@sourceware.org.

17404
.pc/emutramp/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,517 +0,0 @@
dnl Process this with autoconf to create configure
AC_PREREQ(2.68)
AC_INIT([libffi], [3.0.11], [http://github.com/atgreen/libffi/issues])
AC_CONFIG_HEADERS([fficonfig.h])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
AX_ENABLE_BUILDDIR
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.
# Also save and restore CFLAGS, since AC_PROG_CC will come up with
# defaults of its own if none are provided.
m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
m4_define([_AC_ARG_VAR_PRECIOUS],[])
save_CFLAGS=$CFLAGS
AC_PROG_CC
CFLAGS=$save_CFLAGS
m4_undefine([_AC_ARG_VAR_PRECIOUS])
m4_rename([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
AC_SUBST(CFLAGS)
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_CONFIG_MACRO_DIR([m4])
AX_CC_MAXOPT
AX_CFLAGS_WARN_ALL
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -fexceptions"
fi
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
aarch64*-*-*)
TARGET=AARCH64; TARGETDIR=aarch64
;;
alpha*-*-*)
TARGET=ALPHA; TARGETDIR=alpha;
# Support 128-bit long double, changeable via command-line switch.
HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
;;
arm*-*-*)
TARGET=ARM; TARGETDIR=arm
;;
amd64-*-freebsd* | amd64-*-openbsd*)
TARGET=X86_64; TARGETDIR=x86
;;
amd64-*-freebsd*)
TARGET=X86_64; TARGETDIR=x86
;;
avr32*-*-*)
TARGET=AVR32; TARGETDIR=avr32
;;
bfin*)
TARGET=BFIN; TARGETDIR=bfin
;;
cris-*-*)
TARGET=LIBFFI_CRIS; TARGETDIR=cris
;;
frv-*-*)
TARGET=FRV; TARGETDIR=frv
;;
hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
TARGET=PA64_HPUX; TARGETDIR=pa
;;
hppa*-*-hpux*)
TARGET=PA_HPUX; TARGETDIR=pa
;;
i?86-*-freebsd* | i?86-*-openbsd*)
TARGET=X86_FREEBSD; TARGETDIR=x86
;;
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*)
TARGET=X86_WIN32; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
i?86-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
i?86-*-solaris2.1[[0-9]]*)
TARGET=X86_64; TARGETDIR=x86
;;
i?86-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux* | mips*-*-openbsd*)
# Support 128-bit long double for NewABI.
HAVE_LONG_DOUBLE='defined(__mips64)'
TARGET=MIPS; TARGETDIR=mips
;;
moxie-*-*)
TARGET=MOXIE; TARGETDIR=moxie
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-amigaos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin* | powerpc64-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd* | powerpc-*-openbsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc64-*-freebsd*)
TARGET=POWERPC; 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
;;
tile*-*)
TARGET=TILE; TARGETDIR=tile
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
TARGET=X86_WIN64; TARGETDIR=x86
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
# We must also check with_cross_host to decide if this is a native
# or cross-build and select where to install dlls appropriately.
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';
else
AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';
fi
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac
AC_SUBST(AM_RUNTESTFLAGS)
AC_SUBST(AM_LTLDFLAGS)
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(BFIN, test x$TARGET = xBFIN)
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(MOXIE, test x$TARGET = xMOXIE)
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(AARCH64, test x$TARGET = xAARCH64)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
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)
AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
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
GCC_AS_CFI_PSEUDO_OP
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 | $EGREP -i 'illegal|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
AC_CACHE_CHECK([assembler .ascii pseudo-op support],
libffi_cv_as_ascii_pseudo_op, [
libffi_cv_as_ascii_pseudo_op=unknown
# Check if we have .ascii
AC_TRY_COMPILE([asm (".ascii \\"string\\"");],,
[libffi_cv_as_ascii_pseudo_op=yes],
[libffi_cv_as_ascii_pseudo_op=no])
])
if test "x$libffi_cv_as_ascii_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_ASCII_PSEUDO_OP, 1,
[Define if your assembler supports .ascii.])
fi
AC_CACHE_CHECK([assembler .string pseudo-op support],
libffi_cv_as_string_pseudo_op, [
libffi_cv_as_string_pseudo_op=unknown
# Check if we have .string
AC_TRY_COMPILE([asm (".string \\"string\\"");],,
[libffi_cv_as_string_pseudo_op=yes],
[libffi_cv_as_string_pseudo_op=no])
])
if test "x$libffi_cv_as_string_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_STRING_PSEUDO_OP, 1,
[Define if your assembler supports .string.])
fi
fi
if test x$TARGET = xX86_WIN64; then
LT_SYS_SYMBOL_USCORE
if test "x$sys_symbol_underscore" = xyes; then
AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])
fi
fi
FFI_EXEC_TRAMPOLINE_TABLE=0
case "$target" in
*arm*-apple-darwin*)
FFI_EXEC_TRAMPOLINE_TABLE=1
AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,
[Cannot use PROT_EXEC on this target, so, we revert to
alternative means])
;;
*-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
[Cannot use malloc on this target, so, we revert to
alternative means])
;;
esac
AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)
AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)
if test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports unwind section type],
libffi_cv_as_x86_64_unwind_section_type, [
libffi_cv_as_x86_64_unwind_section_type=yes
echo '.section .eh_frame,"a",@unwind' > conftest.s
if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then
libffi_cv_as_x86_64_unwind_section_type=no
fi
])
if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then
AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,
[Define if your assembler supports unwind section type.])
fi
fi
if test "x$GCC" = "xyes"; then
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
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)
AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
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)
# These variables are only ever used when we cross-build to X86_WIN32.
# And we only support this with GCC, so...
if test x"$GCC" != x"no"; then
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)
fi
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 libffi.pc)
AC_OUTPUT

View File

@@ -1,615 +0,0 @@
/* -----------------------------------------------------------------------
closures.c - Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
Copyright (c) 2011 Plausible Labs Cooperative, 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>
#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
# 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) || defined(__OS2__)
/* 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_EXEC_TRAMPOLINE_TABLE
// Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
# elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
#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__) || defined(__INTERIX)
#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(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
/* 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(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
#define mmap dlmmap
#define munmap dlmunmap
#include "dlmalloc.c"
#undef mmap
#undef munmap
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
/* 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)) == NULL)
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(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
/* 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

File diff suppressed because it is too large Load Diff

View File

@@ -1,637 +0,0 @@
/* -----------------------------------------------------------------------
ffi64.c - Copyright (c) 20011 Anthony Green
Copyright (c) 2008, 2010 Red Hat, Inc.
Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
x86-64 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>
#include <stdarg.h>
#ifdef __x86_64__
#define MAX_GPR_REGS 6
#define MAX_SSE_REGS 8
struct register_args
{
/* Registers for argument passing. */
UINT64 gpr[MAX_GPR_REGS];
__int128_t sse[MAX_SSE_REGS];
};
extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
void *raddr, void (*fnaddr)(void), unsigned ssecount);
/* All reference to register classes here is identical to the code in
gcc/config/i386/i386.c. Do *not* change one without the other. */
/* Register class used for passing given 64bit part of the argument.
These represent classes as documented by the PS ABI, with the
exception of SSESF, SSEDF classes, that are basically SSE class,
just gcc will use SF or DFmode move instead of DImode to avoid
reformatting penalties.
Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
whenever possible (upper half does contain padding). */
enum x86_64_reg_class
{
X86_64_NO_CLASS,
X86_64_INTEGER_CLASS,
X86_64_INTEGERSI_CLASS,
X86_64_SSE_CLASS,
X86_64_SSESF_CLASS,
X86_64_SSEDF_CLASS,
X86_64_SSEUP_CLASS,
X86_64_X87_CLASS,
X86_64_X87UP_CLASS,
X86_64_COMPLEX_X87_CLASS,
X86_64_MEMORY_CLASS
};
#define MAX_CLASSES 4
#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)
/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
of this code is to classify each 8bytes of incoming argument by the register
class and assign registers accordingly. */
/* Return the union class of CLASS1 and CLASS2.
See the x86-64 PS ABI for details. */
static enum x86_64_reg_class
merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
{
/* Rule #1: If both classes are equal, this is the resulting class. */
if (class1 == class2)
return class1;
/* Rule #2: If one of the classes is NO_CLASS, the resulting class is
the other class. */
if (class1 == X86_64_NO_CLASS)
return class2;
if (class2 == X86_64_NO_CLASS)
return class1;
/* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
return X86_64_MEMORY_CLASS;
/* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
|| (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
return X86_64_INTEGERSI_CLASS;
if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
|| class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
return X86_64_INTEGER_CLASS;
/* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
MEMORY is used. */
if (class1 == X86_64_X87_CLASS
|| class1 == X86_64_X87UP_CLASS
|| class1 == X86_64_COMPLEX_X87_CLASS
|| class2 == X86_64_X87_CLASS
|| class2 == X86_64_X87UP_CLASS
|| class2 == X86_64_COMPLEX_X87_CLASS)
return X86_64_MEMORY_CLASS;
/* Rule #6: Otherwise class SSE is used. */
return X86_64_SSE_CLASS;
}
/* Classify the argument of type TYPE and mode MODE.
CLASSES will be filled by the register class used to pass each word
of the operand. The number of words is returned. In case the parameter
should be passed in memory, 0 is returned. As a special case for zero
sized containers, classes[0] will be NO_CLASS and 1 is returned.
See the x86-64 PS ABI for details.
*/
static int
classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
size_t byte_offset)
{
switch (type->type)
{
case FFI_TYPE_UINT8:
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT16:
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64:
case FFI_TYPE_POINTER:
{
int size = byte_offset + type->size;
if (size <= 4)
{
classes[0] = X86_64_INTEGERSI_CLASS;
return 1;
}
else if (size <= 8)
{
classes[0] = X86_64_INTEGER_CLASS;
return 1;
}
else if (size <= 12)
{
classes[0] = X86_64_INTEGER_CLASS;
classes[1] = X86_64_INTEGERSI_CLASS;
return 2;
}
else if (size <= 16)
{
classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
return 2;
}
else
FFI_ASSERT (0);
}
case FFI_TYPE_FLOAT:
if (!(byte_offset % 8))
classes[0] = X86_64_SSESF_CLASS;
else
classes[0] = X86_64_SSE_CLASS;
return 1;
case FFI_TYPE_DOUBLE:
classes[0] = X86_64_SSEDF_CLASS;
return 1;
case FFI_TYPE_LONGDOUBLE:
classes[0] = X86_64_X87_CLASS;
classes[1] = X86_64_X87UP_CLASS;
return 2;
case FFI_TYPE_STRUCT:
{
const int UNITS_PER_WORD = 8;
int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
ffi_type **ptr;
int i;
enum x86_64_reg_class subclasses[MAX_CLASSES];
/* If the struct is larger than 32 bytes, pass it on the stack. */
if (type->size > 32)
return 0;
for (i = 0; i < words; i++)
classes[i] = X86_64_NO_CLASS;
/* Zero sized arrays or structures are NO_CLASS. We return 0 to
signalize memory class, so handle it as special case. */
if (!words)
{
classes[0] = X86_64_NO_CLASS;
return 1;
}
/* Merge the fields of structure. */
for (ptr = type->elements; *ptr != NULL; ptr++)
{
int num;
byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
num = classify_argument (*ptr, subclasses, byte_offset % 8);
if (num == 0)
return 0;
for (i = 0; i < num; i++)
{
int pos = byte_offset / 8;
classes[i + pos] =
merge_classes (subclasses[i], classes[i + pos]);
}
byte_offset += (*ptr)->size;
}
if (words > 2)
{
/* When size > 16 bytes, if the first one isn't
X86_64_SSE_CLASS or any other ones aren't
X86_64_SSEUP_CLASS, everything should be passed in
memory. */
if (classes[0] != X86_64_SSE_CLASS)
return 0;
for (i = 1; i < words; i++)
if (classes[i] != X86_64_SSEUP_CLASS)
return 0;
}
/* Final merger cleanup. */
for (i = 0; i < words; i++)
{
/* If one class is MEMORY, everything should be passed in
memory. */
if (classes[i] == X86_64_MEMORY_CLASS)
return 0;
/* The X86_64_SSEUP_CLASS should be always preceded by
X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
if (classes[i] == X86_64_SSEUP_CLASS
&& classes[i - 1] != X86_64_SSE_CLASS
&& classes[i - 1] != X86_64_SSEUP_CLASS)
{
/* The first one should never be X86_64_SSEUP_CLASS. */
FFI_ASSERT (i != 0);
classes[i] = X86_64_SSE_CLASS;
}
/* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
everything should be passed in memory. */
if (classes[i] == X86_64_X87UP_CLASS
&& (classes[i - 1] != X86_64_X87_CLASS))
{
/* The first one should never be X86_64_X87UP_CLASS. */
FFI_ASSERT (i != 0);
return 0;
}
}
return words;
}
default:
FFI_ASSERT(0);
}
return 0; /* Never reached. */
}
/* Examine the argument and return set number of register required in each
class. Return zero iff parameter should be passed in memory, otherwise
the number of registers. */
static int
examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
_Bool in_return, int *pngpr, int *pnsse)
{
int i, n, ngpr, nsse;
n = classify_argument (type, classes, 0);
if (n == 0)
return 0;
ngpr = nsse = 0;
for (i = 0; i < n; ++i)
switch (classes[i])
{
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
ngpr++;
break;
case X86_64_SSE_CLASS:
case X86_64_SSESF_CLASS:
case X86_64_SSEDF_CLASS:
nsse++;
break;
case X86_64_NO_CLASS:
case X86_64_SSEUP_CLASS:
break;
case X86_64_X87_CLASS:
case X86_64_X87UP_CLASS:
case X86_64_COMPLEX_X87_CLASS:
return in_return != 0;
default:
abort ();
}
*pngpr = ngpr;
*pnsse = nsse;
return n;
}
/* Perform machine dependent cif processing. */
ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{
int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
enum x86_64_reg_class classes[MAX_CLASSES];
size_t bytes;
gprcount = ssecount = 0;
flags = cif->rtype->type;
if (flags != FFI_TYPE_VOID)
{
n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
if (n == 0)
{
/* The return value is passed in memory. A pointer to that
memory is the first argument. Allocate a register for it. */
gprcount++;
/* We don't have to do anything in asm for the return. */
flags = FFI_TYPE_VOID;
}
else if (flags == FFI_TYPE_STRUCT)
{
/* Mark which registers the result appears in. */
_Bool sse0 = SSE_CLASS_P (classes[0]);
_Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
if (sse0 && !sse1)
flags |= 1 << 8;
else if (!sse0 && sse1)
flags |= 1 << 9;
else if (sse0 && sse1)
flags |= 1 << 10;
/* Mark the true size of the structure. */
flags |= cif->rtype->size << 12;
}
}
/* Go over all arguments and determine the way they should be passed.
If it's in a register and there is space for it, let that be so. If
not, add it's size to the stack byte count. */
for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)
{
if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0
|| gprcount + ngpr > MAX_GPR_REGS
|| ssecount + nsse > MAX_SSE_REGS)
{
long align = cif->arg_types[i]->alignment;
if (align < 8)
align = 8;
bytes = ALIGN (bytes, align);
bytes += cif->arg_types[i]->size;
}
else
{
gprcount += ngpr;
ssecount += nsse;
}
}
if (ssecount)
flags |= 1 << 11;
cif->flags = flags;
cif->bytes = ALIGN (bytes, 8);
return FFI_OK;
}
void
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
enum x86_64_reg_class classes[MAX_CLASSES];
char *stack, *argp;
ffi_type **arg_types;
int gprcount, ssecount, ngpr, nsse, i, avn;
_Bool ret_in_memory;
struct register_args *reg_args;
/* Can't call 32-bit mode from 64-bit mode. */
FFI_ASSERT (cif->abi == FFI_UNIX64);
/* If the return value is a struct and we don't have a return value
address then we need to make one. Note the setting of flags to
VOID above in ffi_prep_cif_machdep. */
ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
&& (cif->flags & 0xff) == FFI_TYPE_VOID);
if (rvalue == NULL && ret_in_memory)
rvalue = alloca (cif->rtype->size);
/* Allocate the space for the arguments, plus 4 words of temp space. */
stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
reg_args = (struct register_args *) stack;
argp = stack + sizeof (struct register_args);
gprcount = ssecount = 0;
/* If the return value is passed in memory, add the pointer as the
first integer argument. */
if (ret_in_memory)
reg_args->gpr[gprcount++] = (unsigned long) rvalue;
avn = cif->nargs;
arg_types = cif->arg_types;
for (i = 0; i < avn; ++i)
{
size_t size = arg_types[i]->size;
int n;
n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
if (n == 0
|| gprcount + ngpr > MAX_GPR_REGS
|| ssecount + nsse > MAX_SSE_REGS)
{
long align = arg_types[i]->alignment;
/* Stack arguments are *always* at least 8 byte aligned. */
if (align < 8)
align = 8;
/* Pass this argument in memory. */
argp = (void *) ALIGN (argp, align);
memcpy (argp, avalue[i], size);
argp += size;
}
else
{
/* The argument is passed entirely in registers. */
char *a = (char *) avalue[i];
int j;
for (j = 0; j < n; j++, a += 8, size -= 8)
{
switch (classes[j])
{
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
reg_args->gpr[gprcount] = 0;
memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
gprcount++;
break;
case X86_64_SSE_CLASS:
case X86_64_SSEDF_CLASS:
reg_args->sse[ssecount++] = *(UINT64 *) a;
break;
case X86_64_SSESF_CLASS:
reg_args->sse[ssecount++] = *(UINT32 *) a;
break;
default:
abort();
}
}
}
}
ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
cif->flags, rvalue, fn, ssecount);
}
extern void ffi_closure_unix64(void);
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data,
void *codeloc)
{
volatile unsigned short *tramp;
/* Sanity check on the cif ABI. */
{
int abi = cif->abi;
if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
return FFI_BAD_ABI;
}
tramp = (volatile unsigned short *) &closure->tramp[0];
tramp[0] = 0xbb49; /* mov <code>, %r11 */
*((unsigned long long * volatile) &tramp[1])
= (unsigned long) ffi_closure_unix64;
tramp[5] = 0xba49; /* mov <data>, %r10 */
*((unsigned long long * volatile) &tramp[6])
= (unsigned long) codeloc;
/* Set the carry bit iff the function uses any sse registers.
This is clc or stc, together with the first byte of the jmp. */
tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
tramp[11] = 0xe3ff; /* jmp *%r11 */
closure->cif = cif;
closure->fun = fun;
closure->user_data = user_data;
return FFI_OK;
}
int
ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
struct register_args *reg_args, char *argp)
{
ffi_cif *cif;
void **avalue;
ffi_type **arg_types;
long i, avn;
int gprcount, ssecount, ngpr, nsse;
int ret;
cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *));
gprcount = ssecount = 0;
ret = cif->rtype->type;
if (ret != FFI_TYPE_VOID)
{
enum x86_64_reg_class classes[MAX_CLASSES];
int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
if (n == 0)
{
/* The return value goes in memory. Arrange for the closure
return value to go directly back to the original caller. */
rvalue = (void *) (unsigned long) reg_args->gpr[gprcount++];
/* We don't have to do anything in asm for the return. */
ret = FFI_TYPE_VOID;
}
else if (ret == FFI_TYPE_STRUCT && n == 2)
{
/* Mark which register the second word of the structure goes in. */
_Bool sse0 = SSE_CLASS_P (classes[0]);
_Bool sse1 = SSE_CLASS_P (classes[1]);
if (!sse0 && sse1)
ret |= 1 << 8;
else if (sse0 && !sse1)
ret |= 1 << 9;
}
}
avn = cif->nargs;
arg_types = cif->arg_types;
for (i = 0; i < avn; ++i)
{
enum x86_64_reg_class classes[MAX_CLASSES];
int n;
n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
if (n == 0
|| gprcount + ngpr > MAX_GPR_REGS
|| ssecount + nsse > MAX_SSE_REGS)
{
long align = arg_types[i]->alignment;
/* Stack arguments are *always* at least 8 byte aligned. */
if (align < 8)
align = 8;
/* Pass this argument in memory. */
argp = (void *) ALIGN (argp, align);
avalue[i] = argp;
argp += arg_types[i]->size;
}
/* If the argument is in a single register, or two consecutive
integer registers, then we can use that address directly. */
else if (n == 1
|| (n == 2 && !(SSE_CLASS_P (classes[0])
|| SSE_CLASS_P (classes[1]))))
{
/* The argument is in a single register. */
if (SSE_CLASS_P (classes[0]))
{
avalue[i] = &reg_args->sse[ssecount];
ssecount += n;
}
else
{
avalue[i] = &reg_args->gpr[gprcount];
gprcount += n;
}
}
/* Otherwise, allocate space to make them consecutive. */
else
{
char *a = alloca (16);
int j;
avalue[i] = a;
for (j = 0; j < n; j++, a += 8)
{
if (SSE_CLASS_P (classes[j]))
memcpy (a, &reg_args->sse[ssecount++], 8);
else
memcpy (a, &reg_args->gpr[gprcount++], 8);
}
}
}
/* Invoke the closure. */
closure->fun (cif, rvalue, avalue, closure->user_data);
/* Tell assembly how to perform return type promotions. */
return ret;
}
#endif /* __x86_64__ */

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,363 +0,0 @@
Status
======
libffi-3.0.12 was released on XXXXXXX. 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.
For specific configuration details and testing status, please
refer to the wiki page here:
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.11
At the time of release, the following basic configurations have been
tested:
|--------------+------------------|
| Architecture | Operating System |
|--------------+------------------|
| Alpha | Linux |
| Alpha | Tru64 |
| ARM | Linux |
| ARM | iOS |
| AVR32 | Linux |
| Blackfin | uClinux |
| HPPA | HPUX |
| IA-64 | Linux |
| M68K | FreeMiNT |
| M68K | RTEMS |
| MIPS | IRIX |
| MIPS | Linux |
| MIPS | RTEMS |
| MIPS64 | Linux |
| PowerPC | AMIGA |
| PowerPC | Linux |
| PowerPC | Mac OSX |
| PowerPC | FreeBSD |
| PowerPC64 | Linux |
| S390 | Linux |
| S390X | Linux |
| SPARC | Linux |
| SPARC | Solaris |
| SPARC64 | Linux |
| SPARC64 | FreeBSD |
| X86 | FreeBSD |
| X86 | Interix |
| X86 | kFreeBSD |
| X86 | Linux |
| X86 | Mac OSX |
| X86 | OpenBSD |
| X86 | OS/2 |
| X86 | Solaris |
| X86 | Windows/Cygwin |
| X86 | Windows/MingW |
| X86-64 | FreeBSD |
| X86-64 | Linux |
| X86-64 | Linux/x32 |
| X86-64 | OpenBSD |
| X86-64 | Windows/MingW |
|--------------+------------------|
Please send additional platform test results to
libffi-discuss@sourceware.org and feel free to update the wiki page
above.
Installing libffi
=================
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.
It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
You may also need to specify --build appropriately. When building with MSVC
under a MingW environment, you may need to remove the line in configure
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.)
For iOS builds, run generate-ios-source-and-headers.py and then
libffi.xcodeproj should work.
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".
History
=======
See the ChangeLog files for details.
3.0.12 XXX-XX-XX
Add Blackfin support.
3.0.11 Apr-11-12
Lots of build fixes.
Add Amiga newer MacOS support.
Add support for variadic functions (ffi_prep_cif_var).
Add Linux/x32 support.
Add thiscall, fastcall and MSVC cdecl support on Windows.
Add Amiga and newer MacOS support.
Add m68k FreeMiNT support.
Integration with iOS' xcode build tools.
Fix Octeon and MC68881 support.
Fix code pessimizations.
Lots of build fixes.
3.0.10 Aug-23-11
Add support for Apple's iOS.
Add support for ARM VFP ABI.
Add RTEMS support for MIPS and M68K.
Fix instruction cache clearing problems on
ARM and SPARC.
Fix the N64 build on mips-sgi-irix6.5.
Enable builds with Microsoft's compiler.
Enable x86 builds with Oracle's Solaris compiler.
Fix support for calling code compiled with Oracle's Sparc
Solaris compiler.
Testsuite fixes for Tru64 Unix.
Additional platform support.
3.0.9 Dec-31-09
Add AVR32 and win64 ports. Add ARM softfp support.
Many fixes for AIX, Solaris, HP-UX, *BSD.
Several PowerPC and x86-64 bug fixes.
Build DLL for windows.
3.0.8 Dec-19-08
Add *BSD, BeOS, and PA-Linux support.
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 the
author at green@moxielogic.com, or the project mailing list at
libffi-discuss@sourceware.org.

View File

@@ -1,595 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
6C43CBDC1534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBD1534F76F00162364 /* ffi.c */; };
6C43CBDD1534F76F00162364 /* sysv.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBF1534F76F00162364 /* sysv.S */; };
6C43CBDE1534F76F00162364 /* trampoline.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC01534F76F00162364 /* trampoline.S */; };
6C43CBE61534F76F00162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC91534F76F00162364 /* darwin.S */; };
6C43CBE81534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBCB1534F76F00162364 /* ffi.c */; };
6C43CBE91534F76F00162364 /* ffi64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBCC1534F76F00162364 /* ffi64.c */; };
6C43CC1F1534F77800162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC051534F77800162364 /* darwin.S */; };
6C43CC201534F77800162364 /* darwin64.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC061534F77800162364 /* darwin64.S */; };
6C43CC211534F77800162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC071534F77800162364 /* ffi.c */; };
6C43CC221534F77800162364 /* ffi64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC081534F77800162364 /* ffi64.c */; };
6C43CC2F1534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; };
6C43CC301534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; };
6C43CC311534F7BE00162364 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC291534F7BE00162364 /* debug.c */; };
6C43CC321534F7BE00162364 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC291534F7BE00162364 /* debug.c */; };
6C43CC331534F7BE00162364 /* dlmalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2A1534F7BE00162364 /* dlmalloc.c */; };
6C43CC341534F7BE00162364 /* dlmalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2A1534F7BE00162364 /* dlmalloc.c */; };
6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; };
6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; };
6C43CC371534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; };
6C43CC381534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; };
6C43CC391534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; };
6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; };
6C43CC3B1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; };
6C43CC3C1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; };
6C43CC971535032600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8D1535032600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CC981535032600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8E1535032600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CC991535032600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8F1535032600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC901535032600162364 /* ffi_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CC9B1535032600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC911535032600162364 /* fficonfig.h */; };
6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC921535032600162364 /* fficonfig_i386.h */; };
6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC931535032600162364 /* fficonfig_x86_64.h */; };
6C43CC9E1535032600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC941535032600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC951535032600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC961535032600162364 /* ffitarget_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCAD1535039600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA21535039600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA31535039600162364 /* ffi_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCAF1535039600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA41535039600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCB01535039600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA51535039600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCB11535039600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA61535039600162364 /* fficonfig.h */; };
6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA71535039600162364 /* fficonfig_armv7.h */; };
6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA81535039600162364 /* fficonfig_i386.h */; };
6C43CCB41535039600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA91535039600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAA1535039600162364 /* ffitarget_arm.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAB1535039600162364 /* ffitarget_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; };
6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAC1535039600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
6C43CB3D1534E9D100162364 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
6C43CBBD1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = "<group>"; };
6C43CBBF1534F76F00162364 /* sysv.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv.S; sourceTree = "<group>"; };
6C43CBC01534F76F00162364 /* trampoline.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline.S; sourceTree = "<group>"; };
6C43CBC91534F76F00162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = "<group>"; };
6C43CBCB1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = "<group>"; };
6C43CBCC1534F76F00162364 /* ffi64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64.c; sourceTree = "<group>"; };
6C43CC051534F77800162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = "<group>"; };
6C43CC061534F77800162364 /* darwin64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64.S; sourceTree = "<group>"; };
6C43CC071534F77800162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = "<group>"; };
6C43CC081534F77800162364 /* ffi64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64.c; sourceTree = "<group>"; };
6C43CC281534F7BE00162364 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = closures.c; path = src/closures.c; sourceTree = SOURCE_ROOT; };
6C43CC291534F7BE00162364 /* debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debug.c; path = src/debug.c; sourceTree = SOURCE_ROOT; };
6C43CC2A1534F7BE00162364 /* dlmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dlmalloc.c; path = src/dlmalloc.c; sourceTree = SOURCE_ROOT; };
6C43CC2B1534F7BE00162364 /* java_raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = java_raw_api.c; path = src/java_raw_api.c; sourceTree = SOURCE_ROOT; };
6C43CC2C1534F7BE00162364 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prep_cif.c; path = src/prep_cif.c; sourceTree = SOURCE_ROOT; };
6C43CC2D1534F7BE00162364 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raw_api.c; path = src/raw_api.c; sourceTree = SOURCE_ROOT; };
6C43CC2E1534F7BE00162364 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = types.c; path = src/types.c; sourceTree = SOURCE_ROOT; };
6C43CC8D1535032600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
6C43CC8E1535032600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = "<group>"; };
6C43CC8F1535032600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
6C43CC901535032600162364 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = "<group>"; };
6C43CC911535032600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = "<group>"; };
6C43CC921535032600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
6C43CC931535032600162364 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = "<group>"; };
6C43CC941535032600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = "<group>"; };
6C43CC951535032600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
6C43CC961535032600162364 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
6C43CCA21535039600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
6C43CCA31535039600162364 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = "<group>"; };
6C43CCA41535039600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = "<group>"; };
6C43CCA51535039600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
6C43CCA61535039600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = "<group>"; };
6C43CCA71535039600162364 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = "<group>"; };
6C43CCA81535039600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
6C43CCA91535039600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = "<group>"; };
6C43CCAA1535039600162364 /* ffitarget_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm.h; sourceTree = "<group>"; };
6C43CCAB1535039600162364 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = "<group>"; };
6C43CCAC1535039600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
F6F980BA147386130008F121 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6C43CB3A1534E9D100162364 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F6F980B7147386130008F121 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
6C43CBAF1534F76F00162364 /* iOS */ = {
isa = PBXGroup;
children = (
6C43CCA11535039600162364 /* include */,
6C43CBBB1534F76F00162364 /* src */,
);
name = iOS;
path = ios;
sourceTree = "<group>";
};
6C43CBBB1534F76F00162364 /* src */ = {
isa = PBXGroup;
children = (
6C43CBC81534F76F00162364 /* x86 */,
6C43CBBC1534F76F00162364 /* arm */,
);
path = src;
sourceTree = "<group>";
};
6C43CBBC1534F76F00162364 /* arm */ = {
isa = PBXGroup;
children = (
6C43CBBD1534F76F00162364 /* ffi.c */,
6C43CBBF1534F76F00162364 /* sysv.S */,
6C43CBC01534F76F00162364 /* trampoline.S */,
);
path = arm;
sourceTree = "<group>";
};
6C43CBC81534F76F00162364 /* x86 */ = {
isa = PBXGroup;
children = (
6C43CBC91534F76F00162364 /* darwin.S */,
6C43CBCB1534F76F00162364 /* ffi.c */,
6C43CBCC1534F76F00162364 /* ffi64.c */,
);
path = x86;
sourceTree = "<group>";
};
6C43CBF01534F77800162364 /* OS X */ = {
isa = PBXGroup;
children = (
6C43CC8C1535032600162364 /* include */,
6C43CBFC1534F77800162364 /* src */,
);
name = "OS X";
path = osx;
sourceTree = "<group>";
};
6C43CBFC1534F77800162364 /* src */ = {
isa = PBXGroup;
children = (
6C43CC041534F77800162364 /* x86 */,
);
path = src;
sourceTree = "<group>";
};
6C43CC041534F77800162364 /* x86 */ = {
isa = PBXGroup;
children = (
6C43CC051534F77800162364 /* darwin.S */,
6C43CC061534F77800162364 /* darwin64.S */,
6C43CC071534F77800162364 /* ffi.c */,
6C43CC081534F77800162364 /* ffi64.c */,
);
path = x86;
sourceTree = "<group>";
};
6C43CC3D1534F7C400162364 /* src */ = {
isa = PBXGroup;
children = (
6C43CC281534F7BE00162364 /* closures.c */,
6C43CC291534F7BE00162364 /* debug.c */,
6C43CC2A1534F7BE00162364 /* dlmalloc.c */,
6C43CC2B1534F7BE00162364 /* java_raw_api.c */,
6C43CC2C1534F7BE00162364 /* prep_cif.c */,
6C43CC2D1534F7BE00162364 /* raw_api.c */,
6C43CC2E1534F7BE00162364 /* types.c */,
);
name = src;
path = ios;
sourceTree = "<group>";
};
6C43CC8C1535032600162364 /* include */ = {
isa = PBXGroup;
children = (
6C43CC8D1535032600162364 /* ffi.h */,
6C43CC8E1535032600162364 /* ffi_common.h */,
6C43CC8F1535032600162364 /* ffi_i386.h */,
6C43CC901535032600162364 /* ffi_x86_64.h */,
6C43CC911535032600162364 /* fficonfig.h */,
6C43CC921535032600162364 /* fficonfig_i386.h */,
6C43CC931535032600162364 /* fficonfig_x86_64.h */,
6C43CC941535032600162364 /* ffitarget.h */,
6C43CC951535032600162364 /* ffitarget_i386.h */,
6C43CC961535032600162364 /* ffitarget_x86_64.h */,
);
path = include;
sourceTree = "<group>";
};
6C43CCA11535039600162364 /* include */ = {
isa = PBXGroup;
children = (
6C43CCA21535039600162364 /* ffi.h */,
6C43CCA31535039600162364 /* ffi_armv7.h */,
6C43CCA41535039600162364 /* ffi_common.h */,
6C43CCA51535039600162364 /* ffi_i386.h */,
6C43CCA61535039600162364 /* fficonfig.h */,
6C43CCA71535039600162364 /* fficonfig_armv7.h */,
6C43CCA81535039600162364 /* fficonfig_i386.h */,
6C43CCA91535039600162364 /* ffitarget.h */,
6C43CCAA1535039600162364 /* ffitarget_arm.h */,
6C43CCAB1535039600162364 /* ffitarget_armv7.h */,
6C43CCAC1535039600162364 /* ffitarget_i386.h */,
);
path = include;
sourceTree = "<group>";
};
F6B0839514721EE50031D8A1 = {
isa = PBXGroup;
children = (
6C43CC3D1534F7C400162364 /* src */,
6C43CBAF1534F76F00162364 /* iOS */,
6C43CBF01534F77800162364 /* OS X */,
F6F980C6147386260008F121 /* Products */,
);
sourceTree = "<group>";
};
F6F980C6147386260008F121 /* Products */ = {
isa = PBXGroup;
children = (
F6F980BA147386130008F121 /* libffi.a */,
6C43CB3D1534E9D100162364 /* libffi.a */,
);
name = Products;
path = ../..;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
6C43CB3B1534E9D100162364 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
6C43CC971535032600162364 /* ffi.h in Headers */,
6C43CC981535032600162364 /* ffi_common.h in Headers */,
6C43CC991535032600162364 /* ffi_i386.h in Headers */,
6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */,
6C43CC9E1535032600162364 /* ffitarget.h in Headers */,
6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */,
6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */,
6C43CC9B1535032600162364 /* fficonfig.h in Headers */,
6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */,
6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F6F980B8147386130008F121 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
6C43CCAD1535039600162364 /* ffi.h in Headers */,
6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */,
6C43CCAF1535039600162364 /* ffi_common.h in Headers */,
6C43CCB01535039600162364 /* ffi_i386.h in Headers */,
6C43CCB41535039600162364 /* ffitarget.h in Headers */,
6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */,
6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */,
6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */,
6C43CCB11535039600162364 /* fficonfig.h in Headers */,
6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */,
6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
6C43CB3C1534E9D100162364 /* libffi OS X */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */;
buildPhases = (
6C43CC401534FF3B00162364 /* Generate Source and Headers */,
6C43CB391534E9D100162364 /* Sources */,
6C43CB3A1534E9D100162364 /* Frameworks */,
6C43CB3B1534E9D100162364 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = "libffi OS X";
productName = "ffi OS X";
productReference = 6C43CB3D1534E9D100162364 /* libffi.a */;
productType = "com.apple.product-type.library.static";
};
F6F980B9147386130008F121 /* libffi iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */;
buildPhases = (
6C43CC3E1534F8E200162364 /* Generate Trampoline */,
6C43CC3F1534FF1B00162364 /* Generate Source and Headers */,
F6F980B6147386130008F121 /* Sources */,
F6F980B7147386130008F121 /* Frameworks */,
F6F980B8147386130008F121 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = "libffi iOS";
productName = ffi;
productReference = F6F980BA147386130008F121 /* libffi.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
F6B0839714721EE50031D8A1 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0430;
};
buildConfigurationList = F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = F6B0839514721EE50031D8A1;
productRefGroup = F6B0839514721EE50031D8A1;
projectDirPath = "";
projectRoot = "";
targets = (
F6F980B9147386130008F121 /* libffi iOS */,
6C43CB3C1534E9D100162364 /* libffi OS X */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
6C43CC3E1534F8E200162364 /* Generate Trampoline */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Generate Trampoline";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /usr/bin/python;
shellScript = "import subprocess\nimport re\nimport os\nimport errno\nimport sys\n\ndef main():\n with open('src/arm/trampoline.S', 'w') as tramp_out:\n p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)\n p.wait()\n\nif __name__ == '__main__':\n main()";
};
6C43CC3F1534FF1B00162364 /* Generate Source and Headers */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Generate Source and Headers";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/bin/python generate-ios-source-and-headers.py";
};
6C43CC401534FF3B00162364 /* Generate Source and Headers */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Generate Source and Headers";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/bin/python generate-osx-source-and-headers.py";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
6C43CB391534E9D100162364 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6C43CC1F1534F77800162364 /* darwin.S in Sources */,
6C43CC201534F77800162364 /* darwin64.S in Sources */,
6C43CC211534F77800162364 /* ffi.c in Sources */,
6C43CC221534F77800162364 /* ffi64.c in Sources */,
6C43CC301534F7BE00162364 /* closures.c in Sources */,
6C43CC321534F7BE00162364 /* debug.c in Sources */,
6C43CC341534F7BE00162364 /* dlmalloc.c in Sources */,
6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */,
6C43CC381534F7BE00162364 /* prep_cif.c in Sources */,
6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */,
6C43CC3C1534F7BE00162364 /* types.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F6F980B6147386130008F121 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6C43CBDC1534F76F00162364 /* ffi.c in Sources */,
6C43CBDD1534F76F00162364 /* sysv.S in Sources */,
6C43CBDE1534F76F00162364 /* trampoline.S in Sources */,
6C43CBE61534F76F00162364 /* darwin.S in Sources */,
6C43CBE81534F76F00162364 /* ffi.c in Sources */,
6C43CBE91534F76F00162364 /* ffi64.c in Sources */,
6C43CC2F1534F7BE00162364 /* closures.c in Sources */,
6C43CC311534F7BE00162364 /* debug.c in Sources */,
6C43CC331534F7BE00162364 /* dlmalloc.c in Sources */,
6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */,
6C43CC371534F7BE00162364 /* prep_cif.c in Sources */,
6C43CC391534F7BE00162364 /* raw_api.c in Sources */,
6C43CC3B1534F7BE00162364 /* types.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
6C43CB4B1534E9D100162364 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
DSTROOT = /tmp/ffi.dst;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
);
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = ffi;
SDKROOT = macosx;
};
name = Debug;
};
6C43CB4C1534E9D100162364 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DSTROOT = /tmp/ffi.dst;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
);
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
MACOSX_DEPLOYMENT_TARGET = 10.6;
PRODUCT_NAME = ffi;
SDKROOT = macosx;
};
name = Release;
};
F6B083AB14721EE50031D8A1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VALUE = NO;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ios/include;
SDKROOT = iphoneos;
};
name = Debug;
};
F6B083AC14721EE50031D8A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PREPROCESSOR_DEFINITIONS = "";
GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VALUE = NO;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = ios/include;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
F6F980C2147386130008F121 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
armv6,
armv7,
);
DSTROOT = /tmp/ffi.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_THUMB_SUPPORT = NO;
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = ffi;
SKIP_INSTALL = YES;
};
name = Debug;
};
F6F980C3147386130008F121 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
armv6,
armv7,
);
DSTROOT = /tmp/ffi.dst;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_THUMB_SUPPORT = NO;
IPHONEOS_DEPLOYMENT_TARGET = 4.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = ffi;
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */ = {
isa = XCConfigurationList;
buildConfigurations = (
6C43CB4B1534E9D100162364 /* Debug */,
6C43CB4C1534E9D100162364 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6B083AB14721EE50031D8A1 /* Debug */,
F6B083AC14721EE50031D8A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F6F980C2147386130008F121 /* Debug */,
F6F980C3147386130008F121 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = F6B0839714721EE50031D8A1 /* Project object */;
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,355 +0,0 @@
Status
======
libffi-3.0.12 was released on *****************. 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.
For specific configuration details and testing status, please
refer to the wiki page here:
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.11
At the time of release, the following basic configurations have been
tested:
|--------------+------------------|
| Architecture | Operating System |
|--------------+------------------|
| Alpha | Linux |
| Alpha | Tru64 |
| ARM | Linux |
| ARM | iOS |
| AVR32 | Linux |
| HPPA | HPUX |
| IA-64 | Linux |
| M68K | RTEMS |
| MIPS | IRIX |
| MIPS | Linux |
| MIPS | RTEMS |
| MIPS64 | Linux |
| PowerPC | AMIGA |
| PowerPC | Linux |
| PowerPC | Mac OSX |
| PowerPC | FreeBSD |
| PowerPC64 | Linux |
| S390 | Linux |
| S390X | Linux |
| SPARC | Linux |
| SPARC | Solaris |
| SPARC64 | Linux |
| SPARC64 | FreeBSD |
| X86 | FreeBSD |
| X86 | Interix |
| X86 | kFreeBSD |
| X86 | Linux |
| X86 | Linux/x32 |
| X86 | Mac OSX |
| X86 | OpenBSD |
| X86 | OS/2 |
| X86 | Solaris |
| X86 | Windows/Cygwin |
| X86 | Windows/MingW |
| X86-64 | FreeBSD |
| X86-64 | Linux |
| X86-64 | OpenBSD |
| X86-64 | Windows/MingW |
|--------------+------------------|
Please send additional platform test results to
libffi-discuss@sourceware.org and feel free to update the wiki page
above.
Installing libffi
=================
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.
It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\"
For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64".
You may also need to specify --build appropriately. When building with MSVC
under a MingW environment, you may need to remove the line in configure
that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not
present in MingW, and is not required when using MingW-style paths.)
For iOS builds, refer to the build-ios.sh script for guidance.
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".
History
=======
See the ChangeLog files for details.
3.0.11 MMM-DD-YY
Lots of build fixes.
Add Amiga newer MacOS support.
Add support for variadic functions (ffi_prep_cif_var).
Add Linux/x32 support.
Add thiscall, fastcall and MSVC cdecl support on Windows.
Add Amiga and newer MacOS support.
Fix Octeon and MC68881 support.
Fix code pessimizations.
Lots of build fixes.
3.0.10 Aug-23-11
Add support for Apple's iOS.
Add support for ARM VFP ABI.
Add RTEMS support for MIPS and M68K.
Fix instruction cache clearing problems on
ARM and SPARC.
Fix the N64 build on mips-sgi-irix6.5.
Enable builds with Microsoft's compiler.
Enable x86 builds with Oracle's Solaris compiler.
Fix support for calling code compiled with Oracle's Sparc
Solaris compiler.
Testsuite fixes for Tru64 Unix.
Additional platform support.
3.0.9 Dec-31-09
Add AVR32 and win64 ports. Add ARM softfp support.
Many fixes for AIX, Solaris, HP-UX, *BSD.
Several PowerPC and x86-64 bug fixes.
Build DLL for windows.
3.0.8 Dec-19-08
Add *BSD, BeOS, and PA-Linux support.
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 the
author at green@moxielogic.com, or the project mailing list at
libffi-discuss@sourceware.org.

View File

@@ -1,289 +0,0 @@
/* -----------------------------------------------------------------------
ffi.c
m68k Foreign Function Interface
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __rtems__
void rtems_cache_flush_multiple_data_lines( const void *, size_t );
#else
#include <sys/syscall.h>
#include <asm/cachectl.h>
#endif
void ffi_call_SYSV (extended_cif *,
unsigned, unsigned,
void *, void (*fn) ());
void *ffi_prep_args (void *stack, extended_cif *ecif);
void ffi_closure_SYSV (ffi_closure *);
void ffi_closure_struct_SYSV (ffi_closure *);
unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
void *resp, void *args);
/* ffi_prep_args is called by the assembly routine once stack space has
been allocated for the function's arguments. */
void *
ffi_prep_args (void *stack, extended_cif *ecif)
{
unsigned int i;
void **p_argv;
char *argp;
ffi_type **p_arg;
void *struct_value_ptr;
argp = stack;
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
&& !ecif->cif->flags)
struct_value_ptr = ecif->rvalue;
else
struct_value_ptr = NULL;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
i != 0;
i--, p_arg++)
{
size_t z;
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;
case FFI_TYPE_STRUCT:
memcpy (argp + sizeof (int) - z, *p_argv, z);
break;
default:
FFI_ASSERT (0);
}
z = sizeof (int);
}
else
{
memcpy (argp, *p_argv, z);
/* Align if necessary. */
if ((sizeof(int) - 1) & z)
z = ALIGN(z, sizeof(int));
}
p_argv++;
argp += z;
}
return struct_value_ptr;
}
#define CIF_FLAGS_INT 1
#define CIF_FLAGS_DINT 2
#define CIF_FLAGS_FLOAT 4
#define CIF_FLAGS_DOUBLE 8
#define CIF_FLAGS_LDOUBLE 16
#define CIF_FLAGS_POINTER 32
#define CIF_FLAGS_STRUCT1 64
#define CIF_FLAGS_STRUCT2 128
/* Perform machine dependent cif processing */
ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
cif->flags = 0;
break;
case FFI_TYPE_STRUCT:
switch (cif->rtype->size)
{
case 1:
cif->flags = CIF_FLAGS_STRUCT1;
break;
case 2:
cif->flags = CIF_FLAGS_STRUCT2;
break;
case 4:
cif->flags = CIF_FLAGS_INT;
break;
case 8:
cif->flags = CIF_FLAGS_DINT;
break;
default:
cif->flags = 0;
break;
}
break;
case FFI_TYPE_FLOAT:
cif->flags = CIF_FLAGS_FLOAT;
break;
case FFI_TYPE_DOUBLE:
cif->flags = CIF_FLAGS_DOUBLE;
break;
#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
case FFI_TYPE_LONGDOUBLE:
cif->flags = CIF_FLAGS_LDOUBLE;
break;
#endif
case FFI_TYPE_POINTER:
cif->flags = CIF_FLAGS_POINTER;
break;
case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64:
cif->flags = CIF_FLAGS_DINT;
break;
default:
cif->flags = CIF_FLAGS_INT;
break;
}
return FFI_OK;
}
void
ffi_call (ffi_cif *cif, void (*fn) (), 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
&& cif->rtype->size > 8)
ecif.rvalue = alloca (cif->rtype->size);
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
case FFI_SYSV:
ffi_call_SYSV (&ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
default:
FFI_ASSERT (0);
break;
}
}
static void
ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
{
unsigned int i;
void **p_argv;
char *argp;
ffi_type **p_arg;
argp = stack;
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
z = (*p_arg)->size;
if (z <= 4)
{
*p_argv = (void *) (argp + 4 - z);
z = 4;
}
else
{
*p_argv = (void *) argp;
/* Align if necessary */
if ((sizeof(int) - 1) & z)
z = ALIGN(z, sizeof(int));
}
p_argv++;
argp += z;
}
}
unsigned int
ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
{
ffi_cif *cif;
void **arg_area;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void *));
ffi_prep_incoming_args_SYSV(args, arg_area, cif);
(closure->fun) (cif, resp, arg_area, closure->user_data);
return cif->flags;
}
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc)
{
if (cif->abi != FFI_SYSV)
return FFI_BAD_ABI;
*(unsigned short *)closure->tramp = 0x207c;
*(void **)(closure->tramp + 2) = codeloc;
*(unsigned short *)(closure->tramp + 6) = 0x4ef9;
if (cif->rtype->type == FFI_TYPE_STRUCT
&& !cif->flags)
*(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
else
*(void **)(closure->tramp + 8) = ffi_closure_SYSV;
#ifdef __rtems__
rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
#else
syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
#endif
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}

View File

@@ -1,270 +0,0 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1998, 2012 Andreas Schwab
Copyright (c) 2008 Red Hat, Inc.
m68k 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_AS_CFI_PSEUDO_OP
#define CFI_STARTPROC() .cfi_startproc
#define CFI_OFFSET(reg,off) .cfi_offset reg,off
#define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off
#define CFI_ENDPROC() .cfi_endproc
#else
#define CFI_STARTPROC()
#define CFI_OFFSET(reg,off)
#define CFI_DEF_CFA(reg,off)
#define CFI_ENDPROC()
#endif
.text
.globl ffi_call_SYSV
.type ffi_call_SYSV,@function
.align 4
ffi_call_SYSV:
CFI_STARTPROC()
link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %d2,-(%sp)
CFI_OFFSET(2,-12)
| Make room for all of the new args.
sub.l 12(%fp),%sp
| Call ffi_prep_args
move.l 8(%fp),-(%sp)
pea 4(%sp)
#if !defined __PIC__
jsr ffi_prep_args
#else
bsr.l ffi_prep_args@PLTPC
#endif
addq.l #8,%sp
| Pass pointer to struct value, if any
move.l %a0,%a1
| Call the function
move.l 24(%fp),%a0
jsr (%a0)
| Remove the space we pushed for the args
add.l 12(%fp),%sp
| Load the pointer to storage for the return value
move.l 20(%fp),%a1
| Load the return type code
move.l 16(%fp),%d2
| If the return value pointer is NULL, assume no return value.
| NOTE: On the mc68000, tst on an address register is not supported.
#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
cmp.w #0, %a1
#else
tst.l %a1
#endif
jbeq noretval
btst #0,%d2
jbeq retlongint
move.l %d0,(%a1)
jbra epilogue
retlongint:
btst #1,%d2
jbeq retfloat
move.l %d0,(%a1)
move.l %d1,4(%a1)
jbra epilogue
retfloat:
btst #2,%d2
jbeq retdouble
#if defined(__MC68881__) || defined(__HAVE_68881__)
fmove.s %fp0,(%a1)
#else
move.l %d0,(%a1)
#endif
jbra epilogue
retdouble:
btst #3,%d2
jbeq retlongdouble
#if defined(__MC68881__) || defined(__HAVE_68881__)
fmove.d %fp0,(%a1)
#else
move.l %d0,(%a1)+
move.l %d1,(%a1)
#endif
jbra epilogue
retlongdouble:
btst #4,%d2
jbeq retpointer
#if defined(__MC68881__) || defined(__HAVE_68881__)
fmove.x %fp0,(%a1)
#else
move.l %d0,(%a1)+
move.l %d1,(%a1)+
move.l %d2,(%a1)
#endif
jbra epilogue
retpointer:
btst #5,%d2
jbeq retstruct1
move.l %a0,(%a1)
jbra epilogue
retstruct1:
btst #6,%d2
jbeq retstruct2
move.b %d0,(%a1)
jbra epilogue
retstruct2:
btst #7,%d2
jbeq noretval
move.w %d0,(%a1)
noretval:
epilogue:
move.l (%sp)+,%d2
unlk %fp
rts
CFI_ENDPROC()
.size ffi_call_SYSV,.-ffi_call_SYSV
.globl ffi_closure_SYSV
.type ffi_closure_SYSV, @function
.align 4
ffi_closure_SYSV:
CFI_STARTPROC()
link %fp,#-12
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
pea -12(%fp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
lsr.l #1,%d0
jne 1f
jcc .Lcls_epilogue
move.l -12(%fp),%d0
.Lcls_epilogue:
unlk %fp
rts
1:
lea -12(%fp),%a0
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_float
move.l (%a0)+,%d0
move.l (%a0),%d1
jra .Lcls_epilogue
.Lcls_ret_float:
#if defined(__MC68881__) || defined(__HAVE_68881__)
fmove.s (%a0),%fp0
#else
move.l (%a0),%d0
#endif
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_ldouble
#if defined(__MC68881__) || defined(__HAVE_68881__)
fmove.d (%a0),%fp0
#else
move.l (%a0)+,%d0
move.l (%a0),%d1
#endif
jra .Lcls_epilogue
.Lcls_ret_ldouble:
#if defined(__MC68881__) || defined(__HAVE_68881__)
fmove.x (%a0),%fp0
#else
move.l (%a0)+,%d0
move.l (%a0)+,%d1
move.l (%a0),%d2
#endif
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne .Lcls_ret_struct2
jcs .Lcls_ret_struct1
move.l (%a0),%a0
move.l %a0,%d0
jra .Lcls_epilogue
.Lcls_ret_struct1:
move.b (%a0),%d0
jra .Lcls_epilogue
.Lcls_ret_struct2:
move.w (%a0),%d0
jra .Lcls_epilogue
CFI_ENDPROC()
.size ffi_closure_SYSV,.-ffi_closure_SYSV
.globl ffi_closure_struct_SYSV
.type ffi_closure_struct_SYSV, @function
.align 4
ffi_closure_struct_SYSV:
CFI_STARTPROC()
link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
move.l %a1,-(%sp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
unlk %fp
rts
CFI_ENDPROC()
.size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",@progbits
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,203 +0,0 @@
## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects
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/avr32/ffi.c src/avr32/sysv.S src/avr32/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/win64.S src/x86/freebsd.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 libtool-version \
ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 build-ios.sh \
m4/ltversion.m4 build-ios.sh src/arm/gentramp.sh src/debug.c \
msvcc.sh
info_TEXINFOS = doc/libffi.texi
## ################################################################
##
## 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)" \
"mandir=$(mandir)" \
"prefix=$(prefix)" \
"AR=$(AR)" \
"AS=$(AS)" \
"CC=$(CC)" \
"CXX=$(CXX)" \
"LD=$(LD)" \
"NM=$(NM)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES=
ACLOCAL_AMFLAGS=$(ACLOCAL_AMFLAGS) -I m4
lib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/closures.c
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libffi.pc
nodist_libffi_la_SOURCES =
if FFI_DEBUG
nodist_libffi_la_SOURCES += src/debug.c
endif
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
if FFI_EXEC_TRAMPOLINE_TABLE
nodist_libffi_la_SOURCES += src/arm/trampoline.S
endif
endif
if AVR32
nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/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 = -g
if FFI_DEBUG
# Build debug. Define FFI_DEBUG on the commandline so that, when building with
# MSVC, it can link against the debug CRT.
AM_CFLAGS += -DFFI_DEBUG
endif
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
AM_CCASFLAGS = $(AM_CPPFLAGS) -g
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf:

File diff suppressed because it is too large Load Diff

View File

@@ -1,443 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
libffi @VERSION@ - Copyright (c) 2011 Anthony Green
- 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. */
#ifndef @TARGET@
#define @TARGET@
#endif
/* ---- 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. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif /* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif /* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# 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 != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#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 == FFI_64_BIT_MAX
# 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;
/* Used internally, but overridden by some architectures */
ffi_status ffi_prep_cif_core(ffi_cif *cif,
ffi_abi abi,
unsigned int isvariadic,
unsigned int nfixedargs,
unsigned int ntotalargs,
ffi_type *rtype,
ffi_type **atypes);
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# 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
#ifdef _MSC_VER
__declspec(align(8))
#endif
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
#ifdef __GNUC__
} ffi_closure __attribute__((aligned (8)));
#else
} ffi_closure;
# ifdef __sgi
# pragma pack 0
# endif
#endif
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);
#ifdef __sgi
# pragma pack 8
#endif
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);
ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_abi abi,
unsigned int nfixedargs,
unsigned int ntotalargs,
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

@@ -1,826 +0,0 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
Copyright (c) 2002 Ranjit Mathew
Copyright (c) 2002 Bo Thorsen
Copyright (c) 2002 Roger Sayle
Copyright (C) 2008, 2010 Free Software Foundation, Inc.
x86 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.
----------------------------------------------------------------------- */
#if !defined(__x86_64__) || defined(_WIN64)
#ifdef _WIN64
#include <windows.h>
#endif
#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;
#ifdef X86_WIN32
size_t p_stack_args[2];
void *p_stack_data[2];
char *argp2 = stack;
int stack_args_count = 0;
int cabi = ecif->cif->abi;
#endif
argp = stack;
if (ecif->cif->flags == FFI_TYPE_STRUCT
#ifdef X86_WIN64
&& (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
&& ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
#endif
)
{
*(void **) argp = ecif->rvalue;
#ifdef X86_WIN32
/* For fastcall/thiscall this is first register-passed
argument. */
if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
{
p_stack_args[stack_args_count] = sizeof (void*);
p_stack_data[stack_args_count] = argp;
++stack_args_count;
}
#endif
argp += sizeof(void*);
}
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 ((sizeof(void*) - 1) & (size_t) argp)
argp = (char *) ALIGN(argp, sizeof(void*));
z = (*p_arg)->size;
#ifdef X86_WIN64
if (z > sizeof(ffi_arg)
|| ((*p_arg)->type == FFI_TYPE_STRUCT
&& (z != 1 && z != 2 && z != 4 && z != 8))
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
|| ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
#endif
)
{
z = sizeof(ffi_arg);
*(void **)argp = *p_argv;
}
else if ((*p_arg)->type == FFI_TYPE_FLOAT)
{
memcpy(argp, *p_argv, z);
}
else
#endif
if (z < sizeof(ffi_arg))
{
z = sizeof(ffi_arg);
switch ((*p_arg)->type)
{
case FFI_TYPE_SINT8:
*(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
break;
case FFI_TYPE_UINT8:
*(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
break;
case FFI_TYPE_SINT16:
*(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
break;
case FFI_TYPE_UINT16:
*(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
break;
case FFI_TYPE_SINT32:
*(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
break;
case FFI_TYPE_UINT32:
*(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
break;
case FFI_TYPE_STRUCT:
*(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
break;
default:
FFI_ASSERT(0);
}
}
else
{
memcpy(argp, *p_argv, z);
}
#ifdef X86_WIN32
/* For thiscall/fastcall convention register-passed arguments
are the first two none-floating-point arguments with a size
smaller or equal to sizeof (void*). */
if ((cabi == FFI_THISCALL && stack_args_count < 1)
|| (cabi == FFI_FASTCALL && stack_args_count < 2))
{
if (z <= 4
&& ((*p_arg)->type != FFI_TYPE_FLOAT
&& (*p_arg)->type != FFI_TYPE_STRUCT))
{
p_stack_args[stack_args_count] = z;
p_stack_data[stack_args_count] = argp;
++stack_args_count;
}
}
#endif
p_argv++;
#ifdef X86_WIN64
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
#else
argp += z;
#endif
}
#ifdef X86_WIN32
/* We need to move the register-passed arguments for thiscall/fastcall
on top of stack, so that those can be moved to registers ecx/edx by
call-handler. */
if (stack_args_count > 0)
{
size_t zz = (p_stack_args[0] + 3) & ~3;
char *h;
/* Move first argument to top-stack position. */
if (p_stack_data[0] != argp2)
{
h = alloca (zz + 1);
memcpy (h, p_stack_data[0], zz);
memmove (argp2 + zz, argp2,
(size_t) ((char *) p_stack_data[0] - (char*)argp2));
memcpy (argp2, h, zz);
}
argp2 += zz;
--stack_args_count;
if (zz > 4)
stack_args_count = 0;
/* If we have a second argument, then move it on top
after the first one. */
if (stack_args_count > 0 && p_stack_data[1] != argp2)
{
zz = p_stack_args[1];
zz = (zz + 3) & ~3;
h = alloca (zz + 1);
h = alloca (zz + 1);
memcpy (h, p_stack_data[1], zz);
memmove (argp2 + zz, argp2, (size_t) ((char*) p_stack_data[1] - (char*)argp2));
memcpy (argp2, h, zz);
}
}
#endif
return;
}
/* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
unsigned int i;
ffi_type **ptr;
/* Set the return type flag */
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
#ifdef X86_WIN64
case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32:
#endif
case FFI_TYPE_SINT64:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
#ifndef X86_WIN64
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
#endif
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_UINT64:
#ifdef X86_WIN64
case FFI_TYPE_POINTER:
#endif
cif->flags = FFI_TYPE_SINT64;
break;
case FFI_TYPE_STRUCT:
#ifndef X86
if (cif->rtype->size == 1)
{
cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
}
else if (cif->rtype->size == 2)
{
cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
}
else if (cif->rtype->size == 4)
{
#ifdef X86_WIN64
cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
#else
cif->flags = FFI_TYPE_INT; /* same as int type */
#endif
}
else if (cif->rtype->size == 8)
{
cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
}
else
#endif
{
cif->flags = FFI_TYPE_STRUCT;
/* allocate space for return value pointer */
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
}
break;
default:
#ifdef X86_WIN64
cif->flags = FFI_TYPE_SINT64;
break;
case FFI_TYPE_INT:
cif->flags = FFI_TYPE_SINT32;
#else
cif->flags = FFI_TYPE_INT;
#endif
break;
}
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
if (((*ptr)->alignment - 1) & cif->bytes)
cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
}
#ifdef X86_WIN64
/* ensure space for storing four registers */
cif->bytes += 4 * sizeof(ffi_arg);
#endif
#ifdef X86_DARWIN
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
return FFI_OK;
}
#ifdef X86_WIN64
extern int
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#elif defined(X86_WIN32)
extern void
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned, unsigned *, void (*fn)(void));
#else
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#endif
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 */
#ifdef X86_WIN64
if (rvalue == NULL
&& cif->flags == FFI_TYPE_STRUCT
&& cif->rtype->size != 1 && cif->rtype->size != 2
&& cif->rtype->size != 4 && cif->rtype->size != 8)
{
ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
}
#else
if (rvalue == NULL
&& cif->flags == FFI_TYPE_STRUCT)
{
ecif.rvalue = alloca(cif->rtype->size);
}
#endif
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
#ifdef X86_WIN64
case FFI_WIN64:
ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn);
break;
#elif defined(X86_WIN32)
case FFI_SYSV:
case FFI_STDCALL:
ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
case FFI_THISCALL:
case FFI_FASTCALL:
{
unsigned int abi = cif->abi;
unsigned int i, passed_regs = 0;
if (cif->flags == FFI_TYPE_STRUCT)
++passed_regs;
for (i=0; i < cif->nargs && passed_regs < 2;i++)
{
size_t sz;
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
continue;
sz = (cif->arg_types[i]->size + 3) & ~3;
if (sz == 0 || sz > 4)
continue;
++passed_regs;
}
if (passed_regs < 2 && abi == FFI_FASTCALL)
abi = FFI_THISCALL;
if (passed_regs < 1 && abi == FFI_THISCALL)
abi = FFI_STDCALL;
ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
}
break;
#else
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
fn);
break;
#endif
default:
FFI_ASSERT(0);
break;
}
}
/** private members **/
/* The following __attribute__((regparm(1))) decorations will have no effect
on MSVC - standard cdecl convention applies. */
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
__attribute__ ((regparm(1)));
unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
__attribute__ ((regparm(1)));
#ifdef X86_WIN32
void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
__attribute__ ((regparm(1)));
#endif
#ifdef X86_WIN64
void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
#endif
/* This function is jumped to by the trampoline */
#ifdef X86_WIN64
void * FFI_HIDDEN
ffi_closure_win64_inner (ffi_closure *closure, void *args) {
ffi_cif *cif;
void **arg_area;
void *result;
void *resp = &result;
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 change RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
(closure->fun) (cif, resp, arg_area, closure->user_data);
/* The result is returned in rax. This does the right thing for
result types except for floats; we have to 'mov xmm0, rax' in the
caller to correct this.
TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
*/
return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
}
#else
unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
ffi_closure_SYSV_inner (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 change 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;
}
#endif /* !X86_WIN64 */
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
ffi_cif *cif)
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
#ifdef X86_WIN64
if (cif->rtype->size > sizeof(ffi_arg)
|| (cif->flags == FFI_TYPE_STRUCT
&& (cif->rtype->size != 1 && cif->rtype->size != 2
&& cif->rtype->size != 4 && cif->rtype->size != 8))) {
*rvalue = *(void **) argp;
argp += sizeof(void *);
}
#else
if ( cif->flags == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
argp += sizeof(void *);
}
#endif
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
/* Align if necessary */
if ((sizeof(void*) - 1) & (size_t) argp) {
argp = (char *) ALIGN(argp, sizeof(void*));
}
#ifdef X86_WIN64
if ((*p_arg)->size > sizeof(ffi_arg)
|| ((*p_arg)->type == FFI_TYPE_STRUCT
&& ((*p_arg)->size != 1 && (*p_arg)->size != 2
&& (*p_arg)->size != 4 && (*p_arg)->size != 8)))
{
z = sizeof(void *);
*p_argv = *(void **)argp;
}
else
#endif
{
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
}
p_argv++;
#ifdef X86_WIN64
argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
#else
argp += z;
#endif
}
return;
}
#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
void* __fun = (void*)(FUN); \
void* __ctx = (void*)(CTX); \
*(unsigned char*) &__tramp[0] = 0x41; \
*(unsigned char*) &__tramp[1] = 0xbb; \
*(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
*(unsigned char*) &__tramp[6] = 0x48; \
*(unsigned char*) &__tramp[7] = 0xb8; \
*(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
*(unsigned char *) &__tramp[16] = 0x49; \
*(unsigned char *) &__tramp[17] = 0xba; \
*(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
*(unsigned char *) &__tramp[26] = 0x41; \
*(unsigned char *) &__tramp[27] = 0xff; \
*(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
}
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
#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 __dis = __fun - (__ctx + 10); \
*(unsigned char*) &__tramp[0] = 0xb8; \
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe9; \
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
}
#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - (__ctx + 49); \
unsigned short __size = (unsigned short)(SIZE); \
*(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
*(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
*(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \
*(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \
*(unsigned char*) &__tramp[13] = 0xb8; \
*(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \
*(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \
*(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \
*(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \
*(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \
*(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \
*(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \
*(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \
*(unsigned char*) &__tramp[39] = 0xb8; \
*(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[44] = 0xe8; \
*(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \
*(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \
*(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \
}
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - (__ctx + 10); \
unsigned short __size = (unsigned short)(SIZE); \
*(unsigned char*) &__tramp[0] = 0xb8; \
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe8; \
*(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
*(unsigned char *) &__tramp[10] = 0xc2; \
*(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
}
/* 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)
{
#ifdef X86_WIN64
#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
if (cif->abi == FFI_WIN64)
{
int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
&ffi_closure_win64,
codeloc, mask);
/* make sure we can execute here */
}
#else
if (cif->abi == FFI_SYSV)
{
FFI_INIT_TRAMPOLINE (&closure->tramp[0],
&ffi_closure_SYSV,
(void*)codeloc);
}
#ifdef X86_WIN32
else if (cif->abi == FFI_THISCALL)
{
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0],
&ffi_closure_THISCALL,
(void*)codeloc,
cif->bytes);
}
else if (cif->abi == FFI_STDCALL)
{
FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
&ffi_closure_STDCALL,
(void*)codeloc, cif->bytes);
}
#endif /* X86_WIN32 */
#endif /* !X86_WIN64 */
else
{
return FFI_BAD_ABI;
}
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}
/* ------- Native raw API support -------------------------------- */
#if !FFI_NO_RAW_API
ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc)
{
int i;
if (cif->abi != FFI_SYSV) {
#ifdef X86_WIN32
if (cif->abi != FFI_THISCALL)
#endif
return FFI_BAD_ABI;
}
/* we currently don't support certain kinds of arguments for raw
closures. This should be implemented by a separate assembly
language routine, since it would require argument processing,
something we don't do now for performance. */
for (i = cif->nargs-1; i >= 0; i--)
{
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
}
#ifdef X86_WIN32
if (cif->abi == FFI_SYSV)
{
#endif
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
codeloc);
#ifdef X86_WIN32
}
else if (cif->abi == FFI_THISCALL)
{
FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL,
codeloc, cif->bytes);
}
#endif
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}
static void
ffi_prep_args_raw(char *stack, extended_cif *ecif)
{
memcpy (stack, ecif->avalue, ecif->cif->bytes);
}
/* we borrow this routine from libffi (it must be changed, though, to
* actually call the function passed in the first argument. as of
* libffi-1.20, this is not the case.)
*/
void
ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
{
extended_cif ecif;
void **avalue = (void **)fake_avalue;
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)
{
#ifdef X86_WIN32
case FFI_SYSV:
case FFI_STDCALL:
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
case FFI_THISCALL:
case FFI_FASTCALL:
{
unsigned int abi = cif->abi;
unsigned int i, passed_regs = 0;
if (cif->flags == FFI_TYPE_STRUCT)
++passed_regs;
for (i=0; i < cif->nargs && passed_regs < 2;i++)
{
size_t sz;
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
continue;
sz = (cif->arg_types[i]->size + 3) & ~3;
if (sz == 0 || sz > 4)
continue;
++passed_regs;
}
if (passed_regs < 2 && abi == FFI_FASTCALL)
cif->abi = abi = FFI_THISCALL;
if (passed_regs < 1 && abi == FFI_THISCALL)
cif->abi = abi = FFI_STDCALL;
ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
}
break;
#else
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
#endif
default:
FFI_ASSERT(0);
break;
}
}
#endif
#endif /* !__x86_64__ || X86_WIN64 */

View File

@@ -1,135 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 2012 Anthony Green
Copyright (c) 1996-2003, 2010 Red Hat, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
Target configuration macros for x86 and x86-64.
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_H
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
/* ---- System specific configurations ----------------------------------- */
/* For code common to all platforms on x86 and x86_64. */
#define X86_ANY
#if defined (X86_64) && defined (__i386__)
#undef X86_64
#define X86
#endif
#ifdef X86_WIN64
#define FFI_SIZEOF_ARG 8
#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
#endif
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
#ifdef X86_WIN64
#ifdef _MSC_VER
typedef unsigned __int64 ffi_arg;
typedef __int64 ffi_sarg;
#else
typedef unsigned long long ffi_arg;
typedef long long ffi_sarg;
#endif
#else
#if defined __x86_64__ && defined __ILP32__
#define FFI_SIZEOF_ARG 8
#define FFI_SIZEOF_JAVA_RAW 4
typedef unsigned long long ffi_arg;
typedef long long ffi_sarg;
#else
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
#endif
#endif
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
/* ---- Intel x86 Win32 ---------- */
#ifdef X86_WIN32
FFI_SYSV,
FFI_STDCALL,
FFI_THISCALL,
FFI_FASTCALL,
FFI_LAST_ABI,
/* TODO: Add fastcall support for the sake of completeness */
FFI_DEFAULT_ABI = FFI_SYSV
#elif defined(X86_WIN64)
FFI_WIN64,
FFI_LAST_ABI,
FFI_DEFAULT_ABI = FFI_WIN64
#else
/* ---- Intel x86 and AMD x86-64 - */
FFI_SYSV,
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
FFI_LAST_ABI,
#if defined(__i386__) || defined(__i386)
FFI_DEFAULT_ABI = FFI_SYSV
#else
FFI_DEFAULT_ABI = FFI_UNIX64
#endif
#endif
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#else
#ifdef X86_WIN32
#define FFI_TRAMPOLINE_SIZE 52
#else
#ifdef X86_WIN64
#define FFI_TRAMPOLINE_SIZE 29
#define FFI_NATIVE_RAW_API 0
#define FFI_NO_RAW_API 1
#else
#define FFI_TRAMPOLINE_SIZE 10
#endif
#endif
#ifndef X86_WIN64
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +0,0 @@
/* Area: closure_call (stdcall convention)
Purpose: Check handling when caller expects stdcall callee
Limitations: none.
PR: none.
Originator: <twalljava@dev.java.net> */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static void
closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(int *)args[0] + (int)(*(int *)args[1])
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ (int)(intptr_t)userdata;
printf("%d %d %d %d: %d\n",
(int)*(int *)args[0], (int)(*(int *)args[1]),
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
(int)*(ffi_arg *)resp);
}
typedef int (__stdcall *closure_test_type0)(int, int, int, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
void* sp_pre;
void* sp_post;
char buf[1024];
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = &ffi_type_uint;
cl_arg_types[2] = &ffi_type_uint;
cl_arg_types[3] = &ffi_type_uint;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
(void *) 3 /* userdata */, code) == FFI_OK);
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
res = (*(closure_test_type0)code)(0, 1, 2, 3);
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
/* { dg-output "0 1 2 3: 9" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 9" } */
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
/* { dg-output "\nstack pointer match" } */
exit(0);
}

View File

@@ -1,64 +0,0 @@
/* Area: closure_call (thiscall convention)
Purpose: Check handling when caller expects thiscall callee
Limitations: none.
PR: none.
Originator: <ktietz@redhat.com> */
/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
#include "ffitest.h"
static void
closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{
*(ffi_arg*)resp =
(int)*(int *)args[0] + (int)(*(int *)args[1])
+ (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ (int)(intptr_t)userdata;
printf("%d %d %d %d: %d\n",
(int)*(int *)args[0], (int)(*(int *)args[1]),
(int)(*(int *)args[2]), (int)(*(int *)args[3]),
(int)*(ffi_arg *)resp);
}
typedef int (__thiscall *closure_test_type0)(int, int, int, int);
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
void* sp_pre;
void* sp_post;
char buf[1024];
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = &ffi_type_uint;
cl_arg_types[2] = &ffi_type_uint;
cl_arg_types[3] = &ffi_type_uint;
cl_arg_types[4] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4,
&ffi_type_sint, cl_arg_types) == FFI_OK);
CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall,
(void *) 3 /* userdata */, code) == FFI_OK);
asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
res = (*(closure_test_type0)code)(0, 1, 2, 3);
asm volatile (" movl %%esp,%0" : "=g" (sp_post));
/* { dg-output "0 1 2 3: 9" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 9" } */
sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
/* { dg-output "\nstack pointer match" } */
exit(0);
}

View File

@@ -1,94 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_12byte {
int a;
int b;
int c;
} cls_struct_12byte;
cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
struct cls_struct_12byte b2)
{
struct cls_struct_12byte result;
result.a = b1.a + b2.a;
result.b = b1.b + b2.b;
result.c = b1.c + b2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
result.a, result.b, result.c);
return result;
}
static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args , void* userdata __UNUSED__)
{
struct cls_struct_12byte b1, b2;
b1 = *(struct cls_struct_12byte*)(args[0]);
b2 = *(struct cls_struct_12byte*)(args[1]);
*(cls_struct_12byte*)resp = cls_struct_12byte_fn(b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_12byte h_dbl = { 7, 4, 9 };
struct cls_struct_12byte j_dbl = { 1, 5, 3 };
struct cls_struct_12byte res_dbl;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &h_dbl;
args_dbl[1] = &j_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_12byte_fn), &res_dbl, args_dbl);
/* { dg-output "7 4 9 1 5 3: 8 9 12" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 9 12" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 9 12" } */
exit(0);
}

View File

@@ -1,95 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_16byte {
int a;
double b;
int c;
} cls_struct_16byte;
cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
struct cls_struct_16byte b2)
{
struct cls_struct_16byte result;
result.a = b1.a + b2.a;
result.b = b1.b + b2.b;
result.c = b1.c + b2.c;
printf("%d %g %d %d %g %d: %d %g %d\n", b1.a, b1.b, b1.c, b2.a, b2.b, b2.c,
result.a, result.b, result.c);
return result;
}
static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{
struct cls_struct_16byte b1, b2;
b1 = *(struct cls_struct_16byte*)(args[0]);
b2 = *(struct cls_struct_16byte*)(args[1]);
*(cls_struct_16byte*)resp = cls_struct_16byte_fn(b1, b2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
struct cls_struct_16byte res_dbl;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &h_dbl;
args_dbl[1] = &j_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
/* { dg-output "7 8 9 1 9 3: 8 17 12" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 17 12" } */
res_dbl.a = 0;
res_dbl.b = 0.0;
res_dbl.c = 0;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 17 12" } */
exit(0);
}

View File

@@ -1,96 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Double alignment check on darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030915 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_18byte {
double a;
unsigned char b;
unsigned char c;
double d;
} cls_struct_18byte;
cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
struct cls_struct_18byte a2)
{
struct cls_struct_18byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
printf("%g %d %d %g %g %d %d %g: %g %d %d %g\n", a1.a, a1.b, a1.c, a1.d,
a2.a, a2.b, a2.c, a2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_18byte a1, a2;
a1 = *(struct cls_struct_18byte*)(args[0]);
a2 = *(struct cls_struct_18byte*)(args[1]);
*(cls_struct_18byte*)resp = cls_struct_18byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 };
struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 };
struct cls_struct_18byte res_dbl;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_double;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_18byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 127 126 3 4 125 124 5: 5 252 250 8" } */
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 5 252 250 8" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 5 252 250 8" } */
exit(0);
}

View File

@@ -1,102 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Double alignment check on darwin.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030915 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_19byte {
double a;
unsigned char b;
unsigned char c;
double d;
unsigned char e;
} cls_struct_19byte;
cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
struct cls_struct_19byte a2)
{
struct cls_struct_19byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
result.d = a1.d + a2.d;
result.e = a1.e + a2.e;
printf("%g %d %d %g %d %g %d %d %g %d: %g %d %d %g %d\n",
a1.a, a1.b, a1.c, a1.d, a1.e,
a2.a, a2.b, a2.c, a2.d, a2.e,
result.a, result.b, result.c, result.d, result.e);
return result;
}
static void
cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_19byte a1, a2;
a1 = *(struct cls_struct_19byte*)(args[0]);
a2 = *(struct cls_struct_19byte*)(args[1]);
*(cls_struct_19byte*)resp = cls_struct_19byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[6];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 };
struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 };
struct cls_struct_19byte res_dbl;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = &ffi_type_double;
cls_struct_fields[4] = &ffi_type_uchar;
cls_struct_fields[5] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_19byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 5 252 250 8 239" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 5 252 250 8 239" } */
exit(0);
}

View File

@@ -1,89 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_1_1byte {
unsigned char a;
} cls_struct_1_1byte;
cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
struct cls_struct_1_1byte a2)
{
struct cls_struct_1_1byte result;
result.a = a1.a + a2.a;
printf("%d %d: %d\n", a1.a, a2.a, result.a);
return result;
}
static void
cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_1_1byte a1, a2;
a1 = *(struct cls_struct_1_1byte*)(args[0]);
a2 = *(struct cls_struct_1_1byte*)(args[1]);
*(cls_struct_1_1byte*)resp = cls_struct_1_1byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[2];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_1_1byte g_dbl = { 12 };
struct cls_struct_1_1byte f_dbl = { 178 };
struct cls_struct_1_1byte res_dbl;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_1_1byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 178: 190" } */
printf("res: %d\n", res_dbl.a);
/* { dg-output "\nres: 190" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 178: 190" } */
printf("res: %d\n", res_dbl.a);
/* { dg-output "\nres: 190" } */
exit(0);
}

View File

@@ -1,91 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_20byte {
double a;
double b;
int c;
} cls_struct_20byte;
cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
struct cls_struct_20byte a2)
{
struct cls_struct_20byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%g %g %d %g %g %d: %g %g %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_20byte a1, a2;
a1 = *(struct cls_struct_20byte*)(args[0]);
a2 = *(struct cls_struct_20byte*)(args[1]);
*(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 };
struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 };
struct cls_struct_20byte res_dbl;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 3 4 5 7: 5 7 10" } */
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
exit(0);
}

View File

@@ -1,93 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_20byte {
int a;
double b;
double c;
} cls_struct_20byte;
cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
struct cls_struct_20byte a2)
{
struct cls_struct_20byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %g %g %d %g %g: %d %g %g\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_20byte a1, a2;
a1 = *(struct cls_struct_20byte*)(args[0]);
a2 = *(struct cls_struct_20byte*)(args[1]);
*(cls_struct_20byte*)resp = cls_struct_20byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
struct cls_struct_20byte res_dbl;
cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_double;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
/* { dg-output "1 2 3 4 5 7: 5 7 10" } */
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
exit(0);
}

View File

@@ -1,113 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_24byte {
double a;
double b;
int c;
float d;
} cls_struct_24byte;
cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
struct cls_struct_24byte b1,
struct cls_struct_24byte b2,
struct cls_struct_24byte b3)
{
struct cls_struct_24byte result;
result.a = b0.a + b1.a + b2.a + b3.a;
result.b = b0.b + b1.b + b2.b + b3.b;
result.c = b0.c + b1.c + b2.c + b3.c;
result.d = b0.d + b1.d + b2.d + b3.d;
printf("%g %g %d %g %g %g %d %g %g %g %d %g %g %g %d %g: %g %g %d %g\n",
b0.a, b0.b, b0.c, b0.d,
b1.a, b1.b, b1.c, b1.d,
b2.a, b2.b, b2.c, b2.d,
b3.a, b3.b, b3.c, b2.d,
result.a, result.b, result.c, result.d);
return result;
}
static void
cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_24byte b0, b1, b2, b3;
b0 = *(struct cls_struct_24byte*)(args[0]);
b1 = *(struct cls_struct_24byte*)(args[1]);
b2 = *(struct cls_struct_24byte*)(args[2]);
b3 = *(struct cls_struct_24byte*)(args[3]);
*(cls_struct_24byte*)resp = cls_struct_24byte_fn(b0, b1, b2, b3);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 };
struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 };
struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 };
struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 };
struct cls_struct_24byte res_dbl;
cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = &ffi_type_float;
cls_struct_fields[4] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = &cls_struct_type;
dbl_arg_types[3] = &cls_struct_type;
dbl_arg_types[4] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &e_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = &g_dbl;
args_dbl[3] = &h_dbl;
args_dbl[4] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_24byte_fn), &res_dbl, args_dbl);
/* { dg-output "9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 22 15 17 25" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
cls_struct_24byte,
cls_struct_24byte,
cls_struct_24byte))
(code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 22 15 17 25" } */
exit(0);
}

View File

@@ -1,90 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_2byte {
unsigned char a;
unsigned char b;
} cls_struct_2byte;
cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
struct cls_struct_2byte a2)
{
struct cls_struct_2byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_2byte a1, a2;
a1 = *(struct cls_struct_2byte*)(args[0]);
a2 = *(struct cls_struct_2byte*)(args[1]);
*(cls_struct_2byte*)resp = cls_struct_2byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_2byte g_dbl = { 12, 127 };
struct cls_struct_2byte f_dbl = { 1, 13 };
struct cls_struct_2byte res_dbl;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_2byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 127 1 13: 13 140" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 140" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 127 1 13: 13 140" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 140" } */
exit(0);
}

View File

@@ -1,95 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_3_1byte {
unsigned char a;
unsigned char b;
unsigned char c;
} cls_struct_3_1byte;
cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
struct cls_struct_3_1byte a2)
{
struct cls_struct_3_1byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, a1.b, a1.c,
a2.a, a2.b, a2.c,
result.a, result.b, result.c);
return result;
}
static void
cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_3_1byte a1, a2;
a1 = *(struct cls_struct_3_1byte*)(args[0]);
a2 = *(struct cls_struct_3_1byte*)(args[1]);
*(cls_struct_3_1byte*)resp = cls_struct_3_1byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_3_1byte g_dbl = { 12, 13, 14 };
struct cls_struct_3_1byte f_dbl = { 178, 179, 180 };
struct cls_struct_3_1byte res_dbl;
cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_3_1byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 13 14 178 179 180: 190 192 194" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 190 192 194" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 190 192 194" } */
exit(0);
}

View File

@@ -1,90 +0,0 @@
/* Area: ffi_call, closure_call
Purpose: Check structure passing with different structure size.
Especially with small structures which may fit in one
register. Depending on the ABI. Check overlapping.
Limitations: none.
PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run } */
#include "ffitest.h"
typedef struct cls_struct_3byte {
unsigned short a;
unsigned char b;
} cls_struct_3byte;
cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
struct cls_struct_3byte a2)
{
struct cls_struct_3byte result;
result.a = a1.a + a2.a;
result.b = a1.b + a2.b;
printf("%d %d %d %d: %d %d\n", a1.a, a1.b, a2.a, a2.b, result.a, result.b);
return result;
}
static void
cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{
struct cls_struct_3byte a1, a2;
a1 = *(struct cls_struct_3byte*)(args[0]);
a2 = *(struct cls_struct_3byte*)(args[1]);
*(cls_struct_3byte*)resp = cls_struct_3byte_fn(a1, a2);
}
int main (void)
{
ffi_cif cif;
void *code;
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
cls_struct_type.elements = cls_struct_fields;
struct cls_struct_3byte g_dbl = { 12, 119 };
struct cls_struct_3byte f_dbl = { 1, 15 };
struct cls_struct_3byte res_dbl;
cls_struct_fields[0] = &ffi_type_ushort;
cls_struct_fields[1] = &ffi_type_uchar;
cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type;
dbl_arg_types[1] = &cls_struct_type;
dbl_arg_types[2] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
dbl_arg_types) == FFI_OK);
args_dbl[0] = &g_dbl;
args_dbl[1] = &f_dbl;
args_dbl[2] = NULL;
ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
/* { dg-output "12 119 1 15: 13 134" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 134" } */
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 119 1 15: 13 134" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 134" } */
exit(0);
}

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