Merge pull request #238 from KubaKaszycki/master
authorAnthony Green <green@moxielogic.com>
Thu, 16 Mar 2017 11:50:07 +0000 (07:50 -0400)
committerGitHub <noreply@github.com>
Thu, 16 Mar 2017 11:50:07 +0000 (07:50 -0400)
Update README with a new port

33 files changed:
.travis.yml
.travis/install.sh [new file with mode: 0755]
Makefile.am
README
acinclude.m4
configure.ac
configure.host
doc/libffi.texi
generate-darwin-source-and-headers.py
include/Makefile.am
include/ffi.h.in
include/ffi_common.h
libffi.map.in [new file with mode: 0644]
libffi.pc.in
libtool-version
src/aarch64/ffi.c
src/aarch64/ffitarget.h
src/arc/ffi.c
src/closures.c
src/dlmalloc.c
src/m68k/sysv.S
src/microblaze/ffi.c
src/mips/n32.S
src/mips/o32.S
src/powerpc/darwin_closure.S
src/x86/ffi64.c
src/x86/ffiw64.c
src/x86/win64.S
testsuite/lib/libffi.exp
testsuite/libffi.call/cls_dbls_struct.c
testsuite/libffi.call/ffitest.h
testsuite/libffi.call/float2.c
testsuite/libffi.call/unwindtest.cc

index 289076a..5411673 100644 (file)
@@ -1,23 +1,27 @@
+---
+sudo: required
+
 language: cpp
+
+os:
+  - linux
 compiler:
   - gcc
   - clang
-env:
-  -
-  - HOST=i386-pc-linux-gnu
 matrix:
-  exclude:
-    - compiler: clang
+  include:
+    - os: linux
+      compiler: gcc
       env: HOST=i386-pc-linux-gnu
 
-before_script:
-  - sudo apt-get update
-  - sudo apt-get install dejagnu texinfo
-  - if [ "$HOST" = i386-pc-linux-gnu ] ; then sudo apt-get install gcc-multilib g++-multilib && CC="$CC -m32" && CXX="$CXX -m32" ; fi
+install:
+  - ./.travis/install.sh
 
 script:
   - ./autogen.sh
+  - if test x"$HOST" = x"i386-pc-linux-gnu"; then CC="$CC -m32"; CXX="$CXX -m32"; fi
   - ./configure ${HOST+--host=$HOST}
   - make
   - make dist
   - make check
+  - cat */testsuite/libffi.log
diff --git a/.travis/install.sh b/.travis/install.sh
new file mode 100755 (executable)
index 0000000..67b5104
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+if [[ $TRAVIS_OS_NAME != 'linux' ]]; then
+  brew update
+  # fix an issue with libtool on travis by reinstalling it
+  brew uninstall libtool;
+  brew install libtool dejagnu;
+else
+  sudo apt-get update
+  sudo apt-get install dejagnu texinfo
+  if [ "$HOST" = i386-pc-linux-gnu ] ; then
+      sudo apt-get install gcc-multilib g++-multilib;
+  fi
+fi
index 20fa382..4ddd12d 100644 (file)
@@ -155,7 +155,6 @@ EXTRA_libffi_la_SOURCES = \
 
 TARGET_OBJ = @TARGET_OBJ@
 libffi_la_LIBADD = $(TARGET_OBJ)
-libffi_la_DEPENDENCIES = $(TARGET_OBJ)
 
 libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
 EXTRA_libffi_convenience_la_SOURCES = $(EXTRA_libffi_la_SOURCES)
@@ -172,7 +171,32 @@ if FFI_DEBUG
 AM_CFLAGS += -DFFI_DEBUG
 endif
 
-libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS)
+if LIBFFI_BUILD_VERSIONED_SHLIB
+if LIBFFI_BUILD_VERSIONED_SHLIB_GNU
+libffi_version_script = -Wl,--version-script,libffi.map
+libffi_version_dep = libffi.map
+endif
+if LIBFFI_BUILD_VERSIONED_SHLIB_SUN
+libffi_version_script = -Wl,-M,libffi.map-sun
+libffi_version_dep = libffi.map-sun
+libffi.map-sun : libffi.map $(top_srcdir)/../contrib/make_sunver.pl \
+                $(libffi_la_OBJECTS) $(libffi_la_LIBADD)
+       perl $(top_srcdir)/../contrib/make_sunver.pl libffi.map \
+        `echo $(libffi_la_OBJECTS) $(libffi_la_LIBADD) | \
+           sed 's,\([^/        ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
+        > $@ || (rm -f $@ ; exit 1)
+endif
+else
+libffi_version_script =
+libffi_version_dep =
+endif
+libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
+
+libffi.map: $(top_srcdir)/libffi.map.in
+       $(COMPILE) -D$(TARGET) -E -x assembler-with-cpp -o $@ $<
+
+libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
+libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
 
 AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
 AM_CCASFLAGS = $(AM_CPPFLAGS)
diff --git a/README b/README
index e8da7f6..8ebe74d 100644 (file)
--- a/README
+++ b/README
@@ -145,6 +145,9 @@ 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.
 
+If you don't want to build documentation, use the --disable-docs
+configure switch.
+
 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:
@@ -181,7 +184,7 @@ To install the library and header files, type "make install".
 History
 =======
 
-See the git log for details at http://github.com/atgreen/libffi.
+See the git log for details at http://github.com/libffi/libffi.
 
 4.0 TBD
         New API in support of GO closures.
index 3e8f8ba..5df37a8 100644 (file)
@@ -90,3 +90,384 @@ if test $ac_cv_func_mmap_anon = yes; then
            [Define if mmap with MAP_ANON(YMOUS) works.])
 fi
 ])
+
+dnl ----------------------------------------------------------------------
+dnl This whole bit snagged from libstdc++-v3, via libatomic.
+
+dnl
+dnl LIBFFI_ENABLE
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
+dnl
+dnl See docs/html/17_intro/configury.html#enable for documentation.
+dnl
+m4_define([LIBFFI_ENABLE],[dnl
+m4_define([_g_switch],[--enable-$1])dnl
+m4_define([_g_help],[AC_HELP_STRING(_g_switch$3,[$4 @<:@default=$2@:>@])])dnl
+ AC_ARG_ENABLE($1,_g_help,
+  m4_bmatch([$5],
+   [^permit ],
+     [[
+      case "$enableval" in
+       m4_bpatsubst([$5],[permit ])) ;;
+       *) AC_MSG_ERROR(Unknown argument to enable/disable $1) ;;
+          dnl Idea for future:  generate a URL pointing to
+          dnl "onlinedocs/configopts.html#whatever"
+      esac
+     ]],
+   [^$],
+     [[
+      case "$enableval" in
+       yes|no) ;;
+       *) AC_MSG_ERROR(Argument to enable/disable $1 must be yes or no) ;;
+      esac
+     ]],
+   [[$5]]),
+  [enable_]m4_bpatsubst([$1],-,_)[=][$2])
+m4_undefine([_g_switch])dnl
+m4_undefine([_g_help])dnl
+])
+
+dnl
+dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
+dnl the native linker is in use, all variables will be defined to something
+dnl safe (like an empty string).
+dnl
+dnl Defines:
+dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
+dnl  OPT_LDFLAGS='-Wl,-O1' if possible
+dnl  LD (as a side effect of testing)
+dnl Sets:
+dnl  with_gnu_ld
+dnl  libat_ld_is_gold (possibly)
+dnl  libat_gnu_ld_version (possibly)
+dnl
+dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
+dnl set libat_gnu_ld_version to 12345.  Zeros cause problems.
+dnl
+AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
+  # If we're not using GNU ld, then there's no point in even trying these
+  # tests.  Check for that first.  We should have already tested for gld
+  # by now (in libtool), but require it now just to be safe...
+  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+  AC_REQUIRE([AC_PROG_LD])
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # The name set by libtool depends on the version of libtool.  Shame on us
+  # for depending on an impl detail, but c'est la vie.  Older versions used
+  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+  # set (hence we're using an older libtool), then set it.
+  if test x${with_gnu_ld+set} != xset; then
+    if test x${ac_cv_prog_gnu_ld+set} != xset; then
+      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+      with_gnu_ld=no
+    else
+      with_gnu_ld=$ac_cv_prog_gnu_ld
+    fi
+  fi
+
+  # Start by getting the version number.  I think the libtool test already
+  # does some of this, but throws away the result.
+  libat_ld_is_gold=no
+  if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
+    libat_ld_is_gold=yes
+  fi
+  changequote(,)
+  ldver=`$LD --version 2>/dev/null |
+         sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
+  changequote([,])
+  libat_gnu_ld_version=`echo $ldver | \
+         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
+
+  # Set --gc-sections.
+  if test "$with_gnu_ld" = "notbroken"; then
+    # GNU ld it is!  Joy and bunny rabbits!
+
+    # All these tests are for C++; save the language and the compiler flags.
+    # Need to do this so that g++ won't try to link in libstdc++
+    ac_test_CFLAGS="${CFLAGS+set}"
+    ac_save_CFLAGS="$CFLAGS"
+    CFLAGS='-x c++  -Wl,--gc-sections'
+
+    # Check for -Wl,--gc-sections
+    # XXX This test is broken at the moment, as symbols required for linking
+    # are now in libsupc++ (not built yet).  In addition, this test has
+    # cored on solaris in the past.  In addition, --gc-sections doesn't
+    # really work at the moment (keeps on discarding used sections, first
+    # .eh_frame and now some of the glibc sections for iconv).
+    # Bzzzzt.  Thanks for playing, maybe next time.
+    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
+    AC_TRY_RUN([
+     int main(void)
+     {
+       try { throw 1; }
+       catch (...) { };
+       return 0;
+     }
+    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
+    if test "$ac_test_CFLAGS" = set; then
+      CFLAGS="$ac_save_CFLAGS"
+    else
+      # this is the suspicious part
+      CFLAGS=''
+    fi
+    if test "$ac_sectionLDflags" = "yes"; then
+      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+    fi
+    AC_MSG_RESULT($ac_sectionLDflags)
+  fi
+
+  # Set linker optimization flags.
+  if test x"$with_gnu_ld" = x"yes"; then
+    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+  fi
+
+  AC_SUBST(SECTION_LDFLAGS)
+  AC_SUBST(OPT_LDFLAGS)
+])
+
+
+dnl
+dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
+dnl the native linker is in use, all variables will be defined to something
+dnl safe (like an empty string).
+dnl
+dnl Defines:
+dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
+dnl  OPT_LDFLAGS='-Wl,-O1' if possible
+dnl  LD (as a side effect of testing)
+dnl Sets:
+dnl  with_gnu_ld
+dnl  libat_ld_is_gold (possibly)
+dnl  libat_gnu_ld_version (possibly)
+dnl
+dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
+dnl set libat_gnu_ld_version to 12345.  Zeros cause problems.
+dnl
+AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
+  # If we're not using GNU ld, then there's no point in even trying these
+  # tests.  Check for that first.  We should have already tested for gld
+  # by now (in libtool), but require it now just to be safe...
+  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+  AC_REQUIRE([AC_PROG_LD])
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # The name set by libtool depends on the version of libtool.  Shame on us
+  # for depending on an impl detail, but c'est la vie.  Older versions used
+  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+  # set (hence we're using an older libtool), then set it.
+  if test x${with_gnu_ld+set} != xset; then
+    if test x${ac_cv_prog_gnu_ld+set} != xset; then
+      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+      with_gnu_ld=no
+    else
+      with_gnu_ld=$ac_cv_prog_gnu_ld
+    fi
+  fi
+
+  # Start by getting the version number.  I think the libtool test already
+  # does some of this, but throws away the result.
+  libat_ld_is_gold=no
+  if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
+    libat_ld_is_gold=yes
+  fi
+  changequote(,)
+  ldver=`$LD --version 2>/dev/null |
+         sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
+  changequote([,])
+  libat_gnu_ld_version=`echo $ldver | \
+         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
+
+  # Set --gc-sections.
+  if test "$with_gnu_ld" = "notbroken"; then
+    # GNU ld it is!  Joy and bunny rabbits!
+
+    # All these tests are for C++; save the language and the compiler flags.
+    # Need to do this so that g++ won't try to link in libstdc++
+    ac_test_CFLAGS="${CFLAGS+set}"
+    ac_save_CFLAGS="$CFLAGS"
+    CFLAGS='-x c++  -Wl,--gc-sections'
+
+    # Check for -Wl,--gc-sections
+    # XXX This test is broken at the moment, as symbols required for linking
+    # are now in libsupc++ (not built yet).  In addition, this test has
+    # cored on solaris in the past.  In addition, --gc-sections doesn't
+    # really work at the moment (keeps on discarding used sections, first
+    # .eh_frame and now some of the glibc sections for iconv).
+    # Bzzzzt.  Thanks for playing, maybe next time.
+    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
+    AC_TRY_RUN([
+     int main(void)
+     {
+       try { throw 1; }
+       catch (...) { };
+       return 0;
+     }
+    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
+    if test "$ac_test_CFLAGS" = set; then
+      CFLAGS="$ac_save_CFLAGS"
+    else
+      # this is the suspicious part
+      CFLAGS=''
+    fi
+    if test "$ac_sectionLDflags" = "yes"; then
+      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+    fi
+    AC_MSG_RESULT($ac_sectionLDflags)
+  fi
+
+  # Set linker optimization flags.
+  if test x"$with_gnu_ld" = x"yes"; then
+    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+  fi
+
+  AC_SUBST(SECTION_LDFLAGS)
+  AC_SUBST(OPT_LDFLAGS)
+])
+
+
+dnl
+dnl Add version tags to symbols in shared library (or not), additionally
+dnl marking other symbols as private/local (or not).
+dnl
+dnl --enable-symvers=style adds a version script to the linker call when
+dnl       creating the shared library.  The choice of version script is
+dnl       controlled by 'style'.
+dnl --disable-symvers does not.
+dnl  +  Usage:  LIBFFI_ENABLE_SYMVERS[(DEFAULT)]
+dnl       Where DEFAULT is either 'yes' or 'no'.  Passing `yes' tries to
+dnl       choose a default style based on linker characteristics.  Passing
+dnl       'no' disables versioning.
+dnl
+AC_DEFUN([LIBFFI_ENABLE_SYMVERS], [
+
+LIBFFI_ENABLE(symvers,yes,[=STYLE],
+  [enables symbol versioning of the shared library],
+  [permit yes|no|gnu*|sun])
+
+# If we never went through the LIBFFI_CHECK_LINKER_FEATURES macro, then we
+# don't know enough about $LD to do tricks...
+AC_REQUIRE([LIBFFI_CHECK_LINKER_FEATURES])
+
+# Turn a 'yes' into a suitable default.
+if test x$enable_symvers = xyes ; then
+  # FIXME  The following test is too strict, in theory.
+  if test $enable_shared = no || test "x$LD" = x; then
+    enable_symvers=no
+  else
+    if test $with_gnu_ld = yes ; then
+      enable_symvers=gnu
+    else
+      case ${target_os} in
+        # Sun symbol versioning exists since Solaris 2.5.
+        solaris2.[[5-9]]* | solaris2.1[[0-9]]*)
+          enable_symvers=sun ;;
+        *)
+          enable_symvers=no ;;
+      esac
+    fi
+  fi
+fi
+
+# Check if 'sun' was requested on non-Solaris 2 platforms.
+if test x$enable_symvers = xsun ; then
+  case ${target_os} in
+    solaris2*)
+      # All fine.
+      ;;
+    *)
+      # Unlikely to work.
+      AC_MSG_WARN([=== You have requested Sun symbol versioning, but])
+      AC_MSG_WARN([=== you are not targetting Solaris 2.])
+      AC_MSG_WARN([=== Symbol versioning will be disabled.])
+      enable_symvers=no
+      ;;
+  esac
+fi
+
+# Check to see if libgcc_s exists, indicating that shared libgcc is possible.
+if test $enable_symvers != no; then
+  AC_MSG_CHECKING([for shared libgcc])
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=' -lgcc_s'
+  AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes, libat_shared_libgcc=no)
+  CFLAGS="$ac_save_CFLAGS"
+  if test $libat_shared_libgcc = no; then
+    cat > conftest.c <<EOF
+int main (void) { return 0; }
+EOF
+changequote(,)dnl
+    libat_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
+                            -shared -shared-libgcc -o conftest.so \
+                            conftest.c -v 2>&1 >/dev/null \
+                            | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
+changequote([,])dnl
+    rm -f conftest.c conftest.so
+    if test x${libat_libgcc_s_suffix+set} = xset; then
+      CFLAGS=" -lgcc_s$libat_libgcc_s_suffix"
+      AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes)
+      CFLAGS="$ac_save_CFLAGS"
+    fi
+  fi
+  AC_MSG_RESULT($libat_shared_libgcc)
+fi
+
+# For GNU ld, we need at least this version.  The format is described in
+# LIBFFI_CHECK_LINKER_FEATURES above.
+libat_min_gnu_ld_version=21400
+# XXXXXXXXXXX libat_gnu_ld_version=21390
+
+# Check to see if unspecified "yes" value can win, given results above.
+# Change "yes" into either "no" or a style name.
+if test $enable_symvers != no && test $libat_shared_libgcc = yes; then
+  if test $with_gnu_ld = yes; then
+    if test $libat_gnu_ld_version -ge $libat_min_gnu_ld_version ; then
+      enable_symvers=gnu
+    elif test $libat_ld_is_gold = yes ; then
+      enable_symvers=gnu
+    else
+      # The right tools, the right setup, but too old.  Fallbacks?
+      AC_MSG_WARN(=== Linker version $libat_gnu_ld_version is too old for)
+      AC_MSG_WARN(=== full symbol versioning support in this release of GCC.)
+      AC_MSG_WARN(=== You would need to upgrade your binutils to version)
+      AC_MSG_WARN(=== $libat_min_gnu_ld_version or later and rebuild GCC.)
+      if test $libat_gnu_ld_version -ge 21200 ; then
+        # Globbing fix is present, proper block support is not.
+        dnl AC_MSG_WARN([=== Dude, you are soooo close.  Maybe we can fake it.])
+        dnl enable_symvers=???
+        AC_MSG_WARN([=== Symbol versioning will be disabled.])
+        enable_symvers=no
+      else
+        # 2.11 or older.
+        AC_MSG_WARN([=== Symbol versioning will be disabled.])
+        enable_symvers=no
+      fi
+    fi
+  elif test $enable_symvers = sun; then
+    : All interesting versions of Sun ld support sun style symbol versioning.
+  else
+    # just fail for now
+    AC_MSG_WARN([=== You have requested some kind of symbol versioning, but])
+    AC_MSG_WARN([=== either you are not using a supported linker, or you are])
+    AC_MSG_WARN([=== not building a shared libgcc_s (which is required).])
+    AC_MSG_WARN([=== Symbol versioning will be disabled.])
+    enable_symvers=no
+  fi
+fi
+if test $enable_symvers = gnu; then
+  AC_DEFINE(LIBFFI_GNU_SYMBOL_VERSIONING, 1,
+           [Define to 1 if GNU symbol versioning is used for libatomic.])
+fi
+
+AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB, test $enable_symvers != no)
+AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_GNU, test $enable_symvers = gnu)
+AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_SUN, test $enable_symvers = sun)
+AC_MSG_NOTICE(versioning on shared library symbols is $enable_symvers)
+])
index da7c432..e49a788 100644 (file)
@@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure
 
 AC_PREREQ(2.68)
 
-AC_INIT([libffi], [3.99999], [http://github.com/atgreen/libffi/issues])
+AC_INIT([libffi], [3.99999], [http://github.com/libffi/libffi/issues])
 AC_CONFIG_HEADERS([fficonfig.h])
 
 AC_CANONICAL_SYSTEM
@@ -197,7 +197,7 @@ case "$target" in
                  [Cannot use PROT_EXEC on this target, so, we revert to
                    alternative means])
      ;;
-     *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
+     *-apple-darwin* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*)
        AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,
                  [Cannot use malloc on this target, so, we revert to
                    alternative means])
@@ -372,6 +372,9 @@ else
 fi
 AC_SUBST(toolexeclibdir)
 
+# Check linker support.
+LIBFFI_ENABLE_SYMVERS
+
 AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
 AC_CONFIG_COMMANDS(src, [
 test -d src || mkdir src
index a4a22b7..e366c74 100644 (file)
@@ -96,7 +96,7 @@ case "${host}" in
        TARGETDIR=x86
        if test $ac_cv_sizeof_size_t = 4; then
          case "$host" in
-           *-gnux32)
+           x86_64-*x32|x86_64-x32-*)
              TARGET=X86_64
              ;;
            *)
index 94b7a9e..8cfa1c0 100644 (file)
@@ -155,7 +155,7 @@ If the function being called is variadic (varargs) then
 @findex ffi_prep_cif_var
 @defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nfixedargs}, unsigned int @var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
 This initializes @var{cif} according to the given parameters for
-a call to a variadic function.  In general it's operation is the
+a call to a variadic function.  In general its operation is the
 same as for @code{ffi_prep_cif} except that:
 
 @var{nfixedargs} is the number of fixed arguments, prior to any
@@ -214,7 +214,7 @@ burden of copying pass-by-value arguments is placed on the caller.
 
 Note that while the return value must be register-sized, arguments
 should exactly match their declared type.  For example, if an argument
-is a @code{short}, then the entry is @var{avalues} should point to an
+is a @code{short}, then the entry in @var{avalues} should point to an
 object declared as @code{short}; but if the return type is
 @code{short}, then @var{rvalue} should point to an object declared as
 a larger type -- usually @code{ffi_arg}.
@@ -474,9 +474,9 @@ Compute the offset of each element of the given structure type.
 @var{abi} is the ABI to use; this is needed because in some cases the
 layout depends on the ABI.
 
-@var{sizes} is an out parameter.  The caller is responsible for
+@var{offsets} is an out parameter.  The caller is responsible for
 providing enough space for all the results to be written -- one
-element per element type in @var{struct_type}.  If @var{sizes} is
+element per element type in @var{struct_type}.  If @var{offsets} is
 @code{NULL}, then the type will be laid out but not otherwise
 modified.  This can be useful for accessing the type's size or layout,
 as mentioned above.
index f551c35..005537f 100644 (file)
@@ -91,9 +91,7 @@ def mkdir_p(path):
     try:
         os.makedirs(path)
     except OSError as exc:  # Python >2.5
-        if exc.errno == errno.EEXIST:
-            pass
-        else:
+        if exc.errno != errno.EEXIST:
             raise
 
 
index bb241e8..c59df9f 100644 (file)
@@ -6,5 +6,4 @@ DISTCLEANFILES=ffitarget.h
 noinst_HEADERS=ffi_common.h ffi_cfi.h
 EXTRA_DIST=ffi.h.in
 
-includesdir = $(libdir)/@PACKAGE_NAME@-@PACKAGE_VERSION@/include
-nodist_includes_HEADERS = ffi.h ffitarget.h
+nodist_include_HEADERS = ffi.h ffitarget.h
index 9e65277..5833525 100644 (file)
    ----------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------
-   The basic API is described in the README file.
+   Most of the API is documented in doc/libffi.texi.
 
-   The raw API is designed to bypass some of the argument packing
-   and unpacking on architectures for which it can be avoided.
+   The raw API is designed to bypass some of the argument packing and
+   unpacking on architectures for which it can be avoided.  Routines
+   are provided to emulate the raw API if the underlying platform
+   doesn't allow faster implementation.
 
-   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:
+   More details on the raw API can be found in:
 
    http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
 
@@ -106,8 +97,8 @@ extern "C" {
 # endif
 #endif
 
-/* The closure code assumes that this works on pointers, i.e. a size_t */
-/* can hold a pointer.                                                 */
+/* The closure code assumes that this works on pointers, i.e. a size_t
+   can hold a pointer.  */
 
 typedef struct _ffi_type
 {
@@ -166,21 +157,20 @@ typedef struct _ffi_type
  #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. */
+/* 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 */
+/* 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;
@@ -229,15 +219,6 @@ typedef struct {
 #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
@@ -284,9 +265,9 @@ 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.             */
+/* 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),
@@ -314,10 +295,13 @@ typedef struct {
   ffi_cif   *cif;
   void     (*fun)(ffi_cif*,void*,void**,void*);
   void      *user_data;
+} ffi_closure
 #ifdef __GNUC__
-} ffi_closure __attribute__((aligned (8)));
-#else
-} ffi_closure;
+    __attribute__((aligned (8)))
+#endif
+    ;
+
+#ifndef __GNUC__
 # ifdef __sgi
 #  pragma pack 0
 # endif
@@ -354,9 +338,9 @@ typedef struct {
 
 #if !FFI_NATIVE_RAW_API
 
-  /* if this is enabled, then a raw closure has the same layout 
+  /* 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*. */
+     handler to do the transaltion, void** -> ffi_raw*.  */
 
   void     (*translate_args)(ffi_cif*,void*,void**,void*);
   void      *this_closure;
@@ -380,9 +364,9 @@ typedef struct {
 
 #if !FFI_NATIVE_RAW_API
 
-  /* if this is enabled, then a raw closure has the same layout 
+  /* 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*. */
+     handler to do the translation, void** -> ffi_raw*.  */
 
   void     (*translate_args)(ffi_cif*,void*,void**,void*);
   void      *this_closure;
@@ -461,7 +445,7 @@ void ffi_call(ffi_cif *cif,
 ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
                                   size_t *offsets);
 
-/* Useful for eliminating compiler warnings */
+/* Useful for eliminating compiler warnings */
 #define FFI_FN(f) ((void (*)(void))f)
 
 /* ---- Definitions shared with assembly code ---------------------------- */
@@ -490,7 +474,7 @@ ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
 #define FFI_TYPE_POINTER    14
 #define FFI_TYPE_COMPLEX    15
 
-/* This should always refer to the last type code (for sanity checks) */
+/* This should always refer to the last type code (for sanity checks) */
 #define FFI_TYPE_LAST       FFI_TYPE_COMPLEX
 
 #ifdef __cplusplus
index b312297..00eae1b 100644 (file)
@@ -82,11 +82,21 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
 ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
         unsigned int nfixedargs, unsigned int ntotalargs);
 
+
 #if HAVE_LONG_DOUBLE_VARIANT
 /* Used to adjust size/alignment of ffi types.  */
 void ffi_prep_types (ffi_abi abi);
 #endif
 
+/* 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);
+
 /* Extended cif, used in callback from assembly routine */
 typedef struct
 {
diff --git a/libffi.map.in b/libffi.map.in
new file mode 100644 (file)
index 0000000..5553ab0
--- /dev/null
@@ -0,0 +1,80 @@
+#define LIBFFI_ASM
+#define LIBFFI_H
+#include <fficonfig.h>
+#include <ffitarget.h>
+
+/* These version numbers correspond to the libtool-version abi numbers,
+   not to the libffi release numbers.  */
+
+LIBFFI_BASE_7.0 {
+  global:
+       /* Exported data variables.  */
+       ffi_type_void;
+       ffi_type_uint8;
+       ffi_type_sint8;
+       ffi_type_uint16;
+       ffi_type_sint16;
+       ffi_type_uint32;
+       ffi_type_sint32;
+       ffi_type_uint64;
+       ffi_type_sint64;
+       ffi_type_float;
+       ffi_type_double;
+       ffi_type_longdouble;
+       ffi_type_pointer;
+
+       /* Exported functions.  */
+       ffi_call;
+       ffi_prep_cif;
+       ffi_prep_cif_var;
+
+       ffi_raw_call;
+       ffi_ptrarray_to_raw;
+       ffi_raw_to_ptrarray;
+       ffi_raw_size;
+
+       ffi_java_raw_call;
+       ffi_java_ptrarray_to_raw;
+       ffi_java_raw_to_ptrarray;
+       ffi_java_raw_size;
+
+  local:
+       *;
+};
+
+LIBFFI_BASE_7.1 {
+  global:
+       ffi_get_struct_offsets;
+} LIBFFI_BASE_7.0;
+
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+LIBFFI_COMPLEX_7.0 {
+  global:
+       /* Exported data variables.  */
+       ffi_type_complex_float;
+       ffi_type_complex_double;
+       ffi_type_complex_longdouble;
+} LIBFFI_BASE_7.0;
+#endif
+
+#if FFI_CLOSURES
+LIBFFI_CLOSURE_7.0 {
+  global:
+       ffi_closure_alloc;
+       ffi_closure_free;
+       ffi_prep_closure;
+       ffi_prep_closure_loc;
+       ffi_prep_raw_closure;
+       ffi_prep_raw_closure_loc;
+       ffi_prep_java_raw_closure;
+       ffi_prep_java_raw_closure_loc;
+} LIBFFI_BASE_7.0;
+#endif
+
+#if FFI_GO_CLOSURES
+LIBFFI_GO_CLOSURE_7.0 {
+  global:
+       ffi_call_go;
+       ffi_prep_go_closure;
+} LIBFFI_CLOSURE_7.0;
+#endif
index edf6fde..6fad83b 100644 (file)
@@ -2,7 +2,7 @@ prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
 toolexeclibdir=@toolexeclibdir@
-includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include
+includedir=@includedir@
 
 Name: @PACKAGE_NAME@
 Description: Library supporting Foreign Function Interfaces
index 149a51a..e4f5aa2 100644 (file)
@@ -26,4 +26,4 @@
 #    release, then set age to 0.
 #
 # CURRENT:REVISION:AGE
-6:4:0
+8:0:1
index cf33abc..e7cf6ce 100644 (file)
@@ -55,6 +55,14 @@ struct call_context
   UINT64 x[N_X_ARG_REG];
 };
 
+#if FFI_EXEC_TRAMPOLINE_TABLE
+
+#ifdef __MACH__
+#include <mach/vm_param.h>
+#endif
+
+#else
+
 #if defined (__clang__) && defined (__APPLE__)
 extern void sys_icache_invalidate (void *start, size_t len);
 #endif
@@ -71,12 +79,6 @@ ffi_clear_cache (void *start, void *end)
 #endif
 }
 
-#if FFI_EXEC_TRAMPOLINE_TABLE
-
-#ifdef __MACH__
-#include <mach/vm_param.h>
-#endif
-
 #endif
 
 /* A subroutine of is_vfp_type.  Given a structure type, return the type code
@@ -316,7 +318,7 @@ extend_integer_type (void *source, int type)
 static void
 extend_hfa_type (void *dest, void *src, int h)
 {
-  int f = h - AARCH64_RET_S4;
+  ssize_t f = h - AARCH64_RET_S4;
   void *x0;
 
   asm volatile (
@@ -666,6 +668,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
                   the argument is replaced by a pointer to the copy.  */
                a = &avalue[i];
                t = FFI_TYPE_POINTER;
+               s = sizeof (void *);
                goto do_pointer;
              }
            else
@@ -917,6 +920,15 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
        default:
          abort();
        }
+
+#if defined (__APPLE__)
+      if (i + 1 == cif->aarch64_nfixedargs)
+       {
+         state.ngrn = N_X_ARG_REG;
+         state.nsrn = N_V_ARG_REG;
+         state.allocating_variadic = 1;
+       }
+#endif
     }
 
   flags = cif->flags;
index 5ded0e4..65086cd 100644 (file)
@@ -29,6 +29,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 #ifndef LIBFFI_ASM
 #ifdef __ILP32__
 #define FFI_SIZEOF_ARG 8
+#define FFI_SIZEOF_JAVA_RAW  4
 typedef unsigned long long ffi_arg;
 typedef signed long long ffi_sarg;
 #else
index 32f82a7..8a507f3 100644 (file)
@@ -46,12 +46,10 @@ void
 ffi_prep_args (char *stack, extended_cif * ecif)
 {
   unsigned int i;
-  int tmp;
   void **p_argv;
   char *argp;
   ffi_type **p_arg;
 
-  tmp = 0;
   argp = stack;
 
   if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
index 3dec0e3..78d6aeb 100644 (file)
@@ -35,7 +35,7 @@
 #include <ffi_common.h>
 
 #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
-# if __gnu_linux__ && !defined(__ANDROID__)
+# if __linux__ && !defined(__ANDROID__)
 /* 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
@@ -211,6 +211,7 @@ ffi_closure_alloc (size_t size, void **code)
       table = ffi_trampoline_table_alloc ();
       if (table == NULL)
        {
+         pthread_mutex_unlock (&ffi_trampoline_lock);
          free (closure);
          return NULL;
        }
@@ -331,14 +332,6 @@ ffi_closure_free (void *ptr)
 /* 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>
@@ -758,10 +751,6 @@ dlmmap (void *start, size_t length, int prot,
          && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
          && fd == -1 && offset == 0);
 
-#if FFI_CLOSURE_TEST
-  printf ("mapping in %zi\n", length);
-#endif
-
   if (execfd == -1 && is_emutramp_enabled ())
     {
       ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
@@ -807,10 +796,6 @@ dlmunmap (void *start, size_t length)
   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);
@@ -879,26 +864,6 @@ ffi_closure_free (void *ptr)
   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
index 7e4ea83..d63dd36 100644 (file)
@@ -438,6 +438,11 @@ DEFAULT_MMAP_THRESHOLD       default: 256K
 
 */
 
+#if defined __linux__ && !defined _GNU_SOURCE
+/* mremap() on Linux requires this via sys/mman.h */
+#define _GNU_SOURCE 1
+#endif
+
 #ifndef WIN32
 #ifdef _WIN32
 #define WIN32 1
index ec2b14f..ea40f11 100644 (file)
@@ -3,7 +3,7 @@
    sysv.S - Copyright (c) 2012 Alan Hourihane
            Copyright (c) 1998, 2012 Andreas Schwab
            Copyright (c) 2008 Red Hat, Inc.
-           Copyright (c) 2012 Thorsten Glaser
+           Copyright (c) 2012, 2016 Thorsten Glaser
 
    m68k Foreign Function Interface
 
@@ -72,6 +72,15 @@ CALLFUNC(ffi_call_SYSV):
        pea     4(%sp)
 #if !defined __PIC__
        jsr     CALLFUNC(ffi_prep_args)
+#elif defined(__uClinux__) && defined(__ID_SHARED_LIBRARY__)
+       move.l  _current_shared_library_a5_offset_(%a5),%a0
+       move.l  CALLFUNC(ffi_prep_args@GOT)(%a0),%a0
+       jsr     (%a0)
+#elif defined(__mcoldfire__) && !defined(__mcfisab__) && !defined(__mcfisac__)
+       move.l  #_GLOBAL_OFFSET_TABLE_@GOTPC,%a0
+       lea     (-6,%pc,%a0),%a0
+       move.l  CALLFUNC(ffi_prep_args@GOT)(%a0),%a0
+       jsr     (%a0)
 #else
        bsr.l   CALLFUNC(ffi_prep_args@PLTPC)
 #endif
@@ -215,6 +224,15 @@ CALLFUNC(ffi_closure_SYSV):
        move.l  %a0,-(%sp)
 #if !defined __PIC__
        jsr     CALLFUNC(ffi_closure_SYSV_inner)
+#elif defined(__uClinux__) && defined(__ID_SHARED_LIBRARY__)
+       move.l  _current_shared_library_a5_offset_(%a5),%a0
+       move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
+       jsr     (%a0)
+#elif defined(__mcoldfire__) && !defined(__mcfisab__) && !defined(__mcfisac__)
+       move.l  #_GLOBAL_OFFSET_TABLE_@GOTPC,%a0
+       lea     (-6,%pc,%a0),%a0
+       move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
+       jsr     (%a0)
 #else
        bsr.l   CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
 #endif
@@ -317,6 +335,15 @@ CALLFUNC(ffi_closure_struct_SYSV):
        move.l  %a0,-(%sp)
 #if !defined __PIC__
        jsr     CALLFUNC(ffi_closure_SYSV_inner)
+#elif defined(__uClinux__) && defined(__ID_SHARED_LIBRARY__)
+       move.l  _current_shared_library_a5_offset_(%a5),%a0
+       move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
+       jsr     (%a0)
+#elif defined(__mcoldfire__) && !defined(__mcfisab__) && !defined(__mcfisac__)
+       move.l  #_GLOBAL_OFFSET_TABLE_@GOTPC,%a0
+       lea     (-6,%pc,%a0),%a0
+       move.l  CALLFUNC(ffi_closure_SYSV_inner@GOT)(%a0),%a0
+       jsr     (%a0)
 #else
        bsr.l   CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
 #endif
index ea962ea..5733e6e 100644 (file)
@@ -46,12 +46,12 @@ void ffi_prep_args(void* stack, extended_cif* ecif)
        void** p_argv;
        void* stack_args_p = stack;
 
-       p_argv = ecif->avalue;
-
        if (ecif == NULL || ecif->cif == NULL) {
                return; /* no description to prepare */
        }
 
+       p_argv = ecif->avalue;
+
        if ((ecif->cif->rtype != NULL) &&
                        (ecif->cif->rtype->type == FFI_TYPE_STRUCT))
        {
index b402c88..edc6905 100644 (file)
@@ -112,6 +112,16 @@ loadregs:
 
        REG_L   t6, 3*FFI_SIZEOF_ARG($fp)  # load the flags word into t6.
 
+#ifdef __mips_soft_float
+       REG_L   a0, 0*FFI_SIZEOF_ARG(t9)
+       REG_L   a1, 1*FFI_SIZEOF_ARG(t9)
+       REG_L   a2, 2*FFI_SIZEOF_ARG(t9)
+       REG_L   a3, 3*FFI_SIZEOF_ARG(t9)
+       REG_L   a4, 4*FFI_SIZEOF_ARG(t9)
+       REG_L   a5, 5*FFI_SIZEOF_ARG(t9)
+       REG_L   a6, 6*FFI_SIZEOF_ARG(t9)
+       REG_L   a7, 7*FFI_SIZEOF_ARG(t9)
+#else
        and     t4, t6, ((1<<FFI_FLAG_BITS)-1)
        REG_L   a0, 0*FFI_SIZEOF_ARG(t9)
        beqz    t4, arg1_next
@@ -198,6 +208,7 @@ arg7_next:
 arg8_doublep:  
        l.d     $f19, 7*FFI_SIZEOF_ARG(t9)      
 arg8_next:     
+#endif
 
 callit:                
        # Load the function pointer
@@ -222,6 +233,7 @@ retint:
        b       epilogue
 
 retfloat:
+#ifndef __mips_soft_float
        bne     t6, FFI_TYPE_FLOAT, retdouble
        jal     t9
        REG_L   t4, 4*FFI_SIZEOF_ARG($fp)
@@ -280,6 +292,7 @@ retstruct_f_d:
        s.s     $f0, 0(t4)
        s.d     $f2, 8(t4)
        b       epilogue
+#endif
 
 retstruct_d_soft:
        bne     t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
@@ -483,6 +496,7 @@ $do_closure:
        REG_S   a6, A6_OFF2($sp)
        REG_S   a7, A7_OFF2($sp)
 
+#ifndef __mips_soft_float
        # Store all possible float/double registers.
        s.d     $f12, F12_OFF2($sp)
        s.d     $f13, F13_OFF2($sp)
@@ -492,6 +506,7 @@ $do_closure:
        s.d     $f17, F17_OFF2($sp)
        s.d     $f18, F18_OFF2($sp)
        s.d     $f19, F19_OFF2($sp)
+#endif
 
        jalr    t9
 
@@ -506,6 +521,7 @@ cls_retint:
        b       cls_epilogue
 
 cls_retfloat:
+#ifndef __mips_soft_float
        bne     v0, FFI_TYPE_FLOAT, cls_retdouble
        l.s     $f0, V0_OFF2($sp)
        b       cls_epilogue
@@ -548,6 +564,7 @@ cls_retstruct_f_d:
        l.s     $f0, V0_OFF2($sp)
        l.d     $f2, V1_OFF2($sp)
        b       cls_epilogue
+#endif
        
 cls_retstruct_small2:  
        REG_L   v0, V0_OFF2($sp)
index 69324e6..44e74cb 100644 (file)
@@ -82,13 +82,16 @@ sixteen:
                
        ADDU    $sp, 4 * FFI_SIZEOF_ARG         # adjust $sp to new args
 
+#ifndef __mips_soft_float
        bnez    t0, pass_d                      # make it quick for int
+#endif
        REG_L   a0, 0*FFI_SIZEOF_ARG($sp)       # just go ahead and load the
        REG_L   a1, 1*FFI_SIZEOF_ARG($sp)       # four regs.
        REG_L   a2, 2*FFI_SIZEOF_ARG($sp)
        REG_L   a3, 3*FFI_SIZEOF_ARG($sp)
        b       call_it
 
+#ifndef __mips_soft_float
 pass_d:
        bne     t0, FFI_ARGS_D, pass_f
        l.d     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
@@ -130,6 +133,7 @@ pass_f_d:
  #     bne     t0, FFI_ARGS_F_D, call_it
        l.s     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
        l.d     $f14, 2*FFI_SIZEOF_ARG($sp)     # passing double and float
+#endif
 
 call_it:       
        # Load the static chain pointer
@@ -161,14 +165,23 @@ retfloat:
        bne     t2, FFI_TYPE_FLOAT, retdouble
        jalr    t9
        REG_L   t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+#ifndef __mips_soft_float
        s.s     $f0, 0(t0)
+#else
+       REG_S   v0, 0(t0)
+#endif
        b       epilogue
 
 retdouble:     
        bne     t2, FFI_TYPE_DOUBLE, noretval
        jalr    t9
        REG_L   t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
+#ifndef __mips_soft_float
        s.d     $f0, 0(t0)
+#else
+       REG_S   v1, 4(t0)
+       REG_S   v0, 0(t0)
+#endif
        b       epilogue
        
 noretval:      
@@ -324,9 +337,11 @@ $LCFI22:
        li      $13, 1          # FFI_O32
        bne     $16, $13, 1f    # Skip fp save if FFI_O32_SOFT_FLOAT
        
+#ifndef __mips_soft_float
        # Store all possible float/double registers.
        s.d     $f12, FA_0_0_OFF2($fp)
        s.d     $f14, FA_1_0_OFF2($fp)
+#endif
 1:     
        # prepare arguments for ffi_closure_mips_inner_O32
        REG_L   a0, 20($12)      # cif pointer follows tramp.
@@ -353,6 +368,7 @@ $do_closure:
        li      $13, 1          # FFI_O32
        bne     $16, $13, 1f    # Skip fp restore if FFI_O32_SOFT_FLOAT
 
+#ifndef __mips_soft_float
        li      $9, FFI_TYPE_FLOAT
        l.s     $f0, V0_OFF2($fp)
        beq     $8, $9, closure_done
@@ -360,6 +376,7 @@ $do_closure:
        li      $9, FFI_TYPE_DOUBLE
        l.d     $f0, V0_OFF2($fp)
        beq     $8, $9, closure_done
+#endif
 1:     
        REG_L   $3, V1_OFF2($fp)
        REG_L   $2, V0_OFF2($fp)
index c7734d4..3121e6a 100644 (file)
@@ -353,7 +353,7 @@ Lret_type13:
        bgt     Lstructend              ; not a special small case
        b       Lsmallstruct            ; see if we need more.
 #else
-       cmp   0,r0,4
+       cmpwi   0,r0,4
        bgt     Lfinish         ; not by value
        lg      r3,0(r5)
        b       Lfinish
@@ -494,8 +494,8 @@ LSFDE1:
 LASFDE1:
        .long   LASFDE1-EH_frame1       ; FDE CIE offset
        .g_long Lstartcode-.    ; FDE initial location
-       .set    L$set$3,LFE1-Lstartcode
-       .g_long L$set$3 ; FDE address range
+       .set    L$set$2,LFE1-Lstartcode
+       .g_long L$set$2 ; FDE address range
        .byte   0x0     ; uleb128 0x0; Augmentation size
        .byte   0x4     ; DW_CFA_advance_loc4
        .set    L$set$3,LCFI1-LCFI0
index f52749e..93dcc35 100644 (file)
@@ -219,7 +219,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
        const size_t UNITS_PER_WORD = 8;
        size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
        ffi_type **ptr;
-       int i;
+       unsigned int i;
        enum x86_64_reg_class subclasses[MAX_CLASSES];
 
        /* If the struct is larger than 32 bytes, pass it on the stack.  */
@@ -350,7 +350,8 @@ examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
                  _Bool in_return, int *pngpr, int *pnsse)
 {
   size_t n;
-  int i, ngpr, nsse;
+  unsigned int i;
+  int ngpr, nsse;
 
   n = classify_argument (type, classes, 0);
   if (n == 0)
@@ -611,7 +612,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
        {
          /* The argument is passed entirely in registers.  */
          char *a = (char *) avalue[i];
-         int j;
+         unsigned int j;
 
          for (j = 0; j < n; j++, a += 8, size -= 8)
            {
@@ -808,7 +809,7 @@ ffi_closure_unix64_inner(ffi_cif *cif,
       else
        {
          char *a = alloca (16);
-         int j;
+         unsigned int j;
 
          avalue[i] = a;
          for (j = 0; j < n; j++, a += 8)
index 0029be0..fd47c58 100644 (file)
@@ -231,7 +231,11 @@ struct win64_closure_frame
   UINT64 args[];
 };
 
-int FFI_HIDDEN
+/* Force the inner function to use the MS ABI.  When compiling on win64
+   this is a nop.  When compiling on unix, this simplifies the assembly,
+   and places the burden of saving the extra call-saved registers on
+   the compiler.  */
+int FFI_HIDDEN __attribute__((ms_abi))
 ffi_closure_win64_inner(ffi_cif *cif,
                        void (*fun)(ffi_cif*, void*, void**, void*),
                        void *user_data,
index 9d4f8b9..f8cbf9f 100644 (file)
 #define arg3   %rcx
 #endif
 
-.macro E which
-       .align  8
-       .org    0b + \which * 8
-.endm
+/* This macro allows the safe creation of jump tables without an
+   actual table.  The entry points into the table are all 8 bytes.
+   The use of ORG asserts that we're at the correct location.  */
+/* ??? The clang assembler doesn't handle .org with symbolic expressions.  */
+#if defined(__clang__) || defined(__APPLE__) || (defined (__sun__) && defined(__svr4__))
+# define E(BASE, X)    .balign 8
+#else
+# define E(BASE, X)    .balign 8; .org BASE + X * 8
+#endif
 
        .text
 
    deallocate some of the stack that has been alloca'd.  */
 
        .align  8
-       .globl  ffi_call_win64
+       .globl  C(ffi_call_win64)
 
        SEH(.seh_proc ffi_call_win64)
-ffi_call_win64:
+C(ffi_call_win64):
        cfi_startproc
        /* Set up the local stack frame and install it in rbp/rsp.  */
        movq    (%rsp), %rax
@@ -88,69 +93,69 @@ ffi_call_win64:
 
        .align  8
 0:
-E FFI_TYPE_VOID
+E(0b, FFI_TYPE_VOID)
        epilogue
-E FFI_TYPE_INT
+E(0b, FFI_TYPE_INT)
        movslq  %eax, %rax
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_FLOAT
+E(0b, FFI_TYPE_FLOAT)
        movss   %xmm0, (%r8)
        epilogue
-E FFI_TYPE_DOUBLE
+E(0b, FFI_TYPE_DOUBLE)
        movsd   %xmm0, (%r8)
        epilogue
-E FFI_TYPE_LONGDOUBLE
+E(0b, FFI_TYPE_LONGDOUBLE)
        call    PLT(C(abort))
-E FFI_TYPE_UINT8
+E(0b, FFI_TYPE_UINT8)
        movzbl  %al, %eax
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_SINT8
+E(0b, FFI_TYPE_SINT8)
        movsbq  %al, %rax
        jmp     98f
-E FFI_TYPE_UINT16
+E(0b, FFI_TYPE_UINT16)
        movzwl  %ax, %eax
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_SINT16
+E(0b, FFI_TYPE_SINT16)
        movswq  %ax, %rax
        jmp     98f
-E FFI_TYPE_UINT32
+E(0b, FFI_TYPE_UINT32)
        movl    %eax, %eax
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_SINT32
+E(0b, FFI_TYPE_SINT32)
        movslq  %eax, %rax
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_UINT64
+E(0b, FFI_TYPE_UINT64)
 98:    movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_SINT64
+E(0b, FFI_TYPE_SINT64)
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_STRUCT
+E(0b, FFI_TYPE_STRUCT)
        epilogue
-E FFI_TYPE_POINTER
+E(0b, FFI_TYPE_POINTER)
        movq    %rax, (%r8)
        epilogue
-E FFI_TYPE_COMPLEX
+E(0b, FFI_TYPE_COMPLEX)
        call    PLT(C(abort))
-E FFI_TYPE_SMALL_STRUCT_1B
+E(0b, FFI_TYPE_SMALL_STRUCT_1B)
        movb    %al, (%r8)
        epilogue
-E FFI_TYPE_SMALL_STRUCT_2B
+E(0b, FFI_TYPE_SMALL_STRUCT_2B)
        movw    %ax, (%r8)
        epilogue
-E FFI_TYPE_SMALL_STRUCT_4B
+E(0b, FFI_TYPE_SMALL_STRUCT_4B)
        movl    %eax, (%r8)
        epilogue
 
        .align  8
 99:    call    PLT(C(abort))
 
-.purgem epilogue
+       epilogue
 
        cfi_endproc
        SEH(.seh_endproc)
@@ -163,10 +168,10 @@ E FFI_TYPE_SMALL_STRUCT_4B
 #define ffi_clo_OFF_X  (32+8+16)
 
        .align  8
-       .globl  ffi_go_closure_win64
+       .globl  C(ffi_go_closure_win64)
 
        SEH(.seh_proc ffi_go_closure_win64)
-ffi_go_closure_win64:
+C(ffi_go_closure_win64):
        cfi_startproc
        /* Save all integer arguments into the incoming reg stack space.  */
        movq    %rcx, 8(%rsp)
@@ -174,18 +179,18 @@ ffi_go_closure_win64:
        movq    %r8, 24(%rsp)
        movq    %r9, 32(%rsp)
 
-       movq    8(%r10), arg0                   /* load cif */
-       movq    16(%r10), arg1                  /* load fun */
-       movq    %r10, arg2                      /* closure is user_data */
+       movq    8(%r10), %rcx                   /* load cif */
+       movq    16(%r10), %rdx                  /* load fun */
+       movq    %r10, %r8                       /* closure is user_data */
        jmp     0f
        cfi_endproc
        SEH(.seh_endproc)
 
        .align  8
-       .globl  ffi_closure_win64
+       .globl  C(ffi_closure_win64)
 
        SEH(.seh_proc ffi_closure_win64)
-ffi_closure_win64:
+C(ffi_closure_win64):
        cfi_startproc
        /* Save all integer arguments into the incoming reg stack space.  */
        movq    %rcx, 8(%rsp)
@@ -193,9 +198,9 @@ ffi_closure_win64:
        movq    %r8, 24(%rsp)
        movq    %r9, 32(%rsp)
 
-       movq    FFI_TRAMPOLINE_SIZE(%r10), arg0         /* load cif */
-       movq    FFI_TRAMPOLINE_SIZE+8(%r10), arg1       /* load fun */
-       movq    FFI_TRAMPOLINE_SIZE+16(%r10), arg2      /* load user_data */
+       movq    FFI_TRAMPOLINE_SIZE(%r10), %rcx         /* load cif */
+       movq    FFI_TRAMPOLINE_SIZE+8(%r10), %rdx       /* load fun */
+       movq    FFI_TRAMPOLINE_SIZE+16(%r10), %r8       /* load user_data */
 0:
        subq    $ffi_clo_FS, %rsp
        cfi_adjust_cfa_offset(ffi_clo_FS)
@@ -208,8 +213,8 @@ ffi_closure_win64:
        movsd   %xmm2, ffi_clo_OFF_X+16(%rsp)
        movsd   %xmm3, ffi_clo_OFF_X+24(%rsp)
 
-       leaq    ffi_clo_OFF_R(%rsp), arg3
-       call    ffi_closure_win64_inner
+       leaq    ffi_clo_OFF_R(%rsp), %r9
+       call    C(ffi_closure_win64_inner)
 
        /* Load the result into both possible result registers.  */
        movq    ffi_clo_OFF_R(%rsp), %rax
@@ -221,3 +226,7 @@ ffi_closure_win64:
 
        cfi_endproc
        SEH(.seh_endproc)
+
+#if defined __ELF__ && defined __linux__
+       .section        .note.GNU-stack,"",@progbits
+#endif
index 0d74627..37e4cf6 100644 (file)
@@ -102,11 +102,14 @@ proc libffi-init { args } {
     global ld_library_path
     global compiler_vendor
 
-    set blddirffi [pwd]/.. 
+    if ![info exists blddirffi] {
+       set blddirffi [pwd]/..
+    }
+
     verbose "libffi $blddirffi"
 
     # Which compiler are we building with?
-    set tmp [grep ../config.log "^ax_cv_c_compiler_vendor.*$"]
+    set tmp [grep "$blddirffi/config.log" "^ax_cv_c_compiler_vendor.*$"]
     regexp -- {^[^=]*=(.*)$} $tmp nil compiler_vendor
 
     if { [string match $compiler_vendor "gnu"] } {
@@ -172,7 +175,7 @@ proc libffi_target_compile { source dest type options } {
     global libffi_link_flags
     global libffi_include
     global target_triplet
-
+    global compiler_vendor
 
     if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
        lappend options "libs=${gluefile}"
@@ -215,8 +218,13 @@ proc libffi_target_compile { source dest type options } {
        lappend options "libs= -lpthread"
     }
 
+    # this may be required for g++, but just confused clang.
     if { [string match "*.cc" $source] } {
-       lappend options "c++"
+        lappend options "c++"
+    }
+
+    if { [string match "arc*-*-linux*" $target_triplet] } {
+       lappend options "libs= -lpthread"
     }
 
     verbose "options: $options"
@@ -225,20 +233,21 @@ proc libffi_target_compile { source dest type options } {
 
 # TEST should be a preprocessor condition.  Returns true if it holds.
 proc libffi_feature_test { test } {
-    set src "ffitest.c"
+    set src "ffitest[pid].c"
 
     set f [open $src "w"]
     puts $f "#include <ffi.h>"
     puts $f $test
-    puts $f "xyzzy"
+    puts $f "/* OK */"
+    puts $f "#else"
+    puts $f "# error Failed $test"
     puts $f "#endif"
     close $f
 
-    set lines [libffi_target_compile $src "" "preprocess" ""]
+    set lines [libffi_target_compile $src /dev/null assembly ""]
     file delete $src
 
-    set last [lindex $lines end]
-    return [regexp -- "xyzzy" $last]
+    return [string match "" $lines]
 }
 
 # Utility routines.
@@ -315,6 +324,11 @@ proc run-many-tests { testcases extra_flags } {
                 "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__"
                 "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__"
             }
+        } elseif [istarget "x86_64-*-*"] {
+            set targetabis {
+                ""
+                "-DABI_NUM=FFI_WIN64 -DABI_ATTR=__MSABI__"
+            }
         }
     }
 
index d663791..e451dea 100644 (file)
@@ -57,10 +57,10 @@ int main(int argc __UNUSED__, char** argv __UNUSED__)
        CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
 
        ((void*(*)(Dbls))(code))(arg);
-       /* { dg-output "1.0 2.0\n" } */
+       /* { dg-output "1.0 2.0" } */
 
        closure_test_fn(arg);
-       /* { dg-output "1.0 2.0\n" } */
+       /* { dg-output "\n1.0 2.0" } */
 
        return 0;
 }
index 15d5e44..5e19451 100644 (file)
@@ -24,6 +24,7 @@
 #define __STDCALL__ __attribute__((stdcall))
 #define __THISCALL__ __attribute__((thiscall))
 #define __FASTCALL__ __attribute__((fastcall))
+#define __MSABI__ __attribute__((ms_abi))
 #else
 #define __UNUSED__
 #define __STDCALL__ __stdcall
index 20a8c40..d583e22 100644 (file)
@@ -22,6 +22,7 @@ int main (void)
   void *values[MAX_ARGS];
   float f;
   long double ld;
+  long double original;
 
   args[0] = &ffi_type_float;
   values[0] = &f;
@@ -49,7 +50,8 @@ int main (void)
 #endif
 
   /* These are not always the same!! Check for a reasonable delta */
-  if (fabsl(ld - ldblit(f)) < LDBL_EPSILON)
+  original = ldblit(f);
+  if (((ld > original) ? (ld - original) : (original - ld)) < LDBL_EPSILON)
     puts("long double return value tests ok!");
   else
     CHECK(0);
index 67cfefe..77d3a74 100644 (file)
@@ -4,7 +4,7 @@
    PR:         none.
    Originator: Jeff Sturm <jsturm@one-point.com>  */
 
-/* { dg-do run } */
+/* { dg-do run { xfail x86_64-apple-darwin* } } */
 
 #include "ffitest.h"