mirror of https://github.com/python/cpython
Merged revisions 79101 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r79101 | matthias.klose | 2010-03-19 19:59:20 +0100 (Fr, 19 Mär 2010) | 3 lines update libffi to commit 59a259f4d348f593b45f452309f4d020a28051c4 from the trunk (adding msvc port). ........
This commit is contained in:
parent
9b86b9a086
commit
9a6587747c
|
@ -111,31 +111,3 @@ diff -urN libffi.orig/configure.ac libffi/configure.ac
|
|||
+AC_CONFIG_FILES(fficonfig.py)
|
||||
+
|
||||
AC_OUTPUT
|
||||
diff -urN libffi.orig/src/x86/ffi64.c libffi/src/x86/ffi64.c
|
||||
--- libffi.orig/src/x86/ffi64.c 2010-03-19 18:27:45.008523897 +0100
|
||||
+++ libffi/src/x86/ffi64.c 2010-03-19 18:24:36.437500070 +0100
|
||||
@@ -52,7 +52,7 @@
|
||||
/* 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 reformating penalties.
|
||||
+ 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). */
|
||||
diff -urN libffi.orig/src/x86/ffi.c libffi/src/x86/ffi.c
|
||||
--- libffi.orig/src/x86/ffi.c 2010-03-19 18:27:45.008523897 +0100
|
||||
+++ libffi/src/x86/ffi.c 2010-03-19 18:24:36.441496039 +0100
|
||||
@@ -594,10 +594,10 @@
|
||||
return FFI_BAD_ABI;
|
||||
}
|
||||
|
||||
- // we currently don't support certain kinds of arguments for raw
|
||||
+ /* 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.
|
||||
+ // don't do now for performance. */
|
||||
|
||||
for (i = cif->nargs-1; i >= 0; i--)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,89 @@
|
|||
2010-03-14 Matthias Klose <doko@ubuntu.com>
|
||||
|
||||
* src/x86/ffi64.c: Fix typo in comment.
|
||||
* src/x86/ffi.c: Use /* ... */ comment style.
|
||||
|
||||
2010-01-07 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR libffi/40701
|
||||
* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL,
|
||||
PRIuLL, PRId64, PRIu64, PRIuPTR): Define.
|
||||
* testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on
|
||||
alpha*-dec-osf*.
|
||||
* testsuite/libffi.call/cls_align_uint64.c: Likewise.
|
||||
* testsuite/libffi.call/cls_ulonglong.c: Likewise.
|
||||
* testsuite/libffi.call/return_ll1.c: Likewise.
|
||||
* testsuite/libffi.call/stret_medium2.c: Likewise.
|
||||
* testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast
|
||||
MAP_FAILED to char *.
|
||||
|
||||
2010-01-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__.
|
||||
|
||||
2009-12-31 Anthony Green <green@redhat.com>
|
||||
|
||||
* README: Update for libffi 3.0.9.
|
||||
|
||||
2009-12-27 Matthias Klose <doko@ubuntu.com>
|
||||
|
||||
* configure.ac (HAVE_LONG_DOUBLE): Define for mips when
|
||||
appropriate.
|
||||
* configure: Rebuilt.
|
||||
|
||||
2009-12-26 Anthony Green <green@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for
|
||||
avr32*-*-*.
|
||||
* testsuite/libffi.call/cls_double_va.c: Ditto.
|
||||
|
||||
2009-12-26 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
* testsuite/libffi.call/ffitest.h: Conditionally include stdint.h
|
||||
and inttypes.h.
|
||||
* testsuite/libffi.special/unwindtest.cc: Ditto.
|
||||
|
||||
2009-12-26 Andreas Tobler <a.tobler@schweiz.org>
|
||||
|
||||
* configure.ac: Add amd64-*-openbsd*.
|
||||
* configure: Rebuilt.
|
||||
* testsuite/lib/libffi-dg.exp (libffi_target_compile): Link
|
||||
openbsd programs with -lpthread.
|
||||
|
||||
2009-12-26 Anthony Green <green@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/cls_double_va.c,
|
||||
testsuite/libffi.call/cls_longdouble.c,
|
||||
testsuite/libffi.call/cls_longdouble_va.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for
|
||||
mips*-*-* and arm*-*-*.
|
||||
* testsuite/libffi.call/cls_align_longdouble_split.c,
|
||||
testsuite/libffi.call/cls_align_longdouble_split2.c,
|
||||
testsuite/libffi.call/stret_medium2.c,
|
||||
testsuite/libffi.call/stret_medium.c,
|
||||
testsuite/libffi.call/stret_large.c,
|
||||
testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*.
|
||||
|
||||
2009-12-31 Kay Tietz <ktietz70@googlemail.com>
|
||||
|
||||
* testsuite/libffi.call/ffitest.h,
|
||||
testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix
|
||||
definitions.
|
||||
|
||||
2009-12-31 Carlo Bramini <carlo.bramix@libero.it>
|
||||
|
||||
* configure.ac (AM_LTLDFLAGS): Define for windows hosts.
|
||||
* Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS.
|
||||
* configure: Rebuilt.
|
||||
* Makefile.in: Rebuilt.
|
||||
|
||||
2009-12-31 Anthony Green <green@redhat.com>
|
||||
Blake Chaffin.
|
||||
|
||||
* testsuite/libffi.call/huge_struct.c: New test case from Blake
|
||||
Chaffin @ Apple.
|
||||
|
||||
2009-12-28 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
|
||||
|
|
|
@ -1,56 +1,35 @@
|
|||
2009-12-27 Matthias Klose <doko@ubuntu.com>
|
||||
2010-01-15 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac (HAVE_LONG_DOUBLE): Define for mips when
|
||||
appropriate.
|
||||
* configure: Rebuilt.
|
||||
* README: Add notes on building with Microsoft Visual C++.
|
||||
|
||||
2009-12-27 Anthony Green <green@redhat.com>
|
||||
2010-01-15 Daniel Witte <dwitte@mozilla.com>
|
||||
|
||||
* testsuite/libffi.call/cls_longdouble.c: Don't xfail for ARM.
|
||||
* msvcc.sh: New file.
|
||||
|
||||
2009-12-26 Anthony Green <green@redhat.com>
|
||||
* src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
|
||||
* src/x86/ffi.c: Tweak function declaration and remove excess
|
||||
parens.
|
||||
* include/ffi.h.in: Add __declspec(align(8)) to typedef struct
|
||||
ffi_closure.
|
||||
|
||||
* testsuite/libffi.call/huge_struct.c: Don't xfail for avr32*-*-*.
|
||||
* testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for
|
||||
avr32*-*-*.
|
||||
* testsuite/libffi.call/cls_double_va.c: Ditto.
|
||||
* src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
|
||||
function ffi_call_win32 on X86_WIN32.
|
||||
* src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
|
||||
(ffi_call_STDCALL): Remove.
|
||||
|
||||
2009-12-26 Andreas Tobler <a.tobler@schweiz.org>
|
||||
* src/prep_cif.c (ffi_prep_cif): Move stack space allocation code
|
||||
to ffi_prep_cif_machdep for x86.
|
||||
* src/x86/ffi.c (ffi_prep_cif_machdep): To here.
|
||||
|
||||
* testsuite/libffi.call/ffitest.h: Conditionally include stdint.h
|
||||
and inttypes.h.
|
||||
* testsuite/libffi.special/unwindtest.cc: Ditto.
|
||||
* testsuite/libffi.call/huge_struct.c: Don't include stdint.h
|
||||
directly.
|
||||
2010-01-15 Oliver Kiddle <okiddle@yahoo.co.uk>
|
||||
|
||||
2009-12-26 Andreas Tobler <a.tobler@schweiz.org>
|
||||
* src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for
|
||||
Sun Studio compiler compatibility.
|
||||
|
||||
* configure.ac: Add amd64-*-openbsd*.
|
||||
* configure: Rebuilt.
|
||||
* testsuite/lib/libffi-dg.exp (libffi_target_compile): Link
|
||||
openbsd programs with -lpthread.
|
||||
2010-01-12 Conrad Irwin <conrad.irwin@gmail.com>
|
||||
|
||||
2009-12-26 Anthony Green <green@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/cls_double_va.c,
|
||||
testsuite/libffi.call/cls_longdouble.c,
|
||||
testsuite/libffi.call/cls_longdouble_va.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for
|
||||
mips*-*-* and arm*-*-*.
|
||||
* testsuite/libffi.call/cls_align_longdouble_split.c,
|
||||
testsuite/libffi.call/cls_align_longdouble_split2.c,
|
||||
testsuite/libffi.call/stret_medium2.c,
|
||||
testsuite/libffi.call/stret_medium.c,
|
||||
testsuite/libffi.call/stret_large.c,
|
||||
testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*.
|
||||
|
||||
2009-12-26 Andreas Tobler <a.tobler@schweiz.org>
|
||||
Anthony Green <green@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/huge_struct.c (test_large_fn): Replace
|
||||
format code %p with %#lx because %p does not add a leading 0x on
|
||||
Solaris. Also change relevant arguments to unsigned long.
|
||||
* doc/libffi.texi: Add closure example.
|
||||
* doc/libffi.info: Rebuilt.
|
||||
|
||||
2009-12-25 Samuli Suominen <ssuominen@gentoo.org>
|
||||
|
||||
|
@ -58,30 +37,6 @@
|
|||
* configure: Rebuilt.
|
||||
* fficonfig.h.in: Rebuilt.
|
||||
|
||||
2009-12-29 Kay Tietz <ktietz70@googlemail.com>
|
||||
|
||||
* testsuite/libffi.call/ffitest.h,
|
||||
testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix
|
||||
definitions.
|
||||
|
||||
2009-12-25 Carlo Bramini <carlo.bramix@libero.it>
|
||||
|
||||
* configure.ac (AM_LTLDFLAGS): Define for windows hosts.
|
||||
* Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS.
|
||||
* configure: Rebuilt.
|
||||
* Makefile.in: Rebuilt.
|
||||
|
||||
2009-12-24 Anthony Green <green@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/huge_struct.c: Fix printf format, and
|
||||
don't xfail x86 Linux.
|
||||
* testsuite/libffi.call/huge_struct.c: Don't xfail mips.
|
||||
* testsuite/libffi.call/cls_pointer.c: Ditto.
|
||||
* testsuite/libffi.call/cls_pointer_stack.c: Ditto.
|
||||
* testsuite/libffi.call/cls_longdouble_va.c: Ditto.
|
||||
* testsuite/libffi.call/cls_longdouble.c: Ditto.
|
||||
* testsuite/libffi.call/cls_double_va.c: Ditto.
|
||||
|
||||
2009-06-16 Andrew Haley <aph@redhat.com>
|
||||
|
||||
* testsuite/libffi.call/cls_align_sint64.c,
|
||||
|
@ -257,20 +212,20 @@
|
|||
2008-12-22 Timothy Wall <twall@users.sf.net>
|
||||
|
||||
* testsuite/libffi.call/closure_fn0.c,
|
||||
testsuite/libffi.call/closure_fn1.c,
|
||||
testsuite/libffi.call/closure_fn2.c,
|
||||
testsuite/libffi.call/closure_fn3.c,
|
||||
testsuite/libffi.call/closure_fn4.c,
|
||||
testsuite/libffi.call/closure_fn5.c,
|
||||
testsuite/libffi.call/closure_fn6.c,
|
||||
testsuite/libffi.call/closure_loc_fn0.c,
|
||||
testsuite/libffi.call/closure_stdcall.c,
|
||||
testsuite/libffi.call/cls_align_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/closure_fn1.c,
|
||||
testsuite/libffi.call/closure_fn2.c,
|
||||
testsuite/libffi.call/closure_fn3.c,
|
||||
testsuite/libffi.call/closure_fn4.c,
|
||||
testsuite/libffi.call/closure_fn5.c,
|
||||
testsuite/libffi.call/closure_fn6.c,
|
||||
testsuite/libffi.call/closure_loc_fn0.c,
|
||||
testsuite/libffi.call/closure_stdcall.c,
|
||||
testsuite/libffi.call/cls_align_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer.c,
|
||||
testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
|
||||
pointer to integer (intptr_t).
|
||||
* testsuite/libffi.call/cls_longdouble.c: disable for win64.
|
||||
|
||||
|
||||
2008-12-19 Anthony Green <green@redhat.com>
|
||||
|
||||
* configure.ac: Bump version to 3.0.8.
|
||||
|
|
|
@ -175,7 +175,7 @@ nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
|
|||
|
||||
AM_CFLAGS = -Wall -g -fexceptions
|
||||
|
||||
libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(AM_LTLDFLAGS)
|
||||
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)
|
||||
|
@ -184,4 +184,3 @@ AM_CCASFLAGS = $(AM_CPPFLAGS)
|
|||
.PHONY: install-html install-pdf
|
||||
install-html:
|
||||
install-pdf:
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Status
|
||||
======
|
||||
|
||||
libffi-3.0.9 was released on December 31, 2009. Check the libffi web
|
||||
libffi-3.0.10 was released on XXXXXXXXXX, 2010. Check the libffi web
|
||||
page for updates: <URL:http://sourceware.org/libffi/>.
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ 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.9
|
||||
http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.10
|
||||
|
||||
At the time of release, the following basic configurations have been
|
||||
tested:
|
||||
|
@ -52,6 +52,7 @@ tested:
|
|||
| Architecture | Operating System |
|
||||
|--------------+------------------|
|
||||
| Alpha | Linux |
|
||||
| Alpha | Tru64 |
|
||||
| ARM | Linux |
|
||||
| AVR32 | Linux |
|
||||
| HPPA | HPUX |
|
||||
|
@ -80,6 +81,7 @@ tested:
|
|||
| X86-64 | FreeBSD |
|
||||
| X86-64 | Linux |
|
||||
| X86-64 | OpenBSD |
|
||||
| X86-64 | Windows/MingW |
|
||||
|--------------+------------------|
|
||||
|
||||
Please send additional platform test results to
|
||||
|
@ -107,6 +109,14 @@ 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 --enable-shared --enable-static \
|
||||
CC=path/to/msvcc.sh LD=link \
|
||||
CPP=\"cl -nologo -EP\"
|
||||
|
||||
Configure has many other options. Use "configure --help" to see them all.
|
||||
|
||||
Once configure has finished, type "make". Note that you must be using
|
||||
|
@ -123,6 +133,12 @@ History
|
|||
|
||||
See the ChangeLog files for details.
|
||||
|
||||
3.0.10 ???-??-??
|
||||
Fix the N64 build on mips-sgi-irix6.5.
|
||||
Testsuite fixes for Tru64 Unix.
|
||||
Enable builds with Microsoft's compiler.
|
||||
Enable x86 builds with Sun's compiler.
|
||||
|
||||
3.0.9 Dec-31-09
|
||||
Add AVR32 and win64 ports. Add ARM softfp support.
|
||||
Many fixes for AIX, Solaris, HP-UX, *BSD.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.65 for libffi 3.0.9.
|
||||
# Generated by GNU Autoconf 2.65 for libffi 3.0.10rc0.
|
||||
#
|
||||
# Report bugs to <http://gcc.gnu.org/bugs.html>.
|
||||
#
|
||||
|
@ -701,8 +701,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='libffi'
|
||||
PACKAGE_TARNAME='libffi'
|
||||
PACKAGE_VERSION='3.0.9'
|
||||
PACKAGE_STRING='libffi 3.0.9'
|
||||
PACKAGE_VERSION='3.0.10rc0'
|
||||
PACKAGE_STRING='libffi 3.0.10rc0'
|
||||
PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html'
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
@ -1489,7 +1489,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures libffi 3.0.9 to adapt to many kinds of systems.
|
||||
\`configure' configures libffi 3.0.10rc0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1560,7 +1560,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of libffi 3.0.9:";;
|
||||
short | recursive ) echo "Configuration of libffi 3.0.10rc0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1667,7 +1667,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
libffi configure 3.0.9
|
||||
libffi configure 3.0.10rc0
|
||||
generated by GNU Autoconf 2.65
|
||||
|
||||
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
|
@ -2216,7 +2216,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by libffi $as_me 3.0.9, which was
|
||||
It was created by libffi $as_me 3.0.10rc0, which was
|
||||
generated by GNU Autoconf 2.65. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -3142,7 +3142,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='libffi'
|
||||
VERSION='3.0.9'
|
||||
VERSION='3.0.10rc0'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -11192,6 +11192,10 @@ case "$host" in
|
|||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
@ -13069,7 +13073,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by libffi $as_me 3.0.9, which was
|
||||
This file was extended by libffi $as_me 3.0.10rc0, which was
|
||||
generated by GNU Autoconf 2.65. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -13139,7 +13143,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
libffi config.status 3.0.9
|
||||
libffi config.status 3.0.10rc0
|
||||
configured by $0, generated by GNU Autoconf 2.65,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ dnl Process this with autoconf to create configure
|
|||
|
||||
AC_PREREQ(2.63)
|
||||
|
||||
AC_INIT([libffi], [3.0.9], [http://gcc.gnu.org/bugs.html])
|
||||
AC_INIT([libffi], [3.0.10rc0], [http://gcc.gnu.org/bugs.html])
|
||||
AC_CONFIG_HEADERS([fficonfig.h])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
@ -58,6 +58,10 @@ case "$host" in
|
|||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
amd64-*-freebsd*)
|
||||
TARGET=X86_64; TARGETDIR=x86
|
||||
;;
|
||||
|
||||
avr32*-*-*)
|
||||
TARGET=AVR32; TARGETDIR=avr32
|
||||
;;
|
||||
|
|
|
@ -4,7 +4,7 @@ from ../libffi/doc/libffi.texi.
|
|||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright (C) 2008 Red Hat, Inc.
|
||||
Copyright (C) 2008, 2010 Red Hat, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License as
|
||||
|
@ -27,7 +27,7 @@ libffi
|
|||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright (C) 2008 Red Hat, Inc.
|
||||
Copyright (C) 2008, 2010 Red Hat, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU General Public License as
|
||||
|
@ -89,6 +89,7 @@ File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduc
|
|||
* Types:: libffi type descriptions.
|
||||
* Multiple ABIs:: Different passing styles on one platform.
|
||||
* The Closure API:: Writing a generic function.
|
||||
* Closure Example:: A closure example.
|
||||
|
||||
|
||||
File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi
|
||||
|
@ -368,7 +369,7 @@ instance, the x86 platform has both `stdcall' and `fastcall' functions.
|
|||
necessarily platform-specific.
|
||||
|
||||
|
||||
File: libffi.info, Node: The Closure API, Prev: Multiple ABIs, Up: Using libffi
|
||||
File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multiple ABIs, Up: Using libffi
|
||||
|
||||
2.5 The Closure API
|
||||
===================
|
||||
|
@ -443,6 +444,62 @@ closure function:
|
|||
is deprecated, as it cannot handle the need for separate writable and
|
||||
executable addresses.
|
||||
|
||||
|
||||
File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using libffi
|
||||
|
||||
2.6 Closure Example
|
||||
===================
|
||||
|
||||
A trivial example that creates a new `puts' by binding `fputs' with
|
||||
`stdin'.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
/* Acts like puts with the file given at time of enclosure. */
|
||||
void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[],
|
||||
FILE *stream)
|
||||
{
|
||||
*ret = fputs(*(char **)args[0], stream);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
ffi_closure *closure;
|
||||
|
||||
int (*bound_puts)(char *);
|
||||
int rc;
|
||||
|
||||
/* Allocate closure and bound_puts */
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
|
||||
|
||||
if (closure)
|
||||
{
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_uint, args) == FFI_OK)
|
||||
{
|
||||
/* Initialize the closure, setting stream to stdout */
|
||||
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
||||
stdout, bound_puts) == FFI_OK)
|
||||
{
|
||||
rc = bound_puts("Hello World!");
|
||||
/* rc now holds the result of the call to fputs */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deallocate both closure, and bound_puts */
|
||||
ffi_closure_free(closure);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top
|
||||
|
||||
|
@ -516,18 +573,19 @@ Index
|
|||
|
||||
|
||||
Tag Table:
|
||||
Node: Top700
|
||||
Node: Introduction1436
|
||||
Node: Using libffi3072
|
||||
Node: The Basics3507
|
||||
Node: Simple Example6114
|
||||
Node: Types7141
|
||||
Node: Primitive Types7424
|
||||
Node: Structures9244
|
||||
Node: Type Example10104
|
||||
Node: Multiple ABIs11327
|
||||
Node: The Closure API11698
|
||||
Node: Missing Features14618
|
||||
Node: Index15111
|
||||
Node: Top706
|
||||
Node: Introduction1448
|
||||
Node: Using libffi3084
|
||||
Node: The Basics3570
|
||||
Node: Simple Example6177
|
||||
Node: Types7204
|
||||
Node: Primitive Types7487
|
||||
Node: Structures9307
|
||||
Node: Type Example10167
|
||||
Node: Multiple ABIs11390
|
||||
Node: The Closure API11761
|
||||
Node: Closure Example14705
|
||||
Node: Missing Features16264
|
||||
Node: Index16757
|
||||
|
||||
End Tag Table
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
This manual is for Libffi, a portable foreign-function interface
|
||||
library.
|
||||
|
||||
Copyright @copyright{} 2008 Red Hat, Inc.
|
||||
Copyright @copyright{} 2008, 2010 Red Hat, Inc.
|
||||
|
||||
@quotation
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
|
@ -106,6 +106,7 @@ values passed between the two languages.
|
|||
* Types:: libffi type descriptions.
|
||||
* Multiple ABIs:: Different passing styles on one platform.
|
||||
* The Closure API:: Writing a generic function.
|
||||
* Closure Example:: A closure example.
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -500,12 +501,66 @@ After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
|
|||
to the appropriate pointer-to-function type.
|
||||
@end defun
|
||||
|
||||
@c FIXME: example
|
||||
|
||||
You may see old code referring to @code{ffi_prep_closure}. This
|
||||
function is deprecated, as it cannot handle the need for separate
|
||||
writable and executable addresses.
|
||||
|
||||
@node Closure Example
|
||||
@section Closure Example
|
||||
|
||||
A trivial example that creates a new @code{puts} by binding
|
||||
@code{fputs} with @code{stdin}.
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <ffi.h>
|
||||
|
||||
/* Acts like puts with the file given at time of enclosure. */
|
||||
void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[],
|
||||
FILE *stream)
|
||||
@{
|
||||
*ret = fputs(*(char **)args[0], stream);
|
||||
@}
|
||||
|
||||
int main()
|
||||
@{
|
||||
ffi_cif cif;
|
||||
ffi_type *args[1];
|
||||
ffi_closure *closure;
|
||||
|
||||
int (*bound_puts)(char *);
|
||||
int rc;
|
||||
|
||||
/* Allocate closure and bound_puts */
|
||||
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
|
||||
|
||||
if (closure)
|
||||
@{
|
||||
/* Initialize the argument info vectors */
|
||||
args[0] = &ffi_type_pointer;
|
||||
|
||||
/* Initialize the cif */
|
||||
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||
&ffi_type_uint, args) == FFI_OK)
|
||||
@{
|
||||
/* Initialize the closure, setting stream to stdout */
|
||||
if (ffi_prep_closure_loc(closure, &cif, puts_binding,
|
||||
stdout, bound_puts) == FFI_OK)
|
||||
@{
|
||||
rc = bound_puts("Hello World!");
|
||||
/* rc now holds the result of the call to fputs */
|
||||
@}
|
||||
@}
|
||||
@}
|
||||
|
||||
/* Deallocate both closure, and bound_puts */
|
||||
ffi_closure_free(closure);
|
||||
|
||||
return 0;
|
||||
@}
|
||||
|
||||
@end example
|
||||
|
||||
|
||||
@node Missing Features
|
||||
@chapter Missing Features
|
||||
|
@ -525,6 +580,8 @@ There is no support for bit fields in structures.
|
|||
@item
|
||||
The closure API is
|
||||
|
||||
@c FIXME: ...
|
||||
|
||||
@item
|
||||
The ``raw'' API is undocumented.
|
||||
@c argument promotion?
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@set UPDATED 29 December 2009
|
||||
@set UPDATED-MONTH December 2009
|
||||
@set EDITION 3.0.9
|
||||
@set VERSION 3.0.9
|
||||
@set UPDATED 14 February 2008
|
||||
@set UPDATED-MONTH February 2008
|
||||
@set EDITION 3.0.8
|
||||
@set VERSION 3.0.8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@set UPDATED 29 December 2009
|
||||
@set UPDATED-MONTH December 2009
|
||||
@set EDITION 3.0.9
|
||||
@set VERSION 3.0.9
|
||||
@set UPDATED 14 February 2008
|
||||
@set UPDATED-MONTH February 2008
|
||||
@set EDITION 3.0.8
|
||||
@set VERSION 3.0.8
|
||||
|
|
|
@ -125,6 +125,9 @@
|
|||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
|
|
|
@ -251,6 +251,9 @@ size_t ffi_java_raw_size (ffi_cif *cif);
|
|||
|
||||
#if FFI_CLOSURES
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(8))
|
||||
#endif
|
||||
typedef struct {
|
||||
char tramp[FFI_TRAMPOLINE_SIZE];
|
||||
ffi_cif *cif;
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
#!/bin/sh
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the MSVC wrappificator.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Timothy Wall <twalljava@dev.java.net>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Daniel Witte <dwitte@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
#
|
||||
# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
|
||||
# format and translated into something sensible for cl or ml.
|
||||
#
|
||||
|
||||
# Disable specific warnings, and enable warnings-as-errors so we catch any
|
||||
# mistranslated args.
|
||||
nowarn="-wd4127 -wd4820 -wd4706 -wd4100 -wd4255 -wd4668 -wd4053 -wd4324"
|
||||
args="-nologo -W3 -WX $nowarn"
|
||||
md=-MD
|
||||
cl="cl"
|
||||
ml="ml"
|
||||
output=
|
||||
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1
|
||||
in
|
||||
-fexceptions)
|
||||
# Don't enable exceptions for now.
|
||||
#args="$args -EHac"
|
||||
shift 1
|
||||
;;
|
||||
-m32)
|
||||
shift 1
|
||||
;;
|
||||
-m64)
|
||||
cl="cl" # "$MSVC/x86_amd64/cl"
|
||||
ml="ml64" # "$MSVC/x86_amd64/ml64"
|
||||
shift 1
|
||||
;;
|
||||
-O*)
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
-g)
|
||||
# Can't specify -RTC1 or -Zi in opt. -Gy is ok. Use -OPT:REF?
|
||||
args="$args -D_DEBUG -RTC1 -Zi"
|
||||
md=-MDd
|
||||
shift 1
|
||||
;;
|
||||
-c)
|
||||
args="$args -c"
|
||||
args="$(echo $args | sed 's%/Fe%/Fo%g')"
|
||||
single="-c"
|
||||
shift 1
|
||||
;;
|
||||
-D*=*)
|
||||
name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
|
||||
value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
|
||||
args="$args -D${name}='$value'"
|
||||
defines="$defines -D${name}='$value'"
|
||||
shift 1
|
||||
;;
|
||||
-D*)
|
||||
args="$args $1"
|
||||
defines="$defines $1"
|
||||
shift 1
|
||||
;;
|
||||
-I)
|
||||
args="$args -I$2"
|
||||
includes="$includes -I$2"
|
||||
shift 2
|
||||
;;
|
||||
-I*)
|
||||
args="$args $1"
|
||||
includes="$includes $1"
|
||||
shift 1
|
||||
;;
|
||||
-W|-Wextra)
|
||||
# TODO map extra warnings
|
||||
shift 1
|
||||
;;
|
||||
-Wall)
|
||||
args="$args -Wall"
|
||||
shift 1
|
||||
;;
|
||||
-Werror)
|
||||
args="$args -WX"
|
||||
shift 1
|
||||
;;
|
||||
-W*)
|
||||
# TODO map specific warnings
|
||||
shift 1
|
||||
;;
|
||||
-S)
|
||||
args="$args -FAs"
|
||||
shift 1
|
||||
;;
|
||||
-o)
|
||||
outdir="$(dirname $2)"
|
||||
base="$(basename $2|sed 's/\.[^.]*//g')"
|
||||
if [ -n "$single" ]; then
|
||||
output="-Fo$2"
|
||||
else
|
||||
output="-Fe$2"
|
||||
fi
|
||||
if [ -n "$assembly" ]; then
|
||||
args="$args $output"
|
||||
else
|
||||
args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*.S)
|
||||
src=$1
|
||||
assembly="true"
|
||||
shift 1
|
||||
;;
|
||||
*.c)
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
# Assume it's an MSVC argument, and pass it through.
|
||||
args="$args $1"
|
||||
shift 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$assembly" ]; then
|
||||
if [ -z "$outdir" ]; then
|
||||
outdir="."
|
||||
fi
|
||||
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
|
||||
echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
|
||||
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
|
||||
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
|
||||
args="-nologo -safeseh $single $output $ppsrc"
|
||||
|
||||
echo "$ml $args"
|
||||
eval "\"$ml\" $args"
|
||||
result=$?
|
||||
|
||||
# required to fix ml64 broken output?
|
||||
#mv *.obj $outdir
|
||||
else
|
||||
args="$md $args"
|
||||
echo "$cl $args"
|
||||
eval "\"$cl\" $args"
|
||||
result=$?
|
||||
fi
|
||||
|
||||
exit $result
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
closures.c - Copyright (c) 2007, 2009 Red Hat, Inc.
|
||||
closures.c - Copyright (c) 2007 Red Hat, Inc.
|
||||
Copyright (C) 2007, 2009 Free Software Foundation, Inc
|
||||
|
||||
Code to allocate and deallocate memory for closures.
|
||||
|
@ -209,8 +209,6 @@ static int dlmunmap(void *, size_t);
|
|||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
|
||||
|
||||
#if FFI_MMAP_EXEC_SELINUX
|
||||
|
||||
/* A mutex used to synchronize access to *exec* variables in this file. */
|
||||
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -480,27 +478,6 @@ dlmmap (void *start, size_t length, int prot,
|
|||
return dlmmap_locked (start, length, prot, flags, offset);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void *
|
||||
dlmmap (void *start, size_t length, int prot,
|
||||
int flags, int fd, off_t offset)
|
||||
{
|
||||
|
||||
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
|
||||
|
||||
return mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Release memory at the given address, as well as the corresponding
|
||||
executable page if it's separate. */
|
||||
static int
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
n32.S - Copyright (c) 1996, 1998, 2005 Red Hat, Inc.
|
||||
n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010 Red Hat, Inc.
|
||||
|
||||
MIPS Foreign Function Interface
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
#define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG )
|
||||
|
||||
#ifdef linux
|
||||
#ifdef __GNUC__
|
||||
.abicalls
|
||||
#endif
|
||||
.text
|
||||
|
@ -529,7 +529,7 @@ cls_epilogue:
|
|||
.LFE2:
|
||||
.end ffi_closure_N32
|
||||
|
||||
#ifdef linux
|
||||
#ifdef __GNUC__
|
||||
.section .eh_frame,"aw",@progbits
|
||||
.Lframe1:
|
||||
.4byte .LECIE1-.LSCIE1 # length
|
||||
|
@ -586,6 +586,6 @@ cls_epilogue:
|
|||
.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
|
||||
.align EH_FRAME_ALIGN
|
||||
.LEFDE3:
|
||||
#endif /* linux */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
eabi.S - Copyright (c) 2004 Anthony Green
|
||||
|
||||
FR-V Assembly glue.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
|
||||
.globl ffi_prep_args_EABI
|
||||
|
||||
.text
|
||||
.p2align 4
|
||||
.globl ffi_call_EABI
|
||||
.type ffi_call_EABI, @function
|
||||
|
||||
# gr8 : ffi_prep_args
|
||||
# gr9 : &ecif
|
||||
# gr10: cif->bytes
|
||||
# gr11: fig->flags
|
||||
# gr12: ecif.rvalue
|
||||
# gr13: fn
|
||||
|
||||
ffi_call_EABI:
|
||||
addi sp, #-80, sp
|
||||
sti fp, @(sp, #24)
|
||||
addi sp, #24, fp
|
||||
movsg lr, gr5
|
||||
|
||||
/* Make room for the new arguments. */
|
||||
/* subi sp, fp, gr10 */
|
||||
|
||||
/* Store return address and incoming args on stack. */
|
||||
sti gr5, @(fp, #8)
|
||||
sti gr8, @(fp, #-4)
|
||||
sti gr9, @(fp, #-8)
|
||||
sti gr10, @(fp, #-12)
|
||||
sti gr11, @(fp, #-16)
|
||||
sti gr12, @(fp, #-20)
|
||||
sti gr13, @(fp, #-24)
|
||||
|
||||
sub sp, gr10, sp
|
||||
|
||||
/* Call ffi_prep_args. */
|
||||
ldi @(fp, #-4), gr4
|
||||
addi sp, #0, gr8
|
||||
ldi @(fp, #-8), gr9
|
||||
#ifdef __FRV_FDPIC__
|
||||
ldd @(gr4, gr0), gr14
|
||||
calll @(gr14, gr0)
|
||||
#else
|
||||
calll @(gr4, gr0)
|
||||
#endif
|
||||
|
||||
/* ffi_prep_args returns the new stack pointer. */
|
||||
mov gr8, gr4
|
||||
|
||||
ldi @(sp, #0), gr8
|
||||
ldi @(sp, #4), gr9
|
||||
ldi @(sp, #8), gr10
|
||||
ldi @(sp, #12), gr11
|
||||
ldi @(sp, #16), gr12
|
||||
ldi @(sp, #20), gr13
|
||||
|
||||
/* Always copy the return value pointer into the hidden
|
||||
parameter register. This is only strictly necessary
|
||||
when we're returning an aggregate type, but it doesn't
|
||||
hurt to do this all the time, and it saves a branch. */
|
||||
ldi @(fp, #-20), gr3
|
||||
|
||||
/* Use the ffi_prep_args return value for the new sp. */
|
||||
mov gr4, sp
|
||||
|
||||
/* Call the target function. */
|
||||
ldi @(fp, -24), gr4
|
||||
#ifdef __FRV_FDPIC__
|
||||
ldd @(gr4, gr0), gr14
|
||||
calll @(gr14, gr0)
|
||||
#else
|
||||
calll @(gr4, gr0)
|
||||
#endif
|
||||
|
||||
/* Store the result. */
|
||||
ldi @(fp, #-16), gr10 /* fig->flags */
|
||||
ldi @(fp, #-20), gr4 /* ecif.rvalue */
|
||||
|
||||
/* Is the return value stored in two registers? */
|
||||
cmpi gr10, #8, icc0
|
||||
bne icc0, 0, .L2
|
||||
/* Yes, save them. */
|
||||
sti gr8, @(gr4, #0)
|
||||
sti gr9, @(gr4, #4)
|
||||
bra .L3
|
||||
.L2:
|
||||
/* Is the return value a structure? */
|
||||
cmpi gr10, #-1, icc0
|
||||
beq icc0, 0, .L3
|
||||
/* No, save a 4 byte return value. */
|
||||
sti gr8, @(gr4, #0)
|
||||
.L3:
|
||||
|
||||
/* Restore the stack, and return. */
|
||||
ldi @(fp, 8), gr5
|
||||
ld @(fp, gr0), fp
|
||||
addi sp,#80,sp
|
||||
jmpl @(gr5,gr0)
|
||||
.size ffi_call_EABI, .-ffi_call_EABI
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (C) 2009 Anthony Green
|
||||
|
||||
Moxie Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments */
|
||||
|
||||
void *ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
register unsigned int i;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
register int count = 0;
|
||||
|
||||
p_argv = ecif->avalue;
|
||||
argp = stack;
|
||||
|
||||
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||
(i != 0);
|
||||
i--, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
z = (*p_arg)->size;
|
||||
|
||||
if ((*p_arg)->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
z = sizeof(void*);
|
||||
*(void **) argp = *p_argv;
|
||||
}
|
||||
/* if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
{
|
||||
if (count > 24)
|
||||
{
|
||||
// This is going on the stack. Turn it into a double.
|
||||
*(double *) argp = (double) *(float*)(* p_argv);
|
||||
z = sizeof(double);
|
||||
}
|
||||
else
|
||||
*(void **) argp = *(void **)(* p_argv);
|
||||
} */
|
||||
else if (z < sizeof(int))
|
||||
{
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(argp, *p_argv, z);
|
||||
}
|
||||
p_argv++;
|
||||
argp += z;
|
||||
count += z;
|
||||
}
|
||||
|
||||
return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
cif->flags = -1;
|
||||
else
|
||||
cif->flags = cif->rtype->size;
|
||||
|
||||
cif->bytes = ALIGN (cif->bytes, 8);
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
extern void ffi_call_EABI(void *(*)(char *, extended_cif *),
|
||||
extended_cif *,
|
||||
unsigned, unsigned,
|
||||
unsigned *,
|
||||
void (*fn)(void));
|
||||
|
||||
void ffi_call(ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if ((rvalue == NULL) &&
|
||||
(cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_EABI:
|
||||
ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
break;
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
|
||||
unsigned arg4, unsigned arg5, unsigned arg6)
|
||||
{
|
||||
/* This function is called by a trampoline. The trampoline stows a
|
||||
pointer to the ffi_closure object in gr7. We must save this
|
||||
pointer in a place that will persist while we do our work. */
|
||||
register ffi_closure *creg __asm__ ("gr7");
|
||||
ffi_closure *closure = creg;
|
||||
|
||||
/* Arguments that don't fit in registers are found on the stack
|
||||
at a fixed offset above the current frame pointer. */
|
||||
register char *frame_pointer __asm__ ("fp");
|
||||
char *stack_args = frame_pointer + 16;
|
||||
|
||||
/* Lay the register arguments down in a continuous chunk of memory. */
|
||||
unsigned register_args[6] =
|
||||
{ arg1, arg2, arg3, arg4, arg5, arg6 };
|
||||
|
||||
ffi_cif *cif = closure->cif;
|
||||
ffi_type **arg_types = cif->arg_types;
|
||||
void **avalue = alloca (cif->nargs * sizeof(void *));
|
||||
char *ptr = (char *) register_args;
|
||||
int i;
|
||||
|
||||
/* Find the address of each argument. */
|
||||
for (i = 0; i < cif->nargs; i++)
|
||||
{
|
||||
switch (arg_types[i]->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
avalue[i] = ptr + 3;
|
||||
break;
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
avalue[i] = ptr + 2;
|
||||
break;
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_FLOAT:
|
||||
avalue[i] = ptr;
|
||||
break;
|
||||
case FFI_TYPE_STRUCT:
|
||||
avalue[i] = *(void**)ptr;
|
||||
break;
|
||||
default:
|
||||
/* This is an 8-byte value. */
|
||||
avalue[i] = ptr;
|
||||
ptr += 4;
|
||||
break;
|
||||
}
|
||||
ptr += 4;
|
||||
|
||||
/* If we've handled more arguments than fit in registers,
|
||||
start looking at the those passed on the stack. */
|
||||
if (ptr == ((char *)register_args + (6*4)))
|
||||
ptr = stack_args;
|
||||
}
|
||||
|
||||
/* Invoke the closure. */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
||||
{
|
||||
/* The caller allocates space for the return structure, and
|
||||
passes a pointer to this space in gr3. Use this value directly
|
||||
as the return value. */
|
||||
register void *return_struct_ptr __asm__("gr3");
|
||||
(closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Allocate space for the return value and call the function. */
|
||||
long long rvalue;
|
||||
(closure->fun) (cif, &rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Functions return 4-byte or smaller results in gr8. 8-byte
|
||||
values also use gr9. We fill the both, even for small return
|
||||
values, just to avoid a branch. */
|
||||
asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue));
|
||||
asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));
|
||||
}
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
unsigned int *tramp = (unsigned int *) &closure->tramp[0];
|
||||
unsigned long fn = (long) ffi_closure_eabi;
|
||||
unsigned long cls = (long) codeloc;
|
||||
int i;
|
||||
|
||||
fn = (unsigned long) ffi_closure_eabi;
|
||||
|
||||
tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
|
||||
tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
|
||||
tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */
|
||||
tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */
|
||||
tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
|
||||
/* Cache flushing. */
|
||||
for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
|
||||
__asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),
|
||||
"r" (codeloc));
|
||||
|
||||
return FFI_OK;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 2009 Anthony Green
|
||||
Target configuration macros for Moxie
|
||||
|
||||
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
|
||||
|
||||
/* ---- System specific configurations ----------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
|
||||
#ifdef MOXIE
|
||||
FFI_EABI,
|
||||
FFI_DEFAULT_ABI = FFI_EABI,
|
||||
#endif
|
||||
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
#define FFI_CLOSURES 0
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
/* Trampolines are 5 4-byte instructions long. */
|
||||
#define FFI_TRAMPOLINE_SIZE (5*4)
|
||||
|
||||
#endif
|
|
@ -109,15 +109,12 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
|||
/* Perform a sanity check on the return type */
|
||||
FFI_ASSERT_VALID_TYPE(cif->rtype);
|
||||
|
||||
/* x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
||||
#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
|
||||
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
|
||||
#if !defined M68K && !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
|
||||
/* Make space for the return structure pointer */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
#ifdef SPARC
|
||||
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
|
||||
#endif
|
||||
#ifdef X86_DARWIN
|
||||
&& (cif->rtype->size > 8)
|
||||
#endif
|
||||
)
|
||||
bytes = STACK_ARG_SIZE(sizeof(void*));
|
||||
|
@ -134,7 +131,7 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
|
|||
check after the initialization. */
|
||||
FFI_ASSERT_VALID_TYPE(*ptr);
|
||||
|
||||
#if !defined __x86_64__ && !defined S390 && !defined PA
|
||||
#if !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
|
||||
#ifdef SPARC
|
||||
if (((*ptr)->type == FFI_TYPE_STRUCT
|
||||
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
|
||||
|
|
|
@ -148,13 +148,13 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
|||
/* 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:
|
||||
#ifdef X86
|
||||
case FFI_TYPE_STRUCT:
|
||||
#endif
|
||||
#if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_UINT16:
|
||||
|
@ -165,7 +165,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
|||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_SINT32:
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
|
@ -184,8 +183,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
|||
cif->flags = FFI_TYPE_SINT64;
|
||||
break;
|
||||
|
||||
#ifndef X86
|
||||
case FFI_TYPE_STRUCT:
|
||||
#ifndef X86
|
||||
if (cif->rtype->size == 1)
|
||||
{
|
||||
cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
|
||||
|
@ -207,15 +206,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
|||
cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cif->flags = FFI_TYPE_STRUCT;
|
||||
#ifdef X86_WIN64
|
||||
// allocate space for return value pointer
|
||||
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
#ifdef X86_WIN64
|
||||
|
@ -229,41 +226,36 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef X86_DARWIN
|
||||
cif->bytes = (cif->bytes + 15) & ~0xF;
|
||||
#endif
|
||||
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
|
||||
{
|
||||
unsigned int i;
|
||||
ffi_type **ptr;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
|
||||
#ifdef X86_WIN32
|
||||
extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
|
||||
#endif /* X86_WIN32 */
|
||||
#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 *, 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)
|
||||
|
@ -321,18 +313,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
|||
cif->flags, ecif.rvalue, fn);
|
||||
}
|
||||
break;
|
||||
#elif defined(X86_WIN32)
|
||||
case FFI_SYSV:
|
||||
case FFI_STDCALL:
|
||||
ffi_call_win32(ffi_prep_args, &ecif, 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;
|
||||
#ifdef X86_WIN32
|
||||
case FFI_STDCALL:
|
||||
ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
#endif /* X86_WIN32 */
|
||||
#endif /* X86_WIN64 */
|
||||
#endif
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
|
@ -342,6 +334,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
|||
|
||||
/** 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 *)
|
||||
|
@ -390,11 +384,8 @@ ffi_closure_win64_inner (ffi_closure *closure, void *args) {
|
|||
}
|
||||
|
||||
#else
|
||||
unsigned int FFI_HIDDEN
|
||||
ffi_closure_SYSV_inner (closure, respp, args)
|
||||
ffi_closure *closure;
|
||||
void **respp;
|
||||
void *args;
|
||||
unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
|
||||
ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
|
||||
{
|
||||
/* our various things... */
|
||||
ffi_cif *cif;
|
||||
|
@ -505,7 +496,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
|||
/* 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 char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned int __dis = __fun - (__ctx + 10); \
|
||||
|
@ -513,10 +504,10 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
|||
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
|
||||
*(unsigned char *) &__tramp[5] = 0xe9; \
|
||||
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
|
||||
})
|
||||
}
|
||||
|
||||
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
|
||||
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||
unsigned int __fun = (unsigned int)(FUN); \
|
||||
unsigned int __ctx = (unsigned int)(CTX); \
|
||||
unsigned int __dis = __fun - (__ctx + 10); \
|
||||
|
@ -527,7 +518,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
|
|||
*(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 */
|
||||
|
||||
|
@ -595,9 +586,9 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
|
|||
}
|
||||
|
||||
/* 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. */
|
||||
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--)
|
||||
{
|
||||
|
@ -627,16 +618,6 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
|
|||
* libffi-1.20, this is not the case.)
|
||||
*/
|
||||
|
||||
extern void
|
||||
ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
|
||||
unsigned, unsigned *, void (*fn)(void));
|
||||
|
||||
#ifdef X86_WIN32
|
||||
extern void
|
||||
ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
|
||||
unsigned, unsigned *, void (*fn)(void));
|
||||
#endif /* X86_WIN32 */
|
||||
|
||||
void
|
||||
ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
||||
{
|
||||
|
@ -660,16 +641,18 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
|
|||
|
||||
switch (cif->abi)
|
||||
{
|
||||
#ifdef X86_WIN32
|
||||
case FFI_SYSV:
|
||||
case FFI_STDCALL:
|
||||
ffi_call_win32(ffi_prep_args_raw, &ecif, 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;
|
||||
#ifdef X86_WIN32
|
||||
case FFI_STDCALL:
|
||||
ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
|
||||
ecif.rvalue, fn);
|
||||
break;
|
||||
#endif /* X86_WIN32 */
|
||||
#endif
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
|
|
|
@ -50,9 +50,10 @@ extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
|
|||
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.
|
||||
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). */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
ffitarget.h - Copyright (c) 1996-2003, 2010 Red Hat, Inc.
|
||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
|
||||
Target configuration macros for x86 and x86-64.
|
||||
|
@ -74,10 +74,10 @@ typedef enum ffi_abi {
|
|||
#else
|
||||
|
||||
/* ---- Intel x86 and AMD x86-64 - */
|
||||
#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
|
||||
#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__) || defined(__i386) || defined(__amd64))
|
||||
FFI_SYSV,
|
||||
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
|
||||
#ifdef __i386__
|
||||
#if defined(__i386__) || defined(__i386)
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_UNIX64,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009 Red Hat, Inc.
|
||||
Copyright (c) 2001 John Beniton
|
||||
Copyright (c) 2002 Ranjit Mathew
|
||||
Copyright (c) 2009 Daniel Witte
|
||||
|
||||
|
||||
X86 Foreign Function Interface
|
||||
|
@ -31,14 +32,371 @@
|
|||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
.386
|
||||
.MODEL FLAT, C
|
||||
|
||||
EXTRN ffi_closure_SYSV_inner:NEAR
|
||||
|
||||
_TEXT SEGMENT
|
||||
|
||||
ffi_call_win32 PROC NEAR,
|
||||
ffi_prep_args : NEAR PTR DWORD,
|
||||
ecif : NEAR PTR DWORD,
|
||||
cif_bytes : DWORD,
|
||||
cif_flags : DWORD,
|
||||
rvalue : NEAR PTR DWORD,
|
||||
fn : NEAR PTR DWORD
|
||||
|
||||
;; Make room for all of the new args.
|
||||
mov ecx, cif_bytes
|
||||
sub esp, ecx
|
||||
|
||||
mov eax, esp
|
||||
|
||||
;; Place all of the ffi_prep_args in position
|
||||
push ecif
|
||||
push eax
|
||||
call ffi_prep_args
|
||||
|
||||
;; Return stack to previous state and call the function
|
||||
add esp, 8
|
||||
|
||||
call fn
|
||||
|
||||
;; cdecl: we restore esp in the epilogue, so there's no need to
|
||||
;; remove the space we pushed for the args.
|
||||
;; stdcall: the callee has already cleaned the stack.
|
||||
|
||||
;; Load ecx with the return type code
|
||||
mov ecx, cif_flags
|
||||
|
||||
;; If the return value pointer is NULL, assume no return value.
|
||||
cmp rvalue, 0
|
||||
jne ca_jumptable
|
||||
|
||||
;; Even if there is no space for the return value, we are
|
||||
;; obliged to handle floating-point values.
|
||||
cmp ecx, FFI_TYPE_FLOAT
|
||||
jne ca_epilogue
|
||||
fstp st(0)
|
||||
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_jumptable:
|
||||
jmp [ca_jumpdata + 4 * ecx]
|
||||
ca_jumpdata:
|
||||
;; Do not insert anything here between label and jump table.
|
||||
dd offset ca_epilogue ;; FFI_TYPE_VOID
|
||||
dd offset ca_retint ;; FFI_TYPE_INT
|
||||
dd offset ca_retfloat ;; FFI_TYPE_FLOAT
|
||||
dd offset ca_retdouble ;; FFI_TYPE_DOUBLE
|
||||
dd offset ca_retlongdouble ;; FFI_TYPE_LONGDOUBLE
|
||||
dd offset ca_retint8 ;; FFI_TYPE_UINT8
|
||||
dd offset ca_retint8 ;; FFI_TYPE_SINT8
|
||||
dd offset ca_retint16 ;; FFI_TYPE_UINT16
|
||||
dd offset ca_retint16 ;; FFI_TYPE_SINT16
|
||||
dd offset ca_retint ;; FFI_TYPE_UINT32
|
||||
dd offset ca_retint ;; FFI_TYPE_SINT32
|
||||
dd offset ca_retint64 ;; FFI_TYPE_UINT64
|
||||
dd offset ca_retint64 ;; FFI_TYPE_SINT64
|
||||
dd offset ca_epilogue ;; FFI_TYPE_STRUCT
|
||||
dd offset ca_retint ;; FFI_TYPE_POINTER
|
||||
dd offset ca_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B
|
||||
dd offset ca_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B
|
||||
dd offset ca_retint ;; FFI_TYPE_SMALL_STRUCT_4B
|
||||
|
||||
ca_retint8:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
mov [ecx + 0], al
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_retint16:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
mov [ecx + 0], ax
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_retint:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
mov [ecx + 0], eax
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_retint64:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
mov [ecx + 0], eax
|
||||
mov [ecx + 4], edx
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_retfloat:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
fstp DWORD PTR [ecx]
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_retdouble:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
fstp QWORD PTR [ecx]
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_retlongdouble:
|
||||
;; Load %ecx with the pointer to storage for the return value
|
||||
mov ecx, rvalue
|
||||
fstp TBYTE PTR [ecx]
|
||||
jmp ca_epilogue
|
||||
|
||||
ca_epilogue:
|
||||
;; Epilogue code is autogenerated.
|
||||
ret
|
||||
ffi_call_win32 ENDP
|
||||
|
||||
ffi_closure_SYSV PROC NEAR FORCEFRAME
|
||||
;; the ffi_closure ctx is passed in eax by the trampoline.
|
||||
|
||||
sub esp, 40
|
||||
lea edx, [ebp - 24]
|
||||
mov [ebp - 12], edx ;; resp
|
||||
lea edx, [ebp + 8]
|
||||
mov [esp + 8], edx ;; args
|
||||
lea edx, [ebp - 12]
|
||||
mov [esp + 4], edx ;; &resp
|
||||
mov [esp], eax ;; closure
|
||||
call ffi_closure_SYSV_inner
|
||||
mov ecx, [ebp - 12]
|
||||
|
||||
cs_jumptable:
|
||||
jmp [cs_jumpdata + 4 * eax]
|
||||
cs_jumpdata:
|
||||
;; Do not insert anything here between the label and jump table.
|
||||
dd offset cs_epilogue ;; FFI_TYPE_VOID
|
||||
dd offset cs_retint ;; FFI_TYPE_INT
|
||||
dd offset cs_retfloat ;; FFI_TYPE_FLOAT
|
||||
dd offset cs_retdouble ;; FFI_TYPE_DOUBLE
|
||||
dd offset cs_retlongdouble ;; FFI_TYPE_LONGDOUBLE
|
||||
dd offset cs_retint8 ;; FFI_TYPE_UINT8
|
||||
dd offset cs_retint8 ;; FFI_TYPE_SINT8
|
||||
dd offset cs_retint16 ;; FFI_TYPE_UINT16
|
||||
dd offset cs_retint16 ;; FFI_TYPE_SINT16
|
||||
dd offset cs_retint ;; FFI_TYPE_UINT32
|
||||
dd offset cs_retint ;; FFI_TYPE_SINT32
|
||||
dd offset cs_retint64 ;; FFI_TYPE_UINT64
|
||||
dd offset cs_retint64 ;; FFI_TYPE_SINT64
|
||||
dd offset cs_retstruct ;; FFI_TYPE_STRUCT
|
||||
dd offset cs_retint ;; FFI_TYPE_POINTER
|
||||
dd offset cs_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B
|
||||
dd offset cs_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B
|
||||
dd offset cs_retint ;; FFI_TYPE_SMALL_STRUCT_4B
|
||||
|
||||
cs_retint8:
|
||||
mov al, [ecx]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retint16:
|
||||
mov ax, [ecx]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retint:
|
||||
mov eax, [ecx]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retint64:
|
||||
mov eax, [ecx + 0]
|
||||
mov edx, [ecx + 4]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retfloat:
|
||||
fld DWORD PTR [ecx]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retdouble:
|
||||
fld QWORD PTR [ecx]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retlongdouble:
|
||||
fld TBYTE PTR [ecx]
|
||||
jmp cs_epilogue
|
||||
|
||||
cs_retstruct:
|
||||
;; Caller expects us to pop struct return value pointer hidden arg.
|
||||
;; Epilogue code is autogenerated.
|
||||
ret 4
|
||||
|
||||
cs_epilogue:
|
||||
;; Epilogue code is autogenerated.
|
||||
ret
|
||||
ffi_closure_SYSV ENDP
|
||||
|
||||
#if !FFI_NO_RAW_API
|
||||
|
||||
#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3)
|
||||
#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
|
||||
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
|
||||
#define CIF_FLAGS_OFFSET 20
|
||||
|
||||
ffi_closure_raw_SYSV PROC NEAR USES esi
|
||||
;; the ffi_closure ctx is passed in eax by the trampoline.
|
||||
|
||||
sub esp, 40
|
||||
mov esi, [eax + RAW_CLOSURE_CIF_OFFSET] ;; closure->cif
|
||||
mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data
|
||||
mov [esp + 12], edx ;; user_data
|
||||
lea edx, [ebp + 8]
|
||||
mov [esp + 8], edx ;; raw_args
|
||||
lea edx, [ebp - 24]
|
||||
mov [esp + 4], edx ;; &res
|
||||
mov [esp], esi ;; cif
|
||||
call DWORD PTR [eax + RAW_CLOSURE_FUN_OFFSET] ;; closure->fun
|
||||
mov eax, [esi + CIF_FLAGS_OFFSET] ;; cif->flags
|
||||
lea ecx, [ebp - 24]
|
||||
|
||||
cr_jumptable:
|
||||
jmp [cr_jumpdata + 4 * eax]
|
||||
cr_jumpdata:
|
||||
;; Do not insert anything here between the label and jump table.
|
||||
dd offset cr_epilogue ;; FFI_TYPE_VOID
|
||||
dd offset cr_retint ;; FFI_TYPE_INT
|
||||
dd offset cr_retfloat ;; FFI_TYPE_FLOAT
|
||||
dd offset cr_retdouble ;; FFI_TYPE_DOUBLE
|
||||
dd offset cr_retlongdouble ;; FFI_TYPE_LONGDOUBLE
|
||||
dd offset cr_retint8 ;; FFI_TYPE_UINT8
|
||||
dd offset cr_retint8 ;; FFI_TYPE_SINT8
|
||||
dd offset cr_retint16 ;; FFI_TYPE_UINT16
|
||||
dd offset cr_retint16 ;; FFI_TYPE_SINT16
|
||||
dd offset cr_retint ;; FFI_TYPE_UINT32
|
||||
dd offset cr_retint ;; FFI_TYPE_SINT32
|
||||
dd offset cr_retint64 ;; FFI_TYPE_UINT64
|
||||
dd offset cr_retint64 ;; FFI_TYPE_SINT64
|
||||
dd offset cr_epilogue ;; FFI_TYPE_STRUCT
|
||||
dd offset cr_retint ;; FFI_TYPE_POINTER
|
||||
dd offset cr_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B
|
||||
dd offset cr_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B
|
||||
dd offset cr_retint ;; FFI_TYPE_SMALL_STRUCT_4B
|
||||
|
||||
cr_retint8:
|
||||
mov al, [ecx]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_retint16:
|
||||
mov ax, [ecx]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_retint:
|
||||
mov eax, [ecx]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_retint64:
|
||||
mov eax, [ecx + 0]
|
||||
mov edx, [ecx + 4]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_retfloat:
|
||||
fld DWORD PTR [ecx]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_retdouble:
|
||||
fld QWORD PTR [ecx]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_retlongdouble:
|
||||
fld TBYTE PTR [ecx]
|
||||
jmp cr_epilogue
|
||||
|
||||
cr_epilogue:
|
||||
;; Epilogue code is autogenerated.
|
||||
ret
|
||||
ffi_closure_raw_SYSV ENDP
|
||||
|
||||
#endif /* !FFI_NO_RAW_API */
|
||||
|
||||
ffi_closure_STDCALL PROC NEAR FORCEFRAME
|
||||
;; the ffi_closure ctx is passed in eax by the trampoline.
|
||||
|
||||
sub esp, 40
|
||||
lea edx, [ebp - 24]
|
||||
mov [ebp - 12], edx ;; resp
|
||||
lea edx, [ebp + 12] ;; account for stub return address on stack
|
||||
mov [esp + 8], edx ;; args
|
||||
lea edx, [ebp - 12]
|
||||
mov [esp + 4], edx ;; &resp
|
||||
mov [esp], eax ;; closure
|
||||
call ffi_closure_SYSV_inner
|
||||
mov ecx, [ebp - 12]
|
||||
|
||||
cd_jumptable:
|
||||
jmp [cd_jumpdata + 4 * eax]
|
||||
cd_jumpdata:
|
||||
;; Do not insert anything here between the label and jump table.
|
||||
dd offset cd_epilogue ;; FFI_TYPE_VOID
|
||||
dd offset cd_retint ;; FFI_TYPE_INT
|
||||
dd offset cd_retfloat ;; FFI_TYPE_FLOAT
|
||||
dd offset cd_retdouble ;; FFI_TYPE_DOUBLE
|
||||
dd offset cd_retlongdouble ;; FFI_TYPE_LONGDOUBLE
|
||||
dd offset cd_retint8 ;; FFI_TYPE_UINT8
|
||||
dd offset cd_retint8 ;; FFI_TYPE_SINT8
|
||||
dd offset cd_retint16 ;; FFI_TYPE_UINT16
|
||||
dd offset cd_retint16 ;; FFI_TYPE_SINT16
|
||||
dd offset cd_retint ;; FFI_TYPE_UINT32
|
||||
dd offset cd_retint ;; FFI_TYPE_SINT32
|
||||
dd offset cd_retint64 ;; FFI_TYPE_UINT64
|
||||
dd offset cd_retint64 ;; FFI_TYPE_SINT64
|
||||
dd offset cd_epilogue ;; FFI_TYPE_STRUCT
|
||||
dd offset cd_retint ;; FFI_TYPE_POINTER
|
||||
dd offset cd_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B
|
||||
dd offset cd_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B
|
||||
dd offset cd_retint ;; FFI_TYPE_SMALL_STRUCT_4B
|
||||
|
||||
cd_retint8:
|
||||
mov al, [ecx]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_retint16:
|
||||
mov ax, [ecx]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_retint:
|
||||
mov eax, [ecx]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_retint64:
|
||||
mov eax, [ecx + 0]
|
||||
mov edx, [ecx + 4]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_retfloat:
|
||||
fld DWORD PTR [ecx]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_retdouble:
|
||||
fld QWORD PTR [ecx]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_retlongdouble:
|
||||
fld TBYTE PTR [ecx]
|
||||
jmp cd_epilogue
|
||||
|
||||
cd_epilogue:
|
||||
;; Epilogue code is autogenerated.
|
||||
ret
|
||||
ffi_closure_STDCALL ENDP
|
||||
|
||||
_TEXT ENDS
|
||||
END
|
||||
|
||||
#else
|
||||
|
||||
.text
|
||||
|
||||
# This assumes we are using gas.
|
||||
.balign 16
|
||||
.globl _ffi_call_SYSV
|
||||
.def _ffi_call_SYSV; .scl 2; .type 32; .endef
|
||||
_ffi_call_SYSV:
|
||||
.globl _ffi_call_win32
|
||||
.def _ffi_call_win32; .scl 2; .type 32; .endef
|
||||
_ffi_call_win32:
|
||||
.LFB1:
|
||||
pushl %ebp
|
||||
.LCFI0:
|
||||
|
@ -61,8 +419,10 @@ _ffi_call_SYSV:
|
|||
# FIXME: Align the stack to a 128-bit boundary to avoid
|
||||
# potential performance hits.
|
||||
|
||||
call *28(%ebp)
|
||||
call *28(%ebp)
|
||||
|
||||
# stdcall functions pop arguments off the stack themselves
|
||||
|
||||
# Load %ecx with the return type code
|
||||
movl 20(%ebp),%ecx
|
||||
|
||||
|
@ -181,162 +541,9 @@ _ffi_call_SYSV:
|
|||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.ffi_call_SYSV_end:
|
||||
.ffi_call_win32_end:
|
||||
.LFE1:
|
||||
|
||||
# This assumes we are using gas.
|
||||
.balign 16
|
||||
.globl _ffi_call_STDCALL
|
||||
.def _ffi_call_STDCALL; .scl 2; .type 32; .endef
|
||||
_ffi_call_STDCALL:
|
||||
.LFB2:
|
||||
pushl %ebp
|
||||
.LCFI2:
|
||||
movl %esp,%ebp
|
||||
.LCFI3:
|
||||
# Make room for all of the new args.
|
||||
movl 16(%ebp),%ecx
|
||||
subl %ecx,%esp
|
||||
|
||||
movl %esp,%eax
|
||||
|
||||
# Place all of the ffi_prep_args in position
|
||||
pushl 12(%ebp)
|
||||
pushl %eax
|
||||
call *8(%ebp)
|
||||
|
||||
# Return stack to previous state and call the function
|
||||
addl $8,%esp
|
||||
|
||||
# FIXME: Align the stack to a 128-bit boundary to avoid
|
||||
# potential performance hits.
|
||||
|
||||
call *28(%ebp)
|
||||
|
||||
# stdcall functions pop arguments off the stack themselves
|
||||
|
||||
# Load %ecx with the return type code
|
||||
movl 20(%ebp),%ecx
|
||||
|
||||
# If the return value pointer is NULL, assume no return value.
|
||||
cmpl $0,24(%ebp)
|
||||
jne 0f
|
||||
|
||||
# Even if there is no space for the return value, we are
|
||||
# obliged to handle floating-point values.
|
||||
cmpl $FFI_TYPE_FLOAT,%ecx
|
||||
jne .Lsc_noretval
|
||||
fstp %st(0)
|
||||
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
0:
|
||||
call 1f
|
||||
# Do not insert anything here between the call and the jump table.
|
||||
.Lsc_store_table:
|
||||
.long .Lsc_noretval /* FFI_TYPE_VOID */
|
||||
.long .Lsc_retint /* FFI_TYPE_INT */
|
||||
.long .Lsc_retfloat /* FFI_TYPE_FLOAT */
|
||||
.long .Lsc_retdouble /* FFI_TYPE_DOUBLE */
|
||||
.long .Lsc_retlongdouble /* FFI_TYPE_LONGDOUBLE */
|
||||
.long .Lsc_retuint8 /* FFI_TYPE_UINT8 */
|
||||
.long .Lsc_retsint8 /* FFI_TYPE_SINT8 */
|
||||
.long .Lsc_retuint16 /* FFI_TYPE_UINT16 */
|
||||
.long .Lsc_retsint16 /* FFI_TYPE_SINT16 */
|
||||
.long .Lsc_retint /* FFI_TYPE_UINT32 */
|
||||
.long .Lsc_retint /* FFI_TYPE_SINT32 */
|
||||
.long .Lsc_retint64 /* FFI_TYPE_UINT64 */
|
||||
.long .Lsc_retint64 /* FFI_TYPE_SINT64 */
|
||||
.long .Lsc_retstruct /* FFI_TYPE_STRUCT */
|
||||
.long .Lsc_retint /* FFI_TYPE_POINTER */
|
||||
.long .Lsc_retstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */
|
||||
.long .Lsc_retstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */
|
||||
.long .Lsc_retstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */
|
||||
|
||||
1:
|
||||
add %ecx, %ecx
|
||||
add %ecx, %ecx
|
||||
add (%esp),%ecx
|
||||
add $4, %esp
|
||||
jmp *(%ecx)
|
||||
|
||||
/* Sign/zero extend as appropriate. */
|
||||
.Lsc_retsint8:
|
||||
movsbl %al, %eax
|
||||
jmp .Lsc_retint
|
||||
|
||||
.Lsc_retsint16:
|
||||
movswl %ax, %eax
|
||||
jmp .Lsc_retint
|
||||
|
||||
.Lsc_retuint8:
|
||||
movzbl %al, %eax
|
||||
jmp .Lsc_retint
|
||||
|
||||
.Lsc_retuint16:
|
||||
movzwl %ax, %eax
|
||||
jmp .Lsc_retint
|
||||
|
||||
.Lsc_retint:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
movl %eax,0(%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retfloat:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
fstps (%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retdouble:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
fstpl (%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retlongdouble:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
fstpt (%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retint64:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
movl %eax,0(%ecx)
|
||||
movl %edx,4(%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retstruct1b:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
movb %al,0(%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retstruct2b:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
movw %ax,0(%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retstruct4b:
|
||||
# Load %ecx with the pointer to storage for the return value
|
||||
movl 24(%ebp),%ecx
|
||||
movl %eax,0(%ecx)
|
||||
jmp .Lsc_epilogue
|
||||
|
||||
.Lsc_retstruct:
|
||||
# Nothing to do!
|
||||
|
||||
.Lsc_noretval:
|
||||
.Lsc_epilogue:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
.ffi_call_STDCALL_end:
|
||||
.LFE2:
|
||||
|
||||
# This assumes we are using gas.
|
||||
.balign 16
|
||||
.globl _ffi_closure_SYSV
|
||||
|
@ -742,38 +949,6 @@ _ffi_closure_STDCALL:
|
|||
.LEFDE1:
|
||||
|
||||
|
||||
.LSFDE2:
|
||||
.long .LEFDE2-.LASFDE2 /* FDE Length */
|
||||
.LASFDE2:
|
||||
.long .LASFDE2-.Lframe1 /* FDE CIE offset */
|
||||
#if defined __PIC__ && defined HAVE_AS_X86_PCREL
|
||||
.long .LFB2-. /* FDE initial location */
|
||||
#else
|
||||
.long .LFB2
|
||||
#endif
|
||||
.long .LFE2-.LFB2 /* FDE address range */
|
||||
#ifdef __PIC__
|
||||
.byte 0x0 /* .uleb128 0x0; Augmentation size */
|
||||
#endif
|
||||
/* DW_CFA_xxx CFI instructions go here. */
|
||||
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.long .LCFI2-.LFB2
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
|
||||
.byte 0x8 /* .uleb128 0x8 */
|
||||
.byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
|
||||
.byte 0x2 /* .uleb128 0x2 */
|
||||
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.long .LCFI3-.LCFI2
|
||||
.byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
|
||||
.byte 0x5 /* .uleb128 0x5 */
|
||||
|
||||
/* End of DW_CFA_xxx CFI instructions. */
|
||||
.align 4
|
||||
.LEFDE2:
|
||||
|
||||
|
||||
.LSFDE3:
|
||||
.long .LEFDE3-.LASFDE3 /* FDE Length */
|
||||
.LASFDE3:
|
||||
|
@ -875,3 +1050,6 @@ _ffi_closure_STDCALL:
|
|||
/* End of DW_CFA_xxx CFI instructions. */
|
||||
.align 4
|
||||
.LEFDE5:
|
||||
|
||||
#endif /* !_MSC_VER */
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Copyright (C) 2003, 2005, 2008, 2009 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003, 2005, 2008, 2009, 2010 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 2 of the License, or
|
||||
# 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,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Originator: <hos@tamanegi.org> 20031203 */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct cls_struct_align {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
Originator: Blake Chaffin */
|
||||
|
||||
/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-do run { xfail arm*-*-* strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
|
||||
/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Originator: <andreast@gcc.gnu.org> 20030828 */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
|
||||
|
|
|
@ -60,6 +60,18 @@
|
|||
#define PRIuLL "llu"
|
||||
#endif
|
||||
|
||||
/* Tru64 UNIX kludge. */
|
||||
#if defined(__alpha__) && defined(__osf__)
|
||||
/* Tru64 UNIX V4.0 doesn't support %lld/%lld, but long is 64-bit. */
|
||||
#undef PRIdLL
|
||||
#define PRIdLL "ld"
|
||||
#undef PRIuLL
|
||||
#define PRIuLL "lu"
|
||||
#define PRId64 "ld"
|
||||
#define PRIu64 "lu"
|
||||
#define PRIuPTR "lu"
|
||||
#endif
|
||||
|
||||
/* PA HP-UX kludge. */
|
||||
#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
|
||||
#define PRIuPTR "lu"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
Originator: <andreast@gcc.gnu.org> 20050222 */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
static long long return_ll(int ll0, long long ll1, int ll2)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
Originator: Blake Chaffin 6/21/2007 */
|
||||
|
||||
/* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
|
||||
/* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */
|
||||
#include "ffitest.h"
|
||||
|
||||
typedef struct struct_72byte {
|
||||
|
|
|
@ -84,7 +84,7 @@ allocate_mmap (size_t size)
|
|||
MAP_PRIVATE, dev_zero_fd, 0);
|
||||
#endif
|
||||
|
||||
if (page == MAP_FAILED)
|
||||
if (page == (char *) MAP_FAILED)
|
||||
{
|
||||
perror ("virtual memory exhausted");
|
||||
exit (1);
|
||||
|
|
Loading…
Reference in New Issue