packages feed

libffi-clib (empty) → 3.5.2

raw patch · 174 files changed

+105542/−0 lines, 174 filessetup-changed

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for libffi++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMainWithHooks autoconfUserHooks
+ aclocal.m4 view
@@ -0,0 +1,787 @@+# generated automatically by aclocal 1.18.1 -*- Autoconf -*-++# Copyright (C) 1996-2025 Free Software Foundation, Inc.++# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# This program is distributed in the hope that it will be useful,+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A+# PARTICULAR PURPOSE.++m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])+# Figure out how to run the assembler.                      -*- Autoconf -*-++# Copyright (C) 2001-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# AM_PROG_AS+# ----------+AC_DEFUN([AM_PROG_AS],+[# By default we simply use the C compiler to build assembly code.+AC_REQUIRE([AC_PROG_CC])+test "${CCAS+set}" = set || CCAS=$CC+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS+AC_ARG_VAR([CCAS],      [assembler compiler command (defaults to CC)])+AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl+])++# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-++# Copyright (C) 2001-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.+#+# Of course, Automake must honor this variable whenever it calls a+# tool from the auxiliary directory.  The problem is that $srcdir (and+# therefore $ac_aux_dir as well) can be either absolute or relative,+# depending on how configure is run.  This is pretty annoying, since+# it makes $ac_aux_dir quite unusable in subdirectories: in the top+# source directory, any form will work fine, but in subdirectories a+# relative path needs to be adjusted first.+#+# $ac_aux_dir/missing+#    fails when called from a subdirectory if $ac_aux_dir is relative+# $top_srcdir/$ac_aux_dir/missing+#    fails if $ac_aux_dir is absolute,+#    fails when called from a subdirectory in a VPATH build with+#          a relative $ac_aux_dir+#+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir+# are both prefixed by $srcdir.  In an in-source build this is usually+# harmless because $srcdir is '.', but things will broke when you+# start a VPATH build or use an absolute $srcdir.+#+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`+# and then we would define $MISSING as+#   MISSING="\${SHELL} $am_aux_dir/missing"+# This will work as long as MISSING is not called from configure, because+# unfortunately $(top_srcdir) has no meaning in configure.+# However there are other variables, like CC, which are often used in+# configure, and could therefore not use this "fixed" $ac_aux_dir.+#+# Another solution, used here, is to always expand $ac_aux_dir to an+# absolute PATH.  The drawback is that using absolute paths prevent a+# configured tree to be moved without reconfiguration.++AC_DEFUN([AM_AUX_DIR_EXPAND],+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl+# Expand $ac_aux_dir to an absolute path.+am_aux_dir=`cd "$ac_aux_dir" && pwd`+])++# AM_CONDITIONAL                                            -*- Autoconf -*-++# Copyright (C) 1997-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# AM_CONDITIONAL(NAME, SHELL-CONDITION)+# -------------------------------------+# Define a conditional.+AC_DEFUN([AM_CONDITIONAL],+[AC_PREREQ([2.52])dnl+ m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl+AC_SUBST([$1_TRUE])dnl+AC_SUBST([$1_FALSE])dnl+_AM_SUBST_NOTMAKE([$1_TRUE])dnl+_AM_SUBST_NOTMAKE([$1_FALSE])dnl+m4_define([_AM_COND_VALUE_$1], [$2])dnl+if $2; then+  $1_TRUE=+  $1_FALSE='#'+else+  $1_TRUE='#'+  $1_FALSE=+fi+AC_CONFIG_COMMANDS_PRE(+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then+  AC_MSG_ERROR([[conditional "$1" was never defined.+Usually this means the macro was only invoked conditionally.]])+fi])])++# Copyright (C) 1999-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.+++# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be+# written in clear, in which case automake, when reading aclocal.m4,+# will think it sees a *use*, and therefore will trigger all it's+# C support machinery.  Also note that it means that autoscan, seeing+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...+++# _AM_DEPENDENCIES(NAME)+# ----------------------+# See how the compiler implements dependency checking.+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".+# We try a few techniques and use that to set a single cache variable.+#+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular+# dependency, and given that the user is not expected to run this macro,+# just rely on AC_PROG_CC.+AC_DEFUN([_AM_DEPENDENCIES],+[AC_REQUIRE([AM_SET_DEPDIR])dnl+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl+AC_REQUIRE([AM_MAKE_INCLUDE])dnl+AC_REQUIRE([AM_DEP_TRACK])dnl++m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],+                    [depcc="$$1"   am_compiler_list=])++AC_CACHE_CHECK([dependency style of $depcc],+               [am_cv_$1_dependencies_compiler_type],+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then+  # We make a subdir and do the tests there.  Otherwise we can end up+  # making bogus files that we don't know about and never remove.  For+  # instance it was reported that on HP-UX the gcc test will end up+  # making a dummy file named 'D' -- because '-MD' means "put the output+  # in D".+  rm -rf conftest.dir+  mkdir conftest.dir+  # Copy depcomp to subdir because otherwise we won't find it if we're+  # using a relative directory.+  cp "$am_depcomp" conftest.dir+  cd conftest.dir+  # We will build objects and dependencies in a subdirectory because+  # it helps to detect inapplicable dependency modes.  For instance+  # both Tru64's cc and ICC support -MD to output dependencies as a+  # side effect of compilation, but ICC will put the dependencies in+  # the current directory while Tru64 will put them in the object+  # directory.+  mkdir sub++  am_cv_$1_dependencies_compiler_type=none+  if test "$am_compiler_list" = ""; then+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`+  fi+  am__universal=false+  m4_case([$1], [CC],+    [case " $depcc " in #(+     *\ -arch\ *\ -arch\ *) am__universal=true ;;+     esac],+    [CXX],+    [case " $depcc " in #(+     *\ -arch\ *\ -arch\ *) am__universal=true ;;+     esac])++  for depmode in $am_compiler_list; do+    # Setup a source with many dependencies, because some compilers+    # like to wrap large dependency lists on column 80 (with \), and+    # we should not choose a depcomp mode which is confused by this.+    #+    # We need to recreate these files for each test, as the compiler may+    # overwrite some of them when testing with obscure command lines.+    # This happens at least with the AIX C compiler.+    : > sub/conftest.c+    for i in 1 2 3 4 5 6; do+      echo '#include "conftst'$i'.h"' >> sub/conftest.c+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with+      # Solaris 10 /bin/sh.+      echo '/* dummy */' > sub/conftst$i.h+    done+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf++    # We check with '-c' and '-o' for the sake of the "dashmstdout"+    # mode.  It turns out that the SunPro C++ compiler does not properly+    # handle '-M -o', and we need to detect this.  Also, some Intel+    # versions had trouble with output in subdirs.+    am__obj=sub/conftest.${OBJEXT-o}+    am__minus_obj="-o $am__obj"+    case $depmode in+    gcc)+      # This depmode causes a compiler race in universal mode.+      test "$am__universal" = false || continue+      ;;+    nosideeffect)+      # After this tag, mechanisms are not by side-effect, so they'll+      # only be used when explicitly requested.+      if test "x$enable_dependency_tracking" = xyes; then+	continue+      else+	break+      fi+      ;;+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)+      # This compiler won't grok '-c -o', but also, the minuso test has+      # not run yet.  These depmodes are late enough in the game, and+      # so weak that their functioning should not be impacted.+      am__obj=conftest.${OBJEXT-o}+      am__minus_obj=+      ;;+    none) break ;;+    esac+    if depmode=$depmode \+       source=sub/conftest.c object=$am__obj \+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \+         >/dev/null 2>conftest.err &&+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then+      # icc doesn't choke on unknown options, it will just issue warnings+      # or remarks (even with -Werror).  So we grep stderr for any message+      # that says an option was ignored or not supported.+      # When given -MP, icc 7.0 and 7.1 complain thus:+      #   icc: Command line warning: ignoring option '-M'; no argument required+      # The diagnosis changed in icc 8.0:+      #   icc: Command line remark: option '-MP' not supported+      if (grep 'ignoring option' conftest.err ||+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else+        am_cv_$1_dependencies_compiler_type=$depmode+        break+      fi+    fi+  done++  cd ..+  rm -rf conftest.dir+else+  am_cv_$1_dependencies_compiler_type=none+fi+])+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])+AM_CONDITIONAL([am__fastdep$1], [+  test "x$enable_dependency_tracking" != xno \+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])+])+++# AM_SET_DEPDIR+# -------------+# Choose a directory name for dependency files.+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.+AC_DEFUN([AM_SET_DEPDIR],+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl+])+++# AM_DEP_TRACK+# ------------+AC_DEFUN([AM_DEP_TRACK],+[AC_ARG_ENABLE([dependency-tracking], [dnl+AS_HELP_STRING(+  [--enable-dependency-tracking],+  [do not reject slow dependency extractors])+AS_HELP_STRING(+  [--disable-dependency-tracking],+  [speeds up one-time build])])+if test "x$enable_dependency_tracking" != xno; then+  am_depcomp="$ac_aux_dir/depcomp"+  AMDEPBACKSLASH='\'+  am__nodep='_no'+fi+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])+AC_SUBST([AMDEPBACKSLASH])dnl+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl+AC_SUBST([am__nodep])dnl+_AM_SUBST_NOTMAKE([am__nodep])dnl+])++# Generate code to set up dependency tracking.              -*- Autoconf -*-++# Copyright (C) 1999-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# _AM_OUTPUT_DEPENDENCY_COMMANDS+# ------------------------------+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],+[{+  # Older Autoconf quotes --file arguments for eval, but not when files+  # are listed without --file.  Let's play safe and only enable the eval+  # if we detect the quoting.+  # TODO: see whether this extra hack can be removed once we start+  # requiring Autoconf 2.70 or later.+  AS_CASE([$CONFIG_FILES],+          [*\'*], [eval set x "$CONFIG_FILES"],+          [*], [set x $CONFIG_FILES])+  shift+  # Used to flag and report bootstrapping failures.+  am_rc=0+  for am_mf+  do+    # Strip MF so we end up with the name of the file.+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`+    # Check whether this is an Automake generated Makefile which includes+    # dependency-tracking related rules and includes.+    # Grep'ing the whole file directly is not great: AIX grep has a line+    # limit of 2048, but all sed's we know have understand at least 4000.+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \+      || continue+    am_dirpart=`AS_DIRNAME(["$am_mf"])`+    am_filepart=`AS_BASENAME(["$am_mf"])`+    AM_RUN_LOG([cd "$am_dirpart" \+      && sed -e '/# am--include-marker/d' "$am_filepart" \+        | $MAKE -f - am--depfiles]) || am_rc=$?+  done+  if test $am_rc -ne 0; then+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments+    for automatic dependency tracking.  If GNU make was not used, consider+    re-running the configure script with MAKE="gmake" (or whatever is+    necessary).  You can also try re-running configure with the+    '--disable-dependency-tracking' option to at least be able to build+    the package (albeit without support for automatic dependency tracking).])+  fi+  AS_UNSET([am_dirpart])+  AS_UNSET([am_filepart])+  AS_UNSET([am_mf])+  AS_UNSET([am_rc])+  rm -f conftest-deps.mk+}+])# _AM_OUTPUT_DEPENDENCY_COMMANDS+++# AM_OUTPUT_DEPENDENCY_COMMANDS+# -----------------------------+# This macro should only be invoked once -- use via AC_REQUIRE.+#+# This code is only required when automatic dependency tracking is enabled.+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in+# order to bootstrap the dependency handling code.+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],+[AC_CONFIG_COMMANDS([depfiles],+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])++# Do all the work for Automake.                             -*- Autoconf -*-++# Copyright (C) 1996-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# This macro actually does too much.  Some checks are only needed if+# your package does certain things.  But this isn't really a big deal.++dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.+m4_define([AC_PROG_CC],+m4_defn([AC_PROG_CC])+[_AM_PROG_CC_C_O+])++# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])+# AM_INIT_AUTOMAKE([OPTIONS])+# -----------------------------------------------+# The call with PACKAGE and VERSION arguments is the old style+# call (pre autoconf-2.50), which is being phased out.  PACKAGE+# and VERSION should now be passed to AC_INIT and removed from+# the call to AM_INIT_AUTOMAKE.+# We support both call styles for the transition.  After+# the next Automake release, Autoconf can make the AC_INIT+# arguments mandatory, and then we can depend on a new Autoconf+# release and drop the old call support.+AC_DEFUN([AM_INIT_AUTOMAKE],+[AC_PREREQ([2.65])dnl+m4_ifdef([_$0_ALREADY_INIT],+  [m4_fatal([$0 expanded multiple times+]m4_defn([_$0_ALREADY_INIT]))],+  [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl+dnl Autoconf wants to disallow AM_ names.  We explicitly allow+dnl the ones we care about.+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl+AC_REQUIRE([AC_PROG_INSTALL])dnl+if test "`cd $srcdir && pwd`" != "`pwd`"; then+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output+  # is not polluted with repeated "-I."+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl+  # test to see if srcdir already configured+  if test -f $srcdir/config.status; then+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])+  fi+fi++# test whether we have cygpath+if test -z "$CYGPATH_W"; then+  if (cygpath --version) >/dev/null 2>/dev/null; then+    CYGPATH_W='cygpath -w'+  else+    CYGPATH_W=echo+  fi+fi+AC_SUBST([CYGPATH_W])++# Define the identity of the package.+dnl Distinguish between old-style and new-style calls.+m4_ifval([$2],+[AC_DIAGNOSE([obsolete],+             [$0: two- and three-arguments forms are deprecated.])+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl+ AC_SUBST([PACKAGE], [$1])dnl+ AC_SUBST([VERSION], [$2])],+[_AM_SET_OPTIONS([$1])dnl+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.+m4_if(+  m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),+  [ok:ok],,+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl++_AM_IF_OPTION([no-define],,+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl++# Some tools Automake needs.+AC_REQUIRE([AM_SANITY_CHECK])dnl+AC_REQUIRE([AC_ARG_PROGRAM])dnl+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])+AM_MISSING_PROG([AUTOCONF], [autoconf])+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])+AM_MISSING_PROG([AUTOHEADER], [autoheader])+AM_MISSING_PROG([MAKEINFO], [makeinfo])+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl+AC_REQUIRE([AC_PROG_MKDIR_P])dnl+# For better backward compatibility.  To be removed once Automake 1.9.x+# dies out for good.  For more background, see:+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])+# We need awk for the "check" target (and possibly the TAP driver).  The+# system "awk" is bad on some platforms.+AC_REQUIRE([AC_PROG_AWK])dnl+AC_REQUIRE([AC_PROG_MAKE_SET])dnl+AC_REQUIRE([AM_SET_LEADING_DOT])dnl+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],+  [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],+    [_AM_IF_OPTION([tar-v7], [_AM_PROG_TAR([v7])],+      [_AM_PROG_TAR([ustar])])])])+_AM_IF_OPTION([no-dependencies],,+[AC_PROVIDE_IFELSE([AC_PROG_CC],+		  [_AM_DEPENDENCIES([CC])],+		  [m4_define([AC_PROG_CC],+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl+AC_PROVIDE_IFELSE([AC_PROG_CXX],+		  [_AM_DEPENDENCIES([CXX])],+		  [m4_define([AC_PROG_CXX],+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl+AC_PROVIDE_IFELSE([AC_PROG_OBJC],+		  [_AM_DEPENDENCIES([OBJC])],+		  [m4_define([AC_PROG_OBJC],+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],+		  [_AM_DEPENDENCIES([OBJCXX])],+		  [m4_define([AC_PROG_OBJCXX],+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl+])+# Variables for tags utilities; see am/tags.am+if test -z "$CTAGS"; then+  CTAGS=ctags+fi+AC_SUBST([CTAGS])+if test -z "$ETAGS"; then+  ETAGS=etags+fi+AC_SUBST([ETAGS])+if test -z "$CSCOPE"; then+  CSCOPE=cscope+fi+AC_SUBST([CSCOPE])++AC_REQUIRE([_AM_SILENT_RULES])dnl+dnl The testsuite driver may need to know about EXEEXT, so add the+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.+AC_CONFIG_COMMANDS_PRE(dnl+[m4_provide_if([_AM_COMPILER_EXEEXT],+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl++AC_REQUIRE([_AM_PROG_RM_F])+AC_REQUIRE([_AM_PROG_XARGS_N])++dnl The trailing newline in this macro's definition is deliberate, for+dnl backward compatibility and to allow trailing 'dnl'-style comments+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.+])++dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further+dnl mangled by Autoconf and run in a shell conditional statement.+m4_define([_AC_COMPILER_EXEEXT],+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])++# When config.status generates a header, we must update the stamp-h file.+# This file resides in the same directory as the config header+# that is generated.  The stamp files are numbered to have different names.++# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the+# loop where config.status creates the headers, so we can generate+# our stamp files there.+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],+[# Compute $1's index in $config_headers.+_am_arg=$1+_am_stamp_count=1+for _am_header in $config_headers :; do+  case $_am_header in+    $_am_arg | $_am_arg:* )+      break ;;+    * )+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;+  esac+done+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])++# Copyright (C) 2003-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# Check whether the underlying file-system supports filenames+# with a leading dot.  For instance MS-DOS doesn't.+AC_DEFUN([AM_SET_LEADING_DOT],+[rm -rf .tst 2>/dev/null+mkdir .tst 2>/dev/null+if test -d .tst; then+  am__leading_dot=.+else+  am__leading_dot=_+fi+rmdir .tst 2>/dev/null+AC_SUBST([am__leading_dot])])++# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-+# From Jim Meyering++# Copyright (C) 1996-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# AM_MAINTAINER_MODE([DEFAULT-MODE])+# ----------------------------------+# Control maintainer-specific portions of Makefiles.+# Default is to disable them, unless 'enable' is passed literally.+# For symmetry, 'disable' may be passed as well.  Anyway, the user+# can override the default with the --enable/--disable switch.+AC_DEFUN([AM_MAINTAINER_MODE],+[m4_case(m4_default([$1], [disable]),+       [enable], [m4_define([am_maintainer_other], [disable])],+       [disable], [m4_define([am_maintainer_other], [enable])],+       [m4_define([am_maintainer_other], [enable])+        m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed+  AC_ARG_ENABLE([maintainer-mode],+    [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],+      am_maintainer_other[ make rules and dependencies not useful+      (and sometimes confusing) to the casual installer])],+    [USE_MAINTAINER_MODE=$enableval],+    [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])+  MAINT=$MAINTAINER_MODE_TRUE+  AC_SUBST([MAINT])dnl+]+)++# Check to see how 'make' treats includes.	            -*- Autoconf -*-++# Copyright (C) 2001-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# AM_MAKE_INCLUDE()+# -----------------+# Check whether make has an 'include' directive that can support all+# the idioms we need for our automatic dependency tracking code.+AC_DEFUN([AM_MAKE_INCLUDE],+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])+cat > confinc.mk << 'END'+am__doit:+	@echo this is the am__doit target >confinc.out+.PHONY: am__doit+END+am__include="#"+am__quote=+# BSD make does it like this.+echo '.include "confinc.mk" # ignored' > confmf.BSD+# Other make implementations (GNU, Solaris 10, AIX) do it like this.+echo 'include confinc.mk # ignored' > confmf.GNU+_am_result=no+for s in GNU BSD; do+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],+      ['0:this is the am__doit target'],+      [AS_CASE([$s],+          [BSD], [am__include='.include' am__quote='"'],+          [am__include='include' am__quote=''])])+  if test "$am__include" != "#"; then+    _am_result="yes ($s style)"+    break+  fi+done+rm -f confinc.* confmf.*+AC_MSG_RESULT([${_am_result}])+AC_SUBST([am__include])])+AC_SUBST([am__quote])])++# Helper functions for option handling.                     -*- Autoconf -*-++# Copyright (C) 2001-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# _AM_MANGLE_OPTION(NAME)+# -----------------------+AC_DEFUN([_AM_MANGLE_OPTION],+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])++# _AM_SET_OPTION(NAME)+# --------------------+# Set option NAME.  Presently that only means defining a flag for this option.+AC_DEFUN([_AM_SET_OPTION],+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])++# _AM_SET_OPTIONS(OPTIONS)+# ------------------------+# OPTIONS is a space-separated list of Automake options.+AC_DEFUN([_AM_SET_OPTIONS],+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])++# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])+# -------------------------------------------+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.+AC_DEFUN([_AM_IF_OPTION],+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])++# Copyright (C) 1999-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# _AM_PROG_CC_C_O+# ---------------+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC+# to automatically call this.+AC_DEFUN([_AM_PROG_CC_C_O],+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl+AC_REQUIRE_AUX_FILE([compile])dnl+AC_LANG_PUSH([C])dnl+AC_CACHE_CHECK(+  [whether $CC understands -c and -o together],+  [am_cv_prog_cc_c_o],+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])+  # Make sure it works both with $CC and with simple cc.+  # Following AC_PROG_CC_C_O, we do the test twice because some+  # compilers refuse to overwrite an existing .o file with -o,+  # though they will create one.+  am_cv_prog_cc_c_o=yes+  for am_i in 1 2; do+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \+         && test -f conftest2.$ac_objext; then+      : OK+    else+      am_cv_prog_cc_c_o=no+      break+    fi+  done+  # aligned with autoconf, so not including core; see bug#72225.+  rm -f -r a.out a.exe b.out conftest.$ac_ext conftest.$ac_objext \+    conftest.dSYM conftest1.$ac_ext conftest1.$ac_objext conftest1.dSYM \+    conftest2.$ac_ext conftest2.$ac_objext conftest2.dSYM+  unset am_i])+if test "$am_cv_prog_cc_c_o" != yes; then+   # Losing compiler, so override with the script.+   # FIXME: It is wrong to rewrite CC.+   # But if we don't then we get into trouble of one sort or another.+   # A longer-term fix would be to have automake use am__CC in this case,+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"+   CC="$am_aux_dir/compile $CC"+fi+AC_LANG_POP([C])])++# For backward compatibility.+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])++# Copyright (C) 2001-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# AM_RUN_LOG(COMMAND)+# -------------------+# Run COMMAND, save the exit status in ac_status, and log it.+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)+AC_DEFUN([AM_RUN_LOG],+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD+   ac_status=$?+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD+   (exit $ac_status); }])++# Copyright (C) 2006-2025 Free Software Foundation, Inc.+#+# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# _AM_SUBST_NOTMAKE(VARIABLE)+# ---------------------------+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.+# This macro is traced by Automake.+AC_DEFUN([_AM_SUBST_NOTMAKE])++# AM_SUBST_NOTMAKE(VARIABLE)+# --------------------------+# Public sister of _AM_SUBST_NOTMAKE.+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])++m4_include([m4/asmcfi.m4])+m4_include([m4/ax_cc_maxopt.m4])+m4_include([m4/ax_cflags_warn_all.m4])+m4_include([m4/ax_check_compile_flag.m4])+m4_include([m4/ax_compiler_vendor.m4])+m4_include([m4/ax_configure_args.m4])+m4_include([m4/ax_enable_builddir.m4])+m4_include([m4/ax_gcc_archflag.m4])+m4_include([m4/ax_gcc_x86_cpuid.m4])+m4_include([m4/ax_prepend_flag.m4])+m4_include([m4/ax_require_defined.m4])+m4_include([m4/libtool.m4])+m4_include([m4/lt_undescore.m4])+m4_include([m4/ltoptions.m4])+m4_include([m4/ltsugar.m4])+m4_include([m4/ltversion.m4])+m4_include([m4/lt~obsolete.m4])+m4_include([acinclude.m4])
+ compile view
@@ -0,0 +1,351 @@+#! /bin/sh+# Wrapper for compilers which do not understand '-c -o'.++scriptversion=2024-06-19.01; # UTC++# Copyright (C) 1999-2024 Free Software Foundation, Inc.+# Written by Tom Tromey <tromey@cygnus.com>.+#+# 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, or (at your option)+# any later version.+#+# This program is distributed in the hope that it will be useful,+# but WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+# GNU General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program.  If not, see <https://www.gnu.org/licenses/>.++# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program that contains a+# configuration script generated by Autoconf, you may include it under+# the same distribution terms that you use for the rest of that program.++# This file is maintained in Automake, please report+# bugs to <bug-automake@gnu.org> or send patches to+# <automake-patches@gnu.org>.++nl='+'++# We need space, tab and new line, in precisely that order.  Quoting is+# there to prevent tools from complaining about whitespace usage.+IFS=" ""	$nl"++file_conv=++# func_file_conv build_file lazy+# Convert a $build file to $host form and store it in $file+# Currently only supports Windows hosts. If the determined conversion+# type is listed in (the comma separated) LAZY, no conversion will+# take place.+func_file_conv ()+{+  file=$1+  case $file in+    / | /[!/]*) # absolute file, and not a UNC file+      if test -z "$file_conv"; then+	# lazily determine how to convert abs files+	case `uname -s` in+	  MINGW*)+	    file_conv=mingw+	    ;;+	  CYGWIN* | MSYS*)+	    file_conv=cygwin+	    ;;+	  *)+	    file_conv=wine+	    ;;+	esac+      fi+      case $file_conv/,$2, in+	*,$file_conv,*)+	  ;;+	mingw/*)+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`+	  ;;+	cygwin/* | msys/*)+	  file=`cygpath -m "$file" || echo "$file"`+	  ;;+	wine/*)+	  file=`winepath -w "$file" || echo "$file"`+	  ;;+      esac+      ;;+  esac+}++# func_cl_dashL linkdir+# Make cl look for libraries in LINKDIR+func_cl_dashL ()+{+  func_file_conv "$1"+  if test -z "$lib_path"; then+    lib_path=$file+  else+    lib_path="$lib_path;$file"+  fi+  linker_opts="$linker_opts -LIBPATH:$file"+}++# func_cl_dashl library+# Do a library search-path lookup for cl+func_cl_dashl ()+{+  lib=$1+  found=no+  save_IFS=$IFS+  IFS=';'+  for dir in $lib_path $LIB+  do+    IFS=$save_IFS+    if $shared && test -f "$dir/$lib.dll.lib"; then+      found=yes+      lib=$dir/$lib.dll.lib+      break+    fi+    if test -f "$dir/$lib.lib"; then+      found=yes+      lib=$dir/$lib.lib+      break+    fi+    if test -f "$dir/lib$lib.a"; then+      found=yes+      lib=$dir/lib$lib.a+      break+    fi+  done+  IFS=$save_IFS++  if test "$found" != yes; then+    lib=$lib.lib+  fi+}++# func_cl_wrapper cl arg...+# Adjust compile command to suit cl+func_cl_wrapper ()+{+  # Assume a capable shell+  lib_path=+  shared=:+  linker_opts=+  for arg+  do+    if test -n "$eat"; then+      eat=+    else+      case $1 in+	-o)+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.+	  eat=1+	  case $2 in+	    *.o | *.lo | *.[oO][bB][jJ])+	      func_file_conv "$2"+	      set x "$@" -Fo"$file"+	      shift+	      ;;+	    *)+	      func_file_conv "$2"+	      set x "$@" -Fe"$file"+	      shift+	      ;;+	  esac+	  ;;+	-I)+	  eat=1+	  func_file_conv "$2" mingw+	  set x "$@" -I"$file"+	  shift+	  ;;+	-I*)+	  func_file_conv "${1#-I}" mingw+	  set x "$@" -I"$file"+	  shift+	  ;;+	-l)+	  eat=1+	  func_cl_dashl "$2"+	  set x "$@" "$lib"+	  shift+	  ;;+	-l*)+	  func_cl_dashl "${1#-l}"+	  set x "$@" "$lib"+	  shift+	  ;;+	-L)+	  eat=1+	  func_cl_dashL "$2"+	  ;;+	-L*)+	  func_cl_dashL "${1#-L}"+	  ;;+	-static)+	  shared=false+	  ;;+	-Wl,*)+	  arg=${1#-Wl,}+	  save_ifs="$IFS"; IFS=','+	  for flag in $arg; do+	    IFS="$save_ifs"+	    linker_opts="$linker_opts $flag"+	  done+	  IFS="$save_ifs"+	  ;;+	-Xlinker)+	  eat=1+	  linker_opts="$linker_opts $2"+	  ;;+	-*)+	  set x "$@" "$1"+	  shift+	  ;;+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)+	  func_file_conv "$1"+	  set x "$@" -Tp"$file"+	  shift+	  ;;+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])+	  func_file_conv "$1" mingw+	  set x "$@" "$file"+	  shift+	  ;;+	*)+	  set x "$@" "$1"+	  shift+	  ;;+      esac+    fi+    shift+  done+  if test -n "$linker_opts"; then+    linker_opts="-link$linker_opts"+  fi+  exec "$@" $linker_opts+  exit 1+}++eat=++case $1 in+  '')+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2+     exit 1;+     ;;+  -h | --h*)+    cat <<\EOF+Usage: compile [--help] [--version] PROGRAM [ARGS]++Wrapper for compilers which do not understand '-c -o'.+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining+arguments, and rename the output as expected.++If you are trying to build a whole package this is not the+right script to run: please start by reading the file 'INSTALL'.++Report bugs to <bug-automake@gnu.org>.+GNU Automake home page: <https://www.gnu.org/software/automake/>.+General help using GNU software: <https://www.gnu.org/gethelp/>.+EOF+    exit $?+    ;;+  -v | --v*)+    echo "compile (GNU Automake) $scriptversion"+    exit $?+    ;;+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \+  clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \+  icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )+    func_cl_wrapper "$@"      # Doesn't return...+    ;;+esac++ofile=+cfile=++for arg+do+  if test -n "$eat"; then+    eat=+  else+    case $1 in+      -o)+	# configure might choose to run compile as 'compile cc -o foo foo.c'.+	# So we strip '-o arg' only if arg is an object.+	eat=1+	case $2 in+	  *.o | *.obj)+	    ofile=$2+	    ;;+	  *)+	    set x "$@" -o "$2"+	    shift+	    ;;+	esac+	;;+      *.c)+	cfile=$1+	set x "$@" "$1"+	shift+	;;+      *)+	set x "$@" "$1"+	shift+	;;+    esac+  fi+  shift+done++if test -z "$ofile" || test -z "$cfile"; then+  # If no '-o' option was seen then we might have been invoked from a+  # pattern rule where we don't need one.  That is ok -- this is a+  # normal compilation that the losing compiler can handle.  If no+  # '.c' file was seen then we are probably linking.  That is also+  # ok.+  exec "$@"+fi++# Name of file we expect compiler to create.+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`++# Create the lock directory.+# Note: use '[/\\:.-]' here to ensure that we don't use the same name+# that we are using for the .o file.  Also, base the name on the expected+# object file name, since that is what matters with a parallel build.+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d+while true; do+  if mkdir "$lockdir" >/dev/null 2>&1; then+    break+  fi+  sleep 1+done+# FIXME: race condition here if user kills between mkdir and trap.+trap "rmdir '$lockdir'; exit 1" 1 2 15++# Run the compile.+"$@"+ret=$?++if test -f "$cofile"; then+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"+elif test -f "${cofile}bj"; then+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"+fi++rmdir "$lockdir"+exit $ret++# Local Variables:+# mode: shell-script+# sh-indentation: 2+# eval: (add-hook 'before-save-hook 'time-stamp)+# time-stamp-start: "scriptversion="+# time-stamp-format: "%:y-%02m-%02d.%02H"+# time-stamp-time-zone: "UTC0"+# time-stamp-end: "; # UTC"+# End:
+ config.guess view
@@ -0,0 +1,1812 @@+#! /bin/sh+# Attempt to guess a canonical system name.+#   Copyright 1992-2024 Free Software Foundation, Inc.++# shellcheck disable=SC2006,SC2268 # see below for rationale++timestamp='2024-01-01'++# This file is free software; you can redistribute it and/or modify it+# under the terms of the GNU General Public License as published by+# the Free Software Foundation, either version 3 of the License, or+# (at your option) any later version.+#+# This program is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+# General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program; if not, see <https://www.gnu.org/licenses/>.+#+# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program that contains a+# configuration script generated by Autoconf, you may include it under+# the same distribution terms that you use for the rest of that+# program.  This Exception is an additional permission under section 7+# of the GNU General Public License, version 3 ("GPLv3").+#+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.+#+# You can get the latest version of this script from:+# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess+#+# Please send patches to <config-patches@gnu.org>.+++# The "shellcheck disable" line above the timestamp inhibits complaints+# about features and limitations of the classic Bourne shell that were+# superseded or lifted in POSIX.  However, this script identifies a wide+# variety of pre-POSIX systems that do not have POSIX shells at all, and+# even some reasonably current systems (Solaris 10 as case-in-point) still+# have a pre-POSIX /bin/sh.+++me=`echo "$0" | sed -e 's,.*/,,'`++usage="\+Usage: $0 [OPTION]++Output the configuration name of the system '$me' is run on.++Options:+  -h, --help         print this help, then exit+  -t, --time-stamp   print date of last modification, then exit+  -v, --version      print version number, then exit++Report bugs and patches to <config-patches@gnu.org>."++version="\+GNU config.guess ($timestamp)++Originally written by Per Bothner.+Copyright 1992-2024 Free Software Foundation, Inc.++This is free software; see the source for copying conditions.  There is NO+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."++help="+Try '$me --help' for more information."++# Parse command line+while test $# -gt 0 ; do+  case $1 in+    --time-stamp | --time* | -t )+       echo "$timestamp" ; exit ;;+    --version | -v )+       echo "$version" ; exit ;;+    --help | --h* | -h )+       echo "$usage"; exit ;;+    -- )     # Stop option processing+       shift; break ;;+    - )	# Use stdin as input.+       break ;;+    -* )+       echo "$me: invalid option $1$help" >&2+       exit 1 ;;+    * )+       break ;;+  esac+done++if test $# != 0; then+  echo "$me: too many arguments$help" >&2+  exit 1+fi++# Just in case it came from the environment.+GUESS=++# CC_FOR_BUILD -- compiler used by this script. Note that the use of a+# compiler to aid in system detection is discouraged as it requires+# temporary files to be created and, as you can see below, it is a+# headache to deal with in a portable fashion.++# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still+# use 'HOST_CC' if defined, but it is deprecated.++# Portable tmp directory creation inspired by the Autoconf team.++tmp=+# shellcheck disable=SC2172+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15++set_cc_for_build() {+    # prevent multiple calls if $tmp is already set+    test "$tmp" && return 0+    : "${TMPDIR=/tmp}"+    # shellcheck disable=SC2039,SC3028+    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||+	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||+	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||+	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }+    dummy=$tmp/dummy+    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in+	,,)    echo "int x;" > "$dummy.c"+	       for driver in cc gcc c89 c99 ; do+		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then+		       CC_FOR_BUILD=$driver+		       break+		   fi+	       done+	       if test x"$CC_FOR_BUILD" = x ; then+		   CC_FOR_BUILD=no_compiler_found+	       fi+	       ;;+	,,*)   CC_FOR_BUILD=$CC ;;+	,*,*)  CC_FOR_BUILD=$HOST_CC ;;+    esac+}++# This is needed to find uname on a Pyramid OSx when run in the BSD universe.+# (ghazi@noc.rutgers.edu 1994-08-24)+if test -f /.attbin/uname ; then+	PATH=$PATH:/.attbin ; export PATH+fi++UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown++case $UNAME_SYSTEM in+Linux|GNU|GNU/*)+	LIBC=unknown++	set_cc_for_build+	cat <<-EOF > "$dummy.c"+	#if defined(__ANDROID__)+	LIBC=android+	#else+	#include <features.h>+	#if defined(__UCLIBC__)+	LIBC=uclibc+	#elif defined(__dietlibc__)+	LIBC=dietlibc+	#elif defined(__GLIBC__)+	LIBC=gnu+	#elif defined(__LLVM_LIBC__)+	LIBC=llvm+	#else+	#include <stdarg.h>+	/* First heuristic to detect musl libc.  */+	#ifdef __DEFINED_va_list+	LIBC=musl+	#endif+	#endif+	#endif+	EOF+	cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`+	eval "$cc_set_libc"++	# Second heuristic to detect musl libc.+	if [ "$LIBC" = unknown ] &&+	   command -v ldd >/dev/null &&+	   ldd --version 2>&1 | grep -q ^musl; then+		LIBC=musl+	fi++	# If the system lacks a compiler, then just pick glibc.+	# We could probably try harder.+	if [ "$LIBC" = unknown ]; then+		LIBC=gnu+	fi+	;;+esac++# Note: order is significant - the case branches are not exclusive.++case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in+    *:NetBSD:*:*)+	# NetBSD (nbsd) targets should (where applicable) match one or+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently+	# switched to ELF, *-*-netbsd* would select the old+	# object file format.  This provides both forward+	# compatibility and a consistent mechanism for selecting the+	# object file format.+	#+	# Note: NetBSD doesn't particularly care about the vendor+	# portion of the name.  We always set it to "unknown".+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \+	    /sbin/sysctl -n hw.machine_arch 2>/dev/null || \+	    /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \+	    echo unknown)`+	case $UNAME_MACHINE_ARCH in+	    aarch64eb) machine=aarch64_be-unknown ;;+	    armeb) machine=armeb-unknown ;;+	    arm*) machine=arm-unknown ;;+	    sh3el) machine=shl-unknown ;;+	    sh3eb) machine=sh-unknown ;;+	    sh5el) machine=sh5le-unknown ;;+	    earmv*)+		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`+		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`+		machine=${arch}${endian}-unknown+		;;+	    *) machine=$UNAME_MACHINE_ARCH-unknown ;;+	esac+	# The Operating System including object format, if it has switched+	# to ELF recently (or will in the future) and ABI.+	case $UNAME_MACHINE_ARCH in+	    earm*)+		os=netbsdelf+		;;+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)+		set_cc_for_build+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \+			| grep -q __ELF__+		then+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).+		    # Return netbsd for either.  FIX?+		    os=netbsd+		else+		    os=netbsdelf+		fi+		;;+	    *)+		os=netbsd+		;;+	esac+	# Determine ABI tags.+	case $UNAME_MACHINE_ARCH in+	    earm*)+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'+		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`+		;;+	esac+	# The OS release+	# Debian GNU/NetBSD machines have a different userland, and+	# thus, need a distinct triplet. However, they do not need+	# kernel version information, so it can be replaced with a+	# suitable tag, in the style of linux-gnu.+	case $UNAME_VERSION in+	    Debian*)+		release='-gnu'+		;;+	    *)+		release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`+		;;+	esac+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:+	# contains redundant information, the shorter form:+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.+	GUESS=$machine-${os}${release}${abi-}+	;;+    *:Bitrig:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`+	GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE+	;;+    *:OpenBSD:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`+	GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE+	;;+    *:SecBSD:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`+	GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE+	;;+    *:LibertyBSD:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`+	GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE+	;;+    *:MidnightBSD:*:*)+	GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE+	;;+    *:ekkoBSD:*:*)+	GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE+	;;+    *:SolidBSD:*:*)+	GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE+	;;+    *:OS108:*:*)+	GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE+	;;+    macppc:MirBSD:*:*)+	GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE+	;;+    *:MirBSD:*:*)+	GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE+	;;+    *:Sortix:*:*)+	GUESS=$UNAME_MACHINE-unknown-sortix+	;;+    *:Twizzler:*:*)+	GUESS=$UNAME_MACHINE-unknown-twizzler+	;;+    *:Redox:*:*)+	GUESS=$UNAME_MACHINE-unknown-redox+	;;+    mips:OSF1:*.*)+	GUESS=mips-dec-osf1+	;;+    alpha:OSF1:*:*)+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.+	trap '' 0+	case $UNAME_RELEASE in+	*4.0)+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`+		;;+	*5.*)+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`+		;;+	esac+	# According to Compaq, /usr/sbin/psrinfo has been available on+	# OSF/1 and Tru64 systems produced since 1995.  I hope that+	# covers most systems running today.  This code pipes the CPU+	# types through head -n 1, so we only detect the type of CPU 0.+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`+	case $ALPHA_CPU_TYPE in+	    "EV4 (21064)")+		UNAME_MACHINE=alpha ;;+	    "EV4.5 (21064)")+		UNAME_MACHINE=alpha ;;+	    "LCA4 (21066/21068)")+		UNAME_MACHINE=alpha ;;+	    "EV5 (21164)")+		UNAME_MACHINE=alphaev5 ;;+	    "EV5.6 (21164A)")+		UNAME_MACHINE=alphaev56 ;;+	    "EV5.6 (21164PC)")+		UNAME_MACHINE=alphapca56 ;;+	    "EV5.7 (21164PC)")+		UNAME_MACHINE=alphapca57 ;;+	    "EV6 (21264)")+		UNAME_MACHINE=alphaev6 ;;+	    "EV6.7 (21264A)")+		UNAME_MACHINE=alphaev67 ;;+	    "EV6.8CB (21264C)")+		UNAME_MACHINE=alphaev68 ;;+	    "EV6.8AL (21264B)")+		UNAME_MACHINE=alphaev68 ;;+	    "EV6.8CX (21264D)")+		UNAME_MACHINE=alphaev68 ;;+	    "EV6.9A (21264/EV69A)")+		UNAME_MACHINE=alphaev69 ;;+	    "EV7 (21364)")+		UNAME_MACHINE=alphaev7 ;;+	    "EV7.9 (21364A)")+		UNAME_MACHINE=alphaev79 ;;+	esac+	# A Pn.n version is a patched version.+	# A Vn.n version is a released version.+	# A Tn.n version is a released field test version.+	# A Xn.n version is an unreleased experimental baselevel.+	# 1.2 uses "1.2" for uname -r.+	OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`+	GUESS=$UNAME_MACHINE-dec-osf$OSF_REL+	;;+    Amiga*:UNIX_System_V:4.0:*)+	GUESS=m68k-unknown-sysv4+	;;+    *:[Aa]miga[Oo][Ss]:*:*)+	GUESS=$UNAME_MACHINE-unknown-amigaos+	;;+    *:[Mm]orph[Oo][Ss]:*:*)+	GUESS=$UNAME_MACHINE-unknown-morphos+	;;+    *:OS/390:*:*)+	GUESS=i370-ibm-openedition+	;;+    *:z/VM:*:*)+	GUESS=s390-ibm-zvmoe+	;;+    *:OS400:*:*)+	GUESS=powerpc-ibm-os400+	;;+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)+	GUESS=arm-acorn-riscix$UNAME_RELEASE+	;;+    arm*:riscos:*:*|arm*:RISCOS:*:*)+	GUESS=arm-unknown-riscos+	;;+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)+	GUESS=hppa1.1-hitachi-hiuxmpp+	;;+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.+	case `(/bin/universe) 2>/dev/null` in+	    att) GUESS=pyramid-pyramid-sysv3 ;;+	    *)   GUESS=pyramid-pyramid-bsd   ;;+	esac+	;;+    NILE*:*:*:dcosx)+	GUESS=pyramid-pyramid-svr4+	;;+    DRS?6000:unix:4.0:6*)+	GUESS=sparc-icl-nx6+	;;+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)+	case `/usr/bin/uname -p` in+	    sparc) GUESS=sparc-icl-nx7 ;;+	esac+	;;+    s390x:SunOS:*:*)+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`+	GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL+	;;+    sun4H:SunOS:5.*:*)+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`+	GUESS=sparc-hal-solaris2$SUN_REL+	;;+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`+	GUESS=sparc-sun-solaris2$SUN_REL+	;;+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)+	GUESS=i386-pc-auroraux$UNAME_RELEASE+	;;+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)+	set_cc_for_build+	SUN_ARCH=i386+	# If there is a compiler, see if it is configured for 64-bit objects.+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.+	# This test works for both compilers.+	if test "$CC_FOR_BUILD" != no_compiler_found; then+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \+		(CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \+		grep IS_64BIT_ARCH >/dev/null+	    then+		SUN_ARCH=x86_64+	    fi+	fi+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`+	GUESS=$SUN_ARCH-pc-solaris2$SUN_REL+	;;+    sun4*:SunOS:6*:*)+	# According to config.sub, this is the proper way to canonicalize+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but+	# it's likely to be more like Solaris than SunOS4.+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`+	GUESS=sparc-sun-solaris3$SUN_REL+	;;+    sun4*:SunOS:*:*)+	case `/usr/bin/arch -k` in+	    Series*|S4*)+		UNAME_RELEASE=`uname -v`+		;;+	esac+	# Japanese Language versions have a version number like '4.1.3-JL'.+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`+	GUESS=sparc-sun-sunos$SUN_REL+	;;+    sun3*:SunOS:*:*)+	GUESS=m68k-sun-sunos$UNAME_RELEASE+	;;+    sun*:*:4.2BSD:*)+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`+	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3+	case `/bin/arch` in+	    sun3)+		GUESS=m68k-sun-sunos$UNAME_RELEASE+		;;+	    sun4)+		GUESS=sparc-sun-sunos$UNAME_RELEASE+		;;+	esac+	;;+    aushp:SunOS:*:*)+	GUESS=sparc-auspex-sunos$UNAME_RELEASE+	;;+    # The situation for MiNT is a little confusing.  The machine name+    # can be virtually everything (everything which is not+    # "atarist" or "atariste" at least should have a processor+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"+    # to the lowercase version "mint" (or "freemint").  Finally+    # the system name "TOS" denotes a system which is actually not+    # MiNT.  But MiNT is downward compatible to TOS, so this should+    # be no problem.+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)+	GUESS=m68k-atari-mint$UNAME_RELEASE+	;;+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)+	GUESS=m68k-atari-mint$UNAME_RELEASE+	;;+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)+	GUESS=m68k-atari-mint$UNAME_RELEASE+	;;+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)+	GUESS=m68k-milan-mint$UNAME_RELEASE+	;;+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)+	GUESS=m68k-hades-mint$UNAME_RELEASE+	;;+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)+	GUESS=m68k-unknown-mint$UNAME_RELEASE+	;;+    m68k:machten:*:*)+	GUESS=m68k-apple-machten$UNAME_RELEASE+	;;+    powerpc:machten:*:*)+	GUESS=powerpc-apple-machten$UNAME_RELEASE+	;;+    RISC*:Mach:*:*)+	GUESS=mips-dec-mach_bsd4.3+	;;+    RISC*:ULTRIX:*:*)+	GUESS=mips-dec-ultrix$UNAME_RELEASE+	;;+    VAX*:ULTRIX*:*:*)+	GUESS=vax-dec-ultrix$UNAME_RELEASE+	;;+    2020:CLIX:*:* | 2430:CLIX:*:*)+	GUESS=clipper-intergraph-clix$UNAME_RELEASE+	;;+    mips:*:*:UMIPS | mips:*:*:RISCos)+	set_cc_for_build+	sed 's/^	//' << EOF > "$dummy.c"+#ifdef __cplusplus+#include <stdio.h>  /* for printf() prototype */+	int main (int argc, char *argv[]) {+#else+	int main (argc, argv) int argc; char *argv[]; {+#endif+	#if defined (host_mips) && defined (MIPSEB)+	#if defined (SYSTYPE_SYSV)+	  printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);+	#endif+	#if defined (SYSTYPE_SVR4)+	  printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);+	#endif+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)+	  printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);+	#endif+	#endif+	  exit (-1);+	}+EOF+	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&+	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&+	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&+	    { echo "$SYSTEM_NAME"; exit; }+	GUESS=mips-mips-riscos$UNAME_RELEASE+	;;+    Motorola:PowerMAX_OS:*:*)+	GUESS=powerpc-motorola-powermax+	;;+    Motorola:*:4.3:PL8-*)+	GUESS=powerpc-harris-powermax+	;;+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)+	GUESS=powerpc-harris-powermax+	;;+    Night_Hawk:Power_UNIX:*:*)+	GUESS=powerpc-harris-powerunix+	;;+    m88k:CX/UX:7*:*)+	GUESS=m88k-harris-cxux7+	;;+    m88k:*:4*:R4*)+	GUESS=m88k-motorola-sysv4+	;;+    m88k:*:3*:R3*)+	GUESS=m88k-motorola-sysv3+	;;+    AViiON:dgux:*:*)+	# DG/UX returns AViiON for all architectures+	UNAME_PROCESSOR=`/usr/bin/uname -p`+	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110+	then+	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \+	       test "$TARGET_BINARY_INTERFACE"x = x+	    then+		GUESS=m88k-dg-dgux$UNAME_RELEASE+	    else+		GUESS=m88k-dg-dguxbcs$UNAME_RELEASE+	    fi+	else+	    GUESS=i586-dg-dgux$UNAME_RELEASE+	fi+	;;+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)+	GUESS=m88k-dolphin-sysv3+	;;+    M88*:*:R3*:*)+	# Delta 88k system running SVR3+	GUESS=m88k-motorola-sysv3+	;;+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)+	GUESS=m88k-tektronix-sysv3+	;;+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)+	GUESS=m68k-tektronix-bsd+	;;+    *:IRIX*:*:*)+	IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`+	GUESS=mips-sgi-irix$IRIX_REL+	;;+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.+	GUESS=romp-ibm-aix    # uname -m gives an 8 hex-code CPU id+	;;                    # Note that: echo "'`uname -s`'" gives 'AIX '+    i*86:AIX:*:*)+	GUESS=i386-ibm-aix+	;;+    ia64:AIX:*:*)+	if test -x /usr/bin/oslevel ; then+		IBM_REV=`/usr/bin/oslevel`+	else+		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE+	fi+	GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV+	;;+    *:AIX:2:3)+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then+		set_cc_for_build+		sed 's/^		//' << EOF > "$dummy.c"+		#include <sys/systemcfg.h>++		main()+			{+			if (!__power_pc())+				exit(1);+			puts("powerpc-ibm-aix3.2.5");+			exit(0);+			}+EOF+		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`+		then+			GUESS=$SYSTEM_NAME+		else+			GUESS=rs6000-ibm-aix3.2.5+		fi+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then+		GUESS=rs6000-ibm-aix3.2.4+	else+		GUESS=rs6000-ibm-aix3.2+	fi+	;;+    *:AIX:*:[4567])+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`+	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then+		IBM_ARCH=rs6000+	else+		IBM_ARCH=powerpc+	fi+	if test -x /usr/bin/lslpp ; then+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`+	else+		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE+	fi+	GUESS=$IBM_ARCH-ibm-aix$IBM_REV+	;;+    *:AIX:*:*)+	GUESS=rs6000-ibm-aix+	;;+    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)+	GUESS=romp-ibm-bsd4.4+	;;+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and+	GUESS=romp-ibm-bsd$UNAME_RELEASE    # 4.3 with uname added to+	;;                                  # report: romp-ibm BSD 4.3+    *:BOSX:*:*)+	GUESS=rs6000-bull-bosx+	;;+    DPX/2?00:B.O.S.:*:*)+	GUESS=m68k-bull-sysv3+	;;+    9000/[34]??:4.3bsd:1.*:*)+	GUESS=m68k-hp-bsd+	;;+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)+	GUESS=m68k-hp-bsd4.4+	;;+    9000/[34678]??:HP-UX:*:*)+	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`+	case $UNAME_MACHINE in+	    9000/31?)            HP_ARCH=m68000 ;;+	    9000/[34]??)         HP_ARCH=m68k ;;+	    9000/[678][0-9][0-9])+		if test -x /usr/bin/getconf; then+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`+		    case $sc_cpu_version in+		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0+		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1+		      532)                      # CPU_PA_RISC2_0+			case $sc_kernel_bits in+			  32) HP_ARCH=hppa2.0n ;;+			  64) HP_ARCH=hppa2.0w ;;+			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20+			esac ;;+		    esac+		fi+		if test "$HP_ARCH" = ""; then+		    set_cc_for_build+		    sed 's/^		//' << EOF > "$dummy.c"++		#define _HPUX_SOURCE+		#include <stdlib.h>+		#include <unistd.h>++		int main ()+		{+		#if defined(_SC_KERNEL_BITS)+		    long bits = sysconf(_SC_KERNEL_BITS);+		#endif+		    long cpu  = sysconf (_SC_CPU_VERSION);++		    switch (cpu)+			{+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;+			case CPU_PA_RISC2_0:+		#if defined(_SC_KERNEL_BITS)+			    switch (bits)+				{+				case 64: puts ("hppa2.0w"); break;+				case 32: puts ("hppa2.0n"); break;+				default: puts ("hppa2.0"); break;+				} break;+		#else  /* !defined(_SC_KERNEL_BITS) */+			    puts ("hppa2.0"); break;+		#endif+			default: puts ("hppa1.0"); break;+			}+		    exit (0);+		}+EOF+		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`+		    test -z "$HP_ARCH" && HP_ARCH=hppa+		fi ;;+	esac+	if test "$HP_ARCH" = hppa2.0w+	then+	    set_cc_for_build++	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler+	    # generating 64-bit code.  GNU and HP use different nomenclature:+	    #+	    # $ CC_FOR_BUILD=cc ./config.guess+	    # => hppa2.0w-hp-hpux11.23+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess+	    # => hppa64-hp-hpux11.23++	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |+		grep -q __LP64__+	    then+		HP_ARCH=hppa2.0w+	    else+		HP_ARCH=hppa64+	    fi+	fi+	GUESS=$HP_ARCH-hp-hpux$HPUX_REV+	;;+    ia64:HP-UX:*:*)+	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`+	GUESS=ia64-hp-hpux$HPUX_REV+	;;+    3050*:HI-UX:*:*)+	set_cc_for_build+	sed 's/^	//' << EOF > "$dummy.c"+	#include <unistd.h>+	int+	main ()+	{+	  long cpu = sysconf (_SC_CPU_VERSION);+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct+	     results, however.  */+	  if (CPU_IS_PA_RISC (cpu))+	    {+	      switch (cpu)+		{+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;+		  default: puts ("hppa-hitachi-hiuxwe2"); break;+		}+	    }+	  else if (CPU_IS_HP_MC68K (cpu))+	    puts ("m68k-hitachi-hiuxwe2");+	  else puts ("unknown-hitachi-hiuxwe2");+	  exit (0);+	}+EOF+	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&+		{ echo "$SYSTEM_NAME"; exit; }+	GUESS=unknown-hitachi-hiuxwe2+	;;+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)+	GUESS=hppa1.1-hp-bsd+	;;+    9000/8??:4.3bsd:*:*)+	GUESS=hppa1.0-hp-bsd+	;;+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)+	GUESS=hppa1.0-hp-mpeix+	;;+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)+	GUESS=hppa1.1-hp-osf+	;;+    hp8??:OSF1:*:*)+	GUESS=hppa1.0-hp-osf+	;;+    i*86:OSF1:*:*)+	if test -x /usr/sbin/sysversion ; then+	    GUESS=$UNAME_MACHINE-unknown-osf1mk+	else+	    GUESS=$UNAME_MACHINE-unknown-osf1+	fi+	;;+    parisc*:Lites*:*:*)+	GUESS=hppa1.1-hp-lites+	;;+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)+	GUESS=c1-convex-bsd+	;;+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)+	if getsysinfo -f scalar_acc+	then echo c32-convex-bsd+	else echo c2-convex-bsd+	fi+	exit ;;+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)+	GUESS=c34-convex-bsd+	;;+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)+	GUESS=c38-convex-bsd+	;;+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)+	GUESS=c4-convex-bsd+	;;+    CRAY*Y-MP:*:*:*)+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`+	GUESS=ymp-cray-unicos$CRAY_REL+	;;+    CRAY*[A-Z]90:*:*:*)+	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \+	      -e 's/\.[^.]*$/.X/'+	exit ;;+    CRAY*TS:*:*:*)+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`+	GUESS=t90-cray-unicos$CRAY_REL+	;;+    CRAY*T3E:*:*:*)+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`+	GUESS=alphaev5-cray-unicosmk$CRAY_REL+	;;+    CRAY*SV1:*:*:*)+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`+	GUESS=sv1-cray-unicos$CRAY_REL+	;;+    *:UNICOS/mp:*:*)+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`+	GUESS=craynv-cray-unicosmp$CRAY_REL+	;;+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)+	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`+	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`+	GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}+	;;+    5000:UNIX_System_V:4.*:*)+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`+	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`+	GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}+	;;+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)+	GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE+	;;+    sparc*:BSD/OS:*:*)+	GUESS=sparc-unknown-bsdi$UNAME_RELEASE+	;;+    *:BSD/OS:*:*)+	GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE+	;;+    arm:FreeBSD:*:*)+	UNAME_PROCESSOR=`uname -p`+	set_cc_for_build+	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \+	    | grep -q __ARM_PCS_VFP+	then+	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`+	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi+	else+	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`+	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf+	fi+	;;+    *:FreeBSD:*:*)+	UNAME_PROCESSOR=`uname -p`+	case $UNAME_PROCESSOR in+	    amd64)+		UNAME_PROCESSOR=x86_64 ;;+	    i386)+		UNAME_PROCESSOR=i586 ;;+	esac+	FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`+	GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL+	;;+    i*:CYGWIN*:*)+	GUESS=$UNAME_MACHINE-pc-cygwin+	;;+    *:MINGW64*:*)+	GUESS=$UNAME_MACHINE-pc-mingw64+	;;+    *:MINGW*:*)+	GUESS=$UNAME_MACHINE-pc-mingw32+	;;+    *:MSYS*:*)+	GUESS=$UNAME_MACHINE-pc-msys+	;;+    i*:PW*:*)+	GUESS=$UNAME_MACHINE-pc-pw32+	;;+    *:SerenityOS:*:*)+        GUESS=$UNAME_MACHINE-pc-serenity+        ;;+    *:Interix*:*)+	case $UNAME_MACHINE in+	    x86)+		GUESS=i586-pc-interix$UNAME_RELEASE+		;;+	    authenticamd | genuineintel | EM64T)+		GUESS=x86_64-unknown-interix$UNAME_RELEASE+		;;+	    IA64)+		GUESS=ia64-unknown-interix$UNAME_RELEASE+		;;+	esac ;;+    i*:UWIN*:*)+	GUESS=$UNAME_MACHINE-pc-uwin+	;;+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)+	GUESS=x86_64-pc-cygwin+	;;+    prep*:SunOS:5.*:*)+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`+	GUESS=powerpcle-unknown-solaris2$SUN_REL+	;;+    *:GNU:*:*)+	# the GNU system+	GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`+	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`+	GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL+	;;+    *:GNU/*:*:*)+	# other systems with GNU libc and userland+	GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`+	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`+	GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC+	;;+    x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)+	GUESS="$UNAME_MACHINE-pc-managarm-mlibc"+	;;+    *:[Mm]anagarm:*:*)+	GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"+	;;+    *:Minix:*:*)+	GUESS=$UNAME_MACHINE-unknown-minix+	;;+    aarch64:Linux:*:*)+	set_cc_for_build+	CPU=$UNAME_MACHINE+	LIBCABI=$LIBC+	if test "$CC_FOR_BUILD" != no_compiler_found; then+	    ABI=64+	    sed 's/^	    //' << EOF > "$dummy.c"+	    #ifdef __ARM_EABI__+	    #ifdef __ARM_PCS_VFP+	    ABI=eabihf+	    #else+	    ABI=eabi+	    #endif+	    #endif+EOF+	    cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`+	    eval "$cc_set_abi"+	    case $ABI in+		eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;+	    esac+	fi+	GUESS=$CPU-unknown-linux-$LIBCABI+	;;+    aarch64_be:Linux:*:*)+	UNAME_MACHINE=aarch64_be+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    alpha:Linux:*:*)+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in+	  EV5)   UNAME_MACHINE=alphaev5 ;;+	  EV56)  UNAME_MACHINE=alphaev56 ;;+	  PCA56) UNAME_MACHINE=alphapca56 ;;+	  PCA57) UNAME_MACHINE=alphapca56 ;;+	  EV6)   UNAME_MACHINE=alphaev6 ;;+	  EV67)  UNAME_MACHINE=alphaev67 ;;+	  EV68*) UNAME_MACHINE=alphaev68 ;;+	esac+	objdump --private-headers /bin/sh | grep -q ld.so.1+	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    arm*:Linux:*:*)+	set_cc_for_build+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \+	    | grep -q __ARM_EABI__+	then+	    GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	else+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \+		| grep -q __ARM_PCS_VFP+	    then+		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi+	    else+		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf+	    fi+	fi+	;;+    avr32*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    cris:Linux:*:*)+	GUESS=$UNAME_MACHINE-axis-linux-$LIBC+	;;+    crisv32:Linux:*:*)+	GUESS=$UNAME_MACHINE-axis-linux-$LIBC+	;;+    e2k:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    frv:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    hexagon:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    i*86:Linux:*:*)+	GUESS=$UNAME_MACHINE-pc-linux-$LIBC+	;;+    ia64:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    k1om:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    kvx:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    kvx:cos:*:*)+	GUESS=$UNAME_MACHINE-unknown-cos+	;;+    kvx:mbr:*:*)+	GUESS=$UNAME_MACHINE-unknown-mbr+	;;+    loongarch32:Linux:*:* | loongarch64:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    m32r*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    m68*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    mips:Linux:*:* | mips64:Linux:*:*)+	set_cc_for_build+	IS_GLIBC=0+	test x"${LIBC}" = xgnu && IS_GLIBC=1+	sed 's/^	//' << EOF > "$dummy.c"+	#undef CPU+	#undef mips+	#undef mipsel+	#undef mips64+	#undef mips64el+	#if ${IS_GLIBC} && defined(_ABI64)+	LIBCABI=gnuabi64+	#else+	#if ${IS_GLIBC} && defined(_ABIN32)+	LIBCABI=gnuabin32+	#else+	LIBCABI=${LIBC}+	#endif+	#endif++	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6+	CPU=mipsisa64r6+	#else+	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6+	CPU=mipsisa32r6+	#else+	#if defined(__mips64)+	CPU=mips64+	#else+	CPU=mips+	#endif+	#endif+	#endif++	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)+	MIPS_ENDIAN=el+	#else+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)+	MIPS_ENDIAN=+	#else+	MIPS_ENDIAN=+	#endif+	#endif+EOF+	cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`+	eval "$cc_set_vars"+	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }+	;;+    mips64el:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    openrisc*:Linux:*:*)+	GUESS=or1k-unknown-linux-$LIBC+	;;+    or32:Linux:*:* | or1k*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    padre:Linux:*:*)+	GUESS=sparc-unknown-linux-$LIBC+	;;+    parisc64:Linux:*:* | hppa64:Linux:*:*)+	GUESS=hppa64-unknown-linux-$LIBC+	;;+    parisc:Linux:*:* | hppa:Linux:*:*)+	# Look for CPU level+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in+	  PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;+	  PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;+	  *)    GUESS=hppa-unknown-linux-$LIBC ;;+	esac+	;;+    ppc64:Linux:*:*)+	GUESS=powerpc64-unknown-linux-$LIBC+	;;+    ppc:Linux:*:*)+	GUESS=powerpc-unknown-linux-$LIBC+	;;+    ppc64le:Linux:*:*)+	GUESS=powerpc64le-unknown-linux-$LIBC+	;;+    ppcle:Linux:*:*)+	GUESS=powerpcle-unknown-linux-$LIBC+	;;+    riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    s390:Linux:*:* | s390x:Linux:*:*)+	GUESS=$UNAME_MACHINE-ibm-linux-$LIBC+	;;+    sh64*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    sh*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    sparc:Linux:*:* | sparc64:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    tile*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    vax:Linux:*:*)+	GUESS=$UNAME_MACHINE-dec-linux-$LIBC+	;;+    x86_64:Linux:*:*)+	set_cc_for_build+	CPU=$UNAME_MACHINE+	LIBCABI=$LIBC+	if test "$CC_FOR_BUILD" != no_compiler_found; then+	    ABI=64+	    sed 's/^	    //' << EOF > "$dummy.c"+	    #ifdef __i386__+	    ABI=x86+	    #else+	    #ifdef __ILP32__+	    ABI=x32+	    #endif+	    #endif+EOF+	    cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`+	    eval "$cc_set_abi"+	    case $ABI in+		x86) CPU=i686 ;;+		x32) LIBCABI=${LIBC}x32 ;;+	    esac+	fi+	GUESS=$CPU-pc-linux-$LIBCABI+	;;+    xtensa*:Linux:*:*)+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC+	;;+    i*86:DYNIX/ptx:4*:*)+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.+	# earlier versions are messed up and put the nodename in both+	# sysname and nodename.+	GUESS=i386-sequent-sysv4+	;;+    i*86:UNIX_SV:4.2MP:2.*)+	# Unixware is an offshoot of SVR4, but it has its own version+	# number series starting with 2...+	# I am not positive that other SVR4 systems won't match this,+	# I just have to hope.  -- rms.+	# Use sysv4.2uw... so that sysv4* matches it.+	GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION+	;;+    i*86:OS/2:*:*)+	# If we were able to find 'uname', then EMX Unix compatibility+	# is probably installed.+	GUESS=$UNAME_MACHINE-pc-os2-emx+	;;+    i*86:XTS-300:*:STOP)+	GUESS=$UNAME_MACHINE-unknown-stop+	;;+    i*86:atheos:*:*)+	GUESS=$UNAME_MACHINE-unknown-atheos+	;;+    i*86:syllable:*:*)+	GUESS=$UNAME_MACHINE-pc-syllable+	;;+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)+	GUESS=i386-unknown-lynxos$UNAME_RELEASE+	;;+    i*86:*DOS:*:*)+	GUESS=$UNAME_MACHINE-pc-msdosdjgpp+	;;+    i*86:*:4.*:*)+	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then+		GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL+	else+		GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL+	fi+	;;+    i*86:*:5:[678]*)+	# UnixWare 7.x, OpenUNIX and OpenServer 6.+	case `/bin/uname -X | grep "^Machine"` in+	    *486*)	     UNAME_MACHINE=i486 ;;+	    *Pentium)	     UNAME_MACHINE=i586 ;;+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;+	esac+	GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}+	;;+    i*86:*:3.2:*)+	if test -f /usr/options/cb.name; then+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`+		GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL+	elif /bin/uname -X 2>/dev/null >/dev/null ; then+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \+			&& UNAME_MACHINE=i586+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \+			&& UNAME_MACHINE=i686+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \+			&& UNAME_MACHINE=i686+		GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL+	else+		GUESS=$UNAME_MACHINE-pc-sysv32+	fi+	;;+    pc:*:*:*)+	# Left here for compatibility:+	# uname -m prints for DJGPP always 'pc', but it prints nothing about+	# the processor, so we play safe by assuming i586.+	# Note: whatever this is, it MUST be the same as what config.sub+	# prints for the "djgpp" host, or else GDB configure will decide that+	# this is a cross-build.+	GUESS=i586-pc-msdosdjgpp+	;;+    Intel:Mach:3*:*)+	GUESS=i386-pc-mach3+	;;+    paragon:*:*:*)+	GUESS=i860-intel-osf1+	;;+    i860:*:4.*:*) # i860-SVR4+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then+	  GUESS=i860-stardent-sysv$UNAME_RELEASE    # Stardent Vistra i860-SVR4+	else # Add other i860-SVR4 vendors below as they are discovered.+	  GUESS=i860-unknown-sysv$UNAME_RELEASE     # Unknown i860-SVR4+	fi+	;;+    mini*:CTIX:SYS*5:*)+	# "miniframe"+	GUESS=m68010-convergent-sysv+	;;+    mc68k:UNIX:SYSTEM5:3.51m)+	GUESS=m68k-convergent-sysv+	;;+    M680?0:D-NIX:5.3:*)+	GUESS=m68k-diab-dnix+	;;+    M68*:*:R3V[5678]*:*)+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)+	OS_REL=''+	test -r /etc/.relid \+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \+	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \+	  && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \+	  && { echo i486-ncr-sysv4; exit; } ;;+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)+	OS_REL='.3'+	test -r /etc/.relid \+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \+	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \+	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \+	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)+	GUESS=m68k-unknown-lynxos$UNAME_RELEASE+	;;+    mc68030:UNIX_System_V:4.*:*)+	GUESS=m68k-atari-sysv4+	;;+    TSUNAMI:LynxOS:2.*:*)+	GUESS=sparc-unknown-lynxos$UNAME_RELEASE+	;;+    rs6000:LynxOS:2.*:*)+	GUESS=rs6000-unknown-lynxos$UNAME_RELEASE+	;;+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)+	GUESS=powerpc-unknown-lynxos$UNAME_RELEASE+	;;+    SM[BE]S:UNIX_SV:*:*)+	GUESS=mips-dde-sysv$UNAME_RELEASE+	;;+    RM*:ReliantUNIX-*:*:*)+	GUESS=mips-sni-sysv4+	;;+    RM*:SINIX-*:*:*)+	GUESS=mips-sni-sysv4+	;;+    *:SINIX-*:*:*)+	if uname -p 2>/dev/null >/dev/null ; then+		UNAME_MACHINE=`(uname -p) 2>/dev/null`+		GUESS=$UNAME_MACHINE-sni-sysv4+	else+		GUESS=ns32k-sni-sysv+	fi+	;;+    PENTIUM:*:4.0*:*)	# Unisys 'ClearPath HMP IX 4000' SVR4/MP effort+			# says <Richard.M.Bartel@ccMail.Census.GOV>+	GUESS=i586-unisys-sysv4+	;;+    *:UNIX_System_V:4*:FTX*)+	# From Gerald Hewes <hewes@openmarket.com>.+	# How about differentiating between stratus architectures? -djm+	GUESS=hppa1.1-stratus-sysv4+	;;+    *:*:*:FTX*)+	# From seanf@swdc.stratus.com.+	GUESS=i860-stratus-sysv4+	;;+    i*86:VOS:*:*)+	# From Paul.Green@stratus.com.+	GUESS=$UNAME_MACHINE-stratus-vos+	;;+    *:VOS:*:*)+	# From Paul.Green@stratus.com.+	GUESS=hppa1.1-stratus-vos+	;;+    mc68*:A/UX:*:*)+	GUESS=m68k-apple-aux$UNAME_RELEASE+	;;+    news*:NEWS-OS:6*:*)+	GUESS=mips-sony-newsos6+	;;+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)+	if test -d /usr/nec; then+		GUESS=mips-nec-sysv$UNAME_RELEASE+	else+		GUESS=mips-unknown-sysv$UNAME_RELEASE+	fi+	;;+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.+	GUESS=powerpc-be-beos+	;;+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.+	GUESS=powerpc-apple-beos+	;;+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.+	GUESS=i586-pc-beos+	;;+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.+	GUESS=i586-pc-haiku+	;;+    ppc:Haiku:*:*)	# Haiku running on Apple PowerPC+	GUESS=powerpc-apple-haiku+	;;+    *:Haiku:*:*)	# Haiku modern gcc (not bound by BeOS compat)+	GUESS=$UNAME_MACHINE-unknown-haiku+	;;+    SX-4:SUPER-UX:*:*)+	GUESS=sx4-nec-superux$UNAME_RELEASE+	;;+    SX-5:SUPER-UX:*:*)+	GUESS=sx5-nec-superux$UNAME_RELEASE+	;;+    SX-6:SUPER-UX:*:*)+	GUESS=sx6-nec-superux$UNAME_RELEASE+	;;+    SX-7:SUPER-UX:*:*)+	GUESS=sx7-nec-superux$UNAME_RELEASE+	;;+    SX-8:SUPER-UX:*:*)+	GUESS=sx8-nec-superux$UNAME_RELEASE+	;;+    SX-8R:SUPER-UX:*:*)+	GUESS=sx8r-nec-superux$UNAME_RELEASE+	;;+    SX-ACE:SUPER-UX:*:*)+	GUESS=sxace-nec-superux$UNAME_RELEASE+	;;+    Power*:Rhapsody:*:*)+	GUESS=powerpc-apple-rhapsody$UNAME_RELEASE+	;;+    *:Rhapsody:*:*)+	GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE+	;;+    arm64:Darwin:*:*)+	GUESS=aarch64-apple-darwin$UNAME_RELEASE+	;;+    *:Darwin:*:*)+	UNAME_PROCESSOR=`uname -p`+	case $UNAME_PROCESSOR in+	    unknown) UNAME_PROCESSOR=powerpc ;;+	esac+	if command -v xcode-select > /dev/null 2> /dev/null && \+		! xcode-select --print-path > /dev/null 2> /dev/null ; then+	    # Avoid executing cc if there is no toolchain installed as+	    # cc will be a stub that puts up a graphical alert+	    # prompting the user to install developer tools.+	    CC_FOR_BUILD=no_compiler_found+	else+	    set_cc_for_build+	fi+	if test "$CC_FOR_BUILD" != no_compiler_found; then+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \+		   grep IS_64BIT_ARCH >/dev/null+	    then+		case $UNAME_PROCESSOR in+		    i386) UNAME_PROCESSOR=x86_64 ;;+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;+		esac+	    fi+	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc+	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \+		   grep IS_PPC >/dev/null+	    then+		UNAME_PROCESSOR=powerpc+	    fi+	elif test "$UNAME_PROCESSOR" = i386 ; then+	    # uname -m returns i386 or x86_64+	    UNAME_PROCESSOR=$UNAME_MACHINE+	fi+	GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE+	;;+    *:procnto*:*:* | *:QNX:[0123456789]*:*)+	UNAME_PROCESSOR=`uname -p`+	if test "$UNAME_PROCESSOR" = x86; then+		UNAME_PROCESSOR=i386+		UNAME_MACHINE=pc+	fi+	GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE+	;;+    *:QNX:*:4*)+	GUESS=i386-pc-qnx+	;;+    NEO-*:NONSTOP_KERNEL:*:*)+	GUESS=neo-tandem-nsk$UNAME_RELEASE+	;;+    NSE-*:NONSTOP_KERNEL:*:*)+	GUESS=nse-tandem-nsk$UNAME_RELEASE+	;;+    NSR-*:NONSTOP_KERNEL:*:*)+	GUESS=nsr-tandem-nsk$UNAME_RELEASE+	;;+    NSV-*:NONSTOP_KERNEL:*:*)+	GUESS=nsv-tandem-nsk$UNAME_RELEASE+	;;+    NSX-*:NONSTOP_KERNEL:*:*)+	GUESS=nsx-tandem-nsk$UNAME_RELEASE+	;;+    *:NonStop-UX:*:*)+	GUESS=mips-compaq-nonstopux+	;;+    BS2000:POSIX*:*:*)+	GUESS=bs2000-siemens-sysv+	;;+    DS/*:UNIX_System_V:*:*)+	GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE+	;;+    *:Plan9:*:*)+	# "uname -m" is not consistent, so use $cputype instead. 386+	# is converted to i386 for consistency with other x86+	# operating systems.+	if test "${cputype-}" = 386; then+	    UNAME_MACHINE=i386+	elif test "x${cputype-}" != x; then+	    UNAME_MACHINE=$cputype+	fi+	GUESS=$UNAME_MACHINE-unknown-plan9+	;;+    *:TOPS-10:*:*)+	GUESS=pdp10-unknown-tops10+	;;+    *:TENEX:*:*)+	GUESS=pdp10-unknown-tenex+	;;+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)+	GUESS=pdp10-dec-tops20+	;;+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)+	GUESS=pdp10-xkl-tops20+	;;+    *:TOPS-20:*:*)+	GUESS=pdp10-unknown-tops20+	;;+    *:ITS:*:*)+	GUESS=pdp10-unknown-its+	;;+    SEI:*:*:SEIUX)+	GUESS=mips-sei-seiux$UNAME_RELEASE+	;;+    *:DragonFly:*:*)+	DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`+	GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL+	;;+    *:*VMS:*:*)+	UNAME_MACHINE=`(uname -p) 2>/dev/null`+	case $UNAME_MACHINE in+	    A*) GUESS=alpha-dec-vms ;;+	    I*) GUESS=ia64-dec-vms ;;+	    V*) GUESS=vax-dec-vms ;;+	esac ;;+    *:XENIX:*:SysV)+	GUESS=i386-pc-xenix+	;;+    i*86:skyos:*:*)+	SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`+	GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL+	;;+    i*86:rdos:*:*)+	GUESS=$UNAME_MACHINE-pc-rdos+	;;+    i*86:Fiwix:*:*)+	GUESS=$UNAME_MACHINE-pc-fiwix+	;;+    *:AROS:*:*)+	GUESS=$UNAME_MACHINE-unknown-aros+	;;+    x86_64:VMkernel:*:*)+	GUESS=$UNAME_MACHINE-unknown-esx+	;;+    amd64:Isilon\ OneFS:*:*)+	GUESS=x86_64-unknown-onefs+	;;+    *:Unleashed:*:*)+	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE+	;;+    *:Ironclad:*:*)+	GUESS=$UNAME_MACHINE-unknown-ironclad+	;;+esac++# Do we have a guess based on uname results?+if test "x$GUESS" != x; then+    echo "$GUESS"+    exit+fi++# No uname command or uname output not recognized.+set_cc_for_build+cat > "$dummy.c" <<EOF+#ifdef _SEQUENT_+#include <sys/types.h>+#include <sys/utsname.h>+#endif+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)+#include <signal.h>+#if defined(_SIZE_T_) || defined(SIGLOST)+#include <sys/utsname.h>+#endif+#endif+#endif+main ()+{+#if defined (sony)+#if defined (MIPSEB)+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,+     I don't know....  */+  printf ("mips-sony-bsd\n"); exit (0);+#else+#include <sys/param.h>+  printf ("m68k-sony-newsos%s\n",+#ifdef NEWSOS4+  "4"+#else+  ""+#endif+  ); exit (0);+#endif+#endif++#if defined (NeXT)+#if !defined (__ARCHITECTURE__)+#define __ARCHITECTURE__ "m68k"+#endif+  int version;+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;+  if (version < 4)+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);+  else+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);+  exit (0);+#endif++#if defined (MULTIMAX) || defined (n16)+#if defined (UMAXV)+  printf ("ns32k-encore-sysv\n"); exit (0);+#else+#if defined (CMU)+  printf ("ns32k-encore-mach\n"); exit (0);+#else+  printf ("ns32k-encore-bsd\n"); exit (0);+#endif+#endif+#endif++#if defined (__386BSD__)+  printf ("i386-pc-bsd\n"); exit (0);+#endif++#if defined (sequent)+#if defined (i386)+  printf ("i386-sequent-dynix\n"); exit (0);+#endif+#if defined (ns32000)+  printf ("ns32k-sequent-dynix\n"); exit (0);+#endif+#endif++#if defined (_SEQUENT_)+  struct utsname un;++  uname(&un);+  if (strncmp(un.version, "V2", 2) == 0) {+    printf ("i386-sequent-ptx2\n"); exit (0);+  }+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */+    printf ("i386-sequent-ptx1\n"); exit (0);+  }+  printf ("i386-sequent-ptx\n"); exit (0);+#endif++#if defined (vax)+#if !defined (ultrix)+#include <sys/param.h>+#if defined (BSD)+#if BSD == 43+  printf ("vax-dec-bsd4.3\n"); exit (0);+#else+#if BSD == 199006+  printf ("vax-dec-bsd4.3reno\n"); exit (0);+#else+  printf ("vax-dec-bsd\n"); exit (0);+#endif+#endif+#else+  printf ("vax-dec-bsd\n"); exit (0);+#endif+#else+#if defined(_SIZE_T_) || defined(SIGLOST)+  struct utsname un;+  uname (&un);+  printf ("vax-dec-ultrix%s\n", un.release); exit (0);+#else+  printf ("vax-dec-ultrix\n"); exit (0);+#endif+#endif+#endif+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)+#if defined(_SIZE_T_) || defined(SIGLOST)+  struct utsname *un;+  uname (&un);+  printf ("mips-dec-ultrix%s\n", un.release); exit (0);+#else+  printf ("mips-dec-ultrix\n"); exit (0);+#endif+#endif+#endif++#if defined (alliant) && defined (i860)+  printf ("i860-alliant-bsd\n"); exit (0);+#endif++  exit (1);+}+EOF++$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&+	{ echo "$SYSTEM_NAME"; exit; }++# Apollos put the system type in the environment.+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }++echo "$0: unable to guess system type" >&2++case $UNAME_MACHINE:$UNAME_SYSTEM in+    mips:Linux | mips64:Linux)+	# If we got here on MIPS GNU/Linux, output extra information.+	cat >&2 <<EOF++NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize+the system type. Please install a C compiler and try again.+EOF+	;;+esac++cat >&2 <<EOF++This script (version $timestamp), has failed to recognize the+operating system you are using. If your script is old, overwrite *all*+copies of config.guess and config.sub with the latest versions from:++  https://git.savannah.gnu.org/cgit/config.git/plain/config.guess+and+  https://git.savannah.gnu.org/cgit/config.git/plain/config.sub+EOF++our_year=`echo $timestamp | sed 's,-.*,,'`+thisyear=`date +%Y`+# shellcheck disable=SC2003+script_age=`expr "$thisyear" - "$our_year"`+if test "$script_age" -lt 3 ; then+   cat >&2 <<EOF++If $0 has already been updated, send the following data and any+information you think might be pertinent to config-patches@gnu.org to+provide the necessary information to handle your system.++config.guess timestamp = $timestamp++uname -m = `(uname -m) 2>/dev/null || echo unknown`+uname -r = `(uname -r) 2>/dev/null || echo unknown`+uname -s = `(uname -s) 2>/dev/null || echo unknown`+uname -v = `(uname -v) 2>/dev/null || echo unknown`++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`++hostinfo               = `(hostinfo) 2>/dev/null`+/bin/universe          = `(/bin/universe) 2>/dev/null`+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`+/bin/arch              = `(/bin/arch) 2>/dev/null`+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`++UNAME_MACHINE = "$UNAME_MACHINE"+UNAME_RELEASE = "$UNAME_RELEASE"+UNAME_SYSTEM  = "$UNAME_SYSTEM"+UNAME_VERSION = "$UNAME_VERSION"+EOF+fi++exit 1++# Local variables:+# eval: (add-hook 'before-save-hook 'time-stamp)+# time-stamp-start: "timestamp='"+# time-stamp-format: "%:y-%02m-%02d"+# time-stamp-end: "'"+# End:
+ config.sub view
@@ -0,0 +1,1973 @@+#! /bin/sh+# Configuration validation subroutine script.+#   Copyright 1992-2024 Free Software Foundation, Inc.++# shellcheck disable=SC2006,SC2268 # see below for rationale++timestamp='2024-01-01'++# This file is free software; you can redistribute it and/or modify it+# under the terms of the GNU General Public License as published by+# the Free Software Foundation, either version 3 of the License, or+# (at your option) any later version.+#+# This program is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+# General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program; if not, see <https://www.gnu.org/licenses/>.+#+# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program that contains a+# configuration script generated by Autoconf, you may include it under+# the same distribution terms that you use for the rest of that+# program.  This Exception is an additional permission under section 7+# of the GNU General Public License, version 3 ("GPLv3").+++# Please send patches to <config-patches@gnu.org>.+#+# Configuration subroutine to validate and canonicalize a configuration type.+# Supply the specified configuration type as an argument.+# If it is invalid, we print an error message on stderr and exit with code 1.+# Otherwise, we print the canonical config type on stdout and succeed.++# You can get the latest version of this script from:+# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub++# This file is supposed to be the same for all GNU packages+# and recognize all the CPU types, system types and aliases+# that are meaningful with *any* GNU software.+# Each package is responsible for reporting which valid configurations+# it does not support.  The user should be able to distinguish+# a failure to support a valid configuration from a meaningless+# configuration.++# The goal of this file is to map all the various variations of a given+# machine specification into a single specification in the form:+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM+# or in some cases, the newer four-part form:+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM+# It is wrong to echo any other type of specification.++# The "shellcheck disable" line above the timestamp inhibits complaints+# about features and limitations of the classic Bourne shell that were+# superseded or lifted in POSIX.  However, this script identifies a wide+# variety of pre-POSIX systems that do not have POSIX shells at all, and+# even some reasonably current systems (Solaris 10 as case-in-point) still+# have a pre-POSIX /bin/sh.++me=`echo "$0" | sed -e 's,.*/,,'`++usage="\+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS++Canonicalize a configuration name.++Options:+  -h, --help         print this help, then exit+  -t, --time-stamp   print date of last modification, then exit+  -v, --version      print version number, then exit++Report bugs and patches to <config-patches@gnu.org>."++version="\+GNU config.sub ($timestamp)++Copyright 1992-2024 Free Software Foundation, Inc.++This is free software; see the source for copying conditions.  There is NO+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."++help="+Try '$me --help' for more information."++# Parse command line+while test $# -gt 0 ; do+  case $1 in+    --time-stamp | --time* | -t )+       echo "$timestamp" ; exit ;;+    --version | -v )+       echo "$version" ; exit ;;+    --help | --h* | -h )+       echo "$usage"; exit ;;+    -- )     # Stop option processing+       shift; break ;;+    - )	# Use stdin as input.+       break ;;+    -* )+       echo "$me: invalid option $1$help" >&2+       exit 1 ;;++    *local*)+       # First pass through any local machine types.+       echo "$1"+       exit ;;++    * )+       break ;;+  esac+done++case $# in+ 0) echo "$me: missing argument$help" >&2+    exit 1;;+ 1) ;;+ *) echo "$me: too many arguments$help" >&2+    exit 1;;+esac++# Split fields of configuration type+# shellcheck disable=SC2162+saved_IFS=$IFS+IFS="-" read field1 field2 field3 field4 <<EOF+$1+EOF+IFS=$saved_IFS++# Separate into logical components for further validation+case $1 in+	*-*-*-*-*)+		echo "Invalid configuration '$1': more than four components" >&2+		exit 1+		;;+	*-*-*-*)+		basic_machine=$field1-$field2+		basic_os=$field3-$field4+		;;+	*-*-*)+		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two+		# parts+		maybe_os=$field2-$field3+		case $maybe_os in+			nto-qnx* | linux-* | uclinux-uclibc* \+			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \+			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \+			| storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \+			| windows-* )+				basic_machine=$field1+				basic_os=$maybe_os+				;;+			android-linux)+				basic_machine=$field1-unknown+				basic_os=linux-android+				;;+			*)+				basic_machine=$field1-$field2+				basic_os=$field3+				;;+		esac+		;;+	*-*)+		# A lone config we happen to match not fitting any pattern+		case $field1-$field2 in+			decstation-3100)+				basic_machine=mips-dec+				basic_os=+				;;+			*-*)+				# Second component is usually, but not always the OS+				case $field2 in+					# Prevent following clause from handling this valid os+					sun*os*)+						basic_machine=$field1+						basic_os=$field2+						;;+					zephyr*)+						basic_machine=$field1-unknown+						basic_os=$field2+						;;+					# Manufacturers+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \+					| convergent* | ncr* | news | 32* | 3600* | 3100* \+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \+					| ultra | tti* | harris | dolphin | highlevel | gould \+					| cbm | ns | masscomp | apple | axis | knuth | cray \+					| microblaze* | sim | cisco \+					| oki | wec | wrs | winbond)+						basic_machine=$field1-$field2+						basic_os=+						;;+					*)+						basic_machine=$field1+						basic_os=$field2+						;;+				esac+			;;+		esac+		;;+	*)+		# Convert single-component short-hands not valid as part of+		# multi-component configurations.+		case $field1 in+			386bsd)+				basic_machine=i386-pc+				basic_os=bsd+				;;+			a29khif)+				basic_machine=a29k-amd+				basic_os=udi+				;;+			adobe68k)+				basic_machine=m68010-adobe+				basic_os=scout+				;;+			alliant)+				basic_machine=fx80-alliant+				basic_os=+				;;+			altos | altos3068)+				basic_machine=m68k-altos+				basic_os=+				;;+			am29k)+				basic_machine=a29k-none+				basic_os=bsd+				;;+			amdahl)+				basic_machine=580-amdahl+				basic_os=sysv+				;;+			amiga)+				basic_machine=m68k-unknown+				basic_os=+				;;+			amigaos | amigados)+				basic_machine=m68k-unknown+				basic_os=amigaos+				;;+			amigaunix | amix)+				basic_machine=m68k-unknown+				basic_os=sysv4+				;;+			apollo68)+				basic_machine=m68k-apollo+				basic_os=sysv+				;;+			apollo68bsd)+				basic_machine=m68k-apollo+				basic_os=bsd+				;;+			aros)+				basic_machine=i386-pc+				basic_os=aros+				;;+			aux)+				basic_machine=m68k-apple+				basic_os=aux+				;;+			balance)+				basic_machine=ns32k-sequent+				basic_os=dynix+				;;+			blackfin)+				basic_machine=bfin-unknown+				basic_os=linux+				;;+			cegcc)+				basic_machine=arm-unknown+				basic_os=cegcc+				;;+			convex-c1)+				basic_machine=c1-convex+				basic_os=bsd+				;;+			convex-c2)+				basic_machine=c2-convex+				basic_os=bsd+				;;+			convex-c32)+				basic_machine=c32-convex+				basic_os=bsd+				;;+			convex-c34)+				basic_machine=c34-convex+				basic_os=bsd+				;;+			convex-c38)+				basic_machine=c38-convex+				basic_os=bsd+				;;+			cray)+				basic_machine=j90-cray+				basic_os=unicos+				;;+			crds | unos)+				basic_machine=m68k-crds+				basic_os=+				;;+			da30)+				basic_machine=m68k-da30+				basic_os=+				;;+			decstation | pmax | pmin | dec3100 | decstatn)+				basic_machine=mips-dec+				basic_os=+				;;+			delta88)+				basic_machine=m88k-motorola+				basic_os=sysv3+				;;+			dicos)+				basic_machine=i686-pc+				basic_os=dicos+				;;+			djgpp)+				basic_machine=i586-pc+				basic_os=msdosdjgpp+				;;+			ebmon29k)+				basic_machine=a29k-amd+				basic_os=ebmon+				;;+			es1800 | OSE68k | ose68k | ose | OSE)+				basic_machine=m68k-ericsson+				basic_os=ose+				;;+			gmicro)+				basic_machine=tron-gmicro+				basic_os=sysv+				;;+			go32)+				basic_machine=i386-pc+				basic_os=go32+				;;+			h8300hms)+				basic_machine=h8300-hitachi+				basic_os=hms+				;;+			h8300xray)+				basic_machine=h8300-hitachi+				basic_os=xray+				;;+			h8500hms)+				basic_machine=h8500-hitachi+				basic_os=hms+				;;+			harris)+				basic_machine=m88k-harris+				basic_os=sysv3+				;;+			hp300 | hp300hpux)+				basic_machine=m68k-hp+				basic_os=hpux+				;;+			hp300bsd)+				basic_machine=m68k-hp+				basic_os=bsd+				;;+			hppaosf)+				basic_machine=hppa1.1-hp+				basic_os=osf+				;;+			hppro)+				basic_machine=hppa1.1-hp+				basic_os=proelf+				;;+			i386mach)+				basic_machine=i386-mach+				basic_os=mach+				;;+			isi68 | isi)+				basic_machine=m68k-isi+				basic_os=sysv+				;;+			m68knommu)+				basic_machine=m68k-unknown+				basic_os=linux+				;;+			magnum | m3230)+				basic_machine=mips-mips+				basic_os=sysv+				;;+			merlin)+				basic_machine=ns32k-utek+				basic_os=sysv+				;;+			mingw64)+				basic_machine=x86_64-pc+				basic_os=mingw64+				;;+			mingw32)+				basic_machine=i686-pc+				basic_os=mingw32+				;;+			mingw32ce)+				basic_machine=arm-unknown+				basic_os=mingw32ce+				;;+			monitor)+				basic_machine=m68k-rom68k+				basic_os=coff+				;;+			morphos)+				basic_machine=powerpc-unknown+				basic_os=morphos+				;;+			moxiebox)+				basic_machine=moxie-unknown+				basic_os=moxiebox+				;;+			msdos)+				basic_machine=i386-pc+				basic_os=msdos+				;;+			msys)+				basic_machine=i686-pc+				basic_os=msys+				;;+			mvs)+				basic_machine=i370-ibm+				basic_os=mvs+				;;+			nacl)+				basic_machine=le32-unknown+				basic_os=nacl+				;;+			ncr3000)+				basic_machine=i486-ncr+				basic_os=sysv4+				;;+			netbsd386)+				basic_machine=i386-pc+				basic_os=netbsd+				;;+			netwinder)+				basic_machine=armv4l-rebel+				basic_os=linux+				;;+			news | news700 | news800 | news900)+				basic_machine=m68k-sony+				basic_os=newsos+				;;+			news1000)+				basic_machine=m68030-sony+				basic_os=newsos+				;;+			necv70)+				basic_machine=v70-nec+				basic_os=sysv+				;;+			nh3000)+				basic_machine=m68k-harris+				basic_os=cxux+				;;+			nh[45]000)+				basic_machine=m88k-harris+				basic_os=cxux+				;;+			nindy960)+				basic_machine=i960-intel+				basic_os=nindy+				;;+			mon960)+				basic_machine=i960-intel+				basic_os=mon960+				;;+			nonstopux)+				basic_machine=mips-compaq+				basic_os=nonstopux+				;;+			os400)+				basic_machine=powerpc-ibm+				basic_os=os400+				;;+			OSE68000 | ose68000)+				basic_machine=m68000-ericsson+				basic_os=ose+				;;+			os68k)+				basic_machine=m68k-none+				basic_os=os68k+				;;+			paragon)+				basic_machine=i860-intel+				basic_os=osf+				;;+			parisc)+				basic_machine=hppa-unknown+				basic_os=linux+				;;+			psp)+				basic_machine=mipsallegrexel-sony+				basic_os=psp+				;;+			pw32)+				basic_machine=i586-unknown+				basic_os=pw32+				;;+			rdos | rdos64)+				basic_machine=x86_64-pc+				basic_os=rdos+				;;+			rdos32)+				basic_machine=i386-pc+				basic_os=rdos+				;;+			rom68k)+				basic_machine=m68k-rom68k+				basic_os=coff+				;;+			sa29200)+				basic_machine=a29k-amd+				basic_os=udi+				;;+			sei)+				basic_machine=mips-sei+				basic_os=seiux+				;;+			sequent)+				basic_machine=i386-sequent+				basic_os=+				;;+			sps7)+				basic_machine=m68k-bull+				basic_os=sysv2+				;;+			st2000)+				basic_machine=m68k-tandem+				basic_os=+				;;+			stratus)+				basic_machine=i860-stratus+				basic_os=sysv4+				;;+			sun2)+				basic_machine=m68000-sun+				basic_os=+				;;+			sun2os3)+				basic_machine=m68000-sun+				basic_os=sunos3+				;;+			sun2os4)+				basic_machine=m68000-sun+				basic_os=sunos4+				;;+			sun3)+				basic_machine=m68k-sun+				basic_os=+				;;+			sun3os3)+				basic_machine=m68k-sun+				basic_os=sunos3+				;;+			sun3os4)+				basic_machine=m68k-sun+				basic_os=sunos4+				;;+			sun4)+				basic_machine=sparc-sun+				basic_os=+				;;+			sun4os3)+				basic_machine=sparc-sun+				basic_os=sunos3+				;;+			sun4os4)+				basic_machine=sparc-sun+				basic_os=sunos4+				;;+			sun4sol2)+				basic_machine=sparc-sun+				basic_os=solaris2+				;;+			sun386 | sun386i | roadrunner)+				basic_machine=i386-sun+				basic_os=+				;;+			sv1)+				basic_machine=sv1-cray+				basic_os=unicos+				;;+			symmetry)+				basic_machine=i386-sequent+				basic_os=dynix+				;;+			t3e)+				basic_machine=alphaev5-cray+				basic_os=unicos+				;;+			t90)+				basic_machine=t90-cray+				basic_os=unicos+				;;+			toad1)+				basic_machine=pdp10-xkl+				basic_os=tops20+				;;+			tpf)+				basic_machine=s390x-ibm+				basic_os=tpf+				;;+			udi29k)+				basic_machine=a29k-amd+				basic_os=udi+				;;+			ultra3)+				basic_machine=a29k-nyu+				basic_os=sym1+				;;+			v810 | necv810)+				basic_machine=v810-nec+				basic_os=none+				;;+			vaxv)+				basic_machine=vax-dec+				basic_os=sysv+				;;+			vms)+				basic_machine=vax-dec+				basic_os=vms+				;;+			vsta)+				basic_machine=i386-pc+				basic_os=vsta+				;;+			vxworks960)+				basic_machine=i960-wrs+				basic_os=vxworks+				;;+			vxworks68)+				basic_machine=m68k-wrs+				basic_os=vxworks+				;;+			vxworks29k)+				basic_machine=a29k-wrs+				basic_os=vxworks+				;;+			xbox)+				basic_machine=i686-pc+				basic_os=mingw32+				;;+			ymp)+				basic_machine=ymp-cray+				basic_os=unicos+				;;+			*)+				basic_machine=$1+				basic_os=+				;;+		esac+		;;+esac++# Decode 1-component or ad-hoc basic machines+case $basic_machine in+	# Here we handle the default manufacturer of certain CPU types.  It is in+	# some cases the only manufacturer, in others, it is the most popular.+	w89k)+		cpu=hppa1.1+		vendor=winbond+		;;+	op50n)+		cpu=hppa1.1+		vendor=oki+		;;+	op60c)+		cpu=hppa1.1+		vendor=oki+		;;+	ibm*)+		cpu=i370+		vendor=ibm+		;;+	orion105)+		cpu=clipper+		vendor=highlevel+		;;+	mac | mpw | mac-mpw)+		cpu=m68k+		vendor=apple+		;;+	pmac | pmac-mpw)+		cpu=powerpc+		vendor=apple+		;;++	# Recognize the various machine names and aliases which stand+	# for a CPU type and a company and sometimes even an OS.+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)+		cpu=m68000+		vendor=att+		;;+	3b*)+		cpu=we32k+		vendor=att+		;;+	bluegene*)+		cpu=powerpc+		vendor=ibm+		basic_os=cnk+		;;+	decsystem10* | dec10*)+		cpu=pdp10+		vendor=dec+		basic_os=tops10+		;;+	decsystem20* | dec20*)+		cpu=pdp10+		vendor=dec+		basic_os=tops20+		;;+	delta | 3300 | motorola-3300 | motorola-delta \+	      | 3300-motorola | delta-motorola)+		cpu=m68k+		vendor=motorola+		;;+	dpx2*)+		cpu=m68k+		vendor=bull+		basic_os=sysv3+		;;+	encore | umax | mmax)+		cpu=ns32k+		vendor=encore+		;;+	elxsi)+		cpu=elxsi+		vendor=elxsi+		basic_os=${basic_os:-bsd}+		;;+	fx2800)+		cpu=i860+		vendor=alliant+		;;+	genix)+		cpu=ns32k+		vendor=ns+		;;+	h3050r* | hiux*)+		cpu=hppa1.1+		vendor=hitachi+		basic_os=hiuxwe2+		;;+	hp3k9[0-9][0-9] | hp9[0-9][0-9])+		cpu=hppa1.0+		vendor=hp+		;;+	hp9k2[0-9][0-9] | hp9k31[0-9])+		cpu=m68000+		vendor=hp+		;;+	hp9k3[2-9][0-9])+		cpu=m68k+		vendor=hp+		;;+	hp9k6[0-9][0-9] | hp6[0-9][0-9])+		cpu=hppa1.0+		vendor=hp+		;;+	hp9k7[0-79][0-9] | hp7[0-79][0-9])+		cpu=hppa1.1+		vendor=hp+		;;+	hp9k78[0-9] | hp78[0-9])+		# FIXME: really hppa2.0-hp+		cpu=hppa1.1+		vendor=hp+		;;+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)+		# FIXME: really hppa2.0-hp+		cpu=hppa1.1+		vendor=hp+		;;+	hp9k8[0-9][13679] | hp8[0-9][13679])+		cpu=hppa1.1+		vendor=hp+		;;+	hp9k8[0-9][0-9] | hp8[0-9][0-9])+		cpu=hppa1.0+		vendor=hp+		;;+	i*86v32)+		cpu=`echo "$1" | sed -e 's/86.*/86/'`+		vendor=pc+		basic_os=sysv32+		;;+	i*86v4*)+		cpu=`echo "$1" | sed -e 's/86.*/86/'`+		vendor=pc+		basic_os=sysv4+		;;+	i*86v)+		cpu=`echo "$1" | sed -e 's/86.*/86/'`+		vendor=pc+		basic_os=sysv+		;;+	i*86sol2)+		cpu=`echo "$1" | sed -e 's/86.*/86/'`+		vendor=pc+		basic_os=solaris2+		;;+	j90 | j90-cray)+		cpu=j90+		vendor=cray+		basic_os=${basic_os:-unicos}+		;;+	iris | iris4d)+		cpu=mips+		vendor=sgi+		case $basic_os in+		    irix*)+			;;+		    *)+			basic_os=irix4+			;;+		esac+		;;+	miniframe)+		cpu=m68000+		vendor=convergent+		;;+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)+		cpu=m68k+		vendor=atari+		basic_os=mint+		;;+	news-3600 | risc-news)+		cpu=mips+		vendor=sony+		basic_os=newsos+		;;+	next | m*-next)+		cpu=m68k+		vendor=next+		case $basic_os in+		    openstep*)+		        ;;+		    nextstep*)+			;;+		    ns2*)+		      basic_os=nextstep2+			;;+		    *)+		      basic_os=nextstep3+			;;+		esac+		;;+	np1)+		cpu=np1+		vendor=gould+		;;+	op50n-* | op60c-*)+		cpu=hppa1.1+		vendor=oki+		basic_os=proelf+		;;+	pa-hitachi)+		cpu=hppa1.1+		vendor=hitachi+		basic_os=hiuxwe2+		;;+	pbd)+		cpu=sparc+		vendor=tti+		;;+	pbb)+		cpu=m68k+		vendor=tti+		;;+	pc532)+		cpu=ns32k+		vendor=pc532+		;;+	pn)+		cpu=pn+		vendor=gould+		;;+	power)+		cpu=power+		vendor=ibm+		;;+	ps2)+		cpu=i386+		vendor=ibm+		;;+	rm[46]00)+		cpu=mips+		vendor=siemens+		;;+	rtpc | rtpc-*)+		cpu=romp+		vendor=ibm+		;;+	sde)+		cpu=mipsisa32+		vendor=sde+		basic_os=${basic_os:-elf}+		;;+	simso-wrs)+		cpu=sparclite+		vendor=wrs+		basic_os=vxworks+		;;+	tower | tower-32)+		cpu=m68k+		vendor=ncr+		;;+	vpp*|vx|vx-*)+		cpu=f301+		vendor=fujitsu+		;;+	w65)+		cpu=w65+		vendor=wdc+		;;+	w89k-*)+		cpu=hppa1.1+		vendor=winbond+		basic_os=proelf+		;;+	none)+		cpu=none+		vendor=none+		;;+	leon|leon[3-9])+		cpu=sparc+		vendor=$basic_machine+		;;+	leon-*|leon[3-9]-*)+		cpu=sparc+		vendor=`echo "$basic_machine" | sed 's/-.*//'`+		;;++	*-*)+		# shellcheck disable=SC2162+		saved_IFS=$IFS+		IFS="-" read cpu vendor <<EOF+$basic_machine+EOF+		IFS=$saved_IFS+		;;+	# We use 'pc' rather than 'unknown'+	# because (1) that's what they normally are, and+	# (2) the word "unknown" tends to confuse beginning users.+	i*86 | x86_64)+		cpu=$basic_machine+		vendor=pc+		;;+	# These rules are duplicated from below for sake of the special case above;+	# i.e. things that normalized to x86 arches should also default to "pc"+	pc98)+		cpu=i386+		vendor=pc+		;;+	x64 | amd64)+		cpu=x86_64+		vendor=pc+		;;+	# Recognize the basic CPU types without company name.+	*)+		cpu=$basic_machine+		vendor=unknown+		;;+esac++unset -v basic_machine++# Decode basic machines in the full and proper CPU-Company form.+case $cpu-$vendor in+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in+	# some cases the only manufacturer, in others, it is the most popular.+	craynv-unknown)+		vendor=cray+		basic_os=${basic_os:-unicosmp}+		;;+	c90-unknown | c90-cray)+		vendor=cray+		basic_os=${Basic_os:-unicos}+		;;+	fx80-unknown)+		vendor=alliant+		;;+	romp-unknown)+		vendor=ibm+		;;+	mmix-unknown)+		vendor=knuth+		;;+	microblaze-unknown | microblazeel-unknown)+		vendor=xilinx+		;;+	rs6000-unknown)+		vendor=ibm+		;;+	vax-unknown)+		vendor=dec+		;;+	pdp11-unknown)+		vendor=dec+		;;+	we32k-unknown)+		vendor=att+		;;+	cydra-unknown)+		vendor=cydrome+		;;+	i370-ibm*)+		vendor=ibm+		;;+	orion-unknown)+		vendor=highlevel+		;;+	xps-unknown | xps100-unknown)+		cpu=xps100+		vendor=honeywell+		;;++	# Here we normalize CPU types with a missing or matching vendor+	armh-unknown | armh-alt)+		cpu=armv7l+		vendor=alt+		basic_os=${basic_os:-linux-gnueabihf}+		;;+	dpx20-unknown | dpx20-bull)+		cpu=rs6000+		vendor=bull+		basic_os=${basic_os:-bosx}+		;;++	# Here we normalize CPU types irrespective of the vendor+	amd64-*)+		cpu=x86_64+		;;+	blackfin-*)+		cpu=bfin+		basic_os=linux+		;;+	c54x-*)+		cpu=tic54x+		;;+	c55x-*)+		cpu=tic55x+		;;+	c6x-*)+		cpu=tic6x+		;;+	e500v[12]-*)+		cpu=powerpc+		basic_os=${basic_os}"spe"+		;;+	mips3*-*)+		cpu=mips64+		;;+	ms1-*)+		cpu=mt+		;;+	m68knommu-*)+		cpu=m68k+		basic_os=linux+		;;+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)+		cpu=s12z+		;;+	openrisc-*)+		cpu=or32+		;;+	parisc-*)+		cpu=hppa+		basic_os=linux+		;;+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)+		cpu=i586+		;;+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athlon_*-*)+		cpu=i686+		;;+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)+		cpu=i686+		;;+	pentium4-*)+		cpu=i786+		;;+	pc98-*)+		cpu=i386+		;;+	ppc-* | ppcbe-*)+		cpu=powerpc+		;;+	ppcle-* | powerpclittle-*)+		cpu=powerpcle+		;;+	ppc64-*)+		cpu=powerpc64+		;;+	ppc64le-* | powerpc64little-*)+		cpu=powerpc64le+		;;+	sb1-*)+		cpu=mipsisa64sb1+		;;+	sb1el-*)+		cpu=mipsisa64sb1el+		;;+	sh5e[lb]-*)+		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`+		;;+	spur-*)+		cpu=spur+		;;+	strongarm-* | thumb-*)+		cpu=arm+		;;+	tx39-*)+		cpu=mipstx39+		;;+	tx39el-*)+		cpu=mipstx39el+		;;+	x64-*)+		cpu=x86_64+		;;+	xscale-* | xscalee[bl]-*)+		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`+		;;+	arm64-* | arm64_32-* | aarch64le-*)+		cpu=aarch64+		;;++	# Recognize the canonical CPU Types that limit and/or modify the+	# company names they are paired with.+	cr16-*)+		basic_os=${basic_os:-elf}+		;;+	crisv32-* | etraxfs*-*)+		cpu=crisv32+		vendor=axis+		;;+	cris-* | etrax*-*)+		cpu=cris+		vendor=axis+		;;+	crx-*)+		basic_os=${basic_os:-elf}+		;;+	neo-tandem)+		cpu=neo+		vendor=tandem+		;;+	nse-tandem)+		cpu=nse+		vendor=tandem+		;;+	nsr-tandem)+		cpu=nsr+		vendor=tandem+		;;+	nsv-tandem)+		cpu=nsv+		vendor=tandem+		;;+	nsx-tandem)+		cpu=nsx+		vendor=tandem+		;;+	mipsallegrexel-sony)+		cpu=mipsallegrexel+		vendor=sony+		;;+	tile*-*)+		basic_os=${basic_os:-linux-gnu}+		;;++	*)+		# Recognize the canonical CPU types that are allowed with any+		# company name.+		case $cpu in+			1750a | 580 \+			| a29k \+			| aarch64 | aarch64_be | aarch64c | arm64ec \+			| abacus \+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \+			| alphapca5[67] | alpha64pca5[67] \+			| am33_2.0 \+			| amdgcn \+			| arc | arceb | arc32 | arc64 \+			| arm | arm[lb]e | arme[lb] | armv* \+			| avr | avr32 \+			| asmjs \+			| ba \+			| be32 | be64 \+			| bfin | bpf | bs2000 \+			| c[123]* | c30 | [cjt]90 | c4x \+			| c8051 | clipper | craynv | csky | cydra \+			| d10v | d30v | dlx | dsp16xx \+			| e2k | elxsi | epiphany \+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \+			| javascript \+			| h8300 | h8500 \+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \+			| hexagon \+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \+			| ip2k | iq2000 \+			| k1om \+			| kvx \+			| le32 | le64 \+			| lm32 \+			| loongarch32 | loongarch64 \+			| m32c | m32r | m32rle \+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \+			| m88110 | m88k | maxq | mb | mcore | mep | metag \+			| microblaze | microblazeel \+			| mips* \+			| mmix \+			| mn10200 | mn10300 \+			| moxie \+			| mt \+			| msp430 \+			| nanomips* \+			| nds32 | nds32le | nds32be \+			| nfp \+			| nios | nios2 | nios2eb | nios2el \+			| none | np1 | ns16k | ns32k | nvptx \+			| open8 \+			| or1k* \+			| or32 \+			| orion \+			| picochip \+			| pdp10 | pdp11 | pj | pjl | pn | power \+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \+			| pru \+			| pyramid \+			| riscv | riscv32 | riscv32be | riscv64 | riscv64be \+			| rl78 | romp | rs6000 | rx \+			| s390 | s390x \+			| score \+			| sh | shl \+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \+			| sparclite \+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \+			| spu \+			| tahoe \+			| thumbv7* \+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \+			| tron \+			| ubicom32 \+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \+			| vax \+			| vc4 \+			| visium \+			| w65 \+			| wasm32 | wasm64 \+			| we32k \+			| x86 | x86_64 | xc16x | xgate | xps100 \+			| xstormy16 | xtensa* \+			| ymp \+			| z8k | z80)+				;;++			*)+				echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2+				exit 1+				;;+		esac+		;;+esac++# Here we canonicalize certain aliases for manufacturers.+case $vendor in+	digital*)+		vendor=dec+		;;+	commodore*)+		vendor=cbm+		;;+	*)+		;;+esac++# Decode manufacturer-specific aliases for certain operating systems.++if test x"$basic_os" != x+then++# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just+# set os.+obj=+case $basic_os in+	gnu/linux*)+		kernel=linux+		os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`+		;;+	os2-emx)+		kernel=os2+		os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`+		;;+	nto-qnx*)+		kernel=nto+		os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`+		;;+	*-*)+		# shellcheck disable=SC2162+		saved_IFS=$IFS+		IFS="-" read kernel os <<EOF+$basic_os+EOF+		IFS=$saved_IFS+		;;+	# Default OS when just kernel was specified+	nto*)+		kernel=nto+		os=`echo "$basic_os" | sed -e 's|nto|qnx|'`+		;;+	linux*)+		kernel=linux+		os=`echo "$basic_os" | sed -e 's|linux|gnu|'`+		;;+	managarm*)+		kernel=managarm+		os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`+		;;+	*)+		kernel=+		os=$basic_os+		;;+esac++# Now, normalize the OS (knowing we just have one component, it's not a kernel,+# etc.)+case $os in+	# First match some system type aliases that might get confused+	# with valid system types.+	# solaris* is a basic system type, with this one exception.+	auroraux)+		os=auroraux+		;;+	bluegene*)+		os=cnk+		;;+	solaris1 | solaris1.*)+		os=`echo "$os" | sed -e 's|solaris1|sunos4|'`+		;;+	solaris)+		os=solaris2+		;;+	unixware*)+		os=sysv4.2uw+		;;+	# es1800 is here to avoid being matched by es* (a different OS)+	es1800*)+		os=ose+		;;+	# Some version numbers need modification+	chorusos*)+		os=chorusos+		;;+	isc)+		os=isc2.2+		;;+	sco6)+		os=sco5v6+		;;+	sco5)+		os=sco3.2v5+		;;+	sco4)+		os=sco3.2v4+		;;+	sco3.2.[4-9]*)+		os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`+		;;+	sco*v* | scout)+		# Don't match below+		;;+	sco*)+		os=sco3.2v2+		;;+	psos*)+		os=psos+		;;+	qnx*)+		os=qnx+		;;+	hiux*)+		os=hiuxwe2+		;;+	lynx*178)+		os=lynxos178+		;;+	lynx*5)+		os=lynxos5+		;;+	lynxos*)+		# don't get caught up in next wildcard+		;;+	lynx*)+		os=lynxos+		;;+	mac[0-9]*)+		os=`echo "$os" | sed -e 's|mac|macos|'`+		;;+	opened*)+		os=openedition+		;;+	os400*)+		os=os400+		;;+	sunos5*)+		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`+		;;+	sunos6*)+		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`+		;;+	wince*)+		os=wince+		;;+	utek*)+		os=bsd+		;;+	dynix*)+		os=bsd+		;;+	acis*)+		os=aos+		;;+	atheos*)+		os=atheos+		;;+	syllable*)+		os=syllable+		;;+	386bsd)+		os=bsd+		;;+	ctix* | uts*)+		os=sysv+		;;+	nova*)+		os=rtmk-nova+		;;+	ns2)+		os=nextstep2+		;;+	# Preserve the version number of sinix5.+	sinix5.*)+		os=`echo "$os" | sed -e 's|sinix|sysv|'`+		;;+	sinix*)+		os=sysv4+		;;+	tpf*)+		os=tpf+		;;+	triton*)+		os=sysv3+		;;+	oss*)+		os=sysv3+		;;+	svr4*)+		os=sysv4+		;;+	svr3)+		os=sysv3+		;;+	sysvr4)+		os=sysv4+		;;+	ose*)+		os=ose+		;;+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)+		os=mint+		;;+	dicos*)+		os=dicos+		;;+	pikeos*)+		# Until real need of OS specific support for+		# particular features comes up, bare metal+		# configurations are quite functional.+		case $cpu in+		    arm*)+			os=eabi+			;;+		    *)+			os=+			obj=elf+			;;+		esac+		;;+	aout* | coff* | elf* | pe*)+		# These are machine code file formats, not OSes+		obj=$os+		os=+		;;+	*)+		# No normalization, but not necessarily accepted, that comes below.+		;;+esac++else++# Here we handle the default operating systems that come with various machines.+# The value should be what the vendor currently ships out the door with their+# machine or put another way, the most popular os provided with the machine.++# Note that if you're going to try to match "-MANUFACTURER" here (say,+# "-sun"), then you have to tell the case statement up towards the top+# that MANUFACTURER isn't an operating system.  Otherwise, code above+# will signal an error saying that MANUFACTURER isn't an operating+# system, and we'll never get to this point.++kernel=+obj=+case $cpu-$vendor in+	score-*)+		os=+		obj=elf+		;;+	spu-*)+		os=+		obj=elf+		;;+	*-acorn)+		os=riscix1.2+		;;+	arm*-rebel)+		kernel=linux+		os=gnu+		;;+	arm*-semi)+		os=+		obj=aout+		;;+	c4x-* | tic4x-*)+		os=+		obj=coff+		;;+	c8051-*)+		os=+		obj=elf+		;;+	clipper-intergraph)+		os=clix+		;;+	hexagon-*)+		os=+		obj=elf+		;;+	tic54x-*)+		os=+		obj=coff+		;;+	tic55x-*)+		os=+		obj=coff+		;;+	tic6x-*)+		os=+		obj=coff+		;;+	# This must come before the *-dec entry.+	pdp10-*)+		os=tops20+		;;+	pdp11-*)+		os=none+		;;+	*-dec | vax-*)+		os=ultrix4.2+		;;+	m68*-apollo)+		os=domain+		;;+	i386-sun)+		os=sunos4.0.2+		;;+	m68000-sun)+		os=sunos3+		;;+	m68*-cisco)+		os=+		obj=aout+		;;+	mep-*)+		os=+		obj=elf+		;;+	mips*-cisco)+		os=+		obj=elf+		;;+	mips*-*|nanomips*-*)+		os=+		obj=elf+		;;+	or32-*)+		os=+		obj=coff+		;;+	*-tti)	# must be before sparc entry or we get the wrong os.+		os=sysv3+		;;+	sparc-* | *-sun)+		os=sunos4.1.1+		;;+	pru-*)+		os=+		obj=elf+		;;+	*-be)+		os=beos+		;;+	*-ibm)+		os=aix+		;;+	*-knuth)+		os=mmixware+		;;+	*-wec)+		os=proelf+		;;+	*-winbond)+		os=proelf+		;;+	*-oki)+		os=proelf+		;;+	*-hp)+		os=hpux+		;;+	*-hitachi)+		os=hiux+		;;+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)+		os=sysv+		;;+	*-cbm)+		os=amigaos+		;;+	*-dg)+		os=dgux+		;;+	*-dolphin)+		os=sysv3+		;;+	m68k-ccur)+		os=rtu+		;;+	m88k-omron*)+		os=luna+		;;+	*-next)+		os=nextstep+		;;+	*-sequent)+		os=ptx+		;;+	*-crds)+		os=unos+		;;+	*-ns)+		os=genix+		;;+	i370-*)+		os=mvs+		;;+	*-gould)+		os=sysv+		;;+	*-highlevel)+		os=bsd+		;;+	*-encore)+		os=bsd+		;;+	*-sgi)+		os=irix+		;;+	*-siemens)+		os=sysv4+		;;+	*-masscomp)+		os=rtu+		;;+	f30[01]-fujitsu | f700-fujitsu)+		os=uxpv+		;;+	*-rom68k)+		os=+		obj=coff+		;;+	*-*bug)+		os=+		obj=coff+		;;+	*-apple)+		os=macos+		;;+	*-atari*)+		os=mint+		;;+	*-wrs)+		os=vxworks+		;;+	*)+		os=none+		;;+esac++fi++# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).++case $os in+	# Sometimes we do "kernel-libc", so those need to count as OSes.+	llvm* | musl* | newlib* | relibc* | uclibc*)+		;;+	# Likewise for "kernel-abi"+	eabi* | gnueabi*)+		;;+	# VxWorks passes extra cpu info in the 4th filed.+	simlinux | simwindows | spe)+		;;+	# See `case $cpu-$os` validation below+	ghcjs)+		;;+	# Now accept the basic system types.+	# The portable systems comes first.+	# Each alternative MUST end in a * to match a version number.+	gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \+	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \+	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \+	     | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \+	     | hiux* | abug | nacl* | netware* | windows* \+	     | os9* | macos* | osx* | ios* | tvos* | watchos* \+	     | mpw* | magic* | mmixware* | mon960* | lnews* \+	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \+	     | aos* | aros* | cloudabi* | sortix* | twizzler* \+	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \+	     | mirbsd* | netbsd* | dicos* | openedition* | ose* \+	     | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \+	     | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \+	     | bosx* | nextstep* | cxux* | oabi* \+	     | ptx* | ecoff* | winnt* | domain* | vsta* \+	     | udi* | lites* | ieee* | go32* | aux* | hcos* \+	     | chorusrdb* | cegcc* | glidix* | serenity* \+	     | cygwin* | msys* | moss* | proelf* | rtems* \+	     | midipix* | mingw32* | mingw64* | mint* \+	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \+	     | interix* | uwin* | mks* | rhapsody* | darwin* \+	     | openstep* | oskit* | conix* | pw32* | nonstopux* \+	     | storm-chaos* | tops10* | tenex* | tops20* | its* \+	     | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \+	     | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \+	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \+	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \+	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \+	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \+	     | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \+	     | fiwix* | mlibc* | cos* | mbr* | ironclad* )+		;;+	# This one is extra strict with allowed versions+	sco3.2v2 | sco3.2v[4-9]* | sco5v6*)+		# Don't forget version if it is 3.2v4 or newer.+		;;+	# This refers to builds using the UEFI calling convention+	# (which depends on the architecture) and PE file format.+	# Note that this is both a different calling convention and+	# different file format than that of GNU-EFI+	# (x86_64-w64-mingw32).+	uefi)+		;;+	none)+		;;+	kernel* | msvc* )+		# Restricted further below+		;;+	'')+		if test x"$obj" = x+		then+			echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2+		fi+		;;+	*)+		echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2+		exit 1+		;;+esac++case $obj in+	aout* | coff* | elf* | pe*)+		;;+	'')+		# empty is fine+		;;+	*)+		echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2+		exit 1+		;;+esac++# Here we handle the constraint that a (synthetic) cpu and os are+# valid only in combination with each other and nowhere else.+case $cpu-$os in+	# The "javascript-unknown-ghcjs" triple is used by GHC; we+	# accept it here in order to tolerate that, but reject any+	# variations.+	javascript-ghcjs)+		;;+	javascript-* | *-ghcjs)+		echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2+		exit 1+		;;+esac++# As a final step for OS-related things, validate the OS-kernel combination+# (given a valid OS), if there is a kernel.+case $kernel-$os-$obj in+	linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \+		    | linux-mlibc*- | linux-musl*- | linux-newlib*- \+		    | linux-relibc*- | linux-uclibc*- )+		;;+	uclinux-uclibc*- )+		;;+	managarm-mlibc*- | managarm-kernel*- )+		;;+	windows*-msvc*-)+		;;+	-dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \+		    | -uclibc*- )+		# These are just libc implementations, not actual OSes, and thus+		# require a kernel.+		echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2+		exit 1+		;;+	-kernel*- )+		echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2+		exit 1+		;;+	*-kernel*- )+		echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2+		exit 1+		;;+	*-msvc*- )+		echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2+		exit 1+		;;+	kfreebsd*-gnu*- | kopensolaris*-gnu*-)+		;;+	vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)+		;;+	nto-qnx*-)+		;;+	os2-emx-)+		;;+	ios*-simulator* | tvos*-simulator* | watchos*-simulator*)+		;;	+	*-eabi*- | *-gnueabi*-)+		;;+	none--*)+		# None (no kernel, i.e. freestanding / bare metal),+		# can be paired with an machine code file format+		;;+	-*-)+		# Blank kernel with real OS is always fine.+		;;+	--*)+		# Blank kernel and OS with real machine code file format is always fine.+		;;+	*-*-*)+		echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2+		exit 1+		;;+esac++# Here we handle the case where we know the os, and the CPU type, but not the+# manufacturer.  We pick the logical manufacturer.+case $vendor in+	unknown)+		case $cpu-$os in+			*-riscix*)+				vendor=acorn+				;;+			*-sunos*)+				vendor=sun+				;;+			*-cnk* | *-aix*)+				vendor=ibm+				;;+			*-beos*)+				vendor=be+				;;+			*-hpux*)+				vendor=hp+				;;+			*-mpeix*)+				vendor=hp+				;;+			*-hiux*)+				vendor=hitachi+				;;+			*-unos*)+				vendor=crds+				;;+			*-dgux*)+				vendor=dg+				;;+			*-luna*)+				vendor=omron+				;;+			*-genix*)+				vendor=ns+				;;+			*-clix*)+				vendor=intergraph+				;;+			*-mvs* | *-opened*)+				vendor=ibm+				;;+			*-os400*)+				vendor=ibm+				;;+			s390-* | s390x-*)+				vendor=ibm+				;;+			*-ptx*)+				vendor=sequent+				;;+			*-tpf*)+				vendor=ibm+				;;+			*-vxsim* | *-vxworks* | *-windiss*)+				vendor=wrs+				;;+			*-aux*)+				vendor=apple+				;;+			*-hms*)+				vendor=hitachi+				;;+			*-mpw* | *-macos*)+				vendor=apple+				;;+			*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)+				vendor=atari+				;;+			*-vos*)+				vendor=stratus+				;;+		esac+		;;+esac++echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"+exit++# Local variables:+# eval: (add-hook 'before-save-hook 'time-stamp)+# time-stamp-start: "timestamp='"+# time-stamp-format: "%:y-%02m-%02d"+# time-stamp-end: "'"+# End:
+ configure view
@@ -0,0 +1,23128 @@+#! /bin/sh+# Guess values for system-dependent variables and create Makefiles.+# Generated by GNU Autoconf 2.72 for libffi 3.5.2.+#+# Report bugs to <http://github.com/libffi/libffi/issues>.+#+#+# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,+# Inc.+#+#+# This configure script is free software; the Free Software Foundation+# gives unlimited permission to copy, distribute and modify it.+## -------------------- ##+## M4sh Initialization. ##+## -------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1+then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else case e in #(+  e) case `(set -o) 2>/dev/null` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac ;;+esac+fi++++# Reset variables that may have inherited troublesome values from+# the environment.++# IFS needs to be set, to space, tab, and newline, in precisely that order.+# (If _AS_PATH_WALK were called with IFS unset, it would have the+# side effect of setting IFS to empty, thus disabling word splitting.)+# Quoting is to prevent editors from complaining about space-tab.+as_nl='+'+export as_nl+IFS=" ""	$as_nl"++PS1='$ '+PS2='> '+PS4='+ '++# Ensure predictable behavior from utilities with locale-dependent output.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# We cannot yet rely on "unset" to work, but we need these variables+# to be unset--not just set to an empty or harmless value--now, to+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct+# also avoids known problems related to "unset" and subshell syntax+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH+do eval test \${$as_var+y} \+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :+done++# Ensure that fds 0, 1, and 2 are open.+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi++# The user is always right.+if ${PATH_SEPARATOR+false} :; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# Find who we are.  Look in the path if we contain no directory separator.+as_myself=+case $0 in #((+  *[\\/]* ) as_myself=$0 ;;+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break+  done+IFS=$as_save_IFS++     ;;+esac+# We did not find ourselves, most probably we were run as 'sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+  as_myself=$0+fi+if test ! -f "$as_myself"; then+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+  exit 1+fi+++# Use a proper internal environment variable to ensure we don't fall+  # into an infinite loop, continuously re-executing ourselves.+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then+    _as_can_reexec=no; export _as_can_reexec;+    # We cannot yet assume a decent shell, so we have to provide a+# neutralization value for shells without unset; and this also+# works around shells that cannot unset nonexistent variables.+# Preserve -v and -x to the replacement shell.+BASH_ENV=/dev/null+ENV=/dev/null+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+case $- in # ((((+  *v*x* | *x*v* ) as_opts=-vx ;;+  *v* ) as_opts=-v ;;+  *x* ) as_opts=-x ;;+  * ) as_opts= ;;+esac+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}+# Admittedly, this is quite paranoid, since all the known shells bail+# out after a failed 'exec'.+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2+exit 255+  fi+  # We don't want this to propagate to other subprocesses.+          { _as_can_reexec=; unset _as_can_reexec;}+if test "x$CONFIG_SHELL" = x; then+  as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1+then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '\${1+\"\$@\"}'='\"\$@\"'+  setopt NO_GLOB_SUBST+else case e in #(+  e) case \`(set -o) 2>/dev/null\` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac ;;+esac+fi+"+  as_required="as_fn_return () { (exit \$1); }+as_fn_success () { as_fn_return 0; }+as_fn_failure () { as_fn_return 1; }+as_fn_ret_success () { return 0; }+as_fn_ret_failure () { return 1; }++exitcode=0+as_fn_success || { exitcode=1; echo as_fn_success failed.; }+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }+if ( set x; as_fn_ret_success y && test x = \"\$1\" )+then :++else case e in #(+  e) exitcode=1; echo positional parameters were not saved. ;;+esac+fi+test x\$exitcode = x0 || exit 1+blah=\$(echo \$(echo blah))+test x\"\$blah\" = xblah || exit 1+test -x / || exit 1"+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1+test \$(( 1 + 1 )) = 2 || exit 1++  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO+    PATH=/empty FPATH=/empty; export PATH FPATH+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"+  if (eval "$as_required") 2>/dev/null+then :+  as_have_required=yes+else case e in #(+  e) as_have_required=no ;;+esac+fi+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null+then :++else case e in #(+  e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+as_found=false+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+  as_found=:+  case $as_dir in #(+	 /*)+	   for as_base in sh bash ksh sh5; do+	     # Try only shells that exist, to save several forks.+	     as_shell=$as_dir$as_base+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&+		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null+then :+  CONFIG_SHELL=$as_shell as_have_required=yes+		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null+then :+  break 2+fi+fi+	   done;;+       esac+  as_found=false+done+IFS=$as_save_IFS+if $as_found+then :++else case e in #(+  e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&+	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null+then :+  CONFIG_SHELL=$SHELL as_have_required=yes+fi ;;+esac+fi+++      if test "x$CONFIG_SHELL" != x+then :+  export CONFIG_SHELL+             # We cannot yet assume a decent shell, so we have to provide a+# neutralization value for shells without unset; and this also+# works around shells that cannot unset nonexistent variables.+# Preserve -v and -x to the replacement shell.+BASH_ENV=/dev/null+ENV=/dev/null+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+case $- in # ((((+  *v*x* | *x*v* ) as_opts=-vx ;;+  *v* ) as_opts=-v ;;+  *x* ) as_opts=-x ;;+  * ) as_opts= ;;+esac+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}+# Admittedly, this is quite paranoid, since all the known shells bail+# out after a failed 'exec'.+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2+exit 255+fi++    if test x$as_have_required = xno+then :+  printf "%s\n" "$0: This script requires a shell more modern than all"+  printf "%s\n" "$0: the shells that I found on your system."+  if test ${ZSH_VERSION+y} ; then+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."+  else+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and+$0: http://github.com/libffi/libffi/issues about your+$0: system, including any error possibly output before this+$0: message. Then install a modern shell, or manually run+$0: the script under such a shell if you do have one."+  fi+  exit 1+fi ;;+esac+fi+fi+SHELL=${CONFIG_SHELL-/bin/sh}+export SHELL+# Unset more variables known to interfere with behavior of common tools.+CLICOLOR_FORCE= GREP_OPTIONS=+unset CLICOLOR_FORCE GREP_OPTIONS++## --------------------- ##+## M4sh Shell Functions. ##+## --------------------- ##+# as_fn_unset VAR+# ---------------+# Portably unset VAR.+as_fn_unset ()+{+  { eval $1=; unset $1;}+}+as_unset=as_fn_unset+++# as_fn_set_status STATUS+# -----------------------+# Set $? to STATUS, without forking.+as_fn_set_status ()+{+  return $1+} # as_fn_set_status++# as_fn_exit STATUS+# -----------------+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.+as_fn_exit ()+{+  set +e+  as_fn_set_status $1+  exit $1+} # as_fn_exit++# as_fn_mkdir_p+# -------------+# Create "$as_dir" as a directory, including parents if necessary.+as_fn_mkdir_p ()+{++  case $as_dir in #(+  -*) as_dir=./$as_dir;;+  esac+  test -d "$as_dir" || eval $as_mkdir_p || {+    as_dirs=+    while :; do+      case $as_dir in #(+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+      *) as_qdir=$as_dir;;+      esac+      as_dirs="'$as_qdir' $as_dirs"+      as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_dir" : 'X\(//\)[^/]' \| \+	 X"$as_dir" : 'X\(//\)$' \| \+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X"$as_dir" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+      test -d "$as_dir" && break+    done+    test -z "$as_dirs" || eval "mkdir $as_dirs"+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"+++} # as_fn_mkdir_p++# as_fn_executable_p FILE+# -----------------------+# Test if FILE is an executable regular file.+as_fn_executable_p ()+{+  test -f "$1" && test -x "$1"+} # as_fn_executable_p+# as_fn_append VAR VALUE+# ----------------------+# Append the text in VALUE to the end of the definition contained in VAR. Take+# advantage of any shell optimizations that allow amortized linear growth over+# repeated appends, instead of the typical quadratic growth present in naive+# implementations.+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null+then :+  eval 'as_fn_append ()+  {+    eval $1+=\$2+  }'+else case e in #(+  e) as_fn_append ()+  {+    eval $1=\$$1\$2+  } ;;+esac+fi # as_fn_append++# as_fn_arith ARG...+# ------------------+# Perform arithmetic evaluation on the ARGs, and store the result in the+# global $as_val. Take advantage of shells that can avoid forks. The arguments+# must be portable across $(()) and expr.+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null+then :+  eval 'as_fn_arith ()+  {+    as_val=$(( $* ))+  }'+else case e in #(+  e) as_fn_arith ()+  {+    as_val=`expr "$@" || test $? -eq 1`+  } ;;+esac+fi # as_fn_arith+++# as_fn_error STATUS ERROR [LINENO LOG_FD]+# ----------------------------------------+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the+# script with STATUS, using 1 if that was 0.+as_fn_error ()+{+  as_status=$1; test $as_status -eq 0 && as_status=1+  if test "$4"; then+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4+  fi+  printf "%s\n" "$as_me: error: $2" >&2+  as_fn_exit $as_status+} # as_fn_error++if expr a : '\(a\)' >/dev/null 2>&1 &&+   test "X`expr 00001 : '.*\(...\)'`" = X001; then+  as_expr=expr+else+  as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+  as_basename=basename+else+  as_basename=false+fi++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+  as_dirname=dirname+else+  as_dirname=false+fi++as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$0" : 'X\(//\)$' \| \+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X/"$0" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`++# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits+++  as_lineno_1=$LINENO as_lineno_1a=$LINENO+  as_lineno_2=$LINENO as_lineno_2a=$LINENO+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)+  sed -n '+    p+    /[$]LINENO/=+  ' <$as_myself |+    sed '+      t clear+      :clear+      s/[$]LINENO.*/&-/+      t lineno+      b+      :lineno+      N+      :loop+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/+      t loop+      s/-\n.*//+    ' >$as_me.lineno &&+  chmod +x "$as_me.lineno" ||+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }++  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have+  # already done that, so ensure we don't try to do so again and fall+  # in an infinite loop.  This has already happened in practice.+  _as_can_reexec=no; export _as_can_reexec+  # Don't try to exec as it changes $[0], causing all sort of problems+  # (the dirname of $[0] is not the place where we might find the+  # original and so on.  Autoconf is especially sensitive to this).+  . "./$as_me.lineno"+  # Exit status is that of the last command.+  exit+}+++# Determine whether it's possible to make 'echo' print without a newline.+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed+# for compatibility with existing Makefiles.+ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in #(((((+-n*)+  case `echo 'xy\c'` in+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.+  xy)  ECHO_C='\c';;+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null+       ECHO_T='	';;+  esac;;+*)+  ECHO_N='-n';;+esac++# For backward compatibility with old third-party macros, we provide+# the shell variables $as_echo and $as_echo_n.  New code should use+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.+as_echo='printf %s\n'+as_echo_n='printf %s'++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+  rm -f conf$$.dir/conf$$.file+else+  rm -f conf$$.dir+  mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+  if ln -s conf$$.file conf$$ 2>/dev/null; then+    as_ln_s='ln -s'+    # ... but there are two gotchas:+    # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.+    # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.+    # In both cases, we have to default to 'cp -pR'.+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+      as_ln_s='cp -pR'+  elif ln conf$$.file conf$$ 2>/dev/null; then+    as_ln_s=ln+  else+    as_ln_s='cp -pR'+  fi+else+  as_ln_s='cp -pR'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null++if mkdir -p . 2>/dev/null; then+  as_mkdir_p='mkdir -p "$as_dir"'+else+  test -d ./-p && rmdir ./-p+  as_mkdir_p=false+fi++as_test_x='test -x'+as_executable_p=as_fn_executable_p++# Sed expression to map a string onto a valid CPP name.+as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"+as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated++# Sed expression to map a string onto a valid variable name.+as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"+as_tr_sh="eval sed '$as_sed_sh'" # deprecated++SHELL=${CONFIG_SHELL-/bin/sh}+++test -n "$DJDIR" || exec 7<&0 </dev/null+exec 6>&1++# Name of the host.+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,+# so uname gets run too.+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`++#+# Initializations.+#+ac_default_prefix=/usr/local+ac_clean_files=+ac_config_libobj_dir=.+LIBOBJS=+cross_compiling=no+subdirs=+MFLAGS=+MAKEFLAGS=++# Identity of this package.+PACKAGE_NAME='libffi'+PACKAGE_TARNAME='libffi'+PACKAGE_VERSION='3.5.2'+PACKAGE_STRING='libffi 3.5.2'+PACKAGE_BUGREPORT='http://github.com/libffi/libffi/issues'+PACKAGE_URL=''++# Factoring default headers for most tests.+ac_includes_default="\+#include <stddef.h>+#ifdef HAVE_STDIO_H+# include <stdio.h>+#endif+#ifdef HAVE_STDLIB_H+# include <stdlib.h>+#endif+#ifdef HAVE_STRING_H+# include <string.h>+#endif+#ifdef HAVE_INTTYPES_H+# include <inttypes.h>+#endif+#ifdef HAVE_STDINT_H+# include <stdint.h>+#endif+#ifdef HAVE_STRINGS_H+# include <strings.h>+#endif+#ifdef HAVE_SYS_TYPES_H+# include <sys/types.h>+#endif+#ifdef HAVE_SYS_STAT_H+# include <sys/stat.h>+#endif+#ifdef HAVE_UNISTD_H+# include <unistd.h>+#endif"++ac_header_c_list=+ac_subst_vars='LTLIBOBJS+LIBOBJS+EXTRA_LIBS+LIBFFI_BUILD_VERSIONED_SHLIB_SUN_FALSE+LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE+LIBFFI_BUILD_VERSIONED_SHLIB_GNU_FALSE+LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE+LIBFFI_BUILD_VERSIONED_SHLIB_FALSE+LIBFFI_BUILD_VERSIONED_SHLIB_TRUE+OPT_LDFLAGS+SECTION_LDFLAGS+FFI_DEBUG_FALSE+FFI_DEBUG_TRUE+EXTRA_ASM_SOURCES+EXTRA_SOURCES+TARGETDIR+TARGET+FFI_EXEC_TRAMPOLINE_TABLE+FFI_EXEC_TRAMPOLINE_TABLE_FALSE+FFI_EXEC_TRAMPOLINE_TABLE_TRUE+sys_symbol_underscore+WASM64_MEMORY64+HAVE_LONG_DOUBLE_VARIANT+HAVE_LONG_DOUBLE+AM_LTLDFLAGS+AM_RUNTESTFLAGS+MAINT+MAINTAINER_MODE_FALSE+MAINTAINER_MODE_TRUE+PRTDIAG+CXXCPP+LT_SYS_LIBRARY_PATH+OTOOL64+OTOOL+LIPO+NMEDIT+DSYMUTIL+MANIFEST_TOOL+AWK+RANLIB+STRIP+ac_ct_AR+AR+DLLTOOL+OBJDUMP+FILECMD+LN_S+NM+ac_ct_DUMPBIN+DUMPBIN+LD+FGREP+SED+LIBTOOL+EGREP+GREP+am__fastdepCCAS_FALSE+am__fastdepCCAS_TRUE+CCASDEPMODE+am__nodep+AMDEPBACKSLASH+AMDEP_FALSE+AMDEP_TRUE+am__include+DEPDIR+am__leading_dot+CCASFLAGS+CCAS+ac_ct_CXX+CXXFLAGS+CXX+OBJEXT+EXEEXT+ac_ct_CC+CPPFLAGS+LDFLAGS+CFLAGS+CC+ax_enable_builddir_sed+target_os+target_vendor+target_cpu+target+host_os+host_vendor+host_cpu+host+build_os+build_vendor+build_cpu+build+FFI_VERSION_NUMBER+FFI_VERSION_STRING+target_alias+host_alias+build_alias+LIBS+ECHO_T+ECHO_N+ECHO_C+DEFS+mandir+localedir+libdir+psdir+pdfdir+dvidir+htmldir+infodir+docdir+oldincludedir+includedir+runstatedir+localstatedir+sharedstatedir+sysconfdir+datadir+datarootdir+libexecdir+sbindir+bindir+program_transform_name+prefix+exec_prefix+PACKAGE_URL+PACKAGE_BUGREPORT+PACKAGE_STRING+PACKAGE_VERSION+PACKAGE_TARNAME+PACKAGE_NAME+PATH_SEPARATOR+SHELL+am__quote'+ac_subst_files=''+ac_user_opts='+enable_option_checking+enable_builddir+enable_dependency_tracking+enable_shared+enable_static+enable_pic+with_pic+enable_fast_install+enable_aix_soname+with_aix_soname+with_gnu_ld+with_sysroot+enable_libtool_lock+enable_portable_binary+with_gcc_arch+enable_maintainer_mode+enable_pax_emutramp+enable_debug+enable_structs+enable_raw_api+enable_exec_static_tramp+enable_purify_safety+enable_symvers+'+      ac_precious_vars='build_alias+host_alias+target_alias+CCAS+CCASFLAGS+LT_SYS_LIBRARY_PATH+CXXCPP+CPPFLAGS+WASM64_MEMORY64'+++# Initialize some variables set by options.+ac_init_help=+ac_init_version=false+ac_unrecognized_opts=+ac_unrecognized_sep=+# The variables have the same names as the options, with+# dashes changed to underlines.+cache_file=/dev/null+exec_prefix=NONE+no_create=+no_recursion=+prefix=NONE+program_prefix=NONE+program_suffix=NONE+program_transform_name=s,x,x,+silent=+site=+srcdir=+verbose=+x_includes=NONE+x_libraries=NONE++# Installation directory options.+# These are left unexpanded so users can "make install exec_prefix=/foo"+# and all the variables that are supposed to be based on exec_prefix+# by default will actually change.+# Use braces instead of parens because sh, perl, etc. also accept them.+# (The list follows the same order as the GNU Coding Standards.)+bindir='${exec_prefix}/bin'+sbindir='${exec_prefix}/sbin'+libexecdir='${exec_prefix}/libexec'+datarootdir='${prefix}/share'+datadir='${datarootdir}'+sysconfdir='${prefix}/etc'+sharedstatedir='${prefix}/com'+localstatedir='${prefix}/var'+runstatedir='${localstatedir}/run'+includedir='${prefix}/include'+oldincludedir='/usr/include'+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'+infodir='${datarootdir}/info'+htmldir='${docdir}'+dvidir='${docdir}'+pdfdir='${docdir}'+psdir='${docdir}'+libdir='${exec_prefix}/lib'+localedir='${datarootdir}/locale'+mandir='${datarootdir}/man'++ac_prev=+ac_dashdash=+for ac_option+do+  # If the previous option needs an argument, assign it.+  if test -n "$ac_prev"; then+    eval $ac_prev=\$ac_option+    ac_prev=+    continue+  fi++  case $ac_option in+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;+  *=)   ac_optarg= ;;+  *)    ac_optarg=yes ;;+  esac++  case $ac_dashdash$ac_option in+  --)+    ac_dashdash=yes ;;++  -bindir | --bindir | --bindi | --bind | --bin | --bi)+    ac_prev=bindir ;;+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)+    bindir=$ac_optarg ;;++  -build | --build | --buil | --bui | --bu)+    ac_prev=build_alias ;;+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)+    build_alias=$ac_optarg ;;++  -cache-file | --cache-file | --cache-fil | --cache-fi \+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)+    ac_prev=cache_file ;;+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)+    cache_file=$ac_optarg ;;++  --config-cache | -C)+    cache_file=config.cache ;;++  -datadir | --datadir | --datadi | --datad)+    ac_prev=datadir ;;+  -datadir=* | --datadir=* | --datadi=* | --datad=*)+    datadir=$ac_optarg ;;++  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \+  | --dataroo | --dataro | --datar)+    ac_prev=datarootdir ;;+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)+    datarootdir=$ac_optarg ;;++  -disable-* | --disable-*)+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid feature name: '$ac_useropt'"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"enable_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval enable_$ac_useropt=no ;;++  -docdir | --docdir | --docdi | --doc | --do)+    ac_prev=docdir ;;+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)+    docdir=$ac_optarg ;;++  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)+    ac_prev=dvidir ;;+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)+    dvidir=$ac_optarg ;;++  -enable-* | --enable-*)+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid feature name: '$ac_useropt'"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"enable_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval enable_$ac_useropt=\$ac_optarg ;;++  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \+  | --exec | --exe | --ex)+    ac_prev=exec_prefix ;;+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \+  | --exec=* | --exe=* | --ex=*)+    exec_prefix=$ac_optarg ;;++  -gas | --gas | --ga | --g)+    # Obsolete; use --with-gas.+    with_gas=yes ;;++  -help | --help | --hel | --he | -h)+    ac_init_help=long ;;+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)+    ac_init_help=recursive ;;+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)+    ac_init_help=short ;;++  -host | --host | --hos | --ho)+    ac_prev=host_alias ;;+  -host=* | --host=* | --hos=* | --ho=*)+    host_alias=$ac_optarg ;;++  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)+    ac_prev=htmldir ;;+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \+  | --ht=*)+    htmldir=$ac_optarg ;;++  -includedir | --includedir | --includedi | --included | --include \+  | --includ | --inclu | --incl | --inc)+    ac_prev=includedir ;;+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \+  | --includ=* | --inclu=* | --incl=* | --inc=*)+    includedir=$ac_optarg ;;++  -infodir | --infodir | --infodi | --infod | --info | --inf)+    ac_prev=infodir ;;+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)+    infodir=$ac_optarg ;;++  -libdir | --libdir | --libdi | --libd)+    ac_prev=libdir ;;+  -libdir=* | --libdir=* | --libdi=* | --libd=*)+    libdir=$ac_optarg ;;++  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \+  | --libexe | --libex | --libe)+    ac_prev=libexecdir ;;+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \+  | --libexe=* | --libex=* | --libe=*)+    libexecdir=$ac_optarg ;;++  -localedir | --localedir | --localedi | --localed | --locale)+    ac_prev=localedir ;;+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)+    localedir=$ac_optarg ;;++  -localstatedir | --localstatedir | --localstatedi | --localstated \+  | --localstate | --localstat | --localsta | --localst | --locals)+    ac_prev=localstatedir ;;+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)+    localstatedir=$ac_optarg ;;++  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)+    ac_prev=mandir ;;+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)+    mandir=$ac_optarg ;;++  -nfp | --nfp | --nf)+    # Obsolete; use --without-fp.+    with_fp=no ;;++  -no-create | --no-create | --no-creat | --no-crea | --no-cre \+  | --no-cr | --no-c | -n)+    no_create=yes ;;++  -no-recursion | --no-recursion | --no-recursio | --no-recursi \+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)+    no_recursion=yes ;;++  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \+  | --oldin | --oldi | --old | --ol | --o)+    ac_prev=oldincludedir ;;+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)+    oldincludedir=$ac_optarg ;;++  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)+    ac_prev=prefix ;;+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)+    prefix=$ac_optarg ;;++  -program-prefix | --program-prefix | --program-prefi | --program-pref \+  | --program-pre | --program-pr | --program-p)+    ac_prev=program_prefix ;;+  -program-prefix=* | --program-prefix=* | --program-prefi=* \+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)+    program_prefix=$ac_optarg ;;++  -program-suffix | --program-suffix | --program-suffi | --program-suff \+  | --program-suf | --program-su | --program-s)+    ac_prev=program_suffix ;;+  -program-suffix=* | --program-suffix=* | --program-suffi=* \+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)+    program_suffix=$ac_optarg ;;++  -program-transform-name | --program-transform-name \+  | --program-transform-nam | --program-transform-na \+  | --program-transform-n | --program-transform- \+  | --program-transform | --program-transfor \+  | --program-transfo | --program-transf \+  | --program-trans | --program-tran \+  | --progr-tra | --program-tr | --program-t)+    ac_prev=program_transform_name ;;+  -program-transform-name=* | --program-transform-name=* \+  | --program-transform-nam=* | --program-transform-na=* \+  | --program-transform-n=* | --program-transform-=* \+  | --program-transform=* | --program-transfor=* \+  | --program-transfo=* | --program-transf=* \+  | --program-trans=* | --program-tran=* \+  | --progr-tra=* | --program-tr=* | --program-t=*)+    program_transform_name=$ac_optarg ;;++  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)+    ac_prev=pdfdir ;;+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)+    pdfdir=$ac_optarg ;;++  -psdir | --psdir | --psdi | --psd | --ps)+    ac_prev=psdir ;;+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)+    psdir=$ac_optarg ;;++  -q | -quiet | --quiet | --quie | --qui | --qu | --q \+  | -silent | --silent | --silen | --sile | --sil)+    silent=yes ;;++  -runstatedir | --runstatedir | --runstatedi | --runstated \+  | --runstate | --runstat | --runsta | --runst | --runs \+  | --run | --ru | --r)+    ac_prev=runstatedir ;;+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \+  | --run=* | --ru=* | --r=*)+    runstatedir=$ac_optarg ;;++  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)+    ac_prev=sbindir ;;+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \+  | --sbi=* | --sb=*)+    sbindir=$ac_optarg ;;++  -sharedstatedir | --sharedstatedir | --sharedstatedi \+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \+  | --sharedst | --shareds | --shared | --share | --shar \+  | --sha | --sh)+    ac_prev=sharedstatedir ;;+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \+  | --sha=* | --sh=*)+    sharedstatedir=$ac_optarg ;;++  -site | --site | --sit)+    ac_prev=site ;;+  -site=* | --site=* | --sit=*)+    site=$ac_optarg ;;++  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)+    ac_prev=srcdir ;;+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)+    srcdir=$ac_optarg ;;++  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \+  | --syscon | --sysco | --sysc | --sys | --sy)+    ac_prev=sysconfdir ;;+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)+    sysconfdir=$ac_optarg ;;++  -target | --target | --targe | --targ | --tar | --ta | --t)+    ac_prev=target_alias ;;+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)+    target_alias=$ac_optarg ;;++  -v | -verbose | --verbose | --verbos | --verbo | --verb)+    verbose=yes ;;++  -version | --version | --versio | --versi | --vers | -V)+    ac_init_version=: ;;++  -with-* | --with-*)+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid package name: '$ac_useropt'"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"with_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval with_$ac_useropt=\$ac_optarg ;;++  -without-* | --without-*)+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid package name: '$ac_useropt'"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"with_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval with_$ac_useropt=no ;;++  --x)+    # Obsolete; use --with-x.+    with_x=yes ;;++  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \+  | --x-incl | --x-inc | --x-in | --x-i)+    ac_prev=x_includes ;;+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)+    x_includes=$ac_optarg ;;++  -x-libraries | --x-libraries | --x-librarie | --x-librari \+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)+    ac_prev=x_libraries ;;+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)+    x_libraries=$ac_optarg ;;++  -*) as_fn_error $? "unrecognized option: '$ac_option'+Try '$0 --help' for more information"+    ;;++  *=*)+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`+    # Reject names that are not valid shell variable names.+    case $ac_envvar in #(+      '' | [0-9]* | *[!_$as_cr_alnum]* )+      as_fn_error $? "invalid variable name: '$ac_envvar'" ;;+    esac+    eval $ac_envvar=\$ac_optarg+    export $ac_envvar ;;++  *)+    # FIXME: should be removed in autoconf 3.0.+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"+    ;;++  esac+done++if test -n "$ac_prev"; then+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`+  as_fn_error $? "missing argument to $ac_option"+fi++if test -n "$ac_unrecognized_opts"; then+  case $enable_option_checking in+    no) ;;+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;+  esac+fi++# Check all directory arguments for consistency.+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \+		datadir sysconfdir sharedstatedir localstatedir includedir \+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \+		libdir localedir mandir runstatedir+do+  eval ac_val=\$$ac_var+  # Remove trailing slashes.+  case $ac_val in+    */ )+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`+      eval $ac_var=\$ac_val;;+  esac+  # Be sure to have absolute directory names.+  case $ac_val in+    [\\/$]* | ?:[\\/]* )  continue;;+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;+  esac+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"+done++# There might be people who depend on the old broken behavior: '$host'+# used to hold the argument of --host etc.+# FIXME: To remove some day.+build=$build_alias+host=$host_alias+target=$target_alias++# FIXME: To remove some day.+if test "x$host_alias" != x; then+  if test "x$build_alias" = x; then+    cross_compiling=maybe+  elif test "x$build_alias" != "x$host_alias"; then+    cross_compiling=yes+  fi+fi++ac_tool_prefix=+test -n "$host_alias" && ac_tool_prefix=$host_alias-++test "$silent" = yes && exec 6>/dev/null+++ac_pwd=`pwd` && test -n "$ac_pwd" &&+ac_ls_di=`ls -di .` &&+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||+  as_fn_error $? "working directory cannot be determined"+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||+  as_fn_error $? "pwd does not report name of working directory"+++# Find the source files, if location was not specified.+if test -z "$srcdir"; then+  ac_srcdir_defaulted=yes+  # Try the directory containing this script, then the parent directory.+  ac_confdir=`$as_dirname -- "$as_myself" ||+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_myself" : 'X\(//\)[^/]' \| \+	 X"$as_myself" : 'X\(//\)$' \| \+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X"$as_myself" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+  srcdir=$ac_confdir+  if test ! -r "$srcdir/$ac_unique_file"; then+    srcdir=..+  fi+else+  ac_srcdir_defaulted=no+fi+if test ! -r "$srcdir/$ac_unique_file"; then+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"+fi+ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work"+ac_abs_confdir=`(+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"+	pwd)`+# When building in place, set srcdir=.+if test "$ac_abs_confdir" = "$ac_pwd"; then+  srcdir=.+fi+# Remove unnecessary trailing slashes from srcdir.+# Double slashes in file names in object file debugging info+# mess up M-x gdb in Emacs.+case $srcdir in+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;+esac+for ac_var in $ac_precious_vars; do+  eval ac_env_${ac_var}_set=\${${ac_var}+set}+  eval ac_env_${ac_var}_value=\$${ac_var}+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}+  eval ac_cv_env_${ac_var}_value=\$${ac_var}+done++#+# Report the --help message.+#+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.5.2 to adapt to many kinds of systems.++Usage: $0 [OPTION]... [VAR=VALUE]...++To assign environment variables (e.g., CC, CFLAGS...), specify them as+VAR=VALUE.  See below for descriptions of some of the useful variables.++Defaults for the options are specified in brackets.++Configuration:+  -h, --help              display this help and exit+      --help=short        display options specific to this package+      --help=recursive    display the short help of all the included packages+  -V, --version           display version information and exit+  -q, --quiet, --silent   do not print 'checking ...' messages+      --cache-file=FILE   cache test results in FILE [disabled]+  -C, --config-cache      alias for '--cache-file=config.cache'+  -n, --no-create         do not create output files+      --srcdir=DIR        find the sources in DIR [configure dir or '..']++Installation directories:+  --prefix=PREFIX         install architecture-independent files in PREFIX+                          [$ac_default_prefix]+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX+                          [PREFIX]++By default, 'make install' will install all the files in+'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc.  You can specify+an installation prefix other than '$ac_default_prefix' using '--prefix',+for instance '--prefix=\$HOME'.++For better control, use the options below.++Fine tuning of the installation directories:+  --bindir=DIR            user executables [EPREFIX/bin]+  --sbindir=DIR           system admin executables [EPREFIX/sbin]+  --libexecdir=DIR        program executables [EPREFIX/libexec]+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]+  --libdir=DIR            object code libraries [EPREFIX/lib]+  --includedir=DIR        C header files [PREFIX/include]+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]+  --infodir=DIR           info documentation [DATAROOTDIR/info]+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]+  --mandir=DIR            man documentation [DATAROOTDIR/man]+  --docdir=DIR            documentation root [DATAROOTDIR/doc/libffi]+  --htmldir=DIR           html documentation [DOCDIR]+  --dvidir=DIR            dvi documentation [DOCDIR]+  --pdfdir=DIR            pdf documentation [DOCDIR]+  --psdir=DIR             ps documentation [DOCDIR]+_ACEOF++  cat <<\_ACEOF++System types:+  --build=BUILD     configure for building on BUILD [guessed]+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]+  --target=TARGET   configure for building compilers for TARGET [HOST]+_ACEOF+fi++if test -n "$ac_init_help"; then+  case $ac_init_help in+     short | recursive ) echo "Configuration of libffi 3.5.2:";;+   esac+  cat <<\_ACEOF++Optional Features:+  --disable-option-checking  ignore unrecognized --enable/--with options+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]+  --disable-builddir      disable automatic build in subdir of sources++  --enable-dependency-tracking+                          do not reject slow dependency extractors+  --disable-dependency-tracking+                          speeds up one-time build+  --enable-shared[=PKGS]  build shared libraries [default=yes]+  --enable-static[=PKGS]  build static libraries [default=yes]+  --enable-pic[=PKGS]     try to use only PIC/non-PIC objects [default=use+                          both]+  --enable-fast-install[=PKGS]+                          optimize for fast installation [default=yes]+  --enable-aix-soname=aix|svr4|both+                          shared library versioning (aka "SONAME") variant to+                          provide on AIX, [default=aix].+  --disable-libtool-lock  avoid locking (might break parallel builds)+  --enable-portable-binary+                          disable compiler optimizations that would produce+                          unportable binaries+  --enable-maintainer-mode+                          enable make rules and dependencies not useful (and+                          sometimes confusing) to the casual installer+  --enable-pax_emutramp       enable pax emulated trampolines (experimental)+  --enable-debug          debugging mode+  --disable-structs       omit code for struct support+  --disable-raw-api       make the raw api unavailable+  --disable-exec-static-tramp  disable use of static exec trampolines (enabled by default)+  --enable-purify-safety  purify-safe mode+  --enable-symvers=STYLE  enables symbol versioning of the shared library+                          [default=yes]++Optional Packages:+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]+  --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the+                          compiler's sysroot if not specified).+  --with-gcc-arch=<arch>  use architecture <arch> for gcc -march/-mtune,+                          instead of guessing++Some influential environment variables:+  CC          C compiler command+  CFLAGS      C compiler flags+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a+              nonstandard directory <lib dir>+  LIBS        libraries to pass to the linker, e.g. -l<library>+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if+              you have headers in a nonstandard directory <include dir>+  CXX         C++ compiler command+  CXXFLAGS    C++ compiler flags+  CCAS        assembler compiler command (defaults to CC)+  CCASFLAGS   assembler compiler flags (defaults to CFLAGS)+  LT_SYS_LIBRARY_PATH+              User-defined run-time library search path.+  CXXCPP      C++ preprocessor+  WASM64_MEMORY64+              Used only for the wasm64 target. Set to 1 (default) or 2 for+              Emscripten's -sMEMORY64 mode++Use these variables to override the choices made by 'configure' or to help+it to find libraries and programs with nonstandard names/locations.++Report bugs to <http://github.com/libffi/libffi/issues>.+_ACEOF+ac_status=$?+fi++if test "$ac_init_help" = "recursive"; then+  # If there are subdirs, report their specific --help.+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue+    test -d "$ac_dir" ||+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||+      continue+    ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`+  # A ".." for each directory in $ac_dir_suffix.+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+  case $ac_top_builddir_sub in+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;+  esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+  .)  # We are building in place.+    ac_srcdir=.+    ac_top_srcdir=$ac_top_builddir_sub+    ac_abs_top_srcdir=$ac_pwd ;;+  [\\/]* | ?:[\\/]* )  # Absolute name.+    ac_srcdir=$srcdir$ac_dir_suffix;+    ac_top_srcdir=$srcdir+    ac_abs_top_srcdir=$srcdir ;;+  *) # Relative name.+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+    ac_top_srcdir=$ac_top_build_prefix$srcdir+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix++    cd "$ac_dir" || { ac_status=$?; continue; }+    # Check for configure.gnu first; this name is used for a wrapper for+    # Metaconfig's "Configure" on case-insensitive file systems.+    if test -f "$ac_srcdir/configure.gnu"; then+      echo &&+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive+    elif test -f "$ac_srcdir/configure"; then+      echo &&+      $SHELL "$ac_srcdir/configure" --help=recursive+    else+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2+    fi || ac_status=$?+    cd "$ac_pwd" || { ac_status=$?; break; }+  done+fi++test -n "$ac_init_help" && exit $ac_status+if $ac_init_version; then+  cat <<\_ACEOF+libffi configure 3.5.2+generated by GNU Autoconf 2.72++Copyright (C) 2023 Free Software Foundation, Inc.+This configure script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it.+_ACEOF+  exit+fi++## ------------------------ ##+## Autoconf initialization. ##+## ------------------------ ##++# ac_fn_c_try_compile LINENO+# --------------------------+# Try to compile conftest.$ac_ext, and return whether this succeeded.+ac_fn_c_try_compile ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  rm -f conftest.$ac_objext conftest.beam+  if { { ac_try="$ac_compile"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_compile") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && {+	 test -z "$ac_c_werror_flag" ||+	 test ! -s conftest.err+       } && test -s conftest.$ac_objext+then :+  ac_retval=0+else case e in #(+  e) printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++	ac_retval=1 ;;+esac+fi+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_c_try_compile++# ac_fn_cxx_try_compile LINENO+# ----------------------------+# Try to compile conftest.$ac_ext, and return whether this succeeded.+ac_fn_cxx_try_compile ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  rm -f conftest.$ac_objext conftest.beam+  if { { ac_try="$ac_compile"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_compile") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && {+	 test -z "$ac_cxx_werror_flag" ||+	 test ! -s conftest.err+       } && test -s conftest.$ac_objext+then :+  ac_retval=0+else case e in #(+  e) printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++	ac_retval=1 ;;+esac+fi+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_cxx_try_compile++# ac_fn_c_try_link LINENO+# -----------------------+# Try to link conftest.$ac_ext, and return whether this succeeded.+ac_fn_c_try_link ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext+  if { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && {+	 test -z "$ac_c_werror_flag" ||+	 test ! -s conftest.err+       } && test -s conftest$ac_exeext && {+	 test "$cross_compiling" = yes ||+	 test -x conftest$ac_exeext+       }+then :+  ac_retval=0+else case e in #(+  e) printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++	ac_retval=1 ;;+esac+fi+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would+  # interfere with the next link command; also delete a directory that is+  # left behind by Apple's compiler.  We do this before executing the actions.+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_c_try_link++# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES+# -------------------------------------------------------+# Tests whether HEADER exists and can be compiled using the include files in+# INCLUDES, setting the cache variable VAR accordingly.+ac_fn_c_check_header_compile ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5+printf %s "checking for $2... " >&6; }+if eval test \${$3+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+#include <$2>+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  eval "$3=yes"+else case e in #(+  e) eval "$3=no" ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+eval ac_res=\$$3+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+printf "%s\n" "$ac_res" >&6; }+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno++} # ac_fn_c_check_header_compile++# ac_fn_c_check_func LINENO FUNC VAR+# ----------------------------------+# Tests whether FUNC exists, setting the cache variable VAR accordingly+ac_fn_c_check_func ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5+printf %s "checking for $2... " >&6; }+if eval test \${$3+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */+#define $2 innocuous_$2++/* System header to define __stub macros and hopefully few prototypes,+   which can conflict with char $2 (void); below.  */++#include <limits.h>+#undef $2++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char $2 (void);+/* The GNU C library defines this for functions which it implements+    to always fail with ENOSYS.  Some functions are actually named+    something starting with __ and the normal name is an alias.  */+#if defined __stub_$2 || defined __stub___$2+choke me+#endif++int+main (void)+{+return $2 ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  eval "$3=yes"+else case e in #(+  e) eval "$3=no" ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext ;;+esac+fi+eval ac_res=\$$3+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+printf "%s\n" "$ac_res" >&6; }+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno++} # ac_fn_c_check_func++# ac_fn_cxx_try_cpp LINENO+# ------------------------+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.+ac_fn_cxx_try_cpp ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  if { { ac_try="$ac_cpp conftest.$ac_ext"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } > conftest.i && {+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||+	 test ! -s conftest.err+       }+then :+  ac_retval=0+else case e in #(+  e) printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++    ac_retval=1 ;;+esac+fi+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_cxx_try_cpp++# ac_fn_cxx_try_link LINENO+# -------------------------+# Try to link conftest.$ac_ext, and return whether this succeeded.+ac_fn_cxx_try_link ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext+  if { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && {+	 test -z "$ac_cxx_werror_flag" ||+	 test ! -s conftest.err+       } && test -s conftest$ac_exeext && {+	 test "$cross_compiling" = yes ||+	 test -x conftest$ac_exeext+       }+then :+  ac_retval=0+else case e in #(+  e) printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++	ac_retval=1 ;;+esac+fi+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would+  # interfere with the next link command; also delete a directory that is+  # left behind by Apple's compiler.  We do this before executing the actions.+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_cxx_try_link++# ac_fn_c_try_run LINENO+# ----------------------+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that+# executables *can* be run.+ac_fn_c_try_run ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  if { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'+  { { case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_try") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; }+then :+  ac_retval=0+else case e in #(+  e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5+       printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++       ac_retval=$ac_status ;;+esac+fi+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_c_try_run++# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES+# --------------------------------------------+# Tries to find the compile-time value of EXPR in a program that includes+# INCLUDES, setting VAR accordingly. Returns whether the value could be+# computed+ac_fn_c_compute_int ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  if test "$cross_compiling" = yes; then+    # Depending upon the size, compute the lo and hi bounds.+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main (void)+{+static int test_array [1 - 2 * !(($2) >= 0)];+test_array [0] = 0;+return test_array [0];++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_lo=0 ac_mid=0+  while :; do+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main (void)+{+static int test_array [1 - 2 * !(($2) <= $ac_mid)];+test_array [0] = 0;+return test_array [0];++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_hi=$ac_mid; break+else case e in #(+  e) as_fn_arith $ac_mid + 1 && ac_lo=$as_val+			if test $ac_lo -le $ac_mid; then+			  ac_lo= ac_hi=+			  break+			fi+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  done+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main (void)+{+static int test_array [1 - 2 * !(($2) < 0)];+test_array [0] = 0;+return test_array [0];++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_hi=-1 ac_mid=-1+  while :; do+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main (void)+{+static int test_array [1 - 2 * !(($2) >= $ac_mid)];+test_array [0] = 0;+return test_array [0];++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_lo=$ac_mid; break+else case e in #(+  e) as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val+			if test $ac_mid -le $ac_hi; then+			  ac_lo= ac_hi=+			  break+			fi+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  done+else case e in #(+  e) ac_lo= ac_hi= ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+# Binary search between lo and hi bounds.+while test "x$ac_lo" != "x$ac_hi"; do+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main (void)+{+static int test_array [1 - 2 * !(($2) <= $ac_mid)];+test_array [0] = 0;+return test_array [0];++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_hi=$ac_mid+else case e in #(+  e) as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+done+case $ac_lo in #((+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;+'') ac_retval=1 ;;+esac+  else+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+static long int longval (void) { return $2; }+static unsigned long int ulongval (void) { return $2; }+#include <stdio.h>+#include <stdlib.h>+int+main (void)+{++  FILE *f = fopen ("conftest.val", "w");+  if (! f)+    return 1;+  if (($2) < 0)+    {+      long int i = longval ();+      if (i != ($2))+	return 1;+      fprintf (f, "%ld", i);+    }+  else+    {+      unsigned long int i = ulongval ();+      if (i != ($2))+	return 1;+      fprintf (f, "%lu", i);+    }+  /* Do not output a trailing newline, as this causes \r\n confusion+     on some platforms.  */+  return ferror (f) || fclose (f) != 0;++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0+else case e in #(+  e) ac_retval=1 ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext+rm -f conftest.val++  fi+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_c_compute_int+ac_configure_args_raw=+for ac_arg+do+  case $ac_arg in+  *\'*)+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;+  esac+  as_fn_append ac_configure_args_raw " '$ac_arg'"+done++case $ac_configure_args_raw in+  *$as_nl*)+    ac_safe_unquote= ;;+  *)+    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.+    ac_unsafe_a="$ac_unsafe_z#~"+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;+esac++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.5.2, which was+generated by GNU Autoconf 2.72.  Invocation command line was++  $ $0$ac_configure_args_raw++_ACEOF+exec 5>>config.log+{+cat <<_ASUNAME+## --------- ##+## Platform. ##+## --------- ##++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`+uname -m = `(uname -m) 2>/dev/null || echo unknown`+uname -r = `(uname -r) 2>/dev/null || echo unknown`+uname -s = `(uname -s) 2>/dev/null || echo unknown`+uname -v = `(uname -v) 2>/dev/null || echo unknown`++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`++/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`++_ASUNAME++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    printf "%s\n" "PATH: $as_dir"+  done+IFS=$as_save_IFS++} >&5++cat >&5 <<_ACEOF+++## ----------- ##+## Core tests. ##+## ----------- ##++_ACEOF+++# Keep a trace of the command line.+# Strip out --no-create and --no-recursion so they do not pile up.+# Strip out --silent because we don't want to record it for future runs.+# Also quote any args containing shell meta-characters.+# Make two passes to allow for proper duplicate-argument suppression.+ac_configure_args=+ac_configure_args0=+ac_configure_args1=+ac_must_keep_next=false+for ac_pass in 1 2+do+  for ac_arg+  do+    case $ac_arg in+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \+    | -silent | --silent | --silen | --sile | --sil)+      continue ;;+    *\'*)+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;+    esac+    case $ac_pass in+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;+    2)+      as_fn_append ac_configure_args1 " '$ac_arg'"+      if test $ac_must_keep_next = true; then+	ac_must_keep_next=false # Got value, back to normal.+      else+	case $ac_arg in+	  *=* | --config-cache | -C | -disable-* | --disable-* \+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \+	  | -with-* | --with-* | -without-* | --without-* | --x)+	    case "$ac_configure_args0 " in+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;+	    esac+	    ;;+	  -* ) ac_must_keep_next=true ;;+	esac+      fi+      as_fn_append ac_configure_args " '$ac_arg'"+      ;;+    esac+  done+done+{ ac_configure_args0=; unset ac_configure_args0;}+{ ac_configure_args1=; unset ac_configure_args1;}++# When interrupted or exit'd, cleanup temporary files, and complete+# config.log.  We remove comments because anyway the quotes in there+# would cause problems or look ugly.+# WARNING: Use '\'' to represent an apostrophe within the trap.+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.+trap 'exit_status=$?+  # Sanitize IFS.+  IFS=" ""	$as_nl"+  # Save into config.log some information that might help in debugging.+  {+    echo++    printf "%s\n" "## ---------------- ##+## Cache variables. ##+## ---------------- ##"+    echo+    # The following way of writing the cache mishandles newlines in values,+(+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do+    eval ac_val=\$$ac_var+    case $ac_val in #(+    *${as_nl}*)+      case $ac_var in #(+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+      esac+      case $ac_var in #(+      _ | IFS | as_nl) ;; #(+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+      *) { eval $ac_var=; unset $ac_var;} ;;+      esac ;;+    esac+  done+  (set) 2>&1 |+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(+    *${as_nl}ac_space=\ *)+      sed -n \+	"s/'\''/'\''\\\\'\'''\''/g;+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"+      ;; #(+    *)+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+      ;;+    esac |+    sort+)+    echo++    printf "%s\n" "## ----------------- ##+## Output variables. ##+## ----------------- ##"+    echo+    for ac_var in $ac_subst_vars+    do+      eval ac_val=\$$ac_var+      case $ac_val in+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+      esac+      printf "%s\n" "$ac_var='\''$ac_val'\''"+    done | sort+    echo++    if test -n "$ac_subst_files"; then+      printf "%s\n" "## ------------------- ##+## File substitutions. ##+## ------------------- ##"+      echo+      for ac_var in $ac_subst_files+      do+	eval ac_val=\$$ac_var+	case $ac_val in+	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+	esac+	printf "%s\n" "$ac_var='\''$ac_val'\''"+      done | sort+      echo+    fi++    if test -s confdefs.h; then+      printf "%s\n" "## ----------- ##+## confdefs.h. ##+## ----------- ##"+      echo+      cat confdefs.h+      echo+    fi+    test "$ac_signal" != 0 &&+      printf "%s\n" "$as_me: caught signal $ac_signal"+    printf "%s\n" "$as_me: exit $exit_status"+  } >&5+  rm -f core *.core core.conftest.* &&+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&+    exit $exit_status+' 0+for ac_signal in 1 2 13 15; do+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal+done+ac_signal=0++# confdefs.h avoids OS command line length limits that DEFS can exceed.+rm -f -r conftest* confdefs.h++printf "%s\n" "/* confdefs.h */" > confdefs.h++# Predefined preprocessor variables.++printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h++printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h++printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h++printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h++printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h++printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h+++# Let the site file select an alternate cache file if it wants to.+# Prefer an explicitly selected file to automatically selected ones.+if test -n "$CONFIG_SITE"; then+  ac_site_files="$CONFIG_SITE"+elif test "x$prefix" != xNONE; then+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"+else+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"+fi++for ac_site_file in $ac_site_files+do+  case $ac_site_file in #(+  */*) :+     ;; #(+  *) :+    ac_site_file=./$ac_site_file ;;+esac+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}+    sed 's/^/| /' "$ac_site_file" >&5+    . "$ac_site_file" \+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error $? "failed to load site script $ac_site_file+See 'config.log' for more details" "$LINENO" 5; }+  fi+done++if test -r "$cache_file"; then+  # Some versions of bash will fail to source /dev/null (special files+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}+    case $cache_file in+      [\\/]* | ?:[\\/]* ) . "$cache_file";;+      *)                      . "./$cache_file";;+    esac+  fi+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}+  >$cache_file+fi++# Test code for whether the C compiler supports C89 (global declarations)+ac_c_conftest_c89_globals='+/* Does the compiler advertise C89 conformance?+   Do not test the value of __STDC__, because some compilers set it to 0+   while being otherwise adequately conformant. */+#if !defined __STDC__+# error "Compiler does not advertise C89 conformance"+#endif++#include <stddef.h>+#include <stdarg.h>+struct stat;+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */+struct buf { int x; };+struct buf * (*rcsopen) (struct buf *, struct stat *, int);+static char *e (char **p, int i)+{+  return p[i];+}+static char *f (char * (*g) (char **, int), char **p, ...)+{+  char *s;+  va_list v;+  va_start (v,p);+  s = g (p, va_arg (v,int));+  va_end (v);+  return s;+}++/* C89 style stringification. */+#define noexpand_stringify(a) #a+const char *stringified = noexpand_stringify(arbitrary+token=sequence);++/* C89 style token pasting.  Exercises some of the corner cases that+   e.g. old MSVC gets wrong, but not very hard. */+#define noexpand_concat(a,b) a##b+#define expand_concat(a,b) noexpand_concat(a,b)+extern int vA;+extern int vbee;+#define aye A+#define bee B+int *pvA = &expand_concat(v,aye);+int *pvbee = &noexpand_concat(v,bee);++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has+   function prototypes and stuff, but not \xHH hex character constants.+   These do not provoke an error unfortunately, instead are silently treated+   as an "x".  The following induces an error, until -std is added to get+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an+   array size at least.  It is necessary to write \x00 == 0 to get something+   that is true only with -std.  */+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters+   inside strings and character constants.  */+#define FOO(x) '\''x'\''+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];++int test (int i, double x);+struct s1 {int (*f) (int a);};+struct s2 {int (*f) (double a);};+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),+               int, int);'++# Test code for whether the C compiler supports C89 (body of main).+ac_c_conftest_c89_main='+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);+'++# Test code for whether the C compiler supports C99 (global declarations)+ac_c_conftest_c99_globals='+/* Does the compiler advertise C99 conformance? */+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L+# error "Compiler does not advertise C99 conformance"+#endif++// See if C++-style comments work.++#include <stdbool.h>+extern int puts (const char *);+extern int printf (const char *, ...);+extern int dprintf (int, const char *, ...);+extern void *malloc (size_t);+extern void free (void *);++// Check varargs macros.  These examples are taken from C99 6.10.3.5.+// dprintf is used instead of fprintf to avoid needing to declare+// FILE and stderr.+#define debug(...) dprintf (2, __VA_ARGS__)+#define showlist(...) puts (#__VA_ARGS__)+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))+static void+test_varargs_macros (void)+{+  int x = 1234;+  int y = 5678;+  debug ("Flag");+  debug ("X = %d\n", x);+  showlist (The first, second, and third items.);+  report (x>y, "x is %d but y is %d", x, y);+}++// Check long long types.+#define BIG64 18446744073709551615ull+#define BIG32 4294967295ul+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)+#if !BIG_OK+  #error "your preprocessor is broken"+#endif+#if BIG_OK+#else+  #error "your preprocessor is broken"+#endif+static long long int bignum = -9223372036854775807LL;+static unsigned long long int ubignum = BIG64;++struct incomplete_array+{+  int datasize;+  double data[];+};++struct named_init {+  int number;+  const wchar_t *name;+  double average;+};++typedef const char *ccp;++static inline int+test_restrict (ccp restrict text)+{+  // Iterate through items via the restricted pointer.+  // Also check for declarations in for loops.+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)+    continue;+  return 0;+}++// Check varargs and va_copy.+static bool+test_varargs (const char *format, ...)+{+  va_list args;+  va_start (args, format);+  va_list args_copy;+  va_copy (args_copy, args);++  const char *str = "";+  int number = 0;+  float fnumber = 0;++  while (*format)+    {+      switch (*format++)+	{+	case '\''s'\'': // string+	  str = va_arg (args_copy, const char *);+	  break;+	case '\''d'\'': // int+	  number = va_arg (args_copy, int);+	  break;+	case '\''f'\'': // float+	  fnumber = va_arg (args_copy, double);+	  break;+	default:+	  break;+	}+    }+  va_end (args_copy);+  va_end (args);++  return *str && number && fnumber;+}+'++# Test code for whether the C compiler supports C99 (body of main).+ac_c_conftest_c99_main='+  // Check bool.+  _Bool success = false;+  success |= (argc != 0);++  // Check restrict.+  if (test_restrict ("String literal") == 0)+    success = true;+  char *restrict newvar = "Another string";++  // Check varargs.+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);+  test_varargs_macros ();++  // Check flexible array members.+  struct incomplete_array *ia =+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));+  ia->datasize = 10;+  for (int i = 0; i < ia->datasize; ++i)+    ia->data[i] = i * 1.234;+  // Work around memory leak warnings.+  free (ia);++  // Check named initializers.+  struct named_init ni = {+    .number = 34,+    .name = L"Test wide string",+    .average = 543.34343,+  };++  ni.number = 58;++  int dynamic_array[ni.number];+  dynamic_array[0] = argv[0][0];+  dynamic_array[ni.number - 1] = 543;++  // work around unused variable warnings+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''+	 || dynamic_array[ni.number - 1] != 543);+'++# Test code for whether the C compiler supports C11 (global declarations)+ac_c_conftest_c11_globals='+/* Does the compiler advertise C11 conformance? */+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L+# error "Compiler does not advertise C11 conformance"+#endif++// Check _Alignas.+char _Alignas (double) aligned_as_double;+char _Alignas (0) no_special_alignment;+extern char aligned_as_int;+char _Alignas (0) _Alignas (int) aligned_as_int;++// Check _Alignof.+enum+{+  int_alignment = _Alignof (int),+  int_array_alignment = _Alignof (int[100]),+  char_alignment = _Alignof (char)+};+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");++// Check _Noreturn.+int _Noreturn does_not_return (void) { for (;;) continue; }++// Check _Static_assert.+struct test_static_assert+{+  int x;+  _Static_assert (sizeof (int) <= sizeof (long int),+                  "_Static_assert does not work in struct");+  long int y;+};++// Check UTF-8 literals.+#define u8 syntax error!+char const utf8_literal[] = u8"happens to be ASCII" "another string";++// Check duplicate typedefs.+typedef long *long_ptr;+typedef long int *long_ptr;+typedef long_ptr long_ptr;++// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.+struct anonymous+{+  union {+    struct { int i; int j; };+    struct { int k; long int l; } w;+  };+  int m;+} v1;+'++# Test code for whether the C compiler supports C11 (body of main).+ac_c_conftest_c11_main='+  _Static_assert ((offsetof (struct anonymous, i)+		   == offsetof (struct anonymous, w.k)),+		  "Anonymous union alignment botch");+  v1.i = 2;+  v1.w.k = 5;+  ok |= v1.i != 5;+'++# Test code for whether the C compiler supports C11 (complete).+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}+${ac_c_conftest_c99_globals}+${ac_c_conftest_c11_globals}++int+main (int argc, char **argv)+{+  int ok = 0;+  ${ac_c_conftest_c89_main}+  ${ac_c_conftest_c99_main}+  ${ac_c_conftest_c11_main}+  return ok;+}+"++# Test code for whether the C compiler supports C99 (complete).+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}+${ac_c_conftest_c99_globals}++int+main (int argc, char **argv)+{+  int ok = 0;+  ${ac_c_conftest_c89_main}+  ${ac_c_conftest_c99_main}+  return ok;+}+"++# Test code for whether the C compiler supports C89 (complete).+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}++int+main (int argc, char **argv)+{+  int ok = 0;+  ${ac_c_conftest_c89_main}+  return ok;+}+"++# Test code for whether the C++ compiler supports C++98 (global declarations)+ac_cxx_conftest_cxx98_globals='+// Does the compiler advertise C++98 conformance?+#if !defined __cplusplus || __cplusplus < 199711L+# error "Compiler does not advertise C++98 conformance"+#endif++// These inclusions are to reject old compilers that+// lack the unsuffixed header files.+#include <cstdlib>+#include <exception>++// <cassert> and <cstring> are *not* freestanding headers in C++98.+extern void assert (int);+namespace std {+  extern int strcmp (const char *, const char *);+}++// Namespaces, exceptions, and templates were all added after "C++ 2.0".+using std::exception;+using std::strcmp;++namespace {++void test_exception_syntax()+{+  try {+    throw "test";+  } catch (const char *s) {+    // Extra parentheses suppress a warning when building autoconf itself,+    // due to lint rules shared with more typical C programs.+    assert (!(strcmp) (s, "test"));+  }+}++template <typename T> struct test_template+{+  T const val;+  explicit test_template(T t) : val(t) {}+  template <typename U> T add(U u) { return static_cast<T>(u) + val; }+};++} // anonymous namespace+'++# Test code for whether the C++ compiler supports C++98 (body of main)+ac_cxx_conftest_cxx98_main='+  assert (argc);+  assert (! argv[0]);+{+  test_exception_syntax ();+  test_template<double> tt (2.0);+  assert (tt.add (4) == 6.0);+  assert (true && !false);+}+'++# Test code for whether the C++ compiler supports C++11 (global declarations)+ac_cxx_conftest_cxx11_globals='+// Does the compiler advertise C++ 2011 conformance?+#if !defined __cplusplus || __cplusplus < 201103L+# error "Compiler does not advertise C++11 conformance"+#endif++namespace cxx11test+{+  constexpr int get_val() { return 20; }++  struct testinit+  {+    int i;+    double d;+  };++  class delegate+  {+  public:+    delegate(int n) : n(n) {}+    delegate(): delegate(2354) {}++    virtual int getval() { return this->n; };+  protected:+    int n;+  };++  class overridden : public delegate+  {+  public:+    overridden(int n): delegate(n) {}+    virtual int getval() override final { return this->n * 2; }+  };++  class nocopy+  {+  public:+    nocopy(int i): i(i) {}+    nocopy() = default;+    nocopy(const nocopy&) = delete;+    nocopy & operator=(const nocopy&) = delete;+  private:+    int i;+  };++  // for testing lambda expressions+  template <typename Ret, typename Fn> Ret eval(Fn f, Ret v)+  {+    return f(v);+  }++  // for testing variadic templates and trailing return types+  template <typename V> auto sum(V first) -> V+  {+    return first;+  }+  template <typename V, typename... Args> auto sum(V first, Args... rest) -> V+  {+    return first + sum(rest...);+  }+}+'++# Test code for whether the C++ compiler supports C++11 (body of main)+ac_cxx_conftest_cxx11_main='+{+  // Test auto and decltype+  auto a1 = 6538;+  auto a2 = 48573953.4;+  auto a3 = "String literal";++  int total = 0;+  for (auto i = a3; *i; ++i) { total += *i; }++  decltype(a2) a4 = 34895.034;+}+{+  // Test constexpr+  short sa[cxx11test::get_val()] = { 0 };+}+{+  // Test initializer lists+  cxx11test::testinit il = { 4323, 435234.23544 };+}+{+  // Test range-based for+  int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3,+                 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};+  for (auto &x : array) { x += 23; }+}+{+  // Test lambda expressions+  using cxx11test::eval;+  assert (eval ([](int x) { return x*2; }, 21) == 42);+  double d = 2.0;+  assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0);+  assert (d == 5.0);+  assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0);+  assert (d == 5.0);+}+{+  // Test use of variadic templates+  using cxx11test::sum;+  auto a = sum(1);+  auto b = sum(1, 2);+  auto c = sum(1.0, 2.0, 3.0);+}+{+  // Test constructor delegation+  cxx11test::delegate d1;+  cxx11test::delegate d2();+  cxx11test::delegate d3(45);+}+{+  // Test override and final+  cxx11test::overridden o1(55464);+}+{+  // Test nullptr+  char *c = nullptr;+}+{+  // Test template brackets+  test_template<::test_template<int>> v(test_template<int>(12));+}+{+  // Unicode literals+  char const *utf8 = u8"UTF-8 string \u2500";+  char16_t const *utf16 = u"UTF-8 string \u2500";+  char32_t const *utf32 = U"UTF-32 string \u2500";+}+'++# Test code for whether the C compiler supports C++11 (complete).+ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals}+${ac_cxx_conftest_cxx11_globals}++int+main (int argc, char **argv)+{+  int ok = 0;+  ${ac_cxx_conftest_cxx98_main}+  ${ac_cxx_conftest_cxx11_main}+  return ok;+}+"++# Test code for whether the C compiler supports C++98 (complete).+ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals}+int+main (int argc, char **argv)+{+  int ok = 0;+  ${ac_cxx_conftest_cxx98_main}+  return ok;+}+"++as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"++# Auxiliary files required by this configure script.+ac_aux_files="ltmain.sh compile config.guess config.sub"++# Locations in which to look for auxiliary files.+ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.."++# Search for a directory containing all of the required auxiliary files,+# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.+# If we don't find one directory that contains all the files we need,+# we report the set of missing files from the *first* directory in+# $ac_aux_dir_candidates and give up.+ac_missing_aux_files=""+ac_first_candidate=:+printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+as_found=false+for as_dir in $ac_aux_dir_candidates+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+  as_found=:++  printf "%s\n" "$as_me:${as_lineno-$LINENO}:  trying $as_dir" >&5+  ac_aux_dir_found=yes+  ac_install_sh=+  for ac_aux in $ac_aux_files+  do+    # As a special case, if "install-sh" is required, that requirement+    # can be satisfied by any of "install-sh", "install.sh", or "shtool",+    # and $ac_install_sh is set appropriately for whichever one is found.+    if test x"$ac_aux" = x"install-sh"+    then+      if test -f "${as_dir}install-sh"; then+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install-sh found" >&5+        ac_install_sh="${as_dir}install-sh -c"+      elif test -f "${as_dir}install.sh"; then+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install.sh found" >&5+        ac_install_sh="${as_dir}install.sh -c"+      elif test -f "${as_dir}shtool"; then+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}shtool found" >&5+        ac_install_sh="${as_dir}shtool install -c"+      else+        ac_aux_dir_found=no+        if $ac_first_candidate; then+          ac_missing_aux_files="${ac_missing_aux_files} install-sh"+        else+          break+        fi+      fi+    else+      if test -f "${as_dir}${ac_aux}"; then+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}${ac_aux} found" >&5+      else+        ac_aux_dir_found=no+        if $ac_first_candidate; then+          ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"+        else+          break+        fi+      fi+    fi+  done+  if test "$ac_aux_dir_found" = yes; then+    ac_aux_dir="$as_dir"+    break+  fi+  ac_first_candidate=false++  as_found=false+done+IFS=$as_save_IFS+if $as_found+then :++else case e in #(+  e) as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 ;;+esac+fi+++# These three variables are undocumented and unsupported,+# and are intended to be withdrawn in a future Autoconf release.+# They can cause serious problems if a builder's source tree is in a directory+# whose full name contains unusual characters.+if test -f "${ac_aux_dir}config.guess"; then+  ac_config_guess="$SHELL ${ac_aux_dir}config.guess"+fi+if test -f "${ac_aux_dir}config.sub"; then+  ac_config_sub="$SHELL ${ac_aux_dir}config.sub"+fi+if test -f "$ac_aux_dir/configure"; then+  ac_configure="$SHELL ${ac_aux_dir}configure"+fi++# Check that the precious variables saved in the cache have kept the same+# value.+ac_cache_corrupted=false+for ac_var in $ac_precious_vars; do+  eval ac_old_set=\$ac_cv_env_${ac_var}_set+  eval ac_new_set=\$ac_env_${ac_var}_set+  eval ac_old_val=\$ac_cv_env_${ac_var}_value+  eval ac_new_val=\$ac_env_${ac_var}_value+  case $ac_old_set,$ac_new_set in+    set,)+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5+printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;}+      ac_cache_corrupted=: ;;+    ,set)+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5+printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;}+      ac_cache_corrupted=: ;;+    ,);;+    *)+      if test "x$ac_old_val" != "x$ac_new_val"; then+	# differences in whitespace do not lead to failure.+	ac_old_val_w=`echo x $ac_old_val`+	ac_new_val_w=`echo x $ac_new_val`+	if test "$ac_old_val_w" != "$ac_new_val_w"; then+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5+printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;}+	  ac_cache_corrupted=:+	else+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5+printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;}+	  eval $ac_var=\$ac_old_val+	fi+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  '$ac_old_val'" >&5+printf "%s\n" "$as_me:   former value:  '$ac_old_val'" >&2;}+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: '$ac_new_val'" >&5+printf "%s\n" "$as_me:   current value: '$ac_new_val'" >&2;}+      fi;;+  esac+  # Pass precious variables to config.status.+  if test "$ac_new_set" = set; then+    case $ac_new_val in+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;+    *) ac_arg=$ac_var=$ac_new_val ;;+    esac+    case " $ac_configure_args " in+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;+    esac+  fi+done+if $ac_cache_corrupted; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}+  as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file'+	    and start over" "$LINENO" 5+fi+## -------------------- ##+## Main body of script. ##+## -------------------- ##++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++ac_config_headers="$ac_config_headers fficonfig.h"+++FFI_VERSION_STRING="3.5.2"+FFI_VERSION_NUMBER=30502+++++++  # Make sure we can run config.sub.+$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 ||+  as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5+printf %s "checking build system type... " >&6; }+if test ${ac_cv_build+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_build_alias=$build_alias+test "x$ac_build_alias" = x &&+  ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"`+test "x$ac_build_alias" = x &&+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5+ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` ||+  as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5+printf "%s\n" "$ac_cv_build" >&6; }+case $ac_cv_build in+*-*-*) ;;+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;+esac+build=$ac_cv_build+ac_save_IFS=$IFS; IFS='-'+set x $ac_cv_build+shift+build_cpu=$1+build_vendor=$2+shift; shift+# Remember, the first character of IFS is used to create $*,+# except with old shells:+build_os=$*+IFS=$ac_save_IFS+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5+printf %s "checking host system type... " >&6; }+if test ${ac_cv_host+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test "x$host_alias" = x; then+  ac_cv_host=$ac_cv_build+else+  ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` ||+    as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5+printf "%s\n" "$ac_cv_host" >&6; }+case $ac_cv_host in+*-*-*) ;;+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;+esac+host=$ac_cv_host+ac_save_IFS=$IFS; IFS='-'+set x $ac_cv_host+shift+host_cpu=$1+host_vendor=$2+shift; shift+# Remember, the first character of IFS is used to create $*,+# except with old shells:+host_os=$*+IFS=$ac_save_IFS+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking target system type" >&5+printf %s "checking target system type... " >&6; }+if test ${ac_cv_target+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test "x$target_alias" = x; then+  ac_cv_target=$ac_cv_host+else+  ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` ||+    as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5+printf "%s\n" "$ac_cv_target" >&6; }+case $ac_cv_target in+*-*-*) ;;+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;+esac+target=$ac_cv_target+ac_save_IFS=$IFS; IFS='-'+set x $ac_cv_target+shift+target_cpu=$1+target_vendor=$2+shift; shift+# Remember, the first character of IFS is used to create $*,+# except with old shells:+target_os=$*+IFS=$ac_save_IFS+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac+++# The aliases save the names the user supplied, while $host etc.+# will get canonicalized.+test -n "$target_alias" &&+  test "$program_prefix$program_suffix$program_transform_name" = \+    NONENONEs,x,x, &&+  program_prefix=${target_alias}-+target_alias=${target_alias-$host_alias}++case "${host}" in+  frv*-elf)+    LDFLAGS=`echo $LDFLAGS | sed "s/\-B^ *libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/+    ;;+esac+++   # [$]@ is unusable in 2.60+ but earlier autoconf had no ac_configure_args+   if test "${ac_configure_args+set}" != "set" ; then+      ac_configure_args=+      for ac_arg in ${1+"$@"}; do+         ac_configure_args="$ac_configure_args '$ac_arg'"+      done+   fi+++# Expand $ac_aux_dir to an absolute path.+am_aux_dir=`cd "$ac_aux_dir" && pwd`+++ax_enable_builddir="."+# Check whether --enable-builddir was given.+if test ${enable_builddir+y}+then :+  enableval=$enable_builddir; ax_enable_builddir="$enableval"+else case e in #(+  e) ax_enable_builddir="auto" ;;+esac+fi++if test ".$ac_srcdir_defaulted" != ".no" ; then+if test ".$srcdir" = ".." ; then+  if test -f config.status ; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: toplevel srcdir already configured... skipping subdir build" >&5+printf "%s\n" "$as_me: toplevel srcdir already configured... skipping subdir build" >&6;}+  else+    test ".$ax_enable_builddir" = "."  && ax_enable_builddir="."+    test ".$ax_enable_builddir" = ".no"  && ax_enable_builddir="."+    test ".$TARGET" = "." && TARGET="$target"+    test ".$ax_enable_builddir" = ".auto" && ax_enable_builddir="$TARGET"+    if test ".$ax_enable_builddir" != ".." ; then    # we know where to go and+      as_dir=$ax_enable_builddir; as_fn_mkdir_p+      echo __.$ax_enable_builddir.__ > $ax_enable_builddir/conftest.tmp+      cd $ax_enable_builddir+      if grep __.$ax_enable_builddir.__ conftest.tmp >/dev/null 2>/dev/null ; then+        rm conftest.tmp+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: continue configure in default builddir \"./$ax_enable_builddir\"" >&5+printf "%s\n" "continue configure in default builddir \"./$ax_enable_builddir\"" >&6; }+      else+        as_fn_error $? "could not change to default builddir \"./$ax_enable_builddir\"" "$LINENO" 5+      fi+      srcdir=`echo "$ax_enable_builddir" |+              sed -e 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g;s,[/]$,,;'`+      # going to restart from subdirectory location+      test -f $srcdir/config.log   && mv $srcdir/config.log   .+      test -f $srcdir/confdefs.h   && mv $srcdir/confdefs.h   .+      test -f $srcdir/conftest.log && mv $srcdir/conftest.log .+      test -f $srcdir/$cache_file  && mv $srcdir/$cache_file  .+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ....exec $SHELL $srcdir/$0 \"--srcdir=$srcdir\" \"--enable-builddir=$ax_enable_builddir\" ${1+\"$@\"}" >&5+printf "%s\n" "....exec $SHELL $srcdir/$0 \"--srcdir=$srcdir\" \"--enable-builddir=$ax_enable_builddir\" ${1+\"$@\"}" >&6; }+      case "$0" in # restart+       [\\/]* | ?:[\\/]*) # Absolute name+         eval $SHELL "'$0'" "'--srcdir=$srcdir'" "'--enable-builddir=$ax_enable_builddir'" $ac_configure_args ;;+       *) eval $SHELL "'$srcdir/$0'" "'--srcdir=$srcdir'" "'--enable-builddir=$ax_enable_builddir'" $ac_configure_args ;;+      esac ; exit $?+    fi+  fi+fi fi+test ".$ax_enable_builddir" = ".auto" && ax_enable_builddir="."+# Extract the first word of "gsed sed", so it can be a program name with args.+set dummy gsed sed; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_path_ax_enable_builddir_sed+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) case $ax_enable_builddir_sed in+  [\\/]* | ?:[\\/]*)+  ac_cv_path_ax_enable_builddir_sed="$ax_enable_builddir_sed" # Let the user override the test with a path.+  ;;+  *)+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_path_ax_enable_builddir_sed="$as_dir$ac_word$ac_exec_ext"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_path_ax_enable_builddir_sed" && ac_cv_path_ax_enable_builddir_sed="sed"+  ;;+esac ;;+esac+fi+ax_enable_builddir_sed=$ac_cv_path_ax_enable_builddir_sed+if test -n "$ax_enable_builddir_sed"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_enable_builddir_sed" >&5+printf "%s\n" "$ax_enable_builddir_sed" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++ax_enable_builddir_auxdir="$am_aux_dir"+ac_config_commands="$ac_config_commands buildir"+++# The same as in boehm-gc and libstdc++. Have to borrow it from there.+# We must force CC to /not/ be precious variables; otherwise+# the wrong, non-multilib-adjusted value will be used in multilibs.+# As a side effect, we have to subst CFLAGS ourselves.+# Also save and restore CFLAGS, since AC_PROG_CC will come up with+# defaults of its own if none are provided.++++save_CFLAGS=$CFLAGS++++++++++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.+set dummy ${ac_tool_prefix}gcc; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="${ac_tool_prefix}gcc"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+printf "%s\n" "$CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_CC"; then+  ac_ct_CC=$CC+  # Extract the first word of "gcc", so it can be a program name with args.+set dummy gcc; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_CC"; then+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_CC="gcc"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_CC=$ac_cv_prog_ac_ct_CC+if test -n "$ac_ct_CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5+printf "%s\n" "$ac_ct_CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_CC" = x; then+    CC=""+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    CC=$ac_ct_CC+  fi+else+  CC="$ac_cv_prog_CC"+fi++if test -z "$CC"; then+          if test -n "$ac_tool_prefix"; then+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.+set dummy ${ac_tool_prefix}cc; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="${ac_tool_prefix}cc"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+printf "%s\n" "$CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  fi+fi+if test -z "$CC"; then+  # Extract the first word of "cc", so it can be a program name with args.+set dummy cc; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+  ac_prog_rejected=no+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then+       ac_prog_rejected=yes+       continue+     fi+    ac_cv_prog_CC="cc"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++if test $ac_prog_rejected = yes; then+  # We found a bogon in the path, so make sure we never use it.+  set dummy $ac_cv_prog_CC+  shift+  if test $# != 0; then+    # We chose a different compiler from the bogus one.+    # However, it has the same basename, so the bogon will be chosen+    # first if we set CC to just the basename; use the full file name.+    shift+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"+  fi+fi+fi ;;+esac+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+printf "%s\n" "$CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$CC"; then+  if test -n "$ac_tool_prefix"; then+  for ac_prog in cl.exe+  do+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.+set dummy $ac_tool_prefix$ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+printf "%s\n" "$CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++    test -n "$CC" && break+  done+fi+if test -z "$CC"; then+  ac_ct_CC=$CC+  for ac_prog in cl.exe+do+  # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_CC"; then+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_CC="$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_CC=$ac_cv_prog_ac_ct_CC+if test -n "$ac_ct_CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5+printf "%s\n" "$ac_ct_CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  test -n "$ac_ct_CC" && break+done++  if test "x$ac_ct_CC" = x; then+    CC=""+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    CC=$ac_ct_CC+  fi+fi++fi+if test -z "$CC"; then+  if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.+set dummy ${ac_tool_prefix}clang; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="${ac_tool_prefix}clang"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+printf "%s\n" "$CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_CC"; then+  ac_ct_CC=$CC+  # Extract the first word of "clang", so it can be a program name with args.+set dummy clang; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_CC+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_CC"; then+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_CC="clang"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_CC=$ac_cv_prog_ac_ct_CC+if test -n "$ac_ct_CC"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5+printf "%s\n" "$ac_ct_CC" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_CC" = x; then+    CC=""+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    CC=$ac_ct_CC+  fi+else+  CC="$ac_cv_prog_CC"+fi++fi+++test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error $? "no acceptable C compiler found in \$PATH+See 'config.log' for more details" "$LINENO" 5; }++# Provide some information about the compiler.+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5+set X $ac_compile+ac_compiler=$2+for ac_option in --version -v -V -qversion -version; do+  { { ac_try="$ac_compiler $ac_option >&5"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    sed '10a\+... rest of stderr output deleted ...+         10q' conftest.err >conftest.er1+    cat conftest.er1 >&5+  fi+  rm -f conftest.er1 conftest.err+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+done++cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"+# Try to create an executable without -o first, disregard a.out.+# It will help us diagnose broken compilers, and finding out an intuition+# of exeext.+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5+printf %s "checking whether the C compiler works... " >&6; }+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`++# The possible output files:+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"++ac_rmfiles=+for ac_file in $ac_files+do+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;+  esac+done+rm -f $ac_rmfiles++if { { ac_try="$ac_link_default"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_link_default") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+then :+  # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'.+# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no'+# in a Makefile.  We should not override ac_cv_exeext if it was cached,+# so that the user can short-circuit this test for compilers unknown to+# Autoconf.+for ac_file in $ac_files ''+do+  test -f "$ac_file" || continue+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )+	;;+    [ab].out )+	# We found the default executable, but exeext='' is most+	# certainly right.+	break;;+    *.* )+	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;+	then :; else+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`+	fi+	# We set ac_cv_exeext here because the later test for it is not+	# safe: cross compilers may not add the suffix if given an '-o'+	# argument, so we may need to know it at that point already.+	# Even if this section looks crufty: it has the advantage of+	# actually working.+	break;;+    * )+	break;;+  esac+done+test "$ac_cv_exeext" = no && ac_cv_exeext=++else case e in #(+  e) ac_file='' ;;+esac+fi+if test -z "$ac_file"+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error 77 "C compiler cannot create executables+See 'config.log' for more details" "$LINENO" 5; }+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; } ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5+printf %s "checking for C compiler default output file name... " >&6; }+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5+printf "%s\n" "$ac_file" >&6; }+ac_exeext=$ac_cv_exeext++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out+ac_clean_files=$ac_clean_files_save+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5+printf %s "checking for suffix of executables... " >&6; }+if { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+then :+  # If both 'conftest.exe' and 'conftest' are 'present' (well, observable)+# catch 'conftest.exe'.  For instance with Cygwin, 'ls conftest' will+# work properly (i.e., refer to 'conftest.exe'), while it won't with+# 'rm'.+for ac_file in conftest.exe conftest conftest.*; do+  test -f "$ac_file" || continue+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`+	  break;;+    * ) break;;+  esac+done+else case e in #(+  e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error $? "cannot compute suffix of executables: cannot compile and link+See 'config.log' for more details" "$LINENO" 5; } ;;+esac+fi+rm -f conftest conftest$ac_cv_exeext+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5+printf "%s\n" "$ac_cv_exeext" >&6; }++rm -f conftest.$ac_ext+EXEEXT=$ac_cv_exeext+ac_exeext=$EXEEXT+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdio.h>+int+main (void)+{+FILE *f = fopen ("conftest.out", "w");+ if (!f)+  return 1;+ return ferror (f) || fclose (f) != 0;++  ;+  return 0;+}+_ACEOF+ac_clean_files="$ac_clean_files conftest.out"+# Check that the compiler produces executables we can run.  If not, either+# the compiler is broken, or we cross compile.+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5+printf %s "checking whether we are cross compiling... " >&6; }+if test "$cross_compiling" != yes; then+  { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+  if { ac_try='./conftest$ac_cv_exeext'+  { { case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_try") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; }; then+    cross_compiling=no+  else+    if test "$cross_compiling" = maybe; then+	cross_compiling=yes+    else+	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error 77 "cannot run C compiled programs.+If you meant to cross compile, use '--host'.+See 'config.log' for more details" "$LINENO" 5; }+    fi+  fi+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5+printf "%s\n" "$cross_compiling" >&6; }++rm -f conftest.$ac_ext conftest$ac_cv_exeext \+  conftest.o conftest.obj conftest.out+ac_clean_files=$ac_clean_files_save+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5+printf %s "checking for suffix of object files... " >&6; }+if test ${ac_cv_objext+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+rm -f conftest.o conftest.obj+if { { ac_try="$ac_compile"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_compile") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+then :+  for ac_file in conftest.o conftest.obj conftest.*; do+  test -f "$ac_file" || continue;+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`+       break;;+  esac+done+else case e in #(+  e) printf "%s\n" "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error $? "cannot compute suffix of object files: cannot compile+See 'config.log' for more details" "$LINENO" 5; } ;;+esac+fi+rm -f conftest.$ac_cv_objext conftest.$ac_ext ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5+printf "%s\n" "$ac_cv_objext" >&6; }+OBJEXT=$ac_cv_objext+ac_objext=$OBJEXT+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5+printf %s "checking whether the compiler supports GNU C... " >&6; }+if test ${ac_cv_c_compiler_gnu+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{+#ifndef __GNUC__+       choke me+#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_compiler_gnu=yes+else case e in #(+  e) ac_compiler_gnu=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+ac_cv_c_compiler_gnu=$ac_compiler_gnu+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }+ac_compiler_gnu=$ac_cv_c_compiler_gnu++if test $ac_compiler_gnu = yes; then+  GCC=yes+else+  GCC=+fi+ac_test_CFLAGS=${CFLAGS+y}+ac_save_CFLAGS=$CFLAGS+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5+printf %s "checking whether $CC accepts -g... " >&6; }+if test ${ac_cv_prog_cc_g+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_save_c_werror_flag=$ac_c_werror_flag+   ac_c_werror_flag=yes+   ac_cv_prog_cc_g=no+   CFLAGS="-g"+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_prog_cc_g=yes+else case e in #(+  e) CFLAGS=""+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :++else case e in #(+  e) ac_c_werror_flag=$ac_save_c_werror_flag+	 CFLAGS="-g"+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_prog_cc_g=yes+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+   ac_c_werror_flag=$ac_save_c_werror_flag ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }+if test $ac_test_CFLAGS; then+  CFLAGS=$ac_save_CFLAGS+elif test $ac_cv_prog_cc_g = yes; then+  if test "$GCC" = yes; then+    CFLAGS="-g -O2"+  else+    CFLAGS="-g"+  fi+else+  if test "$GCC" = yes; then+    CFLAGS="-O2"+  else+    CFLAGS=+  fi+fi+ac_prog_cc_stdc=no+if test x$ac_prog_cc_stdc = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5+printf %s "checking for $CC option to enable C11 features... " >&6; }+if test ${ac_cv_prog_cc_c11+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_cv_prog_cc_c11=no+ac_save_CC=$CC+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$ac_c_conftest_c11_program+_ACEOF+for ac_arg in '' -std=gnu11+do+  CC="$ac_save_CC $ac_arg"+  if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_prog_cc_c11=$ac_arg+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam+  test "x$ac_cv_prog_cc_c11" != "xno" && break+done+rm -f conftest.$ac_ext+CC=$ac_save_CC ;;+esac+fi++if test "x$ac_cv_prog_cc_c11" = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5+printf "%s\n" "unsupported" >&6; }+else case e in #(+  e) if test "x$ac_cv_prog_cc_c11" = x+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5+printf "%s\n" "none needed" >&6; }+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }+     CC="$CC $ac_cv_prog_cc_c11" ;;+esac+fi+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11+  ac_prog_cc_stdc=c11 ;;+esac+fi+fi+if test x$ac_prog_cc_stdc = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5+printf %s "checking for $CC option to enable C99 features... " >&6; }+if test ${ac_cv_prog_cc_c99+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_cv_prog_cc_c99=no+ac_save_CC=$CC+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$ac_c_conftest_c99_program+_ACEOF+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=+do+  CC="$ac_save_CC $ac_arg"+  if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_prog_cc_c99=$ac_arg+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam+  test "x$ac_cv_prog_cc_c99" != "xno" && break+done+rm -f conftest.$ac_ext+CC=$ac_save_CC ;;+esac+fi++if test "x$ac_cv_prog_cc_c99" = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5+printf "%s\n" "unsupported" >&6; }+else case e in #(+  e) if test "x$ac_cv_prog_cc_c99" = x+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5+printf "%s\n" "none needed" >&6; }+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }+     CC="$CC $ac_cv_prog_cc_c99" ;;+esac+fi+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99+  ac_prog_cc_stdc=c99 ;;+esac+fi+fi+if test x$ac_prog_cc_stdc = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5+printf %s "checking for $CC option to enable C89 features... " >&6; }+if test ${ac_cv_prog_cc_c89+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_cv_prog_cc_c89=no+ac_save_CC=$CC+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$ac_c_conftest_c89_program+_ACEOF+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"+do+  CC="$ac_save_CC $ac_arg"+  if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_prog_cc_c89=$ac_arg+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam+  test "x$ac_cv_prog_cc_c89" != "xno" && break+done+rm -f conftest.$ac_ext+CC=$ac_save_CC ;;+esac+fi++if test "x$ac_cv_prog_cc_c89" = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5+printf "%s\n" "unsupported" >&6; }+else case e in #(+  e) if test "x$ac_cv_prog_cc_c89" = x+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5+printf "%s\n" "none needed" >&6; }+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }+     CC="$CC $ac_cv_prog_cc_c89" ;;+esac+fi+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89+  ac_prog_cc_stdc=c89 ;;+esac+fi+fi++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++  ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5+printf %s "checking whether $CC understands -c and -o together... " >&6; }+if test ${am_cv_prog_cc_c_o+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+  # Make sure it works both with $CC and with simple cc.+  # Following AC_PROG_CC_C_O, we do the test twice because some+  # compilers refuse to overwrite an existing .o file with -o,+  # though they will create one.+  am_cv_prog_cc_c_o=yes+  for am_i in 1 2; do+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5+   ac_status=$?+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   (exit $ac_status); } \+         && test -f conftest2.$ac_objext; then+      : OK+    else+      am_cv_prog_cc_c_o=no+      break+    fi+  done+  # aligned with autoconf, so not including core; see bug#72225.+  rm -f -r a.out a.exe b.out conftest.$ac_ext conftest.$ac_objext \+    conftest.dSYM conftest1.$ac_ext conftest1.$ac_objext conftest1.dSYM \+    conftest2.$ac_ext conftest2.$ac_objext conftest2.dSYM+  unset am_i ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5+printf "%s\n" "$am_cv_prog_cc_c_o" >&6; }+if test "$am_cv_prog_cc_c_o" != yes; then+   # Losing compiler, so override with the script.+   # FIXME: It is wrong to rewrite CC.+   # But if we don't then we get into trouble of one sort or another.+   # A longer-term fix would be to have automake use am__CC in this case,+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"+   CC="$am_aux_dir/compile $CC"+fi+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++++++++ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu+if test -z "$CXX"; then+  if test -n "$CCC"; then+    CXX=$CCC+  else+    if test -n "$ac_tool_prefix"; then+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang+++  do+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.+set dummy $ac_tool_prefix$ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$CXX"; then+  ac_cv_prog_CXX="$CXX" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+CXX=$ac_cv_prog_CXX+if test -n "$CXX"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5+printf "%s\n" "$CXX" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++    test -n "$CXX" && break+  done+fi+if test -z "$CXX"; then+  ac_ct_CXX=$CXX+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang+++do+  # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_CXX"; then+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_CXX="$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX+if test -n "$ac_ct_CXX"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5+printf "%s\n" "$ac_ct_CXX" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  test -n "$ac_ct_CXX" && break+done++  if test "x$ac_ct_CXX" = x; then+    CXX="g++"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    CXX=$ac_ct_CXX+  fi+fi++  fi+fi+# Provide some information about the compiler.+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5+set X $ac_compile+ac_compiler=$2+for ac_option in --version -v -V -qversion; do+  { { ac_try="$ac_compiler $ac_option >&5"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+printf "%s\n" "$ac_try_echo"; } >&5+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    sed '10a\+... rest of stderr output deleted ...+         10q' conftest.err >conftest.er1+    cat conftest.er1 >&5+  fi+  rm -f conftest.er1 conftest.err+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+done++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5+printf %s "checking whether the compiler supports GNU C++... " >&6; }+if test ${ac_cv_cxx_compiler_gnu+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{+#ifndef __GNUC__+       choke me+#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_compile "$LINENO"+then :+  ac_compiler_gnu=yes+else case e in #(+  e) ac_compiler_gnu=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5+printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; }+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu++if test $ac_compiler_gnu = yes; then+  GXX=yes+else+  GXX=+fi+ac_test_CXXFLAGS=${CXXFLAGS+y}+ac_save_CXXFLAGS=$CXXFLAGS+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5+printf %s "checking whether $CXX accepts -g... " >&6; }+if test ${ac_cv_prog_cxx_g+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_save_cxx_werror_flag=$ac_cxx_werror_flag+   ac_cxx_werror_flag=yes+   ac_cv_prog_cxx_g=no+   CXXFLAGS="-g"+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_compile "$LINENO"+then :+  ac_cv_prog_cxx_g=yes+else case e in #(+  e) CXXFLAGS=""+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_compile "$LINENO"+then :++else case e in #(+  e) ac_cxx_werror_flag=$ac_save_cxx_werror_flag+	 CXXFLAGS="-g"+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_compile "$LINENO"+then :+  ac_cv_prog_cxx_g=yes+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5+printf "%s\n" "$ac_cv_prog_cxx_g" >&6; }+if test $ac_test_CXXFLAGS; then+  CXXFLAGS=$ac_save_CXXFLAGS+elif test $ac_cv_prog_cxx_g = yes; then+  if test "$GXX" = yes; then+    CXXFLAGS="-g -O2"+  else+    CXXFLAGS="-g"+  fi+else+  if test "$GXX" = yes; then+    CXXFLAGS="-O2"+  else+    CXXFLAGS=+  fi+fi+ac_prog_cxx_stdcxx=no+if test x$ac_prog_cxx_stdcxx = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5+printf %s "checking for $CXX option to enable C++11 features... " >&6; }+if test ${ac_cv_prog_cxx_cxx11+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_cv_prog_cxx_cxx11=no+ac_save_CXX=$CXX+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$ac_cxx_conftest_cxx11_program+_ACEOF+for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA+do+  CXX="$ac_save_CXX $ac_arg"+  if ac_fn_cxx_try_compile "$LINENO"+then :+  ac_cv_prog_cxx_cxx11=$ac_arg+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam+  test "x$ac_cv_prog_cxx_cxx11" != "xno" && break+done+rm -f conftest.$ac_ext+CXX=$ac_save_CXX ;;+esac+fi++if test "x$ac_cv_prog_cxx_cxx11" = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5+printf "%s\n" "unsupported" >&6; }+else case e in #(+  e) if test "x$ac_cv_prog_cxx_cxx11" = x+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5+printf "%s\n" "none needed" >&6; }+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5+printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; }+     CXX="$CXX $ac_cv_prog_cxx_cxx11" ;;+esac+fi+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11+  ac_prog_cxx_stdcxx=cxx11 ;;+esac+fi+fi+if test x$ac_prog_cxx_stdcxx = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5+printf %s "checking for $CXX option to enable C++98 features... " >&6; }+if test ${ac_cv_prog_cxx_cxx98+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_cv_prog_cxx_cxx98=no+ac_save_CXX=$CXX+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$ac_cxx_conftest_cxx98_program+_ACEOF+for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA+do+  CXX="$ac_save_CXX $ac_arg"+  if ac_fn_cxx_try_compile "$LINENO"+then :+  ac_cv_prog_cxx_cxx98=$ac_arg+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam+  test "x$ac_cv_prog_cxx_cxx98" != "xno" && break+done+rm -f conftest.$ac_ext+CXX=$ac_save_CXX ;;+esac+fi++if test "x$ac_cv_prog_cxx_cxx98" = xno+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5+printf "%s\n" "unsupported" >&6; }+else case e in #(+  e) if test "x$ac_cv_prog_cxx_cxx98" = x+then :+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5+printf "%s\n" "none needed" >&6; }+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5+printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; }+     CXX="$CXX $ac_cv_prog_cxx_cxx98" ;;+esac+fi+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98+  ac_prog_cxx_stdcxx=cxx98 ;;+esac+fi+fi++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++CFLAGS=$save_CFLAGS++++++rm -rf .tst 2>/dev/null+mkdir .tst 2>/dev/null+if test -d .tst; then+  am__leading_dot=.+else+  am__leading_dot=_+fi+rmdir .tst 2>/dev/null++DEPDIR="${am__leading_dot}deps"++ac_config_commands="$ac_config_commands depfiles"++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5+printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; }+cat > confinc.mk << 'END'+am__doit:+	@echo this is the am__doit target >confinc.out+.PHONY: am__doit+END+am__include="#"+am__quote=+# BSD make does it like this.+echo '.include "confinc.mk" # ignored' > confmf.BSD+# Other make implementations (GNU, Solaris 10, AIX) do it like this.+echo 'include confinc.mk # ignored' > confmf.GNU+_am_result=no+for s in GNU BSD; do+  { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5+   (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5+   ac_status=$?+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   (exit $ac_status); }+  case $?:`cat confinc.out 2>/dev/null` in #(+  '0:this is the am__doit target') :+    case $s in #(+  BSD) :+    am__include='.include' am__quote='"' ;; #(+  *) :+    am__include='include' am__quote='' ;;+esac ;; #(+  *) :+     ;;+esac+  if test "$am__include" != "#"; then+    _am_result="yes ($s style)"+    break+  fi+done+rm -f confinc.* confmf.*+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5+printf "%s\n" "${_am_result}" >&6; }++# Check whether --enable-dependency-tracking was given.+if test ${enable_dependency_tracking+y}+then :+  enableval=$enable_dependency_tracking;+fi++if test "x$enable_dependency_tracking" != xno; then+  am_depcomp="$ac_aux_dir/depcomp"+  AMDEPBACKSLASH='\'+  am__nodep='_no'+fi+ if test "x$enable_dependency_tracking" != xno; then+  AMDEP_TRUE=+  AMDEP_FALSE='#'+else+  AMDEP_TRUE='#'+  AMDEP_FALSE=+fi+++# By default we simply use the C compiler to build assembly code.++test "${CCAS+set}" = set || CCAS=$CC+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS++++depcc="$CCAS"   am_compiler_list=++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5+printf %s "checking dependency style of $depcc... " >&6; }+if test ${am_cv_CCAS_dependencies_compiler_type+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then+  # We make a subdir and do the tests there.  Otherwise we can end up+  # making bogus files that we don't know about and never remove.  For+  # instance it was reported that on HP-UX the gcc test will end up+  # making a dummy file named 'D' -- because '-MD' means "put the output+  # in D".+  rm -rf conftest.dir+  mkdir conftest.dir+  # Copy depcomp to subdir because otherwise we won't find it if we're+  # using a relative directory.+  cp "$am_depcomp" conftest.dir+  cd conftest.dir+  # We will build objects and dependencies in a subdirectory because+  # it helps to detect inapplicable dependency modes.  For instance+  # both Tru64's cc and ICC support -MD to output dependencies as a+  # side effect of compilation, but ICC will put the dependencies in+  # the current directory while Tru64 will put them in the object+  # directory.+  mkdir sub++  am_cv_CCAS_dependencies_compiler_type=none+  if test "$am_compiler_list" = ""; then+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`+  fi+  am__universal=false+++  for depmode in $am_compiler_list; do+    # Setup a source with many dependencies, because some compilers+    # like to wrap large dependency lists on column 80 (with \), and+    # we should not choose a depcomp mode which is confused by this.+    #+    # We need to recreate these files for each test, as the compiler may+    # overwrite some of them when testing with obscure command lines.+    # This happens at least with the AIX C compiler.+    : > sub/conftest.c+    for i in 1 2 3 4 5 6; do+      echo '#include "conftst'$i'.h"' >> sub/conftest.c+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with+      # Solaris 10 /bin/sh.+      echo '/* dummy */' > sub/conftst$i.h+    done+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf++    # We check with '-c' and '-o' for the sake of the "dashmstdout"+    # mode.  It turns out that the SunPro C++ compiler does not properly+    # handle '-M -o', and we need to detect this.  Also, some Intel+    # versions had trouble with output in subdirs.+    am__obj=sub/conftest.${OBJEXT-o}+    am__minus_obj="-o $am__obj"+    case $depmode in+    gcc)+      # This depmode causes a compiler race in universal mode.+      test "$am__universal" = false || continue+      ;;+    nosideeffect)+      # After this tag, mechanisms are not by side-effect, so they'll+      # only be used when explicitly requested.+      if test "x$enable_dependency_tracking" = xyes; then+	continue+      else+	break+      fi+      ;;+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)+      # This compiler won't grok '-c -o', but also, the minuso test has+      # not run yet.  These depmodes are late enough in the game, and+      # so weak that their functioning should not be impacted.+      am__obj=conftest.${OBJEXT-o}+      am__minus_obj=+      ;;+    none) break ;;+    esac+    if depmode=$depmode \+       source=sub/conftest.c object=$am__obj \+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \+         >/dev/null 2>conftest.err &&+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then+      # icc doesn't choke on unknown options, it will just issue warnings+      # or remarks (even with -Werror).  So we grep stderr for any message+      # that says an option was ignored or not supported.+      # When given -MP, icc 7.0 and 7.1 complain thus:+      #   icc: Command line warning: ignoring option '-M'; no argument required+      # The diagnosis changed in icc 8.0:+      #   icc: Command line remark: option '-MP' not supported+      if (grep 'ignoring option' conftest.err ||+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else+        am_cv_CCAS_dependencies_compiler_type=$depmode+        break+      fi+    fi+  done++  cd ..+  rm -rf conftest.dir+else+  am_cv_CCAS_dependencies_compiler_type=none+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5+printf "%s\n" "$am_cv_CCAS_dependencies_compiler_type" >&6; }+CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type++ if+  test "x$enable_dependency_tracking" != xno \+  && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then+  am__fastdepCCAS_TRUE=+  am__fastdepCCAS_FALSE='#'+else+  am__fastdepCCAS_TRUE='#'+  am__fastdepCCAS_FALSE=+fi++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5+printf %s "checking for grep that handles long lines and -e... " >&6; }+if test ${ac_cv_path_GREP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -z "$GREP"; then+  ac_path_GREP_found=false+  # Loop through the user's path and test for each of PROGNAME-LIST+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_prog in grep ggrep+   do+    for ac_exec_ext in '' $ac_executable_extensions; do+      ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"+      as_fn_executable_p "$ac_path_GREP" || continue+# Check for GNU ac_path_GREP and select it if it is found.+  # Check for GNU $ac_path_GREP+case `"$ac_path_GREP" --version 2>&1` in #(+*GNU*)+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;+#(+*)+  ac_count=0+  printf %s 0123456789 >"conftest.in"+  while :+  do+    cat "conftest.in" "conftest.in" >"conftest.tmp"+    mv "conftest.tmp" "conftest.in"+    cp "conftest.in" "conftest.nl"+    printf "%s\n" 'GREP' >> "conftest.nl"+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break+    as_fn_arith $ac_count + 1 && ac_count=$as_val+    if test $ac_count -gt ${ac_path_GREP_max-0}; then+      # Best one so far, save it but keep looking for a better one+      ac_cv_path_GREP="$ac_path_GREP"+      ac_path_GREP_max=$ac_count+    fi+    # 10*(2^10) chars as input seems more than enough+    test $ac_count -gt 10 && break+  done+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;+esac++      $ac_path_GREP_found && break 3+    done+  done+  done+IFS=$as_save_IFS+  if test -z "$ac_cv_path_GREP"; then+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5+  fi+else+  ac_cv_path_GREP=$GREP+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5+printf "%s\n" "$ac_cv_path_GREP" >&6; }+ GREP="$ac_cv_path_GREP"+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5+printf %s "checking for egrep... " >&6; }+if test ${ac_cv_path_EGREP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if echo a | $GREP -E '(a|b)' >/dev/null 2>&1+   then ac_cv_path_EGREP="$GREP -E"+   else+     if test -z "$EGREP"; then+  ac_path_EGREP_found=false+  # Loop through the user's path and test for each of PROGNAME-LIST+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_prog in egrep+   do+    for ac_exec_ext in '' $ac_executable_extensions; do+      ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"+      as_fn_executable_p "$ac_path_EGREP" || continue+# Check for GNU ac_path_EGREP and select it if it is found.+  # Check for GNU $ac_path_EGREP+case `"$ac_path_EGREP" --version 2>&1` in #(+*GNU*)+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;+#(+*)+  ac_count=0+  printf %s 0123456789 >"conftest.in"+  while :+  do+    cat "conftest.in" "conftest.in" >"conftest.tmp"+    mv "conftest.tmp" "conftest.in"+    cp "conftest.in" "conftest.nl"+    printf "%s\n" 'EGREP' >> "conftest.nl"+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break+    as_fn_arith $ac_count + 1 && ac_count=$as_val+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then+      # Best one so far, save it but keep looking for a better one+      ac_cv_path_EGREP="$ac_path_EGREP"+      ac_path_EGREP_max=$ac_count+    fi+    # 10*(2^10) chars as input seems more than enough+    test $ac_count -gt 10 && break+  done+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;+esac++      $ac_path_EGREP_found && break 3+    done+  done+  done+IFS=$as_save_IFS+  if test -z "$ac_cv_path_EGREP"; then+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5+  fi+else+  ac_cv_path_EGREP=$EGREP+fi++   fi ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5+printf "%s\n" "$ac_cv_path_EGREP" >&6; }+ EGREP="$ac_cv_path_EGREP"++         EGREP_TRADITIONAL=$EGREP+ ac_cv_path_EGREP_TRADITIONAL=$EGREP++case `pwd` in+  *\ * | *\	*)+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5+printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;+esac++++macro_version='2.5.4'+macro_revision='2.5.4'+++++++++++++++ltmain=$ac_aux_dir/ltmain.sh++# Backslashify metacharacters that are still active within+# double-quoted strings.+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'++# Same as above, but do not quote variable references.+double_quote_subst='s/\(["`\\]\)/\\\1/g'++# Sed substitution to delay expansion of an escaped shell variable in a+# double_quote_subst'ed string.+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'++# Sed substitution to delay expansion of an escaped single quote.+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'++# Sed substitution to avoid accidental globbing in evaled expressions+no_glob_subst='s/\*/\\\*/g'++ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5+printf %s "checking how to print strings... " >&6; }+# Test print first, because it will be a builtin if present.+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then+  ECHO='print -r --'+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then+  ECHO='printf %s\n'+else+  # Use this function as a fallback that always works.+  func_fallback_echo ()+  {+    eval 'cat <<_LTECHO_EOF+$1+_LTECHO_EOF'+  }+  ECHO='func_fallback_echo'+fi++# func_echo_all arg...+# Invoke $ECHO with all args, space-separated.+func_echo_all ()+{+    $ECHO ""+}++case $ECHO in+  printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5+printf "%s\n" "printf" >&6; } ;;+  print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5+printf "%s\n" "print -r" >&6; } ;;+  *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5+printf "%s\n" "cat" >&6; } ;;+esac+++++++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5+printf %s "checking for a sed that does not truncate output... " >&6; }+if test ${ac_cv_path_SED+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)           ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/+     for ac_i in 1 2 3 4 5 6 7; do+       ac_script="$ac_script$as_nl$ac_script"+     done+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed+     { ac_script=; unset ac_script;}+     if test -z "$SED"; then+  ac_path_SED_found=false+  # Loop through the user's path and test for each of PROGNAME-LIST+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_prog in sed gsed+   do+    for ac_exec_ext in '' $ac_executable_extensions; do+      ac_path_SED="$as_dir$ac_prog$ac_exec_ext"+      as_fn_executable_p "$ac_path_SED" || continue+# Check for GNU ac_path_SED and select it if it is found.+  # Check for GNU $ac_path_SED+case `"$ac_path_SED" --version 2>&1` in #(+*GNU*)+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;+#(+*)+  ac_count=0+  printf %s 0123456789 >"conftest.in"+  while :+  do+    cat "conftest.in" "conftest.in" >"conftest.tmp"+    mv "conftest.tmp" "conftest.in"+    cp "conftest.in" "conftest.nl"+    printf "%s\n" '' >> "conftest.nl"+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break+    as_fn_arith $ac_count + 1 && ac_count=$as_val+    if test $ac_count -gt ${ac_path_SED_max-0}; then+      # Best one so far, save it but keep looking for a better one+      ac_cv_path_SED="$ac_path_SED"+      ac_path_SED_max=$ac_count+    fi+    # 10*(2^10) chars as input seems more than enough+    test $ac_count -gt 10 && break+  done+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;+esac++      $ac_path_SED_found && break 3+    done+  done+  done+IFS=$as_save_IFS+  if test -z "$ac_cv_path_SED"; then+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5+  fi+else+  ac_cv_path_SED=$SED+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5+printf "%s\n" "$ac_cv_path_SED" >&6; }+ SED="$ac_cv_path_SED"+  rm -f conftest.sed++test -z "$SED" && SED=sed+Xsed="$SED -e 1s/^X//"++++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5+printf %s "checking for fgrep... " >&6; }+if test ${ac_cv_path_FGREP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1+   then ac_cv_path_FGREP="$GREP -F"+   else+     if test -z "$FGREP"; then+  ac_path_FGREP_found=false+  # Loop through the user's path and test for each of PROGNAME-LIST+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_prog in fgrep+   do+    for ac_exec_ext in '' $ac_executable_extensions; do+      ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext"+      as_fn_executable_p "$ac_path_FGREP" || continue+# Check for GNU ac_path_FGREP and select it if it is found.+  # Check for GNU $ac_path_FGREP+case `"$ac_path_FGREP" --version 2>&1` in #(+*GNU*)+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;+#(+*)+  ac_count=0+  printf %s 0123456789 >"conftest.in"+  while :+  do+    cat "conftest.in" "conftest.in" >"conftest.tmp"+    mv "conftest.tmp" "conftest.in"+    cp "conftest.in" "conftest.nl"+    printf "%s\n" 'FGREP' >> "conftest.nl"+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break+    as_fn_arith $ac_count + 1 && ac_count=$as_val+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then+      # Best one so far, save it but keep looking for a better one+      ac_cv_path_FGREP="$ac_path_FGREP"+      ac_path_FGREP_max=$ac_count+    fi+    # 10*(2^10) chars as input seems more than enough+    test $ac_count -gt 10 && break+  done+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;+esac++      $ac_path_FGREP_found && break 3+    done+  done+  done+IFS=$as_save_IFS+  if test -z "$ac_cv_path_FGREP"; then+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5+  fi+else+  ac_cv_path_FGREP=$FGREP+fi++   fi ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5+printf "%s\n" "$ac_cv_path_FGREP" >&6; }+ FGREP="$ac_cv_path_FGREP"+++test -z "$GREP" && GREP=grep++++++++++++++++++++# Check whether --with-gnu-ld was given.+if test ${with_gnu_ld+y}+then :+  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes+else case e in #(+  e) with_gnu_ld=no ;;+esac+fi++ac_prog=ld+if test yes = "$GCC"; then+  # Check if gcc -print-prog-name=ld gives a path.+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5+printf %s "checking for ld used by $CC... " >&6; }+  case $host in+  *-*-mingw* | *-*-windows*)+    # gcc leaves a trailing carriage return, which upsets mingw+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;+  *)+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;+  esac+  case $ac_prog in+    # Accept absolute paths.+    [\\/]* | ?:[\\/]*)+      re_direlt='/[^/][^/]*/\.\./'+      # Canonicalize the pathname of ld+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`+      done+      test -z "$LD" && LD=$ac_prog+      ;;+  "")+    # If it fails, then pretend we aren't using GCC.+    ac_prog=ld+    ;;+  *)+    # If it is relative, then search for the first ld in PATH.+    with_gnu_ld=unknown+    ;;+  esac+elif test yes = "$with_gnu_ld"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5+printf %s "checking for GNU ld... " >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5+printf %s "checking for non-GNU ld... " >&6; }+fi+if test ${lt_cv_path_LD+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -z "$LD"; then+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+  for ac_dir in $PATH; do+    IFS=$lt_save_ifs+    test -z "$ac_dir" && ac_dir=.+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then+      lt_cv_path_LD=$ac_dir/$ac_prog+      # Check to see if the program is GNU ld.  I'd rather use --version,+      # but apparently some variants of GNU ld only accept -v.+      # Break only if it was the GNU/non-GNU ld that we prefer.+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in+      *GNU* | *'with BFD'*)+	test no != "$with_gnu_ld" && break+	;;+      *)+	test yes != "$with_gnu_ld" && break+	;;+      esac+    fi+  done+  IFS=$lt_save_ifs+else+  lt_cv_path_LD=$LD # Let the user override the test with a path.+fi ;;+esac+fi++LD=$lt_cv_path_LD+if test -n "$LD"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5+printf "%s\n" "$LD" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5+printf %s "checking if the linker ($LD) is GNU ld... " >&6; }+if test ${lt_cv_prog_gnu_ld+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) # I'd rather use --version here, but apparently some GNU lds only accept -v.+case `$LD -v 2>&1 </dev/null` in+*GNU* | *'with BFD'*)+  lt_cv_prog_gnu_ld=yes+  ;;+*)+  lt_cv_prog_gnu_ld=no+  ;;+esac ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5+printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; }+with_gnu_ld=$lt_cv_prog_gnu_ld++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5+printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; }+if test ${lt_cv_path_NM+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$NM"; then+  # Let the user override the test.+  lt_cv_path_NM=$NM+else+  lt_nm_to_check=${ac_tool_prefix}nm+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then+    lt_nm_to_check="$lt_nm_to_check nm"+  fi+  for lt_tmp_nm in $lt_nm_to_check; do+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do+      IFS=$lt_save_ifs+      test -z "$ac_dir" && ac_dir=.+      tmp_nm=$ac_dir/$lt_tmp_nm+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then+	# Check to see if the nm accepts a BSD-compat flag.+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:+	#   nm: unknown option "B" ignored+	# Tru64's nm complains that /dev/null is an invalid object file+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty+	case $build_os in+	mingw* | windows*) lt_bad_file=conftest.nm/nofile ;;+	*) lt_bad_file=/dev/null ;;+	esac+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in+	*$lt_bad_file* | *'Invalid file or object type'*)+	  lt_cv_path_NM="$tmp_nm -B"+	  break 2+	  ;;+	*)+	  case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in+	  */dev/null*)+	    lt_cv_path_NM="$tmp_nm -p"+	    break 2+	    ;;+	  *)+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but+	    continue # so that we can try to find one that supports BSD flags+	    ;;+	  esac+	  ;;+	esac+      fi+    done+    IFS=$lt_save_ifs+  done+  : ${lt_cv_path_NM=no}+fi ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5+printf "%s\n" "$lt_cv_path_NM" >&6; }+if test no != "$lt_cv_path_NM"; then+  NM=$lt_cv_path_NM+else+  # Didn't find any BSD compatible name lister, look for dumpbin.+  if test -n "$DUMPBIN"; then :+    # Let the user override the test.+  else+    if test -n "$ac_tool_prefix"; then+  for ac_prog in dumpbin "link -dump"+  do+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.+set dummy $ac_tool_prefix$ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_DUMPBIN+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$DUMPBIN"; then+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+DUMPBIN=$ac_cv_prog_DUMPBIN+if test -n "$DUMPBIN"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5+printf "%s\n" "$DUMPBIN" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++    test -n "$DUMPBIN" && break+  done+fi+if test -z "$DUMPBIN"; then+  ac_ct_DUMPBIN=$DUMPBIN+  for ac_prog in dumpbin "link -dump"+do+  # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_DUMPBIN+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_DUMPBIN"; then+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN+if test -n "$ac_ct_DUMPBIN"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5+printf "%s\n" "$ac_ct_DUMPBIN" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  test -n "$ac_ct_DUMPBIN" && break+done++  if test "x$ac_ct_DUMPBIN" = x; then+    DUMPBIN=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    DUMPBIN=$ac_ct_DUMPBIN+  fi+fi++    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in+    *COFF*)+      DUMPBIN="$DUMPBIN -symbols -headers"+      ;;+    *)+      DUMPBIN=:+      ;;+    esac+  fi++  if test : != "$DUMPBIN"; then+    NM=$DUMPBIN+  fi+fi+test -z "$NM" && NM=nm+++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5+printf %s "checking the name lister ($NM) interface... " >&6; }+if test ${lt_cv_nm_interface+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_nm_interface="BSD nm"+  echo "int some_variable = 0;" > conftest.$ac_ext+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)+  (eval "$ac_compile" 2>conftest.err)+  cat conftest.err >&5+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)+  cat conftest.err >&5+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)+  cat conftest.out >&5+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then+    lt_cv_nm_interface="MS dumpbin"+  fi+  rm -f conftest* ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5+printf "%s\n" "$lt_cv_nm_interface" >&6; }++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5+printf %s "checking whether ln -s works... " >&6; }+LN_S=$as_ln_s+if test "$LN_S" = "ln -s"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5+printf "%s\n" "no, using $LN_S" >&6; }+fi++# find the maximum length of command line arguments+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5+printf %s "checking the maximum length of command line arguments... " >&6; }+if test ${lt_cv_sys_max_cmd_len+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)   i=0+  teststring=ABCD++  case $build_os in+  msdosdjgpp*)+    # On DJGPP, this test can blow up pretty badly due to problems in libc+    # (any single argument exceeding 2000 bytes causes a buffer overrun+    # during glob expansion).  Even if it were fixed, the result of this+    # check would be larger than it should be.+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right+    ;;++  gnu* | ironclad*)+    # Under GNU Hurd and Ironclad, this test is not required because there+    # is no limit to the length of command line arguments.+    # Libtool will interpret -1 as no limit whatsoever+    lt_cv_sys_max_cmd_len=-1;+    ;;++  cygwin* | mingw* | windows* | cegcc*)+    # On Win9x/ME, this test blows up -- it succeeds, but takes+    # about 5 minutes as the teststring grows exponentially.+    # Worse, since 9x/ME are not pre-emptively multitasking,+    # you end up with a "frozen" computer, even though with patience+    # the test eventually succeeds (with a max line length of 256k).+    # Instead, let's just punt: use the minimum linelength reported by+    # all of the supported platforms: 8192 (on NT/2K/XP).+    lt_cv_sys_max_cmd_len=8192;+    ;;++  mint*)+    # On MiNT this can take a long time and run out of memory.+    lt_cv_sys_max_cmd_len=8192;+    ;;++  amigaos*)+    # On AmigaOS with pdksh, this test takes hours, literally.+    # So we just punt and use a minimum line length of 8192.+    lt_cv_sys_max_cmd_len=8192;+    ;;++  darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)+    # This has been around since 386BSD, at least.  Likely further.+    if test -x /sbin/sysctl; then+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`+    elif test -x /usr/sbin/sysctl; then+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`+    else+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs+    fi+    # And add a safety zone+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`+    ;;++  interix*)+    # We know the value 262144 and hardcode it with a safety zone (like BSD)+    lt_cv_sys_max_cmd_len=196608+    ;;++  os2*)+    # The test takes a long time on OS/2.+    lt_cv_sys_max_cmd_len=8192+    ;;++  osf*)+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not+    # nice to cause kernel panics so lets avoid the loop below.+    # First set a reasonable default.+    lt_cv_sys_max_cmd_len=16384+    #+    if test -x /sbin/sysconfig; then+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in+        *1*) lt_cv_sys_max_cmd_len=-1 ;;+      esac+    fi+    ;;+  sco3.2v5*)+    lt_cv_sys_max_cmd_len=102400+    ;;+  sysv5* | sco5v6* | sysv4.2uw2*)+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`+    if test -n "$kargmax"; then+      lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[	 ]//'`+    else+      lt_cv_sys_max_cmd_len=32768+    fi+    ;;+  *)+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`+    if test -n "$lt_cv_sys_max_cmd_len" && \+       test undefined != "$lt_cv_sys_max_cmd_len"; then+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`+    else+      # Make teststring a little bigger before we do anything with it.+      # a 1K string should be a reasonable start.+      for i in 1 2 3 4 5 6 7 8; do+        teststring=$teststring$teststring+      done+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}+      # If test is not a shell built-in, we'll probably end up computing a+      # maximum length that is only half of the actual maximum length, but+      # we can't tell.+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&+	      test 17 != "$i" # 1/2 MB should be enough+      do+        i=`expr $i + 1`+        teststring=$teststring$teststring+      done+      # Only check the string length outside the loop.+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`+      teststring=+      # Add a significant safety factor because C++ compilers can tack on+      # massive amounts of additional arguments before passing them to the+      # linker.  It appears as though 1/2 is a usable value.+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`+    fi+    ;;+  esac+ ;;+esac+fi++if test -n "$lt_cv_sys_max_cmd_len"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5+printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5+printf "%s\n" "none" >&6; }+fi+max_cmd_len=$lt_cv_sys_max_cmd_len+++++++: ${CP="cp -f"}+: ${MV="mv -f"}+: ${RM="rm -f"}++if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then+  lt_unset=unset+else+  lt_unset=false+fi++++++# test EBCDIC or ASCII+case `echo X|tr X '\101'` in+ A) # ASCII based system+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr+  lt_SP2NL='tr \040 \012'+  lt_NL2SP='tr \015\012 \040\040'+  ;;+ *) # EBCDIC based system+  lt_SP2NL='tr \100 \n'+  lt_NL2SP='tr \r\n \100\100'+  ;;+esac++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5+printf %s "checking how to convert $build file names to $host format... " >&6; }+if test ${lt_cv_to_host_file_cmd+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) case $host in+  *-*-mingw* )+    case $build in+      *-*-mingw* | *-*-windows* ) # actually msys+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32+        ;;+      *-*-cygwin* )+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32+        ;;+      * ) # otherwise, assume *nix+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32+        ;;+    esac+    ;;+  *-*-cygwin* )+    case $build in+      *-*-mingw* | *-*-windows* ) # actually msys+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin+        ;;+      *-*-cygwin* )+        lt_cv_to_host_file_cmd=func_convert_file_noop+        ;;+      * ) # otherwise, assume *nix+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin+        ;;+    esac+    ;;+  * ) # unhandled hosts (and "normal" native builds)+    lt_cv_to_host_file_cmd=func_convert_file_noop+    ;;+esac+ ;;+esac+fi++to_host_file_cmd=$lt_cv_to_host_file_cmd+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5+printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; }++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5+printf %s "checking how to convert $build file names to toolchain format... " >&6; }+if test ${lt_cv_to_tool_file_cmd+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) #assume ordinary cross tools, or native build.+lt_cv_to_tool_file_cmd=func_convert_file_noop+case $host in+  *-*-mingw* | *-*-windows* )+    case $build in+      *-*-mingw* | *-*-windows* ) # actually msys+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32+        ;;+    esac+    ;;+esac+ ;;+esac+fi++to_tool_file_cmd=$lt_cv_to_tool_file_cmd+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5+printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; }++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5+printf %s "checking for $LD option to reload object files... " >&6; }+if test ${lt_cv_ld_reload_flag+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_ld_reload_flag='-r' ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5+printf "%s\n" "$lt_cv_ld_reload_flag" >&6; }+reload_flag=$lt_cv_ld_reload_flag+case $reload_flag in+"" | " "*) ;;+*) reload_flag=" $reload_flag" ;;+esac+reload_cmds='$LD$reload_flag -o $output$reload_objs'+case $host_os in+  cygwin* | mingw* | windows* | pw32* | cegcc*)+    if test yes != "$GCC"; then+      reload_cmds=false+    fi+    ;;+  darwin*)+    if test yes = "$GCC"; then+      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'+    else+      reload_cmds='$LD$reload_flag -o $output$reload_objs'+    fi+    ;;+esac++++++++++# Extract the first word of "file", so it can be a program name with args.+set dummy file; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_FILECMD+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$FILECMD"; then+  ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_FILECMD="file"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_prog_FILECMD" && ac_cv_prog_FILECMD=":"+fi ;;+esac+fi+FILECMD=$ac_cv_prog_FILECMD+if test -n "$FILECMD"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5+printf "%s\n" "$FILECMD" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++++++++if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.+set dummy ${ac_tool_prefix}objdump; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_OBJDUMP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$OBJDUMP"; then+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+OBJDUMP=$ac_cv_prog_OBJDUMP+if test -n "$OBJDUMP"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5+printf "%s\n" "$OBJDUMP" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_OBJDUMP"; then+  ac_ct_OBJDUMP=$OBJDUMP+  # Extract the first word of "objdump", so it can be a program name with args.+set dummy objdump; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_OBJDUMP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_OBJDUMP"; then+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_OBJDUMP="objdump"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP+if test -n "$ac_ct_OBJDUMP"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5+printf "%s\n" "$ac_ct_OBJDUMP" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_OBJDUMP" = x; then+    OBJDUMP="false"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    OBJDUMP=$ac_ct_OBJDUMP+  fi+else+  OBJDUMP="$ac_cv_prog_OBJDUMP"+fi++test -z "$OBJDUMP" && OBJDUMP=objdump++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5+printf %s "checking how to recognize dependent libraries... " >&6; }+if test ${lt_cv_deplibs_check_method+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_file_magic_cmd='$MAGIC_CMD'+lt_cv_file_magic_test_file=+lt_cv_deplibs_check_method='unknown'+# Need to set the preceding variable on all platforms that support+# interlibrary dependencies.+# 'none' -- dependencies not supported.+# 'unknown' -- same as none, but documents that we really don't know.+# 'pass_all' -- all dependencies passed with no checks.+# 'file_magic [[regex]]' -- check by looking for files in library path+# that responds to the $file_magic_cmd with a given extended regex.+# If you have 'file' or equivalent on your system and you're not sure+# whether 'pass_all' will *always* work, you probably want this one.++case $host_os in+aix[4-9]*)+  lt_cv_deplibs_check_method=pass_all+  ;;++beos*)+  lt_cv_deplibs_check_method=pass_all+  ;;++bsdi[45]*)+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'+  lt_cv_file_magic_cmd='$FILECMD -L'+  lt_cv_file_magic_test_file=/shlib/libc.so+  ;;++cygwin*)+  # func_win32_libid is a shell function defined in ltmain.sh+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'+  lt_cv_file_magic_cmd='func_win32_libid'+  ;;++mingw* | windows* | pw32*)+  # Base MSYS/MinGW do not provide the 'file' command needed by+  # func_win32_libid shell function, so use a weaker test based on 'objdump',+  # unless we find 'file', for example because we are cross-compiling.+  if ( file / ) >/dev/null 2>&1; then+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'+    lt_cv_file_magic_cmd='func_win32_libid'+  else+    # Keep this pattern in sync with the one in func_win32_libid.+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)'+    lt_cv_file_magic_cmd='$OBJDUMP -f'+  fi+  ;;++cegcc*)+  # use the weaker test based on 'objdump'. See mingw*.+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'+  lt_cv_file_magic_cmd='$OBJDUMP -f'+  ;;++darwin* | rhapsody*)+  lt_cv_deplibs_check_method=pass_all+  ;;++freebsd* | dragonfly* | midnightbsd*)+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then+    case $host_cpu in+    i*86 )+      # Not sure whether the presence of OpenBSD here was a mistake.+      # Let's accept both of them until this is cleared up.+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'+      lt_cv_file_magic_cmd=$FILECMD+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`+      ;;+    esac+  else+    lt_cv_deplibs_check_method=pass_all+  fi+  ;;++haiku*)+  lt_cv_deplibs_check_method=pass_all+  ;;++hpux10.20* | hpux11*)+  lt_cv_file_magic_cmd=$FILECMD+  case $host_cpu in+  ia64*)+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so+    ;;+  hppa*64*)+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl+    ;;+  *)+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'+    lt_cv_file_magic_test_file=/usr/lib/libc.sl+    ;;+  esac+  ;;++interix[3-9]*)+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'+  ;;++irix5* | irix6* | nonstopux*)+  case $LD in+  *-32|*"-32 ") libmagic=32-bit;;+  *-n32|*"-n32 ") libmagic=N32;;+  *-64|*"-64 ") libmagic=64-bit;;+  *) libmagic=never-match;;+  esac+  lt_cv_deplibs_check_method=pass_all+  ;;++# This must be glibc/ELF.+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+  lt_cv_deplibs_check_method=pass_all+  ;;++*-mlibc)+  lt_cv_deplibs_check_method=pass_all+  ;;++netbsd* | netbsdelf*-gnu)+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'+  else+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'+  fi+  ;;++newos6*)+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'+  lt_cv_file_magic_cmd=$FILECMD+  lt_cv_file_magic_test_file=/usr/lib/libnls.so+  ;;++*nto* | *qnx*)+  lt_cv_deplibs_check_method=pass_all+  ;;++openbsd*)+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'+  else+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'+  fi+  ;;++osf3* | osf4* | osf5*)+  lt_cv_deplibs_check_method=pass_all+  ;;++rdos*)+  lt_cv_deplibs_check_method=pass_all+  ;;++serenity*)+  lt_cv_deplibs_check_method=pass_all+  ;;++solaris*)+  lt_cv_deplibs_check_method=pass_all+  ;;++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)+  lt_cv_deplibs_check_method=pass_all+  ;;++sysv4 | sysv4.3*)+  case $host_vendor in+  motorola)+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`+    ;;+  ncr)+    lt_cv_deplibs_check_method=pass_all+    ;;+  sequent)+    lt_cv_file_magic_cmd='/bin/file'+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'+    ;;+  sni)+    lt_cv_file_magic_cmd='/bin/file'+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"+    lt_cv_file_magic_test_file=/lib/libc.so+    ;;+  siemens)+    lt_cv_deplibs_check_method=pass_all+    ;;+  pc)+    lt_cv_deplibs_check_method=pass_all+    ;;+  esac+  ;;++tpf*)+  lt_cv_deplibs_check_method=pass_all+  ;;+os2*)+  lt_cv_deplibs_check_method=pass_all+  ;;+esac+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5+printf "%s\n" "$lt_cv_deplibs_check_method" >&6; }++file_magic_glob=+want_nocaseglob=no+if test "$build" = "$host"; then+  case $host_os in+  mingw* | windows* | pw32*)+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then+      want_nocaseglob=yes+    else+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`+    fi+    ;;+  esac+fi++file_magic_cmd=$lt_cv_file_magic_cmd+deplibs_check_method=$lt_cv_deplibs_check_method+test -z "$deplibs_check_method" && deplibs_check_method=unknown+++++++++++++++++++++++if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.+set dummy ${ac_tool_prefix}dlltool; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_DLLTOOL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$DLLTOOL"; then+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+DLLTOOL=$ac_cv_prog_DLLTOOL+if test -n "$DLLTOOL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5+printf "%s\n" "$DLLTOOL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_DLLTOOL"; then+  ac_ct_DLLTOOL=$DLLTOOL+  # Extract the first word of "dlltool", so it can be a program name with args.+set dummy dlltool; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_DLLTOOL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_DLLTOOL"; then+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL+if test -n "$ac_ct_DLLTOOL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5+printf "%s\n" "$ac_ct_DLLTOOL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_DLLTOOL" = x; then+    DLLTOOL="false"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    DLLTOOL=$ac_ct_DLLTOOL+  fi+else+  DLLTOOL="$ac_cv_prog_DLLTOOL"+fi++test -z "$DLLTOOL" && DLLTOOL=dlltool+++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5+printf %s "checking how to associate runtime and link libraries... " >&6; }+if test ${lt_cv_sharedlib_from_linklib_cmd+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_sharedlib_from_linklib_cmd='unknown'++case $host_os in+cygwin* | mingw* | windows* | pw32* | cegcc*)+  # two different shell functions defined in ltmain.sh;+  # decide which one to use based on capabilities of $DLLTOOL+  case `$DLLTOOL --help 2>&1` in+  *--identify-strict*)+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib+    ;;+  *)+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback+    ;;+  esac+  ;;+*)+  # fallback: assume linklib IS sharedlib+  lt_cv_sharedlib_from_linklib_cmd=$ECHO+  ;;+esac+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5+printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; }+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO+++++++++if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.+set dummy ${ac_tool_prefix}ranlib; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_RANLIB+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$RANLIB"; then+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+RANLIB=$ac_cv_prog_RANLIB+if test -n "$RANLIB"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5+printf "%s\n" "$RANLIB" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_RANLIB"; then+  ac_ct_RANLIB=$RANLIB+  # Extract the first word of "ranlib", so it can be a program name with args.+set dummy ranlib; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_RANLIB+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_RANLIB"; then+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_RANLIB="ranlib"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB+if test -n "$ac_ct_RANLIB"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5+printf "%s\n" "$ac_ct_RANLIB" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_RANLIB" = x; then+    RANLIB=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    RANLIB=$ac_ct_RANLIB+  fi+else+  RANLIB="$ac_cv_prog_RANLIB"+fi++if test -n "$ac_tool_prefix"; then+  for ac_prog in ar+  do+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.+set dummy $ac_tool_prefix$ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_AR+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$AR"; then+  ac_cv_prog_AR="$AR" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+AR=$ac_cv_prog_AR+if test -n "$AR"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5+printf "%s\n" "$AR" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++    test -n "$AR" && break+  done+fi+if test -z "$AR"; then+  ac_ct_AR=$AR+  for ac_prog in ar+do+  # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_AR+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_AR"; then+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_AR="$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_AR=$ac_cv_prog_ac_ct_AR+if test -n "$ac_ct_AR"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5+printf "%s\n" "$ac_ct_AR" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  test -n "$ac_ct_AR" && break+done++  if test "x$ac_ct_AR" = x; then+    AR="false"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    AR=$ac_ct_AR+  fi+fi++: ${AR=ar}+++++++# Use ARFLAGS variable as AR's operation code to sync the variable naming with+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have+# higher priority because that's what people were doing historically (setting+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS+# variable obsoleted/removed.++test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}+lt_ar_flags=$AR_FLAGS+++++++# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.+++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5+printf %s "checking for archiver @FILE support... " >&6; }+if test ${lt_cv_ar_at_file+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_ar_at_file=no+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  echo conftest.$ac_objext > conftest.lst+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5+  (eval $lt_ar_try) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+      if test 0 -eq "$ac_status"; then+	# Ensure the archiver fails upon bogus file names.+	rm -f conftest.$ac_objext libconftest.a+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5+  (eval $lt_ar_try) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+	if test 0 -ne "$ac_status"; then+          lt_cv_ar_at_file=@+        fi+      fi+      rm -f conftest.* libconftest.a++fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+   ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5+printf "%s\n" "$lt_cv_ar_at_file" >&6; }++if test no = "$lt_cv_ar_at_file"; then+  archiver_list_spec=+else+  archiver_list_spec=$lt_cv_ar_at_file+fi++++++++if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.+set dummy ${ac_tool_prefix}strip; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_STRIP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$STRIP"; then+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+STRIP=$ac_cv_prog_STRIP+if test -n "$STRIP"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5+printf "%s\n" "$STRIP" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_STRIP"; then+  ac_ct_STRIP=$STRIP+  # Extract the first word of "strip", so it can be a program name with args.+set dummy strip; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_STRIP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_STRIP"; then+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_STRIP="strip"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP+if test -n "$ac_ct_STRIP"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5+printf "%s\n" "$ac_ct_STRIP" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_STRIP" = x; then+    STRIP=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    STRIP=$ac_ct_STRIP+  fi+else+  STRIP="$ac_cv_prog_STRIP"+fi++test -z "$STRIP" && STRIP=:++++++++test -z "$RANLIB" && RANLIB=:+++++++# Determine commands to create old-style static archives.+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'+old_postinstall_cmds='chmod 644 $oldlib'+old_postuninstall_cmds=++if test -n "$RANLIB"; then+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"+  old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"+fi++case $host_os in+  darwin*)+    lock_old_archive_extraction=yes ;;+  *)+    lock_old_archive_extraction=no ;;+esac++++++++++++++++++++++for ac_prog in gawk mawk nawk awk+do+  # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_AWK+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$AWK"; then+  ac_cv_prog_AWK="$AWK" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_AWK="$ac_prog"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+AWK=$ac_cv_prog_AWK+if test -n "$AWK"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5+printf "%s\n" "$AWK" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  test -n "$AWK" && break+done++++++++++++++++++++# If no C compiler was specified, use CC.+LTCC=${LTCC-"$CC"}++# If no C compiler flags were specified, use CFLAGS.+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}++# Allow CC to be a program name with arguments.+compiler=$CC+++# Check for command to grab the raw symbol name followed by C symbol from nm.+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5+printf %s "checking command to parse $NM output from $compiler object... " >&6; }+if test ${lt_cv_sys_global_symbol_pipe+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+# These are sane defaults that work on at least a few old systems.+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]++# Character class describing NM global symbol codes.+symcode='[BCDEGRST]'++# Regexp to match symbols that can be accessed directly from C.+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'++# Define system-specific variables.+case $host_os in+aix*)+  symcode='[BCDT]'+  ;;+cygwin* | mingw* | windows* | pw32* | cegcc*)+  symcode='[ABCDGISTW]'+  ;;+hpux*)+  if test ia64 = "$host_cpu"; then+    symcode='[ABCDEGRST]'+  fi+  ;;+irix* | nonstopux*)+  symcode='[BCDEGRST]'+  ;;+osf*)+  symcode='[BCDEGQRST]'+  ;;+solaris*)+  symcode='[BCDRT]'+  ;;+sco3.2v5*)+  symcode='[DT]'+  ;;+sysv4.2uw2*)+  symcode='[DT]'+  ;;+sysv5* | sco5v6* | unixware* | OpenUNIX*)+  symcode='[ABDT]'+  ;;+sysv4)+  symcode='[DFNSTU]'+  ;;+esac++# If we're using GNU nm, then use its standard symbol codes.+case `$NM -V 2>&1` in+*GNU* | *'with BFD'*)+  symcode='[ABCDGIRSTW]' ;;+esac++if test "$lt_cv_nm_interface" = "MS dumpbin"; then+  # Gets list of data symbols to import.+  lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'"+  # Adjust the below global symbol transforms to fixup imported variables.+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"+  lt_c_name_lib_hook="\+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"+else+  # Disable hooks by default.+  lt_cv_sys_global_symbol_to_import=+  lt_cdecl_hook=+  lt_c_name_hook=+  lt_c_name_lib_hook=+fi++# Transform an extracted symbol line into a proper C declaration.+# Some systems (esp. on ia64) link data and code symbols differently,+# so use this general approach.+lt_cv_sys_global_symbol_to_cdecl="$SED -n"\+$lt_cdecl_hook\+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"++# Transform an extracted symbol line into symbol name and symbol address+lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\+$lt_c_name_hook\+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"++# Transform an extracted symbol line into symbol name with lib prefix and+# symbol address.+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\+$lt_c_name_lib_hook\+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"++# Handle CRLF in mingw tool chain+opt_cr=+case $build_os in+mingw* | windows*)+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp+  ;;+esac++# Try without a prefix underscore, then with it.+for ac_symprfx in "" "_"; do++  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.+  symxfrm="\\1 $ac_symprfx\\2 \\2"++  # Write the raw and C identifiers.+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then+    # Fake it for dumpbin and say T for any non-static function,+    # D for any global variable and I for any imported variable.+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,+    # which start with @ or ?.+    lt_cv_sys_global_symbol_pipe="$AWK '"\+"     {last_section=section; section=\$ 3};"\+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\+"     \$ 0!~/External *\|/{next};"\+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\+"     {if(hide[section]) next};"\+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\+"     ' prfx=^$ac_symprfx"+  else+    lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"+  fi+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'"++  # Check to see that the pipe works correctly.+  pipe_works=no++  rm -f conftest*+  cat > conftest.$ac_ext <<_LT_EOF+#ifdef __cplusplus+extern "C" {+#endif+char nm_test_var;+void nm_test_func(void);+void nm_test_func(void){}+#ifdef __cplusplus+}+#endif+int main(void){nm_test_var='a';nm_test_func();return(0);}+_LT_EOF++  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    # Now try to grab the symbols.+    nlist=conftest.nm+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then+      # Try sorting and uniquifying the output.+      if sort "$nlist" | uniq > "$nlist"T; then+	mv -f "$nlist"T "$nlist"+      else+	rm -f "$nlist"T+      fi++      # Make sure that we snagged all the symbols we need.+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then+	  cat <<_LT_EOF > conftest.$ac_ext+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE+/* DATA imports from DLLs on WIN32 can't be const, because runtime+   relocations are performed -- see ld's documentation on pseudo-relocs.  */+# define LT_DLSYM_CONST+#elif defined __osf__+/* This system does not cope well with relocations in const data.  */+# define LT_DLSYM_CONST+#else+# define LT_DLSYM_CONST const+#endif++#ifdef __cplusplus+extern "C" {+#endif++_LT_EOF+	  # Now generate the symbol file.+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'++	  cat <<_LT_EOF >> conftest.$ac_ext++/* The mapping between symbol names and symbols.  */+LT_DLSYM_CONST struct {+  const char *name;+  void       *address;+}+lt__PROGRAM__LTX_preloaded_symbols[] =+{+  { "@PROGRAM@", (void *) 0 },+_LT_EOF+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext+	  cat <<\_LT_EOF >> conftest.$ac_ext+  {0, (void *) 0}+};++/* This works around a problem in FreeBSD linker */+#ifdef FREEBSD_WORKAROUND+static const void *lt_preloaded_setup() {+  return lt__PROGRAM__LTX_preloaded_symbols;+}+#endif++#ifdef __cplusplus+}+#endif+_LT_EOF+	  # Now try linking the two files.+	  mv conftest.$ac_objext conftstm.$ac_objext+	  lt_globsym_save_LIBS=$LIBS+	  lt_globsym_save_CFLAGS=$CFLAGS+	  LIBS=conftstm.$ac_objext+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5+  (eval $ac_link) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && test -s conftest$ac_exeext; then+	    pipe_works=yes+	  fi+	  LIBS=$lt_globsym_save_LIBS+	  CFLAGS=$lt_globsym_save_CFLAGS+	else+	  echo "cannot find nm_test_func in $nlist" >&5+	fi+      else+	echo "cannot find nm_test_var in $nlist" >&5+      fi+    else+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5+    fi+  else+    echo "$progname: failed program was:" >&5+    cat conftest.$ac_ext >&5+  fi+  rm -rf conftest* conftst*++  # Do not use the global_symbol_pipe unless it works.+  if test yes = "$pipe_works"; then+    break+  else+    lt_cv_sys_global_symbol_pipe=+  fi+done+ ;;+esac+fi++if test -z "$lt_cv_sys_global_symbol_pipe"; then+  lt_cv_sys_global_symbol_to_cdecl=+fi+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5+printf "%s\n" "failed" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5+printf "%s\n" "ok" >&6; }+fi++# Response file support.+if test "$lt_cv_nm_interface" = "MS dumpbin"; then+  nm_file_list_spec='@'+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then+  nm_file_list_spec='@'+fi++++++++++++++++++++++++++++++++++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5+printf %s "checking for sysroot... " >&6; }++# Check whether --with-sysroot was given.+if test ${with_sysroot+y}+then :+  withval=$with_sysroot;+else case e in #(+  e) with_sysroot=no ;;+esac+fi+++lt_sysroot=+case $with_sysroot in #(+ yes)+   if test yes = "$GCC"; then+     # Trim trailing / since we'll always append absolute paths and we want+     # to avoid //, if only for less confusing output for the user.+     lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'`+   fi+   ;; #(+ /*)+   lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"`+   ;; #(+ no|'')+   ;; #(+ *)+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5+printf "%s\n" "$with_sysroot" >&6; }+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5+   ;;+esac++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5+printf "%s\n" "${lt_sysroot:-no}" >&6; }++++++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5+printf %s "checking for a working dd... " >&6; }+if test ${ac_cv_path_lt_DD+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) printf 0123456789abcdef0123456789abcdef >conftest.i+cat conftest.i conftest.i >conftest2.i+: ${lt_DD:=$DD}+if test -z "$lt_DD"; then+  ac_path_lt_DD_found=false+  # Loop through the user's path and test for each of PROGNAME-LIST+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_prog in dd+   do+    for ac_exec_ext in '' $ac_executable_extensions; do+      ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext"+      as_fn_executable_p "$ac_path_lt_DD" || continue+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then+  cmp -s conftest.i conftest.out \+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:+fi+      $ac_path_lt_DD_found && break 3+    done+  done+  done+IFS=$as_save_IFS+  if test -z "$ac_cv_path_lt_DD"; then+    :+  fi+else+  ac_cv_path_lt_DD=$lt_DD+fi++rm -f conftest.i conftest2.i conftest.out ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5+printf "%s\n" "$ac_cv_path_lt_DD" >&6; }+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5+printf %s "checking how to truncate binary pipes... " >&6; }+if test ${lt_cv_truncate_bin+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) printf 0123456789abcdef0123456789abcdef >conftest.i+cat conftest.i conftest.i >conftest2.i+lt_cv_truncate_bin=+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then+  cmp -s conftest.i conftest.out \+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"+fi+rm -f conftest.i conftest2.i conftest.out+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5+printf "%s\n" "$lt_cv_truncate_bin" >&6; }++++++++# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.+func_cc_basename ()+{+    for cc_temp in $*""; do+      case $cc_temp in+        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;+        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;+        \-*) ;;+        *) break;;+      esac+    done+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`+}++# Check whether --enable-libtool-lock was given.+if test ${enable_libtool_lock+y}+then :+  enableval=$enable_libtool_lock;+fi++test no = "$enable_libtool_lock" || enable_libtool_lock=yes++# Some flags need to be propagated to the compiler or linker for good+# libtool support.+case $host in+ia64-*-hpux*)+  # Find out what ABI is being produced by ac_compile, and set mode+  # options accordingly.+  echo 'int i;' > conftest.$ac_ext+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    case `$FILECMD conftest.$ac_objext` in+      *ELF-32*)+	HPUX_IA64_MODE=32+	;;+      *ELF-64*)+	HPUX_IA64_MODE=64+	;;+    esac+  fi+  rm -rf conftest*+  ;;+*-*-irix6*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    if test yes = "$lt_cv_prog_gnu_ld"; then+      case `$FILECMD conftest.$ac_objext` in+	*32-bit*)+	  LD="${LD-ld} -melf32bsmip"+	  ;;+	*N32*)+	  LD="${LD-ld} -melf32bmipn32"+	  ;;+	*64-bit*)+	  LD="${LD-ld} -melf64bmip"+	;;+      esac+    else+      case `$FILECMD conftest.$ac_objext` in+	*32-bit*)+	  LD="${LD-ld} -32"+	  ;;+	*N32*)+	  LD="${LD-ld} -n32"+	  ;;+	*64-bit*)+	  LD="${LD-ld} -64"+	  ;;+      esac+    fi+  fi+  rm -rf conftest*+  ;;++mips64*-*linux*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    emul=elf+    case `$FILECMD conftest.$ac_objext` in+      *32-bit*)+	emul="${emul}32"+	;;+      *64-bit*)+	emul="${emul}64"+	;;+    esac+    case `$FILECMD conftest.$ac_objext` in+      *MSB*)+	emul="${emul}btsmip"+	;;+      *LSB*)+	emul="${emul}ltsmip"+	;;+    esac+    case `$FILECMD conftest.$ac_objext` in+      *N32*)+	emul="${emul}n32"+	;;+    esac+    LD="${LD-ld} -m $emul"+  fi+  rm -rf conftest*+  ;;++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \+s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.  Note that the listed cases only cover the+  # situations where additional linker options are needed (such as when+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or+  # vice versa); the common cases where no linker options are needed do+  # not appear in the list.+  echo 'int i;' > conftest.$ac_ext+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    case `$FILECMD conftest.o` in+      *32-bit*)+	case $host in+	  x86_64-*kfreebsd*-gnu)+	    LD="${LD-ld} -m elf_i386_fbsd"+	    ;;+	  x86_64-*linux*|x86_64-gnu*)+	    case `$FILECMD conftest.o` in+	      *x86-64*)+		LD="${LD-ld} -m elf32_x86_64"+		;;+	      *)+		LD="${LD-ld} -m elf_i386"+		;;+	    esac+	    ;;+	  powerpc64le-*linux*)+	    LD="${LD-ld} -m elf32lppclinux"+	    ;;+	  powerpc64-*linux*)+	    LD="${LD-ld} -m elf32ppclinux"+	    ;;+	  s390x-*linux*)+	    LD="${LD-ld} -m elf_s390"+	    ;;+	  sparc64-*linux*)+	    LD="${LD-ld} -m elf32_sparc"+	    ;;+	esac+	;;+      *64-bit*)+	case $host in+	  x86_64-*kfreebsd*-gnu)+	    LD="${LD-ld} -m elf_x86_64_fbsd"+	    ;;+	  x86_64-*linux*|x86_64-gnu*)+	    LD="${LD-ld} -m elf_x86_64"+	    ;;+	  powerpcle-*linux*)+	    LD="${LD-ld} -m elf64lppc"+	    ;;+	  powerpc-*linux*)+	    LD="${LD-ld} -m elf64ppc"+	    ;;+	  s390*-*linux*|s390*-*tpf*)+	    LD="${LD-ld} -m elf64_s390"+	    ;;+	  sparc*-*linux*)+	    LD="${LD-ld} -m elf64_sparc"+	    ;;+	esac+	;;+    esac+  fi+  rm -rf conftest*+  ;;++*-*-sco3.2v5*)+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.+  SAVE_CFLAGS=$CFLAGS+  CFLAGS="$CFLAGS -belf"+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5+printf %s "checking whether the C compiler needs -belf... " >&6; }+if test ${lt_cv_cc_needs_belf+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++     cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  lt_cv_cc_needs_belf=yes+else case e in #(+  e) lt_cv_cc_needs_belf=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+     ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5+printf "%s\n" "$lt_cv_cc_needs_belf" >&6; }+  if test yes != "$lt_cv_cc_needs_belf"; then+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf+    CFLAGS=$SAVE_CFLAGS+  fi+  ;;+*-*solaris*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.+  echo 'int i;' > conftest.$ac_ext+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    case `$FILECMD conftest.o` in+    *64-bit*)+      case $lt_cv_prog_gnu_ld in+      yes*)+        case $host in+        i?86-*-solaris*|x86_64-*-solaris*)+          LD="${LD-ld} -m elf_x86_64"+          ;;+        sparc*-*-solaris*)+          LD="${LD-ld} -m elf64_sparc"+          ;;+        esac+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then+          LD=${LD-ld}_sol2+        fi+        ;;+      *)+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then+	  LD="${LD-ld} -64"+	fi+	;;+      esac+      ;;+    esac+  fi+  rm -rf conftest*+  ;;+esac++need_locks=$enable_libtool_lock++if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.+set dummy ${ac_tool_prefix}mt; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_MANIFEST_TOOL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$MANIFEST_TOOL"; then+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL+if test -n "$MANIFEST_TOOL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5+printf "%s\n" "$MANIFEST_TOOL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL+  # Extract the first word of "mt", so it can be a program name with args.+set dummy mt; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_MANIFEST_TOOL"; then+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL+if test -n "$ac_ct_MANIFEST_TOOL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5+printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_MANIFEST_TOOL" = x; then+    MANIFEST_TOOL=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL+  fi+else+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"+fi++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5+printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }+if test ${lt_cv_path_manifest_tool+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_path_manifest_tool=no+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out+  cat conftest.err >&5+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then+    lt_cv_path_manifest_tool=yes+  fi+  rm -f conftest* ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_manifest_tool" >&5+printf "%s\n" "$lt_cv_path_manifest_tool" >&6; }+if test yes != "$lt_cv_path_manifest_tool"; then+  MANIFEST_TOOL=:+fi+++++++  case $host_os in+    rhapsody* | darwin*)+    if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_DSYMUTIL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$DSYMUTIL"; then+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+DSYMUTIL=$ac_cv_prog_DSYMUTIL+if test -n "$DSYMUTIL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5+printf "%s\n" "$DSYMUTIL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_DSYMUTIL"; then+  ac_ct_DSYMUTIL=$DSYMUTIL+  # Extract the first word of "dsymutil", so it can be a program name with args.+set dummy dsymutil; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_DSYMUTIL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_DSYMUTIL"; then+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL+if test -n "$ac_ct_DSYMUTIL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5+printf "%s\n" "$ac_ct_DSYMUTIL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_DSYMUTIL" = x; then+    DSYMUTIL=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    DSYMUTIL=$ac_ct_DSYMUTIL+  fi+else+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"+fi++    if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.+set dummy ${ac_tool_prefix}nmedit; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_NMEDIT+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$NMEDIT"; then+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+NMEDIT=$ac_cv_prog_NMEDIT+if test -n "$NMEDIT"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5+printf "%s\n" "$NMEDIT" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_NMEDIT"; then+  ac_ct_NMEDIT=$NMEDIT+  # Extract the first word of "nmedit", so it can be a program name with args.+set dummy nmedit; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_NMEDIT+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_NMEDIT"; then+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_NMEDIT="nmedit"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT+if test -n "$ac_ct_NMEDIT"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5+printf "%s\n" "$ac_ct_NMEDIT" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_NMEDIT" = x; then+    NMEDIT=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    NMEDIT=$ac_ct_NMEDIT+  fi+else+  NMEDIT="$ac_cv_prog_NMEDIT"+fi++    if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.+set dummy ${ac_tool_prefix}lipo; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_LIPO+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$LIPO"; then+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+LIPO=$ac_cv_prog_LIPO+if test -n "$LIPO"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5+printf "%s\n" "$LIPO" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_LIPO"; then+  ac_ct_LIPO=$LIPO+  # Extract the first word of "lipo", so it can be a program name with args.+set dummy lipo; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_LIPO+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_LIPO"; then+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_LIPO="lipo"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO+if test -n "$ac_ct_LIPO"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5+printf "%s\n" "$ac_ct_LIPO" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_LIPO" = x; then+    LIPO=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    LIPO=$ac_ct_LIPO+  fi+else+  LIPO="$ac_cv_prog_LIPO"+fi++    if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.+set dummy ${ac_tool_prefix}otool; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_OTOOL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$OTOOL"; then+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+OTOOL=$ac_cv_prog_OTOOL+if test -n "$OTOOL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5+printf "%s\n" "$OTOOL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_OTOOL"; then+  ac_ct_OTOOL=$OTOOL+  # Extract the first word of "otool", so it can be a program name with args.+set dummy otool; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_OTOOL+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_OTOOL"; then+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_OTOOL="otool"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL+if test -n "$ac_ct_OTOOL"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5+printf "%s\n" "$ac_ct_OTOOL" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_OTOOL" = x; then+    OTOOL=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    OTOOL=$ac_ct_OTOOL+  fi+else+  OTOOL="$ac_cv_prog_OTOOL"+fi++    if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.+set dummy ${ac_tool_prefix}otool64; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_OTOOL64+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$OTOOL64"; then+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+OTOOL64=$ac_cv_prog_OTOOL64+if test -n "$OTOOL64"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5+printf "%s\n" "$OTOOL64" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_OTOOL64"; then+  ac_ct_OTOOL64=$OTOOL64+  # Extract the first word of "otool64", so it can be a program name with args.+set dummy otool64; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_prog_ac_ct_OTOOL64+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -n "$ac_ct_OTOOL64"; then+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_OTOOL64="otool64"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi ;;+esac+fi+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64+if test -n "$ac_ct_OTOOL64"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5+printf "%s\n" "$ac_ct_OTOOL64" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++  if test "x$ac_ct_OTOOL64" = x; then+    OTOOL64=":"+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    OTOOL64=$ac_ct_OTOOL64+  fi+else+  OTOOL64="$ac_cv_prog_OTOOL64"+fi++++++++++++++++++++++++++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5+printf %s "checking for -single_module linker flag... " >&6; }+if test ${lt_cv_apple_cc_single_mod+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_apple_cc_single_mod=no+      if test -z "$LT_MULTI_MODULE"; then+	# By default we will add the -single_module flag. You can override+	# by either setting the environment variable LT_MULTI_MODULE+	# non-empty at configure time, or by adding -multi_module to the+	# link flags.+	rm -rf libconftest.dylib*+	echo "int foo(void){return 1;}" > conftest.c+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \+-dynamiclib -Wl,-single_module conftest.c" >&5+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err+        _lt_result=$?+	# If there is a non-empty error log, and "single_module"+	# appears in it, assume the flag caused a linker warning+        if test -s conftest.err && $GREP single_module conftest.err; then+	  cat conftest.err >&5+	# Otherwise, if the output was created with a 0 exit code from+	# the compiler, it worked.+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then+	  lt_cv_apple_cc_single_mod=yes+	else+	  cat conftest.err >&5+	fi+	rm -rf libconftest.dylib*+	rm -f conftest.*+      fi ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5+printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; }++    # Feature test to disable chained fixups since it is not+    # compatible with '-undefined dynamic_lookup'+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -no_fixup_chains linker flag" >&5+printf %s "checking for -no_fixup_chains linker flag... " >&6; }+if test ${lt_cv_support_no_fixup_chains+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)  save_LDFLAGS=$LDFLAGS+        LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains"+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  lt_cv_support_no_fixup_chains=yes+else case e in #(+  e) lt_cv_support_no_fixup_chains=no+         ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+        LDFLAGS=$save_LDFLAGS++     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_support_no_fixup_chains" >&5+printf "%s\n" "$lt_cv_support_no_fixup_chains" >&6; }++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5+printf %s "checking for -exported_symbols_list linker flag... " >&6; }+if test ${lt_cv_ld_exported_symbols_list+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_ld_exported_symbols_list=no+      save_LDFLAGS=$LDFLAGS+      echo "_main" > conftest.sym+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  lt_cv_ld_exported_symbols_list=yes+else case e in #(+  e) lt_cv_ld_exported_symbols_list=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+	LDFLAGS=$save_LDFLAGS+     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5+printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; }++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5+printf %s "checking for -force_load linker flag... " >&6; }+if test ${lt_cv_ld_force_load+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_ld_force_load=no+      cat > conftest.c << _LT_EOF+int forced_loaded() { return 2;}+_LT_EOF+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5+      $AR $AR_FLAGS libconftest.a conftest.o 2>&5+      echo "$RANLIB libconftest.a" >&5+      $RANLIB libconftest.a 2>&5+      cat > conftest.c << _LT_EOF+int main(void) { return 0;}+_LT_EOF+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err+      _lt_result=$?+      if test -s conftest.err && $GREP force_load conftest.err; then+	cat conftest.err >&5+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then+	lt_cv_ld_force_load=yes+      else+	cat conftest.err >&5+      fi+        rm -f conftest.err libconftest.a conftest conftest.c+        rm -rf conftest.dSYM+     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5+printf "%s\n" "$lt_cv_ld_force_load" >&6; }+    case $host_os in+    rhapsody* | darwin1.[012])+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;+    darwin1.*)+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;+    darwin*)+      case $MACOSX_DEPLOYMENT_TARGET,$host in+        10.[012],*|,*powerpc*-darwin[5-8]*)+          _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;+        *)+          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup'+          if test yes = "$lt_cv_support_no_fixup_chains"; then+            as_fn_append _lt_dar_allow_undefined ' $wl-no_fixup_chains'+          fi+        ;;+      esac+    ;;+  esac+    if test yes = "$lt_cv_apple_cc_single_mod"; then+      _lt_dar_single_mod='$single_module'+    fi+    _lt_dar_needs_single_mod=no+    case $host_os in+    rhapsody* | darwin1.*)+      _lt_dar_needs_single_mod=yes ;;+    darwin*)+      # When targeting Mac OS X 10.4 (darwin 8) or later,+      # -single_module is the default and -multi_module is unsupported.+      # The toolchain on macOS 10.14 (darwin 18) and later cannot+      # target any OS version that needs -single_module.+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in+      10.0,*-darwin[567].*|10.[0-3],*-darwin[5-9].*|10.[0-3],*-darwin1[0-7].*)+        _lt_dar_needs_single_mod=yes ;;+      esac+    ;;+    esac+    if test yes = "$lt_cv_ld_exported_symbols_list"; then+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'+    else+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'+    fi+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then+      _lt_dsymutil='~$DSYMUTIL $lib || :'+    else+      _lt_dsymutil=+    fi+    ;;+  esac++# func_munge_path_list VARIABLE PATH+# -----------------------------------+# VARIABLE is name of variable containing _space_ separated list of+# directories to be munged by the contents of PATH, which is string+# having a format:+# "DIR[:DIR]:"+#       string "DIR[ DIR]" will be prepended to VARIABLE+# ":DIR[:DIR]"+#       string "DIR[ DIR]" will be appended to VARIABLE+# "DIRP[:DIRP]::[DIRA:]DIRA"+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string+#       "DIRA[ DIRA]" will be appended to VARIABLE+# "DIR[:DIR]"+#       VARIABLE will be replaced by "DIR[ DIR]"+func_munge_path_list ()+{+    case x$2 in+    x)+        ;;+    *:)+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"+        ;;+    x:*)+        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"+        ;;+    *::*)+        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"+        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"+        ;;+    *)+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"+        ;;+    esac+}++ac_header= ac_cache=+for ac_item in $ac_header_c_list+do+  if test $ac_cache; then+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then+      printf "%s\n" "#define $ac_item 1" >> confdefs.h+    fi+    ac_header= ac_cache=+  elif test $ac_header; then+    ac_cache=$ac_item+  else+    ac_header=$ac_item+  fi+done+++++++++if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes+then :++printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h++fi+ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default+"+if test "x$ac_cv_header_dlfcn_h" = xyes+then :+  printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h++fi+++++func_stripname_cnf ()+{+  case $2 in+  .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;;+  *)  func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;;+  esac+} # func_stripname_cnf++++++# Set options++++        enable_dlopen=no+++  enable_win32_dll=no+++            # Check whether --enable-shared was given.+if test ${enable_shared+y}+then :+  enableval=$enable_shared; p=${PACKAGE-default}+    case $enableval in+    yes) enable_shared=yes ;;+    no) enable_shared=no ;;+    *)+      enable_shared=no+      # Look at the argument we got.  We use all the common list separators.+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+      for pkg in $enableval; do+	IFS=$lt_save_ifs+	if test "X$pkg" = "X$p"; then+	  enable_shared=yes+	fi+      done+      IFS=$lt_save_ifs+      ;;+    esac+else case e in #(+  e) enable_shared=yes ;;+esac+fi++++++++++  # Check whether --enable-static was given.+if test ${enable_static+y}+then :+  enableval=$enable_static; p=${PACKAGE-default}+    case $enableval in+    yes) enable_static=yes ;;+    no) enable_static=no ;;+    *)+     enable_static=no+      # Look at the argument we got.  We use all the common list separators.+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+      for pkg in $enableval; do+	IFS=$lt_save_ifs+	if test "X$pkg" = "X$p"; then+	  enable_static=yes+	fi+      done+      IFS=$lt_save_ifs+      ;;+    esac+else case e in #(+  e) enable_static=yes ;;+esac+fi++++++++++  # Check whether --enable-pic was given.+if test ${enable_pic+y}+then :+  enableval=$enable_pic; lt_p=${PACKAGE-default}+     case $enableval in+     yes|no) pic_mode=$enableval ;;+     *)+       pic_mode=default+       # Look at the argument we got.  We use all the common list separators.+       lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+       for lt_pkg in $enableval; do+	 IFS=$lt_save_ifs+	 if test "X$lt_pkg" = "X$lt_p"; then+	   pic_mode=yes+	 fi+       done+       IFS=$lt_save_ifs+       ;;+     esac+else case e in #(+  e)           # Check whether --with-pic was given.+if test ${with_pic+y}+then :+  withval=$with_pic; lt_p=${PACKAGE-default}+	 case $withval in+	 yes|no) pic_mode=$withval ;;+	 *)+	   pic_mode=default+	   # Look at the argument we got.  We use all the common list separators.+	   lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+	   for lt_pkg in $withval; do+	     IFS=$lt_save_ifs+	     if test "X$lt_pkg" = "X$lt_p"; then+	       pic_mode=yes+	     fi+	   done+	   IFS=$lt_save_ifs+	   ;;+	 esac+else case e in #(+  e) pic_mode=default ;;+esac+fi++     ;;+esac+fi+++++++++  # Check whether --enable-fast-install was given.+if test ${enable_fast_install+y}+then :+  enableval=$enable_fast_install; p=${PACKAGE-default}+    case $enableval in+    yes) enable_fast_install=yes ;;+    no) enable_fast_install=no ;;+    *)+      enable_fast_install=no+      # Look at the argument we got.  We use all the common list separators.+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+      for pkg in $enableval; do+	IFS=$lt_save_ifs+	if test "X$pkg" = "X$p"; then+	  enable_fast_install=yes+	fi+      done+      IFS=$lt_save_ifs+      ;;+    esac+else case e in #(+  e) enable_fast_install=yes ;;+esac+fi+++++++++  shared_archive_member_spec=+case $host,$enable_shared in+power*-*-aix[5-9]*,yes)+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5+printf %s "checking which variant of shared library versioning to provide... " >&6; }+  # Check whether --enable-aix-soname was given.+if test ${enable_aix_soname+y}+then :+  enableval=$enable_aix_soname; case $enableval in+     aix|svr4|both)+       ;;+     *)+       as_fn_error $? "Unknown argument to --enable-aix-soname" "$LINENO" 5+       ;;+     esac+     lt_cv_with_aix_soname=$enable_aix_soname+else case e in #(+  e) # Check whether --with-aix-soname was given.+if test ${with_aix_soname+y}+then :+  withval=$with_aix_soname; case $withval in+         aix|svr4|both)+           ;;+         *)+           as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5+           ;;+         esac+         lt_cv_with_aix_soname=$with_aix_soname+else case e in #(+  e) if test ${lt_cv_with_aix_soname+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_with_aix_soname=aix ;;+esac+fi+ ;;+esac+fi++     enable_aix_soname=$lt_cv_with_aix_soname ;;+esac+fi++  with_aix_soname=$enable_aix_soname+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5+printf "%s\n" "$with_aix_soname" >&6; }+  if test aix != "$with_aix_soname"; then+    # For the AIX way of multilib, we name the shared archive member+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,+    # the AIX toolchain works better with OBJECT_MODE set (default 32).+    if test 64 = "${OBJECT_MODE-32}"; then+      shared_archive_member_spec=shr_64+    else+      shared_archive_member_spec=shr+    fi+  fi+  ;;+*)+  with_aix_soname=aix+  ;;+esac+++++++++++# This can be used to rebuild libtool when needed+LIBTOOL_DEPS=$ltmain++# Always use our own libtool.+LIBTOOL='$(SHELL) $(top_builddir)/libtool'+++++++++++++++++++++++++++++++test -z "$LN_S" && LN_S="ln -s"+++++++++++++++if test -n "${ZSH_VERSION+set}"; then+   setopt NO_GLOB_SUBST+fi++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5+printf %s "checking for objdir... " >&6; }+if test ${lt_cv_objdir+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) rm -f .libs 2>/dev/null+mkdir .libs 2>/dev/null+if test -d .libs; then+  lt_cv_objdir=.libs+else+  # MS-DOS does not allow filenames that begin with a dot.+  lt_cv_objdir=_libs+fi+rmdir .libs 2>/dev/null ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5+printf "%s\n" "$lt_cv_objdir" >&6; }+objdir=$lt_cv_objdir++++++printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h+++++case $host_os in+aix3*)+  # AIX sometimes has problems with the GCC collect2 program.  For some+  # reason, if we set the COLLECT_NAMES environment variable, the problems+  # vanish in a puff of smoke.+  if test set != "${COLLECT_NAMES+set}"; then+    COLLECT_NAMES=+    export COLLECT_NAMES+  fi+  ;;+esac++# Global variables:+ofile=libtool+can_build_shared=yes++# All known linkers require a '.a' archive for static linking (except MSVC and+# ICC, which need '.lib').+libext=a++with_gnu_ld=$lt_cv_prog_gnu_ld++old_CC=$CC+old_CFLAGS=$CFLAGS++# Set sane defaults for various variables+test -z "$CC" && CC=cc+test -z "$LTCC" && LTCC=$CC+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS+test -z "$LD" && LD=ld+test -z "$ac_objext" && ac_objext=o++func_cc_basename $compiler+cc_basename=$func_cc_basename_result+++# Only perform the check for file, if the check method requires it+test -z "$MAGIC_CMD" && MAGIC_CMD=file+case $deplibs_check_method in+file_magic*)+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5+printf %s "checking for ${ac_tool_prefix}file... " >&6; }+if test ${lt_cv_path_MAGIC_CMD+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) case $MAGIC_CMD in+[\\/*] |  ?:[\\/]*)+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.+  ;;+*)+  lt_save_MAGIC_CMD=$MAGIC_CMD+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"+  for ac_dir in $ac_dummy; do+    IFS=$lt_save_ifs+    test -z "$ac_dir" && ac_dir=.+    if test -f "$ac_dir/${ac_tool_prefix}file"; then+      lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"+      if test -n "$file_magic_test_file"; then+	case $deplibs_check_method in+	"file_magic "*)+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |+	    $EGREP "$file_magic_regex" > /dev/null; then+	    :+	  else+	    cat <<_LT_EOF 1>&2++*** Warning: the command libtool uses to detect shared libraries,+*** $file_magic_cmd, produces output that libtool cannot recognize.+*** The result is that libtool may fail to recognize shared libraries+*** as such.  This will affect the creation of libtool libraries that+*** depend on shared libraries, but programs linked with such libtool+*** libraries will work regardless of this problem.  Nevertheless, you+*** may want to report the problem to your system manager and/or to+*** bug-libtool@gnu.org++_LT_EOF+	  fi ;;+	esac+      fi+      break+    fi+  done+  IFS=$lt_save_ifs+  MAGIC_CMD=$lt_save_MAGIC_CMD+  ;;+esac ;;+esac+fi++MAGIC_CMD=$lt_cv_path_MAGIC_CMD+if test -n "$MAGIC_CMD"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5+printf "%s\n" "$MAGIC_CMD" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi++++++if test -z "$lt_cv_path_MAGIC_CMD"; then+  if test -n "$ac_tool_prefix"; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5+printf %s "checking for file... " >&6; }+if test ${lt_cv_path_MAGIC_CMD+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) case $MAGIC_CMD in+[\\/*] |  ?:[\\/]*)+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.+  ;;+*)+  lt_save_MAGIC_CMD=$MAGIC_CMD+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"+  for ac_dir in $ac_dummy; do+    IFS=$lt_save_ifs+    test -z "$ac_dir" && ac_dir=.+    if test -f "$ac_dir/file"; then+      lt_cv_path_MAGIC_CMD=$ac_dir/"file"+      if test -n "$file_magic_test_file"; then+	case $deplibs_check_method in+	"file_magic "*)+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |+	    $EGREP "$file_magic_regex" > /dev/null; then+	    :+	  else+	    cat <<_LT_EOF 1>&2++*** Warning: the command libtool uses to detect shared libraries,+*** $file_magic_cmd, produces output that libtool cannot recognize.+*** The result is that libtool may fail to recognize shared libraries+*** as such.  This will affect the creation of libtool libraries that+*** depend on shared libraries, but programs linked with such libtool+*** libraries will work regardless of this problem.  Nevertheless, you+*** may want to report the problem to your system manager and/or to+*** bug-libtool@gnu.org++_LT_EOF+	  fi ;;+	esac+      fi+      break+    fi+  done+  IFS=$lt_save_ifs+  MAGIC_CMD=$lt_save_MAGIC_CMD+  ;;+esac ;;+esac+fi++MAGIC_CMD=$lt_cv_path_MAGIC_CMD+if test -n "$MAGIC_CMD"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5+printf "%s\n" "$MAGIC_CMD" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++  else+    MAGIC_CMD=:+  fi+fi++  fi+  ;;+esac++# Use C for the default configuration in the libtool script++lt_save_CC=$CC+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++# Source file extension for C test sources.+ac_ext=c++# Object file extension for compiled C test sources.+objext=o+objext=$objext++# Code to be used in simple compile tests+lt_simple_compile_test_code="int some_variable = 0;"++# Code to be used in simple link tests+lt_simple_link_test_code='int main(void){return(0);}'++++++++# If no C compiler was specified, use CC.+LTCC=${LTCC-"$CC"}++# If no C compiler flags were specified, use CFLAGS.+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}++# Allow CC to be a program name with arguments.+compiler=$CC++# Save the default compiler, since it gets overwritten when the other+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.+compiler_DEFAULT=$CC++# save warnings/boilerplate of simple test code+ac_outfile=conftest.$ac_objext+echo "$lt_simple_compile_test_code" >conftest.$ac_ext+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err+_lt_compiler_boilerplate=`cat conftest.err`+$RM conftest*++ac_outfile=conftest.$ac_objext+echo "$lt_simple_link_test_code" >conftest.$ac_ext+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err+_lt_linker_boilerplate=`cat conftest.err`+$RM -r conftest*+++## CAVEAT EMPTOR:+## There is no encapsulation within the following macros, do not change+## the running order or otherwise move them around unless you know exactly+## what you are doing...+if test -n "$compiler"; then++lt_prog_compiler_no_builtin_flag=++if test yes = "$GCC"; then+  case $cc_basename in+  nvcc*)+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;+  *)+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;+  esac++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5+printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }+if test ${lt_cv_prog_compiler_rtti_exceptions+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_rtti_exceptions=no+   ac_outfile=conftest.$ac_objext+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext+   lt_compiler_flag="-fno-rtti -fno-exceptions"  ## exclude from sc_useless_quotes_in_assignment+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   # The option is referenced via a variable to avoid confusing sed.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>conftest.err)+   ac_status=$?+   cat conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s "$ac_outfile"; then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings other than the usual output.+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_rtti_exceptions=yes+     fi+   fi+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5+printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; }++if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"+else+    :+fi++fi+++++++  lt_prog_compiler_wl=+lt_prog_compiler_pic=+lt_prog_compiler_static=+++  if test yes = "$GCC"; then+    lt_prog_compiler_wl='-Wl,'+    lt_prog_compiler_static='-static'++    case $host_os in+      aix*)+      # All AIX code is PIC.+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	lt_prog_compiler_static='-Bstatic'+      fi+      lt_prog_compiler_pic='-fPIC'+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            lt_prog_compiler_pic='-fPIC'+        ;;+      m68k)+            # FIXME: we need at least 68020 code to build shared libraries, but+            # adding the '-m68020' flag to GCC prevents building anything better,+            # like '-m68040'.+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'+        ;;+      esac+      ;;++    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)+      # PIC is the default for these OSes.+      ;;++    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      # Although the cygwin gcc ignores -fPIC, still need this for old-style+      # (--disable-auto-import) libraries+      lt_prog_compiler_pic='-DDLL_EXPORT'+      case $host_os in+      os2*)+	lt_prog_compiler_static='$wl-static'+	;;+      esac+      ;;++    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      lt_prog_compiler_pic='-fno-common'+      ;;++    haiku*)+      # PIC is the default for Haiku.+      # The "-static" flag exists, but is broken.+      lt_prog_compiler_static=+      ;;++    hpux*)+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag+      # sets the default TLS model and affects inlining.+      case $host_cpu in+      hppa*64*)+	# +Z the default+	;;+      *)+	lt_prog_compiler_pic='-fPIC'+	;;+      esac+      ;;++    interix[3-9]*)+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.+      # Instead, we relocate shared libraries at runtime.+      ;;++    msdosdjgpp*)+      # Just because we use GCC doesn't mean we suddenly get shared libraries+      # on systems that don't support them.+      lt_prog_compiler_can_build_shared=no+      enable_shared=no+      ;;++    *nto* | *qnx*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      lt_prog_compiler_pic='-fPIC -shared'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	lt_prog_compiler_pic=-Kconform_pic+      fi+      ;;++    *)+      lt_prog_compiler_pic='-fPIC'+      ;;+    esac++    case $cc_basename in+    nvcc*) # Cuda Compiler Driver 2.2+      lt_prog_compiler_wl='-Xlinker '+      if test -n "$lt_prog_compiler_pic"; then+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"+      fi+      ;;+    esac+  else+    # PORTME Check for flag to pass linker flags through the system compiler.+    case $host_os in+    aix*)+      lt_prog_compiler_wl='-Wl,'+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	lt_prog_compiler_static='-Bstatic'+      else+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'+      fi+      ;;++    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      lt_prog_compiler_pic='-fno-common'+      case $cc_basename in+      nagfor*)+        # NAG Fortran compiler+        lt_prog_compiler_wl='-Wl,-Wl,,'+        lt_prog_compiler_pic='-PIC'+        lt_prog_compiler_static='-Bstatic'+        ;;+      esac+      ;;++    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      lt_prog_compiler_pic='-DDLL_EXPORT'+      case $host_os in+      os2*)+	lt_prog_compiler_static='$wl-static'+	;;+      esac+      ;;++    hpux9* | hpux10* | hpux11*)+      lt_prog_compiler_wl='-Wl,'+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but+      # not for PA HP-UX.+      case $host_cpu in+      hppa*64*|ia64*)+	# +Z the default+	;;+      *)+	lt_prog_compiler_pic='+Z'+	;;+      esac+      # Is there a better lt_prog_compiler_static that works with the bundled CC?+      lt_prog_compiler_static='$wl-a ${wl}archive'+      ;;++    irix5* | irix6* | nonstopux*)+      lt_prog_compiler_wl='-Wl,'+      # PIC (with -KPIC) is the default.+      lt_prog_compiler_static='-non_shared'+      ;;++    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+      case $cc_basename in+      # old Intel for x86_64, which still supported -KPIC.+      ecc*)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-KPIC'+	lt_prog_compiler_static='-static'+        ;;+      *flang* | ftn | f18* | f95*)+        # Flang compiler.+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fPIC'+	lt_prog_compiler_static='-static'+        ;;+      # icc used to be incompatible with GCC.+      # ICC 10 doesn't accept -KPIC any more.+      icc* | ifort*)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fPIC'+	lt_prog_compiler_static='-static'+        ;;+      # Lahey Fortran 8.1.+      lf95*)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='--shared'+	lt_prog_compiler_static='--static'+	;;+      nagfor*)+	# NAG Fortran compiler+	lt_prog_compiler_wl='-Wl,-Wl,,'+	lt_prog_compiler_pic='-PIC'+	lt_prog_compiler_static='-Bstatic'+	;;+      tcc*)+	# Fabrice Bellard et al's Tiny C Compiler+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fPIC'+	lt_prog_compiler_static='-static'+	;;+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)+        # Portland Group compilers (*not* the Pentium gcc compiler,+	# which looks to be a dead project)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fpic'+	lt_prog_compiler_static='-Bstatic'+        ;;+      ccc*)+        lt_prog_compiler_wl='-Wl,'+        # All Alpha code is PIC.+        lt_prog_compiler_static='-non_shared'+        ;;+      xl* | bgxl* | bgf* | mpixl*)+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-qpic'+	lt_prog_compiler_static='-qstaticlink'+	;;+      *)+	case `$CC -V 2>&1 | $SED 5q` in+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker+	  lt_prog_compiler_pic='-KPIC'+	  lt_prog_compiler_static='-Bstatic'+	  lt_prog_compiler_wl=''+	  ;;+	*Sun\ F* | *Sun*Fortran*)+	  lt_prog_compiler_pic='-KPIC'+	  lt_prog_compiler_static='-Bstatic'+	  lt_prog_compiler_wl='-Qoption ld '+	  ;;+	*Sun\ C*)+	  # Sun C 5.9+	  lt_prog_compiler_pic='-KPIC'+	  lt_prog_compiler_static='-Bstatic'+	  lt_prog_compiler_wl='-Wl,'+	  ;;+        *Intel*\ [CF]*Compiler*)+	  lt_prog_compiler_wl='-Wl,'+	  lt_prog_compiler_pic='-fPIC'+	  lt_prog_compiler_static='-static'+	  ;;+	*Portland\ Group*)+	  lt_prog_compiler_wl='-Wl,'+	  lt_prog_compiler_pic='-fpic'+	  lt_prog_compiler_static='-Bstatic'+	  ;;+	esac+	;;+      esac+      ;;++    newsos6)+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    *-mlibc)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_pic='-fPIC'+      lt_prog_compiler_static='-static'+      ;;++    *nto* | *qnx*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      lt_prog_compiler_pic='-fPIC -shared'+      ;;++    osf3* | osf4* | osf5*)+      lt_prog_compiler_wl='-Wl,'+      # All OSF/1 code is PIC.+      lt_prog_compiler_static='-non_shared'+      ;;++    rdos*)+      lt_prog_compiler_static='-non_shared'+      ;;++    serenity*)+      ;;++    solaris*)+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      case $cc_basename in+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)+	lt_prog_compiler_wl='-Qoption ld ';;+      *)+	lt_prog_compiler_wl='-Wl,';;+      esac+      ;;++    sunos4*)+      lt_prog_compiler_wl='-Qoption ld '+      lt_prog_compiler_pic='-PIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    sysv4 | sysv4.2uw2* | sysv4.3*)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	lt_prog_compiler_pic='-Kconform_pic'+	lt_prog_compiler_static='-Bstatic'+      fi+      ;;++    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    unicos*)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_can_build_shared=no+      ;;++    uts4*)+      lt_prog_compiler_pic='-pic'+      lt_prog_compiler_static='-Bstatic'+      ;;++    *)+      lt_prog_compiler_can_build_shared=no+      ;;+    esac+  fi++case $host_os in+  # For platforms that do not support PIC, -DPIC is meaningless:+  *djgpp*)+    lt_prog_compiler_pic=+    ;;+  *)+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"+    ;;+esac++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5+printf %s "checking for $compiler option to produce PIC... " >&6; }+if test ${lt_cv_prog_compiler_pic+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic=$lt_prog_compiler_pic ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; }+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic++#+# Check to make sure the PIC flag actually works.+#+if test -n "$lt_prog_compiler_pic"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5+printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }+if test ${lt_cv_prog_compiler_pic_works+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic_works=no+   ac_outfile=conftest.$ac_objext+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   # The option is referenced via a variable to avoid confusing sed.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>conftest.err)+   ac_status=$?+   cat conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s "$ac_outfile"; then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings other than the usual output.+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_pic_works=yes+     fi+   fi+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; }++if test yes = "$lt_cv_prog_compiler_pic_works"; then+    case $lt_prog_compiler_pic in+     "" | " "*) ;;+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;+     esac+else+    lt_prog_compiler_pic=+     lt_prog_compiler_can_build_shared=no+fi++fi++++++++++++#+# Check to make sure the static flag actually works.+#+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5+printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }+if test ${lt_cv_prog_compiler_static_works+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_static_works=no+   save_LDFLAGS=$LDFLAGS+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"+   echo "$lt_simple_link_test_code" > conftest.$ac_ext+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then+     # The linker can only warn and ignore the option if not recognized+     # So say no if there are warnings+     if test -s conftest.err; then+       # Append any errors to the config.log.+       cat conftest.err 1>&5+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+       if diff conftest.exp conftest.er2 >/dev/null; then+         lt_cv_prog_compiler_static_works=yes+       fi+     else+       lt_cv_prog_compiler_static_works=yes+     fi+   fi+   $RM -r conftest*+   LDFLAGS=$save_LDFLAGS+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5+printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; }++if test yes = "$lt_cv_prog_compiler_static_works"; then+    :+else+    lt_prog_compiler_static=+fi++++++++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }+if test ${lt_cv_prog_compiler_c_o+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_c_o=no+   $RM -r conftest 2>/dev/null+   mkdir conftest+   cd conftest+   mkdir out+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext++   lt_compiler_flag="-o out/conftest2.$ac_objext"+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>out/conftest.err)+   ac_status=$?+   cat out/conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s out/conftest2.$ac_objext+   then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_c_o=yes+     fi+   fi+   chmod u+w . 2>&5+   $RM conftest*+   # SGI C++ compiler will create directory out/ii_files/ for+   # template instantiation+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files+   $RM out/* && rmdir out+   cd ..+   $RM -r conftest+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5+printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; }+++++++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }+if test ${lt_cv_prog_compiler_c_o+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_c_o=no+   $RM -r conftest 2>/dev/null+   mkdir conftest+   cd conftest+   mkdir out+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext++   lt_compiler_flag="-o out/conftest2.$ac_objext"+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>out/conftest.err)+   ac_status=$?+   cat out/conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s out/conftest2.$ac_objext+   then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_c_o=yes+     fi+   fi+   chmod u+w . 2>&5+   $RM conftest*+   # SGI C++ compiler will create directory out/ii_files/ for+   # template instantiation+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files+   $RM out/* && rmdir out+   cd ..+   $RM -r conftest+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5+printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; }+++++hard_links=nottested+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then+  # do not overwrite the value of need_locks provided by the user+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5+printf %s "checking if we can lock with hard links... " >&6; }+  hard_links=yes+  $RM conftest*+  ln conftest.a conftest.b 2>/dev/null && hard_links=no+  touch conftest.a+  ln conftest.a conftest.b 2>&5 || hard_links=no+  ln conftest.a conftest.b 2>/dev/null && hard_links=no+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5+printf "%s\n" "$hard_links" >&6; }+  if test no = "$hard_links"; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5+printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}+    need_locks=warn+  fi+else+  need_locks=no+fi+++++++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5+printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }++  runpath_var=+  allow_undefined_flag=+  always_export_symbols=no+  archive_cmds=+  archive_expsym_cmds=+  compiler_needs_object=no+  enable_shared_with_static_runtimes=no+  export_dynamic_flag_spec=+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'+  hardcode_automatic=no+  hardcode_direct=no+  hardcode_direct_absolute=no+  hardcode_libdir_flag_spec=+  hardcode_libdir_separator=+  hardcode_minus_L=no+  hardcode_shlibpath_var=unsupported+  inherit_rpath=no+  link_all_deplibs=unknown+  module_cmds=+  module_expsym_cmds=+  old_archive_from_new_cmds=+  old_archive_from_expsyms_cmds=+  thread_safe_flag_spec=+  whole_archive_flag_spec=+  # include_expsyms should be a list of space-separated symbols to be *always*+  # included in the symbol list+  include_expsyms=+  # exclude_expsyms can be an extended regexp of symbols to exclude+  # it will be wrapped by ' (' and ')$', so one must not match beginning or+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',+  # as well as any symbol that contains 'd'.+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out+  # platforms (ab)use it in PIC code, but their linkers get confused if+  # the symbol is explicitly referenced.  Since portable code cannot+  # rely on this symbol name, it's probably fine to never include it in+  # preloaded symbol tables.+  # Exclude shared library initialization/finalization symbols.+  extract_expsyms_cmds=++  case $host_os in+  cygwin* | mingw* | windows* | pw32* | cegcc*)+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time+    # When not using gcc, we currently assume that we are using+    # Microsoft Visual C++ or Intel C++ Compiler.+    if test yes != "$GCC"; then+      with_gnu_ld=no+    fi+    ;;+  interix*)+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)+    with_gnu_ld=yes+    ;;+  esac++  ld_shlibs=yes++  # On some targets, GNU ld is compatible enough with the native linker+  # that we're better off using the native interface for both.+  lt_use_gnu_ld_interface=no+  if test yes = "$with_gnu_ld"; then+    case $host_os in+      aix*)+	# The AIX port of GNU ld has always aspired to compatibility+	# with the native linker.  However, as the warning in the GNU ld+	# block says, versions before 2.19.5* couldn't really create working+	# shared libraries, regardless of the interface used.+	case `$LD -v 2>&1` in+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;+	  *)+	    lt_use_gnu_ld_interface=yes+	    ;;+	esac+	;;+      *)+	lt_use_gnu_ld_interface=yes+	;;+    esac+  fi++  if test yes = "$lt_use_gnu_ld_interface"; then+    # If archive_cmds runs LD, not CC, wlarc should be empty+    wlarc='$wl'++    # Set some defaults for GNU ld with shared library support. These+    # are reset later if shared libraries are not supported. Putting them+    # here allows them to be overridden if necessary.+    runpath_var=LD_RUN_PATH+    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+    export_dynamic_flag_spec='$wl--export-dynamic'+    # ancient GNU ld didn't support --whole-archive et. al.+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then+      whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'+    else+      whole_archive_flag_spec=+    fi+    supports_anon_versioning=no+    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in+      *GNU\ gold*) supports_anon_versioning=yes ;;+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...+      *\ 2.11.*) ;; # other 2.11 versions+      *) supports_anon_versioning=yes ;;+    esac++    # See if GNU ld supports shared libraries.+    case $host_os in+    aix[3-9]*)+      # On AIX/PPC, the GNU linker is very broken+      if test ia64 != "$host_cpu"; then+	ld_shlibs=no+	cat <<_LT_EOF 1>&2++*** Warning: the GNU linker, at least up to release 2.19, is reported+*** to be unable to reliably create shared libraries on AIX.+*** Therefore, libtool is disabling shared libraries support.  If you+*** really care for shared libraries, you may want to install binutils+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.+*** You will then need to restart the configuration process.++_LT_EOF+      fi+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+            archive_expsym_cmds=''+        ;;+      m68k)+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'+            hardcode_libdir_flag_spec='-L$libdir'+            hardcode_minus_L=yes+        ;;+      esac+      ;;++    beos*)+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	allow_undefined_flag=unsupported+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc+	# support --undefined.  This deserves some investigation.  FIXME+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+      else+	ld_shlibs=no+      fi+      ;;++    cygwin* | mingw* | windows* | pw32* | cegcc*)+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,+      # as there is no search path for DLLs.+      hardcode_libdir_flag_spec='-L$libdir'+      export_dynamic_flag_spec='$wl--export-all-symbols'+      allow_undefined_flag=unsupported+      always_export_symbols=no+      enable_shared_with_static_runtimes=yes+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'+      file_list_spec='@'++      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+	# If the export-symbols file already is a .def file, use it as+	# is; otherwise, prepend EXPORTS...+	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then+          cp $export_symbols $output_objdir/$soname.def;+        else+          echo EXPORTS > $output_objdir/$soname.def;+          cat $export_symbols >> $output_objdir/$soname.def;+        fi~+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+      else+	ld_shlibs=no+      fi+      ;;++    haiku*)+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+      link_all_deplibs=no+      ;;++    os2*)+      hardcode_libdir_flag_spec='-L$libdir'+      hardcode_minus_L=yes+      allow_undefined_flag=unsupported+      shrext_cmds=.dll+      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	prefix_cmds="$SED"~+	if test EXPORTS = "`$SED 1q $export_symbols`"; then+	  prefix_cmds="$prefix_cmds -e 1d";+	fi~+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'+      enable_shared_with_static_runtimes=yes+      file_list_spec='@'+      ;;++    interix[3-9]*)+      hardcode_direct=no+      hardcode_shlibpath_var=no+      hardcode_libdir_flag_spec='$wl-rpath,$libdir'+      export_dynamic_flag_spec='$wl-E'+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.+      # Instead, shared libraries are loaded at an image base (0x10000000 by+      # default) and relocated if they conflict, which is a slow very memory+      # consuming and fragmenting process.  To avoid this, we pick a random,+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+      archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+      ;;++    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)+      tmp_diet=no+      if test linux-dietlibc = "$host_os"; then+	case $cc_basename in+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)+	esac+      fi+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \+	 && test no = "$tmp_diet"+      then+	tmp_addflag=' $pic_flag'+	tmp_sharedflag='-shared'+	case $cc_basename,$host_cpu in+        pgcc*)				# Portland Group C compiler+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  tmp_addflag=' $pic_flag'+	  ;;+	pgf77* | pgf90* | pgf95* | pgfortran*)+					# Portland Group f77 and f90 compilers+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  tmp_addflag=' $pic_flag -Mnomain' ;;+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64+	  tmp_addflag=' -i_dynamic' ;;+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64+	  tmp_addflag=' -i_dynamic -nofor_main' ;;+	ifc* | ifort*)			# Intel Fortran compiler+	  tmp_addflag=' -nofor_main' ;;+	lf95*)				# Lahey Fortran 8.1+	  whole_archive_flag_spec=+	  tmp_sharedflag='--shared' ;;+        nagfor*)                        # NAGFOR 5.3+          tmp_sharedflag='-Wl,-shared' ;;+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)+	  tmp_sharedflag='-qmkshrobj'+	  tmp_addflag= ;;+	nvcc*)	# Cuda Compiler Driver 2.2+	  whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  compiler_needs_object=yes+	  ;;+	esac+	case `$CC -V 2>&1 | $SED 5q` in+	*Sun\ C*)			# Sun C 5.9+	  whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  compiler_needs_object=yes+	  tmp_sharedflag='-G' ;;+	*Sun\ F*)			# Sun Fortran 8.3+	  tmp_sharedflag='-G' ;;+	esac+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'++        if test yes = "$supports_anon_versioning"; then+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~+            cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~+            echo "local: *; };" >> $output_objdir/$libname.ver~+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'+        fi++	case $cc_basename in+	tcc*)+	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+	  export_dynamic_flag_spec='-rdynamic'+	  ;;+	xlf* | bgf* | bgxlf* | mpixlf*)+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'+	  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'+	  if test yes = "$supports_anon_versioning"; then+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~+              cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~+              echo "local: *; };" >> $output_objdir/$libname.ver~+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'+	  fi+	  ;;+	esac+      else+        ld_shlibs=no+      fi+      ;;++    *-mlibc)+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      ;;++    netbsd* | netbsdelf*-gnu)+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'+	wlarc=+      else+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      fi+      ;;++    solaris*)+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then+	ld_shlibs=no+	cat <<_LT_EOF 1>&2++*** Warning: The releases 2.8.* of the GNU linker cannot reliably+*** create shared libraries on Solaris systems.  Therefore, libtool+*** is disabling shared libraries support.  We urge you to upgrade GNU+*** binutils to release 2.9.1 or newer.  Another option is to modify+*** your PATH or compiler configuration so that the native linker is+*** used, and then restart.++_LT_EOF+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      else+	ld_shlibs=no+      fi+      ;;++    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)+      case `$LD -v 2>&1` in+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)+	ld_shlibs=no+	cat <<_LT_EOF 1>&2++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot+*** reliably create shared libraries on SCO systems.  Therefore, libtool+*** is disabling shared libraries support.  We urge you to upgrade GNU+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify+*** your PATH or compiler configuration so that the native linker is+*** used, and then restart.++_LT_EOF+	;;+	*)+	  # For security reasons, it is highly recommended that you always+	  # use absolute paths for naming shared libraries, and exclude the+	  # DT_RUNPATH tag from executables and libraries.  But doing so+	  # requires that you compile everything twice, which is a pain.+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	    hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+	  else+	    ld_shlibs=no+	  fi+	;;+      esac+      ;;++    sunos4*)+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'+      wlarc=+      hardcode_direct=yes+      hardcode_shlibpath_var=no+      ;;++    *)+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      else+	ld_shlibs=no+      fi+      ;;+    esac++    if test no = "$ld_shlibs"; then+      runpath_var=+      hardcode_libdir_flag_spec=+      export_dynamic_flag_spec=+      whole_archive_flag_spec=+    fi+  else+    # PORTME fill in a description of your system's linker (not GNU ld)+    case $host_os in+    aix3*)+      allow_undefined_flag=unsupported+      always_export_symbols=yes+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'+      # Note: this linker hardcodes the directories in LIBPATH if there+      # are no directories specified by -L.+      hardcode_minus_L=yes+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then+	# Neither direct hardcoding nor static linking is supported with a+	# broken collect2.+	hardcode_direct=unsupported+      fi+      ;;++    aix[4-9]*)+      if test ia64 = "$host_cpu"; then+	# On IA64, the linker does run time linking by default, so we don't+	# have to do anything special.+	aix_use_runtimelinking=no+	exp_sym_flag='-Bexport'+	no_entry_flag=+      else+	# If we're using GNU nm, then we don't want the "-C" option.+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.+	# Without the "-l" option, or with the "-B" option, AIX nm treats+	# weak defined symbols like other global defined symbols, whereas+	# GNU nm marks them as "W".+	# While the 'weak' keyword is ignored in the Export File, we need+	# it in the Import File for the 'aix-soname' feature, so we have+	# to replace the "-B" option with "-P" for AIX nm.+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'+	else+	  export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'+	fi+	aix_use_runtimelinking=no++	# Test if we are trying to use run time linking or normal+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we+	# have runtime linking enabled, and use it for executables.+	# For shared libraries, we enable/disable runtime linking+	# depending on the kind of the shared library created -+	# when "with_aix_soname,aix_use_runtimelinking" is:+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables+	# "aix,yes"  lib.so          shared, rtl:yes, for executables+	#            lib.a           static archive+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes+	#            lib.a(lib.so.V) shared, rtl:no,  for executables+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables+	#            lib.a(lib.so.V) shared, rtl:no+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables+	#            lib.a           static archive+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)+	  for ld_flag in $LDFLAGS; do+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then+	    aix_use_runtimelinking=yes+	    break+	  fi+	  done+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,+	    # so we don't have lib.a shared libs to link our executables.+	    # We have to force runtime linking in this case.+	    aix_use_runtimelinking=yes+	    LDFLAGS="$LDFLAGS -Wl,-brtl"+	  fi+	  ;;+	esac++	exp_sym_flag='-bexport'+	no_entry_flag='-bnoentry'+      fi++      # When large executables or shared objects are built, AIX ld can+      # have problems creating the table of contents.  If linking a library+      # or program results in "error TOC overflow" add -mminimal-toc to+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.++      archive_cmds=''+      hardcode_direct=yes+      hardcode_direct_absolute=yes+      hardcode_libdir_separator=':'+      link_all_deplibs=yes+      file_list_spec='$wl-f,'+      case $with_aix_soname,$aix_use_runtimelinking in+      aix,*) ;; # traditional, no import file+      svr4,* | *,yes) # use import file+	# The Import File defines what to hardcode.+	hardcode_direct=no+	hardcode_direct_absolute=no+	;;+      esac++      if test yes = "$GCC"; then+	case $host_os in aix4.[012]|aix4.[012].*)+	# We only want to do this on AIX 4.2 and lower, the check+	# below for broken collect2 doesn't work under 4.3++	  collect2name=`$CC -print-prog-name=collect2`+	  if test -f "$collect2name" &&+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null+	  then+	  # We have reworked collect2+	  :+	  else+	  # We have old collect2+	  hardcode_direct=unsupported+	  # It fails to find uninstalled libraries when the uninstalled+	  # path is not listed in the libpath.  Setting hardcode_minus_L+	  # to unsupported forces relinking+	  hardcode_minus_L=yes+	  hardcode_libdir_flag_spec='-L$libdir'+	  hardcode_libdir_separator=+	  fi+	  ;;+	esac+	shared_flag='-shared'+	if test yes = "$aix_use_runtimelinking"; then+	  shared_flag="$shared_flag "'$wl-G'+	fi+	# Need to ensure runtime linking is disabled for the traditional+	# shared library, or the linker may eventually find shared libraries+	# /with/ Import File - we do not want to mix them.+	shared_flag_aix='-shared'+	shared_flag_svr4='-shared $wl-G'+      else+	# not using gcc+	if test ia64 = "$host_cpu"; then+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release+	# chokes on -Wl,-G. The following line is correct:+	  shared_flag='-G'+	else+	  if test yes = "$aix_use_runtimelinking"; then+	    shared_flag='$wl-G'+	  else+	    shared_flag='$wl-bM:SRE'+	  fi+	  shared_flag_aix='$wl-bM:SRE'+	  shared_flag_svr4='$wl-G'+	fi+      fi++      export_dynamic_flag_spec='$wl-bexpall'+      # It seems that -bexpall does not export symbols beginning with+      # underscore (_), so it is better to generate a list of symbols to export.+      always_export_symbols=yes+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then+	# Warning - without using the other runtime loading flags (-brtl),+	# -berok will link without error, but may produce a broken library.+	allow_undefined_flag='-berok'+        # Determine the default libpath from the value encoded in an+        # empty executable.+        if test set = "${lt_cv_aix_libpath+set}"; then+  aix_libpath=$lt_cv_aix_libpath+else+  if test ${lt_cv_aix_libpath_+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :++  lt_aix_libpath_sed='+      /Import File Strings/,/^$/ {+	  /^0/ {+	      s/^0  *\([^ ]*\) *$/\1/+	      p+	  }+      }'+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  # Check for a 64-bit object if we didn't find anything.+  if test -z "$lt_cv_aix_libpath_"; then+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+  if test -z "$lt_cv_aix_libpath_"; then+    lt_cv_aix_libpath_=/usr/lib:/lib+  fi+   ;;+esac+fi++  aix_libpath=$lt_cv_aix_libpath_+fi++        hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag+      else+	if test ia64 = "$host_cpu"; then+	  hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'+	  allow_undefined_flag="-z nodefs"+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"+	else+	 # Determine the default libpath from the value encoded in an+	 # empty executable.+	 if test set = "${lt_cv_aix_libpath+set}"; then+  aix_libpath=$lt_cv_aix_libpath+else+  if test ${lt_cv_aix_libpath_+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :++  lt_aix_libpath_sed='+      /Import File Strings/,/^$/ {+	  /^0/ {+	      s/^0  *\([^ ]*\) *$/\1/+	      p+	  }+      }'+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  # Check for a 64-bit object if we didn't find anything.+  if test -z "$lt_cv_aix_libpath_"; then+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+  if test -z "$lt_cv_aix_libpath_"; then+    lt_cv_aix_libpath_=/usr/lib:/lib+  fi+   ;;+esac+fi++  aix_libpath=$lt_cv_aix_libpath_+fi++	 hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"+	  # Warning - without using the other run time loading flags,+	  # -berok will link without error, but may produce a broken library.+	  no_undefined_flag=' $wl-bernotok'+	  allow_undefined_flag=' $wl-berok'+	  if test yes = "$with_gnu_ld"; then+	    # We only use this code for GNU lds that support --whole-archive.+	    whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'+	  else+	    # Exported symbols can be pulled into shared objects from archives+	    whole_archive_flag_spec='$convenience'+	  fi+	  archive_cmds_need_lc=yes+	  archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'+	  # -brtl affects multiple linker settings, -berok does not and is overridden later+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'+	  if test svr4 != "$with_aix_soname"; then+	    # This is similar to how AIX traditionally builds its shared libraries.+	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'+	  fi+	  if test aix != "$with_aix_soname"; then+	    archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'+	  else+	    # used by -dlpreopen to get the symbols+	    archive_expsym_cmds="$archive_expsym_cmds"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'+	  fi+	  archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'+	fi+      fi+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+            archive_expsym_cmds=''+        ;;+      m68k)+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'+            hardcode_libdir_flag_spec='-L$libdir'+            hardcode_minus_L=yes+        ;;+      esac+      ;;++    bsdi[45]*)+      export_dynamic_flag_spec=-rdynamic+      ;;++    cygwin* | mingw* | windows* | pw32* | cegcc*)+      # When not using gcc, we currently assume that we are using+      # Microsoft Visual C++ or Intel C++ Compiler.+      # hardcode_libdir_flag_spec is actually meaningless, as there is+      # no search path for DLLs.+      case $cc_basename in+      cl* | icl*)+	# Native MSVC or ICC+	hardcode_libdir_flag_spec=' '+	allow_undefined_flag=unsupported+	always_export_symbols=yes+	file_list_spec='@'+	# Tell ltmain to make .lib files, not .a files.+	libext=lib+	# Tell ltmain to make .dll files, not .so files.+	shrext_cmds=.dll+	# FIXME: Setting linknames here is a bad hack.+	archive_cmds='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='+	archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then+            cp "$export_symbols" "$output_objdir/$soname.def";+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";+          else+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;+          fi~+          $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~+          linknames='+	# The linker will not automatically build a static lib if we build a DLL.+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'+	enable_shared_with_static_runtimes=yes+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'+	# Don't use ranlib+	old_postinstall_cmds='chmod 644 $oldlib'+	postlink_cmds='lt_outputfile="@OUTPUT@"~+          lt_tool_outputfile="@TOOL_OUTPUT@"~+          case $lt_outputfile in+            *.exe|*.EXE) ;;+            *)+              lt_outputfile=$lt_outputfile.exe+              lt_tool_outputfile=$lt_tool_outputfile.exe+              ;;+          esac~+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;+            $RM "$lt_outputfile.manifest";+          fi'+	;;+      *)+	# Assume MSVC and ICC wrapper+	hardcode_libdir_flag_spec=' '+	allow_undefined_flag=unsupported+	# Tell ltmain to make .lib files, not .a files.+	libext=lib+	# Tell ltmain to make .dll files, not .so files.+	shrext_cmds=.dll+	# FIXME: Setting linknames here is a bad hack.+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='+	# The linker will automatically build a .lib file if we build a DLL.+	old_archive_from_new_cmds='true'+	# FIXME: Should let the user specify the lib program.+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'+	enable_shared_with_static_runtimes=yes+	;;+      esac+      ;;++    darwin* | rhapsody*)+++  archive_cmds_need_lc=no+  hardcode_direct=no+  hardcode_automatic=yes+  hardcode_shlibpath_var=unsupported+  if test yes = "$lt_cv_ld_force_load"; then+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'++  else+    whole_archive_flag_spec=''+  fi+  link_all_deplibs=yes+  allow_undefined_flag=$_lt_dar_allow_undefined+  case $cc_basename in+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;+     *) _lt_dar_can_shared=$GCC ;;+  esac+  if test yes = "$_lt_dar_can_shared"; then+    output_verbose_link_cmd=func_echo_all+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"+    archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"+    module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"++  else+  ld_shlibs=no+  fi++      ;;++    dgux*)+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      hardcode_libdir_flag_spec='-L$libdir'+      hardcode_shlibpath_var=no+      ;;++    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor+    # support.  Future versions do this automatically, but an explicit c++rt0.o+    # does not break anything, and helps significantly (at the cost of a little+    # extra space).+    freebsd2.2*)+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'+      hardcode_libdir_flag_spec='-R$libdir'+      hardcode_direct=yes+      hardcode_shlibpath_var=no+      ;;++    # Unfortunately, older versions of FreeBSD 2 do not have this feature.+    freebsd2.*)+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'+      hardcode_direct=yes+      hardcode_minus_L=yes+      hardcode_shlibpath_var=no+      ;;++    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.+    freebsd* | dragonfly* | midnightbsd*)+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+      hardcode_libdir_flag_spec='-R$libdir'+      hardcode_direct=yes+      hardcode_shlibpath_var=no+      ;;++    hpux9*)+      if test yes = "$GCC"; then+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+      else+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+      fi+      hardcode_libdir_flag_spec='$wl+b $wl$libdir'+      hardcode_libdir_separator=:+      hardcode_direct=yes++      # hardcode_minus_L: Not really in the search PATH,+      # but as the default location of the library.+      hardcode_minus_L=yes+      export_dynamic_flag_spec='$wl-E'+      ;;++    hpux10*)+      if test yes,no = "$GCC,$with_gnu_ld"; then+	archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'+      else+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'+      fi+      if test no = "$with_gnu_ld"; then+	hardcode_libdir_flag_spec='$wl+b $wl$libdir'+	hardcode_libdir_separator=:+	hardcode_direct=yes+	hardcode_direct_absolute=yes+	export_dynamic_flag_spec='$wl-E'+	# hardcode_minus_L: Not really in the search PATH,+	# but as the default location of the library.+	hardcode_minus_L=yes+      fi+      ;;++    hpux11*)+      if test yes,no = "$GCC,$with_gnu_ld"; then+	case $host_cpu in+	hppa*64*)+	  archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	ia64*)+	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	*)+	  archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	esac+      else+	case $host_cpu in+	hppa*64*)+	  archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	ia64*)+	  archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	*)++	  # Older versions of the 11.00 compiler do not understand -b yet+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5+printf %s "checking if $CC understands -b... " >&6; }+if test ${lt_cv_prog_compiler__b+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler__b=no+   save_LDFLAGS=$LDFLAGS+   LDFLAGS="$LDFLAGS -b"+   echo "$lt_simple_link_test_code" > conftest.$ac_ext+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then+     # The linker can only warn and ignore the option if not recognized+     # So say no if there are warnings+     if test -s conftest.err; then+       # Append any errors to the config.log.+       cat conftest.err 1>&5+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+       if diff conftest.exp conftest.er2 >/dev/null; then+         lt_cv_prog_compiler__b=yes+       fi+     else+       lt_cv_prog_compiler__b=yes+     fi+   fi+   $RM -r conftest*+   LDFLAGS=$save_LDFLAGS+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5+printf "%s\n" "$lt_cv_prog_compiler__b" >&6; }++if test yes = "$lt_cv_prog_compiler__b"; then+    archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'+else+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'+fi++	  ;;+	esac+      fi+      if test no = "$with_gnu_ld"; then+	hardcode_libdir_flag_spec='$wl+b $wl$libdir'+	hardcode_libdir_separator=:++	case $host_cpu in+	hppa*64*|ia64*)+	  hardcode_direct=no+	  hardcode_shlibpath_var=no+	  ;;+	*)+	  hardcode_direct=yes+	  hardcode_direct_absolute=yes+	  export_dynamic_flag_spec='$wl-E'++	  # hardcode_minus_L: Not really in the search PATH,+	  # but as the default location of the library.+	  hardcode_minus_L=yes+	  ;;+	esac+      fi+      ;;++    irix5* | irix6* | nonstopux*)+      if test yes = "$GCC"; then+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+	# Try to use the -exported_symbol ld option, if it does not+	# work, assume that -exports_file does not work either and+	# implicitly export all symbols.+	# This should be the same for all languages, so no per-tag cache variable.+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5+printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; }+if test ${lt_cv_irix_exported_symbol+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) save_LDFLAGS=$LDFLAGS+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+int foo (void) { return 0; }+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  lt_cv_irix_exported_symbol=yes+else case e in #(+  e) lt_cv_irix_exported_symbol=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+           LDFLAGS=$save_LDFLAGS ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5+printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; }+	if test yes = "$lt_cv_irix_exported_symbol"; then+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'+	fi+      else+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'+      fi+      archive_cmds_need_lc='no'+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+      hardcode_libdir_separator=:+      inherit_rpath=yes+      link_all_deplibs=yes+      ;;++    linux*)+      case $cc_basename in+      tcc*)+	# Fabrice Bellard et al's Tiny C Compiler+	ld_shlibs=yes+	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+	;;+      esac+      ;;++    *-mlibc)+      ;;++    netbsd* | netbsdelf*-gnu)+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out+      else+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF+      fi+      hardcode_libdir_flag_spec='-R$libdir'+      hardcode_direct=yes+      hardcode_shlibpath_var=no+      ;;++    newsos6)+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      hardcode_direct=yes+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+      hardcode_libdir_separator=:+      hardcode_shlibpath_var=no+      ;;++    *nto* | *qnx*)+      ;;++    openbsd*)+      if test -f /usr/libexec/ld.so; then+	hardcode_direct=yes+	hardcode_shlibpath_var=no+	hardcode_direct_absolute=yes+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'+	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'+	  export_dynamic_flag_spec='$wl-E'+	else+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+	  hardcode_libdir_flag_spec='$wl-rpath,$libdir'+	fi+      else+	ld_shlibs=no+      fi+      ;;++    os2*)+      hardcode_libdir_flag_spec='-L$libdir'+      hardcode_minus_L=yes+      allow_undefined_flag=unsupported+      shrext_cmds=.dll+      archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	prefix_cmds="$SED"~+	if test EXPORTS = "`$SED 1q $export_symbols`"; then+	  prefix_cmds="$prefix_cmds -e 1d";+	fi~+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'+      enable_shared_with_static_runtimes=yes+      file_list_spec='@'+      ;;++    osf3*)+      if test yes = "$GCC"; then+	allow_undefined_flag=' $wl-expect_unresolved $wl\*'+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+      else+	allow_undefined_flag=' -expect_unresolved \*'+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+      fi+      archive_cmds_need_lc='no'+      hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+      hardcode_libdir_separator=:+      ;;++    osf4* | osf5*)	# as osf3* with the addition of -msym flag+      if test yes = "$GCC"; then+	allow_undefined_flag=' $wl-expect_unresolved $wl\*'+	archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+	hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+      else+	allow_undefined_flag=' -expect_unresolved \*'+	archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'++	# Both c and cxx compiler support -rpath directly+	hardcode_libdir_flag_spec='-rpath $libdir'+      fi+      archive_cmds_need_lc='no'+      hardcode_libdir_separator=:+      ;;++    serenity*)+      ;;++    solaris*)+      no_undefined_flag=' -z defs'+      if test yes = "$GCC"; then+	wlarc='$wl'+	archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'+      else+	case `$CC -V 2>&1` in+	*"Compilers 5.0"*)+	  wlarc=''+	  archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'+	  ;;+	*)+	  wlarc='$wl'+	  archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'+	  ;;+	esac+      fi+      hardcode_libdir_flag_spec='-R$libdir'+      hardcode_shlibpath_var=no+      case $host_os in+      solaris2.[0-5] | solaris2.[0-5].*) ;;+      *)+	# The compiler driver will combine and reorder linker options,+	# but understands '-z linker_flag'.  GCC discards it without '$wl',+	# but is careful enough not to reorder.+	# Supported since Solaris 2.6 (maybe 2.5.1?)+	if test yes = "$GCC"; then+	  whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'+	else+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'+	fi+	;;+      esac+      link_all_deplibs=yes+      ;;++    sunos4*)+      if test sequent = "$host_vendor"; then+	# Use $CC to link under sequent, because it throws in some extra .o+	# files that make .init and .fini sections work.+	archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'+      else+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'+      fi+      hardcode_libdir_flag_spec='-L$libdir'+      hardcode_direct=yes+      hardcode_minus_L=yes+      hardcode_shlibpath_var=no+      ;;++    sysv4)+      case $host_vendor in+	sni)+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+	  hardcode_direct=yes # is this really true???+	;;+	siemens)+	  ## LD is ld it makes a PLAMLIB+	  ## CC just makes a GrossModule.+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'+	  reload_cmds='$CC -r -o $output$reload_objs'+	  hardcode_direct=no+        ;;+	motorola)+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie+	;;+      esac+      runpath_var='LD_RUN_PATH'+      hardcode_shlibpath_var=no+      ;;++    sysv4.3*)+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      hardcode_shlibpath_var=no+      export_dynamic_flag_spec='-Bexport'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+	hardcode_shlibpath_var=no+	runpath_var=LD_RUN_PATH+	hardcode_runpath_var=yes+	ld_shlibs=yes+      fi+      ;;++    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)+      no_undefined_flag='$wl-z,text'+      archive_cmds_need_lc=no+      hardcode_shlibpath_var=no+      runpath_var='LD_RUN_PATH'++      if test yes = "$GCC"; then+	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      else+	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      fi+      ;;++    sysv5* | sco3.2v5* | sco5v6*)+      # Note: We CANNOT use -z defs as we might desire, because we do not+      # link with -lc, and that would cause any symbols used from libc to+      # always be unresolved, which means just about no library would+      # ever link correctly.  If we're not using GNU ld we use -z text+      # though, which does catch some bad symbols but isn't as heavy-handed+      # as -z defs.+      no_undefined_flag='$wl-z,text'+      allow_undefined_flag='$wl-z,nodefs'+      archive_cmds_need_lc=no+      hardcode_shlibpath_var=no+      hardcode_libdir_flag_spec='$wl-R,$libdir'+      hardcode_libdir_separator=':'+      link_all_deplibs=yes+      export_dynamic_flag_spec='$wl-Bexport'+      runpath_var='LD_RUN_PATH'++      if test yes = "$GCC"; then+	archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      else+	archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      fi+      ;;++    uts4*)+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      hardcode_libdir_flag_spec='-L$libdir'+      hardcode_shlibpath_var=no+      ;;++    *)+      ld_shlibs=no+      ;;+    esac++    if test sni = "$host_vendor"; then+      case $host in+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)+	export_dynamic_flag_spec='$wl-Blargedynsym'+	;;+      esac+    fi+  fi++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5+printf "%s\n" "$ld_shlibs" >&6; }+test no = "$ld_shlibs" && can_build_shared=no++with_gnu_ld=$with_gnu_ld++++++++++++++++#+# Do we need to explicitly link libc?+#+case "x$archive_cmds_need_lc" in+x|xyes)+  # Assume -lc should be added+  archive_cmds_need_lc=yes++  if test yes,yes = "$GCC,$enable_shared"; then+    case $archive_cmds in+    *'~'*)+      # FIXME: we may have to deal with multi-command sequences.+      ;;+    '$CC '*)+      # Test whether the compiler implicitly links with -lc since on some+      # systems, -lgcc has to come before -lc. If gcc already passes -lc+      # to ld, don't add -lc before -lgcc.+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5+printf %s "checking whether -lc should be explicitly linked in... " >&6; }+if test ${lt_cv_archive_cmds_need_lc+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) $RM conftest*+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext++	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } 2>conftest.err; then+	  soname=conftest+	  lib=conftest+	  libobjs=conftest.$ac_objext+	  deplibs=+	  wl=$lt_prog_compiler_wl+	  pic_flag=$lt_prog_compiler_pic+	  compiler_flags=-v+	  linker_flags=-v+	  verstring=+	  output_objdir=.+	  libname=conftest+	  lt_save_allow_undefined_flag=$allow_undefined_flag+	  allow_undefined_flag=+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+	  then+	    lt_cv_archive_cmds_need_lc=no+	  else+	    lt_cv_archive_cmds_need_lc=yes+	  fi+	  allow_undefined_flag=$lt_save_allow_undefined_flag+	else+	  cat conftest.err 1>&5+	fi+	$RM conftest*+	 ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5+printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; }+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc+      ;;+    esac+  fi+  ;;+esac+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5+printf %s "checking dynamic linker characteristics... " >&6; }++if test yes = "$GCC"; then+  case $host_os in+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;+    *) lt_awk_arg='/^libraries:/' ;;+  esac+  case $host_os in+    mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;+    *) lt_sed_strip_eq='s|=/|/|g' ;;+  esac+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`+  case $lt_search_path_spec in+  *\;*)+    # if the path contains ";" then we assume it to be the separator+    # otherwise default to the standard path separator (i.e. ":") - it is+    # assumed that no part of a normal pathname contains ";" but that should+    # okay in the real world where ";" in dirpaths is itself problematic.+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`+    ;;+  *)+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`+    ;;+  esac+  # Ok, now we have the path, separated by spaces, we can step through it+  # and add multilib dir if necessary...+  lt_tmp_lt_search_path_spec=+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`+  # ...but if some path component already ends with the multilib dir we assume+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).+  case "$lt_multi_os_dir; $lt_search_path_spec " in+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)+    lt_multi_os_dir=+    ;;+  esac+  for lt_sys_path in $lt_search_path_spec; do+    if test -d "$lt_sys_path$lt_multi_os_dir"; then+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"+    elif test -n "$lt_multi_os_dir"; then+      test -d "$lt_sys_path" && \+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"+    fi+  done+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '+BEGIN {RS = " "; FS = "/|\n";} {+  lt_foo = "";+  lt_count = 0;+  for (lt_i = NF; lt_i > 0; lt_i--) {+    if ($lt_i != "" && $lt_i != ".") {+      if ($lt_i == "..") {+        lt_count++;+      } else {+        if (lt_count == 0) {+          lt_foo = "/" $lt_i lt_foo;+        } else {+          lt_count--;+        }+      }+    }+  }+  if (lt_foo != "") { lt_freq[lt_foo]++; }+  if (lt_freq[lt_foo] == 1) { print lt_foo; }+}'`+  # AWK program above erroneously prepends '/' to C:/dos/paths+  # for these hosts.+  case $host_os in+    mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\+      $SED 's|/\([A-Za-z]:\)|\1|g'` ;;+  esac+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`+else+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"+fi+library_names_spec=+libname_spec='lib$name'+soname_spec=+shrext_cmds=.so+postinstall_cmds=+postuninstall_cmds=+finish_cmds=+finish_eval=+shlibpath_var=+shlibpath_overrides_runpath=unknown+version_type=none+dynamic_linker="$host_os ld.so"+sys_lib_dlsearch_path_spec="/lib /usr/lib"+need_lib_prefix=unknown+hardcode_into_libs=no++# when you set need_version to no, make sure it does not cause -set_version+# flags to be left without arguments+need_version=unknown++++case $host_os in+aix3*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'+  shlibpath_var=LIBPATH++  # AIX 3 has no versioning support, so we append a major version to the name.+  soname_spec='$libname$release$shared_ext$major'+  ;;++aix[4-9]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  hardcode_into_libs=yes+  if test ia64 = "$host_cpu"; then+    # AIX 5 supports IA64+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'+    shlibpath_var=LD_LIBRARY_PATH+  else+    # With GCC up to 2.95.x, collect2 would create an import file+    # for dependence libraries.  The import file would start with+    # the line '#! .'.  This would cause the generated library to+    # depend on '.', always an invalid library.  This was fixed in+    # development snapshots of GCC prior to 3.0.+    case $host_os in+      aix4 | aix4.[01] | aix4.[01].*)+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'+	   echo ' yes '+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then+	:+      else+	can_build_shared=no+      fi+      ;;+    esac+    # Using Import Files as archive members, it is possible to support+    # filename-based versioning of shared library archives on AIX. While+    # this would work for both with and without runtime linking, it will+    # prevent static linking of such archives. So we do filename-based+    # shared library versioning with .so extension only, which is used+    # when both runtime linking and shared linking is enabled.+    # Unfortunately, runtime linking may impact performance, so we do+    # not want this to be the default eventually. Also, we use the+    # versioned .so libs for executables only if there is the -brtl+    # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only.+    # To allow for filename-based versioning support, we need to create+    # libNAME.so.V as an archive file, containing:+    # *) an Import File, referring to the versioned filename of the+    #    archive as well as the shared archive member, telling the+    #    bitwidth (32 or 64) of that shared object, and providing the+    #    list of exported symbols of that shared object, eventually+    #    decorated with the 'weak' keyword+    # *) the shared object with the F_LOADONLY flag set, to really avoid+    #    it being seen by the linker.+    # At run time we better use the real file rather than another symlink,+    # but for link time we create the symlink libNAME.so -> libNAME.so.V++    case $with_aix_soname,$aix_use_runtimelinking in+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct+    # soname into executable. Probably we can add versioning support to+    # collect2, so additional links can be useful in future.+    aix,yes) # traditional libtool+      dynamic_linker='AIX unversionable lib.so'+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so+      # instead of lib<name>.a to let people know that these are not+      # typical AIX shared libraries.+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+      ;;+    aix,no) # traditional AIX only+      dynamic_linker='AIX lib.a(lib.so.V)'+      # We preserve .a as extension for shared libraries through AIX4.2+      # and later when we are not doing run time linking.+      library_names_spec='$libname$release.a $libname.a'+      soname_spec='$libname$release$shared_ext$major'+      ;;+    svr4,*) # full svr4 only+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'+      # We do not specify a path in Import Files, so LIBPATH fires.+      shlibpath_overrides_runpath=yes+      ;;+    *,yes) # both, prefer svr4+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'+      # unpreferred sharedlib libNAME.a needs extra handling+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'+      # We do not specify a path in Import Files, so LIBPATH fires.+      shlibpath_overrides_runpath=yes+      ;;+    *,no) # both, prefer aix+      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"+      library_names_spec='$libname$release.a $libname.a'+      soname_spec='$libname$release$shared_ext$major'+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'+      ;;+    esac+    shlibpath_var=LIBPATH+  fi+  ;;++amigaos*)+  case $host_cpu in+  powerpc)+    # Since July 2007 AmigaOS4 officially supports .so libraries.+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    ;;+  m68k)+    library_names_spec='$libname.ixlibrary $libname.a'+    # Create ${libname}_ixlibrary.a entries in /sys/libs.+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'+    ;;+  esac+  ;;++beos*)+  library_names_spec='$libname$shared_ext'+  dynamic_linker="$host_os ld.so"+  shlibpath_var=LIBRARY_PATH+  ;;++bsdi[45]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"+  # the default ld.so.conf also contains /usr/contrib/lib and+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow+  # libtool to hard-code these into programs+  ;;++cygwin* | mingw* | windows* | pw32* | cegcc*)+  version_type=windows+  shrext_cmds=.dll+  need_version=no+  need_lib_prefix=no++  case $GCC,$cc_basename in+  yes,*)+    # gcc+    library_names_spec='$libname.dll.a'+    # DLL is installed to $(libdir)/../bin by postinstall_cmds+    # If user builds GCC with multilib enabled,+    # it should just install on $(libdir)+    # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones.+    if test xyes = x"$multilib"; then+      postinstall_cmds='base_file=`basename \$file`~+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+        dldir=$destdir/`dirname \$dlpath`~+        $install_prog $dir/$dlname $destdir/$dlname~+        chmod a+x $destdir/$dlname~+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+          eval '\''$striplib $destdir/$dlname'\'' || exit \$?;+        fi'+    else+      postinstall_cmds='base_file=`basename \$file`~+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+        dldir=$destdir/`dirname \$dlpath`~+        test -d \$dldir || mkdir -p \$dldir~+        $install_prog $dir/$dlname \$dldir/$dlname~+        chmod a+x \$dldir/$dlname~+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+          eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;+        fi'+    fi+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~+      dlpath=$dir/\$dldll~+       $RM \$dlpath'+    shlibpath_overrides_runpath=yes++    case $host_os in+    cygwin*)+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'+      soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'++      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"+      ;;+    mingw* | windows* | cegcc*)+      # MinGW DLLs use traditional 'lib' prefix+      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'+      ;;+    pw32*)+      # pw32 DLLs use 'pw' prefix rather than 'lib'+      library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'+      ;;+    esac+    dynamic_linker='Win32 ld.exe'+    ;;++  *,cl* | *,icl*)+    # Native MSVC or ICC+    libname_spec='$name'+    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'+    library_names_spec='$libname.dll.lib'++    case $build_os in+    mingw* | windows*)+      sys_lib_search_path_spec=+      lt_save_ifs=$IFS+      IFS=';'+      for lt_path in $LIB+      do+        IFS=$lt_save_ifs+        # Let DOS variable expansion print the short 8.3 style file name.+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"+      done+      IFS=$lt_save_ifs+      # Convert to MSYS style.+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`+      ;;+    cygwin*)+      # Convert to unix form, then to dos form, then back to unix form+      # but this time dos style (no spaces!) so that the unix form looks+      # like /cygdrive/c/PROGRA~1:/cygdr...+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`+      ;;+    *)+      sys_lib_search_path_spec=$LIB+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then+        # It is most probably a Windows format PATH.+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`+      else+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`+      fi+      # FIXME: find the short name or the path components, as spaces are+      # common. (e.g. "Program Files" -> "PROGRA~1")+      ;;+    esac++    # DLL is installed to $(libdir)/../bin by postinstall_cmds+    postinstall_cmds='base_file=`basename \$file`~+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+      dldir=$destdir/`dirname \$dlpath`~+      test -d \$dldir || mkdir -p \$dldir~+      $install_prog $dir/$dlname \$dldir/$dlname'+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~+      dlpath=$dir/\$dldll~+       $RM \$dlpath'+    shlibpath_overrides_runpath=yes+    dynamic_linker='Win32 link.exe'+    ;;++  *)+    # Assume MSVC and ICC wrapper+    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'+    dynamic_linker='Win32 ld.exe'+    ;;+  esac+  # FIXME: first we should search . and the directory the executable is in+  shlibpath_var=PATH+  ;;++darwin* | rhapsody*)+  dynamic_linker="$host_os dyld"+  version_type=darwin+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$major$shared_ext'+  shlibpath_overrides_runpath=yes+  shlibpath_var=DYLD_LIBRARY_PATH+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'++  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'+  ;;++dgux*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  ;;++freebsd* | dragonfly* | midnightbsd*)+  # DragonFly does not have aout.  When/if they implement a new+  # versioning mechanism, adjust this.+  if test -x /usr/bin/objformat; then+    objformat=`/usr/bin/objformat`+  else+    case $host_os in+    freebsd[23].*) objformat=aout ;;+    *) objformat=elf ;;+    esac+  fi+  version_type=freebsd-$objformat+  case $version_type in+    freebsd-elf*)+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+      soname_spec='$libname$release$shared_ext$major'+      need_version=no+      need_lib_prefix=no+      ;;+    freebsd-*)+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+      need_version=yes+      ;;+  esac+  case $host_cpu in+    powerpc64)+      # On FreeBSD bi-arch platforms, a different variable is used for 32-bit+      # binaries.  See <https://man.freebsd.org/cgi/man.cgi?query=ld.so>.+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+int test_pointer_size[sizeof (void *) - 5];++_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  shlibpath_var=LD_LIBRARY_PATH+else case e in #(+  e) shlibpath_var=LD_32_LIBRARY_PATH ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+      ;;+    *)+      shlibpath_var=LD_LIBRARY_PATH+      ;;+  esac+  case $host_os in+  freebsd2.*)+    shlibpath_overrides_runpath=yes+    ;;+  freebsd3.[01]* | freebsdelf3.[01]*)+    shlibpath_overrides_runpath=yes+    hardcode_into_libs=yes+    ;;+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)+    shlibpath_overrides_runpath=no+    hardcode_into_libs=yes+    ;;+  *) # from 4.6 on, and DragonFly+    shlibpath_overrides_runpath=yes+    hardcode_into_libs=yes+    ;;+  esac+  ;;++haiku*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  dynamic_linker="$host_os runtime_loader"+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LIBRARY_PATH+  shlibpath_overrides_runpath=no+  sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib'+  sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib'+  hardcode_into_libs=no+  ;;++hpux9* | hpux10* | hpux11*)+  # Give a soname corresponding to the major version so that dld.sl refuses to+  # link against other versions.+  version_type=sunos+  need_lib_prefix=no+  need_version=no+  case $host_cpu in+  ia64*)+    shrext_cmds='.so'+    hardcode_into_libs=yes+    dynamic_linker="$host_os dld.so"+    shlibpath_var=LD_LIBRARY_PATH+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    if test 32 = "$HPUX_IA64_MODE"; then+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32+    else+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64+    fi+    ;;+  hppa*64*)+    shrext_cmds='.sl'+    hardcode_into_libs=yes+    dynamic_linker="$host_os dld.sl"+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+    ;;+  *)+    shrext_cmds='.sl'+    dynamic_linker="$host_os dld.sl"+    shlibpath_var=SHLIB_PATH+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    ;;+  esac+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...+  postinstall_cmds='chmod 555 $lib'+  # or fails outright, so override atomically:+  install_override_mode=555+  ;;++interix[3-9]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++irix5* | irix6* | nonstopux*)+  case $host_os in+    nonstopux*) version_type=nonstopux ;;+    *)+	if test yes = "$lt_cv_prog_gnu_ld"; then+		version_type=linux # correct to gnu/linux during the next big refactor+	else+		version_type=irix+	fi ;;+  esac+  need_lib_prefix=no+  need_version=no+  soname_spec='$libname$release$shared_ext$major'+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'+  case $host_os in+  irix5* | nonstopux*)+    libsuff= shlibsuff=+    ;;+  *)+    case $LD in # libtool.m4 will add one of these switches to LD+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")+      libsuff= shlibsuff= libmagic=32-bit;;+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")+      libsuff=32 shlibsuff=N32 libmagic=N32;;+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")+      libsuff=64 shlibsuff=64 libmagic=64-bit;;+    *) libsuff= shlibsuff= libmagic=never-match;;+    esac+    ;;+  esac+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH+  shlibpath_overrides_runpath=no+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"+  hardcode_into_libs=yes+  ;;++# No shared lib support for Linux oldld, aout, or coff.+linux*oldld* | linux*aout* | linux*coff*)+  dynamic_linker=no+  ;;++linux*android*)+  version_type=none # Android doesn't support versioned libraries.+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$shared_ext'+  finish_cmds=+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes++  # This implies no fast_install, which is unacceptable.+  # Some rework will be needed to allow for fast_install+  # before this can be enabled.+  hardcode_into_libs=yes++  dynamic_linker='Android linker'+  # -rpath works at least for libraries that are not overridden by+  # libraries installed in system locations.+  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'+  ;;++# This must be glibc/ELF.+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no++  # Some binutils ld are patched to set DT_RUNPATH+  if test ${lt_cv_shlibpath_overrides_runpath+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_shlibpath_overrides_runpath=no+    save_LDFLAGS=$LDFLAGS+    save_libdir=$libdir+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null+then :+  lt_cv_shlibpath_overrides_runpath=yes+fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+    LDFLAGS=$save_LDFLAGS+    libdir=$save_libdir+     ;;+esac+fi++  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath++  # This implies no fast_install, which is unacceptable.+  # Some rework will be needed to allow for fast_install+  # before this can be enabled.+  hardcode_into_libs=yes++  # Add ABI-specific directories to the system library path.+  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"++  # Ideally, we could use ldconfig to report *all* directories which are+  # searched for libraries, however this is still not possible.  Aside from not+  # being certain /sbin/ldconfig is available, command+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,+  # even though it is searched at run-time.  Try to do the best guess by+  # appending ld.so.conf contents (and includes) to the search path.+  if test -f /etc/ld.so.conf; then+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`+    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"+  fi++  # We used to test for /lib/ld.so.1 and disable shared libraries on+  # powerpc, because MkLinux only supported shared libraries with the+  # GNU dynamic linker.  Since this was broken with cross compilers,+  # most powerpc-linux boxes support dynamic linking these days and+  # people can always --disable-shared, the test was removed, and we+  # assume the GNU/Linux dynamic linker is in use.+  dynamic_linker='GNU/Linux ld.so'+  ;;++netbsdelf*-gnu)+  version_type=linux+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  dynamic_linker='NetBSD ld.elf_so'+  ;;++netbsd*)+  version_type=sunos+  need_lib_prefix=no+  need_version=no+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'+    dynamic_linker='NetBSD (a.out) ld.so'+  else+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    dynamic_linker='NetBSD ld.elf_so'+  fi+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  ;;++*-mlibc)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  dynamic_linker='mlibc ld.so'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++newsos6)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  ;;++*nto* | *qnx*)+  version_type=qnx+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  dynamic_linker='ldqnx.so'+  ;;++openbsd*)+  version_type=sunos+  sys_lib_dlsearch_path_spec=/usr/lib+  need_lib_prefix=no+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+    need_version=no+  else+    need_version=yes+  fi+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  ;;++os2*)+  libname_spec='$name'+  version_type=windows+  shrext_cmds=.dll+  need_version=no+  need_lib_prefix=no+  # OS/2 can only load a DLL with a base name of 8 characters or less.+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";+    v=$($ECHO $release$versuffix | tr -d .-);+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);+    $ECHO $n$v`$shared_ext'+  library_names_spec='${libname}_dll.$libext'+  dynamic_linker='OS/2 ld.exe'+  shlibpath_var=BEGINLIBPATH+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+  postinstall_cmds='base_file=`basename \$file`~+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~+    dldir=$destdir/`dirname \$dlpath`~+    test -d \$dldir || mkdir -p \$dldir~+    $install_prog $dir/$dlname \$dldir/$dlname~+    chmod a+x \$dldir/$dlname~+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;+    fi'+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~+    dlpath=$dir/\$dldll~+    $RM \$dlpath'+  ;;++osf3* | osf4* | osf5*)+  version_type=osf+  need_lib_prefix=no+  need_version=no+  soname_spec='$libname$release$shared_ext$major'+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+  ;;++rdos*)+  dynamic_linker=no+  ;;++serenity*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  dynamic_linker='SerenityOS LibELF'+  ;;++solaris*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  # ldd complains unless libraries are executable+  postinstall_cmds='chmod +x $lib'+  ;;++sunos4*)+  version_type=sunos+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  if test yes = "$with_gnu_ld"; then+    need_lib_prefix=no+  fi+  need_version=yes+  ;;++sysv4 | sysv4.3*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  case $host_vendor in+    sni)+      shlibpath_overrides_runpath=no+      need_lib_prefix=no+      runpath_var=LD_RUN_PATH+      ;;+    siemens)+      need_lib_prefix=no+      ;;+    motorola)+      need_lib_prefix=no+      need_version=no+      shlibpath_overrides_runpath=no+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'+      ;;+  esac+  ;;++sysv4*MP*)+  if test -d /usr/nec; then+    version_type=linux # correct to gnu/linux during the next big refactor+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'+    soname_spec='$libname$shared_ext.$major'+    shlibpath_var=LD_LIBRARY_PATH+  fi+  ;;++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)+  version_type=sco+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  if test yes = "$with_gnu_ld"; then+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'+  else+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'+    case $host_os in+      sco3.2v5*)+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"+	;;+    esac+  fi+  sys_lib_dlsearch_path_spec='/usr/lib'+  ;;++tpf*)+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++uts4*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  ;;++emscripten*)+  version_type=none+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext'+  soname_spec='$libname$release$shared_ext'+  finish_cmds=+  dynamic_linker="Emscripten linker"+  lt_prog_compiler_wl=+lt_prog_compiler_pic=+lt_prog_compiler_static=+++  if test yes = "$GCC"; then+    lt_prog_compiler_wl='-Wl,'+    lt_prog_compiler_static='-static'++    case $host_os in+      aix*)+      # All AIX code is PIC.+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	lt_prog_compiler_static='-Bstatic'+      fi+      lt_prog_compiler_pic='-fPIC'+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            lt_prog_compiler_pic='-fPIC'+        ;;+      m68k)+            # FIXME: we need at least 68020 code to build shared libraries, but+            # adding the '-m68020' flag to GCC prevents building anything better,+            # like '-m68040'.+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'+        ;;+      esac+      ;;++    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)+      # PIC is the default for these OSes.+      ;;++    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      # Although the cygwin gcc ignores -fPIC, still need this for old-style+      # (--disable-auto-import) libraries+      lt_prog_compiler_pic='-DDLL_EXPORT'+      case $host_os in+      os2*)+	lt_prog_compiler_static='$wl-static'+	;;+      esac+      ;;++    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      lt_prog_compiler_pic='-fno-common'+      ;;++    haiku*)+      # PIC is the default for Haiku.+      # The "-static" flag exists, but is broken.+      lt_prog_compiler_static=+      ;;++    hpux*)+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag+      # sets the default TLS model and affects inlining.+      case $host_cpu in+      hppa*64*)+	# +Z the default+	;;+      *)+	lt_prog_compiler_pic='-fPIC'+	;;+      esac+      ;;++    interix[3-9]*)+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.+      # Instead, we relocate shared libraries at runtime.+      ;;++    msdosdjgpp*)+      # Just because we use GCC doesn't mean we suddenly get shared libraries+      # on systems that don't support them.+      lt_prog_compiler_can_build_shared=no+      enable_shared=no+      ;;++    *nto* | *qnx*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      lt_prog_compiler_pic='-fPIC -shared'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	lt_prog_compiler_pic=-Kconform_pic+      fi+      ;;++    *)+      lt_prog_compiler_pic='-fPIC'+      ;;+    esac++    case $cc_basename in+    nvcc*) # Cuda Compiler Driver 2.2+      lt_prog_compiler_wl='-Xlinker '+      if test -n "$lt_prog_compiler_pic"; then+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"+      fi+      ;;+    esac+  else+    # PORTME Check for flag to pass linker flags through the system compiler.+    case $host_os in+    aix*)+      lt_prog_compiler_wl='-Wl,'+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	lt_prog_compiler_static='-Bstatic'+      else+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'+      fi+      ;;++    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      lt_prog_compiler_pic='-fno-common'+      case $cc_basename in+      nagfor*)+        # NAG Fortran compiler+        lt_prog_compiler_wl='-Wl,-Wl,,'+        lt_prog_compiler_pic='-PIC'+        lt_prog_compiler_static='-Bstatic'+        ;;+      esac+      ;;++    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      lt_prog_compiler_pic='-DDLL_EXPORT'+      case $host_os in+      os2*)+	lt_prog_compiler_static='$wl-static'+	;;+      esac+      ;;++    hpux9* | hpux10* | hpux11*)+      lt_prog_compiler_wl='-Wl,'+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but+      # not for PA HP-UX.+      case $host_cpu in+      hppa*64*|ia64*)+	# +Z the default+	;;+      *)+	lt_prog_compiler_pic='+Z'+	;;+      esac+      # Is there a better lt_prog_compiler_static that works with the bundled CC?+      lt_prog_compiler_static='$wl-a ${wl}archive'+      ;;++    irix5* | irix6* | nonstopux*)+      lt_prog_compiler_wl='-Wl,'+      # PIC (with -KPIC) is the default.+      lt_prog_compiler_static='-non_shared'+      ;;++    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+      case $cc_basename in+      # old Intel for x86_64, which still supported -KPIC.+      ecc*)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-KPIC'+	lt_prog_compiler_static='-static'+        ;;+      *flang* | ftn | f18* | f95*)+        # Flang compiler.+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fPIC'+	lt_prog_compiler_static='-static'+        ;;+      # icc used to be incompatible with GCC.+      # ICC 10 doesn't accept -KPIC any more.+      icc* | ifort*)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fPIC'+	lt_prog_compiler_static='-static'+        ;;+      # Lahey Fortran 8.1.+      lf95*)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='--shared'+	lt_prog_compiler_static='--static'+	;;+      nagfor*)+	# NAG Fortran compiler+	lt_prog_compiler_wl='-Wl,-Wl,,'+	lt_prog_compiler_pic='-PIC'+	lt_prog_compiler_static='-Bstatic'+	;;+      tcc*)+	# Fabrice Bellard et al's Tiny C Compiler+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fPIC'+	lt_prog_compiler_static='-static'+	;;+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)+        # Portland Group compilers (*not* the Pentium gcc compiler,+	# which looks to be a dead project)+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-fpic'+	lt_prog_compiler_static='-Bstatic'+        ;;+      ccc*)+        lt_prog_compiler_wl='-Wl,'+        # All Alpha code is PIC.+        lt_prog_compiler_static='-non_shared'+        ;;+      xl* | bgxl* | bgf* | mpixl*)+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene+	lt_prog_compiler_wl='-Wl,'+	lt_prog_compiler_pic='-qpic'+	lt_prog_compiler_static='-qstaticlink'+	;;+      *)+	case `$CC -V 2>&1 | $SED 5q` in+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker+	  lt_prog_compiler_pic='-KPIC'+	  lt_prog_compiler_static='-Bstatic'+	  lt_prog_compiler_wl=''+	  ;;+	*Sun\ F* | *Sun*Fortran*)+	  lt_prog_compiler_pic='-KPIC'+	  lt_prog_compiler_static='-Bstatic'+	  lt_prog_compiler_wl='-Qoption ld '+	  ;;+	*Sun\ C*)+	  # Sun C 5.9+	  lt_prog_compiler_pic='-KPIC'+	  lt_prog_compiler_static='-Bstatic'+	  lt_prog_compiler_wl='-Wl,'+	  ;;+        *Intel*\ [CF]*Compiler*)+	  lt_prog_compiler_wl='-Wl,'+	  lt_prog_compiler_pic='-fPIC'+	  lt_prog_compiler_static='-static'+	  ;;+	*Portland\ Group*)+	  lt_prog_compiler_wl='-Wl,'+	  lt_prog_compiler_pic='-fpic'+	  lt_prog_compiler_static='-Bstatic'+	  ;;+	esac+	;;+      esac+      ;;++    newsos6)+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    *-mlibc)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_pic='-fPIC'+      lt_prog_compiler_static='-static'+      ;;++    *nto* | *qnx*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      lt_prog_compiler_pic='-fPIC -shared'+      ;;++    osf3* | osf4* | osf5*)+      lt_prog_compiler_wl='-Wl,'+      # All OSF/1 code is PIC.+      lt_prog_compiler_static='-non_shared'+      ;;++    rdos*)+      lt_prog_compiler_static='-non_shared'+      ;;++    serenity*)+      ;;++    solaris*)+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      case $cc_basename in+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)+	lt_prog_compiler_wl='-Qoption ld ';;+      *)+	lt_prog_compiler_wl='-Wl,';;+      esac+      ;;++    sunos4*)+      lt_prog_compiler_wl='-Qoption ld '+      lt_prog_compiler_pic='-PIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    sysv4 | sysv4.2uw2* | sysv4.3*)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	lt_prog_compiler_pic='-Kconform_pic'+	lt_prog_compiler_static='-Bstatic'+      fi+      ;;++    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_pic='-KPIC'+      lt_prog_compiler_static='-Bstatic'+      ;;++    unicos*)+      lt_prog_compiler_wl='-Wl,'+      lt_prog_compiler_can_build_shared=no+      ;;++    uts4*)+      lt_prog_compiler_pic='-pic'+      lt_prog_compiler_static='-Bstatic'+      ;;++    *)+      lt_prog_compiler_can_build_shared=no+      ;;+    esac+  fi++case $host_os in+  # For platforms that do not support PIC, -DPIC is meaningless:+  *djgpp*)+    lt_prog_compiler_pic=+    ;;+  *)+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"+    ;;+esac++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5+printf %s "checking for $compiler option to produce PIC... " >&6; }+if test ${lt_cv_prog_compiler_pic+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic=$lt_prog_compiler_pic ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; }+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic++#+# Check to make sure the PIC flag actually works.+#+if test -n "$lt_prog_compiler_pic"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5+printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }+if test ${lt_cv_prog_compiler_pic_works+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic_works=no+   ac_outfile=conftest.$ac_objext+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   # The option is referenced via a variable to avoid confusing sed.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>conftest.err)+   ac_status=$?+   cat conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s "$ac_outfile"; then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings other than the usual output.+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_pic_works=yes+     fi+   fi+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; }++if test yes = "$lt_cv_prog_compiler_pic_works"; then+    case $lt_prog_compiler_pic in+     "" | " "*) ;;+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;+     esac+else+    lt_prog_compiler_pic=+     lt_prog_compiler_can_build_shared=no+fi++fi++++++#+# Check to make sure the static flag actually works.+#+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5+printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }+if test ${lt_cv_prog_compiler_static_works+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_static_works=no+   save_LDFLAGS=$LDFLAGS+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"+   echo "$lt_simple_link_test_code" > conftest.$ac_ext+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then+     # The linker can only warn and ignore the option if not recognized+     # So say no if there are warnings+     if test -s conftest.err; then+       # Append any errors to the config.log.+       cat conftest.err 1>&5+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+       if diff conftest.exp conftest.er2 >/dev/null; then+         lt_cv_prog_compiler_static_works=yes+       fi+     else+       lt_cv_prog_compiler_static_works=yes+     fi+   fi+   $RM -r conftest*+   LDFLAGS=$save_LDFLAGS+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5+printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; }++if test yes = "$lt_cv_prog_compiler_static_works"; then+    :+else+    lt_prog_compiler_static=+fi++++='-fPIC'+  archive_cmds='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib'+  archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym'+  archive_cmds_need_lc=no+  no_undefined_flag=+  ;;++*)+  dynamic_linker=no+  ;;+esac+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5+printf "%s\n" "$dynamic_linker" >&6; }+test no = "$dynamic_linker" && can_build_shared=no++variables_saved_for_relink="PATH $shlibpath_var $runpath_var"+if test yes = "$GCC"; then+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"+fi++if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec+fi++if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec+fi++# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec++# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"++# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5+printf %s "checking how to hardcode library paths into programs... " >&6; }+hardcode_action=+if test -n "$hardcode_libdir_flag_spec" ||+   test -n "$runpath_var" ||+   test yes = "$hardcode_automatic"; then++  # We can hardcode non-existent directories.+  if test no != "$hardcode_direct" &&+     # If the only mechanism to avoid hardcoding is shlibpath_var, we+     # have to relink, otherwise we might link with an installed library+     # when we should be linking with a yet-to-be-installed one+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&+     test no != "$hardcode_minus_L"; then+    # Linking always hardcodes the temporary library directory.+    hardcode_action=relink+  else+    # We can link without hardcoding, and we can hardcode nonexisting dirs.+    hardcode_action=immediate+  fi+else+  # We cannot hardcode anything, or else we can only hardcode existing+  # directories.+  hardcode_action=unsupported+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5+printf "%s\n" "$hardcode_action" >&6; }++if test relink = "$hardcode_action" ||+   test yes = "$inherit_rpath"; then+  # Fast installation is not supported+  enable_fast_install=no+elif test yes = "$shlibpath_overrides_runpath" ||+     test no = "$enable_shared"; then+  # Fast installation is not necessary+  enable_fast_install=needless+fi+++++++  if test yes != "$enable_dlopen"; then+  enable_dlopen=unknown+  enable_dlopen_self=unknown+  enable_dlopen_self_static=unknown+else+  lt_cv_dlopen=no+  lt_cv_dlopen_libs=++  case $host_os in+  beos*)+    lt_cv_dlopen=load_add_on+    lt_cv_dlopen_libs=+    lt_cv_dlopen_self=yes+    ;;++  mingw* | windows* | pw32* | cegcc*)+    lt_cv_dlopen=LoadLibrary+    lt_cv_dlopen_libs=+    ;;++  cygwin*)+    lt_cv_dlopen=dlopen+    lt_cv_dlopen_libs=+    ;;++  darwin*)+    # if libdl is installed we need to link against it+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5+printf %s "checking for dlopen in -ldl... " >&6; }+if test ${ac_cv_lib_dl_dlopen+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_check_lib_save_LIBS=$LIBS+LIBS="-ldl  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.+   The 'extern "C"' is for builds by C++ compilers;+   although this is not generally supported in C code supporting it here+   has little cost and some practical benefit (sr 110532).  */+#ifdef __cplusplus+extern "C"+#endif+char dlopen (void);+int+main (void)+{+return dlopen ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  ac_cv_lib_dl_dlopen=yes+else case e in #(+  e) ac_cv_lib_dl_dlopen=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5+printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; }+if test "x$ac_cv_lib_dl_dlopen" = xyes+then :+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl+else case e in #(+  e)+    lt_cv_dlopen=dyld+    lt_cv_dlopen_libs=+    lt_cv_dlopen_self=yes+     ;;+esac+fi++    ;;++  tpf*)+    # Don't try to run any link tests for TPF.  We know it's impossible+    # because TPF is a cross-compiler, and we know how we open DSOs.+    lt_cv_dlopen=dlopen+    lt_cv_dlopen_libs=+    lt_cv_dlopen_self=no+    ;;++  *)+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"+if test "x$ac_cv_func_shl_load" = xyes+then :+  lt_cv_dlopen=shl_load+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5+printf %s "checking for shl_load in -ldld... " >&6; }+if test ${ac_cv_lib_dld_shl_load+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_check_lib_save_LIBS=$LIBS+LIBS="-ldld  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.+   The 'extern "C"' is for builds by C++ compilers;+   although this is not generally supported in C code supporting it here+   has little cost and some practical benefit (sr 110532).  */+#ifdef __cplusplus+extern "C"+#endif+char shl_load (void);+int+main (void)+{+return shl_load ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  ac_cv_lib_dld_shl_load=yes+else case e in #(+  e) ac_cv_lib_dld_shl_load=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5+printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; }+if test "x$ac_cv_lib_dld_shl_load" = xyes+then :+  lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld+else case e in #(+  e) ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"+if test "x$ac_cv_func_dlopen" = xyes+then :+  lt_cv_dlopen=dlopen+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5+printf %s "checking for dlopen in -ldl... " >&6; }+if test ${ac_cv_lib_dl_dlopen+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_check_lib_save_LIBS=$LIBS+LIBS="-ldl  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.+   The 'extern "C"' is for builds by C++ compilers;+   although this is not generally supported in C code supporting it here+   has little cost and some practical benefit (sr 110532).  */+#ifdef __cplusplus+extern "C"+#endif+char dlopen (void);+int+main (void)+{+return dlopen ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  ac_cv_lib_dl_dlopen=yes+else case e in #(+  e) ac_cv_lib_dl_dlopen=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5+printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; }+if test "x$ac_cv_lib_dl_dlopen" = xyes+then :+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5+printf %s "checking for dlopen in -lsvld... " >&6; }+if test ${ac_cv_lib_svld_dlopen+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_check_lib_save_LIBS=$LIBS+LIBS="-lsvld  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.+   The 'extern "C"' is for builds by C++ compilers;+   although this is not generally supported in C code supporting it here+   has little cost and some practical benefit (sr 110532).  */+#ifdef __cplusplus+extern "C"+#endif+char dlopen (void);+int+main (void)+{+return dlopen ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  ac_cv_lib_svld_dlopen=yes+else case e in #(+  e) ac_cv_lib_svld_dlopen=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5+printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; }+if test "x$ac_cv_lib_svld_dlopen" = xyes+then :+  lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld+else case e in #(+  e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5+printf %s "checking for dld_link in -ldld... " >&6; }+if test ${ac_cv_lib_dld_dld_link+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_check_lib_save_LIBS=$LIBS+LIBS="-ldld  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.+   The 'extern "C"' is for builds by C++ compilers;+   although this is not generally supported in C code supporting it here+   has little cost and some practical benefit (sr 110532).  */+#ifdef __cplusplus+extern "C"+#endif+char dld_link (void);+int+main (void)+{+return dld_link ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  ac_cv_lib_dld_dld_link=yes+else case e in #(+  e) ac_cv_lib_dld_dld_link=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5+printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; }+if test "x$ac_cv_lib_dld_dld_link" = xyes+then :+  lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld+fi++	       ;;+esac+fi++	     ;;+esac+fi++	   ;;+esac+fi++	 ;;+esac+fi++       ;;+esac+fi++    ;;+  esac++  if test no = "$lt_cv_dlopen"; then+    enable_dlopen=no+  else+    enable_dlopen=yes+  fi++  case $lt_cv_dlopen in+  dlopen)+    save_CPPFLAGS=$CPPFLAGS+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"++    save_LDFLAGS=$LDFLAGS+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"++    save_LIBS=$LIBS+    LIBS="$lt_cv_dlopen_libs $LIBS"++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5+printf %s "checking whether a program can dlopen itself... " >&6; }+if test ${lt_cv_dlopen_self+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) 	  if test yes = "$cross_compiling"; then :+  lt_cv_dlopen_self=cross+else+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2+  lt_status=$lt_dlunknown+  cat > conftest.$ac_ext <<_LT_EOF+#line $LINENO "configure"+#include "confdefs.h"++#if HAVE_DLFCN_H+#include <dlfcn.h>+#endif++#include <stdio.h>++#ifdef RTLD_GLOBAL+#  define LT_DLGLOBAL		RTLD_GLOBAL+#else+#  ifdef DL_GLOBAL+#    define LT_DLGLOBAL		DL_GLOBAL+#  else+#    define LT_DLGLOBAL		0+#  endif+#endif++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we+   find out it does not work in some platform. */+#ifndef LT_DLLAZY_OR_NOW+#  ifdef RTLD_LAZY+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY+#  else+#    ifdef DL_LAZY+#      define LT_DLLAZY_OR_NOW		DL_LAZY+#    else+#      ifdef RTLD_NOW+#        define LT_DLLAZY_OR_NOW	RTLD_NOW+#      else+#        ifdef DL_NOW+#          define LT_DLLAZY_OR_NOW	DL_NOW+#        else+#          define LT_DLLAZY_OR_NOW	0+#        endif+#      endif+#    endif+#  endif+#endif++/* When -fvisibility=hidden is used, assume the code has been annotated+   correspondingly for the symbols needed.  */+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))+int fnord (void) __attribute__((visibility("default")));+#endif++int fnord (void) { return 42; }+int main (void)+{+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);+  int status = $lt_dlunknown;++  if (self)+    {+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;+      else+        {+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;+          else puts (dlerror ());+	}+      /* dlclose (self); */+    }+  else+    puts (dlerror ());++  return status;+}+_LT_EOF+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5+  (eval $ac_link) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then+    (./conftest; exit; ) >&5 2>/dev/null+    lt_status=$?+    case x$lt_status in+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;+    esac+  else :+    # compilation failed+    lt_cv_dlopen_self=no+  fi+fi+rm -fr conftest*++     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5+printf "%s\n" "$lt_cv_dlopen_self" >&6; }++    if test yes = "$lt_cv_dlopen_self"; then+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5+printf %s "checking whether a statically linked program can dlopen itself... " >&6; }+if test ${lt_cv_dlopen_self_static+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) 	  if test yes = "$cross_compiling"; then :+  lt_cv_dlopen_self_static=cross+else+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2+  lt_status=$lt_dlunknown+  cat > conftest.$ac_ext <<_LT_EOF+#line $LINENO "configure"+#include "confdefs.h"++#if HAVE_DLFCN_H+#include <dlfcn.h>+#endif++#include <stdio.h>++#ifdef RTLD_GLOBAL+#  define LT_DLGLOBAL		RTLD_GLOBAL+#else+#  ifdef DL_GLOBAL+#    define LT_DLGLOBAL		DL_GLOBAL+#  else+#    define LT_DLGLOBAL		0+#  endif+#endif++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we+   find out it does not work in some platform. */+#ifndef LT_DLLAZY_OR_NOW+#  ifdef RTLD_LAZY+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY+#  else+#    ifdef DL_LAZY+#      define LT_DLLAZY_OR_NOW		DL_LAZY+#    else+#      ifdef RTLD_NOW+#        define LT_DLLAZY_OR_NOW	RTLD_NOW+#      else+#        ifdef DL_NOW+#          define LT_DLLAZY_OR_NOW	DL_NOW+#        else+#          define LT_DLLAZY_OR_NOW	0+#        endif+#      endif+#    endif+#  endif+#endif++/* When -fvisibility=hidden is used, assume the code has been annotated+   correspondingly for the symbols needed.  */+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))+int fnord (void) __attribute__((visibility("default")));+#endif++int fnord (void) { return 42; }+int main (void)+{+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);+  int status = $lt_dlunknown;++  if (self)+    {+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;+      else+        {+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;+          else puts (dlerror ());+	}+      /* dlclose (self); */+    }+  else+    puts (dlerror ());++  return status;+}+_LT_EOF+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5+  (eval $ac_link) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then+    (./conftest; exit; ) >&5 2>/dev/null+    lt_status=$?+    case x$lt_status in+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;+    esac+  else :+    # compilation failed+    lt_cv_dlopen_self_static=no+  fi+fi+rm -fr conftest*++       ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5+printf "%s\n" "$lt_cv_dlopen_self_static" >&6; }+    fi++    CPPFLAGS=$save_CPPFLAGS+    LDFLAGS=$save_LDFLAGS+    LIBS=$save_LIBS+    ;;+  esac++  case $lt_cv_dlopen_self in+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;+  *) enable_dlopen_self=unknown ;;+  esac++  case $lt_cv_dlopen_self_static in+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;+  *) enable_dlopen_self_static=unknown ;;+  esac+fi++++++++++++++++++striplib=+old_striplib=+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5+printf %s "checking whether stripping libraries is possible... " >&6; }+if test -z "$STRIP"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+else+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then+    old_striplib="$STRIP --strip-debug"+    striplib="$STRIP --strip-unneeded"+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; }+  else+    case $host_os in+    darwin*)+      # FIXME - insert some real tests, host_os isn't really good enough+      striplib="$STRIP -x"+      old_striplib="$STRIP -S"+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; }+      ;;+    freebsd*)+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then+        old_striplib="$STRIP --strip-debug"+        striplib="$STRIP --strip-unneeded"+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5+printf "%s\n" "yes" >&6; }+      else+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+      fi+      ;;+    *)+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+      ;;+    esac+  fi+fi+++++++++++++  # Report what library types will actually be built+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5+printf %s "checking if libtool supports shared libraries... " >&6; }+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5+printf "%s\n" "$can_build_shared" >&6; }++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5+printf %s "checking whether to build shared libraries... " >&6; }+  test no = "$can_build_shared" && enable_shared=no++  # On AIX, shared libraries and static libraries use the same namespace, and+  # are all built from PIC.+  case $host_os in+  aix3*)+    test yes = "$enable_shared" && enable_static=no+    if test -n "$RANLIB"; then+      archive_cmds="$archive_cmds~\$RANLIB \$lib"+      postinstall_cmds='$RANLIB $lib'+    fi+    ;;++  aix[4-9]*)+    if test ia64 != "$host_cpu"; then+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in+      yes,aix,yes) ;;			# shared object as lib.so file only+      yes,svr4,*) ;;			# shared object as lib.so archive member only+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well+      esac+    fi+    ;;+  esac+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5+printf "%s\n" "$enable_shared" >&6; }++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5+printf %s "checking whether to build static libraries... " >&6; }+  # Make sure either enable_shared or enable_static is yes.+  test yes = "$enable_shared" || enable_static=yes+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5+printf "%s\n" "$enable_static" >&6; }+++++fi+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++CC=$lt_save_CC++      if test -n "$CXX" && ( test no != "$CXX" &&+    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||+    (test g++ != "$CXX"))); then+  ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5+printf %s "checking how to run the C++ preprocessor... " >&6; }+if test -z "$CXXCPP"; then+  if test ${ac_cv_prog_CXXCPP+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)     # Double quotes because $CXX needs to be expanded+    for CXXCPP in "$CXX -E" cpp /lib/cpp+    do+      ac_preproc_ok=false+for ac_cxx_preproc_warn_flag in '' yes+do+  # Use a header file that comes with gcc, so configuring glibc+  # with a fresh cross-compiler works.+  # On the NeXT, cc -E runs the code through the compiler's parser,+  # not just through cpp. "Syntax error" is here to catch this case.+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <limits.h>+		     Syntax error+_ACEOF+if ac_fn_cxx_try_cpp "$LINENO"+then :++else case e in #(+  e) # Broken: fails on valid input.+continue ;;+esac+fi+rm -f conftest.err conftest.i conftest.$ac_ext++  # OK, works on sane cases.  Now check whether nonexistent headers+  # can be detected and how.+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <ac_nonexistent.h>+_ACEOF+if ac_fn_cxx_try_cpp "$LINENO"+then :+  # Broken: success on invalid input.+continue+else case e in #(+  e) # Passes both tests.+ac_preproc_ok=:+break ;;+esac+fi+rm -f conftest.err conftest.i conftest.$ac_ext++done+# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped.+rm -f conftest.i conftest.err conftest.$ac_ext+if $ac_preproc_ok+then :+  break+fi++    done+    ac_cv_prog_CXXCPP=$CXXCPP+   ;;+esac+fi+  CXXCPP=$ac_cv_prog_CXXCPP+else+  ac_cv_prog_CXXCPP=$CXXCPP+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5+printf "%s\n" "$CXXCPP" >&6; }+ac_preproc_ok=false+for ac_cxx_preproc_warn_flag in '' yes+do+  # Use a header file that comes with gcc, so configuring glibc+  # with a fresh cross-compiler works.+  # On the NeXT, cc -E runs the code through the compiler's parser,+  # not just through cpp. "Syntax error" is here to catch this case.+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <limits.h>+		     Syntax error+_ACEOF+if ac_fn_cxx_try_cpp "$LINENO"+then :++else case e in #(+  e) # Broken: fails on valid input.+continue ;;+esac+fi+rm -f conftest.err conftest.i conftest.$ac_ext++  # OK, works on sane cases.  Now check whether nonexistent headers+  # can be detected and how.+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <ac_nonexistent.h>+_ACEOF+if ac_fn_cxx_try_cpp "$LINENO"+then :+  # Broken: success on invalid input.+continue+else case e in #(+  e) # Passes both tests.+ac_preproc_ok=:+break ;;+esac+fi+rm -f conftest.err conftest.i conftest.$ac_ext++done+# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped.+rm -f conftest.i conftest.err conftest.$ac_ext+if $ac_preproc_ok+then :++else case e in #(+  e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check+See 'config.log' for more details" "$LINENO" 5; } ;;+esac+fi++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++else+  _lt_caught_CXX_error=yes+fi++ac_ext=cpp+ac_cpp='$CXXCPP $CPPFLAGS'+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu++archive_cmds_need_lc_CXX=no+allow_undefined_flag_CXX=+always_export_symbols_CXX=no+archive_expsym_cmds_CXX=+compiler_needs_object_CXX=no+export_dynamic_flag_spec_CXX=+hardcode_direct_CXX=no+hardcode_direct_absolute_CXX=no+hardcode_libdir_flag_spec_CXX=+hardcode_libdir_separator_CXX=+hardcode_minus_L_CXX=no+hardcode_shlibpath_var_CXX=unsupported+hardcode_automatic_CXX=no+inherit_rpath_CXX=no+module_cmds_CXX=+module_expsym_cmds_CXX=+link_all_deplibs_CXX=unknown+old_archive_cmds_CXX=$old_archive_cmds+reload_flag_CXX=$reload_flag+reload_cmds_CXX=$reload_cmds+no_undefined_flag_CXX=+whole_archive_flag_spec_CXX=+enable_shared_with_static_runtimes_CXX=no++# Source file extension for C++ test sources.+ac_ext=cpp++# Object file extension for compiled C++ test sources.+objext=o+objext_CXX=$objext++# No sense in running all these tests if we already determined that+# the CXX compiler isn't working.  Some variables (like enable_shared)+# are currently assumed to apply to all compilers on this platform,+# and will be corrupted by setting them based on a non-working compiler.+if test yes != "$_lt_caught_CXX_error"; then+  # Code to be used in simple compile tests+  lt_simple_compile_test_code="int some_variable = 0;"++  # Code to be used in simple link tests+  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'++  # ltmain only uses $CC for tagged configurations so make sure $CC is set.+++++++# If no C compiler was specified, use CC.+LTCC=${LTCC-"$CC"}++# If no C compiler flags were specified, use CFLAGS.+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}++# Allow CC to be a program name with arguments.+compiler=$CC+++  # save warnings/boilerplate of simple test code+  ac_outfile=conftest.$ac_objext+echo "$lt_simple_compile_test_code" >conftest.$ac_ext+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err+_lt_compiler_boilerplate=`cat conftest.err`+$RM conftest*++  ac_outfile=conftest.$ac_objext+echo "$lt_simple_link_test_code" >conftest.$ac_ext+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err+_lt_linker_boilerplate=`cat conftest.err`+$RM -r conftest*+++  # Allow CC to be a program name with arguments.+  lt_save_CC=$CC+  lt_save_CFLAGS=$CFLAGS+  lt_save_LD=$LD+  lt_save_GCC=$GCC+  GCC=$GXX+  lt_save_with_gnu_ld=$with_gnu_ld+  lt_save_path_LD=$lt_cv_path_LD+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx+  else+    $as_unset lt_cv_prog_gnu_ld+  fi+  if test -n "${lt_cv_path_LDCXX+set}"; then+    lt_cv_path_LD=$lt_cv_path_LDCXX+  else+    $as_unset lt_cv_path_LD+  fi+  test -z "${LDCXX+set}" || LD=$LDCXX+  CC=${CXX-"c++"}+  CFLAGS=$CXXFLAGS+  compiler=$CC+  compiler_CXX=$CC+  func_cc_basename $compiler+cc_basename=$func_cc_basename_result+++  if test -n "$compiler"; then+    # We don't want -fno-exception when compiling C++ code, so set the+    # no_builtin_flag separately+    if test yes = "$GXX"; then+      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'+    else+      lt_prog_compiler_no_builtin_flag_CXX=+    fi++    if test yes = "$GXX"; then+      # Set up default GNU C++ configuration++++# Check whether --with-gnu-ld was given.+if test ${with_gnu_ld+y}+then :+  withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes+else case e in #(+  e) with_gnu_ld=no ;;+esac+fi++ac_prog=ld+if test yes = "$GCC"; then+  # Check if gcc -print-prog-name=ld gives a path.+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5+printf %s "checking for ld used by $CC... " >&6; }+  case $host in+  *-*-mingw* | *-*-windows*)+    # gcc leaves a trailing carriage return, which upsets mingw+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;+  *)+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;+  esac+  case $ac_prog in+    # Accept absolute paths.+    [\\/]* | ?:[\\/]*)+      re_direlt='/[^/][^/]*/\.\./'+      # Canonicalize the pathname of ld+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`+      done+      test -z "$LD" && LD=$ac_prog+      ;;+  "")+    # If it fails, then pretend we aren't using GCC.+    ac_prog=ld+    ;;+  *)+    # If it is relative, then search for the first ld in PATH.+    with_gnu_ld=unknown+    ;;+  esac+elif test yes = "$with_gnu_ld"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5+printf %s "checking for GNU ld... " >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5+printf %s "checking for non-GNU ld... " >&6; }+fi+if test ${lt_cv_path_LD+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test -z "$LD"; then+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+  for ac_dir in $PATH; do+    IFS=$lt_save_ifs+    test -z "$ac_dir" && ac_dir=.+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then+      lt_cv_path_LD=$ac_dir/$ac_prog+      # Check to see if the program is GNU ld.  I'd rather use --version,+      # but apparently some variants of GNU ld only accept -v.+      # Break only if it was the GNU/non-GNU ld that we prefer.+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in+      *GNU* | *'with BFD'*)+	test no != "$with_gnu_ld" && break+	;;+      *)+	test yes != "$with_gnu_ld" && break+	;;+      esac+    fi+  done+  IFS=$lt_save_ifs+else+  lt_cv_path_LD=$LD # Let the user override the test with a path.+fi ;;+esac+fi++LD=$lt_cv_path_LD+if test -n "$LD"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5+printf "%s\n" "$LD" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5+printf %s "checking if the linker ($LD) is GNU ld... " >&6; }+if test ${lt_cv_prog_gnu_ld+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) # I'd rather use --version here, but apparently some GNU lds only accept -v.+case `$LD -v 2>&1 </dev/null` in+*GNU* | *'with BFD'*)+  lt_cv_prog_gnu_ld=yes+  ;;+*)+  lt_cv_prog_gnu_ld=no+  ;;+esac ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5+printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; }+with_gnu_ld=$lt_cv_prog_gnu_ld++++++++      # Check if GNU C++ uses GNU ld as the underlying linker, since the+      # archiving commands below assume that GNU ld is being used.+      if test yes = "$with_gnu_ld"; then+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'++        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'+        export_dynamic_flag_spec_CXX='$wl--export-dynamic'++        # If archive_cmds runs LD, not CC, wlarc should be empty+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to+        #     investigate it a little bit more. (MM)+        wlarc='$wl'++        # ancient GNU ld didn't support --whole-archive et. al.+        if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then+          whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'+        else+          whole_archive_flag_spec_CXX=+        fi+      else+        with_gnu_ld=no+        wlarc=++        # A generic and very simple default shared library creation+        # command for GNU C++ for the case where it uses the native+        # linker, instead of GNU ld.  If possible, this setting should+        # overridden to take advantage of the native linker features on+        # the platform it is being used on.+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'+      fi++      # Commands to make compiler produce verbose output that lists+      # what "hidden" libraries, object files and flags are used when+      # linking a shared library.+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"'++    else+      GXX=no+      with_gnu_ld=no+      wlarc=+    fi++    # PORTME: fill in a description of your system's C++ link characteristics+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5+printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }+    ld_shlibs_CXX=yes+    case $host_os in+      aix3*)+        # FIXME: insert proper C++ library support+        ld_shlibs_CXX=no+        ;;+      aix[4-9]*)+        if test ia64 = "$host_cpu"; then+          # On IA64, the linker does run time linking by default, so we don't+          # have to do anything special.+          aix_use_runtimelinking=no+          exp_sym_flag='-Bexport'+          no_entry_flag=+        else+          aix_use_runtimelinking=no++          # Test if we are trying to use run time linking or normal+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we+          # have runtime linking enabled, and use it for executables.+          # For shared libraries, we enable/disable runtime linking+          # depending on the kind of the shared library created -+          # when "with_aix_soname,aix_use_runtimelinking" is:+          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables+          # "aix,yes"  lib.so          shared, rtl:yes, for executables+          #            lib.a           static archive+          # "both,no"  lib.so.V(shr.o) shared, rtl:yes+          #            lib.a(lib.so.V) shared, rtl:no,  for executables+          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables+          #            lib.a(lib.so.V) shared, rtl:no+          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables+          #            lib.a           static archive+          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)+	    for ld_flag in $LDFLAGS; do+	      case $ld_flag in+	      *-brtl*)+	        aix_use_runtimelinking=yes+	        break+	        ;;+	      esac+	    done+	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then+	      # With aix-soname=svr4, we create the lib.so.V shared archives only,+	      # so we don't have lib.a shared libs to link our executables.+	      # We have to force runtime linking in this case.+	      aix_use_runtimelinking=yes+	      LDFLAGS="$LDFLAGS -Wl,-brtl"+	    fi+	    ;;+          esac++          exp_sym_flag='-bexport'+          no_entry_flag='-bnoentry'+        fi++        # When large executables or shared objects are built, AIX ld can+        # have problems creating the table of contents.  If linking a library+        # or program results in "error TOC overflow" add -mminimal-toc to+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.++        archive_cmds_CXX=''+        hardcode_direct_CXX=yes+        hardcode_direct_absolute_CXX=yes+        hardcode_libdir_separator_CXX=':'+        link_all_deplibs_CXX=yes+        file_list_spec_CXX='$wl-f,'+        case $with_aix_soname,$aix_use_runtimelinking in+        aix,*) ;;	# no import file+        svr4,* | *,yes) # use import file+          # The Import File defines what to hardcode.+          hardcode_direct_CXX=no+          hardcode_direct_absolute_CXX=no+          ;;+        esac++        if test yes = "$GXX"; then+          case $host_os in aix4.[012]|aix4.[012].*)+          # We only want to do this on AIX 4.2 and lower, the check+          # below for broken collect2 doesn't work under 4.3++	  collect2name=`$CC -print-prog-name=collect2`+	  if test -f "$collect2name" &&+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null+	  then+	    # We have reworked collect2+	    :+	  else+	    # We have old collect2+	    hardcode_direct_CXX=unsupported+	    # It fails to find uninstalled libraries when the uninstalled+	    # path is not listed in the libpath.  Setting hardcode_minus_L+	    # to unsupported forces relinking+	    hardcode_minus_L_CXX=yes+	    hardcode_libdir_flag_spec_CXX='-L$libdir'+	    hardcode_libdir_separator_CXX=+	  fi+          esac+          shared_flag='-shared'+	  if test yes = "$aix_use_runtimelinking"; then+	    shared_flag=$shared_flag' $wl-G'+	  fi+	  # Need to ensure runtime linking is disabled for the traditional+	  # shared library, or the linker may eventually find shared libraries+	  # /with/ Import File - we do not want to mix them.+	  shared_flag_aix='-shared'+	  shared_flag_svr4='-shared $wl-G'+        else+          # not using gcc+          if test ia64 = "$host_cpu"; then+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release+	  # chokes on -Wl,-G. The following line is correct:+	  shared_flag='-G'+          else+	    if test yes = "$aix_use_runtimelinking"; then+	      shared_flag='$wl-G'+	    else+	      shared_flag='$wl-bM:SRE'+	    fi+	    shared_flag_aix='$wl-bM:SRE'+	    shared_flag_svr4='$wl-G'+          fi+        fi++        export_dynamic_flag_spec_CXX='$wl-bexpall'+        # It seems that -bexpall does not export symbols beginning with+        # underscore (_), so it is better to generate a list of symbols to+	# export.+        always_export_symbols_CXX=yes+	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then+          # Warning - without using the other runtime loading flags (-brtl),+          # -berok will link without error, but may produce a broken library.+          # The "-G" linker flag allows undefined symbols.+          no_undefined_flag_CXX='-bernotok'+          # Determine the default libpath from the value encoded in an empty+          # executable.+          if test set = "${lt_cv_aix_libpath+set}"; then+  aix_libpath=$lt_cv_aix_libpath+else+  if test ${lt_cv_aix_libpath__CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_link "$LINENO"+then :++  lt_aix_libpath_sed='+      /Import File Strings/,/^$/ {+	  /^0/ {+	      s/^0  *\([^ ]*\) *$/\1/+	      p+	  }+      }'+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  # Check for a 64-bit object if we didn't find anything.+  if test -z "$lt_cv_aix_libpath__CXX"; then+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+  if test -z "$lt_cv_aix_libpath__CXX"; then+    lt_cv_aix_libpath__CXX=/usr/lib:/lib+  fi+   ;;+esac+fi++  aix_libpath=$lt_cv_aix_libpath__CXX+fi++          hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"++          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag+        else+          if test ia64 = "$host_cpu"; then+	    hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib'+	    allow_undefined_flag_CXX="-z nodefs"+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"+          else+	    # Determine the default libpath from the value encoded in an+	    # empty executable.+	    if test set = "${lt_cv_aix_libpath+set}"; then+  aix_libpath=$lt_cv_aix_libpath+else+  if test ${lt_cv_aix_libpath__CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_link "$LINENO"+then :++  lt_aix_libpath_sed='+      /Import File Strings/,/^$/ {+	  /^0/ {+	      s/^0  *\([^ ]*\) *$/\1/+	      p+	  }+      }'+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  # Check for a 64-bit object if we didn't find anything.+  if test -z "$lt_cv_aix_libpath__CXX"; then+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+  if test -z "$lt_cv_aix_libpath__CXX"; then+    lt_cv_aix_libpath__CXX=/usr/lib:/lib+  fi+   ;;+esac+fi++  aix_libpath=$lt_cv_aix_libpath__CXX+fi++	    hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath"+	    # Warning - without using the other run time loading flags,+	    # -berok will link without error, but may produce a broken library.+	    no_undefined_flag_CXX=' $wl-bernotok'+	    allow_undefined_flag_CXX=' $wl-berok'+	    if test yes = "$with_gnu_ld"; then+	      # We only use this code for GNU lds that support --whole-archive.+	      whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'+	    else+	      # Exported symbols can be pulled into shared objects from archives+	      whole_archive_flag_spec_CXX='$convenience'+	    fi+	    archive_cmds_need_lc_CXX=yes+	    archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'+	    # -brtl affects multiple linker settings, -berok does not and is overridden later+	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'+	    if test svr4 != "$with_aix_soname"; then+	      # This is similar to how AIX traditionally builds its shared+	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.+	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'+	    fi+	    if test aix != "$with_aix_soname"; then+	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'+	    else+	      # used by -dlpreopen to get the symbols+	      archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'+	    fi+	    archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d'+          fi+        fi+        ;;++      beos*)+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	  allow_undefined_flag_CXX=unsupported+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc+	  # support --undefined.  This deserves some investigation.  FIXME+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	else+	  ld_shlibs_CXX=no+	fi+	;;++      chorus*)+        case $cc_basename in+          *)+	  # FIXME: insert proper C++ library support+	  ld_shlibs_CXX=no+	  ;;+        esac+        ;;++      cygwin* | mingw* | windows* | pw32* | cegcc*)+	case $GXX,$cc_basename in+	,cl* | no,cl* | ,icl* | no,icl*)+	  # Native MSVC or ICC+	  # hardcode_libdir_flag_spec is actually meaningless, as there is+	  # no search path for DLLs.+	  hardcode_libdir_flag_spec_CXX=' '+	  allow_undefined_flag_CXX=unsupported+	  always_export_symbols_CXX=yes+	  file_list_spec_CXX='@'+	  # Tell ltmain to make .lib files, not .a files.+	  libext=lib+	  # Tell ltmain to make .dll files, not .so files.+	  shrext_cmds=.dll+	  # FIXME: Setting linknames here is a bad hack.+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='+	  archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then+              cp "$export_symbols" "$output_objdir/$soname.def";+              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";+            else+              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;+            fi~+            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~+            linknames='+	  # The linker will not automatically build a static lib if we build a DLL.+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'+	  enable_shared_with_static_runtimes_CXX=yes+	  # Don't use ranlib+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~+            lt_tool_outputfile="@TOOL_OUTPUT@"~+            case $lt_outputfile in+              *.exe|*.EXE) ;;+              *)+                lt_outputfile=$lt_outputfile.exe+                lt_tool_outputfile=$lt_tool_outputfile.exe+                ;;+            esac~+            func_to_tool_file "$lt_outputfile"~+            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then+              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;+              $RM "$lt_outputfile.manifest";+            fi'+	  ;;+	*)+	  # g+++	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,+	  # as there is no search path for DLLs.+	  hardcode_libdir_flag_spec_CXX='-L$libdir'+	  export_dynamic_flag_spec_CXX='$wl--export-all-symbols'+	  allow_undefined_flag_CXX=unsupported+	  always_export_symbols_CXX=no+	  enable_shared_with_static_runtimes_CXX=yes+	  file_list_spec_CXX='@'++	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+	    # If the export-symbols file already is a .def file, use it as+	    # is; otherwise, prepend EXPORTS...+	    archive_expsym_cmds_CXX='if   test DEF = "`$SED -n     -e '\''s/^[	 ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then+              cp $export_symbols $output_objdir/$soname.def;+            else+              echo EXPORTS > $output_objdir/$soname.def;+              cat $export_symbols >> $output_objdir/$soname.def;+            fi~+            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+	  else+	    ld_shlibs_CXX=no+	  fi+	  ;;+	esac+	;;+      darwin* | rhapsody*)+++  archive_cmds_need_lc_CXX=no+  hardcode_direct_CXX=no+  hardcode_automatic_CXX=yes+  hardcode_shlibpath_var_CXX=unsupported+  if test yes = "$lt_cv_ld_force_load"; then+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'++  else+    whole_archive_flag_spec_CXX=''+  fi+  link_all_deplibs_CXX=yes+  allow_undefined_flag_CXX=$_lt_dar_allow_undefined+  case $cc_basename in+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;+     *) _lt_dar_can_shared=$GCC ;;+  esac+  if test yes = "$_lt_dar_can_shared"; then+    output_verbose_link_cmd=func_echo_all+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"+    archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"+    module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"+       if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"+      archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"+    fi++  else+  ld_shlibs_CXX=no+  fi++	;;++      os2*)+	hardcode_libdir_flag_spec_CXX='-L$libdir'+	hardcode_minus_L_CXX=yes+	allow_undefined_flag_CXX=unsupported+	shrext_cmds=.dll+	archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	  $ECHO EXPORTS >> $output_objdir/$libname.def~+	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	  emximp -o $lib $output_objdir/$libname.def'+	archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	  $ECHO EXPORTS >> $output_objdir/$libname.def~+	  prefix_cmds="$SED"~+	  if test EXPORTS = "`$SED 1q $export_symbols`"; then+	    prefix_cmds="$prefix_cmds -e 1d";+	  fi~+	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~+	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	  emximp -o $lib $output_objdir/$libname.def'+	old_archive_from_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'+	enable_shared_with_static_runtimes_CXX=yes+	file_list_spec_CXX='@'+	;;++      dgux*)+        case $cc_basename in+          ec++*)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          ghcx*)+	    # Green Hills C++ Compiler+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          *)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+        esac+        ;;++      freebsd2.*)+        # C++ shared libraries reported to be fairly broken before+	# switch to ELF+        ld_shlibs_CXX=no+        ;;++      freebsd-elf*)+        archive_cmds_need_lc_CXX=no+        ;;++      freebsd* | dragonfly* | midnightbsd*)+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF+        # conventions+        ld_shlibs_CXX=yes+        ;;++      haiku*)+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+        link_all_deplibs_CXX=no+        ;;++      hpux9*)+        hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'+        hardcode_libdir_separator_CXX=:+        export_dynamic_flag_spec_CXX='$wl-E'+        hardcode_direct_CXX=yes+        hardcode_minus_L_CXX=yes # Not in the search PATH,+				             # but as the default+				             # location of the library.++        case $cc_basename in+          CC*)+            # FIXME: insert proper C++ library support+            ld_shlibs_CXX=no+            ;;+          aCC*)+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+            # Commands to make compiler produce verbose output that lists+            # what "hidden" libraries, object files and flags are used when+            # linking a shared library.+            #+            # There doesn't appear to be a way to prevent this compiler from+            # explicitly linking system object files so we need to strip them+            # from the output so that they don't get included in the library+            # dependencies.+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[-]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'+            ;;+          *)+            if test yes = "$GXX"; then+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+            else+              # FIXME: insert proper C++ library support+              ld_shlibs_CXX=no+            fi+            ;;+        esac+        ;;++      hpux10*|hpux11*)+        if test no = "$with_gnu_ld"; then+	  hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir'+	  hardcode_libdir_separator_CXX=:++          case $host_cpu in+            hppa*64*|ia64*)+              ;;+            *)+	      export_dynamic_flag_spec_CXX='$wl-E'+              ;;+          esac+        fi+        case $host_cpu in+          hppa*64*|ia64*)+            hardcode_direct_CXX=no+            hardcode_shlibpath_var_CXX=no+            ;;+          *)+            hardcode_direct_CXX=yes+            hardcode_direct_absolute_CXX=yes+            hardcode_minus_L_CXX=yes # Not in the search PATH,+					         # but as the default+					         # location of the library.+            ;;+        esac++        case $cc_basename in+          CC*)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          aCC*)+	    case $host_cpu in+	      hppa*64*)+	        archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	        ;;+	      ia64*)+	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	        ;;+	      *)+	        archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	        ;;+	    esac+	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [-]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'+	    ;;+          *)+	    if test yes = "$GXX"; then+	      if test no = "$with_gnu_ld"; then+	        case $host_cpu in+	          hppa*64*)+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	            ;;+	          ia64*)+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	            ;;+	          *)+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	            ;;+	        esac+	      fi+	    else+	      # FIXME: insert proper C++ library support+	      ld_shlibs_CXX=no+	    fi+	    ;;+        esac+        ;;++      interix[3-9]*)+	hardcode_direct_CXX=no+	hardcode_shlibpath_var_CXX=no+	hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'+	export_dynamic_flag_spec_CXX='$wl-E'+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.+	# Instead, shared libraries are loaded at an image base (0x10000000 by+	# default) and relocated if they conflict, which is a slow very memory+	# consuming and fragmenting process.  To avoid this, we pick a random,+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+	archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+	;;+      irix5* | irix6*)+        case $cc_basename in+          CC*)+	    # SGI C+++	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'++	    # Archives containing C++ object files must be created using+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is+	    # necessary to make sure instantiated templates are included+	    # in the archive.+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'+	    ;;+          *)+	    if test yes = "$GXX"; then+	      if test no = "$with_gnu_ld"; then+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+	      else+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'+	      fi+	    fi+	    link_all_deplibs_CXX=yes+	    ;;+        esac+        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'+        hardcode_libdir_separator_CXX=:+        inherit_rpath_CXX=yes+        ;;++      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+        case $cc_basename in+          KCC*)+	    # Kuck and Associates, Inc. (KAI) C++ Compiler++	    # KCC will only create a shared library if the output file+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library+	    # to its proper name (with version) after linking.+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'+	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'++	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'+	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'++	    # Archives containing C++ object files must be created using+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.+	    old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'+	    ;;+	  icpc* | ecpc* )+	    # Intel C+++	    with_gnu_ld=yes+	    # version 8.0 and above of icpc choke on multiply defined symbols+	    # if we add $predep_objects and $postdep_objects, however 7.1 and+	    # earlier do not add the objects themselves.+	    case `$CC -V 2>&1` in+	      *"Version 7."*)+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+		;;+	      *)  # Version 8.0 or newer+	        tmp_idyn=+	        case $host_cpu in+		  ia64*) tmp_idyn=' -i_dynamic';;+		esac+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+		;;+	    esac+	    archive_cmds_need_lc_CXX=no+	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'+	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'+	    whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive'+	    ;;+          pgCC* | pgcpp*)+            # Portland Group C++ compiler+	    case `$CC -V` in+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)+	      prelink_cmds_CXX='tpldir=Template.dir~+               rm -rf $tpldir~+               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~+               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'+	      old_archive_cmds_CXX='tpldir=Template.dir~+                rm -rf $tpldir~+                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~+                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~+                $RANLIB $oldlib'+	      archive_cmds_CXX='tpldir=Template.dir~+                rm -rf $tpldir~+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+	      archive_expsym_cmds_CXX='tpldir=Template.dir~+                rm -rf $tpldir~+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+	      ;;+	    *) # Version 6 and above use weak symbols+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+	      ;;+	    esac++	    hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir'+	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'+	    whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+            ;;+	  cxx*)+	    # Compaq C+++	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'++	    runpath_var=LD_RUN_PATH+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'+	    hardcode_libdir_separator_CXX=:++	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'+	    ;;+	  xl* | mpixl* | bgxl*)+	    # IBM XL 8.0 on PPC, with GNU ld+	    hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'+	    export_dynamic_flag_spec_CXX='$wl--export-dynamic'+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	    if test yes = "$supports_anon_versioning"; then+	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~+                cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~+                echo "local: *; };" >> $output_objdir/$libname.ver~+                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'+	    fi+	    ;;+	  *)+	    case `$CC -V 2>&1 | $SED 5q` in+	    *Sun\ C*)+	      # Sun C++ 5.9+	      no_undefined_flag_CXX=' -zdefs'+	      archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	      archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'+	      hardcode_libdir_flag_spec_CXX='-R$libdir'+	      whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	      compiler_needs_object_CXX=yes++	      # Not sure whether something based on+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1+	      # would be better.+	      output_verbose_link_cmd='func_echo_all'++	      # Archives containing C++ object files must be created using+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is+	      # necessary to make sure instantiated templates are included+	      # in the archive.+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'+	      ;;+	    esac+	    ;;+	esac+	;;++      lynxos*)+        # FIXME: insert proper C++ library support+	ld_shlibs_CXX=no+	;;++      m88k*)+        # FIXME: insert proper C++ library support+        ld_shlibs_CXX=no+	;;++      mvs*)+        case $cc_basename in+          cxx*)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+	  *)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+	esac+	;;++      *-mlibc)+        ld_shlibs_CXX=yes+	;;++      netbsd*)+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'+	  wlarc=+	  hardcode_libdir_flag_spec_CXX='-R$libdir'+	  hardcode_direct_CXX=yes+	  hardcode_shlibpath_var_CXX=no+	fi+	# Workaround some broken pre-1.5 toolchains+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'+	;;++      *nto* | *qnx*)+        ld_shlibs_CXX=yes+	;;++      openbsd*)+	if test -f /usr/libexec/ld.so; then+	  hardcode_direct_CXX=yes+	  hardcode_shlibpath_var_CXX=no+	  hardcode_direct_absolute_CXX=yes+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'+	  hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'+	    export_dynamic_flag_spec_CXX='$wl-E'+	    whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'+	  fi+	  output_verbose_link_cmd=func_echo_all+	else+	  ld_shlibs_CXX=no+	fi+	;;++      osf3* | osf4* | osf5*)+        case $cc_basename in+          KCC*)+	    # Kuck and Associates, Inc. (KAI) C++ Compiler++	    # KCC will only create a shared library if the output file+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library+	    # to its proper name (with version) after linking.+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'++	    hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir'+	    hardcode_libdir_separator_CXX=:++	    # Archives containing C++ object files must be created using+	    # the KAI C++ compiler.+	    case $host in+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;+	    esac+	    ;;+          RCC*)+	    # Rational C++ 2.4.1+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          cxx*)+	    case $host in+	      osf3*)+	        allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'+	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	        hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'+		;;+	      *)+	        allow_undefined_flag_CXX=' -expect_unresolved \*'+	        archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~+                  echo "-hidden">> $lib.exp~+                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~+                  $RM $lib.exp'+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'+		;;+	    esac++	    hardcode_libdir_separator_CXX=:++	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'+	    ;;+	  *)+	    if test yes,no = "$GXX,$with_gnu_ld"; then+	      allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*'+	      case $host in+	        osf3*)+	          archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+		  ;;+	        *)+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+		  ;;+	      esac++	      hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'+	      hardcode_libdir_separator_CXX=:++	      # Commands to make compiler produce verbose output that lists+	      # what "hidden" libraries, object files and flags are used when+	      # linking a shared library.+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"'++	    else+	      # FIXME: insert proper C++ library support+	      ld_shlibs_CXX=no+	    fi+	    ;;+        esac+        ;;++      psos*)+        # FIXME: insert proper C++ library support+        ld_shlibs_CXX=no+        ;;++      serenity*)+        ;;++      sunos4*)+        case $cc_basename in+          CC*)+	    # Sun C++ 4.x+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          lcc*)+	    # Lucid+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          *)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+        esac+        ;;++      solaris*)+        case $cc_basename in+          CC* | sunCC*)+	    # Sun C++ 4.2, 5.x and Centerline C+++            archive_cmds_need_lc_CXX=yes+	    no_undefined_flag_CXX=' -zdefs'+	    archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'++	    hardcode_libdir_flag_spec_CXX='-R$libdir'+	    hardcode_shlibpath_var_CXX=no+	    case $host_os in+	      solaris2.[0-5] | solaris2.[0-5].*) ;;+	      *)+		# The compiler driver will combine and reorder linker options,+		# but understands '-z linker_flag'.+	        # Supported since Solaris 2.6 (maybe 2.5.1?)+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'+	        ;;+	    esac+	    link_all_deplibs_CXX=yes++	    output_verbose_link_cmd='func_echo_all'++	    # Archives containing C++ object files must be created using+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is+	    # necessary to make sure instantiated templates are included+	    # in the archive.+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'+	    ;;+          gcx*)+	    # Green Hills C++ Compiler+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'++	    # The C++ compiler must be used to create the archive.+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'+	    ;;+          *)+	    # GNU C++ compiler with Solaris linker+	    if test yes,no = "$GXX,$with_gnu_ld"; then+	      no_undefined_flag_CXX=' $wl-z ${wl}defs'+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'++	        # Commands to make compiler produce verbose output that lists+	        # what "hidden" libraries, object files and flags are used when+	        # linking a shared library.+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"'+	      else+	        # g++ 2.7 appears to require '-G' NOT '-shared' on this+	        # platform.+	        archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'++	        # Commands to make compiler produce verbose output that lists+	        # what "hidden" libraries, object files and flags are used when+	        # linking a shared library.+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [-]L"'+	      fi++	      hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'+	      case $host_os in+		solaris2.[0-5] | solaris2.[0-5].*) ;;+		*)+		  whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'+		  ;;+	      esac+	    fi+	    ;;+        esac+        ;;++    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)+      no_undefined_flag_CXX='$wl-z,text'+      archive_cmds_need_lc_CXX=no+      hardcode_shlibpath_var_CXX=no+      runpath_var='LD_RUN_PATH'++      case $cc_basename in+        CC*)+	  archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	*)+	  archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+      esac+      ;;++      sysv5* | sco3.2v5* | sco5v6*)+	# Note: We CANNOT use -z defs as we might desire, because we do not+	# link with -lc, and that would cause any symbols used from libc to+	# always be unresolved, which means just about no library would+	# ever link correctly.  If we're not using GNU ld we use -z text+	# though, which does catch some bad symbols but isn't as heavy-handed+	# as -z defs.+	no_undefined_flag_CXX='$wl-z,text'+	allow_undefined_flag_CXX='$wl-z,nodefs'+	archive_cmds_need_lc_CXX=no+	hardcode_shlibpath_var_CXX=no+	hardcode_libdir_flag_spec_CXX='$wl-R,$libdir'+	hardcode_libdir_separator_CXX=':'+	link_all_deplibs_CXX=yes+	export_dynamic_flag_spec_CXX='$wl-Bexport'+	runpath_var='LD_RUN_PATH'++	case $cc_basename in+          CC*)+	    archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~+              '"$old_archive_cmds_CXX"+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~+              '"$reload_cmds_CXX"+	    ;;+	  *)+	    archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    ;;+	esac+      ;;++      tandem*)+        case $cc_basename in+          NCC*)+	    # NonStop-UX NCC 3.20+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+          *)+	    # FIXME: insert proper C++ library support+	    ld_shlibs_CXX=no+	    ;;+        esac+        ;;++      vxworks*)+        # FIXME: insert proper C++ library support+        ld_shlibs_CXX=no+        ;;++      *)+        # FIXME: insert proper C++ library support+        ld_shlibs_CXX=no+        ;;+    esac++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5+printf "%s\n" "$ld_shlibs_CXX" >&6; }+    test no = "$ld_shlibs_CXX" && can_build_shared=no++    GCC_CXX=$GXX+    LD_CXX=$LD++    ## CAVEAT EMPTOR:+    ## There is no encapsulation within the following macros, do not change+    ## the running order or otherwise move them around unless you know exactly+    ## what you are doing...+    # Dependencies to place before and after the object being linked:+predep_objects_CXX=+postdep_objects_CXX=+predeps_CXX=+postdeps_CXX=+compiler_lib_search_path_CXX=++cat > conftest.$ac_ext <<_LT_EOF+class Foo+{+public:+  Foo (void) { a = 0; }+private:+  int a;+};+_LT_EOF+++_lt_libdeps_save_CFLAGS=$CFLAGS+case "$CC $CFLAGS " in #(+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;+esac++if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+  # Parse the compiler output and extract the necessary+  # objects, libraries and library flags.++  # Sentinel used to keep track of whether or not we are before+  # the conftest object file.+  pre_test_object_deps_done=no++  for p in `eval "$output_verbose_link_cmd"`; do+    case $prev$p in++    -L* | -R* | -l*)+       # Some compilers place space between "-{L,R,l}" and the path.+       # Remove the space.+       if test x-L = x"$p" ||+          test x-R = x"$p" ||+          test x-l = x"$p"; then+	 prev=$p+	 continue+       fi++       # Expand the sysroot to ease extracting the directories later.+       if test -z "$prev"; then+         case $p in+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;+         esac+       fi+       case $p in+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;+       esac+       if test no = "$pre_test_object_deps_done"; then+	 case $prev in+	 -L | -R)+	   # Internal compiler library paths should come after those+	   # provided the user.  The postdeps already come after the+	   # user supplied libs so there is no need to process them.+	   if test -z "$compiler_lib_search_path_CXX"; then+	     compiler_lib_search_path_CXX=$prev$p+	   else+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p"+	   fi+	   ;;+	 # The "-l" case would never come before the object being+	 # linked, so don't bother handling this case.+	 esac+       else+	 if test -z "$postdeps_CXX"; then+	   postdeps_CXX=$prev$p+	 else+	   postdeps_CXX="${postdeps_CXX} $prev$p"+	 fi+       fi+       prev=+       ;;++    *.lto.$objext) ;; # Ignore GCC LTO objects+    *.$objext)+       # This assumes that the test object file only shows up+       # once in the compiler output.+       if test "$p" = "conftest.$objext"; then+	 pre_test_object_deps_done=yes+	 continue+       fi++       if test no = "$pre_test_object_deps_done"; then+	 if test -z "$predep_objects_CXX"; then+	   predep_objects_CXX=$p+	 else+	   predep_objects_CXX="$predep_objects_CXX $p"+	 fi+       else+	 if test -z "$postdep_objects_CXX"; then+	   postdep_objects_CXX=$p+	 else+	   postdep_objects_CXX="$postdep_objects_CXX $p"+	 fi+       fi+       ;;++    *) ;; # Ignore the rest.++    esac+  done++  # Clean up.+  rm -f a.out a.exe+else+  echo "libtool.m4: error: problem compiling CXX test program"+fi++$RM -f confest.$objext+CFLAGS=$_lt_libdeps_save_CFLAGS++# PORTME: override above test on systems where it is broken+case $host_os in+interix[3-9]*)+  # Interix 3.5 installs completely hosed .la files for C++, so rather than+  # hack all around it, let's just trust "g++" to DTRT.+  predep_objects_CXX=+  postdep_objects_CXX=+  postdeps_CXX=+  ;;+esac+++case " $postdeps_CXX " in+*" -lc "*) archive_cmds_need_lc_CXX=no ;;+esac+ compiler_lib_search_dirs_CXX=+if test -n "${compiler_lib_search_path_CXX}"; then+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'`+fi++++++++++++++++++++++++++++++++    lt_prog_compiler_wl_CXX=+lt_prog_compiler_pic_CXX=+lt_prog_compiler_static_CXX=+++  # C++ specific cases for pic, static, wl, etc.+  if test yes = "$GXX"; then+    lt_prog_compiler_wl_CXX='-Wl,'+    lt_prog_compiler_static_CXX='-static'++    case $host_os in+    aix*)+      # All AIX code is PIC.+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	lt_prog_compiler_static_CXX='-Bstatic'+      fi+      lt_prog_compiler_pic_CXX='-fPIC'+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            lt_prog_compiler_pic_CXX='-fPIC'+        ;;+      m68k)+            # FIXME: we need at least 68020 code to build shared libraries, but+            # adding the '-m68020' flag to GCC prevents building anything better,+            # like '-m68040'.+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'+        ;;+      esac+      ;;++    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)+      # PIC is the default for these OSes.+      ;;+    mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      # Although the cygwin gcc ignores -fPIC, still need this for old-style+      # (--disable-auto-import) libraries+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'+      case $host_os in+      os2*)+	lt_prog_compiler_static_CXX='$wl-static'+	;;+      esac+      ;;+    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      lt_prog_compiler_pic_CXX='-fno-common'+      ;;+    *djgpp*)+      # DJGPP does not support shared libraries at all+      lt_prog_compiler_pic_CXX=+      ;;+    haiku*)+      # PIC is the default for Haiku.+      # The "-static" flag exists, but is broken.+      lt_prog_compiler_static_CXX=+      ;;+    interix[3-9]*)+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.+      # Instead, we relocate shared libraries at runtime.+      ;;+    sysv4*MP*)+      if test -d /usr/nec; then+	lt_prog_compiler_pic_CXX=-Kconform_pic+      fi+      ;;+    hpux*)+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag+      # sets the default TLS model and affects inlining.+      case $host_cpu in+      hppa*64*)+	;;+      *)+	lt_prog_compiler_pic_CXX='-fPIC'+	;;+      esac+      ;;+    *qnx* | *nto*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      lt_prog_compiler_pic_CXX='-fPIC -shared'+      ;;+    *)+      lt_prog_compiler_pic_CXX='-fPIC'+      ;;+    esac+  else+    case $host_os in+      aix[4-9]*)+	# All AIX code is PIC.+	if test ia64 = "$host_cpu"; then+	  # AIX 5 now supports IA64 processor+	  lt_prog_compiler_static_CXX='-Bstatic'+	else+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'+	fi+	;;+      chorus*)+	case $cc_basename in+	cxch68*)+	  # Green Hills C++ Compiler+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"+	  ;;+	esac+	;;+      mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)+	# This hack is so that the source file can tell whether it is being+	# built for inclusion in a dll (and should export symbols for example).+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'+	;;+      dgux*)+	case $cc_basename in+	  ec++*)+	    lt_prog_compiler_pic_CXX='-KPIC'+	    ;;+	  ghcx*)+	    # Green Hills C++ Compiler+	    lt_prog_compiler_pic_CXX='-pic'+	    ;;+	  *)+	    ;;+	esac+	;;+      freebsd* | dragonfly* | midnightbsd*)+	# FreeBSD uses GNU C+++	;;+      hpux9* | hpux10* | hpux11*)+	case $cc_basename in+	  CC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'+	    if test ia64 != "$host_cpu"; then+	      lt_prog_compiler_pic_CXX='+Z'+	    fi+	    ;;+	  aCC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'+	    case $host_cpu in+	    hppa*64*|ia64*)+	      # +Z the default+	      ;;+	    *)+	      lt_prog_compiler_pic_CXX='+Z'+	      ;;+	    esac+	    ;;+	  *)+	    ;;+	esac+	;;+      interix*)+	# This is c89, which is MS Visual C++ (no shared libs)+	# Anyone wants to do a port?+	;;+      irix5* | irix6* | nonstopux*)+	case $cc_basename in+	  CC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_static_CXX='-non_shared'+	    # CC pic flag -KPIC is the default.+	    ;;+	  *)+	    ;;+	esac+	;;+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+	case $cc_basename in+	  KCC*)+	    # KAI C++ Compiler+	    lt_prog_compiler_wl_CXX='--backend -Wl,'+	    lt_prog_compiler_pic_CXX='-fPIC'+	    ;;+	  ecpc* )+	    # old Intel C++ for x86_64, which still supported -KPIC.+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-KPIC'+	    lt_prog_compiler_static_CXX='-static'+	    ;;+	  icpc* )+	    # Intel C++, used to be incompatible with GCC.+	    # ICC 10 doesn't accept -KPIC any more.+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-fPIC'+	    lt_prog_compiler_static_CXX='-static'+	    ;;+	  pgCC* | pgcpp*)+	    # Portland Group C++ compiler+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-fpic'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    ;;+	  cxx*)+	    # Compaq C+++	    # Make sure the PIC flag is empty.  It appears that all Alpha+	    # Linux and Compaq Tru64 Unix objects are PIC.+	    lt_prog_compiler_pic_CXX=+	    lt_prog_compiler_static_CXX='-non_shared'+	    ;;+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)+	    # IBM XL 8.0, 9.0 on PPC and BlueGene+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-qpic'+	    lt_prog_compiler_static_CXX='-qstaticlink'+	    ;;+	  *)+	    case `$CC -V 2>&1 | $SED 5q` in+	    *Sun\ C*)+	      # Sun C++ 5.9+	      lt_prog_compiler_pic_CXX='-KPIC'+	      lt_prog_compiler_static_CXX='-Bstatic'+	      lt_prog_compiler_wl_CXX='-Qoption ld '+	      ;;+	    esac+	    ;;+	esac+	;;+      lynxos*)+	;;+      m88k*)+	;;+      mvs*)+	case $cc_basename in+	  cxx*)+	    lt_prog_compiler_pic_CXX='-W c,exportall'+	    ;;+	  *)+	    ;;+	esac+	;;+      netbsd* | netbsdelf*-gnu)+	;;+      *-mlibc)+	;;+      *qnx* | *nto*)+        # QNX uses GNU C++, but need to define -shared option too, otherwise+        # it will coredump.+        lt_prog_compiler_pic_CXX='-fPIC -shared'+        ;;+      osf3* | osf4* | osf5*)+	case $cc_basename in+	  KCC*)+	    lt_prog_compiler_wl_CXX='--backend -Wl,'+	    ;;+	  RCC*)+	    # Rational C++ 2.4.1+	    lt_prog_compiler_pic_CXX='-pic'+	    ;;+	  cxx*)+	    # Digital/Compaq C+++	    lt_prog_compiler_wl_CXX='-Wl,'+	    # Make sure the PIC flag is empty.  It appears that all Alpha+	    # Linux and Compaq Tru64 Unix objects are PIC.+	    lt_prog_compiler_pic_CXX=+	    lt_prog_compiler_static_CXX='-non_shared'+	    ;;+	  *)+	    ;;+	esac+	;;+      psos*)+	;;+      serenity*)+        ;;+      solaris*)+	case $cc_basename in+	  CC* | sunCC*)+	    # Sun C++ 4.2, 5.x and Centerline C+++	    lt_prog_compiler_pic_CXX='-KPIC'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    lt_prog_compiler_wl_CXX='-Qoption ld '+	    ;;+	  gcx*)+	    # Green Hills C++ Compiler+	    lt_prog_compiler_pic_CXX='-PIC'+	    ;;+	  *)+	    ;;+	esac+	;;+      sunos4*)+	case $cc_basename in+	  CC*)+	    # Sun C++ 4.x+	    lt_prog_compiler_pic_CXX='-pic'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    ;;+	  lcc*)+	    # Lucid+	    lt_prog_compiler_pic_CXX='-pic'+	    ;;+	  *)+	    ;;+	esac+	;;+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)+	case $cc_basename in+	  CC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-KPIC'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    ;;+	esac+	;;+      tandem*)+	case $cc_basename in+	  NCC*)+	    # NonStop-UX NCC 3.20+	    lt_prog_compiler_pic_CXX='-KPIC'+	    ;;+	  *)+	    ;;+	esac+	;;+      vxworks*)+	;;+      *)+	lt_prog_compiler_can_build_shared_CXX=no+	;;+    esac+  fi++case $host_os in+  # For platforms that do not support PIC, -DPIC is meaningless:+  *djgpp*)+    lt_prog_compiler_pic_CXX=+    ;;+  *)+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"+    ;;+esac++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5+printf %s "checking for $compiler option to produce PIC... " >&6; }+if test ${lt_cv_prog_compiler_pic_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; }+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX++#+# Check to make sure the PIC flag actually works.+#+if test -n "$lt_prog_compiler_pic_CXX"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5+printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }+if test ${lt_cv_prog_compiler_pic_works_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic_works_CXX=no+   ac_outfile=conftest.$ac_objext+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"  ## exclude from sc_useless_quotes_in_assignment+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   # The option is referenced via a variable to avoid confusing sed.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>conftest.err)+   ac_status=$?+   cat conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s "$ac_outfile"; then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings other than the usual output.+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_pic_works_CXX=yes+     fi+   fi+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; }++if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then+    case $lt_prog_compiler_pic_CXX in+     "" | " "*) ;;+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;+     esac+else+    lt_prog_compiler_pic_CXX=+     lt_prog_compiler_can_build_shared_CXX=no+fi++fi++++++#+# Check to make sure the static flag actually works.+#+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5+printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }+if test ${lt_cv_prog_compiler_static_works_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_static_works_CXX=no+   save_LDFLAGS=$LDFLAGS+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"+   echo "$lt_simple_link_test_code" > conftest.$ac_ext+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then+     # The linker can only warn and ignore the option if not recognized+     # So say no if there are warnings+     if test -s conftest.err; then+       # Append any errors to the config.log.+       cat conftest.err 1>&5+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+       if diff conftest.exp conftest.er2 >/dev/null; then+         lt_cv_prog_compiler_static_works_CXX=yes+       fi+     else+       lt_cv_prog_compiler_static_works_CXX=yes+     fi+   fi+   $RM -r conftest*+   LDFLAGS=$save_LDFLAGS+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; }++if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then+    :+else+    lt_prog_compiler_static_CXX=+fi+++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }+if test ${lt_cv_prog_compiler_c_o_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_c_o_CXX=no+   $RM -r conftest 2>/dev/null+   mkdir conftest+   cd conftest+   mkdir out+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext++   lt_compiler_flag="-o out/conftest2.$ac_objext"+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>out/conftest.err)+   ac_status=$?+   cat out/conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s out/conftest2.$ac_objext+   then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_c_o_CXX=yes+     fi+   fi+   chmod u+w . 2>&5+   $RM conftest*+   # SGI C++ compiler will create directory out/ii_files/ for+   # template instantiation+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files+   $RM out/* && rmdir out+   cd ..+   $RM -r conftest+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; }++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5+printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; }+if test ${lt_cv_prog_compiler_c_o_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_c_o_CXX=no+   $RM -r conftest 2>/dev/null+   mkdir conftest+   cd conftest+   mkdir out+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext++   lt_compiler_flag="-o out/conftest2.$ac_objext"+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>out/conftest.err)+   ac_status=$?+   cat out/conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s out/conftest2.$ac_objext+   then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_c_o_CXX=yes+     fi+   fi+   chmod u+w . 2>&5+   $RM conftest*+   # SGI C++ compiler will create directory out/ii_files/ for+   # template instantiation+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files+   $RM out/* && rmdir out+   cd ..+   $RM -r conftest+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; }+++++hard_links=nottested+if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then+  # do not overwrite the value of need_locks provided by the user+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5+printf %s "checking if we can lock with hard links... " >&6; }+  hard_links=yes+  $RM conftest*+  ln conftest.a conftest.b 2>/dev/null && hard_links=no+  touch conftest.a+  ln conftest.a conftest.b 2>&5 || hard_links=no+  ln conftest.a conftest.b 2>/dev/null && hard_links=no+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5+printf "%s\n" "$hard_links" >&6; }+  if test no = "$hard_links"; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5+printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}+    need_locks=warn+  fi+else+  need_locks=no+fi++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5+printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }++  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'+  case $host_os in+  aix[4-9]*)+    # If we're using GNU nm, then we don't want the "-C" option.+    # -C means demangle to GNU nm, but means don't demangle to AIX nm.+    # Without the "-l" option, or with the "-B" option, AIX nm treats+    # weak defined symbols like other global defined symbols, whereas+    # GNU nm marks them as "W".+    # While the 'weak' keyword is ignored in the Export File, we need+    # it in the Import File for the 'aix-soname' feature, so we have+    # to replace the "-B" option with "-P" for AIX nm.+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'+    else+      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'+    fi+    ;;+  pw32*)+    export_symbols_cmds_CXX=$ltdll_cmds+    ;;+  cygwin* | mingw* | windows* | cegcc*)+    case $cc_basename in+    cl* | icl*)+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'+      ;;+    *)+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'+      ;;+    esac+    ;;+  *)+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'+    ;;+  esac++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5+printf "%s\n" "$ld_shlibs_CXX" >&6; }+test no = "$ld_shlibs_CXX" && can_build_shared=no++with_gnu_ld_CXX=$with_gnu_ld+++++++#+# Do we need to explicitly link libc?+#+case "x$archive_cmds_need_lc_CXX" in+x|xyes)+  # Assume -lc should be added+  archive_cmds_need_lc_CXX=yes++  if test yes,yes = "$GCC,$enable_shared"; then+    case $archive_cmds_CXX in+    *'~'*)+      # FIXME: we may have to deal with multi-command sequences.+      ;;+    '$CC '*)+      # Test whether the compiler implicitly links with -lc since on some+      # systems, -lgcc has to come before -lc. If gcc already passes -lc+      # to ld, don't add -lc before -lgcc.+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5+printf %s "checking whether -lc should be explicitly linked in... " >&6; }+if test ${lt_cv_archive_cmds_need_lc_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) $RM conftest*+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext++	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } 2>conftest.err; then+	  soname=conftest+	  lib=conftest+	  libobjs=conftest.$ac_objext+	  deplibs=+	  wl=$lt_prog_compiler_wl_CXX+	  pic_flag=$lt_prog_compiler_pic_CXX+	  compiler_flags=-v+	  linker_flags=-v+	  verstring=+	  output_objdir=.+	  libname=conftest+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX+	  allow_undefined_flag_CXX=+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5+  (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+	  then+	    lt_cv_archive_cmds_need_lc_CXX=no+	  else+	    lt_cv_archive_cmds_need_lc_CXX=yes+	  fi+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag+	else+	  cat conftest.err 1>&5+	fi+	$RM conftest*+	 ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5+printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; }+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX+      ;;+    esac+  fi+  ;;+esac+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5+printf %s "checking dynamic linker characteristics... " >&6; }++library_names_spec=+libname_spec='lib$name'+soname_spec=+shrext_cmds=.so+postinstall_cmds=+postuninstall_cmds=+finish_cmds=+finish_eval=+shlibpath_var=+shlibpath_overrides_runpath=unknown+version_type=none+dynamic_linker="$host_os ld.so"+sys_lib_dlsearch_path_spec="/lib /usr/lib"+need_lib_prefix=unknown+hardcode_into_libs=no++# when you set need_version to no, make sure it does not cause -set_version+# flags to be left without arguments+need_version=unknown++++case $host_os in+aix3*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'+  shlibpath_var=LIBPATH++  # AIX 3 has no versioning support, so we append a major version to the name.+  soname_spec='$libname$release$shared_ext$major'+  ;;++aix[4-9]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  hardcode_into_libs=yes+  if test ia64 = "$host_cpu"; then+    # AIX 5 supports IA64+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'+    shlibpath_var=LD_LIBRARY_PATH+  else+    # With GCC up to 2.95.x, collect2 would create an import file+    # for dependence libraries.  The import file would start with+    # the line '#! .'.  This would cause the generated library to+    # depend on '.', always an invalid library.  This was fixed in+    # development snapshots of GCC prior to 3.0.+    case $host_os in+      aix4 | aix4.[01] | aix4.[01].*)+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'+	   echo ' yes '+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then+	:+      else+	can_build_shared=no+      fi+      ;;+    esac+    # Using Import Files as archive members, it is possible to support+    # filename-based versioning of shared library archives on AIX. While+    # this would work for both with and without runtime linking, it will+    # prevent static linking of such archives. So we do filename-based+    # shared library versioning with .so extension only, which is used+    # when both runtime linking and shared linking is enabled.+    # Unfortunately, runtime linking may impact performance, so we do+    # not want this to be the default eventually. Also, we use the+    # versioned .so libs for executables only if there is the -brtl+    # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only.+    # To allow for filename-based versioning support, we need to create+    # libNAME.so.V as an archive file, containing:+    # *) an Import File, referring to the versioned filename of the+    #    archive as well as the shared archive member, telling the+    #    bitwidth (32 or 64) of that shared object, and providing the+    #    list of exported symbols of that shared object, eventually+    #    decorated with the 'weak' keyword+    # *) the shared object with the F_LOADONLY flag set, to really avoid+    #    it being seen by the linker.+    # At run time we better use the real file rather than another symlink,+    # but for link time we create the symlink libNAME.so -> libNAME.so.V++    case $with_aix_soname,$aix_use_runtimelinking in+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct+    # soname into executable. Probably we can add versioning support to+    # collect2, so additional links can be useful in future.+    aix,yes) # traditional libtool+      dynamic_linker='AIX unversionable lib.so'+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so+      # instead of lib<name>.a to let people know that these are not+      # typical AIX shared libraries.+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+      ;;+    aix,no) # traditional AIX only+      dynamic_linker='AIX lib.a(lib.so.V)'+      # We preserve .a as extension for shared libraries through AIX4.2+      # and later when we are not doing run time linking.+      library_names_spec='$libname$release.a $libname.a'+      soname_spec='$libname$release$shared_ext$major'+      ;;+    svr4,*) # full svr4 only+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'+      # We do not specify a path in Import Files, so LIBPATH fires.+      shlibpath_overrides_runpath=yes+      ;;+    *,yes) # both, prefer svr4+      dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'+      # unpreferred sharedlib libNAME.a needs extra handling+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'+      # We do not specify a path in Import Files, so LIBPATH fires.+      shlibpath_overrides_runpath=yes+      ;;+    *,no) # both, prefer aix+      dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"+      library_names_spec='$libname$release.a $libname.a'+      soname_spec='$libname$release$shared_ext$major'+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'+      ;;+    esac+    shlibpath_var=LIBPATH+  fi+  ;;++amigaos*)+  case $host_cpu in+  powerpc)+    # Since July 2007 AmigaOS4 officially supports .so libraries.+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    ;;+  m68k)+    library_names_spec='$libname.ixlibrary $libname.a'+    # Create ${libname}_ixlibrary.a entries in /sys/libs.+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'+    ;;+  esac+  ;;++beos*)+  library_names_spec='$libname$shared_ext'+  dynamic_linker="$host_os ld.so"+  shlibpath_var=LIBRARY_PATH+  ;;++bsdi[45]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"+  # the default ld.so.conf also contains /usr/contrib/lib and+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow+  # libtool to hard-code these into programs+  ;;++cygwin* | mingw* | windows* | pw32* | cegcc*)+  version_type=windows+  shrext_cmds=.dll+  need_version=no+  need_lib_prefix=no++  case $GCC,$cc_basename in+  yes,*)+    # gcc+    library_names_spec='$libname.dll.a'+    # DLL is installed to $(libdir)/../bin by postinstall_cmds+    # If user builds GCC with multilib enabled,+    # it should just install on $(libdir)+    # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones.+    if test xyes = x"$multilib"; then+      postinstall_cmds='base_file=`basename \$file`~+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+        dldir=$destdir/`dirname \$dlpath`~+        $install_prog $dir/$dlname $destdir/$dlname~+        chmod a+x $destdir/$dlname~+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+          eval '\''$striplib $destdir/$dlname'\'' || exit \$?;+        fi'+    else+      postinstall_cmds='base_file=`basename \$file`~+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+        dldir=$destdir/`dirname \$dlpath`~+        test -d \$dldir || mkdir -p \$dldir~+        $install_prog $dir/$dlname \$dldir/$dlname~+        chmod a+x \$dldir/$dlname~+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+          eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;+        fi'+    fi+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~+      dlpath=$dir/\$dldll~+       $RM \$dlpath'+    shlibpath_overrides_runpath=yes++    case $host_os in+    cygwin*)+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'+      soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'++      ;;+    mingw* | windows* | cegcc*)+      # MinGW DLLs use traditional 'lib' prefix+      soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'+      ;;+    pw32*)+      # pw32 DLLs use 'pw' prefix rather than 'lib'+      library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'+      ;;+    esac+    dynamic_linker='Win32 ld.exe'+    ;;++  *,cl* | *,icl*)+    # Native MSVC or ICC+    libname_spec='$name'+    soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'+    library_names_spec='$libname.dll.lib'++    case $build_os in+    mingw* | windows*)+      sys_lib_search_path_spec=+      lt_save_ifs=$IFS+      IFS=';'+      for lt_path in $LIB+      do+        IFS=$lt_save_ifs+        # Let DOS variable expansion print the short 8.3 style file name.+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"+      done+      IFS=$lt_save_ifs+      # Convert to MSYS style.+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`+      ;;+    cygwin*)+      # Convert to unix form, then to dos form, then back to unix form+      # but this time dos style (no spaces!) so that the unix form looks+      # like /cygdrive/c/PROGRA~1:/cygdr...+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`+      ;;+    *)+      sys_lib_search_path_spec=$LIB+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then+        # It is most probably a Windows format PATH.+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`+      else+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`+      fi+      # FIXME: find the short name or the path components, as spaces are+      # common. (e.g. "Program Files" -> "PROGRA~1")+      ;;+    esac++    # DLL is installed to $(libdir)/../bin by postinstall_cmds+    postinstall_cmds='base_file=`basename \$file`~+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+      dldir=$destdir/`dirname \$dlpath`~+      test -d \$dldir || mkdir -p \$dldir~+      $install_prog $dir/$dlname \$dldir/$dlname'+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~+      dlpath=$dir/\$dldll~+       $RM \$dlpath'+    shlibpath_overrides_runpath=yes+    dynamic_linker='Win32 link.exe'+    ;;++  *)+    # Assume MSVC and ICC wrapper+    library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'+    dynamic_linker='Win32 ld.exe'+    ;;+  esac+  # FIXME: first we should search . and the directory the executable is in+  shlibpath_var=PATH+  ;;++darwin* | rhapsody*)+  dynamic_linker="$host_os dyld"+  version_type=darwin+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$major$shared_ext'+  shlibpath_overrides_runpath=yes+  shlibpath_var=DYLD_LIBRARY_PATH+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'++  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'+  ;;++dgux*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  ;;++freebsd* | dragonfly* | midnightbsd*)+  # DragonFly does not have aout.  When/if they implement a new+  # versioning mechanism, adjust this.+  if test -x /usr/bin/objformat; then+    objformat=`/usr/bin/objformat`+  else+    case $host_os in+    freebsd[23].*) objformat=aout ;;+    *) objformat=elf ;;+    esac+  fi+  version_type=freebsd-$objformat+  case $version_type in+    freebsd-elf*)+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+      soname_spec='$libname$release$shared_ext$major'+      need_version=no+      need_lib_prefix=no+      ;;+    freebsd-*)+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+      need_version=yes+      ;;+  esac+  case $host_cpu in+    powerpc64)+      # On FreeBSD bi-arch platforms, a different variable is used for 32-bit+      # binaries.  See <https://man.freebsd.org/cgi/man.cgi?query=ld.so>.+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+int test_pointer_size[sizeof (void *) - 5];++_ACEOF+if ac_fn_cxx_try_compile "$LINENO"+then :+  shlibpath_var=LD_LIBRARY_PATH+else case e in #(+  e) shlibpath_var=LD_32_LIBRARY_PATH ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+      ;;+    *)+      shlibpath_var=LD_LIBRARY_PATH+      ;;+  esac+  case $host_os in+  freebsd2.*)+    shlibpath_overrides_runpath=yes+    ;;+  freebsd3.[01]* | freebsdelf3.[01]*)+    shlibpath_overrides_runpath=yes+    hardcode_into_libs=yes+    ;;+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)+    shlibpath_overrides_runpath=no+    hardcode_into_libs=yes+    ;;+  *) # from 4.6 on, and DragonFly+    shlibpath_overrides_runpath=yes+    hardcode_into_libs=yes+    ;;+  esac+  ;;++haiku*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  dynamic_linker="$host_os runtime_loader"+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LIBRARY_PATH+  shlibpath_overrides_runpath=no+  sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib'+  sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib'+  hardcode_into_libs=no+  ;;++hpux9* | hpux10* | hpux11*)+  # Give a soname corresponding to the major version so that dld.sl refuses to+  # link against other versions.+  version_type=sunos+  need_lib_prefix=no+  need_version=no+  case $host_cpu in+  ia64*)+    shrext_cmds='.so'+    hardcode_into_libs=yes+    dynamic_linker="$host_os dld.so"+    shlibpath_var=LD_LIBRARY_PATH+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    if test 32 = "$HPUX_IA64_MODE"; then+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32+    else+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64+    fi+    ;;+  hppa*64*)+    shrext_cmds='.sl'+    hardcode_into_libs=yes+    dynamic_linker="$host_os dld.sl"+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+    ;;+  *)+    shrext_cmds='.sl'+    dynamic_linker="$host_os dld.sl"+    shlibpath_var=SHLIB_PATH+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    ;;+  esac+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...+  postinstall_cmds='chmod 555 $lib'+  # or fails outright, so override atomically:+  install_override_mode=555+  ;;++interix[3-9]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++irix5* | irix6* | nonstopux*)+  case $host_os in+    nonstopux*) version_type=nonstopux ;;+    *)+	if test yes = "$lt_cv_prog_gnu_ld"; then+		version_type=linux # correct to gnu/linux during the next big refactor+	else+		version_type=irix+	fi ;;+  esac+  need_lib_prefix=no+  need_version=no+  soname_spec='$libname$release$shared_ext$major'+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'+  case $host_os in+  irix5* | nonstopux*)+    libsuff= shlibsuff=+    ;;+  *)+    case $LD in # libtool.m4 will add one of these switches to LD+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")+      libsuff= shlibsuff= libmagic=32-bit;;+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")+      libsuff=32 shlibsuff=N32 libmagic=N32;;+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")+      libsuff=64 shlibsuff=64 libmagic=64-bit;;+    *) libsuff= shlibsuff= libmagic=never-match;;+    esac+    ;;+  esac+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH+  shlibpath_overrides_runpath=no+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"+  hardcode_into_libs=yes+  ;;++# No shared lib support for Linux oldld, aout, or coff.+linux*oldld* | linux*aout* | linux*coff*)+  dynamic_linker=no+  ;;++linux*android*)+  version_type=none # Android doesn't support versioned libraries.+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$shared_ext'+  finish_cmds=+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes++  # This implies no fast_install, which is unacceptable.+  # Some rework will be needed to allow for fast_install+  # before this can be enabled.+  hardcode_into_libs=yes++  dynamic_linker='Android linker'+  # -rpath works at least for libraries that are not overridden by+  # libraries installed in system locations.+  hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir'+  ;;++# This must be glibc/ELF.+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no++  # Some binutils ld are patched to set DT_RUNPATH+  if test ${lt_cv_shlibpath_overrides_runpath+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_shlibpath_overrides_runpath=no+    save_LDFLAGS=$LDFLAGS+    save_libdir=$libdir+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_cxx_try_link "$LINENO"+then :+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null+then :+  lt_cv_shlibpath_overrides_runpath=yes+fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+    LDFLAGS=$save_LDFLAGS+    libdir=$save_libdir+     ;;+esac+fi++  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath++  # This implies no fast_install, which is unacceptable.+  # Some rework will be needed to allow for fast_install+  # before this can be enabled.+  hardcode_into_libs=yes++  # Add ABI-specific directories to the system library path.+  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"++  # Ideally, we could use ldconfig to report *all* directories which are+  # searched for libraries, however this is still not possible.  Aside from not+  # being certain /sbin/ldconfig is available, command+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,+  # even though it is searched at run-time.  Try to do the best guess by+  # appending ld.so.conf contents (and includes) to the search path.+  if test -f /etc/ld.so.conf; then+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`+    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"+  fi++  # We used to test for /lib/ld.so.1 and disable shared libraries on+  # powerpc, because MkLinux only supported shared libraries with the+  # GNU dynamic linker.  Since this was broken with cross compilers,+  # most powerpc-linux boxes support dynamic linking these days and+  # people can always --disable-shared, the test was removed, and we+  # assume the GNU/Linux dynamic linker is in use.+  dynamic_linker='GNU/Linux ld.so'+  ;;++netbsdelf*-gnu)+  version_type=linux+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  dynamic_linker='NetBSD ld.elf_so'+  ;;++netbsd*)+  version_type=sunos+  need_lib_prefix=no+  need_version=no+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'+    dynamic_linker='NetBSD (a.out) ld.so'+  else+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    dynamic_linker='NetBSD ld.elf_so'+  fi+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  ;;++*-mlibc)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  dynamic_linker='mlibc ld.so'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++newsos6)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  ;;++*nto* | *qnx*)+  version_type=qnx+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  dynamic_linker='ldqnx.so'+  ;;++openbsd*)+  version_type=sunos+  sys_lib_dlsearch_path_spec=/usr/lib+  need_lib_prefix=no+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+    need_version=no+  else+    need_version=yes+  fi+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  ;;++os2*)+  libname_spec='$name'+  version_type=windows+  shrext_cmds=.dll+  need_version=no+  need_lib_prefix=no+  # OS/2 can only load a DLL with a base name of 8 characters or less.+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";+    v=$($ECHO $release$versuffix | tr -d .-);+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);+    $ECHO $n$v`$shared_ext'+  library_names_spec='${libname}_dll.$libext'+  dynamic_linker='OS/2 ld.exe'+  shlibpath_var=BEGINLIBPATH+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+  postinstall_cmds='base_file=`basename \$file`~+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~+    dldir=$destdir/`dirname \$dlpath`~+    test -d \$dldir || mkdir -p \$dldir~+    $install_prog $dir/$dlname \$dldir/$dlname~+    chmod a+x \$dldir/$dlname~+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;+    fi'+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~+    dlpath=$dir/\$dldll~+    $RM \$dlpath'+  ;;++osf3* | osf4* | osf5*)+  version_type=osf+  need_lib_prefix=no+  need_version=no+  soname_spec='$libname$release$shared_ext$major'+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+  ;;++rdos*)+  dynamic_linker=no+  ;;++serenity*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  dynamic_linker='SerenityOS LibELF'+  ;;++solaris*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  # ldd complains unless libraries are executable+  postinstall_cmds='chmod +x $lib'+  ;;++sunos4*)+  version_type=sunos+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  if test yes = "$with_gnu_ld"; then+    need_lib_prefix=no+  fi+  need_version=yes+  ;;++sysv4 | sysv4.3*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  case $host_vendor in+    sni)+      shlibpath_overrides_runpath=no+      need_lib_prefix=no+      runpath_var=LD_RUN_PATH+      ;;+    siemens)+      need_lib_prefix=no+      ;;+    motorola)+      need_lib_prefix=no+      need_version=no+      shlibpath_overrides_runpath=no+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'+      ;;+  esac+  ;;++sysv4*MP*)+  if test -d /usr/nec; then+    version_type=linux # correct to gnu/linux during the next big refactor+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'+    soname_spec='$libname$shared_ext.$major'+    shlibpath_var=LD_LIBRARY_PATH+  fi+  ;;++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)+  version_type=sco+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  if test yes = "$with_gnu_ld"; then+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'+  else+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'+    case $host_os in+      sco3.2v5*)+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"+	;;+    esac+  fi+  sys_lib_dlsearch_path_spec='/usr/lib'+  ;;++tpf*)+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++uts4*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  ;;++emscripten*)+  version_type=none+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext'+  soname_spec='$libname$release$shared_ext'+  finish_cmds=+  dynamic_linker="Emscripten linker"+  lt_prog_compiler_wl_CXX=+lt_prog_compiler_pic_CXX=+lt_prog_compiler_static_CXX=+++  # C++ specific cases for pic, static, wl, etc.+  if test yes = "$GXX"; then+    lt_prog_compiler_wl_CXX='-Wl,'+    lt_prog_compiler_static_CXX='-static'++    case $host_os in+    aix*)+      # All AIX code is PIC.+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	lt_prog_compiler_static_CXX='-Bstatic'+      fi+      lt_prog_compiler_pic_CXX='-fPIC'+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            lt_prog_compiler_pic_CXX='-fPIC'+        ;;+      m68k)+            # FIXME: we need at least 68020 code to build shared libraries, but+            # adding the '-m68020' flag to GCC prevents building anything better,+            # like '-m68040'.+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'+        ;;+      esac+      ;;++    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)+      # PIC is the default for these OSes.+      ;;+    mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      # Although the cygwin gcc ignores -fPIC, still need this for old-style+      # (--disable-auto-import) libraries+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'+      case $host_os in+      os2*)+	lt_prog_compiler_static_CXX='$wl-static'+	;;+      esac+      ;;+    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      lt_prog_compiler_pic_CXX='-fno-common'+      ;;+    *djgpp*)+      # DJGPP does not support shared libraries at all+      lt_prog_compiler_pic_CXX=+      ;;+    haiku*)+      # PIC is the default for Haiku.+      # The "-static" flag exists, but is broken.+      lt_prog_compiler_static_CXX=+      ;;+    interix[3-9]*)+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.+      # Instead, we relocate shared libraries at runtime.+      ;;+    sysv4*MP*)+      if test -d /usr/nec; then+	lt_prog_compiler_pic_CXX=-Kconform_pic+      fi+      ;;+    hpux*)+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag+      # sets the default TLS model and affects inlining.+      case $host_cpu in+      hppa*64*)+	;;+      *)+	lt_prog_compiler_pic_CXX='-fPIC'+	;;+      esac+      ;;+    *qnx* | *nto*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      lt_prog_compiler_pic_CXX='-fPIC -shared'+      ;;+    *)+      lt_prog_compiler_pic_CXX='-fPIC'+      ;;+    esac+  else+    case $host_os in+      aix[4-9]*)+	# All AIX code is PIC.+	if test ia64 = "$host_cpu"; then+	  # AIX 5 now supports IA64 processor+	  lt_prog_compiler_static_CXX='-Bstatic'+	else+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'+	fi+	;;+      chorus*)+	case $cc_basename in+	cxch68*)+	  # Green Hills C++ Compiler+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"+	  ;;+	esac+	;;+      mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)+	# This hack is so that the source file can tell whether it is being+	# built for inclusion in a dll (and should export symbols for example).+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'+	;;+      dgux*)+	case $cc_basename in+	  ec++*)+	    lt_prog_compiler_pic_CXX='-KPIC'+	    ;;+	  ghcx*)+	    # Green Hills C++ Compiler+	    lt_prog_compiler_pic_CXX='-pic'+	    ;;+	  *)+	    ;;+	esac+	;;+      freebsd* | dragonfly* | midnightbsd*)+	# FreeBSD uses GNU C+++	;;+      hpux9* | hpux10* | hpux11*)+	case $cc_basename in+	  CC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'+	    if test ia64 != "$host_cpu"; then+	      lt_prog_compiler_pic_CXX='+Z'+	    fi+	    ;;+	  aCC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_static_CXX='$wl-a ${wl}archive'+	    case $host_cpu in+	    hppa*64*|ia64*)+	      # +Z the default+	      ;;+	    *)+	      lt_prog_compiler_pic_CXX='+Z'+	      ;;+	    esac+	    ;;+	  *)+	    ;;+	esac+	;;+      interix*)+	# This is c89, which is MS Visual C++ (no shared libs)+	# Anyone wants to do a port?+	;;+      irix5* | irix6* | nonstopux*)+	case $cc_basename in+	  CC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_static_CXX='-non_shared'+	    # CC pic flag -KPIC is the default.+	    ;;+	  *)+	    ;;+	esac+	;;+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+	case $cc_basename in+	  KCC*)+	    # KAI C++ Compiler+	    lt_prog_compiler_wl_CXX='--backend -Wl,'+	    lt_prog_compiler_pic_CXX='-fPIC'+	    ;;+	  ecpc* )+	    # old Intel C++ for x86_64, which still supported -KPIC.+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-KPIC'+	    lt_prog_compiler_static_CXX='-static'+	    ;;+	  icpc* )+	    # Intel C++, used to be incompatible with GCC.+	    # ICC 10 doesn't accept -KPIC any more.+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-fPIC'+	    lt_prog_compiler_static_CXX='-static'+	    ;;+	  pgCC* | pgcpp*)+	    # Portland Group C++ compiler+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-fpic'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    ;;+	  cxx*)+	    # Compaq C+++	    # Make sure the PIC flag is empty.  It appears that all Alpha+	    # Linux and Compaq Tru64 Unix objects are PIC.+	    lt_prog_compiler_pic_CXX=+	    lt_prog_compiler_static_CXX='-non_shared'+	    ;;+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)+	    # IBM XL 8.0, 9.0 on PPC and BlueGene+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-qpic'+	    lt_prog_compiler_static_CXX='-qstaticlink'+	    ;;+	  *)+	    case `$CC -V 2>&1 | $SED 5q` in+	    *Sun\ C*)+	      # Sun C++ 5.9+	      lt_prog_compiler_pic_CXX='-KPIC'+	      lt_prog_compiler_static_CXX='-Bstatic'+	      lt_prog_compiler_wl_CXX='-Qoption ld '+	      ;;+	    esac+	    ;;+	esac+	;;+      lynxos*)+	;;+      m88k*)+	;;+      mvs*)+	case $cc_basename in+	  cxx*)+	    lt_prog_compiler_pic_CXX='-W c,exportall'+	    ;;+	  *)+	    ;;+	esac+	;;+      netbsd* | netbsdelf*-gnu)+	;;+      *-mlibc)+	;;+      *qnx* | *nto*)+        # QNX uses GNU C++, but need to define -shared option too, otherwise+        # it will coredump.+        lt_prog_compiler_pic_CXX='-fPIC -shared'+        ;;+      osf3* | osf4* | osf5*)+	case $cc_basename in+	  KCC*)+	    lt_prog_compiler_wl_CXX='--backend -Wl,'+	    ;;+	  RCC*)+	    # Rational C++ 2.4.1+	    lt_prog_compiler_pic_CXX='-pic'+	    ;;+	  cxx*)+	    # Digital/Compaq C+++	    lt_prog_compiler_wl_CXX='-Wl,'+	    # Make sure the PIC flag is empty.  It appears that all Alpha+	    # Linux and Compaq Tru64 Unix objects are PIC.+	    lt_prog_compiler_pic_CXX=+	    lt_prog_compiler_static_CXX='-non_shared'+	    ;;+	  *)+	    ;;+	esac+	;;+      psos*)+	;;+      serenity*)+        ;;+      solaris*)+	case $cc_basename in+	  CC* | sunCC*)+	    # Sun C++ 4.2, 5.x and Centerline C+++	    lt_prog_compiler_pic_CXX='-KPIC'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    lt_prog_compiler_wl_CXX='-Qoption ld '+	    ;;+	  gcx*)+	    # Green Hills C++ Compiler+	    lt_prog_compiler_pic_CXX='-PIC'+	    ;;+	  *)+	    ;;+	esac+	;;+      sunos4*)+	case $cc_basename in+	  CC*)+	    # Sun C++ 4.x+	    lt_prog_compiler_pic_CXX='-pic'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    ;;+	  lcc*)+	    # Lucid+	    lt_prog_compiler_pic_CXX='-pic'+	    ;;+	  *)+	    ;;+	esac+	;;+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)+	case $cc_basename in+	  CC*)+	    lt_prog_compiler_wl_CXX='-Wl,'+	    lt_prog_compiler_pic_CXX='-KPIC'+	    lt_prog_compiler_static_CXX='-Bstatic'+	    ;;+	esac+	;;+      tandem*)+	case $cc_basename in+	  NCC*)+	    # NonStop-UX NCC 3.20+	    lt_prog_compiler_pic_CXX='-KPIC'+	    ;;+	  *)+	    ;;+	esac+	;;+      vxworks*)+	;;+      *)+	lt_prog_compiler_can_build_shared_CXX=no+	;;+    esac+  fi++case $host_os in+  # For platforms that do not support PIC, -DPIC is meaningless:+  *djgpp*)+    lt_prog_compiler_pic_CXX=+    ;;+  *)+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"+    ;;+esac++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5+printf %s "checking for $compiler option to produce PIC... " >&6; }+if test ${lt_cv_prog_compiler_pic_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; }+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX++#+# Check to make sure the PIC flag actually works.+#+if test -n "$lt_prog_compiler_pic_CXX"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5+printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }+if test ${lt_cv_prog_compiler_pic_works_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_pic_works_CXX=no+   ac_outfile=conftest.$ac_objext+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"  ## exclude from sc_useless_quotes_in_assignment+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   # The option is referenced via a variable to avoid confusing sed.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)+   (eval "$lt_compile" 2>conftest.err)+   ac_status=$?+   cat conftest.err >&5+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   if (exit $ac_status) && test -s "$ac_outfile"; then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings other than the usual output.+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then+       lt_cv_prog_compiler_pic_works_CXX=yes+     fi+   fi+   $RM conftest*+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; }++if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then+    case $lt_prog_compiler_pic_CXX in+     "" | " "*) ;;+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;+     esac+else+    lt_prog_compiler_pic_CXX=+     lt_prog_compiler_can_build_shared_CXX=no+fi++fi++++++#+# Check to make sure the static flag actually works.+#+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5+printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }+if test ${lt_cv_prog_compiler_static_works_CXX+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_prog_compiler_static_works_CXX=no+   save_LDFLAGS=$LDFLAGS+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"+   echo "$lt_simple_link_test_code" > conftest.$ac_ext+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then+     # The linker can only warn and ignore the option if not recognized+     # So say no if there are warnings+     if test -s conftest.err; then+       # Append any errors to the config.log.+       cat conftest.err 1>&5+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+       if diff conftest.exp conftest.er2 >/dev/null; then+         lt_cv_prog_compiler_static_works_CXX=yes+       fi+     else+       lt_cv_prog_compiler_static_works_CXX=yes+     fi+   fi+   $RM -r conftest*+   LDFLAGS=$save_LDFLAGS+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5+printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; }++if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then+    :+else+    lt_prog_compiler_static_CXX=+fi++++='-fPIC'+  archive_cmds_CXX='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib'+  archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym'+  archive_cmds_need_lc_CXX=no+  no_undefined_flag_CXX=+  ;;++*)+  dynamic_linker=no+  ;;+esac+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5+printf "%s\n" "$dynamic_linker" >&6; }+test no = "$dynamic_linker" && can_build_shared=no++variables_saved_for_relink="PATH $shlibpath_var $runpath_var"+if test yes = "$GCC"; then+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"+fi++if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec+fi++if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec+fi++# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec++# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"++# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH+++++++++++++++++++++++++++++++++++++++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5+printf %s "checking how to hardcode library paths into programs... " >&6; }+hardcode_action_CXX=+if test -n "$hardcode_libdir_flag_spec_CXX" ||+   test -n "$runpath_var_CXX" ||+   test yes = "$hardcode_automatic_CXX"; then++  # We can hardcode non-existent directories.+  if test no != "$hardcode_direct_CXX" &&+     # If the only mechanism to avoid hardcoding is shlibpath_var, we+     # have to relink, otherwise we might link with an installed library+     # when we should be linking with a yet-to-be-installed one+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" &&+     test no != "$hardcode_minus_L_CXX"; then+    # Linking always hardcodes the temporary library directory.+    hardcode_action_CXX=relink+  else+    # We can link without hardcoding, and we can hardcode nonexisting dirs.+    hardcode_action_CXX=immediate+  fi+else+  # We cannot hardcode anything, or else we can only hardcode existing+  # directories.+  hardcode_action_CXX=unsupported+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5+printf "%s\n" "$hardcode_action_CXX" >&6; }++if test relink = "$hardcode_action_CXX" ||+   test yes = "$inherit_rpath_CXX"; then+  # Fast installation is not supported+  enable_fast_install=no+elif test yes = "$shlibpath_overrides_runpath" ||+     test no = "$enable_shared"; then+  # Fast installation is not necessary+  enable_fast_install=needless+fi++++++++  fi # test -n "$compiler"++  CC=$lt_save_CC+  CFLAGS=$lt_save_CFLAGS+  LDCXX=$LD+  LD=$lt_save_LD+  GCC=$lt_save_GCC+  with_gnu_ld=$lt_save_with_gnu_ld+  lt_cv_path_LDCXX=$lt_cv_path_LD+  lt_cv_path_LD=$lt_save_path_LD+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld+fi # test yes != "$_lt_caught_CXX_error"++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++++++++++++++        ac_config_commands="$ac_config_commands libtool"+++++# Only expand once:+++++# Test for 64-bit build.+# The cast to long int works around a bug in the HP C Compiler+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects+# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'.+# This bug is HP SR number 8606223364.+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5+printf %s "checking size of size_t... " >&6; }+if test ${ac_cv_sizeof_size_t+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t"        "$ac_includes_default"+then :++else case e in #(+  e) if test "$ac_cv_type_size_t" = yes; then+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error 77 "cannot compute sizeof (size_t)+See 'config.log' for more details" "$LINENO" 5; }+   else+     ac_cv_sizeof_size_t=0+   fi ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5+printf "%s\n" "$ac_cv_sizeof_size_t" >&6; }++++printf "%s\n" "#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t" >>confdefs.h++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler vendor" >&5+printf %s "checking for C compiler vendor... " >&6; }+if test ${ax_cv_c_compiler_vendor+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+	vendors="+		intel:		__ICC,__ECC,__INTEL_COMPILER+		ibm:		__xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__+		pathscale:	__PATHCC__,__PATHSCALE__+		clang:		__clang__+		cray:		_CRAYC+		fujitsu:	__FUJITSU+		sdcc:		SDCC,__SDCC+		sx:		_SX+		nvhpc:		__NVCOMPILER+		portland:	__PGI+		gnu:		__GNUC__+		sun:		__SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95+		hp:		__HP_cc,__HP_aCC+		dec:		__DECC,__DECCXX,__DECC_VER,__DECCXX_VER+		borland:	__BORLANDC__,__CODEGEARC__,__TURBOC__+		comeau:		__COMO__+		kai:		__KCC+		lcc:		__LCC__+		sgi:		__sgi,sgi+		microsoft:	_MSC_VER+		metrowerks:	__MWERKS__+		watcom:		__WATCOMC__+		tcc:		__TINYC__+		unknown:	UNKNOWN+	"+	for ventest in $vendors; do+	    case $ventest in+		*:)+		    vendor=$ventest+		    continue+		    ;;+		*)+		    vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")"+		    ;;+	    esac++	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++#if !($vencpp)+      thisisanerror;+#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  break+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+	done++	ax_cv_c_compiler_vendor=`echo $vendor | cut -d: -f1`+     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_compiler_vendor" >&5+printf "%s\n" "$ax_cv_c_compiler_vendor" >&6; }+++++++# Check whether --enable-portable-binary was given.+if test ${enable_portable_binary+y}+then :+  enableval=$enable_portable_binary; acx_maxopt_portable=$enableval+else case e in #(+  e) acx_maxopt_portable=no ;;+esac+fi+++# Try to determine "good" native compiler flags if none specified via CFLAGS+if test "x$ac_test_CFLAGS" = "x"; then+  case $ax_cv_c_compiler_vendor in+    dec) CFLAGS="$CFLAGS -newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"+	 if test "x$acx_maxopt_portable" = xno; then+           CFLAGS="$CFLAGS -arch host"+         fi;;++    sun) CFLAGS="$CFLAGS -native -fast -xO5 -dalign"+	 if test "x$acx_maxopt_portable" = xyes; then+	   CFLAGS="$CFLAGS -xarch=generic"+         fi;;++    hp)  CFLAGS="$CFLAGS +Oall +Optrs_ansi +DSnative"+	 if test "x$acx_maxopt_portable" = xyes; then+	   CFLAGS="$CFLAGS +DAportable"+	 fi;;++    ibm) if test "x$acx_maxopt_portable" = xno; then+           xlc_opt="-qarch=auto -qtune=auto"+	 else+           xlc_opt="-qtune=auto"+	 fi+         as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$xlc_opt" | sed "$as_sed_sh"`+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts $xlc_opt" >&5+printf %s "checking whether the C compiler accepts $xlc_opt... " >&6; }+if eval test \${$as_CACHEVAR+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  $xlc_opt $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  eval "$as_CACHEVAR=yes"+else case e in #(+  e) eval "$as_CACHEVAR=no" ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+eval ac_res=\$$as_CACHEVAR+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+printf "%s\n" "$ac_res" >&6; }+if eval test \"x\$"$as_CACHEVAR"\" = x"yes"+then :+  CFLAGS="$CFLAGS -O3 -qansialias -w $xlc_opt"+else case e in #(+  e) CFLAGS="$CFLAGS -O3 -qansialias -w"+                echo "******************************************************"+                echo "*  You seem to have the IBM  C compiler.  It is      *"+                echo "*  recommended for best performance that you use:    *"+                echo "*                                                    *"+                echo "*    CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"+                echo "*                      ^^^        ^^^                *"+                echo "*  where xxx is pwr2, pwr3, 604, or whatever kind of *"+                echo "*  CPU you have.  (Set the CFLAGS environment var.   *"+                echo "*  and re-run configure.)  For more info, man cc.    *"+                echo "******************************************************" ;;+esac+fi++         ;;++    intel) CFLAGS="$CFLAGS -O3 -ansi_alias"+	if test "x$acx_maxopt_portable" = xno; then+	  icc_archflag=unknown+	  icc_flags=""+	  case $host_cpu in+	    i686*|x86_64*)+              # icc accepts gcc assembly syntax, so these should work:++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0 output" >&5+printf %s "checking for x86 cpuid 0 output... " >&6; }+if test ${ax_cv_gcc_x86_cpuid_0+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test "$cross_compiling" = yes+then :+  ax_cv_gcc_x86_cpuid_0=unknown+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdio.h>+int+main (void)+{++     int op = 0, level = 0, eax, ebx, ecx, edx;+     FILE *f;+      __asm__ __volatile__ ("xchg %%ebx, %1\n"+        "cpuid\n"+        "xchg %%ebx, %1\n"+        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)+        : "a" (op), "2" (level));++     f = fopen("conftest_cpuid", "w"); if (!f) return 1;+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);+     fclose(f);+     return 0;++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  ax_cv_gcc_x86_cpuid_0=`cat conftest_cpuid`; rm -f conftest_cpuid+else case e in #(+  e) ax_cv_gcc_x86_cpuid_0=unknown; rm -f conftest_cpuid ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0" >&5+printf "%s\n" "$ax_cv_gcc_x86_cpuid_0" >&6; }+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 1 output" >&5+printf %s "checking for x86 cpuid 1 output... " >&6; }+if test ${ax_cv_gcc_x86_cpuid_1+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test "$cross_compiling" = yes+then :+  ax_cv_gcc_x86_cpuid_1=unknown+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdio.h>+int+main (void)+{++     int op = 1, level = 0, eax, ebx, ecx, edx;+     FILE *f;+      __asm__ __volatile__ ("xchg %%ebx, %1\n"+        "cpuid\n"+        "xchg %%ebx, %1\n"+        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)+        : "a" (op), "2" (level));++     f = fopen("conftest_cpuid", "w"); if (!f) return 1;+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);+     fclose(f);+     return 0;++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  ax_cv_gcc_x86_cpuid_1=`cat conftest_cpuid`; rm -f conftest_cpuid+else case e in #(+  e) ax_cv_gcc_x86_cpuid_1=unknown; rm -f conftest_cpuid ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_1" >&5+printf "%s\n" "$ax_cv_gcc_x86_cpuid_1" >&6; }+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++	      case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG+                *:756e6547:6c65746e:49656e69) # Intel+                  case $ax_cv_gcc_x86_cpuid_1 in+		    *0?6[78ab]?:*:*:*|?6[78ab]?:*:*:*|6[78ab]?:*:*:*) icc_flags="-xK" ;;+		    *0?6[9d]?:*:*:*|?6[9d]?:*:*:*|6[9d]?:*:*:*|*1?65?:*:*:*) icc_flags="-xSSE2 -xB -xK" ;;+		    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) icc_flags="-xSSE3 -xP -xO -xB -xK" ;;+		    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) icc_flags="-xSSSE3 -xT -xB -xK" ;;+		    *1?6[7d]?:*:*:*) icc_flags="-xSSE4.1 -xS -xT -xB -xK" ;;+		    *1?6[aef]?:*:*:*|*2?6[5cef]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;;+		    *2?6[ad]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;;+		    *3?6[ae]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;+		    *3?6[cf]?:*:*:*|*4?6[56]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;+		    *000?f[346]?:*:*:*|?f[346]?:*:*:*|f[346]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;;+		    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;;+                  esac ;;+              esac ;;+          esac+          if test "x$icc_flags" != x; then+            for flag in $icc_flags; do+              as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$flag" | sed "$as_sed_sh"`+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts $flag" >&5+printf %s "checking whether the C compiler accepts $flag... " >&6; }+if eval test \${$as_CACHEVAR+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  $flag $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  eval "$as_CACHEVAR=yes"+else case e in #(+  e) eval "$as_CACHEVAR=no" ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+eval ac_res=\$$as_CACHEVAR+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+printf "%s\n" "$ac_res" >&6; }+if eval test \"x\$"$as_CACHEVAR"\" = x"yes"+then :+  icc_archflag=$flag; break+else case e in #(+  e) : ;;+esac+fi++            done+          fi+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for icc architecture flag" >&5+printf %s "checking for icc architecture flag... " >&6; }+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $icc_archflag" >&5+printf "%s\n" "$icc_archflag" >&6; }+          if test "x$icc_archflag" != xunknown; then+            CFLAGS="$CFLAGS $icc_archflag"+          fi+        fi+	;;++    nvhpc)+     # default optimization flags for nvhpc+     CFLAGS="$CFLAGS -O3"+     ;;++    gnu)+     # default optimization flags for gcc on all systems+     CFLAGS="$CFLAGS -O3 -fomit-frame-pointer"++     # -malign-double for x86 systems+     # LIBFFI_LOCAL: don't do this.+     # The testsuite doesn't use these flags and we'll get test failures.+     # AX_CHECK_COMPILE_FLAG(-malign-double, CFLAGS="$CFLAGS -malign-double")++     #  -fstrict-aliasing for gcc-2.95++     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts -fstrict-aliasing" >&5+printf %s "checking whether the C compiler accepts -fstrict-aliasing... " >&6; }+if test ${ax_cv_check_cflags___fstrict_aliasing+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  -fstrict-aliasing $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ax_cv_check_cflags___fstrict_aliasing=yes+else case e in #(+  e) ax_cv_check_cflags___fstrict_aliasing=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fstrict_aliasing" >&5+printf "%s\n" "$ax_cv_check_cflags___fstrict_aliasing" >&6; }+if test "x$ax_cv_check_cflags___fstrict_aliasing" = xyes+then :+  CFLAGS="$CFLAGS -fstrict-aliasing"+else case e in #(+  e) : ;;+esac+fi+++     # note that we enable "unsafe" fp optimization with other compilers, too+     { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts -ffast-math" >&5+printf %s "checking whether the C compiler accepts -ffast-math... " >&6; }+if test ${ax_cv_check_cflags___ffast_math+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  -ffast-math $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ax_cv_check_cflags___ffast_math=yes+else case e in #(+  e) ax_cv_check_cflags___ffast_math=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___ffast_math" >&5+printf "%s\n" "$ax_cv_check_cflags___ffast_math" >&6; }+if test "x$ax_cv_check_cflags___ffast_math" = xyes+then :+  CFLAGS="$CFLAGS -ffast-math"+else case e in #(+  e) : ;;+esac+fi+++++++++# Check whether --with-gcc-arch was given.+if test ${with_gcc_arch+y}+then :+  withval=$with_gcc_arch; ax_gcc_arch=$withval+else case e in #(+  e) ax_gcc_arch=yes ;;+esac+fi+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc architecture flag" >&5+printf %s "checking for gcc architecture flag... " >&6; }+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: " >&5+printf "%s\n" "" >&6; }+if test ${ax_cv_gcc_archflag+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+ax_cv_gcc_archflag="unknown"++if test "$GCC" = yes; then++if test "x$ax_gcc_arch" = xyes; then+ax_gcc_arch=""+if test "$cross_compiling" = no; then+case $host_cpu in+  i[3456]86*|x86_64*|amd64*) # use cpuid codes++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 0 output" >&5+printf %s "checking for x86 cpuid 0 output... " >&6; }+if test ${ax_cv_gcc_x86_cpuid_0+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test "$cross_compiling" = yes+then :+  ax_cv_gcc_x86_cpuid_0=unknown+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdio.h>+int+main (void)+{++     int op = 0, level = 0, eax, ebx, ecx, edx;+     FILE *f;+      __asm__ __volatile__ ("xchg %%ebx, %1\n"+        "cpuid\n"+        "xchg %%ebx, %1\n"+        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)+        : "a" (op), "2" (level));++     f = fopen("conftest_cpuid", "w"); if (!f) return 1;+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);+     fclose(f);+     return 0;++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  ax_cv_gcc_x86_cpuid_0=`cat conftest_cpuid`; rm -f conftest_cpuid+else case e in #(+  e) ax_cv_gcc_x86_cpuid_0=unknown; rm -f conftest_cpuid ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_0" >&5+printf "%s\n" "$ax_cv_gcc_x86_cpuid_0" >&6; }+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x86 cpuid 1 output" >&5+printf %s "checking for x86 cpuid 1 output... " >&6; }+if test ${ax_cv_gcc_x86_cpuid_1+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if test "$cross_compiling" = yes+then :+  ax_cv_gcc_x86_cpuid_1=unknown+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdio.h>+int+main (void)+{++     int op = 1, level = 0, eax, ebx, ecx, edx;+     FILE *f;+      __asm__ __volatile__ ("xchg %%ebx, %1\n"+        "cpuid\n"+        "xchg %%ebx, %1\n"+        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)+        : "a" (op), "2" (level));++     f = fopen("conftest_cpuid", "w"); if (!f) return 1;+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);+     fclose(f);+     return 0;++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  ax_cv_gcc_x86_cpuid_1=`cat conftest_cpuid`; rm -f conftest_cpuid+else case e in #(+  e) ax_cv_gcc_x86_cpuid_1=unknown; rm -f conftest_cpuid ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_x86_cpuid_1" >&5+printf "%s\n" "$ax_cv_gcc_x86_cpuid_1" >&6; }+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++     case $ax_cv_gcc_x86_cpuid_0 in+       *:756e6547:6c65746e:49656e69) # Intel+          case $ax_cv_gcc_x86_cpuid_1 in+	    *5[4578]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;+	    *5[123]?:*:*:*) ax_gcc_arch=pentium ;;+	    *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;;+	    *0?6[356]?:*:*:*|?6[356]?:*:*:*|6[356]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;+	    *0?6[78ab]?:*:*:*|?6[78ab]?:*:*:*|6[78ab]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;+	    *0?6[9d]?:*:*:*|?6[9d]?:*:*:*|6[9d]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;+	    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;;+	    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;;+	    *1?6[7d]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;;+	    *1?6[aef]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *2?6[5cf]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *2?6[ad]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *3?6[ae]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *3?6[cf]?:*:*:*|*4?6[56]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *3?6d?:*:*:*|*4?6[7f]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *1?6c?:*:*:*|*2?6[67]?:*:*:*|*3?6[56]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;;+	    *3?67?:*:*:*|*[45]?6[ad]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;;+	    *000?f[012]?:*:*:*|?f[012]?:*:*:*|f[012]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;+	    *000?f[346]?:*:*:*|?f[346]?:*:*:*|f[346]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;;+	    # fallback+	    *5??:*:*:*) ax_gcc_arch=pentium ;;+	    *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;;+	    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;+	    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;+          esac ;;+       *:68747541:444d4163:69746e65) # AMD+          case $ax_cv_gcc_x86_cpuid_1 in+	    *5[67]?:*:*:*) ax_gcc_arch=k6 ;;+	    *5[8]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;+	    *5[9d]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;+	    *6[12]?:*:*:*) ax_gcc_arch="athlon k7" ;;+	    *6[34]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;+	    *6[678a]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;+	    *000?f[4578bcef]?:*:*:*|?f[4578bcef]?:*:*:*|f[4578bcef]?:*:*:*|*001?f[4578bcf]?:*:*:*|1?f[4578bcf]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;+	    *002?f[13457bcf]?:*:*:*|2?f[13457bcf]?:*:*:*|*004?f[138bcf]?:*:*:*|4?f[138bcf]?:*:*:*|*005?f[df]?:*:*:*|5?f[df]?:*:*:*|*006?f[8bcf]?:*:*:*|6?f[8bcf]?:*:*:*|*007?f[cf]?:*:*:*|7?f[cf]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;+	    *010?f[245689a]?:*:*:*|10?f[245689a]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;+	    *050?f[12]?:*:*:*|50?f[12]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;+	    *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;+	    *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[03]?:*:*:*|61?f[03]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;+	    *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;+	    *07[03]?f0?:*:*:*|7[03]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;+	    # fallback+	    *0[13]??f??:*:*:*|[13]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;+	    *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;+	    *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;+	    *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;+	    *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;+	    *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;+	    *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;+	    *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;;+          esac ;;+	*:746e6543:736c7561:48727561) # IDT / VIA (Centaur)+	   case $ax_cv_gcc_x86_cpuid_1 in+	     *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;+	     *5[89]?:*:*:*) ax_gcc_arch=winchip2 ;;+	     *66?:*:*:*) ax_gcc_arch=winchip2 ;;+	     *6[78]?:*:*:*) ax_gcc_arch=c3 ;;+	     *6[9adf]?:*:*:*) ax_gcc_arch="c3-2 c3" ;;+	   esac ;;+     esac+     if test x"$ax_gcc_arch" = x; then # fallback+	case $host_cpu in+	  i586*) ax_gcc_arch=pentium ;;+	  i686*) ax_gcc_arch=pentiumpro ;;+        esac+     fi+     ;;++  sparc*)+     # Extract the first word of "prtdiag", so it can be a program name with args.+set dummy prtdiag; ac_word=$2+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+printf %s "checking for $ac_word... " >&6; }+if test ${ac_cv_path_PRTDIAG+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) case $PRTDIAG in+  [\\/]* | ?:[\\/]*)+  ac_cv_path_PRTDIAG="$PRTDIAG" # Let the user override the test with a path.+  ;;+  *)+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+as_dummy="$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/"+for as_dir in $as_dummy+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then+    ac_cv_path_PRTDIAG="$as_dir$ac_word$ac_exec_ext"+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++  test -z "$ac_cv_path_PRTDIAG" && ac_cv_path_PRTDIAG="prtdiag"+  ;;+esac ;;+esac+fi+PRTDIAG=$ac_cv_path_PRTDIAG+if test -n "$PRTDIAG"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PRTDIAG" >&5+printf "%s\n" "$PRTDIAG" >&6; }+else+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5+printf "%s\n" "no" >&6; }+fi+++     cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`+     cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters`+     case $cputype in+         *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;+         *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;+         *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;+         *supersparc*|*tms390z5[05]*) ax_gcc_arch="supersparc v8" ;;+         *hypersparc*|*rt62[056]*) ax_gcc_arch="hypersparc v8" ;;+         *cypress*) ax_gcc_arch=cypress ;;+     esac ;;++  alphaev5) ax_gcc_arch=ev5 ;;+  alphaev56) ax_gcc_arch=ev56 ;;+  alphapca56) ax_gcc_arch="pca56 ev56" ;;+  alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;+  alphaev6) ax_gcc_arch=ev6 ;;+  alphaev67) ax_gcc_arch=ev67 ;;+  alphaev68) ax_gcc_arch="ev68 ev67" ;;+  alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;+  alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;+  alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;++  powerpc*)+     cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`+     cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'`+     case $cputype in+       *750*) ax_gcc_arch="750 G3" ;;+       *740[0-9]*) ax_gcc_arch="$cputype 7400 G4" ;;+       *74[4-5][0-9]*) ax_gcc_arch="$cputype 7450 G4" ;;+       *74[0-9][0-9]*) ax_gcc_arch="$cputype G4" ;;+       *970*) ax_gcc_arch="970 G5 power4";;+       *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;+       *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;+       603ev|8240) ax_gcc_arch="$cputype 603e 603";;+       *POWER7*) ax_gcc_arch="power7";;+       *POWER8*) ax_gcc_arch="power8";;+       *POWER9*) ax_gcc_arch="power9";;+       *POWER10*) ax_gcc_arch="power10";;+       *) ax_gcc_arch=$cputype ;;+     esac+     ax_gcc_arch="$ax_gcc_arch powerpc"+     ;;+  aarch64)+     cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`+     cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`+     cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`+     case $cpuimpl in+       0x42) case $cpuarch in+               8) case $cpuvar in+                    0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;;+                  esac+                  ;;+             esac+             ;;+       0x43) case $cpuarch in+               8) case $cpuvar in+                    0x0) ax_gcc_arch="thunderx armv8-a native" ;;+                    0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;;+                  esac+                  ;;+             esac+             ;;+      esac+      ;;+esac+fi # not cross-compiling+fi # guess arch++if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then+if test "x$acx_maxopt_portable" = xyes; then # if we require portable code+  flag_prefixes="-mtune="+  if test "x$ax_cv_c_compiler_vendor" = xclang; then flag_prefixes="-march="; fi+  # -mcpu=$arch and m$arch generate nonportable code on every arch except+  # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.+  case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac+else+  flag_prefixes="-march= -mcpu= -m"+fi+for flag_prefix in $flag_prefixes; do+  for arch in $ax_gcc_arch; do+    flag="$flag_prefix$arch"+    as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$flag" | sed "$as_sed_sh"`+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts $flag" >&5+printf %s "checking whether the C compiler accepts $flag... " >&6; }+if eval test \${$as_CACHEVAR+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  $flag $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  eval "$as_CACHEVAR=yes"+else case e in #(+  e) eval "$as_CACHEVAR=no" ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+eval ac_res=\$$as_CACHEVAR+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+printf "%s\n" "$ac_res" >&6; }+if eval test \"x\$"$as_CACHEVAR"\" = x"yes"+then :+  if test "x$ax_cv_c_compiler_vendor" = xclang; then+      if test "x$acx_maxopt_portable" = xyes; then+	if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi+      fi+    fi; ax_cv_gcc_archflag=$flag; break+else case e in #(+  e) : ;;+esac+fi++  done+  test "x$ax_cv_gcc_archflag" = xunknown || break+done+fi++fi # $GCC=yes+ ;;+esac+fi++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc architecture flag" >&5+printf %s "checking for gcc architecture flag... " >&6; }+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_gcc_archflag" >&5+printf "%s\n" "$ax_cv_gcc_archflag" >&6; }+if test "x$ax_cv_gcc_archflag" = xunknown; then+  :+else+  CFLAGS="$CFLAGS $ax_cv_gcc_archflag"+fi++     ;;++    microsoft)+     # default optimization flags for MSVC opt builds+     CFLAGS="$CFLAGS -O2"+     ;;+  esac++  if test -z "$CFLAGS"; then+	echo ""+	echo "********************************************************"+        echo "* WARNING: Don't know the best CFLAGS for this system  *"+        echo "* Use ./configure CFLAGS=... to specify your own flags *"+	echo "* (otherwise, a default of CFLAGS=-O3 will be used)    *"+	echo "********************************************************"+	echo ""+        CFLAGS="$CFLAGS -O3"+  fi++  as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$CFLAGS" | sed "$as_sed_sh"`+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts $CFLAGS" >&5+printf %s "checking whether the C compiler accepts $CFLAGS... " >&6; }+if eval test \${$as_CACHEVAR+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  $CFLAGS $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  eval "$as_CACHEVAR=yes"+else case e in #(+  e) eval "$as_CACHEVAR=no" ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+eval ac_res=\$$as_CACHEVAR+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+printf "%s\n" "$ac_res" >&6; }+if eval test \"x\$"$as_CACHEVAR"\" = x"yes"+then :+  :+else case e in #(+  e)+	echo ""+        echo "********************************************************"+        echo "* WARNING: The guessed CFLAGS don't seem to work with  *"+        echo "* your compiler.                                       *"+        echo "* Use ./configure CFLAGS=... to specify your own flags *"+        echo "********************************************************"+        echo ""+   ;;+esac+fi+++fi++# The AX_CFLAGS_WARN_ALL macro doesn't currently work for sunpro+# compiler.+if test "$ax_cv_c_compiler_vendor" != "sun"; then+      ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CFLAGS for most reasonable warnings" >&5+printf %s "checking CFLAGS for most reasonable warnings... " >&6; }+if test ${ac_cv_cflags_warn_all+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+	ac_cv_cflags_warn_all=""+	ac_save_cflags_warn_all_found="yes"+		case "$ax_cv_c_compiler_vendor" in #(+  intel) :+    ac_cv_cflags_warn_all="-w2" ;; #(+  ibm) :+    ac_cv_cflags_warn_all="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" ;; #(+  pathscale) :+     ;; #(+  clang) :+    ac_cv_cflags_warn_all="-Wall" ;; #(+  cray) :+    ac_cv_cflags_warn_all="-h msglevel 2" ;; #(+  fujitsu) :+     ;; #(+  sdcc) :+     ;; #(+  sx) :+    ac_cv_cflags_warn_all="-pvctl,fullmsg" ;; #(+  portland) :+     ;; #(+  gnu) :+    ac_cv_cflags_warn_all="-Wall" ;; #(+  sun) :+    ac_cv_cflags_warn_all="-v" ;; #(+  hp) :+    ac_cv_cflags_warn_all="+w1" ;; #(+  dec) :+    ac_cv_cflags_warn_all="-verbose -w0 -warnprotos" ;; #(+  borland) :+     ;; #(+  comeau) :+     ;; #(+  kai) :+     ;; #(+  lcc) :+     ;; #(+  sgi) :+    ac_cv_cflags_warn_all="-fullwarn" ;; #(+  microsoft) :+     ;; #(+  metrowerks) :+     ;; #(+  watcom) :+     ;; #(+  tcc) :+     ;; #(+  unknown) :++				    ac_cv_cflags_warn_all=""+				    ac_save_cflags_warn_all_found="no"+				 ;; #(+  *) :++				    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Unknown compiler vendor returned by AX_COMPILER_VENDOR" >&5+printf "%s\n" "$as_me: WARNING: Unknown compiler vendor returned by AX_COMPILER_VENDOR" >&2;}+				    ac_cv_cflags_warn_all=""+				    ac_save_cflags_warn_all_found="no"++	 ;;+esac++	if test "x$ac_save_cflags_warn_all_found" = "xyes"+then :+  	    if test "x$ac_cv_cflags_warn_all" != "x"+then :++if test ${CFLAGS+y}+then :++  case " $CFLAGS " in #(+  *" $ac_cv_cflags_warn_all "*) :+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5+  (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } ;; #(+  *) :++     CFLAGS="$ac_cv_cflags_warn_all $CFLAGS"+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5+  (: CFLAGS="$CFLAGS") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+     ;;+esac++else case e in #(+  e)+  CFLAGS=$ac_cv_cflags_warn_all+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5+  (: CFLAGS="$CFLAGS") 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+   ;;+esac+fi++fi++else case e in #(+  e) 	    true+	 ;;+esac+fi     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5+printf "%s\n" "$ac_cv_cflags_warn_all" >&6; }++    ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++fi++if test "x$GCC" = "xyes"; then+  CFLAGS="$CFLAGS -fexceptions"+fi++cat > local.exp <<EOF+set CC_FOR_TARGET "$CC"+set CXX_FOR_TARGET "$CXX"+set compiler_vendor "$ax_cv_c_compiler_vendor"+EOF+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5+printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }+    # Check whether --enable-maintainer-mode was given.+if test ${enable_maintainer_mode+y}+then :+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval+else case e in #(+  e) USE_MAINTAINER_MODE=no ;;+esac+fi++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5+printf "%s\n" "$USE_MAINTAINER_MODE" >&6; }+   if test $USE_MAINTAINER_MODE = yes; then+  MAINTAINER_MODE_TRUE=+  MAINTAINER_MODE_FALSE='#'+else+  MAINTAINER_MODE_TRUE='#'+  MAINTAINER_MODE_FALSE=+fi++  MAINT=$MAINTAINER_MODE_TRUE++++ac_fn_c_check_header_compile "$LINENO" "sys/memfd.h" "ac_cv_header_sys_memfd_h" "$ac_includes_default"+if test "x$ac_cv_header_sys_memfd_h" = xyes+then :+  printf "%s\n" "#define HAVE_SYS_MEMFD_H 1" >>confdefs.h++fi++ac_fn_c_check_func "$LINENO" "memfd_create" "ac_cv_func_memfd_create"+if test "x$ac_cv_func_memfd_create" = xyes+then :+  printf "%s\n" "#define HAVE_MEMFD_CREATE 1" >>confdefs.h++fi+++HAVE_LONG_DOUBLE_VARIANT=0++. ${srcdir}/configure.host++if test -n "${UNSUPPORTED}"; then+  as_fn_error $? "\"libffi has not been ported to $host.\"" "$LINENO" 5+fi++++++ac_fn_c_check_func "$LINENO" "memcpy" "ac_cv_func_memcpy"+if test "x$ac_cv_func_memcpy" = xyes+then :+  printf "%s\n" "#define HAVE_MEMCPY 1" >>confdefs.h++fi++ac_fn_c_check_header_compile "$LINENO" "alloca.h" "ac_cv_header_alloca_h" "$ac_includes_default"+if test "x$ac_cv_header_alloca_h" = xyes+then :+  printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h++fi+++# The cast to long int works around a bug in the HP C Compiler+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects+# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'.+# This bug is HP SR number 8606223364.+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of double" >&5+printf %s "checking size of double... " >&6; }+if test ${ac_cv_sizeof_double+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double"        "$ac_includes_default"+then :++else case e in #(+  e) if test "$ac_cv_type_double" = yes; then+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error 77 "cannot compute sizeof (double)+See 'config.log' for more details" "$LINENO" 5; }+   else+     ac_cv_sizeof_double=0+   fi ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5+printf "%s\n" "$ac_cv_sizeof_double" >&6; }++++printf "%s\n" "#define SIZEOF_DOUBLE $ac_cv_sizeof_double" >>confdefs.h+++# The cast to long int works around a bug in the HP C Compiler+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects+# declarations like 'int a3[[(sizeof (unsigned char)) >= 0]];'.+# This bug is HP SR number 8606223364.+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5+printf %s "checking size of long double... " >&6; }+if test ${ac_cv_sizeof_long_double+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double"        "$ac_includes_default"+then :++else case e in #(+  e) if test "$ac_cv_type_long_double" = yes; then+     { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error 77 "cannot compute sizeof (long double)+See 'config.log' for more details" "$LINENO" 5; }+   else+     ac_cv_sizeof_long_double=0+   fi ;;+esac+fi+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5+printf "%s\n" "$ac_cv_sizeof_long_double" >&6; }++++printf "%s\n" "#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double" >>confdefs.h++++# Also AC_SUBST this variable for ffi.h.+if test -z "$HAVE_LONG_DOUBLE"; then+  HAVE_LONG_DOUBLE=0+  if test $ac_cv_sizeof_long_double != 0; then+    if test $HAVE_LONG_DOUBLE_VARIANT != 0; then++printf "%s\n" "#define HAVE_LONG_DOUBLE_VARIANT 1" >>confdefs.h++      HAVE_LONG_DOUBLE=1+    else+      if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then+        HAVE_LONG_DOUBLE=1++printf "%s\n" "#define HAVE_LONG_DOUBLE 1" >>confdefs.h++      fi+    fi+  fi+fi++++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5+printf %s "checking whether byte ordering is bigendian... " >&6; }+if test ${ac_cv_c_bigendian+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) ac_cv_c_bigendian=unknown+    # See if we're dealing with a universal compiler.+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#ifndef __APPLE_CC__+	       not a universal capable compiler+	     #endif+	     typedef int dummy;++_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :++	# Check for potential -arch flags.  It is not universal unless+	# there are at least two -arch flags with different values.+	ac_arch=+	ac_prev=+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do+	 if test -n "$ac_prev"; then+	   case $ac_word in+	     i?86 | x86_64 | ppc | ppc64)+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then+		 ac_arch=$ac_word+	       else+		 ac_cv_c_bigendian=universal+		 break+	       fi+	       ;;+	   esac+	   ac_prev=+	 elif test "x$ac_word" = "x-arch"; then+	   ac_prev=arch+	 fi+       done+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+    if test $ac_cv_c_bigendian = unknown; then+      # See if sys/param.h defines the BYTE_ORDER macro.+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <sys/types.h>+	     #include <sys/param.h>++int+main (void)+{+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \\+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \\+		     && LITTLE_ENDIAN)+	      bogus endian macros+	     #endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  # It does; now see whether it defined to BIG_ENDIAN or not.+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <sys/types.h>+		#include <sys/param.h>++int+main (void)+{+#if BYTE_ORDER != BIG_ENDIAN+		 not big endian+		#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_c_bigendian=yes+else case e in #(+  e) ac_cv_c_bigendian=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+    fi+    if test $ac_cv_c_bigendian = unknown; then+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <limits.h>++int+main (void)+{+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)+	      bogus endian macros+	     #endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  # It does; now see whether it defined to _BIG_ENDIAN or not.+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <limits.h>++int+main (void)+{+#ifndef _BIG_ENDIAN+		 not big endian+		#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ac_cv_c_bigendian=yes+else case e in #(+  e) ac_cv_c_bigendian=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+    fi+    if test $ac_cv_c_bigendian = unknown; then+      # Compile a test program.+      if test "$cross_compiling" = yes+then :+  # Try to guess by grepping values from an object file.+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+unsigned short int ascii_mm[] =+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };+		unsigned short int ascii_ii[] =+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };+		int use_ascii (int i) {+		  return ascii_mm[i] + ascii_ii[i];+		}+		unsigned short int ebcdic_ii[] =+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };+		unsigned short int ebcdic_mm[] =+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };+		int use_ebcdic (int i) {+		  return ebcdic_mm[i] + ebcdic_ii[i];+		}+		int+		main (int argc, char **argv)+		{+		  /* Intimidate the compiler so that it does not+		     optimize the arrays away.  */+		  char *p = argv[0];+		  ascii_mm[1] = *p++; ebcdic_mm[1] = *p++;+		  ascii_ii[1] = *p++; ebcdic_ii[1] = *p++;+		  return use_ascii (argc) == use_ebcdic (*p);+		}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  if grep BIGenDianSyS conftest$ac_exeext >/dev/null; then+	      ac_cv_c_bigendian=yes+	    fi+	    if grep LiTTleEnDian conftest$ac_exeext >/dev/null ; then+	      if test "$ac_cv_c_bigendian" = unknown; then+		ac_cv_c_bigendian=no+	      else+		# finding both strings is unlikely to happen, but who knows?+		ac_cv_c_bigendian=unknown+	      fi+	    fi+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$ac_includes_default+int+main (void)+{++	     /* Are we little or big endian?  From Harbison&Steele.  */+	     union+	     {+	       long int l;+	       char c[sizeof (long int)];+	     } u;+	     u.l = 1;+	     return u.c[sizeof (long int) - 1] == 1;++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  ac_cv_c_bigendian=no+else case e in #(+  e) ac_cv_c_bigendian=yes ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi++    fi ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5+printf "%s\n" "$ac_cv_c_bigendian" >&6; }+ case $ac_cv_c_bigendian in #(+   yes)+     printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h+;; #(+   no)+      ;; #(+   universal)++printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h++     ;; #(+   *)+     as_fn_error $? "unknown endianness+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;+ esac++++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking assembler .cfi pseudo-op support" >&5+printf %s "checking assembler .cfi pseudo-op support... " >&6; }+if test ${gcc_cv_as_cfi_pseudo_op+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)  ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++        #ifdef _MSC_VER+        Nope.+        #endif+        int foo (void)+        {+          __asm__ (".cfi_remember_state\n\t"+                   ".cfi_restore_state\n\t");+          return 0;+        }++_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  gcc_cv_as_cfi_pseudo_op=yes+else case e in #(+  e) gcc_cv_as_cfi_pseudo_op=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+    ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++   ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cfi_pseudo_op" >&5+printf "%s\n" "$gcc_cv_as_cfi_pseudo_op" >&6; }++  if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then++printf "%s\n" "#define HAVE_AS_CFI_PSEUDO_OP 1" >>confdefs.h++  fi+++++case "$TARGET" in+  SPARC)+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking assembler and linker support unaligned pc related relocs" >&5+printf %s "checking assembler and linker support unaligned pc related relocs... " >&6; }+if test ${libffi_cv_as_sparc_ua_pcrel+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+	save_CFLAGS="$CFLAGS"+	save_LDFLAGS="$LDFLAGS"+	CFLAGS="$CFLAGS -fpic"+	LDFLAGS="$LDFLAGS -shared"+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");+int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  libffi_cv_as_sparc_ua_pcrel=yes+else case e in #(+  e) libffi_cv_as_sparc_ua_pcrel=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+	CFLAGS="$save_CFLAGS"+	LDFLAGS="$save_LDFLAGS" ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_sparc_ua_pcrel" >&5+printf "%s\n" "$libffi_cv_as_sparc_ua_pcrel" >&6; }+    if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then++printf "%s\n" "#define HAVE_AS_SPARC_UA_PCREL 1" >>confdefs.h++    fi++    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking assembler .register pseudo-op support" >&5+printf %s "checking assembler .register pseudo-op support... " >&6; }+if test ${libffi_cv_as_register_pseudo_op+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+       libffi_cv_as_register_pseudo_op=unknown+       # Check if we have .register+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{+asm (".register %g2, #scratch");+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  libffi_cv_as_register_pseudo_op=yes+else case e in #(+  e) libffi_cv_as_register_pseudo_op=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+     ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_register_pseudo_op" >&5+printf "%s\n" "$libffi_cv_as_register_pseudo_op" >&6; }+    if test "x$libffi_cv_as_register_pseudo_op" = xyes; then++printf "%s\n" "#define HAVE_AS_REGISTER_PSEUDO_OP 1" >>confdefs.h++    fi+    ;;++  X86*)+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking assembler supports pc related relocs" >&5+printf %s "checking assembler supports pc related relocs... " >&6; }+if test ${libffi_cv_as_x86_pcrel+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+	libffi_cv_as_x86_pcrel=no+	echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s+	if $CC $CFLAGS -c conftest.s > /dev/null 2>&1; then+	    libffi_cv_as_x86_pcrel=yes+	fi+	 ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_x86_pcrel" >&5+printf "%s\n" "$libffi_cv_as_x86_pcrel" >&6; }+    if test "x$libffi_cv_as_x86_pcrel" = xyes; then++printf "%s\n" "#define HAVE_AS_X86_PCREL 1" >>confdefs.h++    fi+    ;;++  S390)+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking compiler uses zarch features" >&5+printf %s "checking compiler uses zarch features... " >&6; }+if test ${libffi_cv_as_s390_zarch+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+	libffi_cv_as_s390_zarch=no+	echo 'void foo(void) { bar(); bar(); }' > conftest.c+	if $CC $CFLAGS -S conftest.c > /dev/null 2>&1; then+	    if $GREP -q brasl conftest.s; then+	        libffi_cv_as_s390_zarch=yes+	    fi+	fi+	 ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_s390_zarch" >&5+printf "%s\n" "$libffi_cv_as_s390_zarch" >&6; }+    if test "x$libffi_cv_as_s390_zarch" = xyes; then++printf "%s\n" "#define HAVE_AS_S390_ZARCH 1" >>confdefs.h++    fi+    ;;+  wasm64)+    if test -z "$WASM64_MEMORY64"; then+      WASM64_MEMORY64=1+    fi+    CFLAGS="$CFLAGS -sMEMORY64=$WASM64_MEMORY64"+    ;;+esac++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports pointer authentication" >&5+printf %s "checking whether compiler supports pointer authentication... " >&6; }+if test ${libffi_cv_as_ptrauth+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+   libffi_cv_as_ptrauth=unknown+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++#ifdef __clang__+# if __has_feature(ptrauth_calls)+#  define HAVE_ARM64E_PTRAUTH 1+# endif+#endif++#ifndef HAVE_ARM64E_PTRAUTH+# error Pointer authentication not supported+#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  libffi_cv_as_ptrauth=yes+else case e in #(+  e) libffi_cv_as_ptrauth=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+ ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_ptrauth" >&5+printf "%s\n" "$libffi_cv_as_ptrauth" >&6; }+if test "x$libffi_cv_as_ptrauth" = xyes; then++printf "%s\n" "#define HAVE_ARM64E_PTRAUTH 1" >>confdefs.h++fi++# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC;+# if EMUTRAMP is active too ffi could try mapping without PROT_EXEC,+# but the kernel needs to recognize the trampoline generated by ffi.+# Otherwise fallback to double mmap trick.+# Check whether --enable-pax_emutramp was given.+if test ${enable_pax_emutramp+y}+then :+  enableval=$enable_pax_emutramp; if test "$enable_pax_emutramp" = "yes"; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: EMUTRAMP is experimental only.  Use --enable-pax_emutramp=experimental to enforce." >&5+printf "%s\n" "$as_me: WARNING: EMUTRAMP is experimental only.  Use --enable-pax_emutramp=experimental to enforce." >&2;}+  elif test "$enable_pax_emutramp" = "experimental"; then++printf "%s\n" "#define FFI_MMAP_EXEC_EMUTRAMP_PAX 1" >>confdefs.h++  fi+fi+++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5+printf %s "checking for _ prefix in compiled symbols... " >&6; }+if test ${lt_cv_sys_symbol_underscore+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e) lt_cv_sys_symbol_underscore=no+  cat > conftest.$ac_ext <<_LT_EOF+void nm_test_func(){}+int main(void){nm_test_func;return 0;}+_LT_EOF+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5+  (eval $ac_compile) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then+    # Now try to grab the symbols.+    ac_nlist=conftest.nm+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist\""; } >&5+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && test -s "$ac_nlist"; then+      # See whether the symbols have a leading underscore.+      if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then+        lt_cv_sys_symbol_underscore=yes+      else+        if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then+	  :+        else+	  echo "configure: cannot find nm_test_func in $ac_nlist" >&5+        fi+      fi+    else+      echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5+    fi+  else+    echo "configure: failed program was:" >&5+    cat conftest.c >&5+  fi+  rm -rf conftest*+   ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_symbol_underscore" >&5+printf "%s\n" "$lt_cv_sys_symbol_underscore" >&6; }+  sys_symbol_underscore=$lt_cv_sys_symbol_underscore+++if test "x$sys_symbol_underscore" = xyes; then++printf "%s\n" "#define SYMBOL_UNDERSCORE 1" >>confdefs.h++fi++FFI_EXEC_TRAMPOLINE_TABLE=0+case "$target" in+     *arm*-apple-* | aarch64-apple-*)+       FFI_EXEC_TRAMPOLINE_TABLE=1++printf "%s\n" "#define FFI_EXEC_TRAMPOLINE_TABLE 1" >>confdefs.h++     ;;+     *-apple-* | *-*-dragonfly* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*)++printf "%s\n" "#define FFI_MMAP_EXEC_WRIT 1" >>confdefs.h++     ;;+esac+ if test x$FFI_EXEC_TRAMPOLINE_TABLE = x1; then+  FFI_EXEC_TRAMPOLINE_TABLE_TRUE=+  FFI_EXEC_TRAMPOLINE_TABLE_FALSE='#'+else+  FFI_EXEC_TRAMPOLINE_TABLE_TRUE='#'+  FFI_EXEC_TRAMPOLINE_TABLE_FALSE=+fi++++if test x$TARGET = xX86_64; then+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking toolchain supports unwind section type" >&5+printf %s "checking toolchain supports unwind section type... " >&6; }+if test ${libffi_cv_as_x86_64_unwind_section_type+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+        cat  > conftest1.s << EOF+.text+.globl foo+foo:+jmp bar+.section .eh_frame,"a",@unwind+bar:+EOF++        cat > conftest2.c  << EOF+extern void foo();+int main(){foo();}+EOF++	libffi_cv_as_x86_64_unwind_section_type=no+	# we ensure that we can compile _and_ link an assembly file containing an @unwind section+	# since the compiler can support it and not the linker (ie old binutils)+	if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \+           $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then+	    libffi_cv_as_x86_64_unwind_section_type=yes+	fi+	 ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_as_x86_64_unwind_section_type" >&5+printf "%s\n" "$libffi_cv_as_x86_64_unwind_section_type" >&6; }+    if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then++printf "%s\n" "#define HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1" >>confdefs.h++    fi+fi++if test "x$GCC" = "xyes"; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts -fno-lto" >&5+printf %s "checking whether the C compiler accepts -fno-lto... " >&6; }+if test ${ax_cv_check_cflags___fno_lto+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  ax_check_save_flags=$CFLAGS+  if test x"$GCC" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  CFLAGS="$CFLAGS  -fno-lto $add_gnu_werror"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"+then :+  ax_cv_check_cflags___fno_lto=yes+else case e in #(+  e) ax_cv_check_cflags___fno_lto=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext+  CFLAGS=$ax_check_save_flags ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_lto" >&5+printf "%s\n" "$ax_cv_check_cflags___fno_lto" >&6; }+if test "x$ax_cv_check_cflags___fno_lto" = xyes+then :+  libffi_cv_no_lto=-fno-lto+else case e in #(+  e) : ;;+esac+fi+++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5+printf %s "checking whether .eh_frame section should be read-only... " >&6; }+if test ${libffi_cv_ro_eh_frame+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  	libffi_cv_ro_eh_frame=yes+  	echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c+  	if $CC $CFLAGS -c -fpic -fexceptions $libffi_cv_no_lto -o conftest.o conftest.c > /dev/null 2>&1; then+	    if $READELF -WS conftest.o 2>/dev/null | $GREP -q -n 'eh_frame .* WA'; then+	        libffi_cv_ro_eh_frame=no+	    fi+  	fi+  	rm -f conftest.*+       ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_ro_eh_frame" >&5+printf "%s\n" "$libffi_cv_ro_eh_frame" >&6; }+  if test "x$libffi_cv_ro_eh_frame" = xyes; then++printf "%s\n" "#define HAVE_RO_EH_FRAME 1" >>confdefs.h+++printf "%s\n" "#define EH_FRAME_FLAGS \"a\"" >>confdefs.h++  else++printf "%s\n" "#define EH_FRAME_FLAGS \"aw\"" >>confdefs.h++  fi++  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5+printf %s "checking for __attribute__((visibility(\"hidden\")))... " >&6; }+if test ${libffi_cv_hidden_visibility_attribute+y}+then :+  printf %s "(cached) " >&6+else case e in #(+  e)+  	echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c+  	libffi_cv_hidden_visibility_attribute=no+  	if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5'+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5+  (eval $ac_try) 2>&5+  ac_status=$?+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; }; then+  	    if $EGREP '(\.hidden|\.private_extern).*foo|foo.*,hidden' conftest.s >/dev/null; then+  		libffi_cv_hidden_visibility_attribute=yes+  	    fi+  	fi+  	rm -f conftest.*+       ;;+esac+fi+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_hidden_visibility_attribute" >&5+printf "%s\n" "$libffi_cv_hidden_visibility_attribute" >&6; }+  if test $libffi_cv_hidden_visibility_attribute = yes; then++printf "%s\n" "#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1" >>confdefs.h++  fi+fi++++++EXTRA_SOURCES=` printf " %s " "$SOURCES" | sed -E "s/ ([^ ]+)/src\/$TARGETDIR\/\1 /g" `++EXTRA_ASM_SOURCES=` printf " %s " "$ASM_SOURCES" | sed -E "s/ ([^ ]+)/src\/$TARGETDIR\/\1 /g" `+++# Check whether --enable-debug was given.+if test ${enable_debug+y}+then :+  enableval=$enable_debug; if test "$enable_debug" = "yes"; then++printf "%s\n" "#define FFI_DEBUG 1" >>confdefs.h++  fi+fi++ if test "$enable_debug" = "yes"; then+  FFI_DEBUG_TRUE=+  FFI_DEBUG_FALSE='#'+else+  FFI_DEBUG_TRUE='#'+  FFI_DEBUG_FALSE=+fi+++# Check whether --enable-structs was given.+if test ${enable_structs+y}+then :+  enableval=$enable_structs; if test "$enable_structs" = "no"; then++printf "%s\n" "#define FFI_NO_STRUCTS 1" >>confdefs.h++  fi+fi++ if test "$enable_debug" = "yes"; then+  FFI_DEBUG_TRUE=+  FFI_DEBUG_FALSE='#'+else+  FFI_DEBUG_TRUE='#'+  FFI_DEBUG_FALSE=+fi+++# Check whether --enable-raw-api was given.+if test ${enable_raw_api+y}+then :+  enableval=$enable_raw_api; if test "$enable_raw_api" = "no"; then++printf "%s\n" "#define FFI_NO_RAW_API 1" >>confdefs.h++  fi+fi+++# Check whether --enable-exec-static-tramp was given.+if test ${enable_exec_static_tramp+y}+then :+  enableval=$enable_exec_static_tramp;+fi+++if test "$enable_exec_static_tramp" != no; then+case "$target" in+     *-cygwin* | *-msys*)+       # Only define static trampolines if we are using the cygwin runtime.+       # Will this need to be changed for mingw?+       if test "x$GCC" = "xyes"; then++printf "%s\n" "#define FFI_EXEC_STATIC_TRAMP 1" >>confdefs.h++       fi+     ;;+     *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* \+     | loongarch*-*-linux-* | s390x*-linux-* | powerpc*-linux-*)++printf "%s\n" "#define FFI_EXEC_STATIC_TRAMP 1" >>confdefs.h++     ;;+esac+fi++# Check whether --enable-purify-safety was given.+if test ${enable_purify_safety+y}+then :+  enableval=$enable_purify_safety; if test "$enable_purify_safety" = "yes"; then++printf "%s\n" "#define USING_PURIFY 1" >>confdefs.h++  fi+fi+++# Check linker support.++  # 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=''++++  # 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+  libat_ld_is_lld=no+  if $LD --version 2>/dev/null | grep 'LLD '> /dev/null 2>&1; then+    libat_ld_is_lld=yes+  fi+  libat_ld_is_mold=no+  if $LD --version 2>/dev/null | grep 'mold '> /dev/null 2>&1; then+    libat_ld_is_mold=yes+  fi++  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'`++  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.+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld that supports -Wl,--gc-sections" >&5+printf %s "checking for ld that supports -Wl,--gc-sections... " >&6; }+    if test "$cross_compiling" = yes+then :+  ac_sectionLDflags=yes+else case e in #(+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++     int main(void)+     {+       try { throw 1; }+       catch (...) { };+       return 0;+     }++_ACEOF+if ac_fn_c_try_run "$LINENO"+then :+  ac_sectionLDflags=yes+else case e in #(+  e) ac_sectionLDflags=no ;;+esac+fi+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \+  conftest.$ac_objext conftest.beam conftest.$ac_ext ;;+esac+fi++    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+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_sectionLDflags" >&5+printf "%s\n" "$ac_sectionLDflags" >&6; }+  fi++  # Set linker optimization flags.+  if test x"$with_gnu_ld" = x"yes"; then+    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"+  fi+++++++ # Check whether --enable-symvers was given.+if test ${enable_symvers+y}+then :+  enableval=$enable_symvers;+      case "$enableval" in+       yes|no|gnu*|sun) ;;+       *) as_fn_error $? "Unknown argument to enable/disable symvers" "$LINENO" 5 ;;+                          esac++else case e in #(+  e) enable_symvers=yes ;;+esac+fi++++# If we never went through the LIBFFI_CHECK_LINKER_FEATURES macro, then we+# don't know enough about $LD to do tricks...+++# 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.+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === You have requested Sun symbol versioning, but" >&5+printf "%s\n" "$as_me: WARNING: === You have requested Sun symbol versioning, but" >&2;}+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === you are not targetting Solaris 2." >&5+printf "%s\n" "$as_me: WARNING: === you are not targetting Solaris 2." >&2;}+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === Symbol versioning will be disabled." >&5+printf "%s\n" "$as_me: WARNING: === Symbol versioning will be disabled." >&2;}+      enable_symvers=no+      ;;+  esac+fi++# Check to see if libgcc_s exists, indicating that shared libgcc is possible.+if test $enable_symvers != no; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shared libgcc" >&5+printf %s "checking for shared libgcc... " >&6; }+  ac_save_CFLAGS="$CFLAGS"+  CFLAGS=' -lgcc_s'+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{+return 0;+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  libat_shared_libgcc=yes+else case e in #(+  e) libat_shared_libgcc=no ;;+esac+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+  CFLAGS="$ac_save_CFLAGS"+  if test $libat_shared_libgcc = no; then+    cat > conftest.c <<EOF+int main (void) { return 0; }+EOF+    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'`+    rm -f conftest.c conftest.so+    if test x${libat_libgcc_s_suffix+set} = xset; then+      CFLAGS=" -lgcc_s$libat_libgcc_s_suffix"+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main (void)+{+return 0;+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"+then :+  libat_shared_libgcc=yes+fi+rm -f core conftest.err conftest.$ac_objext conftest.beam \+    conftest$ac_exeext conftest.$ac_ext+      CFLAGS="$ac_save_CFLAGS"+    fi+  fi+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libat_shared_libgcc" >&5+printf "%s\n" "$libat_shared_libgcc" >&6; }+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+    elif test $libat_ld_is_lld = yes ; then+      enable_symvers=gnu+    elif test $libat_ld_is_mold = yes ; then+      enable_symvers=gnu+    else+      # The right tools, the right setup, but too old.  Fallbacks?+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === Linker version $libat_gnu_ld_version is too old for" >&5+printf "%s\n" "$as_me: WARNING: === Linker version $libat_gnu_ld_version is too old for" >&2;}+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === full symbol versioning support in this release of GCC." >&5+printf "%s\n" "$as_me: WARNING: === full symbol versioning support in this release of GCC." >&2;}+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === You would need to upgrade your binutils to version" >&5+printf "%s\n" "$as_me: WARNING: === You would need to upgrade your binutils to version" >&2;}+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === $libat_min_gnu_ld_version or later and rebuild GCC." >&5+printf "%s\n" "$as_me: WARNING: === $libat_min_gnu_ld_version or later and rebuild GCC." >&2;}+      if test $libat_gnu_ld_version -ge 21200 ; then+        # Globbing fix is present, proper block support is not.+                        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === Symbol versioning will be disabled." >&5+printf "%s\n" "$as_me: WARNING: === Symbol versioning will be disabled." >&2;}+        enable_symvers=no+      else+        # 2.11 or older.+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === Symbol versioning will be disabled." >&5+printf "%s\n" "$as_me: WARNING: === Symbol versioning will be disabled." >&2;}+        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+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === You have requested some kind of symbol versioning, but" >&5+printf "%s\n" "$as_me: WARNING: === You have requested some kind of symbol versioning, but" >&2;}+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === either you are not using a supported linker, or you are" >&5+printf "%s\n" "$as_me: WARNING: === either you are not using a supported linker, or you are" >&2;}+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === not building a shared libgcc_s (which is required)." >&5+printf "%s\n" "$as_me: WARNING: === not building a shared libgcc_s (which is required)." >&2;}+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: === Symbol versioning will be disabled." >&5+printf "%s\n" "$as_me: WARNING: === Symbol versioning will be disabled." >&2;}+    enable_symvers=no+  fi+fi+if test $enable_symvers = gnu; then++printf "%s\n" "#define LIBFFI_GNU_SYMBOL_VERSIONING 1" >>confdefs.h++fi++ if test $enable_symvers != no; then+  LIBFFI_BUILD_VERSIONED_SHLIB_TRUE=+  LIBFFI_BUILD_VERSIONED_SHLIB_FALSE='#'+else+  LIBFFI_BUILD_VERSIONED_SHLIB_TRUE='#'+  LIBFFI_BUILD_VERSIONED_SHLIB_FALSE=+fi++ if test $enable_symvers = gnu; then+  LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE=+  LIBFFI_BUILD_VERSIONED_SHLIB_GNU_FALSE='#'+else+  LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE='#'+  LIBFFI_BUILD_VERSIONED_SHLIB_GNU_FALSE=+fi++ if test $enable_symvers = sun; then+  LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE=+  LIBFFI_BUILD_VERSIONED_SHLIB_SUN_FALSE='#'+else+  LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE='#'+  LIBFFI_BUILD_VERSIONED_SHLIB_SUN_FALSE=+fi++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: versioning on shared library symbols is $enable_symvers" >&5+printf "%s\n" "$as_me: versioning on shared library symbols is $enable_symvers" >&6;}+++ac_config_files="$ac_config_files include/ffi.h"+++EXTRA_LIBS=` printf " %s " "$LIBS" | sed -E 's/ -l([^ ]*)/\1 /g' `++ac_config_files="$ac_config_files libffi-clib.buildinfo"+++cat >confcache <<\_ACEOF+# This file is a shell script that caches the results of configure+# tests run on this system so they can be shared between configure+# scripts and configure runs, see configure's option --config-cache.+# It is not useful on other systems.  If it contains results you don't+# want to keep, you may remove or edit it.+#+# config.status only pays attention to the cache file if you give it+# the --recheck option to rerun configure.+#+# 'ac_cv_env_foo' variables (set or unset) will be overridden when+# loading this file, other *unset* 'ac_cv_foo' will be assigned the+# following values.++_ACEOF++# The following way of writing the cache mishandles newlines in values,+# but we know of no workaround that is simple, portable, and efficient.+# So, we kill variables containing newlines.+# Ultrix sh set writes to stderr and can't be redirected directly,+# and sets the high bit in the cache file unless we assign to the vars.+(+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do+    eval ac_val=\$$ac_var+    case $ac_val in #(+    *${as_nl}*)+      case $ac_var in #(+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+      esac+      case $ac_var in #(+      _ | IFS | as_nl) ;; #(+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+      *) { eval $ac_var=; unset $ac_var;} ;;+      esac ;;+    esac+  done++  (set) 2>&1 |+    case $as_nl`(ac_space=' '; set) 2>&1` in #(+    *${as_nl}ac_space=\ *)+      # 'set' does not quote correctly, so add quotes: double-quote+      # substitution turns \\\\ into \\, and sed turns \\ into \.+      sed -n \+	"s/'/'\\\\''/g;+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"+      ;; #(+    *)+      # 'set' quotes correctly as required by POSIX, so do not add quotes.+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+      ;;+    esac |+    sort+) |+  sed '+     /^ac_cv_env_/b end+     t clear+     :clear+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/+     t end+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/+     :end' >>confcache+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else+  if test -w "$cache_file"; then+    if test "x$cache_file" != "x/dev/null"; then+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}+      if test ! -f "$cache_file" || test -h "$cache_file"; then+	cat confcache >"$cache_file"+      else+        case $cache_file in #(+        */* | ?:*)+	  mv -f confcache "$cache_file"$$ &&+	  mv -f "$cache_file"$$ "$cache_file" ;; #(+        *)+	  mv -f confcache "$cache_file" ;;+	esac+      fi+    fi+  else+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}+  fi+fi+rm -f confcache++test "x$prefix" = xNONE && prefix=$ac_default_prefix+# Let make expand exec_prefix.+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'++DEFS=-DHAVE_CONFIG_H++ac_libobjs=+ac_ltlibobjs=+U=+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue+  # 1. Remove the extension, and $U if already installed.+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR+  #    will be set to the directory where LIBOBJS objects are built.+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'+done+LIBOBJS=$ac_libobjs++LTLIBOBJS=$ac_ltlibobjs+++if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then+  as_fn_error $? "conditional \"AMDEP\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then+  as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi++if test -z "${FFI_EXEC_TRAMPOLINE_TABLE_TRUE}" && test -z "${FFI_EXEC_TRAMPOLINE_TABLE_FALSE}"; then+  as_fn_error $? "conditional \"FFI_EXEC_TRAMPOLINE_TABLE\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${FFI_DEBUG_TRUE}" && test -z "${FFI_DEBUG_FALSE}"; then+  as_fn_error $? "conditional \"FFI_DEBUG\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${FFI_DEBUG_TRUE}" && test -z "${FFI_DEBUG_FALSE}"; then+  as_fn_error $? "conditional \"FFI_DEBUG\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${LIBFFI_BUILD_VERSIONED_SHLIB_TRUE}" && test -z "${LIBFFI_BUILD_VERSIONED_SHLIB_FALSE}"; then+  as_fn_error $? "conditional \"LIBFFI_BUILD_VERSIONED_SHLIB\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${LIBFFI_BUILD_VERSIONED_SHLIB_GNU_TRUE}" && test -z "${LIBFFI_BUILD_VERSIONED_SHLIB_GNU_FALSE}"; then+  as_fn_error $? "conditional \"LIBFFI_BUILD_VERSIONED_SHLIB_GNU\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi+if test -z "${LIBFFI_BUILD_VERSIONED_SHLIB_SUN_TRUE}" && test -z "${LIBFFI_BUILD_VERSIONED_SHLIB_SUN_FALSE}"; then+  as_fn_error $? "conditional \"LIBFFI_BUILD_VERSIONED_SHLIB_SUN\" was never defined.+Usually this means the macro was only invoked conditionally." "$LINENO" 5+fi++: "${CONFIG_STATUS=./config.status}"+ac_write_fail=0+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files $CONFIG_STATUS"+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}+as_write_fail=0+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1+#! $SHELL+# Generated by $as_me.+# Run this file to recreate the current configuration.+# Compiler output produced by configure, useful for debugging+# configure, is in config.log if it exists.++debug=false+ac_cs_recheck=false+ac_cs_silent=false++SHELL=\${CONFIG_SHELL-$SHELL}+export SHELL+_ASEOF+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1+## -------------------- ##+## M4sh Initialization. ##+## -------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1+then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else case e in #(+  e) case `(set -o) 2>/dev/null` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac ;;+esac+fi++++# Reset variables that may have inherited troublesome values from+# the environment.++# IFS needs to be set, to space, tab, and newline, in precisely that order.+# (If _AS_PATH_WALK were called with IFS unset, it would have the+# side effect of setting IFS to empty, thus disabling word splitting.)+# Quoting is to prevent editors from complaining about space-tab.+as_nl='+'+export as_nl+IFS=" ""	$as_nl"++PS1='$ '+PS2='> '+PS4='+ '++# Ensure predictable behavior from utilities with locale-dependent output.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# We cannot yet rely on "unset" to work, but we need these variables+# to be unset--not just set to an empty or harmless value--now, to+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct+# also avoids known problems related to "unset" and subshell syntax+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH+do eval test \${$as_var+y} \+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :+done++# Ensure that fds 0, 1, and 2 are open.+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi++# The user is always right.+if ${PATH_SEPARATOR+false} :; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# Find who we are.  Look in the path if we contain no directory separator.+as_myself=+case $0 in #((+  *[\\/]* ) as_myself=$0 ;;+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  case $as_dir in #(((+    '') as_dir=./ ;;+    */) ;;+    *) as_dir=$as_dir/ ;;+  esac+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break+  done+IFS=$as_save_IFS++     ;;+esac+# We did not find ourselves, most probably we were run as 'sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+  as_myself=$0+fi+if test ! -f "$as_myself"; then+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+  exit 1+fi++++# as_fn_error STATUS ERROR [LINENO LOG_FD]+# ----------------------------------------+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the+# script with STATUS, using 1 if that was 0.+as_fn_error ()+{+  as_status=$1; test $as_status -eq 0 && as_status=1+  if test "$4"; then+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4+  fi+  printf "%s\n" "$as_me: error: $2" >&2+  as_fn_exit $as_status+} # as_fn_error+++# as_fn_set_status STATUS+# -----------------------+# Set $? to STATUS, without forking.+as_fn_set_status ()+{+  return $1+} # as_fn_set_status++# as_fn_exit STATUS+# -----------------+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.+as_fn_exit ()+{+  set +e+  as_fn_set_status $1+  exit $1+} # as_fn_exit++# as_fn_unset VAR+# ---------------+# Portably unset VAR.+as_fn_unset ()+{+  { eval $1=; unset $1;}+}+as_unset=as_fn_unset++# as_fn_append VAR VALUE+# ----------------------+# Append the text in VALUE to the end of the definition contained in VAR. Take+# advantage of any shell optimizations that allow amortized linear growth over+# repeated appends, instead of the typical quadratic growth present in naive+# implementations.+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null+then :+  eval 'as_fn_append ()+  {+    eval $1+=\$2+  }'+else case e in #(+  e) as_fn_append ()+  {+    eval $1=\$$1\$2+  } ;;+esac+fi # as_fn_append++# as_fn_arith ARG...+# ------------------+# Perform arithmetic evaluation on the ARGs, and store the result in the+# global $as_val. Take advantage of shells that can avoid forks. The arguments+# must be portable across $(()) and expr.+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null+then :+  eval 'as_fn_arith ()+  {+    as_val=$(( $* ))+  }'+else case e in #(+  e) as_fn_arith ()+  {+    as_val=`expr "$@" || test $? -eq 1`+  } ;;+esac+fi # as_fn_arith+++if expr a : '\(a\)' >/dev/null 2>&1 &&+   test "X`expr 00001 : '.*\(...\)'`" = X001; then+  as_expr=expr+else+  as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+  as_basename=basename+else+  as_basename=false+fi++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+  as_dirname=dirname+else+  as_dirname=false+fi++as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$0" : 'X\(//\)$' \| \+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X/"$0" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`++# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits+++# Determine whether it's possible to make 'echo' print without a newline.+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed+# for compatibility with existing Makefiles.+ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in #(((((+-n*)+  case `echo 'xy\c'` in+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.+  xy)  ECHO_C='\c';;+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null+       ECHO_T='	';;+  esac;;+*)+  ECHO_N='-n';;+esac++# For backward compatibility with old third-party macros, we provide+# the shell variables $as_echo and $as_echo_n.  New code should use+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.+as_echo='printf %s\n'+as_echo_n='printf %s'++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+  rm -f conf$$.dir/conf$$.file+else+  rm -f conf$$.dir+  mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+  if ln -s conf$$.file conf$$ 2>/dev/null; then+    as_ln_s='ln -s'+    # ... but there are two gotchas:+    # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail.+    # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable.+    # In both cases, we have to default to 'cp -pR'.+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+      as_ln_s='cp -pR'+  elif ln conf$$.file conf$$ 2>/dev/null; then+    as_ln_s=ln+  else+    as_ln_s='cp -pR'+  fi+else+  as_ln_s='cp -pR'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null+++# as_fn_mkdir_p+# -------------+# Create "$as_dir" as a directory, including parents if necessary.+as_fn_mkdir_p ()+{++  case $as_dir in #(+  -*) as_dir=./$as_dir;;+  esac+  test -d "$as_dir" || eval $as_mkdir_p || {+    as_dirs=+    while :; do+      case $as_dir in #(+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+      *) as_qdir=$as_dir;;+      esac+      as_dirs="'$as_qdir' $as_dirs"+      as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_dir" : 'X\(//\)[^/]' \| \+	 X"$as_dir" : 'X\(//\)$' \| \+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X"$as_dir" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+      test -d "$as_dir" && break+    done+    test -z "$as_dirs" || eval "mkdir $as_dirs"+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"+++} # as_fn_mkdir_p+if mkdir -p . 2>/dev/null; then+  as_mkdir_p='mkdir -p "$as_dir"'+else+  test -d ./-p && rmdir ./-p+  as_mkdir_p=false+fi+++# as_fn_executable_p FILE+# -----------------------+# Test if FILE is an executable regular file.+as_fn_executable_p ()+{+  test -f "$1" && test -x "$1"+} # as_fn_executable_p+as_test_x='test -x'+as_executable_p=as_fn_executable_p++# Sed expression to map a string onto a valid CPP name.+as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"+as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated++# Sed expression to map a string onto a valid variable name.+as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g"+as_tr_sh="eval sed '$as_sed_sh'" # deprecated+++exec 6>&1+## ----------------------------------- ##+## Main body of $CONFIG_STATUS script. ##+## ----------------------------------- ##+_ASEOF+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# Save the log message, to keep $0 and so on meaningful, and to+# 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.5.2, which was+generated by GNU Autoconf 2.72.  Invocation command line was++  CONFIG_FILES    = $CONFIG_FILES+  CONFIG_HEADERS  = $CONFIG_HEADERS+  CONFIG_LINKS    = $CONFIG_LINKS+  CONFIG_COMMANDS = $CONFIG_COMMANDS+  $ $0 $@++on `(hostname || uname -n) 2>/dev/null | sed 1q`+"++_ACEOF++case $ac_config_files in *"+"*) set x $ac_config_files; shift; ac_config_files=$*;;+esac++case $ac_config_headers in *"+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;+esac+++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+# Files that config.status was made for.+config_files="$ac_config_files"+config_headers="$ac_config_headers"+config_commands="$ac_config_commands"++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+ac_cs_usage="\+'$as_me' instantiates files and other configuration actions+from templates according to the current configuration.  Unless the files+and actions are specified as TAGs, all are instantiated by default.++Usage: $0 [OPTION]... [TAG]...++  -h, --help       print this help, then exit+  -V, --version    print version number and configuration settings, then exit+      --config     print configuration, then exit+  -q, --quiet, --silent+                   do not print progress messages+  -d, --debug      don't remove temporary files+      --recheck    update $as_me by reconfiguring in the same conditions+      --file=FILE[:TEMPLATE]+                   instantiate the configuration file FILE+      --header=FILE[:TEMPLATE]+                   instantiate the configuration header FILE++Configuration files:+$config_files++Configuration headers:+$config_headers++Configuration commands:+$config_commands++Report bugs to <http://github.com/libffi/libffi/issues>."++_ACEOF+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_cs_config='$ac_cs_config_escaped'+ac_cs_version="\\+libffi config.status 3.5.2+configured by $0, generated by GNU Autoconf 2.72,+  with options \\"\$ac_cs_config\\"++Copyright (C) 2023 Free Software Foundation, Inc.+This config.status script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it."++ac_pwd='$ac_pwd'+srcdir='$srcdir'+AWK='$AWK'+test -n "\$AWK" || AWK=awk+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# The default lists apply if the user does not specify any file.+ac_need_defaults=:+while test $# != 0+do+  case $1 in+  --*=?*)+    ac_option=`expr "X$1" : 'X\([^=]*\)='`+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`+    ac_shift=:+    ;;+  --*=)+    ac_option=`expr "X$1" : 'X\([^=]*\)='`+    ac_optarg=+    ac_shift=:+    ;;+  *)+    ac_option=$1+    ac_optarg=$2+    ac_shift=shift+    ;;+  esac++  case $ac_option in+  # Handling of the options.+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)+    ac_cs_recheck=: ;;+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )+    printf "%s\n" "$ac_cs_version"; exit ;;+  --config | --confi | --conf | --con | --co | --c )+    printf "%s\n" "$ac_cs_config"; exit ;;+  --debug | --debu | --deb | --de | --d | -d )+    debug=: ;;+  --file | --fil | --fi | --f )+    $ac_shift+    case $ac_optarg in+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;+    '') as_fn_error $? "missing file argument" ;;+    esac+    as_fn_append CONFIG_FILES " '$ac_optarg'"+    ac_need_defaults=false;;+  --header | --heade | --head | --hea )+    $ac_shift+    case $ac_optarg in+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;+    esac+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"+    ac_need_defaults=false;;+  --he | --h)+    # Conflict between --help and --header+    as_fn_error $? "ambiguous option: '$1'+Try '$0 --help' for more information.";;+  --help | --hel | -h )+    printf "%s\n" "$ac_cs_usage"; exit ;;+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \+  | -silent | --silent | --silen | --sile | --sil | --si | --s)+    ac_cs_silent=: ;;++  # This is an error.+  -*) as_fn_error $? "unrecognized option: '$1'+Try '$0 --help' for more information." ;;++  *) as_fn_append ac_config_targets " $1"+     ac_need_defaults=false ;;++  esac+  shift+done++ac_configure_extra_args=++if $ac_cs_silent; then+  exec 6>/dev/null+  ac_configure_extra_args="$ac_configure_extra_args --silent"+fi++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+if \$ac_cs_recheck; then+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion+  shift+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6+  CONFIG_SHELL='$SHELL'+  export CONFIG_SHELL+  exec "\$@"+fi++_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+exec 5>>config.log+{+  echo+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX+## Running $as_me. ##+_ASBOX+  printf "%s\n" "$ac_log"+} >&5++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+#+# INIT-COMMANDS+#+ax_enable_builddir_srcdir="$srcdir"                    # $srcdir+ax_enable_builddir_host="$HOST"                        # $HOST / $host+ax_enable_builddir_version="$VERSION"                  # $VERSION+ax_enable_builddir_package="$PACKAGE"                  # $PACKAGE+ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX+ax_enable_builddir_sed="$ax_enable_builddir_sed"       # $SED+ax_enable_builddir="$ax_enable_builddir"               # $SUB++AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"+++# The HP-UX ksh and POSIX shell print the target directory to stdout+# if CDPATH is set.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH++sed_quote_subst='$sed_quote_subst'+double_quote_subst='$double_quote_subst'+delay_variable_subst='$delay_variable_subst'+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'+FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`'+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'+lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'++LTCC='$LTCC'+LTCFLAGS='$LTCFLAGS'+compiler='$compiler_DEFAULT'++# A function that is used when there is no print builtin or printf.+func_fallback_echo ()+{+  eval 'cat <<_LTECHO_EOF+\$1+_LTECHO_EOF'+}++# Quote evaled strings.+for var in SHELL \+ECHO \+PATH_SEPARATOR \+SED \+GREP \+EGREP \+FGREP \+LD \+NM \+LN_S \+lt_SP2NL \+lt_NL2SP \+reload_flag \+FILECMD \+OBJDUMP \+deplibs_check_method \+file_magic_cmd \+file_magic_glob \+want_nocaseglob \+DLLTOOL \+sharedlib_from_linklib_cmd \+AR \+archiver_list_spec \+STRIP \+RANLIB \+CC \+CFLAGS \+compiler \+lt_cv_sys_global_symbol_pipe \+lt_cv_sys_global_symbol_to_cdecl \+lt_cv_sys_global_symbol_to_import \+lt_cv_sys_global_symbol_to_c_name_address \+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \+lt_cv_nm_interface \+nm_file_list_spec \+lt_cv_truncate_bin \+lt_prog_compiler_no_builtin_flag \+lt_prog_compiler_pic \+lt_prog_compiler_wl \+lt_prog_compiler_static \+lt_cv_prog_compiler_c_o \+need_locks \+MANIFEST_TOOL \+DSYMUTIL \+NMEDIT \+LIPO \+OTOOL \+OTOOL64 \+shrext_cmds \+export_dynamic_flag_spec \+whole_archive_flag_spec \+compiler_needs_object \+with_gnu_ld \+allow_undefined_flag \+no_undefined_flag \+hardcode_libdir_flag_spec \+hardcode_libdir_separator \+exclude_expsyms \+include_expsyms \+file_list_spec \+variables_saved_for_relink \+libname_spec \+library_names_spec \+soname_spec \+install_override_mode \+finish_eval \+old_striplib \+striplib \+compiler_lib_search_dirs \+predep_objects \+postdep_objects \+predeps \+postdeps \+compiler_lib_search_path \+LD_CXX \+reload_flag_CXX \+compiler_CXX \+lt_prog_compiler_no_builtin_flag_CXX \+lt_prog_compiler_pic_CXX \+lt_prog_compiler_wl_CXX \+lt_prog_compiler_static_CXX \+lt_cv_prog_compiler_c_o_CXX \+export_dynamic_flag_spec_CXX \+whole_archive_flag_spec_CXX \+compiler_needs_object_CXX \+with_gnu_ld_CXX \+allow_undefined_flag_CXX \+no_undefined_flag_CXX \+hardcode_libdir_flag_spec_CXX \+hardcode_libdir_separator_CXX \+exclude_expsyms_CXX \+include_expsyms_CXX \+file_list_spec_CXX \+compiler_lib_search_dirs_CXX \+predep_objects_CXX \+postdep_objects_CXX \+predeps_CXX \+postdeps_CXX \+compiler_lib_search_path_CXX; do+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in+    *[\\\\\\\`\\"\\\$]*)+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes+      ;;+    *)+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""+      ;;+    esac+done++# Double-quote double-evaled strings.+for var in reload_cmds \+old_postinstall_cmds \+old_postuninstall_cmds \+old_archive_cmds \+extract_expsyms_cmds \+old_archive_from_new_cmds \+old_archive_from_expsyms_cmds \+archive_cmds \+archive_expsym_cmds \+module_cmds \+module_expsym_cmds \+export_symbols_cmds \+prelink_cmds \+postlink_cmds \+postinstall_cmds \+postuninstall_cmds \+finish_cmds \+sys_lib_search_path_spec \+configure_time_dlsearch_path \+configure_time_lt_sys_library_path \+reload_cmds_CXX \+old_archive_cmds_CXX \+old_archive_from_new_cmds_CXX \+old_archive_from_expsyms_cmds_CXX \+archive_cmds_CXX \+archive_expsym_cmds_CXX \+module_cmds_CXX \+module_expsym_cmds_CXX \+export_symbols_cmds_CXX \+prelink_cmds_CXX \+postlink_cmds_CXX; do+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in+    *[\\\\\\\`\\"\\\$]*)+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes+      ;;+    *)+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""+      ;;+    esac+done++ac_aux_dir='$ac_aux_dir'++# See if we are running on zsh, and set the options that allow our+# commands through without removal of \ escapes INIT.+if test -n "\${ZSH_VERSION+set}"; then+   setopt NO_GLOB_SUBST+fi+++    PACKAGE='$PACKAGE'+    VERSION='$VERSION'+    RM='$RM'+    ofile='$ofile'+++++++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1++# Handling of arguments.+for ac_config_target in $ac_config_targets+do+  case $ac_config_target in+    "fficonfig.h") CONFIG_HEADERS="$CONFIG_HEADERS fficonfig.h" ;;+    "buildir") CONFIG_COMMANDS="$CONFIG_COMMANDS buildir" ;;+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;+    "include/ffi.h") CONFIG_FILES="$CONFIG_FILES include/ffi.h" ;;+    "libffi-clib.buildinfo") CONFIG_FILES="$CONFIG_FILES libffi-clib.buildinfo" ;;++  *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;;+  esac+done+++# If the user did not use the arguments to specify the items to instantiate,+# then the envvar interface is used.  Set only those that are not.+# We use the long form for the default assignment because of an extremely+# bizarre bug on SunOS 4.1.3.+if $ac_need_defaults; then+  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers+  test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands+fi++# Have a temporary directory for convenience.  Make it in the build tree+# simply because there is no reason against having it here, and in addition,+# creating and moving files from /tmp can sometimes cause problems.+# Hook for its removal unless debugging.+# Note that there is a small window in which the directory will not be cleaned:+# after its creation but before its name has been assigned to '$tmp'.+$debug ||+{+  tmp= ac_tmp=+  trap 'exit_status=$?+  : "${ac_tmp:=$tmp}"+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status+' 0+  trap 'as_fn_exit 1' 1 2 13 15+}+# Create a (secure) tmp directory for tmp files.++{+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&+  test -d "$tmp"+}  ||+{+  tmp=./conf$$-$RANDOM+  (umask 077 && mkdir "$tmp")+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5+ac_tmp=$tmp++# Set up the scripts for CONFIG_FILES section.+# No need to generate them if there are no CONFIG_FILES.+# This happens for instance with './config.status config.h'.+if test -n "$CONFIG_FILES"; then+++ac_cr=`echo X | tr X '\015'`+# On cygwin, bash can eat \r inside `` if the user requested igncr.+# But we know of no other shell where ac_cr would be empty at this+# point, so we can use a bashism as a fallback.+if test "x$ac_cr" = x; then+  eval ac_cr=\$\'\\r\'+fi+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then+  ac_cs_awk_cr='\\r'+else+  ac_cs_awk_cr=$ac_cr+fi++echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&+_ACEOF+++{+  echo "cat >conf$$subs.awk <<_ACEOF" &&+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&+  echo "_ACEOF"+} >conf$$subs.sh ||+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`+ac_delim='%!_!# '+for ac_last_try in false false false false false :; do+  . ./conf$$subs.sh ||+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5++  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`+  if test $ac_delim_n = $ac_delim_num; then+    break+  elif $ac_last_try; then+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5+  else+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "+  fi+done+rm -f conf$$subs.sh++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&+_ACEOF+sed -n '+h+s/^/S["/; s/!.*/"]=/+p+g+s/^[^!]*!//+:repl+t repl+s/'"$ac_delim"'$//+t delim+:nl+h+s/\(.\{148\}\)..*/\1/+t more1+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/+p+n+b repl+:more1+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t nl+:delim+h+s/\(.\{148\}\)..*/\1/+t more2+s/["\\]/\\&/g; s/^/"/; s/$/"/+p+b+:more2+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t delim+' <conf$$subs.awk | sed '+/^[^""]/{+  N+  s/\n//+}+' >>$CONFIG_STATUS || ac_write_fail=1+rm -f conf$$subs.awk+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACAWK+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&+  for (key in S) S_is_set[key] = 1+  FS = ""++}+{+  line = $ 0+  nfields = split(line, field, "@")+  substed = 0+  len = length(field[1])+  for (i = 2; i < nfields; i++) {+    key = field[i]+    keylen = length(key)+    if (S_is_set[key]) {+      value = S[key]+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)+      len += length(value) + length(field[++i])+      substed = 1+    } else+      len += 1 + keylen+  }++  print line+}++_ACAWK+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"+else+  cat+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5+_ACEOF++# VPATH may cause trouble with some makes, so we remove sole $(srcdir),+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and+# trailing colons and then remove the whole line if VPATH becomes empty+# (actually we leave an empty line to preserve line numbers).+if test "x$srcdir" = x.; then+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{+h+s///+s/^/:/+s/[	 ]*$/:/+s/:\$(srcdir):/:/g+s/:\${srcdir}:/:/g+s/:@srcdir@:/:/g+s/^:*//+s/:*$//+x+s/\(=[	 ]*\).*/\1/+G+s/\n//+s/^[^=]*=[	 ]*$//+}'+fi++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+fi # test -n "$CONFIG_FILES"++# Set up the scripts for CONFIG_HEADERS section.+# No need to generate them if there are no CONFIG_HEADERS.+# This happens for instance with './config.status Makefile'.+if test -n "$CONFIG_HEADERS"; then+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||+BEGIN {+_ACEOF++# Transform confdefs.h into an awk script 'defines.awk', embedded as+# here-document in config.status, that substitutes the proper values into+# config.h.in to produce config.h.++# Create a delimiter string that does not exist in confdefs.h, to ease+# handling of long lines.+ac_delim='%!_!# '+for ac_last_try in false false :; do+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`+  if test -z "$ac_tt"; then+    break+  elif $ac_last_try; then+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5+  else+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "+  fi+done++# For the awk script, D is an array of macro values keyed by name,+# likewise P contains macro parameters if any.  Preserve backslash+# newline sequences.++ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*+sed -n '+s/.\{148\}/&'"$ac_delim"'/g+t rset+:rset+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /+t def+d+:def+s/\\$//+t bsnl+s/["\\]/\\&/g+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\+D["\1"]=" \3"/p+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p+d+:bsnl+s/["\\]/\\&/g+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\+D["\1"]=" \3\\\\\\n"\\/p+t cont+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p+t cont+d+:cont+n+s/.\{148\}/&'"$ac_delim"'/g+t clear+:clear+s/\\$//+t bsnlc+s/["\\]/\\&/g; s/^/"/; s/$/"/p+d+:bsnlc+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p+b cont+' <confdefs.h | sed '+s/'"$ac_delim"'/"\\\+"/g' >>$CONFIG_STATUS || ac_write_fail=1++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+  for (key in D) D_is_set[key] = 1+  FS = ""+}+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {+  line = \$ 0+  split(line, arg, " ")+  if (arg[1] == "#") {+    defundef = arg[2]+    mac1 = arg[3]+  } else {+    defundef = substr(arg[1], 2)+    mac1 = arg[2]+  }+  split(mac1, mac2, "(") #)+  macro = mac2[1]+  prefix = substr(line, 1, index(line, defundef) - 1)+  if (D_is_set[macro]) {+    # Preserve the white space surrounding the "#".+    print prefix "define", macro P[macro] D[macro]+    next+  } else {+    # Replace #undef with comments.  This is necessary, for example,+    # in the case of _POSIX_SOURCE, which is predefined and required+    # on some systems where configure will not decide to define it.+    if (defundef == "undef") {+      print "/*", prefix defundef, macro, "*/"+      next+    }+  }+}+{ print }+_ACAWK+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5+fi # test -n "$CONFIG_HEADERS"+++eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"+shift+for ac_tag+do+  case $ac_tag in+  :[FHLC]) ac_mode=$ac_tag; continue;;+  esac+  case $ac_mode$ac_tag in+  :[FHL]*:*);;+  :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;;+  :[FH]-) ac_tag=-:-;;+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;+  esac+  ac_save_IFS=$IFS+  IFS=:+  set x $ac_tag+  IFS=$ac_save_IFS+  shift+  ac_file=$1+  shift++  case $ac_mode in+  :L) ac_source=$1;;+  :[FH])+    ac_file_inputs=+    for ac_f+    do+      case $ac_f in+      -) ac_f="$ac_tmp/stdin";;+      *) # Look for the file first in the build tree, then in the source tree+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,+	 # because $ac_f cannot contain ':'.+	 test -f "$ac_f" ||+	   case $ac_f in+	   [\\/$]*) false;;+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;+	   esac ||+	   as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;;+      esac+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac+      as_fn_append ac_file_inputs " '$ac_f'"+    done++    # Let's still pretend it is 'configure' which instantiates (i.e., don't+    # use $as_me), people would be surprised to read:+    #    /* config.h.  Generated by config.status.  */+    configure_input='Generated from '`+	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'+	`' by configure.'+    if test x"$ac_file" != x-; then+      configure_input="$ac_file.  $configure_input"+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5+printf "%s\n" "$as_me: creating $ac_file" >&6;}+    fi+    # Neutralize special characters interpreted by sed in replacement strings.+    case $configure_input in #(+    *\&* | *\|* | *\\* )+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |+       sed 's/[\\\\&|]/\\\\&/g'`;; #(+    *) ac_sed_conf_input=$configure_input;;+    esac++    case $ac_tag in+    *:-:* | *:-) cat >"$ac_tmp/stdin" \+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;+    esac+    ;;+  esac++  ac_dir=`$as_dirname -- "$ac_file" ||+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$ac_file" : 'X\(//\)[^/]' \| \+	 X"$ac_file" : 'X\(//\)$' \| \+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X"$ac_file" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+  as_dir="$ac_dir"; as_fn_mkdir_p+  ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`+  # A ".." for each directory in $ac_dir_suffix.+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+  case $ac_top_builddir_sub in+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;+  esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+  .)  # We are building in place.+    ac_srcdir=.+    ac_top_srcdir=$ac_top_builddir_sub+    ac_abs_top_srcdir=$ac_pwd ;;+  [\\/]* | ?:[\\/]* )  # Absolute name.+    ac_srcdir=$srcdir$ac_dir_suffix;+    ac_top_srcdir=$srcdir+    ac_abs_top_srcdir=$srcdir ;;+  *) # Relative name.+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+    ac_top_srcdir=$ac_top_build_prefix$srcdir+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix+++  case $ac_mode in+  :F)+  #+  # CONFIG_FILE+  #++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# If the template does not know about datarootdir, expand it.+# FIXME: This hack should be removed a few years after 2.60.+ac_datarootdir_hack=; ac_datarootdir_seen=+ac_sed_dataroot='+/datarootdir/ {+  p+  q+}+/@datadir@/p+/@docdir@/p+/@infodir@/p+/@localedir@/p+/@mandir@/p'+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in+*datarootdir*) ac_datarootdir_seen=yes;;+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5+printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}+_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+  ac_datarootdir_hack='+  s&@datadir@&$datadir&g+  s&@docdir@&$docdir&g+  s&@infodir@&$infodir&g+  s&@localedir@&$localedir&g+  s&@mandir@&$mandir&g+  s&\\\${datarootdir}&$datarootdir&g' ;;+esac+_ACEOF++# Neutralize VPATH when '$srcdir' = '.'.+# Shell code in configure.ac might set extrasub.+# FIXME: do we really want to maintain this feature?+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_sed_extra="$ac_vpsub+$extrasub+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+:t+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b+s|@configure_input@|$ac_sed_conf_input|;t t+s&@top_builddir@&$ac_top_builddir_sub&;t t+s&@top_build_prefix@&$ac_top_build_prefix&;t t+s&@srcdir@&$ac_srcdir&;t t+s&@abs_srcdir@&$ac_abs_srcdir&;t t+s&@top_srcdir@&$ac_top_srcdir&;t t+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t+s&@builddir@&$ac_builddir&;t t+s&@abs_builddir@&$ac_abs_builddir&;t t+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t+$ac_datarootdir_hack+"+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \+      "$ac_tmp/out"`; test -z "$ac_out"; } &&+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir'+which seems to be undefined.  Please make sure it is defined" >&5+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir'+which seems to be undefined.  Please make sure it is defined" >&2;}++  rm -f "$ac_tmp/stdin"+  case $ac_file in+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;+  esac \+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5+ ;;+  :H)+  #+  # CONFIG_HEADER+  #+  if test x"$ac_file" != x-; then+    {+      printf "%s\n" "/* $configure_input  */" >&1 \+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"+    } >"$ac_tmp/config.h" \+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}+    else+      rm -f "$ac_file"+      mv "$ac_tmp/config.h" "$ac_file" \+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5+    fi+  else+    printf "%s\n" "/* $configure_input  */" >&1 \+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \+      || as_fn_error $? "could not create -" "$LINENO" 5+  fi+# Compute "$ac_file"'s index in $config_headers.+_am_arg="$ac_file"+_am_stamp_count=1+for _am_header in $config_headers :; do+  case $_am_header in+    $_am_arg | $_am_arg:* )+      break ;;+    * )+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;+  esac+done+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$_am_arg" : 'X\(//\)[^/]' \| \+	 X"$_am_arg" : 'X\(//\)$' \| \+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X"$_am_arg" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`/stamp-h$_am_stamp_count+ ;;++  :C)  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5+printf "%s\n" "$as_me: executing $ac_file commands" >&6;}+ ;;+  esac+++  case $ac_file$ac_mode in+    "buildir":C)   ac_top_srcdir="$ax_enable_builddir_srcdir"+  if test ".$ax_enable_builddir" = ".." ; then+    if test -f "$top_srcdir/Makefile" ; then+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: skipping top_srcdir/Makefile - left untouched" >&5+printf "%s\n" "$as_me: skipping top_srcdir/Makefile - left untouched" >&6;}+    else+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: skipping top_srcdir/Makefile - not created" >&5+printf "%s\n" "$as_me: skipping top_srcdir/Makefile - not created" >&6;}+    fi+  else+    if test -f "$ac_top_srcdir/Makefile" ; then+      a=`grep "^VERSION " "$ac_top_srcdir/Makefile"` ; b=`grep "^VERSION " Makefile`+      test "$a" != "$b" && rm "$ac_top_srcdir/Makefile"+    fi+    if test -f "$ac_top_srcdir/Makefile" ; then+	echo "$ac_top_srcdir/Makefile : $ac_top_srcdir/Makefile.in" > $tmp/conftemp.mk+	echo "	@ echo 'REMOVED,,,' >\$@" >> $tmp/conftemp.mk+      eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"+      if grep '^REMOVED,,,' "$ac_top_srcdir/Makefile" >/dev/null+      then rm $ac_top_srcdir/Makefile ; fi+      cp $tmp/conftemp.mk $ac_top_srcdir/makefiles.mk~      ## DEBUGGING+    fi+    if test ! -f "$ac_top_srcdir/Makefile" ; then+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: create top_srcdir/Makefile guessed from local Makefile" >&5+printf "%s\n" "$as_me: create top_srcdir/Makefile guessed from local Makefile" >&6;}+      x='`' ; cat >$tmp/conftemp.sed <<_EOF+/^\$/n+x+/^\$/bS+x+/\\\\\$/{H;d;}+{H;s/.*//;x;}+bM+:S+x+/\\\\\$/{h;d;}+{h;s/.*//;x;}+:M+s/\\(\\n\\)	/\\1 /g+/^	/d+/^[	 ]*[\\#]/d+/^VPATH *=/d+s/^srcdir *=.*/srcdir = ./+s/^top_srcdir *=.*/top_srcdir = ./+/[:=]/!d+/^\\./d+/ = /b+/ .= /b+/:/!b+s/:.*/:/+s/ /  /g+s/ \\([a-z][a-z-]*[a-zA-Z0-9]\\)\\([ :]\\)/ \\1 \\1-all\\2/g+s/^\\([a-z][a-z-]*[a-zA-Z0-9]\\)\\([ :]\\)/\\1 \\1-all\\2/+s/  / /g+/^all all-all[ :]/i\\+all-configured : all-all+s/ [a-zA-Z0-9-]*-all [a-zA-Z0-9-]*-all-all//g+/-all-all/d+a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh $ax_enable_builddir_auxdir/config.guess $x \\\\\\+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\+	; use=$x basename "\$\@" -all $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\+	; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\+	; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done+/dist-all *:/a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh $ax_enable_builddir_auxdir/config.guess $x \\\\\\+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\+	; if test "\$\$found" -eq "0" ; then : \\\\\\+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done+/dist-[a-zA-Z0-9]*-all *:/a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\+	; if test "\$\$found" -eq "0" ; then : \\\\\\+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done+/distclean-all *:/a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh $ax_enable_builddir_auxdir/config.guess $x \\\\\\+	; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\+	; use=$x basename "\$\@" -all $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\+	; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\+	; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile+_EOF+      cp "$tmp/conftemp.sed" "$ac_top_srcdir/makefile.sed~"            ## DEBUGGING+      $ax_enable_builddir_sed -f $tmp/conftemp.sed Makefile >$ac_top_srcdir/Makefile+      if test -f "$ac_top_srcdir/Makefile.mk" ; then+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: extend top_srcdir/Makefile with top_srcdir/Makefile.mk" >&5+printf "%s\n" "$as_me: extend top_srcdir/Makefile with top_srcdir/Makefile.mk" >&6;}+        cat $ac_top_srcdir/Makefile.mk >>$ac_top_srcdir/Makefile+      fi ; xxxx="####"+      echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$ac_top_srcdir/Makefile+      # sanity check+      if grep '^; echo "MAKE ' $ac_top_srcdir/Makefile >/dev/null ; then+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: buggy sed found - it deletes tab in \"a\" text parts" >&5+printf "%s\n" "$as_me: buggy sed found - it deletes tab in \"a\" text parts" >&6;}+        $ax_enable_builddir_sed -e '/^@ HOST=/s/^/	/' -e '/^; /s/^/	/' $ac_top_srcdir/Makefile \+          >$ac_top_srcdir/Makefile~+        (test -s $ac_top_srcdir/Makefile~ && mv $ac_top_srcdir/Makefile~ $ac_top_srcdir/Makefile) 2>/dev/null+      fi+    else+      xxxx="\\#\\#\\#\\#"+      # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed+      echo "s!^$xxxx [^|]* | *$ax_enable_builddir *\$!$xxxx ...... $ax_enable_builddir!" >$tmp/conftemp.sed+      $ax_enable_builddir_sed -f "$tmp/conftemp.sed" "$ac_top_srcdir/Makefile" >$tmp/mkfile.tmp+        cp "$tmp/conftemp.sed" "$ac_top_srcdir/makefiles.sed~"         ## DEBUGGING+        cp "$tmp/mkfile.tmp"   "$ac_top_srcdir/makefiles.out~"         ## DEBUGGING+      if cmp -s "$ac_top_srcdir/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: keeping top_srcdir/Makefile from earlier configure" >&5+printf "%s\n" "$as_me: keeping top_srcdir/Makefile from earlier configure" >&6;}+        rm "$tmp/mkfile.tmp"+      else+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: reusing top_srcdir/Makefile from earlier configure" >&5+printf "%s\n" "$as_me: reusing top_srcdir/Makefile from earlier configure" >&6;}+        mv "$tmp/mkfile.tmp" "$ac_top_srcdir/Makefile"+      fi+    fi+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: build in $ax_enable_builddir (HOST=$ax_enable_builddir_host)" >&5+printf "%s\n" "$as_me: build in $ax_enable_builddir (HOST=$ax_enable_builddir_host)" >&6;}+    xxxx="####"+    echo "$xxxx" "$ax_enable_builddir_host" "|$ax_enable_builddir" >>$ac_top_srcdir/Makefile+  fi+ ;;+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {+  # Older Autoconf quotes --file arguments for eval, but not when files+  # are listed without --file.  Let's play safe and only enable the eval+  # if we detect the quoting.+  # TODO: see whether this extra hack can be removed once we start+  # requiring Autoconf 2.70 or later.+  case $CONFIG_FILES in #(+  *\'*) :+    eval set x "$CONFIG_FILES" ;; #(+  *) :+    set x $CONFIG_FILES ;; #(+  *) :+     ;;+esac+  shift+  # Used to flag and report bootstrapping failures.+  am_rc=0+  for am_mf+  do+    # Strip MF so we end up with the name of the file.+    am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'`+    # Check whether this is an Automake generated Makefile which includes+    # dependency-tracking related rules and includes.+    # Grep'ing the whole file directly is not great: AIX grep has a line+    # limit of 2048, but all sed's we know have understand at least 4000.+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \+      || continue+    am_dirpart=`$as_dirname -- "$am_mf" ||+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$am_mf" : 'X\(//\)[^/]' \| \+	 X"$am_mf" : 'X\(//\)$' \| \+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X"$am_mf" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+    am_filepart=`$as_basename -- "$am_mf" ||+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$am_mf" : 'X\(//\)$' \| \+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||+printf "%s\n" X/"$am_mf" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+    { echo "$as_me:$LINENO: cd "$am_dirpart" \+      && sed -e '/# am--include-marker/d' "$am_filepart" \+        | $MAKE -f - am--depfiles" >&5+   (cd "$am_dirpart" \+      && sed -e '/# am--include-marker/d' "$am_filepart" \+        | $MAKE -f - am--depfiles) >&5 2>&5+   ac_status=$?+   echo "$as_me:$LINENO: \$? = $ac_status" >&5+   (exit $ac_status); } || am_rc=$?+  done+  if test $am_rc -ne 0; then+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5+printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;}+as_fn_error $? "Something went wrong bootstrapping makefile fragments+    for automatic dependency tracking.  If GNU make was not used, consider+    re-running the configure script with MAKE=\"gmake\" (or whatever is+    necessary).  You can also try re-running configure with the+    '--disable-dependency-tracking' option to at least be able to build+    the package (albeit without support for automatic dependency tracking).+See 'config.log' for more details" "$LINENO" 5; }+  fi+  { am_dirpart=; unset am_dirpart;}+  { am_filepart=; unset am_filepart;}+  { am_mf=; unset am_mf;}+  { am_rc=; unset am_rc;}+  rm -f conftest-deps.mk+}+ ;;+    "libtool":C)++    # See if we are running on zsh, and set the options that allow our+    # commands through without removal of \ escapes.+    if test -n "${ZSH_VERSION+set}"; then+      setopt NO_GLOB_SUBST+    fi++    cfgfile=${ofile}T+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15+    $RM "$cfgfile"++    cat <<_LT_EOF >> "$cfgfile"+#! $SHELL+# Generated automatically by $as_me ($PACKAGE) $VERSION+# NOTE: Changes made to this file will be lost: look at ltmain.sh.++# Provide generalized library-building support services.+# Written by Gordon Matzigkeit, 1996++# Copyright (C) 2024 Free Software Foundation, Inc.+# This is free software; see the source for copying conditions.  There is NO+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.++# GNU Libtool 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+# (at your option) any later version.+#+# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program or library that is built+# using GNU Libtool, you may include this file under the  same+# distribution terms that you use for the rest of that program.+#+# GNU Libtool is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+# GNU General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program.  If not, see <http://www.gnu.org/licenses/>.+++# The names of the tagged configurations supported by this script.+available_tags='CXX '++# Configured defaults for sys_lib_dlsearch_path munging.+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}++# ### BEGIN LIBTOOL CONFIG++# Which release of libtool.m4 was used?+macro_version=$macro_version+macro_revision=$macro_revision++# Whether or not to build shared libraries.+build_libtool_libs=$enable_shared++# Whether or not to build static libraries.+build_old_libs=$enable_static++# What type of objects to build.+pic_mode=$pic_mode++# Whether or not to optimize for fast installation.+fast_install=$enable_fast_install++# Shared archive member basename,for filename based shared library versioning on AIX.+shared_archive_member_spec=$shared_archive_member_spec++# Shell to use when invoking shell scripts.+SHELL=$lt_SHELL++# An echo program that protects backslashes.+ECHO=$lt_ECHO++# The PATH separator for the build system.+PATH_SEPARATOR=$lt_PATH_SEPARATOR++# The host system.+host_alias=$host_alias+host=$host+host_os=$host_os++# The build system.+build_alias=$build_alias+build=$build+build_os=$build_os++# A sed program that does not truncate output.+SED=$lt_SED++# Sed that helps us avoid accidentally triggering echo(1) options like -n.+Xsed="\$SED -e 1s/^X//"++# A grep program that handles long lines.+GREP=$lt_GREP++# An ERE matcher.+EGREP=$lt_EGREP++# A literal string matcher.+FGREP=$lt_FGREP++# A BSD- or MS-compatible name lister.+NM=$lt_NM++# Whether we need soft or hard links.+LN_S=$lt_LN_S++# What is the maximum length of a command?+max_cmd_len=$max_cmd_len++# Object file suffix (normally "o").+objext=$ac_objext++# Executable file suffix (normally "").+exeext=$exeext++# whether the shell understands "unset".+lt_unset=$lt_unset++# turn spaces into newlines.+SP2NL=$lt_lt_SP2NL++# turn newlines into spaces.+NL2SP=$lt_lt_NL2SP++# convert \$build file names to \$host format.+to_host_file_cmd=$lt_cv_to_host_file_cmd++# convert \$build files to toolchain format.+to_tool_file_cmd=$lt_cv_to_tool_file_cmd++# A file(cmd) program that detects file types.+FILECMD=$lt_FILECMD++# An object symbol dumper.+OBJDUMP=$lt_OBJDUMP++# Method to check whether dependent libraries are shared objects.+deplibs_check_method=$lt_deplibs_check_method++# Command to use when deplibs_check_method = "file_magic".+file_magic_cmd=$lt_file_magic_cmd++# How to find potential files when deplibs_check_method = "file_magic".+file_magic_glob=$lt_file_magic_glob++# Find potential files using nocaseglob when deplibs_check_method = "file_magic".+want_nocaseglob=$lt_want_nocaseglob++# DLL creation program.+DLLTOOL=$lt_DLLTOOL++# Command to associate shared and link libraries.+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd++# The archiver.+AR=$lt_AR++# Flags to create an archive (by configure).+lt_ar_flags=$lt_ar_flags++# Flags to create an archive.+AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}++# How to feed a file listing to the archiver.+archiver_list_spec=$lt_archiver_list_spec++# A symbol stripping program.+STRIP=$lt_STRIP++# Commands used to install an old-style archive.+RANLIB=$lt_RANLIB+old_postinstall_cmds=$lt_old_postinstall_cmds+old_postuninstall_cmds=$lt_old_postuninstall_cmds++# Whether to use a lock for old archive extraction.+lock_old_archive_extraction=$lock_old_archive_extraction++# A C compiler.+LTCC=$lt_CC++# LTCC compiler flags.+LTCFLAGS=$lt_CFLAGS++# Take the output of nm and produce a listing of raw symbols and C names.+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe++# Transform the output of nm in a proper C declaration.+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl++# Transform the output of nm into a list of symbols to manually relocate.+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import++# Transform the output of nm in a C name address pair.+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address++# Transform the output of nm in a C name address pair when lib prefix is needed.+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix++# The name lister interface.+nm_interface=$lt_lt_cv_nm_interface++# Specify filename containing input files for \$NM.+nm_file_list_spec=$lt_nm_file_list_spec++# The root where to search for dependent libraries,and where our libraries should be installed.+lt_sysroot=$lt_sysroot++# Command to truncate a binary pipe.+lt_truncate_bin=$lt_lt_cv_truncate_bin++# The name of the directory that contains temporary libtool files.+objdir=$objdir++# Used to examine libraries when file_magic_cmd begins with "file".+MAGIC_CMD=$MAGIC_CMD++# Must we lock files when doing compilation?+need_locks=$lt_need_locks++# Manifest tool.+MANIFEST_TOOL=$lt_MANIFEST_TOOL++# Tool to manipulate archived DWARF debug symbol files on Mac OS X.+DSYMUTIL=$lt_DSYMUTIL++# Tool to change global to local symbols on Mac OS X.+NMEDIT=$lt_NMEDIT++# Tool to manipulate fat objects and archives on Mac OS X.+LIPO=$lt_LIPO++# ldd/readelf like tool for Mach-O binaries on Mac OS X.+OTOOL=$lt_OTOOL++# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.+OTOOL64=$lt_OTOOL64++# Old archive suffix (normally "a").+libext=$libext++# Shared library suffix (normally ".so").+shrext_cmds=$lt_shrext_cmds++# The commands to extract the exported symbol list from a shared archive.+extract_expsyms_cmds=$lt_extract_expsyms_cmds++# Variables whose values should be saved in libtool wrapper scripts and+# restored at link time.+variables_saved_for_relink=$lt_variables_saved_for_relink++# Do we need the "lib" prefix for modules?+need_lib_prefix=$need_lib_prefix++# Do we need a version for libraries?+need_version=$need_version++# Library versioning type.+version_type=$version_type++# Shared library runtime path variable.+runpath_var=$runpath_var++# Shared library path variable.+shlibpath_var=$shlibpath_var++# Is shlibpath searched before the hard-coded library search path?+shlibpath_overrides_runpath=$shlibpath_overrides_runpath++# Format of library name prefix.+libname_spec=$lt_libname_spec++# List of archive names.  First name is the real one, the rest are links.+# The last name is the one that the linker finds with -lNAME+library_names_spec=$lt_library_names_spec++# The coded name of the library, if different from the real name.+soname_spec=$lt_soname_spec++# Permission mode override for installation of shared libraries.+install_override_mode=$lt_install_override_mode++# Command to use after installation of a shared archive.+postinstall_cmds=$lt_postinstall_cmds++# Command to use after uninstallation of a shared archive.+postuninstall_cmds=$lt_postuninstall_cmds++# Commands used to finish a libtool library installation in a directory.+finish_cmds=$lt_finish_cmds++# As "finish_cmds", except a single script fragment to be evaled but+# not shown.+finish_eval=$lt_finish_eval++# Whether we should hardcode library paths into libraries.+hardcode_into_libs=$hardcode_into_libs++# Compile-time system search path for libraries.+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec++# Detected run-time system search path for libraries.+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path++# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path++# Whether dlopen is supported.+dlopen_support=$enable_dlopen++# Whether dlopen of programs is supported.+dlopen_self=$enable_dlopen_self++# Whether dlopen of statically linked programs is supported.+dlopen_self_static=$enable_dlopen_self_static++# Commands to strip libraries.+old_striplib=$lt_old_striplib+striplib=$lt_striplib+++# The linker used to build libraries.+LD=$lt_LD++# How to create reloadable object files.+reload_flag=$lt_reload_flag+reload_cmds=$lt_reload_cmds++# Commands used to build an old-style archive.+old_archive_cmds=$lt_old_archive_cmds++# A language specific compiler.+CC=$lt_compiler++# Is the compiler the GNU compiler?+with_gcc=$GCC++# Compiler flag to turn off builtin functions.+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag++# Additional compiler flags for building library objects.+pic_flag=$lt_lt_prog_compiler_pic++# How to pass a linker flag through the compiler.+wl=$lt_lt_prog_compiler_wl++# Compiler flag to prevent dynamic linking.+link_static_flag=$lt_lt_prog_compiler_static++# Does compiler simultaneously support -c and -o options?+compiler_c_o=$lt_lt_cv_prog_compiler_c_o++# Whether or not to add -lc for building shared libraries.+build_libtool_need_lc=$archive_cmds_need_lc++# Whether or not to disallow shared libs when runtime libs are static.+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes++# Compiler flag to allow reflexive dlopens.+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec++# Compiler flag to generate shared objects directly from archives.+whole_archive_flag_spec=$lt_whole_archive_flag_spec++# Whether the compiler copes with passing no objects directly.+compiler_needs_object=$lt_compiler_needs_object++# Create an old-style archive from a shared archive.+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds++# Create a temporary old-style archive to link instead of a shared archive.+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds++# Commands used to build a shared archive.+archive_cmds=$lt_archive_cmds+archive_expsym_cmds=$lt_archive_expsym_cmds++# Commands used to build a loadable module if different from building+# a shared archive.+module_cmds=$lt_module_cmds+module_expsym_cmds=$lt_module_expsym_cmds++# Whether we are building with GNU ld or not.+with_gnu_ld=$lt_with_gnu_ld++# Flag that allows shared libraries with undefined symbols to be built.+allow_undefined_flag=$lt_allow_undefined_flag++# Flag that enforces no undefined symbols.+no_undefined_flag=$lt_no_undefined_flag++# Flag to hardcode \$libdir into a binary during linking.+# This must work even if \$libdir does not exist+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec++# Whether we need a single "-rpath" flag with a separated argument.+hardcode_libdir_separator=$lt_hardcode_libdir_separator++# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes+# DIR into the resulting binary.+hardcode_direct=$hardcode_direct++# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes+# DIR into the resulting binary and the resulting library dependency is+# "absolute",i.e. impossible to change by setting \$shlibpath_var if the+# library is relocated.+hardcode_direct_absolute=$hardcode_direct_absolute++# Set to "yes" if using the -LDIR flag during linking hardcodes DIR+# into the resulting binary.+hardcode_minus_L=$hardcode_minus_L++# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR+# into the resulting binary.+hardcode_shlibpath_var=$hardcode_shlibpath_var++# Set to "yes" if building a shared library automatically hardcodes DIR+# into the library and all subsequent libraries and executables linked+# against it.+hardcode_automatic=$hardcode_automatic++# Set to yes if linker adds runtime paths of dependent libraries+# to runtime path list.+inherit_rpath=$inherit_rpath++# Whether libtool must link a program against all its dependency libraries.+link_all_deplibs=$link_all_deplibs++# Set to "yes" if exported symbols are required.+always_export_symbols=$always_export_symbols++# The commands to list exported symbols.+export_symbols_cmds=$lt_export_symbols_cmds++# Symbols that should not be listed in the preloaded symbols.+exclude_expsyms=$lt_exclude_expsyms++# Symbols that must always be exported.+include_expsyms=$lt_include_expsyms++# Commands necessary for linking programs (against libraries) with templates.+prelink_cmds=$lt_prelink_cmds++# Commands necessary for finishing linking programs.+postlink_cmds=$lt_postlink_cmds++# Specify filename containing input files.+file_list_spec=$lt_file_list_spec++# How to hardcode a shared library path into an executable.+hardcode_action=$hardcode_action++# The directories searched by this compiler when creating a shared library.+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs++# Dependencies to place before and after the objects being linked to+# create a shared library.+predep_objects=$lt_predep_objects+postdep_objects=$lt_postdep_objects+predeps=$lt_predeps+postdeps=$lt_postdeps++# The library search path used internally by the compiler when linking+# a shared library.+compiler_lib_search_path=$lt_compiler_lib_search_path++# ### END LIBTOOL CONFIG++_LT_EOF++    cat <<'_LT_EOF' >> "$cfgfile"++# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE++# func_munge_path_list VARIABLE PATH+# -----------------------------------+# VARIABLE is name of variable containing _space_ separated list of+# directories to be munged by the contents of PATH, which is string+# having a format:+# "DIR[:DIR]:"+#       string "DIR[ DIR]" will be prepended to VARIABLE+# ":DIR[:DIR]"+#       string "DIR[ DIR]" will be appended to VARIABLE+# "DIRP[:DIRP]::[DIRA:]DIRA"+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string+#       "DIRA[ DIRA]" will be appended to VARIABLE+# "DIR[:DIR]"+#       VARIABLE will be replaced by "DIR[ DIR]"+func_munge_path_list ()+{+    case x$2 in+    x)+        ;;+    *:)+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"+        ;;+    x:*)+        eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"+        ;;+    *::*)+        eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"+        eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"+        ;;+    *)+        eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"+        ;;+    esac+}+++# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.+func_cc_basename ()+{+    for cc_temp in $*""; do+      case $cc_temp in+        compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;+        distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;+        \-*) ;;+        *) break;;+      esac+    done+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`+}+++# ### END FUNCTIONS SHARED WITH CONFIGURE++_LT_EOF++  case $host_os in+  aix3*)+    cat <<\_LT_EOF >> "$cfgfile"+# AIX sometimes has problems with the GCC collect2 program.  For some+# reason, if we set the COLLECT_NAMES environment variable, the problems+# vanish in a puff of smoke.+if test set != "${COLLECT_NAMES+set}"; then+  COLLECT_NAMES=+  export COLLECT_NAMES+fi+_LT_EOF+    ;;+  esac++++ltmain=$ac_aux_dir/ltmain.sh+++  # We use sed instead of cat because bash on DJGPP gets confused if+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in+  # text mode, it properly converts lines to CR/LF.  This bash problem+  # is reportedly fixed, but why not run on old versions too?+  $SED '$q' "$ltmain" >> "$cfgfile" \+     || (rm -f "$cfgfile"; exit 1)++   mv -f "$cfgfile" "$ofile" ||+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")+  chmod +x "$ofile"+++    cat <<_LT_EOF >> "$ofile"++# ### BEGIN LIBTOOL TAG CONFIG: CXX++# The linker used to build libraries.+LD=$lt_LD_CXX++# How to create reloadable object files.+reload_flag=$lt_reload_flag_CXX+reload_cmds=$lt_reload_cmds_CXX++# Commands used to build an old-style archive.+old_archive_cmds=$lt_old_archive_cmds_CXX++# A language specific compiler.+CC=$lt_compiler_CXX++# Is the compiler the GNU compiler?+with_gcc=$GCC_CXX++# Compiler flag to turn off builtin functions.+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX++# Additional compiler flags for building library objects.+pic_flag=$lt_lt_prog_compiler_pic_CXX++# How to pass a linker flag through the compiler.+wl=$lt_lt_prog_compiler_wl_CXX++# Compiler flag to prevent dynamic linking.+link_static_flag=$lt_lt_prog_compiler_static_CXX++# Does compiler simultaneously support -c and -o options?+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX++# Whether or not to add -lc for building shared libraries.+build_libtool_need_lc=$archive_cmds_need_lc_CXX++# Whether or not to disallow shared libs when runtime libs are static.+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX++# Compiler flag to allow reflexive dlopens.+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX++# Compiler flag to generate shared objects directly from archives.+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX++# Whether the compiler copes with passing no objects directly.+compiler_needs_object=$lt_compiler_needs_object_CXX++# Create an old-style archive from a shared archive.+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX++# Create a temporary old-style archive to link instead of a shared archive.+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX++# Commands used to build a shared archive.+archive_cmds=$lt_archive_cmds_CXX+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX++# Commands used to build a loadable module if different from building+# a shared archive.+module_cmds=$lt_module_cmds_CXX+module_expsym_cmds=$lt_module_expsym_cmds_CXX++# Whether we are building with GNU ld or not.+with_gnu_ld=$lt_with_gnu_ld_CXX++# Flag that allows shared libraries with undefined symbols to be built.+allow_undefined_flag=$lt_allow_undefined_flag_CXX++# Flag that enforces no undefined symbols.+no_undefined_flag=$lt_no_undefined_flag_CXX++# Flag to hardcode \$libdir into a binary during linking.+# This must work even if \$libdir does not exist+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX++# Whether we need a single "-rpath" flag with a separated argument.+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX++# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes+# DIR into the resulting binary.+hardcode_direct=$hardcode_direct_CXX++# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes+# DIR into the resulting binary and the resulting library dependency is+# "absolute",i.e. impossible to change by setting \$shlibpath_var if the+# library is relocated.+hardcode_direct_absolute=$hardcode_direct_absolute_CXX++# Set to "yes" if using the -LDIR flag during linking hardcodes DIR+# into the resulting binary.+hardcode_minus_L=$hardcode_minus_L_CXX++# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR+# into the resulting binary.+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX++# Set to "yes" if building a shared library automatically hardcodes DIR+# into the library and all subsequent libraries and executables linked+# against it.+hardcode_automatic=$hardcode_automatic_CXX++# Set to yes if linker adds runtime paths of dependent libraries+# to runtime path list.+inherit_rpath=$inherit_rpath_CXX++# Whether libtool must link a program against all its dependency libraries.+link_all_deplibs=$link_all_deplibs_CXX++# Set to "yes" if exported symbols are required.+always_export_symbols=$always_export_symbols_CXX++# The commands to list exported symbols.+export_symbols_cmds=$lt_export_symbols_cmds_CXX++# Symbols that should not be listed in the preloaded symbols.+exclude_expsyms=$lt_exclude_expsyms_CXX++# Symbols that must always be exported.+include_expsyms=$lt_include_expsyms_CXX++# Commands necessary for linking programs (against libraries) with templates.+prelink_cmds=$lt_prelink_cmds_CXX++# Commands necessary for finishing linking programs.+postlink_cmds=$lt_postlink_cmds_CXX++# Specify filename containing input files.+file_list_spec=$lt_file_list_spec_CXX++# How to hardcode a shared library path into an executable.+hardcode_action=$hardcode_action_CXX++# The directories searched by this compiler when creating a shared library.+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX++# Dependencies to place before and after the objects being linked to+# create a shared library.+predep_objects=$lt_predep_objects_CXX+postdep_objects=$lt_postdep_objects_CXX+predeps=$lt_predeps_CXX+postdeps=$lt_postdeps_CXX++# The library search path used internally by the compiler when linking+# a shared library.+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX++# ### END LIBTOOL TAG CONFIG: CXX+_LT_EOF++ ;;++  esac+done # for ac_tag+++as_fn_exit 0+_ACEOF+ac_clean_files=$ac_clean_files_save++test $ac_write_fail = 0 ||+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5+++# configure is writing to config.log, and then calls config.status.+# config.status does its own redirection, appending to config.log.+# Unfortunately, on DOS this fails, as config.log is still kept open+# by configure, so config.status won't be able to write to it; its+# output is simply discarded.  So we exec the FD to /dev/null,+# effectively closing config.log, so it can be properly (re)opened and+# appended to by config.status.  When coming back to configure, we+# need to make the FD available again.+if test "$no_create" != yes; then+  ac_cs_success=:+  ac_config_status_args=+  test "$silent" = yes &&+    ac_config_status_args="$ac_config_status_args --quiet"+  exec 5>/dev/null+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false+  exec 5>>config.log+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which+  # would make configure fail if this is the last instruction.+  $ac_cs_success || as_fn_exit 1+fi+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}+fi+++
+ configure.ac view
@@ -0,0 +1,395 @@+dnl Process this with autoconf to create configure++AC_PREREQ([2.68])++AC_INIT([libffi],[3.5.2],[http://github.com/libffi/libffi/issues])+AC_CONFIG_HEADERS([fficonfig.h])++FFI_VERSION_STRING="3.5.2"+FFI_VERSION_NUMBER=30502+AC_SUBST(FFI_VERSION_STRING)+AC_SUBST(FFI_VERSION_NUMBER)++AC_CANONICAL_TARGET+target_alias=${target_alias-$host_alias}++case "${host}" in+  frv*-elf)+    LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/+    ;;+esac++AX_ENABLE_BUILDDIR++# The same as in boehm-gc and libstdc++. Have to borrow it from there.+# We must force CC to /not/ be precious variables; otherwise+# the wrong, non-multilib-adjusted value will be used in multilibs.+# As a side effect, we have to subst CFLAGS ourselves.+# Also save and restore CFLAGS, since AC_PROG_CC will come up with+# defaults of its own if none are provided.++m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])+m4_define([_AC_ARG_VAR_PRECIOUS],[])+save_CFLAGS=$CFLAGS+AC_PROG_CC+AC_PROG_CXX+CFLAGS=$save_CFLAGS+m4_undefine([_AC_ARG_VAR_PRECIOUS])+m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])++AC_SUBST(CFLAGS)++AM_PROG_AS+AM_PROG_CC_C_O+AC_PROG_EGREP+LT_INIT+AC_CONFIG_MACRO_DIR([m4])++# Test for 64-bit build.+AC_CHECK_SIZEOF([size_t])++AX_COMPILER_VENDOR+AX_CC_MAXOPT+# The AX_CFLAGS_WARN_ALL macro doesn't currently work for sunpro+# compiler.+if test "$ax_cv_c_compiler_vendor" != "sun"; then+  AX_CFLAGS_WARN_ALL+fi++if test "x$GCC" = "xyes"; then+  CFLAGS="$CFLAGS -fexceptions"+fi++cat > local.exp <<EOF+set CC_FOR_TARGET "$CC"+set CXX_FOR_TARGET "$CXX"+set compiler_vendor "$ax_cv_c_compiler_vendor"+EOF++AM_MAINTAINER_MODE++AC_CHECK_HEADERS(sys/memfd.h)+AC_CHECK_FUNCS([memfd_create])++HAVE_LONG_DOUBLE_VARIANT=0++. ${srcdir}/configure.host++if test -n "${UNSUPPORTED}"; then+  AC_MSG_ERROR(["libffi has not been ported to $host."])+fi++AC_SUBST(AM_RUNTESTFLAGS)+AC_SUBST(AM_LTLDFLAGS)++m4_warn([obsolete],+[The preprocessor macro `STDC_HEADERS' is obsolete.+  Except in unusual embedded environments, you can safely include all+  ISO C90 headers unconditionally.])dnl++AC_CHECK_FUNCS(memcpy)+AC_CHECK_HEADERS(alloca.h)++AC_CHECK_SIZEOF(double)+AC_CHECK_SIZEOF(long double)++# Also AC_SUBST this variable for ffi.h.+if test -z "$HAVE_LONG_DOUBLE"; then+  HAVE_LONG_DOUBLE=0+  if test $ac_cv_sizeof_long_double != 0; then+    if test $HAVE_LONG_DOUBLE_VARIANT != 0; then+      AC_DEFINE(HAVE_LONG_DOUBLE_VARIANT, 1, [Define if you support more than one size of the long double type])+      HAVE_LONG_DOUBLE=1+    else+      if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then+        HAVE_LONG_DOUBLE=1+        AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])+      fi+    fi+  fi+fi+AC_SUBST(HAVE_LONG_DOUBLE)+AC_SUBST(HAVE_LONG_DOUBLE_VARIANT)++AC_C_BIGENDIAN++GCC_AS_CFI_PSEUDO_OP++AC_ARG_VAR([WASM64_MEMORY64], [Used only for the wasm64 target. Set to 1 (default) or 2 for Emscripten's -sMEMORY64 mode])++case "$TARGET" in+  SPARC)+    AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],+	libffi_cv_as_sparc_ua_pcrel, [+	save_CFLAGS="$CFLAGS"+	save_LDFLAGS="$LDFLAGS"+	CFLAGS="$CFLAGS -fpic"+	LDFLAGS="$LDFLAGS -shared"+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");]], [[]])],[libffi_cv_as_sparc_ua_pcrel=yes],[libffi_cv_as_sparc_ua_pcrel=no])+	CFLAGS="$save_CFLAGS"+	LDFLAGS="$save_LDFLAGS"])+    if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then+	AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,+		  [Define if your assembler and linker support unaligned PC relative relocs.])+    fi++    AC_CACHE_CHECK([assembler .register pseudo-op support],+       libffi_cv_as_register_pseudo_op, [+       libffi_cv_as_register_pseudo_op=unknown+       # Check if we have .register+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[asm (".register %g2, #scratch");]])],[libffi_cv_as_register_pseudo_op=yes],[libffi_cv_as_register_pseudo_op=no])+    ])+    if test "x$libffi_cv_as_register_pseudo_op" = xyes; then+       AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,+	       [Define if your assembler supports .register.])+    fi+    ;;++  X86*)+    AC_CACHE_CHECK([assembler supports pc related relocs],+	libffi_cv_as_x86_pcrel, [+	libffi_cv_as_x86_pcrel=no+	echo '.text; foo: nop; .data; .long foo-.; .text' > conftest.s+	if $CC $CFLAGS -c conftest.s > /dev/null 2>&1; then+	    libffi_cv_as_x86_pcrel=yes+	fi+	])+    if test "x$libffi_cv_as_x86_pcrel" = xyes; then+	AC_DEFINE(HAVE_AS_X86_PCREL, 1,+		  [Define if your assembler supports PC relative relocs.])+    fi+    ;;++  S390)+    AC_CACHE_CHECK([compiler uses zarch features],+	libffi_cv_as_s390_zarch, [+	libffi_cv_as_s390_zarch=no+	echo 'void foo(void) { bar(); bar(); }' > conftest.c+	if $CC $CFLAGS -S conftest.c > /dev/null 2>&1; then+	    if $GREP -q brasl conftest.s; then+	        libffi_cv_as_s390_zarch=yes+	    fi+	fi+	])+    if test "x$libffi_cv_as_s390_zarch" = xyes; then+	AC_DEFINE(HAVE_AS_S390_ZARCH, 1,+		  [Define if the compiler uses zarch features.])+    fi+    ;;+  wasm64)+    if test -z "$WASM64_MEMORY64"; then+      WASM64_MEMORY64=1+    fi+    CFLAGS="$CFLAGS -sMEMORY64=$WASM64_MEMORY64"+    ;;+esac++AC_CACHE_CHECK([whether compiler supports pointer authentication],+   libffi_cv_as_ptrauth, [+   libffi_cv_as_ptrauth=unknown+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[+#ifdef __clang__+# if __has_feature(ptrauth_calls)+#  define HAVE_ARM64E_PTRAUTH 1+# endif+#endif++#ifndef HAVE_ARM64E_PTRAUTH+# error Pointer authentication not supported+#endif+		   ]])],[libffi_cv_as_ptrauth=yes],[libffi_cv_as_ptrauth=no])+])+if test "x$libffi_cv_as_ptrauth" = xyes; then+    AC_DEFINE(HAVE_ARM64E_PTRAUTH, 1,+	      [Define if your compiler supports pointer authentication.])+fi++# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC;+# if EMUTRAMP is active too ffi could try mapping without PROT_EXEC,+# but the kernel needs to recognize the trampoline generated by ffi.+# Otherwise fallback to double mmap trick.+AC_ARG_ENABLE(pax_emutramp,+  [  --enable-pax_emutramp       enable pax emulated trampolines (experimental)],+  if test "$enable_pax_emutramp" = "yes"; then+    AC_MSG_WARN([EMUTRAMP is experimental only.  Use --enable-pax_emutramp=experimental to enforce.])+  elif test "$enable_pax_emutramp" = "experimental"; then+    AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1,+      [Define this if you want to enable pax emulated trampolines (experimental)])+  fi)++LT_SYS_SYMBOL_USCORE+if test "x$sys_symbol_underscore" = xyes; then+    AC_DEFINE(SYMBOL_UNDERSCORE, 1, [Define if symbols are underscored.])+fi++FFI_EXEC_TRAMPOLINE_TABLE=0+case "$target" in+     *arm*-apple-* | aarch64-apple-*)+       FFI_EXEC_TRAMPOLINE_TABLE=1+       AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1,+                 [Cannot use PROT_EXEC on this target, so, we revert to+                   alternative means])+     ;;+     *-apple-* | *-*-dragonfly* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris* | *-linux-android*)+       AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1,+                 [Cannot use malloc on this target, so, we revert to+                   alternative means])+     ;;+esac+AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1)+AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE)++if test x$TARGET = xX86_64; then+    AC_CACHE_CHECK([toolchain supports unwind section type],+	libffi_cv_as_x86_64_unwind_section_type, [+        cat  > conftest1.s << EOF+.text+.globl foo+foo:+jmp bar+.section .eh_frame,"a",@unwind+bar:+EOF++        cat > conftest2.c  << EOF+extern void foo();+int main(){foo();}+EOF++	libffi_cv_as_x86_64_unwind_section_type=no+	# we ensure that we can compile _and_ link an assembly file containing an @unwind section+	# since the compiler can support it and not the linker (ie old binutils)+	if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \+           $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then+	    libffi_cv_as_x86_64_unwind_section_type=yes+	fi+	])+    if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then+	AC_DEFINE(HAVE_AS_X86_64_UNWIND_SECTION_TYPE, 1,+		  [Define if your assembler supports unwind section type.])+    fi+fi++if test "x$GCC" = "xyes"; then+  AX_CHECK_COMPILE_FLAG(-fno-lto, libffi_cv_no_lto=-fno-lto)++  AC_CACHE_CHECK([whether .eh_frame section should be read-only],+      libffi_cv_ro_eh_frame, [+  	libffi_cv_ro_eh_frame=yes+  	echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c+  	if $CC $CFLAGS -c -fpic -fexceptions $libffi_cv_no_lto -o conftest.o conftest.c > /dev/null 2>&1; then+	    if $READELF -WS conftest.o 2>/dev/null | $GREP -q -n 'eh_frame .* WA'; then+	        libffi_cv_ro_eh_frame=no+	    fi+  	fi+  	rm -f conftest.*+      ])+  if test "x$libffi_cv_ro_eh_frame" = xyes; then+      AC_DEFINE(HAVE_RO_EH_FRAME, 1,+  	      [Define if .eh_frame sections should be read-only.])+      AC_DEFINE(EH_FRAME_FLAGS, "a",+  	      [Define to the flags needed for the .section .eh_frame directive.  ])+  else+      AC_DEFINE(EH_FRAME_FLAGS, "aw",+  	      [Define to the flags needed for the .section .eh_frame directive.  ])+  fi++  AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],+      libffi_cv_hidden_visibility_attribute, [+  	echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1  ; }' > conftest.c+  	libffi_cv_hidden_visibility_attribute=no+  	if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then+  	    if $EGREP '(\.hidden|\.private_extern).*foo|foo.*,hidden' conftest.s >/dev/null; then+  		libffi_cv_hidden_visibility_attribute=yes+  	    fi+  	fi+  	rm -f conftest.*+      ])+  if test $libffi_cv_hidden_visibility_attribute = yes; then+      AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1,+  	      [Define if __attribute__((visibility("hidden"))) is supported.])+  fi+fi++AH_BOTTOM([+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE+#ifdef LIBFFI_ASM+#ifdef __APPLE__+#define FFI_HIDDEN(name) .private_extern name+#else+#define FFI_HIDDEN(name) .hidden name+#endif+#else+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))+#endif+#else+#ifdef LIBFFI_ASM+#define FFI_HIDDEN(name)+#else+#define FFI_HIDDEN+#endif+#endif+])++AC_SUBST(TARGET)+AC_SUBST(TARGETDIR)+AC_SUBST([EXTRA_SOURCES],[` printf " %s " "$SOURCES" | sed -E "s/ ([[^ ]]+)/src\/$TARGETDIR\/\1 /g" `])+AC_SUBST([EXTRA_ASM_SOURCES],[` printf " %s " "$ASM_SOURCES" | sed -E "s/ ([[^ ]]+)/src\/$TARGETDIR\/\1 /g" `])++AC_ARG_ENABLE(debug,+[  --enable-debug          debugging mode],+  if test "$enable_debug" = "yes"; then+    AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])+  fi)+AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")++AC_ARG_ENABLE(structs,+[  --disable-structs       omit code for struct support],+  if test "$enable_structs" = "no"; then+    AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this if you do not want support for aggregate types.])+  fi)+AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")++AC_ARG_ENABLE(raw-api,+[  --disable-raw-api       make the raw api unavailable],+  if test "$enable_raw_api" = "no"; then+    AC_DEFINE(FFI_NO_RAW_API, 1, [Define this if you do not want support for the raw API.])+  fi)++AC_ARG_ENABLE(exec-static-tramp,+[  --disable-exec-static-tramp  disable use of static exec trampolines (enabled by default)])++if test "$enable_exec_static_tramp" != no; then+case "$target" in+     *-cygwin* | *-msys*)+       # Only define static trampolines if we are using the cygwin runtime.+       # Will this need to be changed for mingw?+       if test "x$GCC" = "xyes"; then+         AC_DEFINE(FFI_EXEC_STATIC_TRAMP, 1,+                   [Define this if you want statically defined trampolines])+       fi+     ;;+     *arm*-*-linux-* | aarch64*-*-linux-* | i*86-*-linux-* | x86_64-*-linux-* \+     | loongarch*-*-linux-* | s390x*-linux-* | powerpc*-linux-*)+       AC_DEFINE(FFI_EXEC_STATIC_TRAMP, 1,+                 [Define this if you want statically defined trampolines])+     ;;+esac+fi++AC_ARG_ENABLE(purify-safety,+[  --enable-purify-safety  purify-safe mode],+  if test "$enable_purify_safety" = "yes"; then+    AC_DEFINE(USING_PURIFY, 1, [Define this if you are using Purify and want to suppress spurious messages.])+  fi)++# Check linker support.+LIBFFI_ENABLE_SYMVERS++AC_CONFIG_FILES(include/ffi.h)++AC_SUBST([EXTRA_LIBS],[` printf " %s " "$LIBS" | sed -E 's/ -l([[^ ]]*)/\1 /g' `])+AC_CONFIG_FILES([libffi-clib.buildinfo])++AC_OUTPUT+
+ configure.host view
@@ -0,0 +1,336 @@+# configure.host+#+# This shell script handles all host based configuration for libffi.+#++# THIS TABLE IS SORTED.  KEEP IT THAT WAY.+# Most of the time we can define all the variables all at once...+case "${host}" in+  aarch64*-*-cygwin* | aarch64*-*-msys* | aarch64*-*-mingw* | aarch64*-*-win* )+	TARGET=ARM_WIN64; TARGETDIR=aarch64+	if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then+	  MSVC=1+	fi+	;;++  aarch64*-*-*)+	TARGET=AARCH64; TARGETDIR=aarch64+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  alpha*-*-*)+	TARGET=ALPHA; TARGETDIR=alpha;+	# Support 128-bit long double, changeable via command-line switch.+	HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'+	SOURCES="ffi.c"; ASM_SOURCES="osf.S"+	;;++  arc*-*-*)+	TARGET=ARC; TARGETDIR=arc+	SOURCES="ffi.c"; ASM_SOURCES="arcompact.S"+	;;++  arm*-*-cygwin* | arm*-*-msys* | arm*-*-mingw* | arm*-*-win* )+	TARGET=ARM_WIN32; TARGETDIR=arm+	if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then+	  MSVC=1+	fi+	;;++  arm*-*-*)+	TARGET=ARM; TARGETDIR=arm+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  avr32*-*-*)+	TARGET=AVR32; TARGETDIR=avr32+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  bfin*)+	TARGET=BFIN; TARGETDIR=bfin+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  cris-*-*)+	TARGET=LIBFFI_CRIS; TARGETDIR=cris+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  csky-*-*)+        TARGET=CSKY; TARGETDIR=csky+        SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+        ;;++  frv-*-*)+	TARGET=FRV; TARGETDIR=frv+	SOURCES="ffi.c"; ASM_SOURCES="eabi.S"+	;;++  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)+	TARGET=PA_LINUX; TARGETDIR=pa+	SOURCES="ffi.c"; ASM_SOURCES="linux.S"+	;;+  hppa*64-*-hpux*)+	TARGET=PA64_HPUX; TARGETDIR=pa+	SOURCES="ffi64.c"; ASM_SOURCES="hpux64.S"+	;;+  hppa*-*-hpux*)+	TARGET=PA_HPUX; TARGETDIR=pa+	SOURCES="ffi.c"; ASM_SOURCES="hpux32.S"+	;;++  i?86-*-freebsd* | i?86-*-openbsd*)+	TARGET=X86_FREEBSD; TARGETDIR=x86+	;;++  i?86-*-cygwin* | i?86-*-msys* | i?86-*-mingw* | i?86-*-win* | i?86-*-os2* | i?86-*-interix* \+  | x86_64-*-cygwin* | x86_64-*-msys* | x86_64-*-mingw* | x86_64-*-win* )+	TARGETDIR=x86+	if test $ac_cv_sizeof_size_t = 4; then+	  TARGET=X86_WIN32+	else+	  TARGET=X86_WIN64+	fi+	if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then+	  MSVC=1+	fi+	# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.+	# We must also check with_cross_host to decide if this is a native+	# or cross-build and select where to install dlls appropriately.+	if test -n "$with_cross_host" &&+	   test x"$with_cross_host" != x"no"; then+	  AM_LTLDFLAGS='-no-undefined -bindir "$(toolexeclibdir)"';+	else+	  AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"';+	fi+	;;++  i?86-*-darwin* | x86_64-*-darwin* | i?86-*-ios | x86_64-*-ios)+	TARGETDIR=x86+	if test $ac_cv_sizeof_size_t = 4; then+	  TARGET=X86_DARWIN+	else+	  TARGET=X86_64+	fi+	;;++  i?86-*-* | x86_64-*-* | amd64-*)+	TARGETDIR=x86+	if test $ac_cv_sizeof_size_t = 4; then+	  echo 'int foo (void) { return __x86_64__; }' > conftest.c+	  if $CC $CFLAGS -Werror -S conftest.c -o conftest.s > /dev/null 2>&1; then+	    TARGET_X32=yes+	    TARGET=X86_64+	  else+	    TARGET=X86;+	  fi+	  rm -f conftest.*+	else+	  TARGET=X86_64;+	fi+	;;++  ia64*-*-*)+	TARGET=IA64; TARGETDIR=ia64+	SOURCES="ffi.c"; ASM_SOURCES="unix.S"+	;;++  kvx-*-*)+	TARGET=KVX; TARGETDIR=kvx+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  loongarch64-*-*)+	TARGET=LOONGARCH64; TARGETDIR=loongarch64+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  m32r*-*-*)+	TARGET=M32R; TARGETDIR=m32r+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  m68k-*-*)+	TARGET=M68K; TARGETDIR=m68k+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  m88k-*-*)+	TARGET=M88K; TARGETDIR=m88k+	SOURCES="ffi.c"; ASM_SOURCES="obsd.S"+	;;++  microblaze*-*-*)+	TARGET=MICROBLAZE; TARGETDIR=microblaze+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  moxie-*-*)+	TARGET=MOXIE; TARGETDIR=moxie+	SOURCES="ffi.c"; ASM_SOURCES="eabi.S"+	;;++  metag-*-*)+	TARGET=METAG; TARGETDIR=metag+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)+	TARGET=MIPS; TARGETDIR=mips+	;;+  mips*-*linux* | mips*-*-openbsd* | mips*-*-freebsd*)+	# Support 128-bit long double for NewABI.+	HAVE_LONG_DOUBLE='defined(__mips64)'+	TARGET=MIPS; TARGETDIR=mips+	;;++  or1k*-*-*)+	TARGET=OR1K; TARGETDIR=or1k+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  powerpc*-*-linux* | powerpc-*-sysv*)+	TARGET=POWERPC; TARGETDIR=powerpc+	HAVE_LONG_DOUBLE_VARIANT=1+	;;+  powerpc-*-amigaos*)+	TARGET=POWERPC; TARGETDIR=powerpc+	;;+  powerpc-*-eabi*)+	TARGET=POWERPC; TARGETDIR=powerpc+	;;+  powerpc-*-beos* | powerpc-*-haiku*)+	TARGET=POWERPC; TARGETDIR=powerpc+	;;+  powerpc-*-darwin* | powerpc64-*-darwin*)+	TARGET=POWERPC_DARWIN; TARGETDIR=powerpc+	;;+  powerpc-*-aix* | rs6000-*-aix*)+	TARGET=POWERPC_AIX; TARGETDIR=powerpc+	# Create AIX-style "FAT" libraries.+	tmake_file="t-aix"+	;;+  powerpc-*-freebsd* | powerpc-*-openbsd* | powerpc-*-netbsd*)+	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc+	HAVE_LONG_DOUBLE_VARIANT=1+	;;+  powerpcspe-*-freebsd*)+	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc+	CFLAGS="$CFLAGS -D__NO_FPRS__"+	;;+  powerpc64-*-freebsd* | powerpc64le-*-freebsd*)+	TARGET=POWERPC; TARGETDIR=powerpc+	;;+  powerpc*-*-rtems*)+	TARGET=POWERPC; TARGETDIR=powerpc+	;;++  riscv*-*)+	TARGET=RISCV; TARGETDIR=riscv+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  s390-*-* | s390x-*-*)+	TARGET=S390; TARGETDIR=s390+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  sh-*-* | sh[34]*-*-*)+	TARGET=SH; TARGETDIR=sh+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;+  sh64-*-* | sh5*-*-*)+	TARGET=SH64; TARGETDIR=sh64+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;++  sparc*-*-*)+	TARGET=SPARC; TARGETDIR=sparc+	SOURCES="ffi.c ffi64.c"; ASM_SOURCES="v8.S v9.S"+	;;++  tile*-*)+        TARGET=TILE; TARGETDIR=tile+	SOURCES="ffi.c"; ASM_SOURCES="tile.S"+        ;;++  vax-*-*)+	TARGET=VAX; TARGETDIR=vax+	SOURCES="ffi.c"; ASM_SOURCES="elfbsd.S"+	;;++  wasm32-*-*)+	TARGET=wasm32; TARGETDIR=wasm+	SOURCES="ffi.c"+	;;++  wasm64-*-*)+	TARGET=wasm64; TARGETDIR=wasm+	SOURCES="ffi.c"+	;;++  xtensa*-*)+	TARGET=XTENSA; TARGETDIR=xtensa+	SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	;;+esac++# ... but some of the cases above share configury.+case "${TARGET}" in+  ARM_WIN32)+	if test "$MSVC" = 1; then+		SOURCES="ffi.c"; ASM_SOURCES="sysv_msvc_arm32.S"+	else+		SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	fi+	;;+  ARM_WIN64)+	if test "$MSVC" = 1; then+		SOURCES="ffi.c"; ASM_SOURCES="win64_armasm.S"+	else+		SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	fi+	;;+  MIPS)+	SOURCES="ffi.c"; ASM_SOURCES="o32.S n32.S"+	;;+  POWERPC)+	SOURCES="ffi.c ffi_sysv.c ffi_linux64.c"; ASM_SOURCES="sysv.S ppc_closure.S linux64.S linux64_closure.S"+	;;+  POWERPC_AIX)+	SOURCES="ffi_darwin.c"; ASM_SOURCES="aix.S aix_closure.S"+	;;+  POWERPC_DARWIN)+	SOURCES="ffi_darwin.c"; ASM_SOURCES="darwin.S darwin_closure.S"+	;;+  POWERPC_FREEBSD)+	SOURCES="ffi.c ffi_sysv.c"; ASM_SOURCES="sysv.S ppc_closure.S"+	;;+  X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32)+	if test "$MSVC" = 1; then+		SOURCES="ffi.c"; ASM_SOURCES="sysv_intel.S"+	else+		SOURCES="ffi.c"; ASM_SOURCES="sysv.S"+	fi+	;;+  X86_64)+	if test x"$TARGET_X32" = xyes; then+		SOURCES="ffi64.c"; ASM_SOURCES="unix64.S"+	else+		SOURCES="ffi64.c"; ASM_SOURCES="unix64.S ffiw64.c win64.S"+	fi+	;;+  X86_WIN64)+	if test "$MSVC" = 1; then+		SOURCES="ffiw64.c"; ASM_SOURCES="win64_intel.S"+	else+		SOURCES="ffiw64.c"; ASM_SOURCES="win64.S"+	fi+	;;+esac++# If we failed to configure SOURCES, we can't do anything.+if test -z "${SOURCES}"; then+  UNSUPPORTED=1+fi
+ fficonfig.h.in view
@@ -0,0 +1,182 @@+/* fficonfig.h.in.  Generated from configure.ac by autoheader.  */++/* Define if building universal (internal helper macro) */+#undef AC_APPLE_UNIVERSAL_BUILD++/* Define to the flags needed for the .section .eh_frame directive. */+#undef EH_FRAME_FLAGS++/* Define this if you want extra debugging. */+#undef FFI_DEBUG++/* Define this if you want statically defined trampolines */+#undef FFI_EXEC_STATIC_TRAMP++/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */+#undef FFI_EXEC_TRAMPOLINE_TABLE++/* Define this if you want to enable pax emulated trampolines (experimental)+   */+#undef FFI_MMAP_EXEC_EMUTRAMP_PAX++/* Cannot use malloc on this target, so, we revert to alternative means */+#undef FFI_MMAP_EXEC_WRIT++/* Define this if you do not want support for the raw API. */+#undef FFI_NO_RAW_API++/* Define this if you do not want support for aggregate types. */+#undef FFI_NO_STRUCTS++/* Define to 1 if you have the <alloca.h> header file. */+#undef HAVE_ALLOCA_H++/* Define if your compiler supports pointer authentication. */+#undef HAVE_ARM64E_PTRAUTH++/* Define if your assembler supports .cfi_* directives. */+#undef HAVE_AS_CFI_PSEUDO_OP++/* Define if your assembler supports .register. */+#undef HAVE_AS_REGISTER_PSEUDO_OP++/* Define if the compiler uses zarch features. */+#undef HAVE_AS_S390_ZARCH++/* Define if your assembler and linker support unaligned PC relative relocs.+   */+#undef HAVE_AS_SPARC_UA_PCREL++/* Define if your assembler supports unwind section type. */+#undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE++/* Define if your assembler supports PC relative relocs. */+#undef HAVE_AS_X86_PCREL++/* Define to 1 if you have the <dlfcn.h> header file. */+#undef HAVE_DLFCN_H++/* Define if __attribute__((visibility("hidden"))) is supported. */+#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE++/* Define to 1 if you have the <inttypes.h> header file. */+#undef HAVE_INTTYPES_H++/* Define if you have the long double type and it is bigger than a double */+#undef HAVE_LONG_DOUBLE++/* Define if you support more than one size of the long double type */+#undef HAVE_LONG_DOUBLE_VARIANT++/* Define to 1 if you have the 'memcpy' function. */+#undef HAVE_MEMCPY++/* Define to 1 if you have the 'memfd_create' function. */+#undef HAVE_MEMFD_CREATE++/* Define if .eh_frame sections should be read-only. */+#undef HAVE_RO_EH_FRAME++/* Define to 1 if you have the <stdint.h> header file. */+#undef HAVE_STDINT_H++/* Define to 1 if you have the <stdio.h> header file. */+#undef HAVE_STDIO_H++/* Define to 1 if you have the <stdlib.h> header file. */+#undef HAVE_STDLIB_H++/* Define to 1 if you have the <strings.h> header file. */+#undef HAVE_STRINGS_H++/* Define to 1 if you have the <string.h> header file. */+#undef HAVE_STRING_H++/* Define to 1 if you have the <sys/memfd.h> header file. */+#undef HAVE_SYS_MEMFD_H++/* Define to 1 if you have the <sys/stat.h> header file. */+#undef HAVE_SYS_STAT_H++/* Define to 1 if you have the <sys/types.h> header file. */+#undef HAVE_SYS_TYPES_H++/* Define to 1 if you have the <unistd.h> header file. */+#undef HAVE_UNISTD_H++/* Define to 1 if GNU symbol versioning is used for libatomic. */+#undef LIBFFI_GNU_SYMBOL_VERSIONING++/* Define to the sub-directory where libtool stores uninstalled libraries. */+#undef LT_OBJDIR++/* Define to the address where bug reports for this package should be sent. */+#undef PACKAGE_BUGREPORT++/* Define to the full name of this package. */+#undef PACKAGE_NAME++/* Define to the full name and version of this package. */+#undef PACKAGE_STRING++/* Define to the one symbol short name of this package. */+#undef PACKAGE_TARNAME++/* Define to the home page for this package. */+#undef PACKAGE_URL++/* Define to the version of this package. */+#undef PACKAGE_VERSION++/* The size of 'double', as computed by sizeof. */+#undef SIZEOF_DOUBLE++/* The size of 'long double', as computed by sizeof. */+#undef SIZEOF_LONG_DOUBLE++/* The size of 'size_t', as computed by sizeof. */+#undef SIZEOF_SIZE_T++/* Define to 1 if all of the C89 standard headers exist (not just the ones+   required in a freestanding environment). This macro is provided for+   backward compatibility; new code need not use it. */+#undef STDC_HEADERS++/* Define if symbols are underscored. */+#undef SYMBOL_UNDERSCORE++/* Define this if you are using Purify and want to suppress spurious messages.+   */+#undef USING_PURIFY++/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most+   significant byte first (like Motorola and SPARC, unlike Intel). */+#if defined AC_APPLE_UNIVERSAL_BUILD+# if defined __BIG_ENDIAN__+#  define WORDS_BIGENDIAN 1+# endif+#else+# ifndef WORDS_BIGENDIAN+#  undef WORDS_BIGENDIAN+# endif+#endif+++#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE+#ifdef LIBFFI_ASM+#ifdef __APPLE__+#define FFI_HIDDEN(name) .private_extern name+#else+#define FFI_HIDDEN(name) .hidden name+#endif+#else+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))+#endif+#else+#ifdef LIBFFI_ASM+#define FFI_HIDDEN(name)+#else+#define FFI_HIDDEN+#endif+#endif+
+ include/ffi.h.in view
@@ -0,0 +1,536 @@+/* -----------------------------------------------------------------*-C-*-+   libffi @VERSION@+     - Copyright (c) 2011, 2014, 2019, 2021, 2022, 2024, 2025 Anthony Green+     - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.++   Permission is hereby granted, free of charge, to any person+   obtaining a copy of this software and associated documentation+   files (the ``Software''), to deal in the Software without+   restriction, including without limitation the rights to use, copy,+   modify, merge, publish, distribute, sublicense, and/or sell copies+   of the Software, and to permit persons to whom the Software is+   furnished to do so, subject to the following conditions:++   The above copyright notice and this permission notice shall be+   included in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++/* -------------------------------------------------------------------+   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.  Routines+   are provided to emulate the raw API if the underlying platform+   doesn't allow faster implementation.++   More details on the raw API can be found in:++   http://gcc.gnu.org/ml/java/1999-q3/msg00138.html++   and++   http://gcc.gnu.org/ml/java/1999-q3/msg00174.html+   -------------------------------------------------------------------- */++#ifndef LIBFFI_H+#define LIBFFI_H++#ifdef __cplusplus+extern "C" {+#endif++/* Specify which architecture libffi is configured for. */+#ifndef @TARGET@+#define @TARGET@+#endif++/* ---- System configuration information --------------------------------- */++/* If these change, update src/mips/ffitarget.h. */+#define FFI_TYPE_VOID       0+#define FFI_TYPE_INT        1+#define FFI_TYPE_FLOAT      2+#define FFI_TYPE_DOUBLE     3+#if @HAVE_LONG_DOUBLE@+#define FFI_TYPE_LONGDOUBLE 4+#else+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE+#endif+#define FFI_TYPE_UINT8      5+#define FFI_TYPE_SINT8      6+#define FFI_TYPE_UINT16     7+#define FFI_TYPE_SINT16     8+#define FFI_TYPE_UINT32     9+#define FFI_TYPE_SINT32     10+#define FFI_TYPE_UINT64     11+#define FFI_TYPE_SINT64     12+#define FFI_TYPE_STRUCT     13+#define FFI_TYPE_POINTER    14+#define FFI_TYPE_COMPLEX    15++/* This should always refer to the last type code (for sanity checks).  */+#define FFI_TYPE_LAST       FFI_TYPE_COMPLEX++#include <ffitarget.h>++#ifndef LIBFFI_ASM++#if defined(_MSC_VER) && !defined(__clang__)+#define __attribute__(X)+#endif++#include <stddef.h>+#include <limits.h>++/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).+   But we can find it either under the correct ANSI name, or under GNU+   C's internal name.  */++#define FFI_64_BIT_MAX 9223372036854775807++#ifdef LONG_LONG_MAX+# define FFI_LONG_LONG_MAX LONG_LONG_MAX+#else+# ifdef LLONG_MAX+#  define FFI_LONG_LONG_MAX LLONG_MAX+#  ifdef _AIX52 /* or newer has C99 LLONG_MAX */+#   undef FFI_64_BIT_MAX+#   define FFI_64_BIT_MAX 9223372036854775807LL+#  endif /* _AIX52 or newer */+# else+#  ifdef __GNUC__+#   define FFI_LONG_LONG_MAX __LONG_LONG_MAX__+#  endif+#  ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */+#   ifndef __PPC64__+#    if defined (__IBMC__) || defined (__IBMCPP__)+#     define FFI_LONG_LONG_MAX LONGLONG_MAX+#    endif+#   endif /* __PPC64__ */+#   undef  FFI_64_BIT_MAX+#   define FFI_64_BIT_MAX 9223372036854775807LL+#  endif+# endif+#endif++/* The closure code assumes that this works on pointers, i.e. a size_t+   can hold a pointer.  */++typedef struct _ffi_type+{+  size_t size;+  unsigned short alignment;+  unsigned short type;+  struct _ffi_type **elements;+} ffi_type;++/* Need minimal decorations for DLLs to work on Windows.  GCC has+   autoimport and autoexport.  Always mark externally visible symbols+   as dllimport for MSVC clients, even if it means an extra indirection+   when using the static version of the library.+   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_STATIC_BUILD)+# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */+#  define FFI_API __declspec(dllexport)+# else  /* Importing libffi.DLL */+#  define FFI_API __declspec(dllimport)+# endif+#else+# define FFI_API+#endif++/* The externally visible type declarations also need the MSVC DLL+   decorations, or they will not be exported from the object file.  */+#if defined LIBFFI_HIDE_BASIC_TYPES+# define FFI_EXTERN FFI_API+#else+# define FFI_EXTERN extern FFI_API+#endif++#ifndef LIBFFI_HIDE_BASIC_TYPES+#if SCHAR_MAX == 127+# define ffi_type_uchar                ffi_type_uint8+# define ffi_type_schar                ffi_type_sint8+#else+ #error "char size not supported"+#endif++#if SHRT_MAX == 32767+# define ffi_type_ushort       ffi_type_uint16+# define ffi_type_sshort       ffi_type_sint16+#elif SHRT_MAX == 2147483647+# define ffi_type_ushort       ffi_type_uint32+# define ffi_type_sshort       ffi_type_sint32+#else+ #error "short size not supported"+#endif++#if INT_MAX == 32767+# define ffi_type_uint         ffi_type_uint16+# define ffi_type_sint         ffi_type_sint16+#elif INT_MAX == 2147483647+# define ffi_type_uint         ffi_type_uint32+# define ffi_type_sint         ffi_type_sint32+#elif INT_MAX == 9223372036854775807+# define ffi_type_uint         ffi_type_uint64+# define ffi_type_sint         ffi_type_sint64+#else+ #error "int size not supported"+#endif++#if LONG_MAX == 2147483647+# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX+ #error "no 64-bit data type supported"+# endif+#elif LONG_MAX != FFI_64_BIT_MAX+ #error "long size not supported"+#endif++#if LONG_MAX == 2147483647+# define ffi_type_ulong        ffi_type_uint32+# define ffi_type_slong        ffi_type_sint32+#elif LONG_MAX == FFI_64_BIT_MAX+# define ffi_type_ulong        ffi_type_uint64+# define ffi_type_slong        ffi_type_sint64+#else+ #error "long size not supported"+#endif++/* These are defined in types.c.  */+FFI_EXTERN ffi_type ffi_type_void;+FFI_EXTERN ffi_type ffi_type_uint8;+FFI_EXTERN ffi_type ffi_type_sint8;+FFI_EXTERN ffi_type ffi_type_uint16;+FFI_EXTERN ffi_type ffi_type_sint16;+FFI_EXTERN ffi_type ffi_type_uint32;+FFI_EXTERN ffi_type ffi_type_sint32;+FFI_EXTERN ffi_type ffi_type_uint64;+FFI_EXTERN ffi_type ffi_type_sint64;+FFI_EXTERN ffi_type ffi_type_float;+FFI_EXTERN ffi_type ffi_type_double;+FFI_EXTERN ffi_type ffi_type_pointer;+FFI_EXTERN ffi_type ffi_type_longdouble;++#ifdef FFI_TARGET_HAS_COMPLEX_TYPE+FFI_EXTERN ffi_type ffi_type_complex_float;+FFI_EXTERN ffi_type ffi_type_complex_double;+FFI_EXTERN ffi_type ffi_type_complex_longdouble;+#endif+#endif /* LIBFFI_HIDE_BASIC_TYPES */++typedef enum {+  FFI_OK = 0,+  FFI_BAD_TYPEDEF,+  FFI_BAD_ABI,+  FFI_BAD_ARGTYPE+} ffi_status;++typedef struct {+  ffi_abi abi;+  unsigned nargs;+  ffi_type **arg_types;+  ffi_type *rtype;+  unsigned bytes;+  unsigned flags;+#ifdef FFI_EXTRA_CIF_FIELDS+  FFI_EXTRA_CIF_FIELDS;+#endif+} ffi_cif;++/* ---- Definitions for the raw API -------------------------------------- */++#ifndef FFI_SIZEOF_ARG+# if LONG_MAX == 2147483647+#  define FFI_SIZEOF_ARG        4+# elif LONG_MAX == FFI_64_BIT_MAX+#  define FFI_SIZEOF_ARG        8+# endif+#endif++#ifndef FFI_SIZEOF_JAVA_RAW+#  define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG+#endif++typedef union {+  ffi_sarg  sint;+  ffi_arg   uint;+  float	    flt;+  char      data[FFI_SIZEOF_ARG];+  void*     ptr;+} ffi_raw;++#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8+/* This is a special case for mips64/n32 ABI (and perhaps others) where+   sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8.  */+typedef union {+  signed int	sint;+  unsigned int	uint;+  float		flt;+  char		data[FFI_SIZEOF_JAVA_RAW];+  void*		ptr;+} ffi_java_raw;+#else+typedef ffi_raw ffi_java_raw;+#endif+++FFI_API+void ffi_raw_call (ffi_cif *cif,+		   void (*fn)(void),+		   void *rvalue,+		   ffi_raw *avalue);++FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);+FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);+FFI_API 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.  */++#if !FFI_NATIVE_RAW_API+FFI_API+void ffi_java_raw_call (ffi_cif *cif,+			void (*fn)(void),+			void *rvalue,+			ffi_java_raw *avalue) __attribute__((deprecated));+#endif++FFI_API+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));+FFI_API+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));+FFI_API+size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));++/* ---- Version API ------------------------------------------------------ */++#define FFI_VERSION_STRING "@FFI_VERSION_STRING@"+#define FFI_VERSION_NUMBER @FFI_VERSION_NUMBER@++#ifndef LIBFFI_ASM+/* Return a version string. */+FFI_API const char *ffi_get_version (void);++/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */+FFI_API unsigned long ffi_get_version_number (void);+#endif++/* ---- Internals API ---------------------------------------------------- */++FFI_API unsigned int ffi_get_default_abi (void);+FFI_API size_t ffi_get_closure_size (void);++/* ---- Definitions for closures ----------------------------------------- */++#if FFI_CLOSURES++#ifdef _MSC_VER+__declspec(align(8))+#endif+typedef struct {+#if @FFI_EXEC_TRAMPOLINE_TABLE@+  void *trampoline_table;+  void *trampoline_table_entry;+#else+  union {+    char tramp[FFI_TRAMPOLINE_SIZE];+    void *ftramp;+  };+#endif+  ffi_cif   *cif;+  void     (*fun)(ffi_cif*,void*,void**,void*);+  void      *user_data;+#if defined(_MSC_VER) && defined(_M_IX86)+  void      *padding;+#endif+} ffi_closure+#ifdef __GNUC__+    __attribute__((aligned (8)))+#endif+    ;++#ifndef __GNUC__+# ifdef __sgi+#  pragma pack 0+# endif+#endif++FFI_API void *ffi_closure_alloc (size_t size, void **code);+FFI_API void ffi_closure_free (void *);++FFI_API ffi_status+ffi_prep_closure (ffi_closure*,+		  ffi_cif *,+		  void (*fun)(ffi_cif*,void*,void**,void*),+		  void *user_data)+#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)+  __attribute__((deprecated ("use ffi_prep_closure_loc instead")))+#elif defined(__GNUC__) && __GNUC__ >= 3+  __attribute__((deprecated))+#endif+  ;++FFI_API ffi_status+ffi_prep_closure_loc (ffi_closure*,+		      ffi_cif *,+		      void (*fun)(ffi_cif*,void*,void**,void*),+		      void *user_data,+		      void *codeloc);++#ifdef __sgi+# pragma pack 8+#endif+typedef struct {+#if @FFI_EXEC_TRAMPOLINE_TABLE@+  void *trampoline_table;+  void *trampoline_table_entry;+#else+  char tramp[FFI_TRAMPOLINE_SIZE];+#endif+  ffi_cif   *cif;++#if !FFI_NATIVE_RAW_API++  /* If this is enabled, then a raw closure has the same layout+     as a regular closure.  We use this to install an intermediate+     handler to do the translation, void** -> ffi_raw*.  */++  void     (*translate_args)(ffi_cif*,void*,void**,void*);+  void      *this_closure;++#endif++  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);+  void      *user_data;++} ffi_raw_closure;++typedef struct {+#if @FFI_EXEC_TRAMPOLINE_TABLE@+  void *trampoline_table;+  void *trampoline_table_entry;+#else+  char tramp[FFI_TRAMPOLINE_SIZE];+#endif++  ffi_cif   *cif;++#if !FFI_NATIVE_RAW_API++  /* If this is enabled, then a raw closure has the same layout+     as a regular closure.  We use this to install an intermediate+     handler to do the translation, void** -> ffi_raw*.  */++  void     (*translate_args)(ffi_cif*,void*,void**,void*);+  void      *this_closure;++#endif++  void     (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);+  void      *user_data;++} ffi_java_raw_closure;++FFI_API ffi_status+ffi_prep_raw_closure (ffi_raw_closure*,+		      ffi_cif *cif,+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),+		      void *user_data);++FFI_API ffi_status+ffi_prep_raw_closure_loc (ffi_raw_closure*,+			  ffi_cif *cif,+			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),+			  void *user_data,+			  void *codeloc);++#if !FFI_NATIVE_RAW_API+FFI_API ffi_status+ffi_prep_java_raw_closure (ffi_java_raw_closure*,+		           ffi_cif *cif,+		           void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),+		           void *user_data) __attribute__((deprecated));++FFI_API ffi_status+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,+			       ffi_cif *cif,+			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),+			       void *user_data,+			       void *codeloc) __attribute__((deprecated));+#endif++#endif /* FFI_CLOSURES */++#ifdef FFI_GO_CLOSURES++typedef struct {+  void      *tramp;+  ffi_cif   *cif;+  void     (*fun)(ffi_cif*,void*,void**,void*);+} ffi_go_closure;++FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,+				void (*fun)(ffi_cif*,void*,void**,void*));++FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+		  void **avalue, void *closure);++#endif /* FFI_GO_CLOSURES */++/* ---- Public interface definition -------------------------------------- */++FFI_API+ffi_status ffi_prep_cif(ffi_cif *cif,+			ffi_abi abi,+			unsigned int nargs,+			ffi_type *rtype,+			ffi_type **atypes);++FFI_API+ffi_status ffi_prep_cif_var(ffi_cif *cif,+			    ffi_abi abi,+			    unsigned int nfixedargs,+			    unsigned int ntotalargs,+			    ffi_type *rtype,+			    ffi_type **atypes);++FFI_API+void ffi_call(ffi_cif *cif,+	      void (*fn)(void),+	      void *rvalue,+	      void **avalue);++FFI_API+ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,+				   size_t *offsets);++/* Convert between closure and function pointers.  */+#if defined(PA_LINUX) || defined(PA_HPUX)+#define FFI_FN(f) ((void (*)(void))((unsigned int)(f) | 2))+#define FFI_CL(f) ((void *)((unsigned int)(f) & ~3))+#else+#define FFI_FN(f) ((void (*)(void))f)+#define FFI_CL(f) ((void *)(f))+#endif++/* ---- Definitions shared with assembly code ---------------------------- */++#endif++#ifdef __cplusplus+}+#endif++#endif
+ include/ffi_cfi.h view
@@ -0,0 +1,78 @@+/* -----------------------------------------------------------------------+   ffi_cfi.h - Copyright (c) 2014  Red Hat, Inc.++   Conditionally assemble cfi directives. Only necessary for building libffi.++   Permission is hereby granted, free of charge, to any person+   obtaining a copy of this software and associated documentation+   files (the ``Software''), to deal in the Software without+   restriction, including without limitation the rights to use, copy,+   modify, merge, publish, distribute, sublicense, and/or sell copies+   of the Software, and to permit persons to whom the Software is+   furnished to do so, subject to the following conditions:++   The above copyright notice and this permission notice shall be+   included in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef FFI_CFI_H+#define FFI_CFI_H++#ifdef HAVE_AS_CFI_PSEUDO_OP++# define cfi_startproc			.cfi_startproc+# define cfi_endproc			.cfi_endproc+# define cfi_def_cfa(reg, off)		.cfi_def_cfa reg, off+# define cfi_def_cfa_register(reg)	.cfi_def_cfa_register reg+# define cfi_def_cfa_offset(off)	.cfi_def_cfa_offset off+# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off+# define cfi_offset(reg, off)		.cfi_offset reg, off+# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off+# define cfi_register(r1, r2)		.cfi_register r1, r2+# define cfi_return_column(reg)		.cfi_return_column reg+# define cfi_restore(reg)		.cfi_restore reg+# define cfi_same_value(reg)		.cfi_same_value reg+# define cfi_undefined(reg)		.cfi_undefined reg+# define cfi_remember_state		.cfi_remember_state+# define cfi_restore_state		.cfi_restore_state+# define cfi_window_save		.cfi_window_save+# define cfi_personality(enc, exp)	.cfi_personality enc, exp+# define cfi_lsda(enc, exp)		.cfi_lsda enc, exp+# define cfi_escape(...)		.cfi_escape __VA_ARGS__+# define cfi_window_save		.cfi_window_save++#else++# define cfi_startproc+# define cfi_endproc+# define cfi_def_cfa(reg, off)+# define cfi_def_cfa_register(reg)+# define cfi_def_cfa_offset(off)+# define cfi_adjust_cfa_offset(off)+# define cfi_offset(reg, off)+# define cfi_rel_offset(reg, off)+# define cfi_register(r1, r2)+# define cfi_return_column(reg)+# define cfi_restore(reg)+# define cfi_same_value(reg)+# define cfi_undefined(reg)+# define cfi_remember_state+# define cfi_restore_state+# define cfi_window_save+# define cfi_personality(enc, exp)+# define cfi_lsda(enc, exp)+# define cfi_escape(...)+# define cfi_window_save++#endif /* HAVE_AS_CFI_PSEUDO_OP */+#endif /* FFI_CFI_H */
+ include/ffi_common.h view
@@ -0,0 +1,201 @@+/* -----------------------------------------------------------------------+   ffi_common.h - Copyright (C) 2011, 2012, 2013  Anthony Green+                  Copyright (C) 2007  Free Software Foundation, Inc+                  Copyright (c) 1996  Red Hat, Inc.+                  +   Common internal definitions and macros. Only necessary for building+   libffi.++   Permission is hereby granted, free of charge, to any person+   obtaining a copy of this software and associated documentation+   files (the ``Software''), to deal in the Software without+   restriction, including without limitation the rights to use, copy,+   modify, merge, publish, distribute, sublicense, and/or sell copies+   of the Software, and to permit persons to whom the Software is+   furnished to do so, subject to the following conditions:++   The above copyright notice and this permission notice shall be+   included in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef FFI_COMMON_H+#define FFI_COMMON_H++#ifdef __cplusplus+extern "C" {+#endif++#include <fficonfig.h>++/* Do not move this. Some versions of AIX are very picky about where+   this is positioned. */+#ifdef __GNUC__+# if HAVE_ALLOCA_H+#  include <alloca.h>+# else+  /* mingw64 defines this already in malloc.h. */+#  ifndef alloca+#    define alloca __builtin_alloca+#  endif+# endif+# define MAYBE_UNUSED __attribute__((__unused__))+# define NORETURN __attribute__((__noreturn__))+#else+# define MAYBE_UNUSED+# define NORETURN+# if HAVE_ALLOCA_H+#  include <alloca.h>+# else+#  ifdef _AIX+#   pragma alloca+#  else+#   ifndef alloca /* predefined by HP cc +Olibcalls */+#    ifdef _MSC_VER+#     define alloca _alloca+#    else+char *alloca ();+#   endif+#  endif+# endif+# endif+#endif++/* Check for the existence of memcpy. */+#if STDC_HEADERS+# include <string.h>+#else+# ifndef HAVE_MEMCPY+#  define memcpy(d, s, n) bcopy ((s), (d), (n))+# endif+#endif++#if defined(FFI_DEBUG)+#include <stdio.h>+#endif++#ifndef __SANITIZE_ADDRESS__+# ifdef __clang__+#  if __has_feature(address_sanitizer)+#   define FFI_ASAN+#  endif+# endif+#endif+#ifdef __SANITIZE_ADDRESS__+#define FFI_ASAN+#endif++#ifdef FFI_ASAN+#define FFI_ASAN_NO_SANITIZE __attribute__((no_sanitize_address))+#else+#define FFI_ASAN_NO_SANITIZE+#endif++#ifdef FFI_DEBUG+NORETURN void ffi_assert(const char *expr, const char *file, int line);+void ffi_stop_here(void);+void ffi_type_test(ffi_type *a, const char *file, int line);++#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)+#else+#define FFI_ASSERT(x)+#define FFI_ASSERT_AT(x, f, l)+#define FFI_ASSERT_VALID_TYPE(x)+#endif++/* v cast to size_t and aligned up to a multiple of a */+#define FFI_ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)+/* v cast to size_t and aligned down to a multiple of a */+#define FFI_ALIGN_DOWN(v, a) (((size_t) (v)) & -a)++/* Perform machine dependent cif processing */+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);++/* Translate a data pointer to a code pointer.  Needed for closures on+   some targets.  */+void *ffi_data_to_code_pointer (void *data) FFI_HIDDEN;++/* The arch code calls this to determine if a given closure has a+   static trampoline. */+int ffi_tramp_is_present (void *closure) FFI_HIDDEN;++/* Return a file descriptor of a temporary zero-sized file in a+   writable and executable filesystem. */+int open_temp_exec_file(void) FFI_HIDDEN;++/* Extended cif, used in callback from assembly routine */+typedef struct+{+  ffi_cif *cif;+  void *rvalue;+  void **avalue;+} extended_cif;++/* Terse sized type definitions.  */+#if defined(_MSC_VER) || defined(__sgi) || defined(__SUNPRO_C)+typedef unsigned char UINT8;+typedef signed char   SINT8;+typedef unsigned short UINT16;+typedef signed short   SINT16;+typedef unsigned int UINT32;+typedef signed int   SINT32;+# ifdef _MSC_VER+typedef unsigned __int64 UINT64;+typedef signed __int64   SINT64;+# else+# include <inttypes.h>+typedef uint64_t UINT64;+typedef int64_t  SINT64;+# endif+#else+typedef unsigned int UINT8  __attribute__((__mode__(__QI__)));+typedef signed int   SINT8  __attribute__((__mode__(__QI__)));+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));+typedef signed int   SINT16 __attribute__((__mode__(__HI__)));+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));+typedef signed int   SINT32 __attribute__((__mode__(__SI__)));+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));+typedef signed int   SINT64 __attribute__((__mode__(__DI__)));+#endif++typedef float FLOAT32;++#ifndef __GNUC__+#define __builtin_expect(x, expected_value) (x)+#endif+#define LIKELY(x)    __builtin_expect(!!(x),1)+#define UNLIKELY(x)  __builtin_expect((x)!=0,0)++#ifdef __cplusplus+}+#endif++#endif
+ include/tramp.h view
@@ -0,0 +1,45 @@+/* -----------------------------------------------------------------------+   ffi_tramp.h - Copyright (C) 2021  Microsoft, Inc.++   Static trampoline definitions.++   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 FFI_TRAMP_H+#define FFI_TRAMP_H++#ifdef __cplusplus+extern "C" {+#endif++int ffi_tramp_is_supported(void);+void *ffi_tramp_alloc (int flags);+void ffi_tramp_set_parms (void *tramp, void *data, void *code);+void *ffi_tramp_get_addr (void *tramp);+void ffi_tramp_free (void *tramp);++#ifdef __cplusplus+}+#endif++#endif /* FFI_TRAMP_H */
+ install-sh view
@@ -0,0 +1,541 @@+#!/bin/sh+# install - install a program, script, or datafile++scriptversion=2024-06-19.01; # UTC++# This originates from X11R5 (mit/util/scripts/install.sh), which was+# later released in X11R6 (xc/config/util/install.sh) with the+# following copyright and license.+#+# Copyright (C) 1994 X Consortium+#+# 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+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+#+# Except as contained in this notice, the name of the X Consortium shall not+# be used in advertising or otherwise to promote the sale, use or other deal-+# ings in this Software without prior written authorization from the X Consor-+# tium.+#+#+# FSF changes to this file are in the public domain.+#+# Calling this script install-sh is preferred over install.sh, to prevent+# 'make' implicit rules from creating a file called install from it+# when there is no Makefile.+#+# This script is compatible with the BSD install script, but was written+# from scratch.++tab='	'+nl='+'+IFS=" $tab$nl"++# Set DOITPROG to "echo" to test this script.++doit=${DOITPROG-}+doit_exec=${doit:-exec}++# Put in absolute file names if you don't have them in your path;+# or use environment vars.++chgrpprog=${CHGRPPROG-chgrp}+chmodprog=${CHMODPROG-chmod}+chownprog=${CHOWNPROG-chown}+cmpprog=${CMPPROG-cmp}+cpprog=${CPPROG-cp}+mkdirprog=${MKDIRPROG-mkdir}+mvprog=${MVPROG-mv}+rmprog=${RMPROG-rm}+stripprog=${STRIPPROG-strip}++posix_mkdir=++# Desired mode of installed file.+mode=0755++# Create dirs (including intermediate dirs) using mode 755.+# This is like GNU 'install' as of coreutils 8.32 (2020).+mkdir_umask=22++backupsuffix=+chgrpcmd=+chmodcmd=$chmodprog+chowncmd=+mvcmd=$mvprog+rmcmd="$rmprog -f"+stripcmd=++src=+dst=+dir_arg=+dst_arg=++copy_on_change=false+is_target_a_directory=possibly++usage="\+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE+   or: $0 [OPTION]... SRCFILES... DIRECTORY+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...+   or: $0 [OPTION]... -d DIRECTORIES...++In the 1st form, copy SRCFILE to DSTFILE.+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.+In the 4th, create DIRECTORIES.++Options:+     --help     display this help and exit.+     --version  display version info and exit.++  -c            (ignored)+  -C            install only if different (preserve data modification time)+  -d            create directories instead of installing files.+  -g GROUP      $chgrpprog installed files to GROUP.+  -m MODE       $chmodprog installed files to MODE.+  -o USER       $chownprog installed files to USER.+  -p            pass -p to $cpprog.+  -s            $stripprog installed files.+  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.+  -t DIRECTORY  install into DIRECTORY.+  -T            report an error if DSTFILE is a directory.++Environment variables override the default commands:+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG+  RMPROG STRIPPROG++By default, rm is invoked with -f; when overridden with RMPROG,+it's up to you to specify -f if you want it.++If -S is not specified, no backups are attempted.++Report bugs to <bug-automake@gnu.org>.+GNU Automake home page: <https://www.gnu.org/software/automake/>.+General help using GNU software: <https://www.gnu.org/gethelp/>."++while test $# -ne 0; do+  case $1 in+    -c) ;;++    -C) copy_on_change=true;;++    -d) dir_arg=true;;++    -g) chgrpcmd="$chgrpprog $2"+        shift;;++    --help) echo "$usage"; exit $?;;++    -m) mode=$2+        case $mode in+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)+            echo "$0: invalid mode: $mode" >&2+            exit 1;;+        esac+        shift;;++    -o) chowncmd="$chownprog $2"+        shift;;++    -p) cpprog="$cpprog -p";;++    -s) stripcmd=$stripprog;;++    -S) backupsuffix="$2"+        shift;;++    -t)+        is_target_a_directory=always+        dst_arg=$2+        # Protect names problematic for 'test' and other utilities.+        case $dst_arg in+          -* | [=\(\)!]) dst_arg=./$dst_arg;;+        esac+        shift;;++    -T) is_target_a_directory=never;;++    --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;;++    --) shift+        break;;++    -*) echo "$0: invalid option: $1" >&2+        exit 1;;++    *)  break;;+  esac+  shift+done++# We allow the use of options -d and -T together, by making -d+# take the precedence; this is for compatibility with GNU install.++if test -n "$dir_arg"; then+  if test -n "$dst_arg"; then+    echo "$0: target directory not allowed when installing a directory." >&2+    exit 1+  fi+fi++if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then+  # When -d is used, all remaining arguments are directories to create.+  # When -t is used, the destination is already specified.+  # Otherwise, the last argument is the destination.  Remove it from $@.+  for arg+  do+    if test -n "$dst_arg"; then+      # $@ is not empty: it contains at least $arg.+      set fnord "$@" "$dst_arg"+      shift # fnord+    fi+    shift # arg+    dst_arg=$arg+    # Protect names problematic for 'test' and other utilities.+    case $dst_arg in+      -* | [=\(\)!]) dst_arg=./$dst_arg;;+    esac+  done+fi++if test $# -eq 0; then+  if test -z "$dir_arg"; then+    echo "$0: no input file specified." >&2+    exit 1+  fi+  # It's OK to call 'install-sh -d' without argument.+  # This can happen when creating conditional directories.+  exit 0+fi++if test -z "$dir_arg"; then+  if test $# -gt 1 || test "$is_target_a_directory" = always; then+    if test ! -d "$dst_arg"; then+      echo "$0: $dst_arg: Is not a directory." >&2+      exit 1+    fi+  fi+fi++if test -z "$dir_arg"; then+  do_exit='(exit $ret); exit $ret'+  trap "ret=129; $do_exit" 1+  trap "ret=130; $do_exit" 2+  trap "ret=141; $do_exit" 13+  trap "ret=143; $do_exit" 15++  # Set umask so as not to create temps with too-generous modes.+  # However, 'strip' requires both read and write access to temps.+  case $mode in+    # Optimize common cases.+    *644) cp_umask=133;;+    *755) cp_umask=22;;++    *[0-7])+      if test -z "$stripcmd"; then+        u_plus_rw=+      else+        u_plus_rw='% 200'+      fi+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;+    *)+      if test -z "$stripcmd"; then+        u_plus_rw=+      else+        u_plus_rw=,u+rw+      fi+      cp_umask=$mode$u_plus_rw;;+  esac+fi++for src+do+  # Protect names problematic for 'test' and other utilities.+  case $src in+    -* | [=\(\)!]) src=./$src;;+  esac++  if test -n "$dir_arg"; then+    dst=$src+    dstdir=$dst+    test -d "$dstdir"+    dstdir_status=$?+    # Don't chown directories that already exist.+    if test $dstdir_status = 0; then+      chowncmd=""+    fi+  else++    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command+    # might cause directories to be created, which would be especially bad+    # if $src (and thus $dsttmp) contains '*'.+    if test ! -f "$src" && test ! -d "$src"; then+      echo "$0: $src does not exist." >&2+      exit 1+    fi++    if test -z "$dst_arg"; then+      echo "$0: no destination specified." >&2+      exit 1+    fi+    dst=$dst_arg++    # If destination is a directory, append the input filename.+    if test -d "$dst"; then+      if test "$is_target_a_directory" = never; then+        echo "$0: $dst_arg: Is a directory" >&2+        exit 1+      fi+      dstdir=$dst+      dstbase=`basename "$src"`+      case $dst in+	*/) dst=$dst$dstbase;;+	*)  dst=$dst/$dstbase;;+      esac+      dstdir_status=0+    else+      dstdir=`dirname "$dst"`+      test -d "$dstdir"+      dstdir_status=$?+    fi+  fi++  case $dstdir in+    */) dstdirslash=$dstdir;;+    *)  dstdirslash=$dstdir/;;+  esac++  obsolete_mkdir_used=false++  if test $dstdir_status != 0; then+    case $posix_mkdir in+      '')+        # With -d, create the new directory with the user-specified mode.+        # Otherwise, rely on $mkdir_umask.+        if test -n "$dir_arg"; then+          mkdir_mode=-m$mode+        else+          mkdir_mode=+        fi++        posix_mkdir=false+	# The $RANDOM variable is not portable (e.g., dash).  Use it+	# here however when possible just to lower collision chance.+	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$++	trap '+	  ret=$?+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null+	  exit $ret+	' 0++	# Because "mkdir -p" follows existing symlinks and we likely work+	# directly in world-writable /tmp, make sure that the '$tmpdir'+	# directory is successfully created first before we actually test+	# 'mkdir -p'.+	if (umask $mkdir_umask &&+	    $mkdirprog $mkdir_mode "$tmpdir" &&+	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1+	then+	  if test -z "$dir_arg" || {+	       # Check for POSIX incompatibility with -m.+	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or+	       # other-writable bit of parent directory when it shouldn't.+	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.+	       test_tmpdir="$tmpdir/a"+	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`+	       case $ls_ld_tmpdir in+		 d????-?r-*) different_mode=700;;+		 d????-?--*) different_mode=755;;+		 *) false;;+	       esac &&+	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {+		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`+		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"+	       }+	     }+	  then posix_mkdir=:+	  fi+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"+	else+	  # Remove any dirs left behind by ancient mkdir implementations.+	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null+	fi+	trap '' 0;;+    esac++    if+      $posix_mkdir && (+        umask $mkdir_umask &&+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"+      )+    then :+    else++      # mkdir does not conform to POSIX,+      # or it failed possibly due to a race condition.  Create the+      # directory the slow way, step by step, checking for races as we go.++      case $dstdir in+        /*) prefix='/';;+        [-=\(\)!]*) prefix='./';;+        *)  prefix='';;+      esac++      oIFS=$IFS+      IFS=/+      set -f+      set fnord $dstdir+      shift+      set +f+      IFS=$oIFS++      prefixes=++      for d+      do+        test X"$d" = X && continue++        prefix=$prefix$d+        if test -d "$prefix"; then+          prefixes=+        else+          if $posix_mkdir; then+            (umask $mkdir_umask &&+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break+            # Don't fail if two instances are running concurrently.+            test -d "$prefix" || exit 1+          else+            case $prefix in+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;+              *) qprefix=$prefix;;+            esac+            prefixes="$prefixes '$qprefix'"+          fi+        fi+        prefix=$prefix/+      done++      if test -n "$prefixes"; then+        # Don't fail if two instances are running concurrently.+        (umask $mkdir_umask &&+         eval "\$doit_exec \$mkdirprog $prefixes") ||+          test -d "$dstdir" || exit 1+        obsolete_mkdir_used=true+      fi+    fi+  fi++  if test -n "$dir_arg"; then+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1+  else++    # Make a couple of temp file names in the proper directory.+    dsttmp=${dstdirslash}_inst.$$_+    rmtmp=${dstdirslash}_rm.$$_++    # Trap to clean up those temp files at exit.+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0++    # Copy the file name to the temp name.+    (umask $cp_umask &&+     { test -z "$stripcmd" || {+	 # Create $dsttmp read-write so that cp doesn't create it read-only,+	 # which would cause strip to fail.+	 if test -z "$doit"; then+	   : >"$dsttmp" # No need to fork-exec 'touch'.+	 else+	   $doit touch "$dsttmp"+	 fi+       }+     } &&+     $doit_exec $cpprog "$src" "$dsttmp") &&++    # and set any options; do chmod last to preserve setuid bits.+    #+    # If any of these fail, we abort the whole thing.  If we want to+    # ignore errors from any of these, just make sure not to ignore+    # errors from the above "$doit $cpprog $src $dsttmp" command.+    #+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&++    # If -C, don't bother to copy if it wouldn't change the file.+    if $copy_on_change &&+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&+       set -f &&+       set X $old && old=:$2:$4:$5:$6 &&+       set X $new && new=:$2:$4:$5:$6 &&+       set +f &&+       test "$old" = "$new" &&+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1+    then+      rm -f "$dsttmp"+    else+      # If $backupsuffix is set, and the file being installed+      # already exists, attempt a backup.  Don't worry if it fails,+      # e.g., if mv doesn't support -f.+      if test -n "$backupsuffix" && test -f "$dst"; then+        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null+      fi++      # Rename the file to the real destination.+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||++      # The rename failed, perhaps because mv can't rename something else+      # to itself, or perhaps because mv is so ancient that it does not+      # support -f.+      {+        # Now remove or move aside any old file at destination location.+        # We try this two ways since rm can't unlink itself on some+        # systems and the destination file might be busy for other+        # reasons.  In this case, the final cleanup might fail but the new+        # file should still install successfully.+        {+          test ! -f "$dst" ||+          $doit $rmcmd "$dst" 2>/dev/null ||+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&+            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }+          } ||+          { echo "$0: cannot unlink or rename $dst" >&2+            (exit 1); exit 1+          }+        } &&++        # Now rename the file to the real destination.+        $doit $mvcmd "$dsttmp" "$dst"+      }+    fi || exit 1++    trap '' 0+  fi+done++# Local variables:+# eval: (add-hook 'before-save-hook 'time-stamp)+# time-stamp-start: "scriptversion="+# time-stamp-format: "%:y-%02m-%02d.%02H"+# time-stamp-time-zone: "UTC0"+# time-stamp-end: "; # UTC"+# End:
+ libffi-clib.buildinfo.in view
@@ -0,0 +1,7 @@+extra-libraries: @EXTRA_LIBS@+cc-options: @CFLAGS@+ld-options: @LDFLAGS@+include-dirs: src/@TARGETDIR@+install-includes: ffitarget.h+c-sources: @EXTRA_SOURCES@+asm-sources: @EXTRA_ASM_SOURCES@
+ libffi-clib.cabal view
@@ -0,0 +1,92 @@+cabal-version:      3.12+name:               libffi-clib+version:            3.5.2+synopsis:           libffi clibs+description:        C source code for the libffi package+license:            MIT+author:             Julian Ospald+maintainer:         hasufell@posteo.de+build-type:         Configure+extra-doc-files:    CHANGELOG.md++extra-source-files:+    aclocal.m4+    compile+    config.guess+    config.sub+    configure+    configure.ac+    configure.host+    fficonfig.h.in+    include/ffi.h.in+    include/*.h+    install-sh+    libffi-clib.buildinfo.in+    ltmain.sh+    m4/*.m4+    src/**/*.S+    src/**/*.c+    src/**/*.h++flag profiling+  default: False+  manual: True+flag debug+  default: False+  manual: True+flag dynamic+  default: False+  manual: True+flag threaded+  default: False+  manual: True++library+  if arch(javascript)+    buildable: False++  default-language: Haskell2010+  c-sources:+    src/prep_cif.c+    src/types.c+    src/raw_api.c+    src/java_raw_api.c+    src/closures.c+    src/tramp.c++  include-dirs: include+  autogen-includes:+    ffi.h+  install-includes:+    ffi.h++  if flag(threaded)+    extra-library-flavours: _thr+    if flag(dynamic)+      extra-dynamic-library-flavours: _thr++  if flag(profiling)+    extra-library-flavours: _p+    if flag(threaded)+      extra-library-flavours: _thr_p+    if flag(debug)+      extra-library-flavours: _debug_p+      if flag(threaded)+        extra-library-flavours: _thr_debug_p+    if flag(dynamic)+      extra-dynamic-library-flavours: _p+      if flag(threaded)+        extra-dynamic-library-flavours: _thr_p+      if flag(debug)+        extra-dynamic-library-flavours: _debug_p+        if flag(threaded)+          extra-dynamic-library-flavours: _thr_debug_p++  if flag(debug)+    extra-library-flavours: _debug+    if flag(dynamic)+      extra-dynamic-library-flavours: _debug+    if flag(threaded)+      extra-library-flavours: _thr_debug+      if flag(dynamic)+        extra-dynamic-library-flavours: _thr_debug
+ ltmain.sh view
@@ -0,0 +1,11517 @@+#! /usr/bin/env sh+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in+##               by inline-source v2019-02-19.15++# libtool (GNU libtool) 2.5.4+# Provide generalized library-building support services.+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996++# Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc.+# This is free software; see the source for copying conditions.  There is NO+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.++# GNU Libtool 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+# (at your option) any later version.+#+# As a special exception to the GNU General Public License,+# if you distribute this file as part of a program or library that+# is built using GNU Libtool, you may include this file under the+# same distribution terms that you use for the rest of that program.+#+# GNU Libtool is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+# General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program.  If not, see <http://www.gnu.org/licenses/>.+++PROGRAM=libtool+PACKAGE=libtool+VERSION=2.5.4+package_revision=2.5.4+++## ------ ##+## Usage. ##+## ------ ##++# Run './libtool --help' for help with using this script from the+# command line.+++## ------------------------------- ##+## User overridable command paths. ##+## ------------------------------- ##++# After configure completes, it has a better idea of some of the+# shell tools we need than the defaults used by the functions shared+# with bootstrap, so set those here where they can still be over-+# ridden by the user, but otherwise take precedence.++: ${AUTOCONF="autoconf"}+: ${AUTOMAKE="automake"}+++## -------------------------- ##+## Source external libraries. ##+## -------------------------- ##++# Much of our low-level functionality needs to be sourced from external+# libraries, which are installed to $pkgauxdir.++# Set a version string for this script.+scriptversion=2019-02-19.15; # UTC++# General shell script boiler plate, and helper functions.+# Written by Gary V. Vaughan, 2004++# This is free software.  There is NO warranty; not even for+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.+#+# Copyright (C) 2004-2019, 2021, 2023-2024 Bootstrap Authors+#+# This file is dual licensed under the terms of the MIT license+# <https://opensource.org/licenses/MIT>, and GPL version 2 or later+# <https://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of+# these licenses when using or redistributing this software or any of+# the files within it.  See the URLs above, or the file `LICENSE`+# included in the Bootstrap distribution for the full license texts.++# Please report bugs or propose patches to:+# <https://github.com/gnulib-modules/bootstrap/issues>+++## ------ ##+## Usage. ##+## ------ ##++# Evaluate this file near the top of your script to gain access to+# the functions and variables defined here:+#+#   . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh+#+# If you need to override any of the default environment variable+# settings, do that before evaluating this file.+++## -------------------- ##+## Shell normalisation. ##+## -------------------- ##++# Some shells need a little help to be as Bourne compatible as possible.+# Before doing anything else, make sure all that help has been provided!++DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else+  case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac+fi++# NLS nuisances: We save the old values in case they are required later.+_G_user_locale=+_G_safe_locale=+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES+do+  eval "if test set = \"\${$_G_var+set}\"; then+          save_$_G_var=\$$_G_var+          $_G_var=C+	  export $_G_var+	  _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"+	  _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"+	fi"+done+# These NLS vars are set unconditionally (bootstrap issue #24).  Unset those+# in case the environment reset is needed later and the $save_* variant is not+# defined (see the code above).+LC_ALL=C+LANGUAGE=C+export LANGUAGE LC_ALL++# Make sure IFS has a sensible default+sp=' '+nl='+'+IFS="$sp	$nl"++# There are apparently some systems that use ';' as a PATH separator!+if test "${PATH_SEPARATOR+set}" != set; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# func_unset VAR+# --------------+# Portably unset VAR.+# In some shells, an 'unset VAR' statement leaves a non-zero return+# status if VAR is already unset, which might be problematic if the+# statement is used at the end of a function (thus poisoning its return+# value) or when 'set -e' is active (causing even a spurious abort of+# the script in this case).+func_unset ()+{+    { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }+}+++# Make sure CDPATH doesn't cause `cd` commands to output the target dir.+func_unset CDPATH++# Make sure ${,E,F}GREP behave sanely.+func_unset GREP_OPTIONS+++## ------------------------- ##+## Locate command utilities. ##+## ------------------------- ##+++# func_executable_p FILE+# ----------------------+# Check that FILE is an executable regular file.+func_executable_p ()+{+    test -f "$1" && test -x "$1"+}+++# func_path_progs PROGS_LIST CHECK_FUNC [PATH]+# --------------------------------------------+# Search for either a program that responds to --version with output+# containing "GNU", or else returned by CHECK_FUNC otherwise, by+# trying all the directories in PATH with each of the elements of+# PROGS_LIST.+#+# CHECK_FUNC should accept the path to a candidate program, and+# set $func_check_prog_result if it truncates its output less than+# $_G_path_prog_max characters.+func_path_progs ()+{+    _G_progs_list=$1+    _G_check_func=$2+    _G_PATH=${3-"$PATH"}++    _G_path_prog_max=0+    _G_path_prog_found=false+    _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}+    for _G_dir in $_G_PATH; do+      IFS=$_G_save_IFS+      test -z "$_G_dir" && _G_dir=.+      for _G_prog_name in $_G_progs_list; do+        for _exeext in '' .EXE; do+          _G_path_prog=$_G_dir/$_G_prog_name$_exeext+          func_executable_p "$_G_path_prog" || continue+          case `"$_G_path_prog" --version 2>&1` in+            *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;+            *)     $_G_check_func $_G_path_prog+		   func_path_progs_result=$func_check_prog_result+		   ;;+          esac+          $_G_path_prog_found && break 3+        done+      done+    done+    IFS=$_G_save_IFS+    test -z "$func_path_progs_result" && {+      echo "no acceptable sed could be found in \$PATH" >&2+      exit 1+    }+}+++# We want to be able to use the functions in this file before configure+# has figured out where the best binaries are kept, which means we have+# to search for them ourselves - except when the results are already set+# where we skip the searches.++# Unless the user overrides by setting SED, search the path for either GNU+# sed, or the sed that truncates its output the least.+test -z "$SED" && {+  _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/+  for _G_i in 1 2 3 4 5 6 7; do+    _G_sed_script=$_G_sed_script$nl$_G_sed_script+  done+  echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed+  _G_sed_script=++  func_check_prog_sed ()+  {+    _G_path_prog=$1++    _G_count=0+    printf 0123456789 >conftest.in+    while :+    do+      cat conftest.in conftest.in >conftest.tmp+      mv conftest.tmp conftest.in+      cp conftest.in conftest.nl+      echo '' >> conftest.nl+      "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break+      diff conftest.out conftest.nl >/dev/null 2>&1 || break+      _G_count=`expr $_G_count + 1`+      if test "$_G_count" -gt "$_G_path_prog_max"; then+        # Best one so far, save it but keep looking for a better one+        func_check_prog_result=$_G_path_prog+        _G_path_prog_max=$_G_count+      fi+      # 10*(2^10) chars as input seems more than enough+      test 10 -lt "$_G_count" && break+    done+    rm -f conftest.in conftest.tmp conftest.nl conftest.out+  }++  func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"+  rm -f conftest.sed+  SED=$func_path_progs_result+}+++# Unless the user overrides by setting GREP, search the path for either GNU+# grep, or the grep that truncates its output the least.+test -z "$GREP" && {+  func_check_prog_grep ()+  {+    _G_path_prog=$1++    _G_count=0+    _G_path_prog_max=0+    printf 0123456789 >conftest.in+    while :+    do+      cat conftest.in conftest.in >conftest.tmp+      mv conftest.tmp conftest.in+      cp conftest.in conftest.nl+      echo 'GREP' >> conftest.nl+      "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break+      diff conftest.out conftest.nl >/dev/null 2>&1 || break+      _G_count=`expr $_G_count + 1`+      if test "$_G_count" -gt "$_G_path_prog_max"; then+        # Best one so far, save it but keep looking for a better one+        func_check_prog_result=$_G_path_prog+        _G_path_prog_max=$_G_count+      fi+      # 10*(2^10) chars as input seems more than enough+      test 10 -lt "$_G_count" && break+    done+    rm -f conftest.in conftest.tmp conftest.nl conftest.out+  }++  func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"+  GREP=$func_path_progs_result+}+++## ------------------------------- ##+## User overridable command paths. ##+## ------------------------------- ##++# All uppercase variable names are used for environment variables.  These+# variables can be overridden by the user before calling a script that+# uses them if a suitable command of that name is not already available+# in the command search PATH.++: ${CP="cp -f"}+: ${ECHO="printf %s\n"}+: ${EGREP="$GREP -E"}+: ${FGREP="$GREP -F"}+: ${LN_S="ln -s"}+: ${MAKE="make"}+: ${MKDIR="mkdir"}+: ${MV="mv -f"}+: ${RM="rm -f"}+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}+++## -------------------- ##+## Useful sed snippets. ##+## -------------------- ##++sed_dirname='s|/[^/]*$||'+sed_basename='s|^.*/||'++# Sed substitution that helps us do robust quoting.  It backslashifies+# metacharacters that are still active within double-quoted strings.+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'++# Same as above, but do not quote variable references.+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'++# Sed substitution that turns a string into a regex matching for the+# string literally.+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'++# Sed substitution that converts a w32 file name or path+# that contains forward slashes, into one that contains+# (escaped) backslashes.  A very naive implementation.+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'++# Re-'\' parameter expansions in output of sed_double_quote_subst that+# were '\'-ed in input to the same.  If an odd number of '\' preceded a+# '$' in input to sed_double_quote_subst, that '$' was protected from+# expansion.  Since each input '\' is now two '\'s, look for any number+# of runs of four '\'s followed by two '\'s and then a '$'.  '\' that '$'.+_G_bs='\\'+_G_bs2='\\\\'+_G_bs4='\\\\\\\\'+_G_dollar='\$'+sed_double_backslash="\+  s/$_G_bs4/&\\+/g+  s/^$_G_bs2$_G_dollar/$_G_bs&/+  s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g+  s/\n//g"++# require_check_ifs_backslash+# ---------------------------+# Check if we can use backslash as IFS='\' separator, and set+# $check_ifs_backshlash_broken to ':' or 'false'.+require_check_ifs_backslash=func_require_check_ifs_backslash+func_require_check_ifs_backslash ()+{+  _G_save_IFS=$IFS+  IFS='\'+  _G_check_ifs_backshlash='a\\b'+  for _G_i in $_G_check_ifs_backshlash+  do+  case $_G_i in+  a)+    check_ifs_backshlash_broken=false+    ;;+  '')+    break+    ;;+  *)+    check_ifs_backshlash_broken=:+    break+    ;;+  esac+  done+  IFS=$_G_save_IFS+  require_check_ifs_backslash=:+}+++## ----------------- ##+## Global variables. ##+## ----------------- ##++# Except for the global variables explicitly listed below, the following+# functions in the '^func_' namespace, and the '^require_' namespace+# variables initialised in the 'Resource management' section, sourcing+# this file will not pollute your global namespace with anything+# else. There's no portable way to scope variables in Bourne shell+# though, so actually running these functions will sometimes place+# results into a variable named after the function, and often use+# temporary variables in the '^_G_' namespace. If you are careful to+# avoid using those namespaces casually in your sourcing script, things+# should continue to work as you expect. And, of course, you can freely+# overwrite any of the functions or variables defined here before+# calling anything to customize them.++EXIT_SUCCESS=0+EXIT_FAILURE=1+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.++# Allow overriding, eg assuming that you follow the convention of+# putting '$debug_cmd' at the start of all your functions, you can get+# bash to show function call trace with:+#+#    debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name+debug_cmd=${debug_cmd-":"}+exit_cmd=:++# By convention, finish your script with:+#+#    exit $exit_status+#+# so that you can set exit_status to non-zero if you want to indicate+# something went wrong during execution without actually bailing out at+# the point of failure.+exit_status=$EXIT_SUCCESS++# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh+# is ksh but when the shell is invoked as "sh" and the current value of+# the _XPG environment variable is not equal to 1 (one), the special+# positional parameter $0, within a function call, is the name of the+# function.+progpath=$0++# The name of this program.+progname=`$ECHO "$progpath" |$SED "$sed_basename"`++# Make sure we have an absolute progpath for reexecution:+case $progpath in+  [\\/]*|[A-Za-z]:\\*) ;;+  *[\\/]*)+     progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`+     progdir=`cd "$progdir" && pwd`+     progpath=$progdir/$progname+     ;;+  *)+     _G_IFS=$IFS+     IFS=${PATH_SEPARATOR-:}+     for progdir in $PATH; do+       IFS=$_G_IFS+       test -x "$progdir/$progname" && break+     done+     IFS=$_G_IFS+     test -n "$progdir" || progdir=`pwd`+     progpath=$progdir/$progname+     ;;+esac+++## ----------------- ##+## Standard options. ##+## ----------------- ##++# The following options affect the operation of the functions defined+# below, and should be set appropriately depending on run-time para-+# meters passed on the command line.++opt_dry_run=false+opt_quiet=false+opt_verbose=false++# Categories 'all' and 'none' are always available.  Append any others+# you will pass as the first argument to func_warning from your own+# code.+warning_categories=++# By default, display warnings according to 'opt_warning_types'.  Set+# 'warning_func'  to ':' to elide all warnings, or func_fatal_error to+# treat the next displayed warning as a fatal error.+warning_func=func_warn_and_continue++# Set to 'all' to display all warnings, 'none' to suppress all+# warnings, or a space delimited list of some subset of+# 'warning_categories' to display only the listed warnings.+opt_warning_types=all+++## -------------------- ##+## Resource management. ##+## -------------------- ##++# This section contains definitions for functions that each ensure a+# particular resource (a file, or a non-empty configuration variable for+# example) is available, and if appropriate to extract default values+# from pertinent package files. Call them using their associated+# 'require_*' variable to ensure that they are executed, at most, once.+#+# It's entirely deliberate that calling these functions can set+# variables that don't obey the namespace limitations obeyed by the rest+# of this file, in order that that they be as useful as possible to+# callers.+++# require_term_colors+# -------------------+# Allow display of bold text on terminals that support it.+require_term_colors=func_require_term_colors+func_require_term_colors ()+{+    $debug_cmd++    test -t 1 && {+      # COLORTERM and USE_ANSI_COLORS environment variables take+      # precedence, because most terminfo databases neglect to describe+      # whether color sequences are supported.+      test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}++      if test 1 = "$USE_ANSI_COLORS"; then+        # Standard ANSI escape sequences+        tc_reset='[0m'+        tc_bold='[1m';   tc_standout='[7m'+        tc_red='[31m';   tc_green='[32m'+        tc_blue='[34m';  tc_cyan='[36m'+      else+        # Otherwise trust the terminfo database after all.+        test -n "`tput sgr0 2>/dev/null`" && {+          tc_reset=`tput sgr0`+          test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`+          tc_standout=$tc_bold+          test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`+          test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`+          test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`+          test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`+          test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`+        }+      fi+    }++    require_term_colors=:+}+++## ----------------- ##+## Function library. ##+## ----------------- ##++# This section contains a variety of useful functions to call in your+# scripts. Take note of the portable wrappers for features provided by+# some modern shells, which will fall back to slower equivalents on+# less featureful shells.+++# func_append VAR VALUE+# ---------------------+# Append VALUE onto the existing contents of VAR.++  # We should try to minimise forks, especially on Windows where they are+  # unreasonably slow, so skip the feature probes when bash or zsh are+  # being used:+  if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then+    : ${_G_HAVE_ARITH_OP="yes"}+    : ${_G_HAVE_XSI_OPS="yes"}+    # The += operator was introduced in bash 3.1+    case $BASH_VERSION in+      [12].* | 3.0 | 3.0*) ;;+      *)+        : ${_G_HAVE_PLUSEQ_OP="yes"}+        ;;+    esac+  fi++  # _G_HAVE_PLUSEQ_OP+  # Can be empty, in which case the shell is probed, "yes" if += is+  # usable or anything else if it does not work.+  test -z "$_G_HAVE_PLUSEQ_OP" \+    && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \+    && _G_HAVE_PLUSEQ_OP=yes++if test yes = "$_G_HAVE_PLUSEQ_OP"+then+  # This is an XSI compatible shell, allowing a faster implementation...+  eval 'func_append ()+  {+    $debug_cmd++    eval "$1+=\$2"+  }'+else+  # ...otherwise fall back to using expr, which is often a shell builtin.+  func_append ()+  {+    $debug_cmd++    eval "$1=\$$1\$2"+  }+fi+++# func_append_quoted VAR VALUE+# ----------------------------+# Quote VALUE and append to the end of shell variable VAR, separated+# by a space.+if test yes = "$_G_HAVE_PLUSEQ_OP"; then+  eval 'func_append_quoted ()+  {+    $debug_cmd++    func_quote_arg pretty "$2"+    eval "$1+=\\ \$func_quote_arg_result"+  }'+else+  func_append_quoted ()+  {+    $debug_cmd++    func_quote_arg pretty "$2"+    eval "$1=\$$1\\ \$func_quote_arg_result"+  }+fi+++# func_append_uniq VAR VALUE+# --------------------------+# Append unique VALUE onto the existing contents of VAR, assuming+# entries are delimited by the first character of VALUE.  For example:+#+#   func_append_uniq options " --another-option option-argument"+#+# will only append to $options if " --another-option option-argument "+# is not already present somewhere in $options already (note spaces at+# each end implied by leading space in second argument).+func_append_uniq ()+{+    $debug_cmd++    eval _G_current_value='`$ECHO $'$1'`'+    _G_delim=`expr "$2" : '\(.\)'`++    case $_G_delim$_G_current_value$_G_delim in+      *"$2$_G_delim"*) ;;+      *) func_append "$@" ;;+    esac+}+++# func_arith TERM...+# ------------------+# Set func_arith_result to the result of evaluating TERMs.+  test -z "$_G_HAVE_ARITH_OP" \+    && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \+    && _G_HAVE_ARITH_OP=yes++if test yes = "$_G_HAVE_ARITH_OP"; then+  eval 'func_arith ()+  {+    $debug_cmd++    func_arith_result=$(( $* ))+  }'+else+  func_arith ()+  {+    $debug_cmd++    func_arith_result=`expr "$@"`+  }+fi+++# func_basename FILE+# ------------------+# Set func_basename_result to FILE with everything up to and including+# the last / stripped.+if test yes = "$_G_HAVE_XSI_OPS"; then+  # If this shell supports suffix pattern removal, then use it to avoid+  # forking. Hide the definitions single quotes in case the shell chokes+  # on unsupported syntax...+  _b='func_basename_result=${1##*/}'+  _d='case $1 in+        */*) func_dirname_result=${1%/*}$2 ;;+        *  ) func_dirname_result=$3        ;;+      esac'++else+  # ...otherwise fall back to using sed.+  _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'+  _d='func_dirname_result=`$ECHO "$1"  |$SED "$sed_dirname"`+      if test "X$func_dirname_result" = "X$1"; then+        func_dirname_result=$3+      else+        func_append func_dirname_result "$2"+      fi'+fi++eval 'func_basename ()+{+    $debug_cmd++    '"$_b"'+}'+++# func_dirname FILE APPEND NONDIR_REPLACEMENT+# -------------------------------------------+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,+# otherwise set result to NONDIR_REPLACEMENT.+eval 'func_dirname ()+{+    $debug_cmd++    '"$_d"'+}'+++# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT+# --------------------------------------------------------+# Perform func_basename and func_dirname in a single function+# call:+#   dirname:  Compute the dirname of FILE.  If nonempty,+#             add APPEND to the result, otherwise set result+#             to NONDIR_REPLACEMENT.+#             value returned in "$func_dirname_result"+#   basename: Compute filename of FILE.+#             value returned in "$func_basename_result"+# For efficiency, we do not delegate to the functions above but instead+# duplicate the functionality here.+eval 'func_dirname_and_basename ()+{+    $debug_cmd++    '"$_b"'+    '"$_d"'+}'+++# func_echo ARG...+# ----------------+# Echo program name prefixed message.+func_echo ()+{+    $debug_cmd++    _G_message=$*++    func_echo_IFS=$IFS+    IFS=$nl+    for _G_line in $_G_message; do+      IFS=$func_echo_IFS+      $ECHO "$progname: $_G_line"+    done+    IFS=$func_echo_IFS+}+++# func_echo_all ARG...+# --------------------+# Invoke $ECHO with all args, space-separated.+func_echo_all ()+{+    $ECHO "$*"+}+++# func_echo_infix_1 INFIX ARG...+# ------------------------------+# Echo program name, followed by INFIX on the first line, with any+# additional lines not showing INFIX.+func_echo_infix_1 ()+{+    $debug_cmd++    $require_term_colors++    _G_infix=$1; shift+    _G_indent=$_G_infix+    _G_prefix="$progname: $_G_infix: "+    _G_message=$*++    # Strip color escape sequences before counting printable length+    for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"+    do+      test -n "$_G_tc" && {+        _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`+        _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`+      }+    done+    _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`"  " ## exclude from sc_prohibit_nested_quotes++    func_echo_infix_1_IFS=$IFS+    IFS=$nl+    for _G_line in $_G_message; do+      IFS=$func_echo_infix_1_IFS+      $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2+      _G_prefix=$_G_indent+    done+    IFS=$func_echo_infix_1_IFS+}+++# func_error ARG...+# -----------------+# Echo program name prefixed message to standard error.+func_error ()+{+    $debug_cmd++    $require_term_colors++    func_echo_infix_1 "  $tc_standout${tc_red}error$tc_reset" "$*" >&2+}+++# func_fatal_error ARG...+# -----------------------+# Echo program name prefixed message to standard error, and exit.+func_fatal_error ()+{+    $debug_cmd++    func_error "$*"+    exit $EXIT_FAILURE+}+++# func_grep EXPRESSION FILENAME+# -----------------------------+# Check whether EXPRESSION matches any line of FILENAME, without output.+func_grep ()+{+    $debug_cmd++    $GREP "$1" "$2" >/dev/null 2>&1+}+++# func_len STRING+# ---------------+# Set func_len_result to the length of STRING. STRING may not+# start with a hyphen.+  test -z "$_G_HAVE_XSI_OPS" \+    && (eval 'x=a/b/c;+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \+    && _G_HAVE_XSI_OPS=yes++if test yes = "$_G_HAVE_XSI_OPS"; then+  eval 'func_len ()+  {+    $debug_cmd++    func_len_result=${#1}+  }'+else+  func_len ()+  {+    $debug_cmd++    func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`+  }+fi+++# func_mkdir_p DIRECTORY-PATH+# ---------------------------+# Make sure the entire path to DIRECTORY-PATH is available.+func_mkdir_p ()+{+    $debug_cmd++    _G_directory_path=$1+    _G_dir_list=++    if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then++      # Protect directory names starting with '-'+      case $_G_directory_path in+        -*) _G_directory_path=./$_G_directory_path ;;+      esac++      # While some portion of DIR does not yet exist...+      while test ! -d "$_G_directory_path"; do+        # ...make a list in topmost first order.  Use a colon delimited+	# list in case some portion of path contains whitespace.+        _G_dir_list=$_G_directory_path:$_G_dir_list++        # If the last portion added has no slash in it, the list is done+        case $_G_directory_path in */*) ;; *) break ;; esac++        # ...otherwise throw away the child directory and loop+        _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`+      done+      _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`++      func_mkdir_p_IFS=$IFS; IFS=:+      for _G_dir in $_G_dir_list; do+	IFS=$func_mkdir_p_IFS+        # mkdir can fail with a 'File exist' error if two processes+        # try to create one of the directories concurrently.  Don't+        # stop in that case!+        $MKDIR "$_G_dir" 2>/dev/null || :+      done+      IFS=$func_mkdir_p_IFS++      # Bail out if we (or some other process) failed to create a directory.+      test -d "$_G_directory_path" || \+        func_fatal_error "Failed to create '$1'"+    fi+}+++# func_mktempdir [BASENAME]+# -------------------------+# Make a temporary directory that won't clash with other running+# libtool processes, and avoids race conditions if possible.  If+# given, BASENAME is the basename for that directory.+func_mktempdir ()+{+    $debug_cmd++    _G_template=${TMPDIR-/tmp}/${1-$progname}++    if test : = "$opt_dry_run"; then+      # Return a directory name, but don't create it in dry-run mode+      _G_tmpdir=$_G_template-$$+    else++      # If mktemp works, use that first and foremost+      _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`++      if test ! -d "$_G_tmpdir"; then+        # Failing that, at least try and use $RANDOM to avoid a race+        _G_tmpdir=$_G_template-${RANDOM-0}$$++        func_mktempdir_umask=`umask`+        umask 0077+        $MKDIR "$_G_tmpdir"+        umask $func_mktempdir_umask+      fi++      # If we're not in dry-run mode, bomb out on failure+      test -d "$_G_tmpdir" || \+        func_fatal_error "cannot create temporary directory '$_G_tmpdir'"+    fi++    $ECHO "$_G_tmpdir"+}+++# func_normal_abspath PATH+# ------------------------+# Remove doubled-up and trailing slashes, "." path components,+# and cancel out any ".." path components in PATH after making+# it an absolute path.+func_normal_abspath ()+{+    $debug_cmd++    # These SED scripts presuppose an absolute path with a trailing slash.+    _G_pathcar='s|^/\([^/]*\).*$|\1|'+    _G_pathcdr='s|^/[^/]*||'+    _G_removedotparts=':dotsl+		s|/\./|/|g+		t dotsl+		s|/\.$|/|'+    _G_collapseslashes='s|/\{1,\}|/|g'+    _G_finalslash='s|/*$|/|'++    # Start from root dir and reassemble the path.+    func_normal_abspath_result=+    func_normal_abspath_tpath=$1+    func_normal_abspath_altnamespace=+    case $func_normal_abspath_tpath in+      "")+        # Empty path, that just means $cwd.+        func_stripname '' '/' "`pwd`"+        func_normal_abspath_result=$func_stripname_result+        return+        ;;+      # The next three entries are used to spot a run of precisely+      # two leading slashes without using negated character classes;+      # we take advantage of case's first-match behaviour.+      ///*)+        # Unusual form of absolute path, do nothing.+        ;;+      //*)+        # Not necessarily an ordinary path; POSIX reserves leading '//'+        # and for example Cygwin uses it to access remote file shares+        # over CIFS/SMB, so we conserve a leading double slash if found.+        func_normal_abspath_altnamespace=/+        ;;+      /*)+        # Absolute path, do nothing.+        ;;+      *)+        # Relative path, prepend $cwd.+        func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath+        ;;+    esac++    # Cancel out all the simple stuff to save iterations.  We also want+    # the path to end with a slash for ease of parsing, so make sure+    # there is one (and only one) here.+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \+          -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`+    while :; do+      # Processed it all yet?+      if test / = "$func_normal_abspath_tpath"; then+        # If we ascended to the root using ".." the result may be empty now.+        if test -z "$func_normal_abspath_result"; then+          func_normal_abspath_result=/+        fi+        break+      fi+      func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \+          -e "$_G_pathcar"`+      func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \+          -e "$_G_pathcdr"`+      # Figure out what to do with it+      case $func_normal_abspath_tcomponent in+        "")+          # Trailing empty path component, ignore it.+          ;;+        ..)+          # Parent dir; strip last assembled component from result.+          func_dirname "$func_normal_abspath_result"+          func_normal_abspath_result=$func_dirname_result+          ;;+        *)+          # Actual path component, append it.+          func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"+          ;;+      esac+    done+    # Restore leading double-slash if one was found on entry.+    func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result+}+++# func_notquiet ARG...+# --------------------+# Echo program name prefixed message only when not in quiet mode.+func_notquiet ()+{+    $debug_cmd++    $opt_quiet || func_echo ${1+"$@"}++    # A bug in bash halts the script if the last line of a function+    # fails when set -e is in force, so we need another command to+    # work around that:+    :+}+++# func_relative_path SRCDIR DSTDIR+# --------------------------------+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.+func_relative_path ()+{+    $debug_cmd++    func_relative_path_result=+    func_normal_abspath "$1"+    func_relative_path_tlibdir=$func_normal_abspath_result+    func_normal_abspath "$2"+    func_relative_path_tbindir=$func_normal_abspath_result++    # Ascend the tree starting from libdir+    while :; do+      # check if we have found a prefix of bindir+      case $func_relative_path_tbindir in+        $func_relative_path_tlibdir)+          # found an exact match+          func_relative_path_tcancelled=+          break+          ;;+        $func_relative_path_tlibdir*)+          # found a matching prefix+          func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"+          func_relative_path_tcancelled=$func_stripname_result+          if test -z "$func_relative_path_result"; then+            func_relative_path_result=.+          fi+          break+          ;;+        *)+          func_dirname $func_relative_path_tlibdir+          func_relative_path_tlibdir=$func_dirname_result+          if test -z "$func_relative_path_tlibdir"; then+            # Have to descend all the way to the root!+            func_relative_path_result=../$func_relative_path_result+            func_relative_path_tcancelled=$func_relative_path_tbindir+            break+          fi+          func_relative_path_result=../$func_relative_path_result+          ;;+      esac+    done++    # Now calculate path; take care to avoid doubling-up slashes.+    func_stripname '' '/' "$func_relative_path_result"+    func_relative_path_result=$func_stripname_result+    func_stripname '/' '/' "$func_relative_path_tcancelled"+    if test -n "$func_stripname_result"; then+      func_append func_relative_path_result "/$func_stripname_result"+    fi++    # Normalisation. If bindir is libdir, return '.' else relative path.+    if test -n "$func_relative_path_result"; then+      func_stripname './' '' "$func_relative_path_result"+      func_relative_path_result=$func_stripname_result+    fi++    test -n "$func_relative_path_result" || func_relative_path_result=.++    :+}+++# func_quote_portable EVAL ARG+# ----------------------------+# Internal function to portably implement func_quote_arg.  Note that we still+# keep attention to performance here so we as much as possible try to avoid+# calling sed binary (so far O(N) complexity as long as func_append is O(1)).+func_quote_portable ()+{+    $debug_cmd++    $require_check_ifs_backslash++    func_quote_portable_result=$2++    # one-time-loop (easy break)+    while true+    do+      if $1; then+        func_quote_portable_result=`$ECHO "$2" | $SED \+          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`+        break+      fi++      # Quote for eval.+      case $func_quote_portable_result in+        *[\\\`\"\$]*)+          # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string+          # contains the shell wildcard characters.+          case $check_ifs_backshlash_broken$func_quote_portable_result in+            :*|*[\[\*\?]*)+              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \+                  | $SED "$sed_quote_subst"`+              break+              ;;+          esac++          func_quote_portable_old_IFS=$IFS+          for _G_char in '\' '`' '"' '$'+          do+            # STATE($1) PREV($2) SEPARATOR($3)+            set start "" ""+            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy+            IFS=$_G_char+            for _G_part in $func_quote_portable_result+            do+              case $1 in+              quote)+                func_append func_quote_portable_result "$3$2"+                set quote "$_G_part" "\\$_G_char"+                ;;+              start)+                set first "" ""+                func_quote_portable_result=+                ;;+              first)+                set quote "$_G_part" ""+                ;;+              esac+            done+          done+          IFS=$func_quote_portable_old_IFS+          ;;+        *) ;;+      esac+      break+    done++    func_quote_portable_unquoted_result=$func_quote_portable_result+    case $func_quote_portable_result in+      # double-quote args containing shell metacharacters to delay+      # word splitting, command substitution and variable expansion+      # for a subsequent eval.+      # many bourne shells cannot handle close brackets correctly+      # in scan sets, so we specify it separately.+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")+        func_quote_portable_result=\"$func_quote_portable_result\"+        ;;+    esac+}+++# func_quotefast_eval ARG+# -----------------------+# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',+# but optimized for speed.  Result is stored in $func_quotefast_eval.+if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then+  printf -v _GL_test_printf_tilde %q '~'+  if test '\~' = "$_GL_test_printf_tilde"; then+    func_quotefast_eval ()+    {+      printf -v func_quotefast_eval_result %q "$1"+    }+  else+    # Broken older Bash implementations.  Make those faster too if possible.+    func_quotefast_eval ()+    {+      case $1 in+        '~'*)+          func_quote_portable false "$1"+          func_quotefast_eval_result=$func_quote_portable_result+          ;;+        *)+          printf -v func_quotefast_eval_result %q "$1"+          ;;+      esac+    }+  fi+else+  func_quotefast_eval ()+  {+    func_quote_portable false "$1"+    func_quotefast_eval_result=$func_quote_portable_result+  }+fi+++# func_quote_arg MODEs ARG+# ------------------------+# Quote one ARG to be evaled later.  MODEs argument may contain zero or more+# specifiers listed below separated by ',' character.  This function returns two+# values:+#   i) func_quote_arg_result+#      double-quoted (when needed), suitable for a subsequent eval+#  ii) func_quote_arg_unquoted_result+#      has all characters that are still active within double+#      quotes backslashified.  Available only if 'unquoted' is specified.+#+# Available modes:+# ----------------+# 'eval' (default)+#       - escape shell special characters+# 'expand'+#       - the same as 'eval';  but do not quote variable references+# 'pretty'+#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might+#         be used later in func_quote to get output like: 'echo "a b"' instead+#         of 'echo a\ b'.  This is slower than default on some shells.+# 'unquoted'+#       - produce also $func_quote_arg_unquoted_result which does not contain+#         wrapping double-quotes.+#+# Examples for 'func_quote_arg pretty,unquoted string':+#+#   string      | *_result              | *_unquoted_result+#   ------------+-----------------------+-------------------+#   "           | \"                    | \"+#   a b         | "a b"                 | a b+#   "a b"       | "\"a b\""             | \"a b\"+#   *           | "*"                   | *+#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"+#+# Examples for 'func_quote_arg pretty,unquoted,expand string':+#+#   string        |   *_result          |  *_unquoted_result+#   --------------+---------------------+--------------------+#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"+func_quote_arg ()+{+    _G_quote_expand=false+    case ,$1, in+      *,expand,*)+        _G_quote_expand=:+        ;;+    esac++    case ,$1, in+      *,pretty,*|*,expand,*|*,unquoted,*)+        func_quote_portable $_G_quote_expand "$2"+        func_quote_arg_result=$func_quote_portable_result+        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result+        ;;+      *)+        # Faster quote-for-eval for some shells.+        func_quotefast_eval "$2"+        func_quote_arg_result=$func_quotefast_eval_result+        ;;+    esac+}+++# func_quote MODEs ARGs...+# ------------------------+# Quote all ARGs to be evaled later and join them into single command.  See+# func_quote_arg's description for more info.+func_quote ()+{+    $debug_cmd+    _G_func_quote_mode=$1 ; shift+    func_quote_result=+    while test 0 -lt $#; do+      func_quote_arg "$_G_func_quote_mode" "$1"+      if test -n "$func_quote_result"; then+        func_append func_quote_result " $func_quote_arg_result"+      else+        func_append func_quote_result "$func_quote_arg_result"+      fi+      shift+    done+}+++# func_stripname PREFIX SUFFIX NAME+# ---------------------------------+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.+# PREFIX and SUFFIX must not contain globbing or regex special+# characters, hashes, percent signs, but SUFFIX may contain a leading+# dot (in which case that matches only a dot).+if test yes = "$_G_HAVE_XSI_OPS"; then+  eval 'func_stripname ()+  {+    $debug_cmd++    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are+    # positional parameters, so assign one to ordinary variable first.+    func_stripname_result=$3+    func_stripname_result=${func_stripname_result#"$1"}+    func_stripname_result=${func_stripname_result%"$2"}+  }'+else+  func_stripname ()+  {+    $debug_cmd++    case $2 in+      .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;+      *)  func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;+    esac+  }+fi+++# func_show_eval CMD [FAIL_EXP]+# -----------------------------+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP+# is given, then evaluate it.+func_show_eval ()+{+    $debug_cmd++    _G_cmd=$1+    _G_fail_exp=${2-':'}++    func_quote_arg pretty,expand "$_G_cmd"+    eval "func_notquiet $func_quote_arg_result"++    $opt_dry_run || {+      eval "$_G_cmd"+      _G_status=$?+      if test 0 -ne "$_G_status"; then+	eval "(exit $_G_status); $_G_fail_exp"+      fi+    }+}+++# func_show_eval_locale CMD [FAIL_EXP]+# ------------------------------------+# Unless opt_quiet is true, then output CMD.  Then, if opt_dryrun is+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP+# is given, then evaluate it.  Use the saved locale for evaluation.+func_show_eval_locale ()+{+    $debug_cmd++    _G_cmd=$1+    _G_fail_exp=${2-':'}++    $opt_quiet || {+      func_quote_arg expand,pretty "$_G_cmd"+      eval "func_echo $func_quote_arg_result"+    }++    $opt_dry_run || {+      eval "$_G_user_locale+	    $_G_cmd"+      _G_status=$?+      eval "$_G_safe_locale"+      if test 0 -ne "$_G_status"; then+	eval "(exit $_G_status); $_G_fail_exp"+      fi+    }+}+++# func_tr_sh+# ----------+# Turn $1 into a string suitable for a shell variable name.+# Result is stored in $func_tr_sh_result.  All characters+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,+# if $1 begins with a digit, a '_' is prepended as well.+func_tr_sh ()+{+    $debug_cmd++    case $1 in+    [0-9]* | *[!a-zA-Z0-9_]*)+      func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`+      ;;+    * )+      func_tr_sh_result=$1+      ;;+    esac+}+++# func_verbose ARG...+# -------------------+# Echo program name prefixed message in verbose mode only.+func_verbose ()+{+    $debug_cmd++    $opt_verbose && func_echo "$*"++    :+}+++# func_warn_and_continue ARG...+# -----------------------------+# Echo program name prefixed warning message to standard error.+func_warn_and_continue ()+{+    $debug_cmd++    $require_term_colors++    func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2+}+++# func_warning CATEGORY ARG...+# ----------------------------+# Echo program name prefixed warning message to standard error. Warning+# messages can be filtered according to CATEGORY, where this function+# elides messages where CATEGORY is not listed in the global variable+# 'opt_warning_types'.+func_warning ()+{+    $debug_cmd++    # CATEGORY must be in the warning_categories list!+    case " $warning_categories " in+      *" $1 "*) ;;+      *) func_internal_error "invalid warning category '$1'" ;;+    esac++    _G_category=$1+    shift++    case " $opt_warning_types " in+      *" $_G_category "*) $warning_func ${1+"$@"} ;;+    esac+}+++# func_sort_ver VER1 VER2+# -----------------------+# 'sort -V' is not generally available.+# Note this deviates from the version comparison in automake+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a+# but this should suffice as we won't be specifying old+# version formats or redundant trailing .0 in bootstrap.conf.+# If we did want full compatibility then we should probably+# use m4_version_compare from autoconf.+func_sort_ver ()+{+    $debug_cmd++    printf '%s\n%s\n' "$1" "$2" \+      | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n+}++# func_lt_ver PREV CURR+# ---------------------+# Return true if PREV and CURR are in the correct order according to+# func_sort_ver, otherwise false.  Use it like this:+#+#  func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."+func_lt_ver ()+{+    $debug_cmd++    test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`+}+++# Local variables:+# mode: shell-script+# sh-indentation: 2+# eval: (add-hook 'before-save-hook 'time-stamp)+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"+# time-stamp-time-zone: "UTC"+# End:+#! /bin/sh++# A portable, pluggable option parser for Bourne shell.+# Written by Gary V. Vaughan, 2010++# This is free software.  There is NO warranty; not even for+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.+#+# Copyright (C) 2010-2019, 2021, 2023-2024 Bootstrap Authors+#+# This file is dual licensed under the terms of the MIT license+# <https://opensource.org/licenses/MIT>, and GPL version 2 or later+# <https://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of+# these licenses when using or redistributing this software or any of+# the files within it.  See the URLs above, or the file `LICENSE`+# included in the Bootstrap distribution for the full license texts.++# Please report bugs or propose patches to:+# <https://github.com/gnulib-modules/bootstrap/issues>++# Set a version string for this script.+scriptversion=2019-02-19.15; # UTC+++## ------ ##+## Usage. ##+## ------ ##++# This file is a library for parsing options in your shell scripts along+# with assorted other useful supporting features that you can make use+# of too.+#+# For the simplest scripts you might need only:+#+#   #!/bin/sh+#   . relative/path/to/funclib.sh+#   . relative/path/to/options-parser+#   scriptversion=1.0+#   func_options ${1+"$@"}+#   eval set dummy "$func_options_result"; shift+#   ...rest of your script...+#+# In order for the '--version' option to work, you will need to have a+# suitably formatted comment like the one at the top of this file+# starting with '# Written by ' and ending with '# Copyright'.+#+# For '-h' and '--help' to work, you will also need a one line+# description of your script's purpose in a comment directly above the+# '# Written by ' line, like the one at the top of this file.+#+# The default options also support '--debug', which will turn on shell+# execution tracing (see the comment above debug_cmd below for another+# use), and '--verbose' and the func_verbose function to allow your script+# to display verbose messages only when your user has specified+# '--verbose'.+#+# After sourcing this file, you can plug in processing for additional+# options by amending the variables from the 'Configuration' section+# below, and following the instructions in the 'Option parsing'+# section further down.++## -------------- ##+## Configuration. ##+## -------------- ##++# You should override these variables in your script after sourcing this+# file so that they reflect the customisations you have added to the+# option parser.++# The usage line for option parsing errors and the start of '-h' and+# '--help' output messages. You can embed shell variables for delayed+# expansion at the time the message is displayed, but you will need to+# quote other shell meta-characters carefully to prevent them being+# expanded when the contents are evaled.+usage='$progpath [OPTION]...'++# Short help message in response to '-h' and '--help'.  Add to this or+# override it after sourcing this library to reflect the full set of+# options your script accepts.+usage_message="\+       --debug        enable verbose shell tracing+   -W, --warnings=CATEGORY+                      report the warnings falling in CATEGORY [all]+   -v, --verbose      verbosely report processing+       --version      print version information and exit+   -h, --help         print short or long help message and exit+"++# Additional text appended to 'usage_message' in response to '--help'.+long_help_message="+Warning categories include:+       'all'          show all warnings+       'none'         turn off all the warnings+       'error'        warnings are treated as fatal errors"++# Help message printed before fatal option parsing errors.+fatal_help="Try '\$progname --help' for more information."++++## ------------------------- ##+## Hook function management. ##+## ------------------------- ##++# This section contains functions for adding, removing, and running hooks+# in the main code.  A hook is just a list of function names that can be+# run in order later on.++# func_hookable FUNC_NAME+# -----------------------+# Declare that FUNC_NAME will run hooks added with+# 'func_add_hook FUNC_NAME ...'.+func_hookable ()+{+    $debug_cmd++    func_append hookable_fns " $1"+}+++# func_add_hook FUNC_NAME HOOK_FUNC+# ---------------------------------+# Request that FUNC_NAME call HOOK_FUNC before it returns.  FUNC_NAME must+# first have been declared "hookable" by a call to 'func_hookable'.+func_add_hook ()+{+    $debug_cmd++    case " $hookable_fns " in+      *" $1 "*) ;;+      *) func_fatal_error "'$1' does not accept hook functions." ;;+    esac++    eval func_append ${1}_hooks '" $2"'+}+++# func_remove_hook FUNC_NAME HOOK_FUNC+# ------------------------------------+# Remove HOOK_FUNC from the list of hook functions to be called by+# FUNC_NAME.+func_remove_hook ()+{+    $debug_cmd++    eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'+}+++# func_propagate_result FUNC_NAME_A FUNC_NAME_B+# ---------------------------------------------+# If the *_result variable of FUNC_NAME_A _is set_, assign its value to+# *_result variable of FUNC_NAME_B.+func_propagate_result ()+{+    $debug_cmd++    func_propagate_result_result=:+    if eval "test \"\${${1}_result+set}\" = set"+    then+      eval "${2}_result=\$${1}_result"+    else+      func_propagate_result_result=false+    fi+}+++# func_run_hooks FUNC_NAME [ARG]...+# ---------------------------------+# Run all hook functions registered to FUNC_NAME.+# It's assumed that the list of hook functions contains nothing more+# than a whitespace-delimited list of legal shell function names, and+# no effort is wasted trying to catch shell meta-characters or preserve+# whitespace.+func_run_hooks ()+{+    $debug_cmd++    case " $hookable_fns " in+      *" $1 "*) ;;+      *) func_fatal_error "'$1' does not support hook functions." ;;+    esac++    eval _G_hook_fns=\$$1_hooks; shift++    for _G_hook in $_G_hook_fns; do+      func_unset "${_G_hook}_result"+      eval $_G_hook '${1+"$@"}'+      func_propagate_result $_G_hook func_run_hooks+      if $func_propagate_result_result; then+        eval set dummy "$func_run_hooks_result"; shift+      fi+    done+}++++## --------------- ##+## Option parsing. ##+## --------------- ##++# In order to add your own option parsing hooks, you must accept the+# full positional parameter list from your hook function.  You may remove+# or edit any options that you action, and then pass back the remaining+# unprocessed options in '<hooked_function_name>_result', escaped+# suitably for 'eval'.+#+# The '<hooked_function_name>_result' variable is automatically unset+# before your hook gets called; for best performance, only set the+# *_result variable when necessary (i.e. don't call the 'func_quote'+# function unnecessarily because it can be an expensive operation on some+# machines).+#+# Like this:+#+#    my_options_prep ()+#    {+#        $debug_cmd+#+#        # Extend the existing usage message.+#        usage_message=$usage_message'+#      -s, --silent       don'\''t print informational messages+#    '+#        # No change in '$@' (ignored completely by this hook).  Leave+#        # my_options_prep_result variable intact.+#    }+#    func_add_hook func_options_prep my_options_prep+#+#+#    my_silent_option ()+#    {+#        $debug_cmd+#+#        args_changed=false+#+#        # Note that, for efficiency, we parse as many options as we can+#        # recognise in a loop before passing the remainder back to the+#        # caller on the first unrecognised argument we encounter.+#        while test $# -gt 0; do+#          opt=$1; shift+#          case $opt in+#            --silent|-s) opt_silent=:+#                         args_changed=:+#                         ;;+#            # Separate non-argument short options:+#            -s*)         func_split_short_opt "$_G_opt"+#                         set dummy "$func_split_short_opt_name" \+#                             "-$func_split_short_opt_arg" ${1+"$@"}+#                         shift+#                         args_changed=:+#                         ;;+#            *)           # Make sure the first unrecognised option "$_G_opt"+#                         # is added back to "$@" in case we need it later,+#                         # if $args_changed was set to 'true'.+#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;+#          esac+#        done+#+#        # Only call 'func_quote' here if we processed at least one argument.+#        if $args_changed; then+#          func_quote eval ${1+"$@"}+#          my_silent_option_result=$func_quote_result+#        fi+#    }+#    func_add_hook func_parse_options my_silent_option+#+#+#    my_option_validation ()+#    {+#        $debug_cmd+#+#        $opt_silent && $opt_verbose && func_fatal_help "\+#    '--silent' and '--verbose' options are mutually exclusive."+#    }+#    func_add_hook func_validate_options my_option_validation+#+# You'll also need to manually amend $usage_message to reflect the extra+# options you parse.  It's preferable to append if you can, so that+# multiple option parsing hooks can be added safely.+++# func_options_finish [ARG]...+# ----------------------------+# Finishing the option parse loop (call 'func_options' hooks ATM).+func_options_finish ()+{+    $debug_cmd++    func_run_hooks func_options ${1+"$@"}+    func_propagate_result func_run_hooks func_options_finish+}+++# func_options [ARG]...+# ---------------------+# All the functions called inside func_options are hookable. See the+# individual implementations for details.+func_hookable func_options+func_options ()+{+    $debug_cmd++    _G_options_quoted=false++    for my_func in options_prep parse_options validate_options options_finish+    do+      func_unset func_${my_func}_result+      func_unset func_run_hooks_result+      eval func_$my_func '${1+"$@"}'+      func_propagate_result func_$my_func func_options+      if $func_propagate_result_result; then+        eval set dummy "$func_options_result"; shift+        _G_options_quoted=:+      fi+    done++    $_G_options_quoted || {+      # As we (func_options) are top-level options-parser function and+      # nobody quoted "$@" for us yet, we need to do it explicitly for+      # caller.+      func_quote eval ${1+"$@"}+      func_options_result=$func_quote_result+    }+}+++# func_options_prep [ARG]...+# --------------------------+# All initialisations required before starting the option parse loop.+# Note that when calling hook functions, we pass through the list of+# positional parameters.  If a hook function modifies that list, and+# needs to propagate that back to rest of this script, then the complete+# modified list must be put in 'func_run_hooks_result' before returning.+func_hookable func_options_prep+func_options_prep ()+{+    $debug_cmd++    # Option defaults:+    opt_verbose=false+    opt_warning_types=++    func_run_hooks func_options_prep ${1+"$@"}+    func_propagate_result func_run_hooks func_options_prep+}+++# func_parse_options [ARG]...+# ---------------------------+# The main option parsing loop.+func_hookable func_parse_options+func_parse_options ()+{+    $debug_cmd++    _G_parse_options_requote=false+    # this just eases exit handling+    while test $# -gt 0; do+      # Defer to hook functions for initial option parsing, so they+      # get priority in the event of reusing an option name.+      func_run_hooks func_parse_options ${1+"$@"}+      func_propagate_result func_run_hooks func_parse_options+      if $func_propagate_result_result; then+        eval set dummy "$func_parse_options_result"; shift+        # Even though we may have changed "$@", we passed the "$@" array+        # down into the hook and it quoted it for us (because we are in+        # this if-branch).  No need to quote it again.+        _G_parse_options_requote=false+      fi++      # Break out of the loop if we already parsed every option.+      test $# -gt 0 || break++      # We expect that one of the options parsed in this function matches+      # and thus we remove _G_opt from "$@" and need to re-quote.+      _G_match_parse_options=:+      _G_opt=$1+      shift+      case $_G_opt in+        --debug|-x)   debug_cmd='set -x'+                      func_echo "enabling shell trace mode" >&2+                      $debug_cmd+                      ;;++        --no-warnings|--no-warning|--no-warn)+                      set dummy --warnings none ${1+"$@"}+                      shift+		      ;;++        --warnings|--warning|-W)+                      if test $# = 0 && func_missing_arg $_G_opt; then+                        _G_parse_options_requote=:+                        break+                      fi+                      case " $warning_categories $1" in+                        *" $1 "*)+                          # trailing space prevents matching last $1 above+                          func_append_uniq opt_warning_types " $1"+                          ;;+                        *all)+                          opt_warning_types=$warning_categories+                          ;;+                        *none)+                          opt_warning_types=none+                          warning_func=:+                          ;;+                        *error)+                          opt_warning_types=$warning_categories+                          warning_func=func_fatal_error+                          ;;+                        *)+                          func_fatal_error \+                             "unsupported warning category: '$1'"+                          ;;+                      esac+                      shift+                      ;;++        --verbose|-v) opt_verbose=: ;;+        --version)    func_version ;;+        -\?|-h)       func_usage ;;+        --help)       func_help ;;++	# Separate optargs to long options (plugins may need this):+	--*=*)        func_split_equals "$_G_opt"+	              set dummy "$func_split_equals_lhs" \+                          "$func_split_equals_rhs" ${1+"$@"}+                      shift+                      ;;++       # Separate optargs to short options:+        -W*)+                      func_split_short_opt "$_G_opt"+                      set dummy "$func_split_short_opt_name" \+                          "$func_split_short_opt_arg" ${1+"$@"}+                      shift+                      ;;++        # Separate non-argument short options:+        -\?*|-h*|-v*|-x*)+                      func_split_short_opt "$_G_opt"+                      set dummy "$func_split_short_opt_name" \+                          "-$func_split_short_opt_arg" ${1+"$@"}+                      shift+                      ;;++        --)           _G_parse_options_requote=: ; break ;;+        -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;+        *)            set dummy "$_G_opt" ${1+"$@"}; shift+                      _G_match_parse_options=false+                      break+                      ;;+      esac++      if $_G_match_parse_options; then+        _G_parse_options_requote=:+      fi+    done++    if $_G_parse_options_requote; then+      # save modified positional parameters for caller+      func_quote eval ${1+"$@"}+      func_parse_options_result=$func_quote_result+    fi+}+++# func_validate_options [ARG]...+# ------------------------------+# Perform any sanity checks on option settings and/or unconsumed+# arguments.+func_hookable func_validate_options+func_validate_options ()+{+    $debug_cmd++    # Display all warnings if -W was not given.+    test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"++    func_run_hooks func_validate_options ${1+"$@"}+    func_propagate_result func_run_hooks func_validate_options++    # Bail if the options were screwed!+    $exit_cmd $EXIT_FAILURE+}++++## ----------------- ##+## Helper functions. ##+## ----------------- ##++# This section contains the helper functions used by the rest of the+# hookable option parser framework in ascii-betical order.+++# func_fatal_help ARG...+# ----------------------+# Echo program name prefixed message to standard error, followed by+# a help hint, and exit.+func_fatal_help ()+{+    $debug_cmd++    eval \$ECHO \""Usage: $usage"\"+    eval \$ECHO \""$fatal_help"\"+    func_error ${1+"$@"}+    exit $EXIT_FAILURE+}+++# func_help+# ---------+# Echo long help message to standard output and exit.+func_help ()+{+    $debug_cmd++    func_usage_message+    $ECHO "$long_help_message"+    exit 0+}+++# func_missing_arg ARGNAME+# ------------------------+# Echo program name prefixed message to standard error and set global+# exit_cmd.+func_missing_arg ()+{+    $debug_cmd++    func_error "Missing argument for '$1'."+    exit_cmd=exit+}+++# func_split_equals STRING+# ------------------------+# Set func_split_equals_lhs and func_split_equals_rhs shell variables+# after splitting STRING at the '=' sign.+test -z "$_G_HAVE_XSI_OPS" \+    && (eval 'x=a/b/c;+      test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \+    && _G_HAVE_XSI_OPS=yes++if test yes = "$_G_HAVE_XSI_OPS"+then+  # This is an XSI compatible shell, allowing a faster implementation...+  eval 'func_split_equals ()+  {+      $debug_cmd++      func_split_equals_lhs=${1%%=*}+      func_split_equals_rhs=${1#*=}+      if test "x$func_split_equals_lhs" = "x$1"; then+        func_split_equals_rhs=+      fi+  }'+else+  # ...otherwise fall back to using expr, which is often a shell builtin.+  func_split_equals ()+  {+      $debug_cmd++      func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`+      func_split_equals_rhs=+      test "x$func_split_equals_lhs=" = "x$1" \+        || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`+  }+fi #func_split_equals+++# func_split_short_opt SHORTOPT+# -----------------------------+# Set func_split_short_opt_name and func_split_short_opt_arg shell+# variables after splitting SHORTOPT after the 2nd character.+if test yes = "$_G_HAVE_XSI_OPS"+then+  # This is an XSI compatible shell, allowing a faster implementation...+  eval 'func_split_short_opt ()+  {+      $debug_cmd++      func_split_short_opt_arg=${1#??}+      func_split_short_opt_name=${1%"$func_split_short_opt_arg"}+  }'+else+  # ...otherwise fall back to using expr, which is often a shell builtin.+  func_split_short_opt ()+  {+      $debug_cmd++      func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'`+      func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`+  }+fi #func_split_short_opt+++# func_usage+# ----------+# Echo short help message to standard output and exit.+func_usage ()+{+    $debug_cmd++    func_usage_message+    $ECHO "Run '$progname --help |${PAGER-more}' for full usage"+    exit 0+}+++# func_usage_message+# ------------------+# Echo short help message to standard output.+func_usage_message ()+{+    $debug_cmd++    eval \$ECHO \""Usage: $usage"\"+    echo+    $SED -n 's|^# ||+        /^Written by/{+          x;p;x+        }+	h+	/^Written by/q' < "$progpath"+    echo+    eval \$ECHO \""$usage_message"\"+}+++# func_version+# ------------+# Echo version message to standard output and exit.+# The version message is extracted from the calling file's header+# comments, with leading '# ' stripped:+#   1. First display the progname and version+#   2. Followed by the header comment line matching  /^# Written by /+#   3. Then a blank line followed by the first following line matching+#      /^# Copyright /+#   4. Immediately followed by any lines between the previous matches,+#      except lines preceding the intervening completely blank line.+# For example, see the header comments of this file.+func_version ()+{+    $debug_cmd++    printf '%s\n' "$progname $scriptversion"+    $SED -n '+        /^# Written by /!b+        s|^# ||; p; n++        :fwd2blnk+        /./ {+          n+          b fwd2blnk+        }+        p; n++        :holdwrnt+        s|^# ||+        s|^# *$||+        /^Copyright /!{+          /./H+          n+          b holdwrnt+        }++        s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|+        G+        s|\(\n\)\n*|\1|g+        p; q' < "$progpath"++    exit $?+}+++# Local variables:+# mode: shell-script+# sh-indentation: 2+# eval: (add-hook 'before-save-hook 'time-stamp)+# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"+# time-stamp-time-zone: "UTC"+# End:++# Set a version string.+scriptversion='(GNU libtool) 2.5.4'++# func_version+# ------------+# Echo version message to standard output and exit.+func_version ()+{+    $debug_cmd++	year=`date +%Y`++	cat <<EOF+$progname $scriptversion+Copyright (C) $year Free Software Foundation, Inc.+License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>+This is free software: you are free to change and redistribute it.+There is NO WARRANTY, to the extent permitted by law.++Originally written by Gordon Matzigkeit, 1996+(See AUTHORS for complete contributor listing)+EOF++    exit $?+}+++# func_echo ARG...+# ----------------+# Libtool also displays the current mode in messages, so override+# funclib.sh func_echo with this custom definition.+func_echo ()+{+    $debug_cmd++    _G_message=$*++    func_echo_IFS=$IFS+    IFS=$nl+    for _G_line in $_G_message; do+      IFS=$func_echo_IFS+      $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"+    done+    IFS=$func_echo_IFS+}+++## ---------------- ##+## Options parsing. ##+## ---------------- ##++# Hook in the functions to make sure our own options are parsed during+# the option parsing loop.++usage='$progpath [OPTION]... [MODE-ARG]...'++# Short help message in response to '-h'.+usage_message="Options:+       --config                 show all configuration variables+       --debug                  enable verbose shell tracing+   -n, --dry-run                display commands without modifying any files+       --features               display basic configuration information+       --finish                 use operation '--mode=finish'+       --mode=MODE              use operation mode MODE+       --no-finish              don't update shared library cache+       --no-quiet, --no-silent  print default informational messages+       --no-warnings            equivalent to '-Wnone'+       --preserve-dup-deps      don't remove duplicate dependency libraries+       --quiet, --silent        don't print informational messages+       --reorder-cache=DIRS     reorder shared library cache for preferred DIRS+       --tag=TAG                use configuration variables from tag TAG+   -v, --verbose                print more informational messages than default+       --version                print version information+   -W, --warnings=CATEGORY      report the warnings falling in CATEGORY [all]+   -h, --help, --help-all       print short, long, or detailed help message+"++# Additional text appended to 'usage_message' in response to '--help'.+func_help ()+{+    $debug_cmd++    func_usage_message+    $ECHO "$long_help_message++MODE must be one of the following:++       clean           remove files from the build directory+       compile         compile a source file into a libtool object+       execute         automatically set library path, then run a program+       finish          complete the installation of libtool libraries+       install         install libraries or executables+       link            create a library or an executable+       uninstall       remove libraries from an installed directory++MODE-ARGS vary depending on the MODE.  When passed as first option,+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.+Try '$progname --help --mode=MODE' for a more detailed description of MODE.++When reporting a bug, please describe a test case to reproduce it and+include the following information:++       host-triplet:   $host+       shell:          $SHELL+       compiler:       $LTCC+       compiler flags: $LTCFLAGS+       linker:         $LD (gnu? $with_gnu_ld)+       version:        $progname $scriptversion+       automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`+       autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`++Report bugs to <bug-libtool@gnu.org>.+GNU libtool home page: <https://www.gnu.org/software/libtool/>.+General help using GNU software: <https://www.gnu.org/gethelp/>."+    exit 0+}+++# func_lo2o OBJECT-NAME+# ---------------------+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific+# object suffix.++lo2o=s/\\.lo\$/.$objext/+o2lo=s/\\.$objext\$/.lo/++if test yes = "$_G_HAVE_XSI_OPS"; then+  eval 'func_lo2o ()+  {+    case $1 in+      *.lo) func_lo2o_result=${1%.lo}.$objext ;;+      *   ) func_lo2o_result=$1               ;;+    esac+  }'++  # func_xform LIBOBJ-OR-SOURCE+  # ---------------------------+  # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)+  # suffix to a '.lo' libtool-object suffix.+  eval 'func_xform ()+  {+    func_xform_result=${1%.*}.lo+  }'+else+  # ...otherwise fall back to using sed.+  func_lo2o ()+  {+    func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`+  }++  func_xform ()+  {+    func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`+  }+fi+++# func_fatal_configuration ARG...+# -------------------------------+# Echo program name prefixed message to standard error, followed by+# a configuration failure hint, and exit.+func_fatal_configuration ()+{+    func_fatal_error ${1+"$@"} \+      "See the $PACKAGE documentation for more information." \+      "Fatal configuration error."+}+++# func_config+# -----------+# Display the configuration for all the tags in this script.+func_config ()+{+    re_begincf='^# ### BEGIN LIBTOOL'+    re_endcf='^# ### END LIBTOOL'++    # Default configuration.+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"++    # Now print the configurations for the tags.+    for tagname in $taglist; do+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"+    done++    exit $?+}+++# func_features+# -------------+# Display the features supported by this script.+func_features ()+{+    echo "host: $host"+    if test yes = "$build_libtool_libs"; then+      echo "enable shared libraries"+    else+      echo "disable shared libraries"+    fi+    if test yes = "$build_old_libs"; then+      echo "enable static libraries"+    else+      echo "disable static libraries"+    fi++    exit $?+}+++# func_enable_tag TAGNAME+# -----------------------+# Verify that TAGNAME is valid, and either flag an error and exit, or+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist+# variable here.+func_enable_tag ()+{+    # Global variable:+    tagname=$1++    re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"+    re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"+    sed_extractcf=/$re_begincf/,/$re_endcf/p++    # Validate tagname.+    case $tagname in+      *[!-_A-Za-z0-9,/]*)+        func_fatal_error "invalid tag name: $tagname"+        ;;+    esac++    # Don't test for the "default" C tag, as we know it's+    # there but not specially marked.+    case $tagname in+        CC) ;;+    *)+        if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then+	  taglist="$taglist $tagname"++	  # Evaluate the configuration.  Be careful to quote the path+	  # and the sed script, to avoid splitting on whitespace, but+	  # also don't use non-portable quotes within backquotes within+	  # quotes we have to do it in 2 steps:+	  extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`+	  eval "$extractedcf"+        else+	  func_error "ignoring unknown tag $tagname"+        fi+        ;;+    esac+}+++# func_check_version_match+# ------------------------+# Ensure that we are using m4 macros, and libtool script from the same+# release of libtool.+func_check_version_match ()+{+    if test "$package_revision" != "$macro_revision"; then+      if test "$VERSION" != "$macro_version"; then+        if test -z "$macro_version"; then+          cat >&2 <<_LT_EOF+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the+$progname: definition of this LT_INIT comes from an older release.+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION+$progname: and run autoconf again.+_LT_EOF+        else+          cat >&2 <<_LT_EOF+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION+$progname: and run autoconf again.+_LT_EOF+        fi+      else+        cat >&2 <<_LT_EOF+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,+$progname: but the definition of this LT_INIT comes from revision $macro_revision.+$progname: You should recreate aclocal.m4 with macros from revision $package_revision+$progname: of $PACKAGE $VERSION and run autoconf again.+_LT_EOF+      fi++      exit $EXIT_MISMATCH+    fi+}+++# libtool_options_prep [ARG]...+# -----------------------------+# Preparation for options parsed by libtool.+libtool_options_prep ()+{+    $debug_mode++    # Option defaults:+    opt_config=false+    opt_dlopen=+    opt_dry_run=false+    opt_help=false+    opt_mode=+    opt_reorder_cache=false+    opt_preserve_dup_deps=false+    opt_quiet=false+    opt_finishing=true+    opt_warning=++    nonopt=+    preserve_args=++    _G_rc_lt_options_prep=:++    # Shorthand for --mode=foo, only valid as the first argument+    case $1 in+    clean|clea|cle|cl)+      shift; set dummy --mode clean ${1+"$@"}; shift+      ;;+    compile|compil|compi|comp|com|co|c)+      shift; set dummy --mode compile ${1+"$@"}; shift+      ;;+    execute|execut|execu|exec|exe|ex|e)+      shift; set dummy --mode execute ${1+"$@"}; shift+      ;;+    finish|finis|fini|fin|fi|f)+      shift; set dummy --mode finish ${1+"$@"}; shift+      ;;+    install|instal|insta|inst|ins|in|i)+      shift; set dummy --mode install ${1+"$@"}; shift+      ;;+    link|lin|li|l)+      shift; set dummy --mode link ${1+"$@"}; shift+      ;;+    uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)+      shift; set dummy --mode uninstall ${1+"$@"}; shift+      ;;+    *)+      _G_rc_lt_options_prep=false+      ;;+    esac++    if $_G_rc_lt_options_prep; then+      # Pass back the list of options.+      func_quote eval ${1+"$@"}+      libtool_options_prep_result=$func_quote_result+    fi+}+func_add_hook func_options_prep libtool_options_prep+++# libtool_parse_options [ARG]...+# ---------------------------------+# Provide handling for libtool specific options.+libtool_parse_options ()+{+    $debug_cmd++    _G_rc_lt_parse_options=false++    # Perform our own loop to consume as many options as possible in+    # each iteration.+    while test $# -gt 0; do+      _G_match_lt_parse_options=:+      _G_opt=$1+      shift+      case $_G_opt in+        --dry-run|--dryrun|-n)+                        opt_dry_run=:+                        ;;++        --config)       func_config ;;++        --dlopen|-dlopen)+                        opt_dlopen="${opt_dlopen+$opt_dlopen+}$1"+                        shift+                        ;;++        --preserve-dup-deps)+                        opt_preserve_dup_deps=: ;;++        --features)     func_features ;;++        --finish)       set dummy --mode finish ${1+"$@"}; shift ;;++        --help)         opt_help=: ;;++        --help-all)     opt_help=': help-all' ;;++        --mode)         test $# = 0 && func_missing_arg $_G_opt && break+                        opt_mode=$1+                        case $1 in+                          # Valid mode arguments:+                          clean|compile|execute|finish|install|link|relink|uninstall) ;;++                          # Catch anything else as an error+                          *) func_error "invalid argument '$1' for $_G_opt"+                             exit_cmd=exit+                             ;;+                        esac+                        shift+                        ;;++        --no-finish)+                        opt_finishing=false+                        func_append preserve_args " $_G_opt"+                        ;;++        --no-silent|--no-quiet)+                        opt_quiet=false+                        func_append preserve_args " $_G_opt"+                        ;;++        --no-warnings|--no-warning|--no-warn)+                        opt_warning=false+                        func_append preserve_args " $_G_opt"+                        ;;++        --no-verbose)+                        opt_verbose=false+                        func_append preserve_args " $_G_opt"+                        ;;++        --reorder-cache)+                        opt_reorder_cache=true+                        shared_lib_dirs=$1+                        if test -n "$shared_lib_dirs"; then+                          case $1 in+                            # Must begin with /:+                            /*) ;;++                            # Catch anything else as an error (relative paths)+                            *) func_error "invalid argument '$1' for $_G_opt"+                               func_error "absolute paths are required for $_G_opt"+                               exit_cmd=exit+                               ;;+                          esac+                        fi+                        shift+                        ;;++        --silent|--quiet)+                        opt_quiet=:+                        opt_verbose=false+                        func_append preserve_args " $_G_opt"+                        ;;++        --tag)          test $# = 0 && func_missing_arg $_G_opt && break+                        opt_tag=$1+                        func_append preserve_args " $_G_opt $1"+                        func_enable_tag "$1"+                        shift+                        ;;++        --verbose|-v)   opt_quiet=false+                        opt_verbose=:+                        func_append preserve_args " $_G_opt"+                        ;;++        # An option not handled by this hook function:+        *)              set dummy "$_G_opt" ${1+"$@"} ; shift+                        _G_match_lt_parse_options=false+                        break+                        ;;+      esac+      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:+    done++    if $_G_rc_lt_parse_options; then+      # save modified positional parameters for caller+      func_quote eval ${1+"$@"}+      libtool_parse_options_result=$func_quote_result+    fi+}+func_add_hook func_parse_options libtool_parse_options+++# func_warning ARG...+# -------------------+# Libtool warnings are not categorized, so override funclib.sh+# func_warning with this simpler definition.+func_warning ()+{+    if $opt_warning; then+        $debug_cmd+        $warning_func ${1+"$@"}+    fi+}+++# libtool_validate_options [ARG]...+# ---------------------------------+# Perform any sanity checks on option settings and/or unconsumed+# arguments.+libtool_validate_options ()+{+    # save first non-option argument+    if test 0 -lt $#; then+      nonopt=$1+      shift+    fi++    # preserve --debug+    test : = "$debug_cmd" || func_append preserve_args " --debug"++    # Keeping compiler generated duplicates in $postdeps and $predeps is not+    # harmful, and is necessary in a majority of systems that use it to satisfy+    # symbol dependencies.+    opt_duplicate_compiler_generated_deps=:++    $opt_help || {+      # Sanity checks first:+      func_check_version_match++      test yes != "$build_libtool_libs" \+        && test yes != "$build_old_libs" \+        && func_fatal_configuration "not configured to build any kind of library"++      # Darwin sucks+      eval std_shrext=\"$shrext_cmds\"++      # Only execute mode is allowed to have -dlopen flags.+      if test -n "$opt_dlopen" && test execute != "$opt_mode"; then+        func_error "unrecognized option '-dlopen'"+        $ECHO "$help" 1>&2+        exit $EXIT_FAILURE+      fi++      # Change the help message to a mode-specific one.+      generic_help=$help+      help="Try '$progname --help --mode=$opt_mode' for more information."+    }++    # Pass back the unparsed argument list+    func_quote eval ${1+"$@"}+    libtool_validate_options_result=$func_quote_result+}+func_add_hook func_validate_options libtool_validate_options+++# Process options as early as possible so that --help and --version+# can return quickly.+func_options ${1+"$@"}+eval set dummy "$func_options_result"; shift++++## ----------- ##+##    Main.    ##+## ----------- ##++magic='%%%MAGIC variable%%%'+magic_exe='%%%MAGIC EXE variable%%%'++# Global variables.+extracted_archives=+extracted_serial=0++# If this variable is set in any of the actions, the command in it+# will be execed at the end.  This prevents here-documents from being+# left over by shells.+exec_cmd=+++# A function that is used when there is no print builtin or printf.+func_fallback_echo ()+{+  eval 'cat <<_LTECHO_EOF+$1+_LTECHO_EOF'+}++# func_generated_by_libtool+# True iff stdin has been generated by Libtool. This function is only+# a basic sanity check; it will hardly flush out determined imposters.+func_generated_by_libtool_p ()+{+  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1+}++# func_lalib_p file+# True iff FILE is a libtool '.la' library or '.lo' object file.+# This function is only a basic sanity check; it will hardly flush out+# determined imposters.+func_lalib_p ()+{+    test -f "$1" &&+      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p+}++# func_lalib_unsafe_p file+# True iff FILE is a libtool '.la' library or '.lo' object file.+# This function implements the same check as func_lalib_p without+# resorting to external programs.  To this end, it redirects stdin and+# closes it afterwards, without saving the original file descriptor.+# As a safety measure, use it only where a negative result would be+# fatal anyway.  Works if 'file' does not exist.+func_lalib_unsafe_p ()+{+    lalib_p=no+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then+	for lalib_p_l in 1 2 3 4+	do+	    read lalib_p_line+	    case $lalib_p_line in+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;+	    esac+	done+	exec 0<&5 5<&-+    fi+    test yes = "$lalib_p"+}++# func_ltwrapper_script_p file+# True iff FILE is a libtool wrapper script+# This function is only a basic sanity check; it will hardly flush out+# determined imposters.+func_ltwrapper_script_p ()+{+    test -f "$1" &&+      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p+}++# func_ltwrapper_executable_p file+# True iff FILE is a libtool wrapper executable+# This function is only a basic sanity check; it will hardly flush out+# determined imposters.+func_ltwrapper_executable_p ()+{+    func_ltwrapper_exec_suffix=+    case $1 in+    *.exe) ;;+    *) func_ltwrapper_exec_suffix=.exe ;;+    esac+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1+}++# func_ltwrapper_scriptname file+# Assumes file is an ltwrapper_executable+# uses $file to determine the appropriate filename for a+# temporary ltwrapper_script.+func_ltwrapper_scriptname ()+{+    func_dirname_and_basename "$1" "" "."+    func_stripname '' '.exe' "$func_basename_result"+    func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper+}++# func_ltwrapper_p file+# True iff FILE is a libtool wrapper script or wrapper executable+# This function is only a basic sanity check; it will hardly flush out+# determined imposters.+func_ltwrapper_p ()+{+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"+}+++# func_execute_cmds commands fail_cmd+# Execute tilde-delimited COMMANDS.+# If FAIL_CMD is given, eval that upon failure.+# FAIL_CMD may read-access the current command in variable CMD!+func_execute_cmds ()+{+    $debug_cmd++    save_ifs=$IFS; IFS='~'+    for cmd in $1; do+      IFS=$sp$nl+      eval cmd=\"$cmd\"+      IFS=$save_ifs+      func_show_eval "$cmd" "${2-:}"+    done+    IFS=$save_ifs+}+++# func_source file+# Source FILE, adding directory component if necessary.+# Note that it is not necessary on cygwin/mingw to append a dot to+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe+# behavior happens only for exec(3), not for open(2)!  Also, sourcing+# 'FILE.' does not work on cygwin managed mounts.+func_source ()+{+    $debug_cmd++    case $1 in+    */* | *\\*)	. "$1" ;;+    *)		. "./$1" ;;+    esac+}+++# func_resolve_sysroot PATH+# Replace a leading = in PATH with a sysroot.  Store the result into+# func_resolve_sysroot_result+func_resolve_sysroot ()+{+  func_resolve_sysroot_result=$1+  case $func_resolve_sysroot_result in+  =*)+    func_stripname '=' '' "$func_resolve_sysroot_result"+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result+    ;;+  esac+}++# func_replace_sysroot PATH+# If PATH begins with the sysroot, replace it with = and+# store the result into func_replace_sysroot_result.+func_replace_sysroot ()+{+  case $lt_sysroot:$1 in+  ?*:"$lt_sysroot"*)+    func_stripname "$lt_sysroot" '' "$1"+    func_replace_sysroot_result='='$func_stripname_result+    ;;+  *)+    # Including no sysroot.+    func_replace_sysroot_result=$1+    ;;+  esac+}++# func_infer_tag arg+# Infer tagged configuration to use if any are available and+# if one wasn't chosen via the "--tag" command line option.+# Only attempt this if the compiler in the base compile+# command doesn't match the default compiler.+# arg is usually of the form 'gcc ...'+func_infer_tag ()+{+    $debug_cmd++    if test -n "$available_tags" && test -z "$tagname"; then+      CC_quoted=+      for arg in $CC; do+	func_append_quoted CC_quoted "$arg"+      done+      CC_expanded=`func_echo_all $CC`+      CC_quoted_expanded=`func_echo_all $CC_quoted`+      case $@ in+      # Blanks in the command may have been stripped by the calling shell,+      # but not from the CC environment variable when configure was run.+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;+      # Blanks at the start of $base_compile will cause this to fail+      # if we don't check for them as well.+      *)+	for z in $available_tags; do+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then+	    # Evaluate the configuration.+	    eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"+	    CC_quoted=+	    for arg in $CC; do+	      # Double-quote args containing other shell metacharacters.+	      func_append_quoted CC_quoted "$arg"+	    done+	    CC_expanded=`func_echo_all $CC`+	    CC_quoted_expanded=`func_echo_all $CC_quoted`+	    case "$@ " in+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)+	      # The compiler in the base compile command matches+	      # the one in the tagged configuration.+	      # Assume this is the tagged configuration we want.+	      tagname=$z+	      break+	      ;;+	    esac+	  fi+	done+	# If $tagname still isn't set, then no tagged configuration+	# was found and let the user know that the "--tag" command+	# line option must be used.+	if test -z "$tagname"; then+	  func_echo "unable to infer tagged configuration"+	  func_fatal_error "specify a tag with '--tag'"+#	else+#	  func_verbose "using $tagname tagged configuration"+	fi+	;;+      esac+    fi+}++++# func_write_libtool_object output_name pic_name nonpic_name+# Create a libtool object file (analogous to a ".la" file),+# but don't create it if we're doing a dry run.+func_write_libtool_object ()+{+    write_libobj=$1+    if test yes = "$build_libtool_libs"; then+      write_lobj=\'$2\'+    else+      write_lobj=none+    fi++    if test yes = "$build_old_libs"; then+      write_oldobj=\'$3\'+    else+      write_oldobj=none+    fi++    $opt_dry_run || {+      cat >${write_libobj}T <<EOF+# $write_libobj - a libtool object file+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION+#+# Please DO NOT delete this file!+# It is necessary for linking the library.++# Name of the PIC object.+pic_object=$write_lobj++# Name of the non-PIC object+non_pic_object=$write_oldobj++EOF+      $MV "${write_libobj}T" "$write_libobj"+    }+}+++##################################################+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #+##################################################++# func_convert_core_file_wine_to_w32 ARG+# Helper function used by file name conversion functions when $build is *nix,+# and $host is mingw, windows, cygwin, or some other w32 environment. Relies on a+# correctly configured wine environment available, with the winepath program+# in $build's $PATH.+#+# ARG is the $build file name to be converted to w32 format.+# Result is available in $func_convert_core_file_wine_to_w32_result, and will+# be empty on error (or when ARG is empty)+func_convert_core_file_wine_to_w32 ()+{+  $debug_cmd++  func_convert_core_file_wine_to_w32_result=$1+  if test -n "$1"; then+    # Unfortunately, winepath does not exit with a non-zero error code, so we+    # are forced to check the contents of stdout. On the other hand, if the+    # command is not found, the shell will set an exit code of 127 and print+    # *an error message* to stdout. So we must check for both error code of+    # zero AND non-empty stdout, which explains the odd construction:+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`+    if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |+        $SED -e "$sed_naive_backslashify"`+    else+      func_convert_core_file_wine_to_w32_result=+    fi+  fi+}+# end: func_convert_core_file_wine_to_w32+++# func_convert_core_path_wine_to_w32 ARG+# Helper function used by path conversion functions when $build is *nix, and+# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a+# correctly configured wine environment available, with the winepath program+# in $build's $PATH. Assumes ARG has no leading or trailing path separator+# characters.+#+# ARG is path to be converted from $build format to win32.+# Result is available in $func_convert_core_path_wine_to_w32_result.+# Unconvertible file (directory) names in ARG are skipped; if no directory names+# are convertible, then the result may be empty.+func_convert_core_path_wine_to_w32 ()+{+  $debug_cmd++  # unfortunately, winepath doesn't convert paths, only file names+  func_convert_core_path_wine_to_w32_result=+  if test -n "$1"; then+    oldIFS=$IFS+    IFS=:+    for func_convert_core_path_wine_to_w32_f in $1; do+      IFS=$oldIFS+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"+      if test -n "$func_convert_core_file_wine_to_w32_result"; then+        if test -z "$func_convert_core_path_wine_to_w32_result"; then+          func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result+        else+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"+        fi+      fi+    done+    IFS=$oldIFS+  fi+}+# end: func_convert_core_path_wine_to_w32+++# func_cygpath ARGS...+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or+# (2), returns the Cygwin file name or path in func_cygpath_result (input+# file name or path is assumed to be in w32 format, as previously converted+# from $build's *nix or MSYS format). In case (3), returns the w32 file name+# or path in func_cygpath_result (input file name or path is assumed to be in+# Cygwin format). Returns an empty string on error.+#+# ARGS are passed to cygpath, with the last one being the file name or path to+# be converted.+#+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH+# environment variable; do not put it in $PATH.+func_cygpath ()+{+  $debug_cmd++  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`+    if test "$?" -ne 0; then+      # on failure, ensure result is empty+      func_cygpath_result=+    fi+  else+    func_cygpath_result=+    func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"+  fi+}+#end: func_cygpath+++# func_convert_core_msys_to_w32 ARG+# Convert file name or path ARG from MSYS format to w32 format.  Return+# result in func_convert_core_msys_to_w32_result.+func_convert_core_msys_to_w32 ()+{+  $debug_cmd++  # awkward: cmd appends spaces to result+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |+    $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`+}+#end: func_convert_core_msys_to_w32+++# func_convert_file_check ARG1 ARG2+# Verify that ARG1 (a file name in $build format) was converted to $host+# format in ARG2. Otherwise, emit an error message, but continue (resetting+# func_to_host_file_result to ARG1).+func_convert_file_check ()+{+  $debug_cmd++  if test -z "$2" && test -n "$1"; then+    func_error "Could not determine host file name corresponding to"+    func_error "  '$1'"+    func_error "Continuing, but uninstalled executables may not work."+    # Fallback:+    func_to_host_file_result=$1+  fi+}+# end func_convert_file_check+++# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH+# Verify that FROM_PATH (a path in $build format) was converted to $host+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting+# func_to_host_file_result to a simplistic fallback value (see below).+func_convert_path_check ()+{+  $debug_cmd++  if test -z "$4" && test -n "$3"; then+    func_error "Could not determine the host path corresponding to"+    func_error "  '$3'"+    func_error "Continuing, but uninstalled executables may not work."+    # Fallback.  This is a deliberately simplistic "conversion" and+    # should not be "improved".  See libtool.info.+    if test "x$1" != "x$2"; then+      lt_replace_pathsep_chars="s|$1|$2|g"+      func_to_host_path_result=`echo "$3" |+        $SED -e "$lt_replace_pathsep_chars"`+    else+      func_to_host_path_result=$3+    fi+  fi+}+# end func_convert_path_check+++# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT+# and appending REPL if ORIG matches BACKPAT.+func_convert_path_front_back_pathsep ()+{+  $debug_cmd++  case $4 in+  $1 ) func_to_host_path_result=$3$func_to_host_path_result+    ;;+  esac+  case $4 in+  $2 ) func_append func_to_host_path_result "$3"+    ;;+  esac+}+# end func_convert_path_front_back_pathsep+++# func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER+# Replaces a delimiter for a given path.+func_convert_delimited_path ()+{+	converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"`+}+# end func_convert_delimited_path+++##################################################+# $build to $host FILE NAME CONVERSION FUNCTIONS #+##################################################+# invoked via '$to_host_file_cmd ARG'+#+# In each case, ARG is the path to be converted from $build to $host format.+# Result will be available in $func_to_host_file_result.+++# func_to_host_file ARG+# Converts the file name ARG from $build format to $host format. Return result+# in func_to_host_file_result.+func_to_host_file ()+{+  $debug_cmd++  $to_host_file_cmd "$1"+}+# end func_to_host_file+++# func_to_tool_file ARG LAZY+# converts the file name ARG from $build format to toolchain format. Return+# result in func_to_tool_file_result.  If the conversion in use is listed+# in (the comma separated) LAZY, no conversion takes place.+func_to_tool_file ()+{+  $debug_cmd++  case ,$2, in+    *,"$to_tool_file_cmd",*)+      func_to_tool_file_result=$1+      ;;+    *)+      $to_tool_file_cmd "$1"+      func_to_tool_file_result=$func_to_host_file_result+      ;;+  esac+}+# end func_to_tool_file+++# func_convert_file_noop ARG+# Copy ARG to func_to_host_file_result.+func_convert_file_noop ()+{+  func_to_host_file_result=$1+}+# end func_convert_file_noop+++# func_convert_file_msys_to_w32 ARG+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic+# conversion to w32 is not available inside the cwrapper.  Returns result in+# func_to_host_file_result.+func_convert_file_msys_to_w32 ()+{+  $debug_cmd++  func_to_host_file_result=$1+  if test -n "$1"; then+    func_convert_core_msys_to_w32 "$1"+    func_to_host_file_result=$func_convert_core_msys_to_w32_result+  fi+  func_convert_file_check "$1" "$func_to_host_file_result"+}+# end func_convert_file_msys_to_w32+++# func_convert_file_cygwin_to_w32 ARG+# Convert file name ARG from Cygwin to w32 format.  Returns result in+# func_to_host_file_result.+func_convert_file_cygwin_to_w32 ()+{+  $debug_cmd++  func_to_host_file_result=$1+  if test -n "$1"; then+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use+    # LT_CYGPATH in this case.+    func_to_host_file_result=`cygpath -m "$1"`+  fi+  func_convert_file_check "$1" "$func_to_host_file_result"+}+# end func_convert_file_cygwin_to_w32+++# func_convert_file_nix_to_w32 ARG+# Convert file name ARG from *nix to w32 format.  Requires a wine environment+# and a working winepath. Returns result in func_to_host_file_result.+func_convert_file_nix_to_w32 ()+{+  $debug_cmd++  func_to_host_file_result=$1+  if test -n "$1"; then+    func_convert_core_file_wine_to_w32 "$1"+    func_to_host_file_result=$func_convert_core_file_wine_to_w32_result+  fi+  func_convert_file_check "$1" "$func_to_host_file_result"+}+# end func_convert_file_nix_to_w32+++# func_convert_file_msys_to_cygwin ARG+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.+# Returns result in func_to_host_file_result.+func_convert_file_msys_to_cygwin ()+{+  $debug_cmd++  func_to_host_file_result=$1+  if test -n "$1"; then+    func_convert_core_msys_to_w32 "$1"+    func_cygpath -u "$func_convert_core_msys_to_w32_result"+    func_to_host_file_result=$func_cygpath_result+  fi+  func_convert_file_check "$1" "$func_to_host_file_result"+}+# end func_convert_file_msys_to_cygwin+++# func_convert_file_nix_to_cygwin ARG+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result+# in func_to_host_file_result.+func_convert_file_nix_to_cygwin ()+{+  $debug_cmd++  func_to_host_file_result=$1+  if test -n "$1"; then+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.+    func_convert_core_file_wine_to_w32 "$1"+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"+    func_to_host_file_result=$func_cygpath_result+  fi+  func_convert_file_check "$1" "$func_to_host_file_result"+}+# end func_convert_file_nix_to_cygwin+++#############################################+# $build to $host PATH CONVERSION FUNCTIONS #+#############################################+# invoked via '$to_host_path_cmd ARG'+#+# In each case, ARG is the path to be converted from $build to $host format.+# The result will be available in $func_to_host_path_result.+#+# Path separators are also converted from $build format to $host format.  If+# ARG begins or ends with a path separator character, it is preserved (but+# converted to $host format) on output.+#+# All path conversion functions are named using the following convention:+#   file name conversion function    : func_convert_file_X_to_Y ()+#   path conversion function         : func_convert_path_X_to_Y ()+# where, for any given $build/$host combination the 'X_to_Y' value is the+# same.  If conversion functions are added for new $build/$host combinations,+# the two new functions must follow this pattern, or func_init_to_host_path_cmd+# will break.+++# func_init_to_host_path_cmd+# Ensures that function "pointer" variable $to_host_path_cmd is set to the+# appropriate value, based on the value of $to_host_file_cmd.+to_host_path_cmd=+func_init_to_host_path_cmd ()+{+  $debug_cmd++  if test -z "$to_host_path_cmd"; then+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"+    to_host_path_cmd=func_convert_path_$func_stripname_result+  fi+}+++# func_to_host_path ARG+# Converts the path ARG from $build format to $host format. Return result+# in func_to_host_path_result.+func_to_host_path ()+{+  $debug_cmd++  func_init_to_host_path_cmd+  $to_host_path_cmd "$1"+}+# end func_to_host_path+++# func_convert_path_noop ARG+# Copy ARG to func_to_host_path_result.+func_convert_path_noop ()+{+  func_to_host_path_result=$1+}+# end func_convert_path_noop+++# func_convert_path_msys_to_w32 ARG+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic+# conversion to w32 is not available inside the cwrapper.  Returns result in+# func_to_host_path_result.+func_convert_path_msys_to_w32 ()+{+  $debug_cmd++  func_to_host_path_result=$1+  if test -n "$1"; then+    # Remove leading and trailing path separator characters from ARG.  MSYS+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';+    # and winepath ignores them completely.+    func_stripname : : "$1"+    func_to_host_path_tmp1=$func_stripname_result+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"+    func_to_host_path_result=$func_convert_core_msys_to_w32_result+    func_convert_path_check : ";" \+      "$func_to_host_path_tmp1" "$func_to_host_path_result"+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"+  fi+}+# end func_convert_path_msys_to_w32+++# func_convert_path_cygwin_to_w32 ARG+# Convert path ARG from Cygwin to w32 format.  Returns result in+# func_to_host_file_result.+func_convert_path_cygwin_to_w32 ()+{+  $debug_cmd++  func_to_host_path_result=$1+  if test -n "$1"; then+    # See func_convert_path_msys_to_w32:+    func_stripname : : "$1"+    func_to_host_path_tmp1=$func_stripname_result+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`+    func_convert_path_check : ";" \+      "$func_to_host_path_tmp1" "$func_to_host_path_result"+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"+  fi+}+# end func_convert_path_cygwin_to_w32+++# func_convert_path_nix_to_w32 ARG+# Convert path ARG from *nix to w32 format.  Requires a wine environment and+# a working winepath.  Returns result in func_to_host_file_result.+func_convert_path_nix_to_w32 ()+{+  $debug_cmd++  func_to_host_path_result=$1+  if test -n "$1"; then+    # See func_convert_path_msys_to_w32:+    func_stripname : : "$1"+    func_to_host_path_tmp1=$func_stripname_result+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"+    func_to_host_path_result=$func_convert_core_path_wine_to_w32_result+    func_convert_path_check : ";" \+      "$func_to_host_path_tmp1" "$func_to_host_path_result"+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"+  fi+}+# end func_convert_path_nix_to_w32+++# func_convert_path_msys_to_cygwin ARG+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.+# Returns result in func_to_host_file_result.+func_convert_path_msys_to_cygwin ()+{+  $debug_cmd++  func_to_host_path_result=$1+  if test -n "$1"; then+    # See func_convert_path_msys_to_w32:+    func_stripname : : "$1"+    func_to_host_path_tmp1=$func_stripname_result+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"+    func_to_host_path_result=$func_cygpath_result+    func_convert_path_check : : \+      "$func_to_host_path_tmp1" "$func_to_host_path_result"+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"+  fi+}+# end func_convert_path_msys_to_cygwin+++# func_convert_path_nix_to_cygwin ARG+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in+# func_to_host_file_result.+func_convert_path_nix_to_cygwin ()+{+  $debug_cmd++  func_to_host_path_result=$1+  if test -n "$1"; then+    # Remove leading and trailing path separator characters from+    # ARG. msys behavior is inconsistent here, cygpath turns them+    # into '.;' and ';.', and winepath ignores them completely.+    func_stripname : : "$1"+    func_to_host_path_tmp1=$func_stripname_result+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"+    func_to_host_path_result=$func_cygpath_result+    func_convert_path_check : : \+      "$func_to_host_path_tmp1" "$func_to_host_path_result"+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"+  fi+}+# end func_convert_path_nix_to_cygwin+++# func_dll_def_p FILE+# True iff FILE is a Windows DLL '.def' file.+# Keep in sync with _LT_DLL_DEF_P in libtool.m4+func_dll_def_p ()+{+  $debug_cmd++  func_dll_def_p_tmp=`$SED -n \+    -e 's/^[	 ]*//' \+    -e '/^\(;.*\)*$/d' \+    -e 's/^\(EXPORTS\|LIBRARY\)\([	 ].*\)*$/DEF/p' \+    -e q \+    "$1"`+  test DEF = "$func_dll_def_p_tmp"+}+++# func_reorder_shared_lib_cache DIRS+# Reorder the shared library cache by unconfiguring previous shared library cache+# and configuring preferred search directories before previous search directories.+# Previous shared library cache: /usr/lib /usr/local/lib+# Preferred search directories: /tmp/testing+# Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib+func_reorder_shared_lib_cache ()+{+	$debug_cmd++	case $host_os in+	  openbsd*)+	    get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"`+	    func_convert_delimited_path "$get_search_directories" ':' '\ '+	    save_search_directories=$converted_path+	    func_convert_delimited_path "$1" ':' '\ '++	    # Ensure directories exist+	    for dir in $converted_path; do+	      # Ensure each directory is an absolute path+	      case $dir in+	        /*) ;;+	        *) func_error "Directory '$dir' is not an absolute path"+	           exit $EXIT_FAILURE ;;+	      esac+	      # Ensure no trailing slashes+	      func_stripname '' '/' "$dir"+	      dir=$func_stripname_result+	      if test -d "$dir"; then+	        if test -n "$preferred_search_directories"; then+	          preferred_search_directories="$preferred_search_directories $dir"+	        else+	          preferred_search_directories=$dir+	        fi+	      else+	        func_error "Directory '$dir' does not exist"+	        exit $EXIT_FAILURE+	      fi+	    done++	    PATH="$PATH:/sbin" ldconfig -U $save_search_directories+	    PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories+	    get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"`+	    func_convert_delimited_path "$get_search_directories" ':' '\ '+	    reordered_search_directories=$converted_path++	    $ECHO "Original: $save_search_directories"+	    $ECHO "Reordered: $reordered_search_directories"+	    exit $EXIT_SUCCESS+	  ;;+	  *)+	    func_error "--reorder-cache is not supported for host_os=$host_os."+	    exit $EXIT_FAILURE+	  ;;+	esac+}+# end func_reorder_shared_lib_cache+++# func_mode_compile arg...+func_mode_compile ()+{+    $debug_cmd++    # Get the compilation command and the source file.+    base_compile=+    srcfile=$nonopt  #  always keep a non-empty value in "srcfile"+    suppress_opt=yes+    suppress_output=+    arg_mode=normal+    libobj=+    later=+    pie_flag=++    for arg+    do+      case $arg_mode in+      arg  )+	# do not "continue".  Instead, add this to base_compile+	lastarg=$arg+	arg_mode=normal+	;;++      target )+	libobj=$arg+	arg_mode=normal+	continue+	;;++      normal )+	# Accept any command-line options.+	case $arg in+	-o)+	  test -n "$libobj" && \+	    func_fatal_error "you cannot specify '-o' more than once"+	  arg_mode=target+	  continue+	  ;;++	-pie | -fpie | -fPIE)+          func_append pie_flag " $arg"+	  continue+	  ;;++	-shared | -static | -prefer-pic | -prefer-non-pic)+	  func_append later " $arg"+	  continue+	  ;;++	-no-suppress)+	  suppress_opt=no+	  continue+	  ;;++	-Xcompiler)+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list+	  continue      #  The current "srcfile" will either be retained or+	  ;;            #  replaced later.  I would guess that would be a bug.++	-Wc,*)+	  func_stripname '-Wc,' '' "$arg"+	  args=$func_stripname_result+	  lastarg=+	  save_ifs=$IFS; IFS=,+	  for arg in $args; do+	    IFS=$save_ifs+	    func_append_quoted lastarg "$arg"+	  done+	  IFS=$save_ifs+	  func_stripname ' ' '' "$lastarg"+	  lastarg=$func_stripname_result++	  # Add the arguments to base_compile.+	  func_append base_compile " $lastarg"+	  continue+	  ;;++	*)+	  # Accept the current argument as the source file.+	  # The previous "srcfile" becomes the current argument.+	  #+	  lastarg=$srcfile+	  srcfile=$arg+	  ;;+	esac  #  case $arg+	;;+      esac    #  case $arg_mode++      # Aesthetically quote the previous argument.+      func_append_quoted base_compile "$lastarg"+    done # for arg++    case $arg_mode in+    arg)+      func_fatal_error "you must specify an argument for -Xcompile"+      ;;+    target)+      func_fatal_error "you must specify a target with '-o'"+      ;;+    *)+      # Get the name of the library object.+      test -z "$libobj" && {+	func_basename "$srcfile"+	libobj=$func_basename_result+      }+      ;;+    esac++    # Recognize several different file suffixes.+    # If the user specifies -o file.o, it is replaced with file.lo+    case $libobj in+    *.[cCFSifmso] | \+    *.ada | *.adb | *.ads | *.asm | \+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)+      func_xform "$libobj"+      libobj=$func_xform_result+      ;;+    esac++    case $libobj in+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;+    *)+      func_fatal_error "cannot determine name of library object from '$libobj'"+      ;;+    esac++    func_infer_tag $base_compile++    for arg in $later; do+      case $arg in+      -shared)+	test yes = "$build_libtool_libs" \+	  || func_fatal_configuration "cannot build a shared library"+	build_old_libs=no+	continue+	;;++      -static)+	build_libtool_libs=no+	build_old_libs=yes+	continue+	;;++      -prefer-pic)+	pic_mode=yes+	continue+	;;++      -prefer-non-pic)+	pic_mode=no+	continue+	;;+      esac+    done++    func_quote_arg pretty "$libobj"+    test "X$libobj" != "X$func_quote_arg_result" \+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \+      && func_warning "libobj name '$libobj' may not contain shell special characters."+    func_dirname_and_basename "$obj" "/" ""+    objname=$func_basename_result+    xdir=$func_dirname_result+    lobj=$xdir$objdir/$objname++    test -z "$base_compile" && \+      func_fatal_help "you must specify a compilation command"++    # Delete any leftover library objects.+    if test yes = "$build_old_libs"; then+      removelist="$obj $lobj $libobj ${libobj}T"+    else+      removelist="$lobj $libobj ${libobj}T"+    fi++    # On Cygwin there's no "real" PIC flag so we must build both object types+    case $host_os in+    cygwin* | mingw* | windows* | pw32* | os2* | cegcc*)+      pic_mode=default+      ;;+    esac+    if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then+      # non-PIC code in shared libraries is not supported+      pic_mode=default+    fi++    # Calculate the filename of the output object if compiler does+    # not support -o with -c+    if test no = "$compiler_c_o"; then+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext+      lockfile=$output_obj.lock+    else+      output_obj=+      need_locks=no+      lockfile=+    fi++    # Lock this critical section if it is needed+    # We use this script file to make the link, it avoids creating a new file+    if test yes = "$need_locks"; then+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do+	func_echo "Waiting for $lockfile to be removed"+	sleep 2+      done+    elif test warn = "$need_locks"; then+      if test -f "$lockfile"; then+	$ECHO "\+*** ERROR, $lockfile exists and contains:+`cat $lockfile 2>/dev/null`++This indicates that another process is trying to use the same+temporary object file, and libtool could not work around it because+your compiler does not support '-c' and '-o' together.  If you+repeat this compilation, it may succeed, by chance, but you had better+avoid parallel builds (make -j) in this platform, or get a better+compiler."++	$opt_dry_run || $RM $removelist+	exit $EXIT_FAILURE+      fi+      func_append removelist " $output_obj"+      $ECHO "$srcfile" > "$lockfile"+    fi++    $opt_dry_run || $RM $removelist+    func_append removelist " $lockfile"+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15++    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32+    srcfile=$func_to_tool_file_result+    func_quote_arg pretty "$srcfile"+    qsrcfile=$func_quote_arg_result++    # Only build a PIC object if we are building libtool libraries.+    if test yes = "$build_libtool_libs"; then+      # Without this assignment, base_compile gets emptied.+      fbsd_hideous_sh_bug=$base_compile++      if test no != "$pic_mode"; then+	command="$base_compile $qsrcfile $pic_flag"+      else+	# Don't build PIC code+	command="$base_compile $qsrcfile"+      fi++      func_mkdir_p "$xdir$objdir"++      if test -z "$output_obj"; then+	# Place PIC objects in $objdir+	func_append command " -o $lobj"+      fi++      func_show_eval_locale "$command"	\+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'++      if test warn = "$need_locks" &&+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then+	$ECHO "\+*** ERROR, $lockfile contains:+`cat $lockfile 2>/dev/null`++but it should contain:+$srcfile++This indicates that another process is trying to use the same+temporary object file, and libtool could not work around it because+your compiler does not support '-c' and '-o' together.  If you+repeat this compilation, it may succeed, by chance, but you had better+avoid parallel builds (make -j) in this platform, or get a better+compiler."++	$opt_dry_run || $RM $removelist+	exit $EXIT_FAILURE+      fi++      # Just move the object if needed, then go on to compile the next one+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then+	func_show_eval '$MV "$output_obj" "$lobj"' \+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'+      fi++      # Allow error messages only from the first compilation.+      if test yes = "$suppress_opt"; then+	suppress_output=' >/dev/null 2>&1'+      fi+    fi++    # Only build a position-dependent object if we build old libraries.+    if test yes = "$build_old_libs"; then+      if test yes != "$pic_mode"; then+	# Don't build PIC code+	command="$base_compile $qsrcfile$pie_flag"+      else+	command="$base_compile $qsrcfile $pic_flag"+      fi+      if test yes = "$compiler_c_o"; then+	func_append command " -o $obj"+      fi++      # Suppress compiler output if we already did a PIC compilation.+      func_append command "$suppress_output"+      func_show_eval_locale "$command" \+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'++      if test warn = "$need_locks" &&+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then+	$ECHO "\+*** ERROR, $lockfile contains:+`cat $lockfile 2>/dev/null`++but it should contain:+$srcfile++This indicates that another process is trying to use the same+temporary object file, and libtool could not work around it because+your compiler does not support '-c' and '-o' together.  If you+repeat this compilation, it may succeed, by chance, but you had better+avoid parallel builds (make -j) in this platform, or get a better+compiler."++	$opt_dry_run || $RM $removelist+	exit $EXIT_FAILURE+      fi++      # Just move the object if needed+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then+	func_show_eval '$MV "$output_obj" "$obj"' \+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'+      fi+    fi++    $opt_dry_run || {+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"++      # Unlock the critical section if it was locked+      if test no != "$need_locks"; then+	removelist=$lockfile+        $RM "$lockfile"+      fi+    }++    exit $EXIT_SUCCESS+}++$opt_help || {+  test compile = "$opt_mode" && func_mode_compile ${1+"$@"}+}++func_mode_help ()+{+    # We need to display help for each of the modes.+    case $opt_mode in+      "")+        # Generic help is extracted from the usage comments+        # at the start of this file.+        func_help+        ;;++      clean)+        $ECHO \+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...++Remove files from the build directory.++RM is the name of the program to use to delete files associated with each FILE+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed+to RM.++If FILE is a libtool library, object or program, all the files associated+with it are deleted. Otherwise, only FILE itself is deleted using RM."+        ;;++      compile)+      $ECHO \+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE++Compile a source file into a libtool library object.++This mode accepts the following additional options:++  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE+  -no-suppress      do not suppress compiler output for multiple passes+  -prefer-pic       try to build PIC objects only+  -prefer-non-pic   try to build non-PIC objects only+  -shared           do not build a '.o' file suitable for static linking+  -static           only build a '.o' file suitable for static linking+  -Wc,FLAG+  -Xcompiler FLAG   pass FLAG directly to the compiler++COMPILE-COMMAND is a command to be used in creating a 'standard' object file+from the given SOURCEFILE.++The output file name is determined by removing the directory component from+SOURCEFILE, then substituting the C source code suffix '.c' with the+library object suffix, '.lo'."+        ;;++      execute)+        $ECHO \+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...++Automatically set library path, then run a program.++This mode accepts the following additional options:++  -dlopen FILE      add the directory containing FILE to the library path++This mode sets the library path environment variable according to '-dlopen'+flags.++If any of the ARGS are libtool executable wrappers, then they are translated+into their corresponding uninstalled binary, and any of their required library+directories are added to the library path.++Then, COMMAND is executed, with ARGS as arguments."+        ;;++      finish)+        $ECHO \+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...++Complete the installation of libtool libraries.++Each LIBDIR is a directory that contains libtool libraries.++The commands that this mode executes may require superuser privileges.  Use+the '--dry-run' option if you just want to see what would be executed."+        ;;++      install)+        $ECHO \+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...++Install executables or libraries.++INSTALL-COMMAND is the installation command.  The first component should be+either the 'install' or 'cp' program.++The following components of INSTALL-COMMAND are treated specially:++  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation++The rest of the components are interpreted as arguments to that command (only+BSD-compatible install options are recognized)."+        ;;++      link)+        $ECHO \+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...++Link object files or libraries together to form another library, or to+create an executable program.++LINK-COMMAND is a command using the C compiler that you would use to create+a program from several object files.++The following components of LINK-COMMAND are treated specially:++  -all-static       do not do any dynamic linking at all+  -avoid-version    do not add a version suffix if possible+  -bindir BINDIR    specify path to binaries directory (for systems where+                    libraries must be found in the PATH setting at runtime)+  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)+  -export-symbols SYMFILE+                    try to export only the symbols listed in SYMFILE+  -export-symbols-regex REGEX+                    try to export only the symbols matching REGEX+  -LLIBDIR          search LIBDIR for required installed libraries+  -lNAME            OUTPUT-FILE requires the installed library libNAME+  -module           build a library that can dlopened+  -no-fast-install  disable the fast-install mode+  -no-install       link a not-installable executable+  -no-undefined     declare that a library does not refer to external symbols+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects+  -objectlist FILE  use a list of object files found in FILE to specify objects+  -os2dllname NAME  force a short DLL name on OS/2 (no effect on other OSes)+  -precious-files-regex REGEX+                    don't remove output files matching REGEX+  -release RELEASE  specify package release information+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries+  -shared           only do dynamic linking of libtool libraries+  -shrext SUFFIX    override the standard shared library file extension+  -static           do not do any dynamic linking of uninstalled libtool libraries+  -static-libtool-libs+                    do not do any dynamic linking of libtool libraries+  -version-info CURRENT[:REVISION[:AGE]]+                    specify library version info [each variable defaults to 0]+  -weak LIBNAME     declare that the target provides the LIBNAME interface+  -Wc,FLAG+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler+  -Wa,FLAG+  -Xassembler FLAG  pass linker-specific FLAG directly to the assembler+  -Wl,FLAG+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)++All other options (arguments beginning with '-') are ignored.++Every other argument is treated as a filename.  Files ending in '.la' are+treated as uninstalled libtool libraries, other files are standard or library+object files.++If the OUTPUT-FILE ends in '.la', then a libtool library is created,+only library objects ('.lo' files) may be specified, and '-rpath' is+required, except when creating a convenience library.++If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created+using 'ar' and 'ranlib', or on Windows using 'lib'.++If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file+is created, otherwise an executable program is created."+        ;;++      uninstall)+        $ECHO \+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...++Remove libraries from an installation directory.++RM is the name of the program to use to delete files associated with each FILE+(typically '/bin/rm').  RM-OPTIONS are options (such as '-f') to be passed+to RM.++If FILE is a libtool library, all the files associated with it are deleted.+Otherwise, only FILE itself is deleted using RM."+        ;;++      *)+        func_fatal_help "invalid operation mode '$opt_mode'"+        ;;+    esac++    echo+    $ECHO "Try '$progname --help' for more information about other modes."+}++# Now that we've collected a possible --mode arg, show help if necessary+if $opt_help; then+  if test : = "$opt_help"; then+    func_mode_help+  else+    {+      func_help noexit+      for opt_mode in compile link execute install finish uninstall clean; do+	func_mode_help+      done+    } | $SED -n '1p; 2,$s/^Usage:/  or: /p'+    {+      func_help noexit+      for opt_mode in compile link execute install finish uninstall clean; do+	echo+	func_mode_help+      done+    } |+    $SED '1d+      /^When reporting/,/^Report/{+	H+	d+      }+      $x+      /information about other modes/d+      /more detailed .*MODE/d+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'+  fi+  exit $?+fi+++# If option '--reorder-cache', reorder the shared library cache and exit.+if $opt_reorder_cache; then+    func_reorder_shared_lib_cache $shared_lib_dirs+fi+++# func_mode_execute arg...+func_mode_execute ()+{+    $debug_cmd++    # The first argument is the command name.+    cmd=$nonopt+    test -z "$cmd" && \+      func_fatal_help "you must specify a COMMAND"++    # Handle -dlopen flags immediately.+    for file in $opt_dlopen; do+      test -f "$file" \+	|| func_fatal_help "'$file' is not a file"++      dir=+      case $file in+      *.la)+	func_resolve_sysroot "$file"+	file=$func_resolve_sysroot_result++	# Check to see that this really is a libtool archive.+	func_lalib_unsafe_p "$file" \+	  || func_fatal_help "'$lib' is not a valid libtool archive"++	# Read the libtool library.+	dlname=+	library_names=+	func_source "$file"++	# Skip this library if it cannot be dlopened.+	if test -z "$dlname"; then+	  # Warn if it was a shared library.+	  test -n "$library_names" && \+	    func_warning "'$file' was not linked with '-export-dynamic'"+	  continue+	fi++	func_dirname "$file" "" "."+	dir=$func_dirname_result++	if test -f "$dir/$objdir/$dlname"; then+	  func_append dir "/$objdir"+	else+	  if test ! -f "$dir/$dlname"; then+	    func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"+	  fi+	fi+	;;++      *.lo)+	# Just add the directory containing the .lo file.+	func_dirname "$file" "" "."+	dir=$func_dirname_result+	;;++      *)+	func_warning "'-dlopen' is ignored for non-libtool libraries and objects"+	continue+	;;+      esac++      # Get the absolute pathname.+      absdir=`cd "$dir" && pwd`+      test -n "$absdir" && dir=$absdir++      # Now add the directory to shlibpath_var.+      if eval "test -z \"\$$shlibpath_var\""; then+	eval "$shlibpath_var=\"\$dir\""+      else+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""+      fi+    done++    # This variable tells wrapper scripts just to set shlibpath_var+    # rather than running their programs.+    libtool_execute_magic=$magic++    # Check if any of the arguments is a wrapper script.+    args=+    for file+    do+      case $file in+      -* | *.la | *.lo ) ;;+      *)+	# Do a test to see if this is really a libtool program.+	if func_ltwrapper_script_p "$file"; then+	  func_source "$file"+	  # Transform arg to wrapped name.+	  file=$progdir/$program+	elif func_ltwrapper_executable_p "$file"; then+	  func_ltwrapper_scriptname "$file"+	  func_source "$func_ltwrapper_scriptname_result"+	  # Transform arg to wrapped name.+	  file=$progdir/$program+	fi+	;;+      esac+      # Quote arguments (to preserve shell metacharacters).+      func_append_quoted args "$file"+    done++    if $opt_dry_run; then+      # Display what would be done.+      if test -n "$shlibpath_var"; then+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""+	echo "export $shlibpath_var"+      fi+      $ECHO "$cmd$args"+      exit $EXIT_SUCCESS+    else+      if test -n "$shlibpath_var"; then+	# Export the shlibpath_var.+	eval "export $shlibpath_var"+      fi++      # Restore saved environment variables+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES+      do+	eval "if test \"\${save_$lt_var+set}\" = set; then+                $lt_var=\$save_$lt_var; export $lt_var+	      else+		$lt_unset $lt_var+	      fi"+      done++      # Now prepare to actually exec the command.+      exec_cmd=\$cmd$args+    fi+}++test execute = "$opt_mode" && func_mode_execute ${1+"$@"}+++# func_mode_finish arg...+func_mode_finish ()+{+    $debug_cmd++    libs=+    libdirs=+    admincmds=++    for opt in "$nonopt" ${1+"$@"}+    do+      if test -d "$opt"; then+	func_append libdirs " $opt"++      elif test -f "$opt"; then+	if func_lalib_unsafe_p "$opt"; then+	  func_append libs " $opt"+	else+	  func_warning "'$opt' is not a valid libtool archive"+	fi++      else+	func_fatal_error "invalid argument '$opt'"+      fi+    done++    if test -n "$libs"; then+      if test -n "$lt_sysroot"; then+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"+      else+        sysroot_cmd=+      fi++      # Remove sysroot references+      if $opt_dry_run; then+        for lib in $libs; do+          echo "removing references to $lt_sysroot and '=' prefixes from $lib"+        done+      else+        tmpdir=`func_mktempdir`+        for lib in $libs; do+	  $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \+	    > $tmpdir/tmp-la+	  mv -f $tmpdir/tmp-la $lib+	done+        ${RM}r "$tmpdir"+      fi+    fi++    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then+      for libdir in $libdirs; do+	if test -n "$finish_cmds"; then+	  # Do each command in the finish commands.+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds+'"$cmd"'"'+	fi+	if test -n "$finish_eval"; then+	  # Do the single finish_eval.+	  eval cmds=\"$finish_eval\"+	  $opt_dry_run || eval "$cmds" || func_append admincmds "+       $cmds"+	fi+      done+    fi++    # Exit here if they wanted silent mode.+    $opt_quiet && exit $EXIT_SUCCESS++    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then+      echo "----------------------------------------------------------------------"+      echo "Libraries have been installed in:"+      for libdir in $libdirs; do+	$ECHO "   $libdir"+      done+      if test "false" = "$opt_finishing"; then+        echo+        echo "NOTE: finish_cmds were not executed during testing, so you must"+        echo "manually run ldconfig to add a given test directory, LIBDIR, to"+        echo "the search path for generated executables."+      fi+      echo+      echo "If you ever happen to want to link against installed libraries"+      echo "in a given directory, LIBDIR, you must either use libtool, and"+      echo "specify the full pathname of the library, or use the '-LLIBDIR'"+      echo "flag during linking and do at least one of the following:"+      if test -n "$shlibpath_var"; then+	echo "   - add LIBDIR to the '$shlibpath_var' environment variable"+	echo "     during execution"+      fi+      if test -n "$runpath_var"; then+	echo "   - add LIBDIR to the '$runpath_var' environment variable"+	echo "     during linking"+      fi+      if test -n "$hardcode_libdir_flag_spec"; then+	libdir=LIBDIR+	eval flag=\"$hardcode_libdir_flag_spec\"++	$ECHO "   - use the '$flag' linker flag"+      fi+      if test -n "$admincmds"; then+	$ECHO "   - have your system administrator run these commands:$admincmds"+      fi+      if test -f /etc/ld.so.conf; then+	echo "   - have your system administrator add LIBDIR to '/etc/ld.so.conf'"+      fi+      echo++      echo "See any operating system documentation about shared libraries for"+      case $host in+	solaris2.[6789]|solaris2.1[0-9])+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"+	  echo "pages."+	  ;;+	*)+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."+	  ;;+      esac+      echo "----------------------------------------------------------------------"+    fi+    exit $EXIT_SUCCESS+}++test finish = "$opt_mode" && func_mode_finish ${1+"$@"}+++# func_mode_install arg...+func_mode_install ()+{+    $debug_cmd++    # There may be an optional sh(1) argument at the beginning of+    # install_prog (especially on Windows NT).+    if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||+       # Allow the use of GNU shtool's install command.+       case $nonopt in *shtool*) :;; *) false;; esac+    then+      # Aesthetically quote it.+      func_quote_arg pretty "$nonopt"+      install_prog="$func_quote_arg_result "+      arg=$1+      shift+    else+      install_prog=+      arg=$nonopt+    fi++    # The real first argument should be the name of the installation program.+    # Aesthetically quote it.+    func_quote_arg pretty "$arg"+    func_append install_prog "$func_quote_arg_result"+    install_shared_prog=$install_prog+    case " $install_prog " in+      *[\\\ /]cp\ *) install_cp=: ;;+      *) install_cp=false ;;+    esac++    # We need to accept at least all the BSD install flags.+    dest=+    files=+    opts=+    prev=+    install_type=+    isdir=false+    stripme=+    no_mode=:+    for arg+    do+      arg2=+      if test -n "$dest"; then+	func_append files " $dest"+	dest=$arg+	continue+      fi++      case $arg in+      -d) isdir=: ;;+      -f)+	if $install_cp; then :; else+	  prev=$arg+	fi+	;;+      -g | -m | -o)+	prev=$arg+	;;+      -s)+	stripme=" -s"+	continue+	;;+      -*)+	;;+      *)+	# If the previous option needed an argument, then skip it.+	if test -n "$prev"; then+	  if test X-m = "X$prev" && test -n "$install_override_mode"; then+	    arg2=$install_override_mode+	    no_mode=false+	  fi+	  prev=+	else+	  dest=$arg+	  continue+	fi+	;;+      esac++      # Aesthetically quote the argument.+      func_quote_arg pretty "$arg"+      func_append install_prog " $func_quote_arg_result"+      if test -n "$arg2"; then+	func_quote_arg pretty "$arg2"+      fi+      func_append install_shared_prog " $func_quote_arg_result"+    done++    test -z "$install_prog" && \+      func_fatal_help "you must specify an install program"++    test -n "$prev" && \+      func_fatal_help "the '$prev' option requires an argument"++    if test -n "$install_override_mode" && $no_mode; then+      if $install_cp; then :; else+	func_quote_arg pretty "$install_override_mode"+	func_append install_shared_prog " -m $func_quote_arg_result"+      fi+    fi++    if test -z "$files"; then+      if test -z "$dest"; then+	func_fatal_help "no file or destination specified"+      else+	func_fatal_help "you must specify a destination"+      fi+    fi++    # Strip any trailing slash from the destination.+    func_stripname '' '/' "$dest"+    dest=$func_stripname_result++    # Check to see that the destination is a directory.+    test -d "$dest" && isdir=:+    if $isdir; then+      destdir=$dest+      destname=+    else+      func_dirname_and_basename "$dest" "" "."+      destdir=$func_dirname_result+      destname=$func_basename_result++      # Not a directory, so check to see that there is only one file specified.+      set dummy $files; shift+      test "$#" -gt 1 && \+	func_fatal_help "'$dest' is not a directory"+    fi+    case $destdir in+    [\\/]* | [A-Za-z]:[\\/]*) ;;+    *)+      for file in $files; do+	case $file in+	*.lo) ;;+	*)+	  func_fatal_help "'$destdir' must be an absolute directory name"+	  ;;+	esac+      done+      ;;+    esac++    # This variable tells wrapper scripts just to set variables rather+    # than running their programs.+    libtool_install_magic=$magic++    staticlibs=+    future_libdirs=+    current_libdirs=+    for file in $files; do++      # Do each installation.+      case $file in+      *.$libext)+	# Do the static libraries later.+	func_append staticlibs " $file"+	;;++      *.la)+	func_resolve_sysroot "$file"+	file=$func_resolve_sysroot_result++	# Check to see that this really is a libtool archive.+	func_lalib_unsafe_p "$file" \+	  || func_fatal_help "'$file' is not a valid libtool archive"++	library_names=+	old_library=+	relink_command=+	func_source "$file"++	# Add the libdir to current_libdirs if it is the destination.+	if test "X$destdir" = "X$libdir"; then+	  case "$current_libdirs " in+	  *" $libdir "*) ;;+	  *) func_append current_libdirs " $libdir" ;;+	  esac+	else+	  # Note the libdir as a future libdir.+	  case "$future_libdirs " in+	  *" $libdir "*) ;;+	  *) func_append future_libdirs " $libdir" ;;+	  esac+	fi++	func_dirname "$file" "/" ""+	dir=$func_dirname_result+	func_append dir "$objdir"++	if test -n "$relink_command"; then+	  # Strip any trailing slash from the destination.+	  func_stripname '' '/' "$libdir"+	  destlibdir=$func_stripname_result++	  func_stripname '' '/' "$destdir"+	  s_destdir=$func_stripname_result++	  # Determine the prefix the user has applied to our future dir.+	  inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"`++	  # Don't allow the user to place us outside of our expected+	  # location b/c this prevents finding dependent libraries that+	  # are installed to the same prefix.+	  # At present, this check doesn't affect windows .dll's that+	  # are installed into $libdir/../bin (currently, that works fine)+	  # but it's something to keep an eye on.+	  test "$inst_prefix_dir" = "$destdir" && \+	    func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"++	  if test -n "$inst_prefix_dir"; then+	    # Stick the inst_prefix_dir data into the link command.+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`+	  else+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`+	  fi++	  func_warning "relinking '$file'"+	  func_show_eval "$relink_command" \+	    'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'+	fi++	# See the names of the shared library.+	set dummy $library_names; shift+	if test -n "$1"; then+	  realname=$1+	  shift++	  srcname=$realname+	  test -n "$relink_command" && srcname=${realname}T++	  # Install the shared library and build the symlinks.+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \+	      'exit $?'+	  tstripme=$stripme+	  case $host_os in+	  cygwin* | mingw* | windows* | pw32* | cegcc*)+	    case $realname in+	    *.dll.a)+	      tstripme=+	      ;;+	    esac+	    ;;+	  os2*)+	    case $realname in+	    *_dll.a)+	      tstripme=+	      ;;+	    esac+	    ;;+	  esac+	  if test -n "$tstripme" && test -n "$striplib"; then+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'+	  fi++	  if test "$#" -gt 0; then+	    # Delete the old symlinks, and create new ones.+	    # Try 'ln -sf' first, because the 'ln' binary might depend on+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,+	    # so we also need to try rm && ln -s.+	    for linkname+	    do+	      test "$linkname" != "$realname" \+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"+	    done+	  fi++	  # Do each command in the postinstall commands.+	  lib=$destdir/$realname+	  func_execute_cmds "$postinstall_cmds" 'exit $?'+	fi++	# Install the pseudo-library for information purposes.+	func_basename "$file"+	name=$func_basename_result+	instname=$dir/${name}i+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'++	# Maybe install the static library, too.+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"+	;;++      *.lo)+	# Install (i.e. copy) a libtool object.++	# Figure out destination file name, if it wasn't already specified.+	if test -n "$destname"; then+	  destfile=$destdir/$destname+	else+	  func_basename "$file"+	  destfile=$func_basename_result+	  destfile=$destdir/$destfile+	fi++	# Deduce the name of the destination old-style object file.+	case $destfile in+	*.lo)+	  func_lo2o "$destfile"+	  staticdest=$func_lo2o_result+	  ;;+	*.$objext)+	  staticdest=$destfile+	  destfile=+	  ;;+	*)+	  func_fatal_help "cannot copy a libtool object to '$destfile'"+	  ;;+	esac++	# Install the libtool object if requested.+	test -n "$destfile" && \+	  func_show_eval "$install_prog $file $destfile" 'exit $?'++	# Install the old object if enabled.+	if test yes = "$build_old_libs"; then+	  # Deduce the name of the old-style object file.+	  func_lo2o "$file"+	  staticobj=$func_lo2o_result+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'+	fi+	exit $EXIT_SUCCESS+	;;++      *)+	# Figure out destination file name, if it wasn't already specified.+	if test -n "$destname"; then+	  destfile=$destdir/$destname+	else+	  func_basename "$file"+	  destfile=$func_basename_result+	  destfile=$destdir/$destfile+	fi++	# If the file is missing, and there is a .exe on the end, strip it+	# because it is most likely a libtool script we actually want to+	# install+	stripped_ext=+	case $file in+	  *.exe)+	    if test ! -f "$file"; then+	      func_stripname '' '.exe' "$file"+	      file=$func_stripname_result+	      stripped_ext=.exe+	    fi+	    ;;+	esac++	# Do a test to see if this is really a libtool program.+	case $host in+	*cygwin* | *mingw* | *windows*)+	    if func_ltwrapper_executable_p "$file"; then+	      func_ltwrapper_scriptname "$file"+	      wrapper=$func_ltwrapper_scriptname_result+	    else+	      func_stripname '' '.exe' "$file"+	      wrapper=$func_stripname_result+	    fi+	    ;;+	*)+	    wrapper=$file+	    ;;+	esac+	if func_ltwrapper_script_p "$wrapper"; then+	  notinst_deplibs=+	  relink_command=++	  func_source "$wrapper"++	  # Check the variables that should have been set.+	  test -z "$generated_by_libtool_version" && \+	    func_fatal_error "invalid libtool wrapper script '$wrapper'"++	  finalize=:+	  for lib in $notinst_deplibs; do+	    # Check to see that each library is installed.+	    libdir=+	    if test -f "$lib"; then+	      func_source "$lib"+	    fi+	    libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`+	    if test -n "$libdir" && test ! -f "$libfile"; then+	      func_warning "'$lib' has not been installed in '$libdir'"+	      finalize=false+	    fi+	  done++	  relink_command=+	  func_source "$wrapper"++	  outputname=+	  if test no = "$fast_install" && test -n "$relink_command"; then+	    $opt_dry_run || {+	      if $finalize; then+	        tmpdir=`func_mktempdir`+		func_basename "$file$stripped_ext"+		file=$func_basename_result+	        outputname=$tmpdir/$file+	        # Replace the output file specification.+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`++	        $opt_quiet || {+	          func_quote_arg expand,pretty "$relink_command"+		  eval "func_echo $func_quote_arg_result"+	        }+	        if eval "$relink_command"; then :+	          else+		  func_error "error: relink '$file' with the above command before installing it"+		  $opt_dry_run || ${RM}r "$tmpdir"+		  continue+	        fi+	        file=$outputname+	      else+	        func_warning "cannot relink '$file'"+	      fi+	    }+	  else+	    # Install the binary that we compiled earlier.+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`+	  fi+	fi++	# remove .exe since cygwin /usr/bin/install will append another+	# one anyway+	case $install_prog,$host in+	*/usr/bin/install*,*cygwin*)+	  case $file:$destfile in+	  *.exe:*.exe)+	    # this is ok+	    ;;+	  *.exe:*)+	    destfile=$destfile.exe+	    ;;+	  *:*.exe)+	    func_stripname '' '.exe' "$destfile"+	    destfile=$func_stripname_result+	    ;;+	  esac+	  ;;+	esac+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'+	$opt_dry_run || if test -n "$outputname"; then+	  ${RM}r "$tmpdir"+	fi+	;;+      esac+    done++    for file in $staticlibs; do+      func_basename "$file"+      name=$func_basename_result++      # Set up the ranlib parameters.+      oldlib=$destdir/$name+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32+      tool_oldlib=$func_to_tool_file_result++      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'++      if test -n "$stripme" && test -n "$old_striplib"; then+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'+      fi++      # Do each command in the postinstall commands.+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'+    done++    test -n "$future_libdirs" && \+      func_warning "remember to run '$progname --finish$future_libdirs'"++    if test -n "$current_libdirs"; then+      # Maybe just do a dry run.+      $opt_dry_run && current_libdirs=" -n$current_libdirs"+      exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'+    else+      exit $EXIT_SUCCESS+    fi+}++test install = "$opt_mode" && func_mode_install ${1+"$@"}+++# func_generate_dlsyms outputname originator pic_p+# Extract symbols from dlprefiles and create ${outputname}S.o with+# a dlpreopen symbol table.+func_generate_dlsyms ()+{+    $debug_cmd++    my_outputname=$1+    my_originator=$2+    my_pic_p=${3-false}+    my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`+    my_dlsyms=++    if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then+      if test -n "$NM" && test -n "$global_symbol_pipe"; then+	my_dlsyms=${my_outputname}S.c+      else+	func_error "not configured to extract global symbols from dlpreopened files"+      fi+    fi++    if test -n "$my_dlsyms"; then+      case $my_dlsyms in+      "") ;;+      *.c)+	# Discover the nlist of each of the dlfiles.+	nlist=$output_objdir/$my_outputname.nm++	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"++	# Parse the name list into a source file.+	func_verbose "creating $output_objdir/$my_dlsyms"++	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */++#ifdef __cplusplus+extern \"C\" {+#endif++#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"+#endif++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE+/* DATA imports from DLLs on WIN32 can't be const, because runtime+   relocations are performed -- see ld's documentation on pseudo-relocs.  */+# define LT_DLSYM_CONST+#elif defined __osf__+/* This system does not cope well with relocations in const data.  */+# define LT_DLSYM_CONST+#else+# define LT_DLSYM_CONST const+#endif++#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)++/* External symbol declarations for the compiler. */\+"++	if test yes = "$dlself"; then+	  func_verbose "generating symbol list for '$output'"++	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"++	  # Add our own program objects to the symbol list.+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`+	  for progfile in $progfiles; do+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32+	    func_verbose "extracting global C symbols from '$func_to_tool_file_result'"+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"+	  done++	  if test -n "$exclude_expsyms"; then+	    $opt_dry_run || {+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'+	      eval '$MV "$nlist"T "$nlist"'+	    }+	  fi++	  if test -n "$export_symbols_regex"; then+	    $opt_dry_run || {+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'+	      eval '$MV "$nlist"T "$nlist"'+	    }+	  fi++	  # Prepare the list of exported symbols+	  if test -z "$export_symbols"; then+	    export_symbols=$output_objdir/$outputname.exp+	    $opt_dry_run || {+	      $RM $export_symbols+	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'+	      case $host in+	      *cygwin* | *mingw* | *windows* | *cegcc* )+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'+	        ;;+	      esac+	    }+	  else+	    $opt_dry_run || {+	      eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'+	      eval '$MV "$nlist"T "$nlist"'+	      case $host in+	        *cygwin* | *mingw* | *windows* | *cegcc* )+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'+	          ;;+	      esac+	    }+	  fi+	fi++	for dlprefile in $dlprefiles; do+	  func_verbose "extracting global C symbols from '$dlprefile'"+	  func_basename "$dlprefile"+	  name=$func_basename_result+          case $host in+	    *cygwin* | *mingw* | *windows* | *cegcc* )+	      # if an import library, we need to obtain dlname+	      if func_win32_import_lib_p "$dlprefile"; then+	        func_tr_sh "$dlprefile"+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"+	        dlprefile_dlbasename=+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then+	          # Use subshell, to avoid clobbering current variable values+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`+	          if test -n "$dlprefile_dlname"; then+	            func_basename "$dlprefile_dlname"+	            dlprefile_dlbasename=$func_basename_result+	          else+	            # no lafile. user explicitly requested -dlpreopen <import library>.+	            $sharedlib_from_linklib_cmd "$dlprefile"+	            dlprefile_dlbasename=$sharedlib_from_linklib_result+	          fi+	        fi+	        $opt_dry_run || {+	          if test -n "$dlprefile_dlbasename"; then+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'+	          else+	            func_warning "Could not compute DLL name from $name"+	            eval '$ECHO ": $name " >> "$nlist"'+	          fi+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32+	          case $host in+	            i[3456]86-*-mingw32*)+	              eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |+	                $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"+	            ;;+	            *)+	              eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |+	                $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/__nm_//' >> '$nlist'"+	            ;;+	          esac+	        }+	      else # not an import lib+	        $opt_dry_run || {+	          eval '$ECHO ": $name " >> "$nlist"'+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"+	        }+	      fi+	    ;;+	    *)+	      $opt_dry_run || {+	        eval '$ECHO ": $name " >> "$nlist"'+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"+	      }+	    ;;+          esac+	done++	$opt_dry_run || {+	  # Make sure we have at least an empty file.+	  test -f "$nlist" || : > "$nlist"++	  if test -n "$exclude_expsyms"; then+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T+	    $MV "$nlist"T "$nlist"+	  fi++	  # Try sorting and uniquifying the output.+	  if $GREP -v "^: " < "$nlist" |+	      if sort -k 3 </dev/null >/dev/null 2>&1; then+		sort -k 3+	      else+		sort +2+	      fi |+	      uniq > "$nlist"S; then+	    :+	  else+	    $GREP -v "^: " < "$nlist" > "$nlist"S+	  fi++	  if test -f "$nlist"S; then+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'+	  else+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"+	  fi++	  func_show_eval '$RM "${nlist}I"'+	  if test -n "$global_symbol_to_import"; then+	    eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'+	  fi++	  echo >> "$output_objdir/$my_dlsyms" "\++/* The mapping between symbol names and symbols.  */+typedef struct {+  const char *name;+  void *address;+} lt_dlsymlist;+extern LT_DLSYM_CONST lt_dlsymlist+lt_${my_prefix}_LTX_preloaded_symbols[];\+"++	  if test -s "$nlist"I; then+	    echo >> "$output_objdir/$my_dlsyms" "\+static void lt_syminit(void)+{+  LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;+  for (; symbol->name; ++symbol)+    {"+	    $SED 's/.*/      if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"+	    echo >> "$output_objdir/$my_dlsyms" "\+    }+}"+	  fi+	  echo >> "$output_objdir/$my_dlsyms" "\+LT_DLSYM_CONST lt_dlsymlist+lt_${my_prefix}_LTX_preloaded_symbols[] =+{ {\"$my_originator\", (void *) 0},"++	  if test -s "$nlist"I; then+	    echo >> "$output_objdir/$my_dlsyms" "\+  {\"@INIT@\", (void *) &lt_syminit},"+	  fi++	  case $need_lib_prefix in+	  no)+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"+	    ;;+	  *)+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"+	    ;;+	  esac+	  echo >> "$output_objdir/$my_dlsyms" "\+  {0, (void *) 0}+};++/* This works around a problem in FreeBSD linker */+#ifdef FREEBSD_WORKAROUND+static const void *lt_preloaded_setup() {+  return lt_${my_prefix}_LTX_preloaded_symbols;+}+#endif++#ifdef __cplusplus+}+#endif\+"+	} # !$opt_dry_run++	pic_flag_for_symtable=+	case "$compile_command " in+	*" -static "*) ;;+	*)+	  case $host in+	  # compiling the symbol table file with pic_flag works around+	  # a FreeBSD bug that causes programs to crash when -lm is+	  # linked before any other PIC object.  But we must not use+	  # pic_flag when linking with -static.  The problem exists in+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;+	  *-*-hpux*)+	    pic_flag_for_symtable=" $pic_flag"  ;;+	  *)+	    $my_pic_p && pic_flag_for_symtable=" $pic_flag"+	    ;;+	  esac+	  ;;+	esac+	symtab_cflags=+	for arg in $LTCFLAGS; do+	  case $arg in+	  -pie | -fpie | -fPIE) ;;+	  *) func_append symtab_cflags " $arg" ;;+	  esac+	done++	# Now compile the dynamic symbol file.+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'++	# Clean up the generated files.+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'++	# Transform the symbol file into the correct name.+	symfileobj=$output_objdir/${my_outputname}S.$objext+	case $host in+	*cygwin* | *mingw* | *windows* | *cegcc* )+	  if test -f "$output_objdir/$my_outputname.def"; then+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`+	  else+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`+	  fi+	  ;;+	*)+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`+	  ;;+	esac+	;;+      *)+	func_fatal_error "unknown suffix for '$my_dlsyms'"+	;;+      esac+    else+      # We keep going just in case the user didn't refer to+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe+      # really was required.++      # Nullify the symbol file.+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`+    fi+}++# func_cygming_gnu_implib_p ARG+# This predicate returns with zero status (TRUE) if+# ARG is a GNU/binutils-style import library. Returns+# with nonzero status (FALSE) otherwise.+func_cygming_gnu_implib_p ()+{+  $debug_cmd++  func_to_tool_file "$1" func_convert_file_msys_to_w32+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`+  test -n "$func_cygming_gnu_implib_tmp"+}++# func_cygming_ms_implib_p ARG+# This predicate returns with zero status (TRUE) if+# ARG is an MS-style import library. Returns+# with nonzero status (FALSE) otherwise.+func_cygming_ms_implib_p ()+{+  $debug_cmd++  func_to_tool_file "$1" func_convert_file_msys_to_w32+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`+  test -n "$func_cygming_ms_implib_tmp"+}++# func_win32_libid arg+# return the library type of file 'arg'+#+# Need a lot of goo to handle *both* DLLs and import libs+# Has to be a shell function in order to 'eat' the argument+# that is supplied when $file_magic_command is called.+# Despite the name, also deal with 64 bit binaries.+func_win32_libid ()+{+  $debug_cmd++  win32_libid_type=unknown+  win32_fileres=`file -L $1 2>/dev/null`+  case $win32_fileres in+  *ar\ archive\ import\ library*) # definitely import+    win32_libid_type="x86 archive import"+    ;;+  *ar\ archive*) # could be an import, or static+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then+      case $nm_interface in+      "MS dumpbin")+	if func_cygming_ms_implib_p "$1" ||+	   func_cygming_gnu_implib_p "$1"+	then+	  win32_nmres=import+	else+	  win32_nmres=+	fi+	;;+      *)+	func_to_tool_file "$1" func_convert_file_msys_to_w32+	win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |+	  $SED -n -e '+	    1,100{+		/ I /{+		    s|.*|import|+		    p+		    q+		}+	    }'`+	;;+      esac+      case $win32_nmres in+      import*)  win32_libid_type="x86 archive import";;+      *)        win32_libid_type="x86 archive static";;+      esac+    fi+    ;;+  *DLL*)+    win32_libid_type="x86 DLL"+    ;;+  *executable*) # but shell scripts are "executable" too...+    case $win32_fileres in+    *MS\ Windows\ PE\ Intel*)+      win32_libid_type="x86 DLL"+      ;;+    esac+    ;;+  esac+  $ECHO "$win32_libid_type"+}++# func_cygming_dll_for_implib ARG+#+# Platform-specific function to extract the+# name of the DLL associated with the specified+# import library ARG.+# Invoked by eval'ing the libtool variable+#    $sharedlib_from_linklib_cmd+# Result is available in the variable+#    $sharedlib_from_linklib_result+func_cygming_dll_for_implib ()+{+  $debug_cmd++  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`+}++# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs+#+# The is the core of a fallback implementation of a+# platform-specific function to extract the name of the+# DLL associated with the specified import library LIBNAME.+#+# SECTION_NAME is either .idata$6 or .idata$7, depending+# on the platform and compiler that created the implib.+#+# Echos the name of the DLL associated with the+# specified import library.+func_cygming_dll_for_implib_fallback_core ()+{+  $debug_cmd++  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |+    $SED '/^Contents of section '"$match_literal"':/{+      # Place marker at beginning of archive member dllname section+      s/.*/====MARK====/+      p+      d+    }+    # These lines can sometimes be longer than 43 characters, but+    # are always uninteresting+    /:[	 ]*file format pe[i]\{,1\}-/d+    /^In archive [^:]*:/d+    # Ensure marker is printed+    /^====MARK====/p+    # Remove all lines with less than 43 characters+    /^.\{43\}/!d+    # From remaining lines, remove first 43 characters+    s/^.\{43\}//' |+    $SED -n '+      # Join marker and all lines until next marker into a single line+      /^====MARK====/ b para+      H+      $ b para+      b+      :para+      x+      s/\n//g+      # Remove the marker+      s/^====MARK====//+      # Remove trailing dots and whitespace+      s/[\. \t]*$//+      # Print+      /./p' |+    # we now have a list, one entry per line, of the stringified+    # contents of the appropriate section of all members of the+    # archive that possess that section. Heuristic: eliminate+    # all those that have a first or second character that is+    # a '.' (that is, objdump's representation of an unprintable+    # character.) This should work for all archives with less than+    # 0x302f exports -- but will fail for DLLs whose name actually+    # begins with a literal '.' or a single character followed by+    # a '.'.+    #+    # Of those that remain, print the first one.+    $SED -e '/^\./d;/^.\./d;q'+}++# func_cygming_dll_for_implib_fallback ARG+# Platform-specific function to extract the+# name of the DLL associated with the specified+# import library ARG.+#+# This fallback implementation is for use when $DLLTOOL+# does not support the --identify-strict option.+# Invoked by eval'ing the libtool variable+#    $sharedlib_from_linklib_cmd+# Result is available in the variable+#    $sharedlib_from_linklib_result+func_cygming_dll_for_implib_fallback ()+{+  $debug_cmd++  if func_cygming_gnu_implib_p "$1"; then+    # binutils import library+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`+  elif func_cygming_ms_implib_p "$1"; then+    # ms-generated import library+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`+  else+    # unknown+    sharedlib_from_linklib_result=+  fi+}+++# func_extract_an_archive dir oldlib+func_extract_an_archive ()+{+    $debug_cmd++    f_ex_an_ar_dir=$1; shift+    f_ex_an_ar_oldlib=$1+    if test yes = "$lock_old_archive_extraction"; then+      lockfile=$f_ex_an_ar_oldlib.lock+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do+	func_echo "Waiting for $lockfile to be removed"+	sleep 2+      done+    fi+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \+		   'stat=$?; rm -f "$lockfile"; exit $stat'+    if test yes = "$lock_old_archive_extraction"; then+      $opt_dry_run || rm -f "$lockfile"+    fi+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then+     :+    else+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"+    fi+}+++# func_extract_archives gentop oldlib ...+func_extract_archives ()+{+    $debug_cmd++    my_gentop=$1; shift+    my_oldlibs=${1+"$@"}+    my_oldobjs=+    my_xlib=+    my_xabs=+    my_xdir=++    for my_xlib in $my_oldlibs; do+      # Extract the objects.+      case $my_xlib in+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;+	*) my_xabs=`pwd`"/$my_xlib" ;;+      esac+      func_basename "$my_xlib"+      my_xlib=$func_basename_result+      my_xlib_u=$my_xlib+      while :; do+        case " $extracted_archives " in+	*" $my_xlib_u "*)+	  func_arith $extracted_serial + 1+	  extracted_serial=$func_arith_result+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;+	*) break ;;+	esac+      done+      extracted_archives="$extracted_archives $my_xlib_u"+      my_xdir=$my_gentop/$my_xlib_u++      func_mkdir_p "$my_xdir"++      case $host in+      *-darwin*)+	func_verbose "Extracting $my_xabs"+	# Do not bother doing anything if just a dry run+	$opt_dry_run || {+	  darwin_orig_dir=`pwd`+	  cd $my_xdir || exit $?+	  darwin_archive=$my_xabs+	  darwin_curdir=`pwd`+	  func_basename "$darwin_archive"+	  darwin_base_archive=$func_basename_result+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`+	  if test -n "$darwin_arches"; then+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`+	    darwin_arch=+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"+	    for darwin_arch in  $darwin_arches; do+	      func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"+	      $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"+	      cd "unfat-$$/$darwin_base_archive-$darwin_arch"+	      func_extract_an_archive "`pwd`" "$darwin_base_archive"+	      cd "$darwin_curdir"+	      $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"+	    done # $darwin_arches+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`+	    darwin_file=+	    darwin_files=+	    for darwin_file in $darwin_filelist; do+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`+	      $LIPO -create -output "$darwin_file" $darwin_files+	    done # $darwin_filelist+	    $RM -rf unfat-$$+	    cd "$darwin_orig_dir"+	  else+	    cd $darwin_orig_dir+	    func_extract_an_archive "$my_xdir" "$my_xabs"+	  fi # $darwin_arches+	} # !$opt_dry_run+	;;+      *)+        func_extract_an_archive "$my_xdir" "$my_xabs"+	;;+      esac+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`+    done++    func_extract_archives_result=$my_oldobjs+}+++# func_emit_wrapper [arg=no]+#+# Emit a libtool wrapper script on stdout.+# Don't directly open a file because we may want to+# incorporate the script contents within a cygwin/mingw/windows+# wrapper executable.  Must ONLY be called from within+# func_mode_link because it depends on a number of variables+# set therein.+#+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR+# variable will take.  If 'yes', then the emitted script+# will assume that the directory where it is stored is+# the $objdir directory.  This is a cygwin/mingw/windows-specific+# behavior.+func_emit_wrapper ()+{+	func_emit_wrapper_arg1=${1-no}++	$ECHO "\+#! $SHELL++# $output - temporary wrapper script for $objdir/$outputname+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION+#+# The $output program cannot be directly executed until all the libtool+# libraries that it depends on are installed.+#+# This wrapper script should never be moved out of the build directory.+# If it is, it will not operate correctly.++# Sed substitution that helps us do robust quoting.  It backslashifies+# metacharacters that are still active within double-quoted strings.+sed_quote_subst='$sed_quote_subst'++# Be Bourne compatible+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then+  emulate sh+  NULLCMD=:+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '\${1+\"\$@\"}'='\"\$@\"'+  setopt NO_GLOB_SUBST+else+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac+fi+BIN_SH=xpg4; export BIN_SH # for Tru64+DUALCASE=1; export DUALCASE # for MKS sh++# The HP-UX ksh and POSIX shell print the target directory to stdout+# if CDPATH is set.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH++relink_command=\"$relink_command\"++# This environment variable determines our operation mode.+if test \"\$libtool_install_magic\" = \"$magic\"; then+  # install mode needs the following variables:+  generated_by_libtool_version='$macro_version'+  notinst_deplibs='$notinst_deplibs'+else+  # When we are sourced in execute mode, \$file and \$ECHO are already set.+  if test \"\$libtool_execute_magic\" != \"$magic\"; then+    file=\"\$0\""++    func_quote_arg pretty "$ECHO"+    qECHO=$func_quote_arg_result+    $ECHO "\++# A function that is used when there is no print builtin or printf.+func_fallback_echo ()+{+  eval 'cat <<_LTECHO_EOF+\$1+_LTECHO_EOF'+}+    ECHO=$qECHO+  fi++# Very basic option parsing. These options are (a) specific to+# the libtool wrapper, (b) are identical between the wrapper+# /script/ and the wrapper /executable/ that is used only on+# windows platforms, and (c) all begin with the string "--lt-"+# (application programs are unlikely to have options that match+# this pattern).+#+# There are only two supported options: --lt-debug and+# --lt-dump-script. There is, deliberately, no --lt-help.+#+# The first argument to this parsing function should be the+# script's $0 value, followed by "$@".+lt_option_debug=+func_parse_lt_options ()+{+  lt_script_arg0=\$0+  shift+  for lt_opt+  do+    case \"\$lt_opt\" in+    --lt-debug) lt_option_debug=1 ;;+    --lt-dump-script)+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`+        cat \"\$lt_dump_D/\$lt_dump_F\"+        exit 0+      ;;+    --lt-*)+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2+        exit 1+      ;;+    esac+  done++  # Print the debug banner immediately:+  if test -n \"\$lt_option_debug\"; then+    echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2+  fi+}++# Used when --lt-debug. Prints its arguments to stdout+# (redirection is the responsibility of the caller)+func_lt_dump_args ()+{+  lt_dump_args_N=1;+  for lt_arg+  do+    \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`+  done+}++# Core function for launching the target application+func_exec_program_core ()+{+"+  case $host in+  # Backslashes separate directories on plain windows+  *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*)+    $ECHO "\+      if test -n \"\$lt_option_debug\"; then+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2+        func_lt_dump_args \${1+\"\$@\"} 1>&2+      fi+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}+"+    ;;++  *)+    $ECHO "\+      if test -n \"\$lt_option_debug\"; then+        \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2+        func_lt_dump_args \${1+\"\$@\"} 1>&2+      fi+      exec \"\$progdir/\$program\" \${1+\"\$@\"}+"+    ;;+  esac+  $ECHO "\+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2+      exit 1+}++# A function to encapsulate launching the target application+# Strips options in the --lt-* namespace from \$@ and+# launches target application with the remaining arguments.+func_exec_program ()+{+  case \" \$* \" in+  *\\ --lt-*)+    for lt_wr_arg+    do+      case \$lt_wr_arg in+      --lt-*) ;;+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;+      esac+      shift+    done ;;+  esac+  func_exec_program_core \${1+\"\$@\"}+}++  # Parse options+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}++  # Find the directory that this script lives in.+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.++  # Follow symbolic links until we get to the real thisdir.+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`+  while test -n \"\$file\"; do+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`++    # If there was a directory component, then change thisdir.+    if test \"x\$destdir\" != \"x\$file\"; then+      case \"\$destdir\" in+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;+      *) thisdir=\"\$thisdir/\$destdir\" ;;+      esac+    fi++    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`+  done++  # Usually 'no', except on cygwin/mingw/windows when embedded into+  # the cwrapper.+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then+    # special case for '.'+    if test \"\$thisdir\" = \".\"; then+      thisdir=\`pwd\`+    fi+    # remove .libs from thisdir+    case \"\$thisdir\" in+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;+    $objdir )   thisdir=. ;;+    esac+  fi++  # Try to get the absolute directory name.+  absdir=\`cd \"\$thisdir\" && pwd\`+  test -n \"\$absdir\" && thisdir=\"\$absdir\"+"++	if test yes = "$fast_install"; then+	  $ECHO "\+  program=lt-'$outputname'$exeext+  progdir=\"\$thisdir/$objdir\"++  if test ! -f \"\$progdir/\$program\" ||+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then++    file=\"\$\$-\$program\"++    if test ! -d \"\$progdir\"; then+      $MKDIR \"\$progdir\"+    else+      $RM \"\$progdir/\$file\"+    fi"++	  $ECHO "\++    # relink executable if necessary+    if test -n \"\$relink_command\"; then+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :+      else+	\$ECHO \"\$relink_command_output\" >&2+	$RM \"\$progdir/\$file\"+	exit 1+      fi+    fi++    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||+    { $RM \"\$progdir/\$program\";+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }+    $RM \"\$progdir/\$file\"+  fi"+	else+	  $ECHO "\+  program='$outputname'+  progdir=\"\$thisdir/$objdir\"+"+	fi++	$ECHO "\++  if test -f \"\$progdir/\$program\"; then"++	# fixup the dll searchpath if we need to.+	#+	# Fix the DLL searchpath if we need to.  Do this before prepending+	# to shlibpath, because on Windows, both are PATH and uninstalled+	# libraries must come first.+	if test -n "$dllsearchpath"; then+	  $ECHO "\+    # Add the dll search path components to the executable PATH+    PATH=$dllsearchpath:\$PATH+"+	fi++	# Export our shlibpath_var if we have one.+	if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then+	  $ECHO "\+    # Add our own library path to $shlibpath_var+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"++    # Some systems cannot cope with colon-terminated $shlibpath_var+    # The second colon is a workaround for a bug in BeOS R4 sed+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`++    export $shlibpath_var+"+	fi++	$ECHO "\+    if test \"\$libtool_execute_magic\" != \"$magic\"; then+      # Run the actual program with our arguments.+      func_exec_program \${1+\"\$@\"}+    fi+  else+    # The program doesn't exist.+    \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2+    exit 1+  fi+fi\+"+}+++# func_emit_cwrapperexe_src+# emit the source code for a wrapper executable on stdout+# Must ONLY be called from within func_mode_link because+# it depends on a number of variable set therein.+func_emit_cwrapperexe_src ()+{+	cat <<EOF++/* $cwrappersource - temporary wrapper executable for $objdir/$outputname+   Generated by $PROGRAM (GNU $PACKAGE) $VERSION++   The $output program cannot be directly executed until all the libtool+   libraries that it depends on are installed.++   This wrapper executable should never be moved out of the build directory.+   If it is, it will not operate correctly.+*/+EOF+	    cat <<"EOF"+#ifdef _MSC_VER+# define _CRT_SECURE_NO_DEPRECATE 1+#endif+#include <stdio.h>+#include <stdlib.h>+#if defined _WIN32 && !defined __GNUC__+# include <direct.h>+# include <process.h>+# include <io.h>+#else+# include <unistd.h>+# include <stdint.h>+# ifdef __CYGWIN__+#  include <io.h>+# endif+#endif+#include <malloc.h>+#include <stdarg.h>+#include <assert.h>+#include <string.h>+#include <ctype.h>+#include <errno.h>+#include <fcntl.h>+#include <sys/stat.h>++#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)++/* declarations of non-ANSI functions */+#if defined __MINGW32__+# ifdef __STRICT_ANSI__+_CRTIMP int __cdecl _putenv (const char *);+# endif+#elif defined __CYGWIN__+# ifdef __STRICT_ANSI__+char *realpath (const char *, char *);+int putenv (char *);+int setenv (const char *, const char *, int);+# endif+/* #elif defined other_platform || defined ... */+#endif++/* portability defines, excluding path handling macros */+#if defined _MSC_VER+# define setmode _setmode+# define stat    _stat+# define chmod   _chmod+# define getcwd  _getcwd+# define putenv  _putenv+# define S_IXUSR _S_IEXEC+#elif defined __MINGW32__+# define setmode _setmode+# define stat    _stat+# define chmod   _chmod+# define getcwd  _getcwd+# define putenv  _putenv+#elif defined __CYGWIN__+# define HAVE_SETENV+# define FOPEN_WB "wb"+/* #elif defined other platforms ... */+#endif++#if defined PATH_MAX+# define LT_PATHMAX PATH_MAX+#elif defined MAXPATHLEN+# define LT_PATHMAX MAXPATHLEN+#else+# define LT_PATHMAX 1024+#endif++#ifndef S_IXOTH+# define S_IXOTH 0+#endif+#ifndef S_IXGRP+# define S_IXGRP 0+#endif++/* path handling portability macros */+#ifndef DIR_SEPARATOR+# define DIR_SEPARATOR '/'+# define PATH_SEPARATOR ':'+#endif++#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \+  defined __OS2__+# define HAVE_DOS_BASED_FILE_SYSTEM+# define FOPEN_WB "wb"+# ifndef DIR_SEPARATOR_2+#  define DIR_SEPARATOR_2 '\\'+# endif+# ifndef PATH_SEPARATOR_2+#  define PATH_SEPARATOR_2 ';'+# endif+#endif++#ifndef DIR_SEPARATOR_2+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)+#else /* DIR_SEPARATOR_2 */+# define IS_DIR_SEPARATOR(ch) \+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))+#endif /* DIR_SEPARATOR_2 */++#ifndef PATH_SEPARATOR_2+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)+#else /* PATH_SEPARATOR_2 */+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)+#endif /* PATH_SEPARATOR_2 */++#ifndef FOPEN_WB+# define FOPEN_WB "w"+#endif+#ifndef _O_BINARY+# define _O_BINARY 0+#endif++#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))+#define XFREE(stale) do { \+  if (stale) { free (stale); stale = 0; } \+} while (0)++#if defined LT_DEBUGWRAPPER+static int lt_debug = 1;+#else+static int lt_debug = 0;+#endif++const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */++void *xmalloc (size_t num);+char *xstrdup (const char *string);+const char *base_name (const char *name);+char *find_executable (const char *wrapper);+char *chase_symlinks (const char *pathspec);+int make_executable (const char *path);+int check_executable (const char *path);+char *strendzap (char *str, const char *pat);+void lt_debugprintf (const char *file, int line, const char *fmt, ...);+void lt_fatal (const char *file, int line, const char *message, ...);+static const char *nonnull (const char *s);+static const char *nonempty (const char *s);+void lt_setenv (const char *name, const char *value);+char *lt_extend_str (const char *orig_value, const char *add, int to_end);+void lt_update_exe_path (const char *name, const char *value);+void lt_update_lib_path (const char *name, const char *value);+char **prepare_spawn (char **argv);+void lt_dump_script (FILE *f);+EOF++	    cat <<EOF+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)+# define externally_visible volatile+#else+# define externally_visible __attribute__((externally_visible)) volatile+#endif+externally_visible const char * MAGIC_EXE = "$magic_exe";+const char * LIB_PATH_VARNAME = "$shlibpath_var";+EOF++	    if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then+              func_to_host_path "$temp_rpath"+	      cat <<EOF+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";+EOF+	    else+	      cat <<"EOF"+const char * LIB_PATH_VALUE   = "";+EOF+	    fi++	    if test -n "$dllsearchpath"; then+              func_to_host_path "$dllsearchpath:"+	      cat <<EOF+const char * EXE_PATH_VARNAME = "PATH";+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";+EOF+	    else+	      cat <<"EOF"+const char * EXE_PATH_VARNAME = "";+const char * EXE_PATH_VALUE   = "";+EOF+	    fi++	    if test yes = "$fast_install"; then+	      cat <<EOF+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */+EOF+	    else+	      cat <<EOF+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */+EOF+	    fi+++	    cat <<"EOF"++#define LTWRAPPER_OPTION_PREFIX         "--lt-"++static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";++int+main (int argc, char *argv[])+{+  char **newargz;+  int  newargc;+  char *tmp_pathspec;+  char *actual_cwrapper_path;+  char *actual_cwrapper_name;+  char *target_name;+  char *lt_argv_zero;+  int rval = 127;++  int i;++  program_name = (char *) xstrdup (base_name (argv[0]));+  newargz = XMALLOC (char *, (size_t) argc + 1);++  /* very simple arg parsing; don't want to rely on getopt+   * also, copy all non cwrapper options to newargz, except+   * argz[0], which is handled differently+   */+  newargc=0;+  for (i = 1; i < argc; i++)+    {+      if (STREQ (argv[i], dumpscript_opt))+	{+EOF+	    case $host in+	      *mingw* | *windows* | *cygwin* )+		# make stdout use "unix" line endings+		echo "          setmode(1,_O_BINARY);"+		;;+	      esac++	    cat <<"EOF"+	  lt_dump_script (stdout);+	  return 0;+	}+      if (STREQ (argv[i], debug_opt))+	{+          lt_debug = 1;+          continue;+	}+      if (STREQ (argv[i], ltwrapper_option_prefix))+        {+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX+             namespace, but it is not one of the ones we know about and+             have already dealt with, above (including dump-script), then+             report an error. Otherwise, targets might begin to believe+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX+             namespace. The first time any user complains about this, we'll+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option+             or a configure.ac-settable value.+           */+          lt_fatal (__FILE__, __LINE__,+		    "unrecognized %s option: '%s'",+                    ltwrapper_option_prefix, argv[i]);+        }+      /* otherwise ... */+      newargz[++newargc] = xstrdup (argv[i]);+    }+  newargz[++newargc] = NULL;++EOF+	    cat <<EOF+  /* The GNU banner must be the first non-error debug message */+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");+EOF+	    cat <<"EOF"+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);++  tmp_pathspec = find_executable (argv[0]);+  if (tmp_pathspec == NULL)+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);+  lt_debugprintf (__FILE__, __LINE__,+                  "(main) found exe (before symlink chase) at: %s\n",+		  tmp_pathspec);++  actual_cwrapper_path = chase_symlinks (tmp_pathspec);+  lt_debugprintf (__FILE__, __LINE__,+                  "(main) found exe (after symlink chase) at: %s\n",+		  actual_cwrapper_path);+  XFREE (tmp_pathspec);++  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));+  strendzap (actual_cwrapper_path, actual_cwrapper_name);++  /* wrapper name transforms */+  strendzap (actual_cwrapper_name, ".exe");+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);+  XFREE (actual_cwrapper_name);+  actual_cwrapper_name = tmp_pathspec;+  tmp_pathspec = 0;++  /* target_name transforms -- use actual target program name; might have lt- prefix */+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));+  strendzap (target_name, ".exe");+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);+  XFREE (target_name);+  target_name = tmp_pathspec;+  tmp_pathspec = 0;++  lt_debugprintf (__FILE__, __LINE__,+		  "(main) libtool target name: %s\n",+		  target_name);+EOF++	    cat <<EOF+  newargz[0] =+    XMALLOC (char, (strlen (actual_cwrapper_path) ++		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));+  strcpy (newargz[0], actual_cwrapper_path);+  strcat (newargz[0], "$objdir");+  strcat (newargz[0], "/");+EOF++	    cat <<"EOF"+  /* stop here, and copy so we don't have to do this twice */+  tmp_pathspec = xstrdup (newargz[0]);++  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */+  strcat (newargz[0], actual_cwrapper_name);++  /* DO want the lt- prefix here if it exists, so use target_name */+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);+  XFREE (tmp_pathspec);+  tmp_pathspec = NULL;+EOF++	    case $host_os in+	      mingw* | windows*)+	    cat <<"EOF"+  {+    char* p;+    while ((p = strchr (newargz[0], '\\')) != NULL)+      {+	*p = '/';+      }+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)+      {+	*p = '/';+      }+  }+EOF+	    ;;+	    esac++	    cat <<"EOF"+  XFREE (target_name);+  XFREE (actual_cwrapper_path);+  XFREE (actual_cwrapper_name);++  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)+     because on Windows, both *_VARNAMEs are PATH but uninstalled+     libraries must come first. */+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);++  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",+		  nonnull (lt_argv_zero));+  for (i = 0; i < newargc; i++)+    {+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",+		      i, nonnull (newargz[i]));+    }++EOF++	    case $host_os in+	      mingw* | windows*)+		cat <<"EOF"+  /* execv doesn't actually work on mingw as expected on unix */+  newargz = prepare_spawn (newargz);+  rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);+  if (rval == -1)+    {+      /* failed to start process */+      lt_debugprintf (__FILE__, __LINE__,+		      "(main) failed to launch target \"%s\": %s\n",+		      lt_argv_zero, nonnull (strerror (errno)));+      return 127;+    }+  return rval;+EOF+		;;+	      *)+		cat <<"EOF"+  execv (lt_argv_zero, newargz);+  return rval; /* =127, but avoids unused variable warning */+EOF+		;;+	    esac++	    cat <<"EOF"+}++void *+xmalloc (size_t num)+{+  void *p = (void *) malloc (num);+  if (!p)+    lt_fatal (__FILE__, __LINE__, "memory exhausted");++  return p;+}++char *+xstrdup (const char *string)+{+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),+			  string) : NULL;+}++const char *+base_name (const char *name)+{+  const char *base;++#if defined HAVE_DOS_BASED_FILE_SYSTEM+  /* Skip over the disk name in MSDOS pathnames. */+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')+    name += 2;+#endif++  for (base = name; *name; name++)+    if (IS_DIR_SEPARATOR (*name))+      base = name + 1;+  return base;+}++int+check_executable (const char *path)+{+  struct stat st;++  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",+                  nonempty (path));+  if ((!path) || (!*path))+    return 0;++  if ((stat (path, &st) >= 0)+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))+    return 1;+  else+    return 0;+}++int+make_executable (const char *path)+{+  int rval = 0;+  struct stat st;++  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",+                  nonempty (path));+  if ((!path) || (!*path))+    return 0;++  if (stat (path, &st) >= 0)+    {+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);+    }+  return rval;+}++/* Searches for the full path of the wrapper.  Returns+   newly allocated full path name if found, NULL otherwise+   Does not chase symlinks, even on platforms that support them.+*/+char *+find_executable (const char *wrapper)+{+  int has_slash = 0;+  const char *p;+  const char *p_next;+  /* static buffer for getcwd */+  char tmp[LT_PATHMAX + 1];+  size_t tmp_len;+  char *concat_name;++  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",+                  nonempty (wrapper));++  if ((wrapper == NULL) || (*wrapper == '\0'))+    return NULL;++  /* Absolute path? */+#if defined HAVE_DOS_BASED_FILE_SYSTEM+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')+    {+      concat_name = xstrdup (wrapper);+      if (check_executable (concat_name))+	return concat_name;+      XFREE (concat_name);+    }+  else+    {+#endif+      if (IS_DIR_SEPARATOR (wrapper[0]))+	{+	  concat_name = xstrdup (wrapper);+	  if (check_executable (concat_name))+	    return concat_name;+	  XFREE (concat_name);+	}+#if defined HAVE_DOS_BASED_FILE_SYSTEM+    }+#endif++  for (p = wrapper; *p; p++)+    if (*p == '/')+      {+	has_slash = 1;+	break;+      }+  if (!has_slash)+    {+      /* no slashes; search PATH */+      const char *path = getenv ("PATH");+      if (path != NULL)+	{+	  for (p = path; *p; p = p_next)+	    {+	      const char *q;+	      size_t p_len;+	      for (q = p; *q; q++)+		if (IS_PATH_SEPARATOR (*q))+		  break;+	      p_len = (size_t) (q - p);+	      p_next = (*q == '\0' ? q : q + 1);+	      if (p_len == 0)+		{+		  /* empty path: current directory */+		  if (getcwd (tmp, LT_PATHMAX) == NULL)+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",+                              nonnull (strerror (errno)));+		  tmp_len = strlen (tmp);+		  concat_name =+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);+		  memcpy (concat_name, tmp, tmp_len);+		  concat_name[tmp_len] = '/';+		  strcpy (concat_name + tmp_len + 1, wrapper);+		}+	      else+		{+		  concat_name =+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);+		  memcpy (concat_name, p, p_len);+		  concat_name[p_len] = '/';+		  strcpy (concat_name + p_len + 1, wrapper);+		}+	      if (check_executable (concat_name))+		return concat_name;+	      XFREE (concat_name);+	    }+	}+      /* not found in PATH; assume curdir */+    }+  /* Relative path | not found in path: prepend cwd */+  if (getcwd (tmp, LT_PATHMAX) == NULL)+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",+              nonnull (strerror (errno)));+  tmp_len = strlen (tmp);+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);+  memcpy (concat_name, tmp, tmp_len);+  concat_name[tmp_len] = '/';+  strcpy (concat_name + tmp_len + 1, wrapper);++  if (check_executable (concat_name))+    return concat_name;+  XFREE (concat_name);+  return NULL;+}++char *+chase_symlinks (const char *pathspec)+{+#ifndef S_ISLNK+  return xstrdup (pathspec);+#else+  char buf[LT_PATHMAX];+  struct stat s;+  char *tmp_pathspec = xstrdup (pathspec);+  char *p;+  int has_symlinks = 0;+  while (strlen (tmp_pathspec) && !has_symlinks)+    {+      lt_debugprintf (__FILE__, __LINE__,+		      "checking path component for symlinks: %s\n",+		      tmp_pathspec);+      if (lstat (tmp_pathspec, &s) == 0)+	{+	  if (S_ISLNK (s.st_mode) != 0)+	    {+	      has_symlinks = 1;+	      break;+	    }++	  /* search backwards for last DIR_SEPARATOR */+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))+	    p--;+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))+	    {+	      /* no more DIR_SEPARATORS left */+	      break;+	    }+	  *p = '\0';+	}+      else+	{+	  lt_fatal (__FILE__, __LINE__,+		    "error accessing file \"%s\": %s",+		    tmp_pathspec, nonnull (strerror (errno)));+	}+    }+  XFREE (tmp_pathspec);++  if (!has_symlinks)+    {+      return xstrdup (pathspec);+    }++  tmp_pathspec = realpath (pathspec, buf);+  if (tmp_pathspec == 0)+    {+      lt_fatal (__FILE__, __LINE__,+		"could not follow symlinks for %s", pathspec);+    }+  return xstrdup (tmp_pathspec);+#endif+}++char *+strendzap (char *str, const char *pat)+{+  size_t len, patlen;++  assert (str != NULL);+  assert (pat != NULL);++  len = strlen (str);+  patlen = strlen (pat);++  if (patlen <= len)+    {+      str += len - patlen;+      if (STREQ (str, pat))+	*str = '\0';+    }+  return str;+}++void+lt_debugprintf (const char *file, int line, const char *fmt, ...)+{+  va_list args;+  if (lt_debug)+    {+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);+      va_start (args, fmt);+      (void) vfprintf (stderr, fmt, args);+      va_end (args);+    }+}++static void+lt_error_core (int exit_status, const char *file,+	       int line, const char *mode,+	       const char *message, va_list ap)+{+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);+  vfprintf (stderr, message, ap);+  fprintf (stderr, ".\n");++  if (exit_status >= 0)+    exit (exit_status);+}++void+lt_fatal (const char *file, int line, const char *message, ...)+{+  va_list ap;+  va_start (ap, message);+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);+  va_end (ap);+}++static const char *+nonnull (const char *s)+{+  return s ? s : "(null)";+}++static const char *+nonempty (const char *s)+{+  return (s && !*s) ? "(empty)" : nonnull (s);+}++void+lt_setenv (const char *name, const char *value)+{+  lt_debugprintf (__FILE__, __LINE__,+		  "(lt_setenv) setting '%s' to '%s'\n",+                  nonnull (name), nonnull (value));+  {+#ifdef HAVE_SETENV+    /* always make a copy, for consistency with !HAVE_SETENV */+    char *str = xstrdup (value);+    setenv (name, str, 1);+#else+    size_t len = strlen (name) + 1 + strlen (value) + 1;+    char *str = XMALLOC (char, len);+    sprintf (str, "%s=%s", name, value);+    if (putenv (str) != EXIT_SUCCESS)+      {+        XFREE (str);+      }+#endif+  }+}++char *+lt_extend_str (const char *orig_value, const char *add, int to_end)+{+  char *new_value;+  if (orig_value && *orig_value)+    {+      size_t orig_value_len = strlen (orig_value);+      size_t add_len = strlen (add);+      new_value = XMALLOC (char, add_len + orig_value_len + 1);+      if (to_end)+        {+          strcpy (new_value, orig_value);+          strcpy (new_value + orig_value_len, add);+        }+      else+        {+          strcpy (new_value, add);+          strcpy (new_value + add_len, orig_value);+        }+    }+  else+    {+      new_value = xstrdup (add);+    }+  return new_value;+}++void+lt_update_exe_path (const char *name, const char *value)+{+  lt_debugprintf (__FILE__, __LINE__,+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",+                  nonnull (name), nonnull (value));++  if (name && *name && value && *value)+    {+      char *new_value = lt_extend_str (getenv (name), value, 0);+      /* some systems can't cope with a ':'-terminated path #' */+      size_t len = strlen (new_value);+      while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))+        {+          new_value[--len] = '\0';+        }+      lt_setenv (name, new_value);+      XFREE (new_value);+    }+}++void+lt_update_lib_path (const char *name, const char *value)+{+  lt_debugprintf (__FILE__, __LINE__,+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",+                  nonnull (name), nonnull (value));++  if (name && *name && value && *value)+    {+      char *new_value = lt_extend_str (getenv (name), value, 0);+      lt_setenv (name, new_value);+      XFREE (new_value);+    }+}++EOF+	    case $host_os in+	      mingw* | windows*)+		cat <<"EOF"++/* Prepares an argument vector before calling spawn().+   Note that spawn() does not by itself call the command interpreter+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);+         GetVersionEx(&v);+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;+      }) ? "cmd.exe" : "command.com").+   Instead it simply concatenates the arguments, separated by ' ', and calls+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a+   special way:+   - Space and tab are interpreted as delimiters. They are not treated as+     delimiters if they are surrounded by double quotes: "...".+   - Unescaped double quotes are removed from the input. Their only effect is+     that within double quotes, space and tab are treated like normal+     characters.+   - Backslashes not followed by double quotes are not special.+   - But 2*n+1 backslashes followed by a double quote become+     n backslashes followed by a double quote (n >= 0):+       \" -> "+       \\\" -> \"+       \\\\\" -> \\"+ */+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"+char **+prepare_spawn (char **argv)+{+  size_t argc;+  char **new_argv;+  size_t i;++  /* Count number of arguments.  */+  for (argc = 0; argv[argc] != NULL; argc++)+    ;++  /* Allocate new argument vector.  */+  new_argv = XMALLOC (char *, argc + 1);++  /* Put quoted arguments into the new argument vector.  */+  for (i = 0; i < argc; i++)+    {+      const char *string = argv[i];++      if (string[0] == '\0')+	new_argv[i] = xstrdup ("\"\"");+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)+	{+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);+	  size_t length;+	  unsigned int backslashes;+	  const char *s;+	  char *quoted_string;+	  char *p;++	  length = 0;+	  backslashes = 0;+	  if (quote_around)+	    length++;+	  for (s = string; *s != '\0'; s++)+	    {+	      char c = *s;+	      if (c == '"')+		length += backslashes + 1;+	      length++;+	      if (c == '\\')+		backslashes++;+	      else+		backslashes = 0;+	    }+	  if (quote_around)+	    length += backslashes + 1;++	  quoted_string = XMALLOC (char, length + 1);++	  p = quoted_string;+	  backslashes = 0;+	  if (quote_around)+	    *p++ = '"';+	  for (s = string; *s != '\0'; s++)+	    {+	      char c = *s;+	      if (c == '"')+		{+		  unsigned int j;+		  for (j = backslashes + 1; j > 0; j--)+		    *p++ = '\\';+		}+	      *p++ = c;+	      if (c == '\\')+		backslashes++;+	      else+		backslashes = 0;+	    }+	  if (quote_around)+	    {+	      unsigned int j;+	      for (j = backslashes; j > 0; j--)+		*p++ = '\\';+	      *p++ = '"';+	    }+	  *p = '\0';++	  new_argv[i] = quoted_string;+	}+      else+	new_argv[i] = (char *) string;+    }+  new_argv[argc] = NULL;++  return new_argv;+}+EOF+		;;+	    esac++            cat <<"EOF"+void lt_dump_script (FILE* f)+{+EOF+	    func_emit_wrapper yes |+	      $SED -n -e '+s/^\(.\{79\}\)\(..*\)/\1\+\2/+h+s/\([\\"]\)/\\\1/g+s/$/\\n/+s/\([^\n]*\).*/  fputs ("\1", f);/p+g+D'+            cat <<"EOF"+}+EOF+}+# end: func_emit_cwrapperexe_src++# func_win32_import_lib_p ARG+# True if ARG is an import lib, as indicated by $file_magic_cmd+func_win32_import_lib_p ()+{+    $debug_cmd++    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in+    *import*) : ;;+    *) false ;;+    esac+}++# func_suncc_cstd_abi+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!+# Several compiler flags select an ABI that is incompatible with the+# Cstd library. Avoid specifying it if any are in CXXFLAGS.+func_suncc_cstd_abi ()+{+    $debug_cmd++    case " $compile_command " in+    *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)+      suncc_use_cstd_abi=no+      ;;+    *)+      suncc_use_cstd_abi=yes+      ;;+    esac+}++# func_mode_link arg...+func_mode_link ()+{+    $debug_cmd++    case $host in+    *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)+      # It is impossible to link a dll without this setting, and+      # we shouldn't force the makefile maintainer to figure out+      # what system we are compiling for in order to pass an extra+      # flag for every libtool invocation.+      # allow_undefined=no++      # FIXME: Unfortunately, there are problems with the above when trying+      # to make a dll that has undefined symbols, in which case not+      # even a static library is built.  For now, we need to specify+      # -no-undefined on the libtool link line when we can be certain+      # that all symbols are satisfied, otherwise we get a static library.+      allow_undefined=yes+      ;;+    *)+      allow_undefined=yes+      ;;+    esac+    libtool_args=$nonopt+    base_compile="$nonopt $@"+    compile_command=$nonopt+    finalize_command=$nonopt++    compile_rpath=+    compile_rpath_tail=+    finalize_rpath=+    compile_shlibpath=+    finalize_shlibpath=+    convenience=+    old_convenience=+    deplibs=+    old_deplibs=+    compiler_flags=+    linker_flags=+    dllsearchpath=+    lib_search_path=`pwd`+    inst_prefix_dir=+    new_inherited_linker_flags=++    avoid_version=no+    bindir=+    dlfiles=+    dlprefiles=+    dlself=no+    export_dynamic=no+    export_symbols=+    export_symbols_regex=+    generated=+    libobjs=+    ltlibs=+    module=no+    no_install=no+    objs=+    os2dllname=+    non_pic_objects=+    precious_files_regex=+    prefer_static_libs=no+    preload=false+    prev=+    prevarg=+    release=+    rpath=+    xrpath=+    perm_rpath=+    temp_rpath=+    temp_rpath_tail=+    thread_safe=no+    vinfo=+    vinfo_number=no+    weak_libs=+    rpath_arg=+    single_module=$wl-single_module+    func_infer_tag $base_compile++    # We need to know -static, to get the right output filenames.+    for arg+    do+      case $arg in+      -shared)+	test yes != "$build_libtool_libs" \+	  && func_fatal_configuration "cannot build a shared library"+	build_old_libs=no+	break+	;;+      -all-static | -static | -static-libtool-libs)+	case $arg in+	-all-static)+	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then+	    func_warning "complete static linking is impossible in this configuration"+	  fi+	  if test -n "$link_static_flag"; then+	    dlopen_self=$dlopen_self_static+	  fi+	  prefer_static_libs=yes+	  ;;+	-static)+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then+	    dlopen_self=$dlopen_self_static+	  fi+	  prefer_static_libs=built+	  ;;+	-static-libtool-libs)+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then+	    dlopen_self=$dlopen_self_static+	  fi+	  prefer_static_libs=yes+	  ;;+	esac+	build_libtool_libs=no+	build_old_libs=yes+	break+	;;+      esac+    done++    # See if our shared archives depend on static archives.+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes++    # Go through the arguments, transforming them on the way.+    while test "$#" -gt 0; do+      arg=$1+      shift+      func_quote_arg pretty,unquoted "$arg"+      qarg=$func_quote_arg_unquoted_result+      func_append libtool_args " $func_quote_arg_result"++      # If the previous option needs an argument, assign it.+      if test -n "$prev"; then+	case $prev in+	output)+	  func_append compile_command " @OUTPUT@"+	  func_append finalize_command " @OUTPUT@"+	  ;;+	esac++	case $prev in+	bindir)+	  bindir=$arg+	  prev=+	  continue+	  ;;+	dlfiles|dlprefiles)+	  $preload || {+	    # Add the symbol object into the linking commands.+	    func_append compile_command " @SYMFILE@"+	    func_append finalize_command " @SYMFILE@"+	    preload=:+	  }+	  case $arg in+	  *.la | *.lo) ;;  # We handle these cases below.+	  force)+	    if test no = "$dlself"; then+	      dlself=needless+	      export_dynamic=yes+	    fi+	    prev=+	    continue+	    ;;+	  self)+	    if test dlprefiles = "$prev"; then+	      dlself=yes+	    elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then+	      dlself=yes+	    else+	      dlself=needless+	      export_dynamic=yes+	    fi+	    prev=+	    continue+	    ;;+	  *)+	    if test dlfiles = "$prev"; then+	      func_append dlfiles " $arg"+	    else+	      func_append dlprefiles " $arg"+	    fi+	    prev=+	    continue+	    ;;+	  esac+	  ;;+	expsyms)+	  export_symbols=$arg+	  test -f "$arg" \+	    || func_fatal_error "symbol file '$arg' does not exist"+	  prev=+	  continue+	  ;;+	expsyms_regex)+	  export_symbols_regex=$arg+	  prev=+	  continue+	  ;;+	framework)+	  case $host in+	    *-*-darwin*)+	      case "$deplibs " in+		*" $qarg.ltframework "*) ;;+		*) func_append deplibs " $qarg.ltframework" # this is fixed later+		   ;;+	      esac+	      ;;+	  esac+	  prev=+	  continue+	  ;;+	inst_prefix)+	  inst_prefix_dir=$arg+	  prev=+	  continue+	  ;;+	mllvm)+	  # Clang does not use LLVM to link, so we can simply discard any+	  # '-mllvm $arg' options when doing the link step.+	  prev=+	  continue+	  ;;+	objectlist)+	  if test -f "$arg"; then+	    save_arg=$arg+	    moreargs=+	    for fil in `cat "$save_arg"`+	    do+#	      func_append moreargs " $fil"+	      arg=$fil+	      # A libtool-controlled object.++	      # Check to see that this really is a libtool object.+	      if func_lalib_unsafe_p "$arg"; then+		pic_object=+		non_pic_object=++		# Read the .lo file+		func_source "$arg"++		if test -z "$pic_object" ||+		   test -z "$non_pic_object" ||+		   test none = "$pic_object" &&+		   test none = "$non_pic_object"; then+		  func_fatal_error "cannot find name of object for '$arg'"+		fi++		# Extract subdirectory from the argument.+		func_dirname "$arg" "/" ""+		xdir=$func_dirname_result++		if test none != "$pic_object"; then+		  # Prepend the subdirectory the object is found in.+		  pic_object=$xdir$pic_object++		  if test dlfiles = "$prev"; then+		    if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then+		      func_append dlfiles " $pic_object"+		      prev=+		      continue+		    else+		      # If libtool objects are unsupported, then we need to preload.+		      prev=dlprefiles+		    fi+		  fi++		  # CHECK ME:  I think I busted this.  -Ossama+		  if test dlprefiles = "$prev"; then+		    # Preload the old-style object.+		    func_append dlprefiles " $pic_object"+		    prev=+		  fi++		  # A PIC object.+		  func_append libobjs " $pic_object"+		  arg=$pic_object+		fi++		# Non-PIC object.+		if test none != "$non_pic_object"; then+		  # Prepend the subdirectory the object is found in.+		  non_pic_object=$xdir$non_pic_object++		  # A standard non-PIC object+		  func_append non_pic_objects " $non_pic_object"+		  if test -z "$pic_object" || test none = "$pic_object"; then+		    arg=$non_pic_object+		  fi+		else+		  # If the PIC object exists, use it instead.+		  # $xdir was prepended to $pic_object above.+		  non_pic_object=$pic_object+		  func_append non_pic_objects " $non_pic_object"+		fi+	      else+		# Only an error if not doing a dry-run.+		if $opt_dry_run; then+		  # Extract subdirectory from the argument.+		  func_dirname "$arg" "/" ""+		  xdir=$func_dirname_result++		  func_lo2o "$arg"+		  pic_object=$xdir$objdir/$func_lo2o_result+		  non_pic_object=$xdir$func_lo2o_result+		  func_append libobjs " $pic_object"+		  func_append non_pic_objects " $non_pic_object"+	        else+		  func_fatal_error "'$arg' is not a valid libtool object"+		fi+	      fi+	    done+	  else+	    func_fatal_error "link input file '$arg' does not exist"+	  fi+	  arg=$save_arg+	  prev=+	  continue+	  ;;+	os2dllname)+	  os2dllname=$arg+	  prev=+	  continue+	  ;;+	precious_regex)+	  precious_files_regex=$arg+	  prev=+	  continue+	  ;;+	release)+	  release=-$arg+	  prev=+	  continue+	  ;;+	rpath | xrpath)+	  # We need an absolute path.+	  case $arg in+	  [\\/]* | [A-Za-z]:[\\/]*) ;;+	  *)+	    func_fatal_error "argument to -rpath is not absolute: $arg"+	    ;;+	  esac+	  if test rpath = "$prev"; then+	    case "$rpath " in+	    *" $arg "*) ;;+	    *) func_append rpath " $arg" ;;+	    esac+	  else+	    case "$xrpath " in+	    *" $arg "*) ;;+	    *) func_append xrpath " $arg" ;;+	    esac+	  fi+	  prev=+	  continue+	  ;;+	shrext)+	  shrext_cmds=$arg+	  prev=+	  continue+	  ;;+	weak)+	  func_append weak_libs " $arg"+	  prev=+	  continue+	  ;;+	xassembler)+	  func_append compiler_flags " -Xassembler $qarg"+	  prev=+	  func_append compile_command " -Xassembler $qarg"+	  func_append finalize_command " -Xassembler $qarg"+	  continue+	  ;;+	xcclinker)+	  func_append linker_flags " $qarg"+	  func_append compiler_flags " $qarg"+	  prev=+	  func_append compile_command " $qarg"+	  func_append finalize_command " $qarg"+	  continue+	  ;;+	xcompiler)+	  func_append compiler_flags " $qarg"+	  prev=+	  func_append compile_command " $qarg"+	  func_append finalize_command " $qarg"+	  continue+	  ;;+	xlinker)+	  func_append linker_flags " $qarg"+	  func_append compiler_flags " $wl$qarg"+	  prev=+	  func_append compile_command " $wl$qarg"+	  func_append finalize_command " $wl$qarg"+	  continue+	  ;;+	*)+	  eval "$prev=\"\$arg\""+	  prev=+	  continue+	  ;;+	esac+      fi # test -n "$prev"++      prevarg=$arg++      case $arg in+      -all-static)+	if test -n "$link_static_flag"; then+	  # See comment for -static flag below, for more details.+	  func_append compile_command " $link_static_flag"+	  func_append finalize_command " $link_static_flag"+	fi+	continue+	;;++      -allow-undefined)+	# FIXME: remove this flag sometime in the future.+	func_fatal_error "'-allow-undefined' must not be used because it is the default"+	;;++      -avoid-version)+	avoid_version=yes+	continue+	;;++      -bindir)+	prev=bindir+	continue+	;;++      -dlopen)+	prev=dlfiles+	continue+	;;++      -dlpreopen)+	prev=dlprefiles+	continue+	;;++      -export-dynamic)+	export_dynamic=yes+	continue+	;;++      -export-symbols | -export-symbols-regex)+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then+	  func_fatal_error "more than one -exported-symbols argument is not allowed"+	fi+	if test X-export-symbols = "X$arg"; then+	  prev=expsyms+	else+	  prev=expsyms_regex+	fi+	continue+	;;++      -framework)+	prev=framework+	continue+	;;++      -inst-prefix-dir)+	prev=inst_prefix+	continue+	;;++      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*+      # so, if we see these flags be careful not to treat them like -L+      -L[A-Z][A-Z]*:*)+	case $with_gcc/$host in+	no/*-*-irix* | /*-*-irix*)+	  func_append compile_command " $arg"+	  func_append finalize_command " $arg"+	  ;;+	esac+	continue+	;;++      -L*)+	func_stripname "-L" '' "$arg"+	if test -z "$func_stripname_result"; then+	  if test "$#" -gt 0; then+	    func_fatal_error "require no space between '-L' and '$1'"+	  else+	    func_fatal_error "need path for '-L' option"+	  fi+	fi+	func_resolve_sysroot "$func_stripname_result"+	dir=$func_resolve_sysroot_result+	# We need an absolute path.+	case $dir in+	[\\/]* | [A-Za-z]:[\\/]*) ;;+	*)+	  absdir=`cd "$dir" && pwd`+	  test -z "$absdir" && \+	    func_fatal_error "cannot determine absolute directory name of '$dir'"+	  dir=$absdir+	  ;;+	esac+	case "$deplibs " in+	*" -L$dir "* | *" $arg "*)+	  # Will only happen for absolute or sysroot arguments+	  ;;+	*)+	  # Preserve sysroot, but never include relative directories+	  case $dir in+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;+	    *) func_append deplibs " -L$dir" ;;+	  esac+	  func_append lib_search_path " $dir"+	  ;;+	esac+	case $host in+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`+	  case :$dllsearchpath: in+	  *":$dir:"*) ;;+	  ::) dllsearchpath=$dir;;+	  *) func_append dllsearchpath ":$dir";;+	  esac+	  case :$dllsearchpath: in+	  *":$testbindir:"*) ;;+	  ::) dllsearchpath=$testbindir;;+	  *) func_append dllsearchpath ":$testbindir";;+	  esac+	  ;;+	esac+	continue+	;;++      -l*)+	if test X-lc = "X$arg" || test X-lm = "X$arg"; then+	  case $host in+	  *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)+	    # These systems don't actually have a C or math library (as such)+	    continue+	    ;;+	  *-*-os2*)+	    # These systems don't actually have a C library (as such)+	    test X-lc = "X$arg" && continue+	    ;;+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)+	    # Do not include libc due to us having libc/libc_r.+	    test X-lc = "X$arg" && continue+	    ;;+	  *-*-rhapsody* | *-*-darwin1.[012])+	    # Rhapsody C and math libraries are in the System framework+	    func_append deplibs " System.ltframework"+	    continue+	    ;;+	  *-*-sco3.2v5* | *-*-sco5v6*)+	    # Causes problems with __ctype+	    test X-lc = "X$arg" && continue+	    ;;+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)+	    # Compiler inserts libc in the correct place for threads to work+	    test X-lc = "X$arg" && continue+	    ;;+	  esac+	elif test X-lc_r = "X$arg"; then+	 case $host in+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)+	   # Do not include libc_r directly, use -pthread flag.+	   continue+	   ;;+	 esac+	fi+	func_append deplibs " $arg"+	continue+	;;++      -mllvm)+	prev=mllvm+	continue+	;;++      -module)+	module=yes+	continue+	;;++      # Tru64 UNIX uses -model [arg] to determine the layout of C+++      # classes, name mangling, and exception handling.+      # Darwin uses the -arch flag to determine output architecture.+      # -q <option> for IBM XL C/C++ compiler.+      -model|-arch|-isysroot|--sysroot|-q)+	func_append compiler_flags " $arg"+	func_append compile_command " $arg"+	func_append finalize_command " $arg"+	prev=xcompiler+	continue+	;;+     # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199.+     -pthread)+	case $host in+	  *solaris2*) ;;+	  *)+	    case "$new_inherited_linker_flags " in+	        *" $arg "*) ;;+	        * ) func_append new_inherited_linker_flags " $arg" ;;+	    esac+	  ;;+	esac+	continue+	;;+      -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \+      |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*)+	func_append compiler_flags " $arg"+	func_append compile_command " $arg"+	func_append finalize_command " $arg"+	case "$new_inherited_linker_flags " in+	    *" $arg "*) ;;+	    * ) func_append new_inherited_linker_flags " $arg" ;;+	esac+	continue+	;;++      -multi_module)+	single_module=$wl-multi_module+	continue+	;;++      -no-fast-install)+	fast_install=no+	continue+	;;++      -no-install)+	case $host in+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)+	  # The PATH hackery in wrapper scripts is required on Windows+	  # and Darwin in order for the loader to find any dlls it needs.+	  func_warning "'-no-install' is ignored for $host"+	  func_warning "assuming '-no-fast-install' instead"+	  fast_install=no+	  ;;+	*) no_install=yes ;;+	esac+	continue+	;;++      -no-undefined)+	allow_undefined=no+	continue+	;;++      -objectlist)+	prev=objectlist+	continue+	;;++      -os2dllname)+	prev=os2dllname+	continue+	;;++      -o) prev=output ;;++      -precious-files-regex)+	prev=precious_regex+	continue+	;;++      -release)+	prev=release+	continue+	;;++      -rpath)+	prev=rpath+	continue+	;;++      -R)+	prev=xrpath+	continue+	;;++      -R*)+	func_stripname '-R' '' "$arg"+	dir=$func_stripname_result+	# We need an absolute path.+	case $dir in+	[\\/]* | [A-Za-z]:[\\/]*) ;;+	=*)+	  func_stripname '=' '' "$dir"+	  dir=$lt_sysroot$func_stripname_result+	  ;;+	*)+	  func_fatal_error "argument ($arg) to '-R' is not an absolute path: $dir"+	  ;;+	esac+	case "$xrpath " in+	*" $dir "*) ;;+	*) func_append xrpath " $dir" ;;+	esac+	continue+	;;++      -shared)+	# The effects of -shared are defined in a previous loop.+	continue+	;;++      -shrext)+	prev=shrext+	continue+	;;++      -static | -static-libtool-libs)+	# The effects of -static are defined in a previous loop.+	# We used to do the same as -all-static on platforms that+	# didn't have a PIC flag, but the assumption that the effects+	# would be equivalent was wrong.  It would break on at least+	# Digital Unix and AIX.+	continue+	;;++      -thread-safe)+	thread_safe=yes+	continue+	;;++      -version-info)+	prev=vinfo+	continue+	;;++      -version-number)+	prev=vinfo+	vinfo_number=yes+	continue+	;;++      -weak)+        prev=weak+	continue+	;;++      -Wc,*)+	func_stripname '-Wc,' '' "$arg"+	args=$func_stripname_result+	arg=+	save_ifs=$IFS; IFS=,+	for flag in $args; do+	  IFS=$save_ifs+          func_quote_arg pretty "$flag"+	  func_append arg " $func_quote_arg_result"+	  func_append compiler_flags " $func_quote_arg_result"+	done+	IFS=$save_ifs+	func_stripname ' ' '' "$arg"+	arg=$func_stripname_result+	;;++      -Wl,*)+	func_stripname '-Wl,' '' "$arg"+	args=$func_stripname_result+	arg=+	save_ifs=$IFS; IFS=,+	for flag in $args; do+	  IFS=$save_ifs+          func_quote_arg pretty "$flag"+	  func_append arg " $wl$func_quote_arg_result"+	  func_append compiler_flags " $wl$func_quote_arg_result"+	  func_append linker_flags " $func_quote_arg_result"+	done+	IFS=$save_ifs+	func_stripname ' ' '' "$arg"+	arg=$func_stripname_result+	;;++      -Xassembler)+        prev=xassembler+        continue+        ;;++      -Xcompiler)+	prev=xcompiler+	continue+	;;++      -Xlinker)+	prev=xlinker+	continue+	;;++      -XCClinker)+	prev=xcclinker+	continue+	;;++      # -msg_* for osf cc+      -msg_*)+	func_quote_arg pretty "$arg"+	arg=$func_quote_arg_result+	;;++      # Flags to be passed through unchanged, with rationale:+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler+      # -r[0-9][0-9]*        specify processor for the SGI compiler+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler+      # +DA*, +DD*           enable 64-bit mode for the HP compiler+      # -q*                  compiler args for the IBM compiler+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC+      # -F/path              path to uninstalled frameworks, gcc on darwin+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC+      # -fstack-protector*   stack protector flags for GCC+      # @file                GCC response files+      # -tp=*                Portland pgcc target processor selection+      # --sysroot=*          for sysroot support+      # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization+      # -specs=*             GCC specs files+      # -stdlib=*            select c++ std lib with clang+      # -fdiagnostics-color* simply affects output+      # -frecord-gcc-switches used to verify flags were respected+      # -fsanitize=*         Clang/GCC memory and address sanitizer+      # -fno-sanitize*       Clang/GCC memory and address sanitizer+      # -shared-libsan       Link with shared sanitizer runtimes (Clang)+      # -static-libsan       Link with static sanitizer runtimes (Clang)+      # -no-canonical-prefixes Do not expand any symbolic links+      # -fuse-ld=*           Linker select flags for GCC+      # -static-*            direct GCC to link specific libraries statically+      # -fcilkplus           Cilk Plus language extension features for C/C+++      # -rtlib=*             select c runtime lib with clang+      # --unwindlib=*        select unwinder library with clang+      # -f{file|debug|macro|profile}-prefix-map=* needed for lto linking+      # -Wa,*                Pass flags directly to the assembler+      # -Werror, -Werror=*   Report (specified) warnings as errors+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-no-canonical-prefixes| \+      -stdlib=*|-rtlib=*|--unwindlib=*| \+      -specs=*|-fsanitize=*|-fno-sanitize*|-shared-libsan|-static-libsan| \+      -ffile-prefix-map=*|-fdebug-prefix-map=*|-fmacro-prefix-map=*|-fprofile-prefix-map=*| \+      -fdiagnostics-color*|-frecord-gcc-switches| \+      -fuse-ld=*|-static-*|-fcilkplus|-Wa,*|-Werror|-Werror=*)+        func_quote_arg pretty "$arg"+	arg=$func_quote_arg_result+        func_append compile_command " $arg"+        func_append finalize_command " $arg"+        func_append compiler_flags " $arg"+        continue+        ;;++      -Z*)+        if test os2 = "`expr $host : '.*\(os2\)'`"; then+          # OS/2 uses -Zxxx to specify OS/2-specific options+	  compiler_flags="$compiler_flags $arg"+	  func_append compile_command " $arg"+	  func_append finalize_command " $arg"+	  case $arg in+	  -Zlinker | -Zstack)+	    prev=xcompiler+	    ;;+	  esac+	  continue+        else+	  # Otherwise treat like 'Some other compiler flag' below+	  func_quote_arg pretty "$arg"+	  arg=$func_quote_arg_result+        fi+	;;++      # Some other compiler flag.+      -* | +*)+        func_quote_arg pretty "$arg"+	arg=$func_quote_arg_result+	;;++      *.$objext)+	# A standard object.+	func_append objs " $arg"+	;;++      *.lo)+	# A libtool-controlled object.++	# Check to see that this really is a libtool object.+	if func_lalib_unsafe_p "$arg"; then+	  pic_object=+	  non_pic_object=++	  # Read the .lo file+	  func_source "$arg"++	  if test -z "$pic_object" ||+	     test -z "$non_pic_object" ||+	     test none = "$pic_object" &&+	     test none = "$non_pic_object"; then+	    func_fatal_error "cannot find name of object for '$arg'"+	  fi++	  # Extract subdirectory from the argument.+	  func_dirname "$arg" "/" ""+	  xdir=$func_dirname_result++	  test none = "$pic_object" || {+	    # Prepend the subdirectory the object is found in.+	    pic_object=$xdir$pic_object++	    if test dlfiles = "$prev"; then+	      if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then+		func_append dlfiles " $pic_object"+		prev=+		continue+	      else+		# If libtool objects are unsupported, then we need to preload.+		prev=dlprefiles+	      fi+	    fi++	    # CHECK ME:  I think I busted this.  -Ossama+	    if test dlprefiles = "$prev"; then+	      # Preload the old-style object.+	      func_append dlprefiles " $pic_object"+	      prev=+	    fi++	    # A PIC object.+	    func_append libobjs " $pic_object"+	    arg=$pic_object+	  }++	  # Non-PIC object.+	  if test none != "$non_pic_object"; then+	    # Prepend the subdirectory the object is found in.+	    non_pic_object=$xdir$non_pic_object++	    # A standard non-PIC object+	    func_append non_pic_objects " $non_pic_object"+	    if test -z "$pic_object" || test none = "$pic_object"; then+	      arg=$non_pic_object+	    fi+	  else+	    # If the PIC object exists, use it instead.+	    # $xdir was prepended to $pic_object above.+	    non_pic_object=$pic_object+	    func_append non_pic_objects " $non_pic_object"+	  fi+	else+	  # Only an error if not doing a dry-run.+	  if $opt_dry_run; then+	    # Extract subdirectory from the argument.+	    func_dirname "$arg" "/" ""+	    xdir=$func_dirname_result++	    func_lo2o "$arg"+	    pic_object=$xdir$objdir/$func_lo2o_result+	    non_pic_object=$xdir$func_lo2o_result+	    func_append libobjs " $pic_object"+	    func_append non_pic_objects " $non_pic_object"+	  else+	    func_fatal_error "'$arg' is not a valid libtool object"+	  fi+	fi+	;;++      *.$libext)+	# An archive.+	func_append deplibs " $arg"+	func_append old_deplibs " $arg"+	continue+	;;++      *.la)+	# A libtool-controlled library.++	func_resolve_sysroot "$arg"+	if test dlfiles = "$prev"; then+	  # This library was specified with -dlopen.+	  func_append dlfiles " $func_resolve_sysroot_result"+	  prev=+	elif test dlprefiles = "$prev"; then+	  # The library was specified with -dlpreopen.+	  func_append dlprefiles " $func_resolve_sysroot_result"+	  prev=+	else+	  func_append deplibs " $func_resolve_sysroot_result"+	fi+	continue+	;;++      # Some other compiler argument.+      *)+	# Unknown arguments in both finalize_command and compile_command need+	# to be aesthetically quoted because they are evaled later.+	func_quote_arg pretty "$arg"+	arg=$func_quote_arg_result+	;;+      esac # arg++      # Now actually substitute the argument into the commands.+      if test -n "$arg"; then+	if test -n "$rpath_arg"; then+          func_append finalize_rpath " ${arg##*,}"+	  unset rpath_arg+	else+	  case $arg in+          -Wl,-rpath,*)+	    func_append finalize_rpath " ${arg##*,}";;+          -Wl,-rpath)+	    rpath_arg=1;;+          *)+            func_append compile_command " $arg"+	    func_append finalize_command " $arg"+	  esac+        fi+      fi+    done # argument parsing loop++    test -n "$prev" && \+      func_fatal_help "the '$prevarg' option requires an argument"++    if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then+      eval arg=\"$export_dynamic_flag_spec\"+      func_append compile_command " $arg"+      func_append finalize_command " $arg"+    fi++    oldlibs=+    # calculate the name of the file, without its directory+    func_basename "$output"+    outputname=$func_basename_result+    libobjs_save=$libobjs++    if test -n "$shlibpath_var"; then+      # get the directories listed in $shlibpath_var+      eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`+    else+      shlib_search_path=+    fi+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"++    # Definition is injected by LT_CONFIG during libtool generation.+    func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"++    func_dirname "$output" "/" ""+    output_objdir=$func_dirname_result$objdir+    func_to_tool_file "$output_objdir/"+    tool_output_objdir=$func_to_tool_file_result+    # Create the object directory.+    func_mkdir_p "$output_objdir"++    # Determine the type of output+    case $output in+    "")+      func_fatal_help "you must specify an output file"+      ;;+    *.$libext) linkmode=oldlib ;;+    *.lo | *.$objext) linkmode=obj ;;+    *.la) linkmode=lib ;;+    *) linkmode=prog ;; # Anything else should be a program.+    esac++    specialdeplibs=++    libs=+    # Find all interdependent deplibs by searching for libraries+    # that are linked more than once (e.g. -la -lb -la)+    for deplib in $deplibs; do+      if $opt_preserve_dup_deps; then+	case "$libs " in+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;+	esac+      fi+      func_append libs " $deplib"+    done++    if test lib = "$linkmode"; then+      libs="$predeps $libs $compiler_lib_search_path $postdeps"++      # Compute libraries that are listed more than once in $predeps+      # $postdeps and mark them as special (i.e., whose duplicates are+      # not to be eliminated).+      pre_post_deps=+      if $opt_duplicate_compiler_generated_deps; then+	for pre_post_dep in $predeps $postdeps; do+	  case "$pre_post_deps " in+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;+	  esac+	  func_append pre_post_deps " $pre_post_dep"+	done+      fi+      pre_post_deps=+    fi++    deplibs=+    newdependency_libs=+    newlib_search_path=+    need_relink=no # whether we're linking any uninstalled libtool libraries+    notinst_deplibs= # not-installed libtool libraries+    notinst_path= # paths that contain not-installed libtool libraries++    case $linkmode in+    lib)+	passes="conv dlpreopen link"+	for file in $dlfiles $dlprefiles; do+	  case $file in+	  *.la) ;;+	  *)+	    func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"+	    ;;+	  esac+	done+	;;+    prog)+	compile_deplibs=+	finalize_deplibs=+	alldeplibs=false+	newdlfiles=+	newdlprefiles=+	passes="conv scan dlopen dlpreopen link"+	;;+    *)  passes="conv"+	;;+    esac++    for pass in $passes; do+      # The preopen pass in lib mode reverses $deplibs; put it back here+      # so that -L comes before libs that need it for instance...+      if test lib,link = "$linkmode,$pass"; then+	## FIXME: Find the place where the list is rebuilt in the wrong+	##        order, and fix it there properly+        tmp_deplibs=+	for deplib in $deplibs; do+	  tmp_deplibs="$deplib $tmp_deplibs"+	done+	deplibs=$tmp_deplibs+      fi++      if test lib,link = "$linkmode,$pass" ||+	 test prog,scan = "$linkmode,$pass"; then+	libs=$deplibs+	deplibs=+      fi+      if test prog = "$linkmode"; then+	case $pass in+	dlopen) libs=$dlfiles ;;+	dlpreopen) libs=$dlprefiles ;;+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;+	esac+      fi+      if test lib,dlpreopen = "$linkmode,$pass"; then+	# Collect and forward deplibs of preopened libtool libs+	for lib in $dlprefiles; do+	  # Ignore non-libtool-libs+	  dependency_libs=+	  func_resolve_sysroot "$lib"+	  case $lib in+	  *.la)	func_source "$func_resolve_sysroot_result" ;;+	  esac++	  # Collect preopened libtool deplibs, except any this library+	  # has declared as weak libs+	  for deplib in $dependency_libs; do+	    func_basename "$deplib"+            deplib_base=$func_basename_result+	    case " $weak_libs " in+	    *" $deplib_base "*) ;;+	    *) func_append deplibs " $deplib" ;;+	    esac+	  done+	done+	libs=$dlprefiles+      fi+      if test dlopen = "$pass"; then+	# Collect dlpreopened libraries+	save_deplibs=$deplibs+	deplibs=+      fi++      for deplib in $libs; do+	lib=+	found=false+	case $deplib in+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \+        |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*)+	  if test prog,link = "$linkmode,$pass"; then+	    compile_deplibs="$deplib $compile_deplibs"+	    finalize_deplibs="$deplib $finalize_deplibs"+	  else+	    func_append compiler_flags " $deplib"+	    if test lib = "$linkmode"; then+		case "$new_inherited_linker_flags " in+		    *" $deplib "*) ;;+		    * ) func_append new_inherited_linker_flags " $deplib" ;;+		esac+	    fi+	  fi+	  continue+	  ;;+	-l*)+	  if test lib != "$linkmode" && test prog != "$linkmode"; then+	    func_warning "'-l' is ignored for archives/objects"+	    continue+	  fi+	  func_stripname '-l' '' "$deplib"+	  name=$func_stripname_result+	  if test lib = "$linkmode"; then+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"+	  else+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"+	  fi+	  for searchdir in $searchdirs; do+	    for search_ext in .la $std_shrext .so .a; do+	      # Search the libtool library+	      lib=$searchdir/lib$name$search_ext+	      if test -f "$lib"; then+		if test .la = "$search_ext"; then+		  found=:+		else+		  found=false+		fi+		break 2+	      fi+	    done+	  done+	  if $found; then+	    # deplib is a libtool library+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,+	    # We need to do some special things here, and not later.+	    if test yes = "$allow_libtool_libs_with_static_runtimes"; then+	      case " $predeps $postdeps " in+	      *" $deplib "*)+		if func_lalib_p "$lib"; then+		  library_names=+		  old_library=+		  func_source "$lib"+		  for l in $old_library $library_names; do+		    ll=$l+		  done+		  if test "X$ll" = "X$old_library"; then # only static version available+		    found=false+		    func_dirname "$lib" "" "."+		    ladir=$func_dirname_result+		    lib=$ladir/$old_library+		    if test prog,link = "$linkmode,$pass"; then+		      compile_deplibs="$deplib $compile_deplibs"+		      finalize_deplibs="$deplib $finalize_deplibs"+		    else+		      deplibs="$deplib $deplibs"+		      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"+		    fi+		    continue+		  fi+		fi+		;;+	      *) ;;+	      esac+	    fi+	  else+	    # deplib doesn't seem to be a libtool library+	    if test prog,link = "$linkmode,$pass"; then+	      compile_deplibs="$deplib $compile_deplibs"+	      finalize_deplibs="$deplib $finalize_deplibs"+	    else+	      deplibs="$deplib $deplibs"+	      test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"+	    fi+	    continue+	  fi+	  ;; # -l+	*.ltframework)+	  if test prog,link = "$linkmode,$pass"; then+	    compile_deplibs="$deplib $compile_deplibs"+	    finalize_deplibs="$deplib $finalize_deplibs"+	  else+	    deplibs="$deplib $deplibs"+	    if test lib = "$linkmode"; then+		case "$new_inherited_linker_flags " in+		    *" $deplib "*) ;;+		    * ) func_append new_inherited_linker_flags " $deplib" ;;+		esac+	    fi+	  fi+	  continue+	  ;;+	-L*)+	  case $linkmode in+	  lib)+	    deplibs="$deplib $deplibs"+	    test conv = "$pass" && continue+	    newdependency_libs="$deplib $newdependency_libs"+	    func_stripname '-L' '' "$deplib"+	    func_resolve_sysroot "$func_stripname_result"+	    func_append newlib_search_path " $func_resolve_sysroot_result"+	    ;;+	  prog)+	    if test conv = "$pass"; then+	      deplibs="$deplib $deplibs"+	      continue+	    fi+	    if test scan = "$pass"; then+	      deplibs="$deplib $deplibs"+	    else+	      compile_deplibs="$deplib $compile_deplibs"+	      finalize_deplibs="$deplib $finalize_deplibs"+	    fi+	    func_stripname '-L' '' "$deplib"+	    func_resolve_sysroot "$func_stripname_result"+	    func_append newlib_search_path " $func_resolve_sysroot_result"+	    ;;+	  *)+	    func_warning "'-L' is ignored for archives/objects"+	    ;;+	  esac # linkmode+	  continue+	  ;; # -L+	-R*)+	  if test link = "$pass"; then+	    func_stripname '-R' '' "$deplib"+	    func_resolve_sysroot "$func_stripname_result"+	    dir=$func_resolve_sysroot_result+	    # Make sure the xrpath contains only unique directories.+	    case "$xrpath " in+	    *" $dir "*) ;;+	    *) func_append xrpath " $dir" ;;+	    esac+	  fi+	  deplibs="$deplib $deplibs"+	  continue+	  ;;+	*.la)+	  func_resolve_sysroot "$deplib"+	  lib=$func_resolve_sysroot_result+	  ;;+	*.$libext)+	  if test conv = "$pass"; then+	    deplibs="$deplib $deplibs"+	    continue+	  fi+	  case $linkmode in+	  lib)+	    # Linking convenience modules into shared libraries is allowed,+	    # but linking other static libraries is non-portable.+	    case " $dlpreconveniencelibs " in+	    *" $deplib "*) ;;+	    *)+	      valid_a_lib=false+	      case $deplibs_check_method in+		match_pattern*)+		  set dummy $deplibs_check_method; shift+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \+		    | $EGREP "$match_pattern_regex" > /dev/null; then+		    valid_a_lib=:+		  fi+		;;+		pass_all)+		  valid_a_lib=:+		;;+	      esac+	      if $valid_a_lib; then+		func_warning "Linking the shared library $output against the static library $deplib is not portable!"+		deplibs="$deplib $deplibs"+	      else+		func_warning "Trying to link with static lib archive $deplib."+		func_warning "I have the capability to make that library automatically link in when"+		func_warning "you link to this library.  But I can only do this if you have a"+		func_warning "shared version of the library, which you do not appear to have"+		func_warning "because the file extensions .$libext of this argument makes me believe"+		func_warning "that it is just a static archive that I should not use here."+	      fi+	      ;;+	    esac+	    continue+	    ;;+	  prog)+	    if test link != "$pass"; then+	      deplibs="$deplib $deplibs"+	    else+	      compile_deplibs="$deplib $compile_deplibs"+	      finalize_deplibs="$deplib $finalize_deplibs"+	    fi+	    continue+	    ;;+	  esac # linkmode+	  ;; # *.$libext+	*.lo | *.$objext)+	  if test conv = "$pass"; then+	    deplibs="$deplib $deplibs"+	  elif test prog = "$linkmode"; then+	    if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then+	      # If there is no dlopen support or we're linking statically,+	      # we need to preload.+	      func_append newdlprefiles " $deplib"+	      compile_deplibs="$deplib $compile_deplibs"+	      finalize_deplibs="$deplib $finalize_deplibs"+	    else+	      func_append newdlfiles " $deplib"+	    fi+	  fi+	  continue+	  ;;+	%DEPLIBS%)+	  alldeplibs=:+	  continue+	  ;;+	esac # case $deplib++	$found || test -f "$lib" \+	  || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"++	# Check to see that this really is a libtool archive.+	func_lalib_unsafe_p "$lib" \+	  || func_fatal_error "'$lib' is not a valid libtool archive"++	func_dirname "$lib" "" "."+	ladir=$func_dirname_result++	dlname=+	dlopen=+	dlpreopen=+	libdir=+	library_names=+	old_library=+	inherited_linker_flags=+	# If the library was installed with an old release of libtool,+	# it will not redefine variables installed, or shouldnotlink+	installed=yes+	shouldnotlink=no+	avoidtemprpath=+++	# Read the .la file+	func_source "$lib"++	# Convert "-framework foo" to "foo.ltframework"+	if test -n "$inherited_linker_flags"; then+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do+	    case " $new_inherited_linker_flags " in+	      *" $tmp_inherited_linker_flag "*) ;;+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;+	    esac+	  done+	fi+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	if test lib,link = "$linkmode,$pass" ||+	   test prog,scan = "$linkmode,$pass" ||+	   { test prog != "$linkmode" && test lib != "$linkmode"; }; then+	  test -n "$dlopen" && func_append dlfiles " $dlopen"+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"+	fi++	if test conv = "$pass"; then+	  # Only check for convenience libraries+	  deplibs="$lib $deplibs"+	  if test -z "$libdir"; then+	    if test -z "$old_library"; then+	      func_fatal_error "cannot find name of link library for '$lib'"+	    fi+	    # It is a libtool convenience library, so add in its objects.+	    func_append convenience " $ladir/$objdir/$old_library"+	    func_append old_convenience " $ladir/$objdir/$old_library"+	  elif test prog != "$linkmode" && test lib != "$linkmode"; then+	    func_fatal_error "'$lib' is not a convenience library"+	  fi+	  tmp_libs=+	  for deplib in $dependency_libs; do+	    deplibs="$deplib $deplibs"+	    if $opt_preserve_dup_deps; then+	      case "$tmp_libs " in+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;+	      esac+	    fi+	    func_append tmp_libs " $deplib"+	  done+	  continue+	fi # $pass = conv+++	# Get the name of the library we link against.+	linklib=+	if test -n "$old_library" &&+	   { test yes = "$prefer_static_libs" ||+	     test built,no = "$prefer_static_libs,$installed"; }; then+	  linklib=$old_library+	else+	  for l in $old_library $library_names; do+	    linklib=$l+	  done+	fi+	if test -z "$linklib"; then+	  func_fatal_error "cannot find name of link library for '$lib'"+	fi++	# This library was specified with -dlopen.+	if test dlopen = "$pass"; then+	  test -z "$libdir" \+	    && func_fatal_error "cannot -dlopen a convenience library: '$lib'"+	  if test -z "$dlname" ||+	     test yes != "$dlopen_support" ||+	     test no = "$build_libtool_libs"+	  then+	    # If there is no dlname, no dlopen support or we're linking+	    # statically, we need to preload.  We also need to preload any+	    # dependent libraries so libltdl's deplib preloader doesn't+	    # bomb out in the load deplibs phase.+	    func_append dlprefiles " $lib $dependency_libs"+	  else+	    func_append newdlfiles " $lib"+	  fi+	  continue+	fi # $pass = dlopen++	# We need an absolute path.+	case $ladir in+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;+	*)+	  abs_ladir=`cd "$ladir" && pwd`+	  if test -z "$abs_ladir"; then+	    func_warning "cannot determine absolute directory name of '$ladir'"+	    func_warning "passing it literally to the linker, although it might fail"+	    abs_ladir=$ladir+	  fi+	  ;;+	esac+	func_basename "$lib"+	laname=$func_basename_result++	# Find the relevant object directory and library name.+	if test yes = "$installed"; then+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then+	    func_warning "library '$lib' was moved."+	    dir=$ladir+	    absdir=$abs_ladir+	    libdir=$abs_ladir+	  else+	    dir=$lt_sysroot$libdir+	    absdir=$lt_sysroot$libdir+	  fi+	  test yes = "$hardcode_automatic" && avoidtemprpath=yes+	else+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then+	    dir=$ladir+	    absdir=$abs_ladir+	    # Remove this search path later+	    func_append notinst_path " $abs_ladir"+	  else+	    dir=$ladir/$objdir+	    absdir=$abs_ladir/$objdir+	    # Remove this search path later+	    func_append notinst_path " $abs_ladir"+	  fi+	fi # $installed = yes+	func_stripname 'lib' '.la' "$laname"+	name=$func_stripname_result++	# This library was specified with -dlpreopen.+	if test dlpreopen = "$pass"; then+	  if test -z "$libdir" && test prog = "$linkmode"; then+	    func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"+	  fi+	  case $host in+	    # special handling for platforms with PE-DLLs.+	    *cygwin* | *mingw* | *windows* | *cegcc* )+	      # Linker will automatically link against shared library if both+	      # static and shared are present.  Therefore, ensure we extract+	      # symbols from the import library if a shared library is present+	      # (otherwise, the dlopen module name will be incorrect).  We do+	      # this by putting the import library name into $newdlprefiles.+	      # We recover the dlopen module name by 'saving' the la file+	      # name in a special purpose variable, and (later) extracting the+	      # dlname from the la file.+	      if test -n "$dlname"; then+	        func_tr_sh "$dir/$linklib"+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"+	        func_append newdlprefiles " $dir/$linklib"+	      else+	        func_append newdlprefiles " $dir/$old_library"+	        # Keep a list of preopened convenience libraries to check+	        # that they are being used correctly in the link pass.+	        test -z "$libdir" && \+	          func_append dlpreconveniencelibs " $dir/$old_library"+	      fi+	    ;;+	    * )+	      # Prefer using a static library (so that no silly _DYNAMIC symbols+	      # are required to link).+	      if test -n "$old_library"; then+	        func_append newdlprefiles " $dir/$old_library"+	        # Keep a list of preopened convenience libraries to check+	        # that they are being used correctly in the link pass.+	        test -z "$libdir" && \+	          func_append dlpreconveniencelibs " $dir/$old_library"+	      # Otherwise, use the dlname, so that lt_dlopen finds it.+	      elif test -n "$dlname"; then+	        func_append newdlprefiles " $dir/$dlname"+	      else+	        func_append newdlprefiles " $dir/$linklib"+	      fi+	    ;;+	  esac+	fi # $pass = dlpreopen++	if test -z "$libdir"; then+	  # Link the convenience library+	  if test lib = "$linkmode"; then+	    deplibs="$dir/$old_library $deplibs"+	  elif test prog,link = "$linkmode,$pass"; then+	    compile_deplibs="$dir/$old_library $compile_deplibs"+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"+	  else+	    deplibs="$lib $deplibs" # used for prog,scan pass+	  fi+	  continue+	fi+++	if test prog = "$linkmode" && test link != "$pass"; then+	  func_append newlib_search_path " $ladir"+	  deplibs="$lib $deplibs"++	  linkalldeplibs=false+	  if test no != "$link_all_deplibs" || test -z "$library_names" ||+	     test no = "$build_libtool_libs"; then+	    linkalldeplibs=:+	  fi++	  tmp_libs=+	  for deplib in $dependency_libs; do+	    case $deplib in+	    -L*) func_stripname '-L' '' "$deplib"+	         func_resolve_sysroot "$func_stripname_result"+	         func_append newlib_search_path " $func_resolve_sysroot_result"+		 ;;+	    esac+	    # Need to link against all dependency_libs?+	    if $linkalldeplibs; then+	      deplibs="$deplib $deplibs"+	    else+	      # Need to hardcode shared library paths+	      # or/and link against static libraries+	      newdependency_libs="$deplib $newdependency_libs"+	    fi+	    if $opt_preserve_dup_deps; then+	      case "$tmp_libs " in+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;+	      esac+	    fi+	    func_append tmp_libs " $deplib"+	  done # for deplib+	  continue+	fi # $linkmode = prog...++	if test prog,link = "$linkmode,$pass"; then+	  if test -n "$library_names" &&+	     { { test no = "$prefer_static_libs" ||+	         test built,yes = "$prefer_static_libs,$installed"; } ||+	       test -z "$old_library"; }; then+	    # We need to hardcode the library path+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then+	      # Make sure the rpath contains only unique directories.+	      case $temp_rpath: in+	      *"$absdir:"*) ;;+              *) case $absdir in+                 "$progdir/"*) func_append temp_rpath "$absdir:" ;;+                 *)            func_append temp_rpath_tail "$absdir:" ;;+                 esac+	      esac+	    fi++	    # Hardcode the library path.+	    # Skip directories that are in the system default run-time+	    # search path.+	    case " $sys_lib_dlsearch_path " in+	    *" $absdir "*) ;;+	    *)+	      case "$compile_rpath$compile_rpath_tail " in+	      *" $absdir "*) ;;+	      *) case $absdir in+                 "$progdir/"*) func_append compile_rpath " $absdir" ;;+                 *) func_append compile_rpath_tail " $absdir" ;;+		 esac+	      esac+	      ;;+	    esac+	    case " $sys_lib_dlsearch_path " in+	    *" $libdir "*) ;;+	    *)+	      case "$finalize_rpath " in+	      *" $libdir "*) ;;+	      *) func_append finalize_rpath " $libdir" ;;+	      esac+	      ;;+	    esac+	  fi # $linkmode,$pass = prog,link...++	  if $alldeplibs &&+	     { test pass_all = "$deplibs_check_method" ||+	       { test yes = "$build_libtool_libs" &&+		 test -n "$library_names"; }; }; then+	    # We only need to search for static libraries+	    continue+	  fi+	fi++	link_static=no # Whether the deplib will be linked statically+	use_static_libs=$prefer_static_libs+	if test built = "$use_static_libs" && test yes = "$installed"; then+	  use_static_libs=no+	fi+	if test -n "$library_names" &&+	   { test no = "$use_static_libs" || test -z "$old_library"; }; then+	  case $host_os in+	  cygwin* | mingw* | windows* | cegcc* | os2*)+	      # No point in relinking DLLs because paths are not encoded+	      func_append notinst_deplibs " $lib"+	      need_relink=no+	    ;;+	  *)+	    if test no = "$installed"; then+	      func_append notinst_deplibs " $lib"+	      need_relink=yes+	    fi+	    ;;+	  esac+	  # This is a shared library++	  # Warn about portability, can't link against -module's on some+	  # systems (darwin).  Don't bleat about dlopened modules though!+	  dlopenmodule=+	  for dlpremoduletest in $dlprefiles; do+	    if test "X$dlpremoduletest" = "X$lib"; then+	      dlopenmodule=$dlpremoduletest+	      break+	    fi+	  done+	  if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then+	    echo+	    if test prog = "$linkmode"; then+	      func_warning "Linking the executable $output against the loadable module"+	    else+	      func_warning "Linking the shared library $output against the loadable module"+	    fi+	    func_warning "$linklib is not portable!"+	  fi+	  if test lib = "$linkmode" &&+	     test yes = "$hardcode_into_libs"; then+	    # Hardcode the library path.+	    # Skip directories that are in the system default run-time+	    # search path.+	    case " $sys_lib_dlsearch_path " in+	    *" $absdir "*) ;;+	    *)+	      case "$compile_rpath$compile_rpath_tail " in+	      *" $absdir "*) ;;+	      *) case $absdir in+                 "$progdir/"*) func_append compile_rpath " $absdir" ;;+                 *) func_append compile_rpath_tail " $absdir" ;;+		 esac+	      esac+	      ;;+	    esac+	    case " $sys_lib_dlsearch_path " in+	    *" $libdir "*) ;;+	    *)+	      case "$finalize_rpath " in+	      *" $libdir "*) ;;+	      *) func_append finalize_rpath " $libdir" ;;+	      esac+	      ;;+	    esac+	  fi++	  if test -n "$old_archive_from_expsyms_cmds"; then+	    # figure out the soname+	    set dummy $library_names+	    shift+	    realname=$1+	    shift+	    libname=`eval "\\$ECHO \"$libname_spec\""`+	    # use dlname if we got it. it's perfectly good, no?+	    if test -n "$dlname"; then+	      soname=$dlname+	    elif test -n "$soname_spec"; then+	      # bleh windows+	      case $host_os in+	      cygwin* | mingw* | windows* | cegcc* | os2*)+	        func_arith $current - $age+		major=$func_arith_result+		versuffix=-$major+		;;+	      esac+	      eval soname=\"$soname_spec\"+	    else+	      soname=$realname+	    fi++	    # Make a new name for the extract_expsyms_cmds to use+	    soroot=$soname+	    func_basename "$soroot"+	    soname=$func_basename_result+	    func_stripname 'lib' '.dll' "$soname"+	    newlib=libimp-$func_stripname_result.a++	    # If the library has no export list, then create one now+	    if test -f "$output_objdir/$soname-def"; then :+	    else+	      func_verbose "extracting exported symbol list from '$soname'"+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'+	    fi++	    # Create $newlib+	    if test -f "$output_objdir/$newlib"; then :; else+	      func_verbose "generating import library for '$soname'"+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'+	    fi+	    # make sure the library variables are pointing to the new library+	    dir=$output_objdir+	    linklib=$newlib+	  fi # test -n "$old_archive_from_expsyms_cmds"++	  if test prog = "$linkmode" || test relink != "$opt_mode"; then+	    add_shlibpath=+	    add_dir=+	    add=+	    lib_linked=yes+	    case $hardcode_action in+	    immediate | unsupported)+	      if test no = "$hardcode_direct"; then+		add=$dir/$linklib+		case $host in+		  *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;+		  *-*-sysv4*uw2*) add_dir=-L$dir ;;+		  *-*-emscripten*) add_dir=-L$dir ;;+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \+		    *-*-unixware7*) add_dir=-L$dir ;;+		  *-*-darwin* )+		    # if the lib is a (non-dlopened) module then we cannot+		    # link against it, someone is ignoring the earlier warnings+		    if /usr/bin/file -L $add 2> /dev/null |+			 $GREP ": [^:]* bundle" >/dev/null; then+		      if test "X$dlopenmodule" != "X$lib"; then+			func_warning "lib $linklib is a module, not a shared library"+			if test -z "$old_library"; then+			  func_warning "And there doesn't seem to be a static archive available"+			  func_warning "The link will probably fail, sorry"+			else+			  add=$dir/$old_library+			fi+		      elif test -n "$old_library"; then+			add=$dir/$old_library+		      fi+		    fi+		esac+	      elif test no = "$hardcode_minus_L"; then+		case $host in+		*-*-sunos*) add_shlibpath=$dir ;;+		esac+		add_dir=-L$dir+		add=-l$name+	      elif test no = "$hardcode_shlibpath_var"; then+		add_shlibpath=$dir+		add=-l$name+	      else+		lib_linked=no+	      fi+	      ;;+	    relink)+	      if test yes = "$hardcode_direct" &&+	         test no = "$hardcode_direct_absolute"; then+		add=$dir/$linklib+	      elif test yes = "$hardcode_minus_L"; then+		add_dir=-L$absdir+		# Try looking first in the location we're being installed to.+		if test -n "$inst_prefix_dir"; then+		  case $libdir in+		    [\\/]*)+		      func_append add_dir " -L$inst_prefix_dir$libdir"+		      ;;+		  esac+		fi+		add=-l$name+	      elif test yes = "$hardcode_shlibpath_var"; then+		add_shlibpath=$dir+		add=-l$name+	      else+		lib_linked=no+	      fi+	      ;;+	    *) lib_linked=no ;;+	    esac++	    if test yes != "$lib_linked"; then+	      func_fatal_configuration "unsupported hardcode properties"+	    fi++	    if test -n "$add_shlibpath"; then+	      case :$compile_shlibpath: in+	      *":$add_shlibpath:"*) ;;+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;+	      esac+	    fi+	    if test prog = "$linkmode"; then+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"+	    else+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"+	      test -n "$add" && deplibs="$add $deplibs"+	      if test yes != "$hardcode_direct" &&+		 test yes != "$hardcode_minus_L" &&+		 test yes = "$hardcode_shlibpath_var"; then+		case :$finalize_shlibpath: in+		*":$libdir:"*) ;;+		*) func_append finalize_shlibpath "$libdir:" ;;+		esac+	      fi+	    fi+	  fi++	  if test prog = "$linkmode" || test relink = "$opt_mode"; then+	    add_shlibpath=+	    add_dir=+	    add=+	    # Finalize command for both is simple: just hardcode it.+	    if test yes = "$hardcode_direct" &&+	       test no = "$hardcode_direct_absolute"; then+	      add=$libdir/$linklib+	    elif test yes = "$hardcode_minus_L"; then+	      add_dir=-L$lt_sysroot$libdir+	      add=-l$name+	    elif test yes = "$hardcode_shlibpath_var"; then+	      case :$finalize_shlibpath: in+	      *":$libdir:"*) ;;+	      *) func_append finalize_shlibpath "$libdir:" ;;+	      esac+	      add=-l$name+	    elif test yes = "$hardcode_automatic"; then+	      if test -n "$inst_prefix_dir" &&+		 test -f "$inst_prefix_dir$libdir/$linklib"; then+		add=$inst_prefix_dir$libdir/$linklib+	      else+		add=$libdir/$linklib+	      fi+	    else+	      # We cannot seem to hardcode it, guess we'll fake it.+	      add_dir=-L$lt_sysroot$libdir+	      # Try looking first in the location we're being installed to.+	      if test -n "$inst_prefix_dir"; then+		case $libdir in+		  [\\/]*)+		    func_append add_dir " -L$inst_prefix_dir$libdir"+		    ;;+		esac+	      fi+	      add=-l$name+	    fi++	    if test prog = "$linkmode"; then+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"+	    else+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"+	      test -n "$add" && deplibs="$add $deplibs"+	    fi+	  fi+	elif test prog = "$linkmode"; then+	  # Here we assume that one of hardcode_direct or hardcode_minus_L+	  # is not unsupported.  This is valid on all known static and+	  # shared platforms.+	  if test unsupported != "$hardcode_direct"; then+	    test -n "$old_library" && linklib=$old_library+	    compile_deplibs="$dir/$linklib $compile_deplibs"+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"+	  else+	    compile_deplibs="-l$name -L$dir $compile_deplibs"+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"+	  fi+	elif test yes = "$build_libtool_libs"; then+	  # Not a shared library+	  if test pass_all != "$deplibs_check_method"; then+	    # We're trying link a shared library against a static one+	    # but the system doesn't support it.++	    # Just print a warning and add the library to dependency_libs so+	    # that the program can be linked against the static library.+	    func_warning "This system cannot link to static lib archive $lib."+	    func_warning "I have the capability to make that library automatically link in when"+	    func_warning "you link to this library.  But I can only do this if you have a"+	    func_warning "shared version of the library, which you do not appear to have."+	    if test yes = "$module"; then+	      func_warning "But as you try to build a module library, libtool will still create "+	      func_warning "a static module, that should work as long as the dlopening application"+	      func_warning "is linked with the -dlopen flag to resolve symbols at runtime."+	      if test -z "$global_symbol_pipe"; then+		func_warning "However, this would only work if libtool was able to extract symbol"+		func_warning "lists from a program, using 'nm' or equivalent, but libtool could"+		func_warning "not find such a program.  So, this module is probably useless."+		func_warning "'nm' from GNU binutils and a full rebuild may help."+	      fi+	      if test no = "$build_old_libs"; then+		build_libtool_libs=module+		build_old_libs=yes+	      else+		build_libtool_libs=no+	      fi+	    fi+	  else+	    deplibs="$dir/$old_library $deplibs"+	    link_static=yes+	  fi+	fi # link shared/static library?++	if test lib = "$linkmode"; then+	  if test -n "$dependency_libs" &&+	     { test yes != "$hardcode_into_libs" ||+	       test yes = "$build_old_libs" ||+	       test yes = "$link_static"; }; then+	    # Extract -R from dependency_libs+	    temp_deplibs=+	    for libdir in $dependency_libs; do+	      case $libdir in+	      -R*) func_stripname '-R' '' "$libdir"+	           temp_xrpath=$func_stripname_result+		   case " $xrpath " in+		   *" $temp_xrpath "*) ;;+		   *) func_append xrpath " $temp_xrpath";;+		   esac;;+	      *) func_append temp_deplibs " $libdir";;+	      esac+	    done+	    dependency_libs=$temp_deplibs+	  fi++	  func_append newlib_search_path " $absdir"+	  # Link against this library+	  test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"+	  # ... and its dependency_libs+	  tmp_libs=+	  for deplib in $dependency_libs; do+	    newdependency_libs="$deplib $newdependency_libs"+	    case $deplib in+              -L*) func_stripname '-L' '' "$deplib"+                   func_resolve_sysroot "$func_stripname_result";;+              *) func_resolve_sysroot "$deplib" ;;+            esac+	    if $opt_preserve_dup_deps; then+	      case "$tmp_libs " in+	      *" $func_resolve_sysroot_result "*)+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;+	      esac+	    fi+	    func_append tmp_libs " $func_resolve_sysroot_result"+	  done++	  if test no != "$link_all_deplibs"; then+	    # Add the search paths of all dependency libraries+	    for deplib in $dependency_libs; do+	      path=+	      case $deplib in+	      -L*) path=$deplib ;;+	      *.la)+	        func_resolve_sysroot "$deplib"+	        deplib=$func_resolve_sysroot_result+	        func_dirname "$deplib" "" "."+		dir=$func_dirname_result+		# We need an absolute path.+		case $dir in+		[\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;+		*)+		  absdir=`cd "$dir" && pwd`+		  if test -z "$absdir"; then+		    func_warning "cannot determine absolute directory name of '$dir'"+		    absdir=$dir+		  fi+		  ;;+		esac+		if $GREP "^installed=no" $deplib > /dev/null; then+		case $host in+		*-*-darwin*)+		  depdepl=+		  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`+		  if test -n "$deplibrary_names"; then+		    for tmp in $deplibrary_names; do+		      depdepl=$tmp+		    done+		    if test -f "$absdir/$objdir/$depdepl"; then+		      depdepl=$absdir/$objdir/$depdepl+		      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`+                      if test -z "$darwin_install_name"; then+                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`+                      fi+		      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"+		      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"+		      path=+		    fi+		  fi+		  ;;+		*)+		  path=-L$absdir/$objdir+		  ;;+		esac+		else+		  eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`+		  test -z "$libdir" && \+		    func_fatal_error "'$deplib' is not a valid libtool archive"+		  test "$absdir" != "$libdir" && \+		    func_warning "'$deplib' seems to be moved"++		  path=-L$absdir+		fi+		;;+	      esac+	      case " $deplibs " in+	      *" $path "*) ;;+	      *) deplibs="$path $deplibs" ;;+	      esac+	    done+	  fi # link_all_deplibs != no+	fi # linkmode = lib+      done # for deplib in $libs++      func_append temp_rpath "$temp_rpath_tail"+      func_append compile_rpath "$compile_rpath_tail"++      if test link = "$pass"; then+	if test prog = "$linkmode"; then+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"+	else+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	fi+      fi+      dependency_libs=$newdependency_libs+      if test dlpreopen = "$pass"; then+	# Link the dlpreopened libraries before other libraries+	for deplib in $save_deplibs; do+	  deplibs="$deplib $deplibs"+	done+      fi+      if test dlopen != "$pass"; then+	test conv = "$pass" || {+	  # Make sure lib_search_path contains only unique directories.+	  lib_search_path=+	  for dir in $newlib_search_path; do+	    case "$lib_search_path " in+	    *" $dir "*) ;;+	    *) func_append lib_search_path " $dir" ;;+	    esac+	  done+	  newlib_search_path=+	}++	if test prog,link = "$linkmode,$pass"; then+	  vars="compile_deplibs finalize_deplibs"+	else+	  vars=deplibs+	fi+	for var in $vars dependency_libs; do+	  # Add libraries to $var in reverse order+	  eval tmp_libs=\"\$$var\"+	  new_libs=+	  # FIXME: Pedantically, this is the right thing to do, so+	  #        that some nasty dependency loop isn't accidentally+	  #        broken: new_libs="$deplib $new_libs"+	  for deplib in $tmp_libs; do+	    if $opt_preserve_dup_deps; then+	      new_libs="$deplib $new_libs"+	    else+	      # Pragmatically, this seems to cause very few problems in+	      # practice:+	      case $deplib in+	      -L*) new_libs="$deplib $new_libs" ;;+	      -R*) ;;+	      *)+	        # And here is the reason: when a library appears more+	        # than once as an explicit dependence of a library, or+	        # is implicitly linked in more than once by the+	        # compiler, it is considered special, and multiple+	        # occurrences thereof are not removed.  Compare this+	        # with having the same library being listed as a+	        # dependency of multiple other libraries: in this case,+	        # we know (pedantically, we assume) the library does not+	        # need to be listed more than once, so we keep only the+	        # last copy.  This is not always right, but it is rare+	        # enough that we require users that really mean to play+	        # such unportable linking tricks to link the library+	        # using -Wl,-lname, so that libtool does not consider it+	        # for duplicate removal.  And if not possible for portability+	        # reasons, then --preserve-dup-deps should be used.+	        case " $specialdeplibs " in+	        *" $deplib "*) new_libs="$deplib $new_libs" ;;+	        *)+	          case " $new_libs " in+	          *" $deplib "*) ;;+	          *) new_libs="$deplib $new_libs" ;;+	          esac+	          ;;+	        esac+	        ;;+	      esac+	    fi+	  done+	  tmp_libs=+	  for deplib in $new_libs; do+	    case $deplib in+	    -L*)+	      case " $tmp_libs " in+	      *" $deplib "*) ;;+	      *) func_append tmp_libs " $deplib" ;;+	      esac+	      ;;+	    *) func_append tmp_libs " $deplib" ;;+	    esac+	  done+	  eval $var=\"$tmp_libs\"+	done # for var+      fi++      # Add Sun CC postdeps if required:+      test CXX = "$tagname" && {+        case $host_os in+        linux*)+          case `$CC -V 2>&1 | $SED 5q` in+          *Sun\ C*) # Sun C++ 5.9+            func_suncc_cstd_abi++            if test no != "$suncc_use_cstd_abi"; then+              func_append postdeps ' -library=Cstd -library=Crun'+            fi+            ;;+          esac+          ;;++        solaris*)+          func_cc_basename "$CC"+          case $func_cc_basename_result in+          CC* | sunCC*)+            func_suncc_cstd_abi++            if test no != "$suncc_use_cstd_abi"; then+              func_append postdeps ' -library=Cstd -library=Crun'+            fi+            ;;+          esac+          ;;+        esac+      }++      # Last step: remove runtime libs from dependency_libs+      # (they stay in deplibs)+      tmp_libs=+      for i in $dependency_libs; do+	case " $predeps $postdeps $compiler_lib_search_path " in+	*" $i "*)+	  i=+	  ;;+	esac+	if test -n "$i"; then+	  func_append tmp_libs " $i"+	fi+      done+      dependency_libs=$tmp_libs+    done # for pass+    if test prog = "$linkmode"; then+      dlfiles=$newdlfiles+    fi+    if test prog = "$linkmode" || test lib = "$linkmode"; then+      dlprefiles=$newdlprefiles+    fi++    case $linkmode in+    oldlib)+      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then+	func_warning "'-dlopen' is ignored for archives"+      fi++      case " $deplibs" in+      *\ -l* | *\ -L*)+	func_warning "'-l' and '-L' are ignored for archives" ;;+      esac++      test -n "$rpath" && \+	func_warning "'-rpath' is ignored for archives"++      test -n "$xrpath" && \+	func_warning "'-R' is ignored for archives"++      test -n "$vinfo" && \+	func_warning "'-version-info/-version-number' is ignored for archives"++      test -n "$release" && \+	func_warning "'-release' is ignored for archives"++      test -n "$export_symbols$export_symbols_regex" && \+	func_warning "'-export-symbols' is ignored for archives"++      # Now set the variables for building old libraries.+      build_libtool_libs=no+      oldlibs=$output+      func_append objs "$old_deplibs"+      ;;++    lib)+      # Make sure we only generate libraries of the form 'libNAME.la'.+      case $outputname in+      lib*)+	func_stripname 'lib' '.la' "$outputname"+	name=$func_stripname_result+	eval shared_ext=\"$shrext_cmds\"+	eval libname=\"$libname_spec\"+	;;+      *)+	test no = "$module" \+	  && func_fatal_help "libtool library '$output' must begin with 'lib'"++	if test no != "$need_lib_prefix"; then+	  # Add the "lib" prefix for modules if required+	  func_stripname '' '.la' "$outputname"+	  name=$func_stripname_result+	  eval shared_ext=\"$shrext_cmds\"+	  eval libname=\"$libname_spec\"+	else+	  func_stripname '' '.la' "$outputname"+	  libname=$func_stripname_result+	fi+	;;+      esac++      if test -n "$objs"; then+	if test pass_all != "$deplibs_check_method"; then+	  func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"+	else+	  func_warning "Linking the shared library $output against the non-libtool objects $objs is not portable!"+	  func_append libobjs " $objs"+	fi+      fi++      test no = "$dlself" \+	|| func_warning "'-dlopen self' is ignored for libtool libraries"++      set dummy $rpath+      shift+      test 1 -lt "$#" \+	&& func_warning "ignoring multiple '-rpath's for a libtool library"++      install_libdir=$1++      oldlibs=+      if test -z "$rpath"; then+	if test yes = "$build_libtool_libs"; then+	  # Building a libtool convenience library.+	  # Some compilers have problems with a '.al' extension so+	  # convenience libraries should have the same extension an+	  # archive normally would.+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"+	  build_libtool_libs=convenience+	  build_old_libs=yes+	fi++	test -n "$vinfo" && \+	  func_warning "'-version-info/-version-number' is ignored for convenience libraries"++	test -n "$release" && \+	  func_warning "'-release' is ignored for convenience libraries"+      else++	# Parse the version information argument.+	save_ifs=$IFS; IFS=:+	set dummy $vinfo 0 0 0+	shift+	IFS=$save_ifs++	test -n "$7" && \+	  func_fatal_help "too many parameters to '-version-info'"++	# convert absolute version numbers to libtool ages+	# this retains compatibility with .la files and attempts+	# to make the code below a bit more comprehensible++	case $vinfo_number in+	yes)+	  number_major=$1+	  number_minor=$2+	  number_revision=$3+	  #+	  # There are really only two kinds -- those that+	  # use the current revision as the major version+	  # and those that subtract age and use age as+	  # a minor version.  But, then there is irix+	  # that has an extra 1 added just for fun+	  #+	  case $version_type in+	  # correct linux to gnu/linux during the next big refactor+	  darwin|freebsd-elf|linux|midnightbsd-elf|osf|qnx|windows|none)+	    func_arith $number_major + $number_minor+	    current=$func_arith_result+	    age=$number_minor+	    revision=$number_revision+	    ;;+	  freebsd-aout|sco|sunos)+	    current=$number_major+	    revision=$number_minor+	    age=0+	    ;;+	  irix|nonstopux)+	    func_arith $number_major + $number_minor+	    current=$func_arith_result+	    age=$number_minor+	    revision=$number_minor+	    lt_irix_increment=no+	    ;;+	  *)+	    func_fatal_configuration "$modename: unknown library version type '$version_type'"+	    ;;+	  esac+	  ;;+	no)+	  current=$1+	  revision=$2+	  age=$3+	  ;;+	esac++	# Check that each of the things are valid numbers.+	case $current in+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;+	*)+	  func_error "CURRENT '$current' must be a nonnegative integer"+	  func_fatal_error "'$vinfo' is not valid version information"+	  ;;+	esac++	case $revision in+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;+	*)+	  func_error "REVISION '$revision' must be a nonnegative integer"+	  func_fatal_error "'$vinfo' is not valid version information"+	  ;;+	esac++	case $age in+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;+	*)+	  func_error "AGE '$age' must be a nonnegative integer"+	  func_fatal_error "'$vinfo' is not valid version information"+	  ;;+	esac++	if test "$age" -gt "$current"; then+	  func_error "AGE '$age' is greater than the current interface number '$current'"+	  func_fatal_error "'$vinfo' is not valid version information"+	fi++	# Calculate the version variables.+	major=+	versuffix=+	verstring=+	case $version_type in+	none) ;;++	darwin)+	  # Like Linux, but with the current version available in+	  # verstring for coding it into the library header+	  func_arith $current - $age+	  major=.$func_arith_result+	  versuffix=$major.$age.$revision+	  # Darwin ld doesn't like 0 for these options...+	  func_arith $current + 1+	  minor_current=$func_arith_result+	  xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"+          # On Darwin other compilers+          case $CC in+              nagfor*)+                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"+                  ;;+              *)+                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"+                  ;;+          esac+	  ;;++	freebsd-aout)+	  major=.$current+	  versuffix=.$current.$revision+	  ;;++	freebsd-elf | midnightbsd-elf)+	  func_arith $current - $age+	  major=.$func_arith_result+	  versuffix=$major.$age.$revision+	  ;;++	irix | nonstopux)+	  if test no = "$lt_irix_increment"; then+	    func_arith $current - $age+	  else+	    func_arith $current - $age + 1+	  fi+	  major=$func_arith_result++	  case $version_type in+	    nonstopux) verstring_prefix=nonstopux ;;+	    *)         verstring_prefix=sgi ;;+	  esac+	  verstring=$verstring_prefix$major.$revision++	  # Add in all the interfaces that we are compatible with.+	  loop=$revision+	  while test 0 -ne "$loop"; do+	    func_arith $revision - $loop+	    iface=$func_arith_result+	    func_arith $loop - 1+	    loop=$func_arith_result+	    verstring=$verstring_prefix$major.$iface:$verstring+	  done++	  # Before this point, $major must not contain '.'.+	  major=.$major+	  versuffix=$major.$revision+	  ;;++	linux) # correct to gnu/linux during the next big refactor+	  func_arith $current - $age+	  major=.$func_arith_result+	  versuffix=$major.$age.$revision+	  ;;++	osf)+	  func_arith $current - $age+	  major=.$func_arith_result+	  versuffix=.$current.$age.$revision+	  verstring=$current.$age.$revision++	  # Add in all the interfaces that we are compatible with.+	  loop=$age+	  while test 0 -ne "$loop"; do+	    func_arith $current - $loop+	    iface=$func_arith_result+	    func_arith $loop - 1+	    loop=$func_arith_result+	    verstring=$verstring:$iface.0+	  done++	  # Make executables depend on our current version.+	  func_append verstring ":$current.0"+	  ;;++	qnx)+	  func_arith $current - $age+	  major=.$func_arith_result+	  versuffix=$major.$age.$revision+	  ;;++	sco)+	  major=.$current+	  versuffix=.$current+	  ;;++	sunos)+	  major=.$current+	  versuffix=.$current.$revision+	  ;;++	windows)+	  # Use '-' rather than '.', since we only want one+	  # extension on DOS 8.3 file systems.+	  func_arith $current - $age+	  major=$func_arith_result+	  versuffix=-$major+	  ;;++	*)+	  func_fatal_configuration "unknown library version type '$version_type'"+	  ;;+	esac++	# Clear the version info if we defaulted, and they specified a release.+	if test -z "$vinfo" && test -n "$release"; then+	  major=+	  case $version_type in+	  darwin)+	    # we can't check for "0.0" in archive_cmds due to quoting+	    # problems, so we reset it completely+	    verstring=+	    ;;+	  *)+	    verstring=0.0+	    ;;+	  esac+	  if test no = "$need_version"; then+	    versuffix=+	  else+	    versuffix=.0.0+	  fi+	fi++	# Remove version info from name if versioning should be avoided+	if test yes,no = "$avoid_version,$need_version"; then+	  major=+	  versuffix=+	  verstring=+	fi++	# Check to see if the archive will have undefined symbols.+	if test yes = "$allow_undefined"; then+	  if test unsupported = "$allow_undefined_flag"; then+	    if test yes = "$build_old_libs"; then+	      func_warning "undefined symbols not allowed in $host shared libraries; building static only"+	      build_libtool_libs=no+	    else+	      func_fatal_error "can't build $host shared library unless -no-undefined is specified"+	    fi+	  fi+	else+	  # Don't allow undefined symbols.+	  allow_undefined_flag=$no_undefined_flag+	fi++      fi++      func_generate_dlsyms "$libname" "$libname" :+      func_append libobjs " $symfileobj"+      test " " = "$libobjs" && libobjs=++      if test relink != "$opt_mode"; then+	# Remove our outputs, but don't remove object files since they+	# may have been created when compiling PIC objects.+	removelist=+	tempremovelist=`$ECHO "$output_objdir/*"`+	for p in $tempremovelist; do+	  case $p in+	    *.$objext | *.gcno)+	       ;;+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)+	       if test -n "$precious_files_regex"; then+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1+		 then+		   continue+		 fi+	       fi+	       func_append removelist " $p"+	       ;;+	    *) ;;+	  esac+	done+	test -n "$removelist" && \+	  func_show_eval "${RM}r \$removelist"+      fi++      # Now set the variables for building old libraries.+      if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then+	func_append oldlibs " $output_objdir/$libname.$libext"++	# Transform .lo files to .o files.+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`+      fi++      # Eliminate all temporary directories.+      #for path in $notinst_path; do+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`+      #done++      if test -n "$xrpath"; then+	# If the user specified any rpath flags, then add them.+	temp_xrpath=+	for libdir in $xrpath; do+	  func_replace_sysroot "$libdir"+	  func_append temp_xrpath " -R$func_replace_sysroot_result"+	  case "$finalize_rpath " in+	  *" $libdir "*) ;;+	  *) func_append finalize_rpath " $libdir" ;;+	  esac+	done+	if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then+	  dependency_libs="$temp_xrpath $dependency_libs"+	fi+      fi++      # Make sure dlfiles contains only unique files that won't be dlpreopened+      old_dlfiles=$dlfiles+      dlfiles=+      for lib in $old_dlfiles; do+	case " $dlprefiles $dlfiles " in+	*" $lib "*) ;;+	*) func_append dlfiles " $lib" ;;+	esac+      done++      # Make sure dlprefiles contains only unique files+      old_dlprefiles=$dlprefiles+      dlprefiles=+      for lib in $old_dlprefiles; do+	case "$dlprefiles " in+	*" $lib "*) ;;+	*) func_append dlprefiles " $lib" ;;+	esac+      done++      if test yes = "$build_libtool_libs"; then+	if test -n "$rpath"; then+	  case $host in+	  *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)+	    # these systems don't actually have a c library (as such)!+	    ;;+	  *-*-rhapsody* | *-*-darwin1.[012])+	    # Rhapsody C library is in the System framework+	    func_append deplibs " System.ltframework"+	    ;;+	  *-*-netbsd*)+	    # Don't link with libc until the a.out ld.so is fixed.+	    ;;+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)+	    # Do not include libc due to us having libc/libc_r.+	    ;;+	  *-*-sco3.2v5* | *-*-sco5v6*)+	    # Causes problems with __ctype+	    ;;+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)+	    # Compiler inserts libc in the correct place for threads to work+	    ;;+	  *)+	    # Add libc to deplibs on all other systems if necessary.+	    if test yes = "$build_libtool_need_lc"; then+	      func_append deplibs " -lc"+	    fi+	    ;;+	  esac+	fi++	# Transform deplibs into only deplibs that can be linked in shared.+	name_save=$name+	libname_save=$libname+	release_save=$release+	versuffix_save=$versuffix+	major_save=$major+	# I'm not sure if I'm treating the release correctly.  I think+	# release should show up in the -l (ie -lgmp5) so we don't want to+	# add it in twice.  Is that correct?+	release=+	versuffix=+	major=+	newdeplibs=+	droppeddeps=no+	case $deplibs_check_method in+	pass_all)+	  # Don't check for shared/static.  Everything works.+	  # This might be a little naive.  We might want to check+	  # whether the library exists or not.  But this is on+	  # osf3 & osf4 and I'm not really sure... Just+	  # implementing what was already the behavior.+	  newdeplibs=$deplibs+	  ;;+	file_magic*)+	  set dummy $deplibs_check_method; shift+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`+	  for a_deplib in $deplibs; do+	    case $a_deplib in+	    -l*)+	      func_stripname -l '' "$a_deplib"+	      name=$func_stripname_result+	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then+		case " $predeps $postdeps " in+		*" $a_deplib "*)+		  func_append newdeplibs " $a_deplib"+		  a_deplib=+		  ;;+		esac+	      fi+	      if test -n "$a_deplib"; then+		libname=`eval "\\$ECHO \"$libname_spec\""`+		if test -n "$file_magic_glob"; then+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`+		else+		  libnameglob=$libname+		fi+		test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do+		  if test yes = "$want_nocaseglob"; then+		    shopt -s nocaseglob+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`+		    $nocaseglob+		  else+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`+		  fi+		  for potent_lib in $potential_libs; do+		      # Follow soft links.+		      if ls -lLd "$potent_lib" 2>/dev/null |+			 $GREP " -> " >/dev/null; then+			continue+		      fi+		      # The statement above tries to avoid entering an+		      # endless loop below, in case of cyclic links.+		      # We might still enter an endless loop, since a link+		      # loop can be closed while we follow links,+		      # but so what?+		      potlib=$potent_lib+		      while test -h "$potlib" 2>/dev/null; do+			potliblink=`ls -ld $potlib | $SED 's/.* -> //'`+			case $potliblink in+			[\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;+			*) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;+			esac+		      done+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |+			 $SED -e 10q |+			 $EGREP "$file_magic_regex" > /dev/null; then+			func_append newdeplibs " $a_deplib"+			a_deplib=+			break 2+		      fi+		  done+		done+	      fi+	      if test -n "$a_deplib"; then+		droppeddeps=yes+		func_warning "Linker path does not have real file for library $a_deplib."+		func_warning "I have the capability to make that library automatically link in when"+		func_warning "you link to this library.  But I can only do this if you have a"+		func_warning "shared version of the library, which you do not appear to have"+		func_warning "because I did check the linker path looking for a file starting"+		if test -z "$potlib"; then+		  func_warning "with $libname but no candidates were found. (...for file magic test)"+		else+		  func_warning "with $libname and none of the candidates passed a file format test"+		  func_warning "using a file magic. Last file checked: $potlib"+		fi+	      fi+	      ;;+	    *)+	      # Add a -L argument.+	      func_append newdeplibs " $a_deplib"+	      ;;+	    esac+	  done # Gone through all deplibs.+	  ;;+	match_pattern*)+	  set dummy $deplibs_check_method; shift+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`+	  for a_deplib in $deplibs; do+	    case $a_deplib in+	    -l*)+	      func_stripname -l '' "$a_deplib"+	      name=$func_stripname_result+	      if test yes = "$allow_libtool_libs_with_static_runtimes"; then+		case " $predeps $postdeps " in+		*" $a_deplib "*)+		  func_append newdeplibs " $a_deplib"+		  a_deplib=+		  ;;+		esac+	      fi+	      if test -n "$a_deplib"; then+		libname=`eval "\\$ECHO \"$libname_spec\""`+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`+		  for potent_lib in $potential_libs; do+		    potlib=$potent_lib # see symlink-check above in file_magic test+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \+		       $EGREP "$match_pattern_regex" > /dev/null; then+		      func_append newdeplibs " $a_deplib"+		      a_deplib=+		      break 2+		    fi+		  done+		done+	      fi+	      if test -n "$a_deplib"; then+		droppeddeps=yes+		func_warning "Linker path does not have real file for library $a_deplib."+		func_warning "I have the capability to make that library automatically link in when"+		func_warning "you link to this library.  But I can only do this if you have a"+		func_warning "shared version of the library, which you do not appear to have"+		func_warning "because I did check the linker path looking for a file starting"+		if test -z "$potlib"; then+		  func_warning "with $libname but no candidates were found. (...for regex pattern test)"+		else+		  func_warning "with $libname and none of the candidates passed a file format test"+		  func_warning "using a regex pattern. Last file checked: $potlib"+		fi+	      fi+	      ;;+	    *)+	      # Add a -L argument.+	      func_append newdeplibs " $a_deplib"+	      ;;+	    esac+	  done # Gone through all deplibs.+	  ;;+	none | unknown | *)+	  newdeplibs=+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`+	  if test yes = "$allow_libtool_libs_with_static_runtimes"; then+	    for i in $predeps $postdeps; do+	      # can't use Xsed below, because $i might contain '/'+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`+	    done+	  fi+	  case $tmp_deplibs in+	  *[!\	\ ]*)+	    echo+	    if test none = "$deplibs_check_method"; then+	      func_warning "Inter-library dependencies are not supported in this platform."+	    else+	      func_warning "Inter-library dependencies are not known to be supported."+	    fi+	    func_warning "All declared inter-library dependencies are being dropped."+	    droppeddeps=yes+	    ;;+	  esac+	  ;;+	esac+	versuffix=$versuffix_save+	major=$major_save+	release=$release_save+	libname=$libname_save+	name=$name_save++	case $host in+	*-*-rhapsody* | *-*-darwin1.[012])+	  # On Rhapsody replace the C library with the System framework+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`+	  ;;+	esac++	if test yes = "$droppeddeps"; then+	  if test yes = "$module"; then+	    func_warning "libtool could not satisfy all declared inter-library"+	    func_warning "dependencies of module $libname.  Therefore, libtool will create"+	    func_warning "a static module, that should work as long as the dlopening"+	    func_warning "application is linked with the -dlopen flag."+	    if test -z "$global_symbol_pipe"; then+	      func_warning "However, this would only work if libtool was able to extract symbol"+	      func_warning "lists from a program, using 'nm' or equivalent, but libtool could"+	      func_warning "not find such a program.  So, this module is probably useless."+	      func_warning "'nm' from GNU binutils and a full rebuild may help."+	    fi+	    if test no = "$build_old_libs"; then+	      oldlibs=$output_objdir/$libname.$libext+	      build_libtool_libs=module+	      build_old_libs=yes+	    else+	      build_libtool_libs=no+	    fi+	  else+	    echo "*** The inter-library dependencies that have been dropped here will be"+	    echo "*** automatically added whenever a program is linked with this library"+	    echo "*** or is declared to -dlopen it."++	    if test no = "$allow_undefined"; then+	      echo+	      echo "*** Since this library must not contain undefined symbols,"+	      echo "*** because either the platform does not support them or"+	      echo "*** it was explicitly requested with -no-undefined,"+	      echo "*** libtool will only create a static version of it."+	      if test no = "$build_old_libs"; then+		oldlibs=$output_objdir/$libname.$libext+		build_libtool_libs=module+		build_old_libs=yes+	      else+		build_libtool_libs=no+	      fi+	    fi+	  fi+	fi+	# Done checking deplibs!+	deplibs=$newdeplibs+      fi+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"+      case $host in+	*-*-darwin*)+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	  ;;+      esac++      # move library search paths that coincide with paths to not yet+      # installed libraries to the beginning of the library search list+      new_libs=+      for path in $notinst_path; do+	case " $new_libs " in+	*" -L$path/$objdir "*) ;;+	*)+	  case " $deplibs " in+	  *" -L$path/$objdir "*)+	    func_append new_libs " -L$path/$objdir" ;;+	  esac+	  ;;+	esac+      done+      for deplib in $deplibs; do+	case $deplib in+	-L*)+	  case " $new_libs " in+	  *" $deplib "*) ;;+	  *) func_append new_libs " $deplib" ;;+	  esac+	  ;;+	*) func_append new_libs " $deplib" ;;+	esac+      done+      deplibs=$new_libs++      # All the library-specific variables (install_libdir is set above).+      library_names=+      old_library=+      dlname=++      # Test again, we may have decided not to build it any more+      if test yes = "$build_libtool_libs"; then+	# Remove $wl instances when linking with ld.+	# FIXME: should test the right _cmds variable.+	case $archive_cmds in+	  *\$LD\ *) wl= ;;+        esac+	if test yes = "$hardcode_into_libs"; then+	  # Hardcode the library paths+	  hardcode_libdirs=+	  dep_rpath=+	  rpath=$finalize_rpath+	  test relink = "$opt_mode" || rpath=$compile_rpath$rpath+	  for libdir in $rpath; do+	    if test -n "$hardcode_libdir_flag_spec"; then+	      if test -n "$hardcode_libdir_separator"; then+		func_replace_sysroot "$libdir"+		libdir=$func_replace_sysroot_result+		if test -z "$hardcode_libdirs"; then+		  hardcode_libdirs=$libdir+		else+		  # Just accumulate the unique libdirs.+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)+		    ;;+		  *)+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"+		    ;;+		  esac+		fi+	      else+		eval flag=\"$hardcode_libdir_flag_spec\"+		func_append dep_rpath " $flag"+	      fi+	    elif test -n "$runpath_var"; then+	      case "$perm_rpath " in+	      *" $libdir "*) ;;+	      *) func_append perm_rpath " $libdir" ;;+	      esac+	    fi+	  done+	  # Substitute the hardcoded libdirs into the rpath.+	  if test -n "$hardcode_libdir_separator" &&+	     test -n "$hardcode_libdirs"; then+	    libdir=$hardcode_libdirs+	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""+	  fi+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then+	    # We should set the runpath_var.+	    rpath=+	    for dir in $perm_rpath; do+	      func_append rpath "$dir:"+	    done+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"+	  fi+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"+	fi++	shlibpath=$finalize_shlibpath+	test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath+	if test -n "$shlibpath"; then+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"+	fi++	# Get the real and link names of the library.+	eval shared_ext=\"$shrext_cmds\"+	eval library_names=\"$library_names_spec\"+	set dummy $library_names+	shift+	realname=$1+	shift++	if test -n "$soname_spec"; then+	  eval soname=\"$soname_spec\"+	else+	  soname=$realname+	fi+	if test -z "$dlname"; then+	  dlname=$soname+	fi++	lib=$output_objdir/$realname+	linknames=+	for link+	do+	  func_append linknames " $link"+	done++	# Use standard objects if they are pic+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`+	test "X$libobjs" = "X " && libobjs=++	delfiles=+	if test -n "$export_symbols" && test -n "$include_expsyms"; then+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"+	  export_symbols=$output_objdir/$libname.uexp+	  func_append delfiles " $export_symbols"+	fi++	orig_export_symbols=+	case $host_os in+	cygwin* | mingw* | windows* | cegcc*)+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then+	    # exporting using user supplied symfile+	    func_dll_def_p "$export_symbols" || {+	      # and it's NOT already a .def file. Must figure out+	      # which of the given symbols are data symbols and tag+	      # them as such. So, trigger use of export_symbols_cmds.+	      # export_symbols gets reassigned inside the "prepare+	      # the list of exported symbols" if statement, so the+	      # include_expsyms logic still works.+	      orig_export_symbols=$export_symbols+	      export_symbols=+	      always_export_symbols=yes+	    }+	  fi+	  ;;+	esac++	# Prepare the list of exported symbols+	if test -z "$export_symbols"; then+	  if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then+	    func_verbose "generating symbol list for '$libname.la'"+	    export_symbols=$output_objdir/$libname.exp+	    $opt_dry_run || $RM $export_symbols+	    cmds=$export_symbols_cmds+	    save_ifs=$IFS; IFS='~'+	    for cmd1 in $cmds; do+	      IFS=$save_ifs+	      # Take the normal branch if the nm_file_list_spec branch+	      # doesn't work or if tool conversion is not needed.+	      case $nm_file_list_spec~$to_tool_file_cmd in+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)+		  try_normal_branch=yes+		  eval cmd=\"$cmd1\"+		  func_len " $cmd"+		  len=$func_len_result+		  ;;+		*)+		  try_normal_branch=no+		  ;;+	      esac+	      if test yes = "$try_normal_branch" \+		 && { test "$len" -lt "$max_cmd_len" \+		      || test "$max_cmd_len" -le -1; }+	      then+		func_show_eval "$cmd" 'exit $?'+		skipped_export=false+	      elif test -n "$nm_file_list_spec"; then+		func_basename "$output"+		output_la=$func_basename_result+		save_libobjs=$libobjs+		save_output=$output+		output=$output_objdir/$output_la.nm+		func_to_tool_file "$output"+		libobjs=$nm_file_list_spec$func_to_tool_file_result+		func_append delfiles " $output"+		func_verbose "creating $NM input file list: $output"+		for obj in $save_libobjs; do+		  func_to_tool_file "$obj"+		  $ECHO "$func_to_tool_file_result"+		done > "$output"+		eval cmd=\"$cmd1\"+		func_show_eval "$cmd" 'exit $?'+		output=$save_output+		libobjs=$save_libobjs+		skipped_export=false+	      else+		# The command line is too long to execute in one step.+		func_verbose "using reloadable object file for export list..."+		skipped_export=:+		# Break out early, otherwise skipped_export may be+		# set to false by a later but shorter cmd.+		break+	      fi+	    done+	    IFS=$save_ifs+	    if test -n "$export_symbols_regex" && test : != "$skipped_export"; then+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'+	    fi+	  fi+	fi++	if test -n "$export_symbols" && test -n "$include_expsyms"; then+	  tmp_export_symbols=$export_symbols+	  test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'+	fi++	if test : != "$skipped_export" && test -n "$orig_export_symbols"; then+	  # The given exports_symbols file has to be filtered, so filter it.+	  func_verbose "filter symbol list for '$libname.la' to tag DATA exports"+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of+	  # 's' commands, which not all seds can handle. GNU sed should be fine+	  # though. Also, the filter scales superlinearly with the number of+	  # global variables. join(1) would be nice here, but unfortunately+	  # isn't a blessed tool.+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"+	  export_symbols=$output_objdir/$libname.def+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols+	fi++	tmp_deplibs=+	for test_deplib in $deplibs; do+	  case " $convenience " in+	  *" $test_deplib "*) ;;+	  *)+	    func_append tmp_deplibs " $test_deplib"+	    ;;+	  esac+	done+	deplibs=$tmp_deplibs++	if test -n "$convenience"; then+	  if test -n "$whole_archive_flag_spec" &&+	    test yes = "$compiler_needs_object" &&+	    test -z "$libobjs"; then+	    # extract the archives, so we have objects to list.+	    # TODO: could optimize this to just extract one archive.+	    whole_archive_flag_spec=+	  fi+	  if test -n "$whole_archive_flag_spec"; then+	    save_libobjs=$libobjs+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"+	    test "X$libobjs" = "X " && libobjs=+	  else+	    gentop=$output_objdir/${outputname}x+	    func_append generated " $gentop"++	    func_extract_archives $gentop $convenience+	    func_append libobjs " $func_extract_archives_result"+	    test "X$libobjs" = "X " && libobjs=+	  fi+	fi++	if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then+	  eval flag=\"$thread_safe_flag_spec\"+	  func_append linker_flags " $flag"+	fi++	# Make a backup of the uninstalled library when relinking+	if test relink = "$opt_mode"; then+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?+	fi++	# Do each of the archive commands.+	if test yes = "$module" && test -n "$module_cmds"; then+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then+	    eval test_cmds=\"$module_expsym_cmds\"+	    cmds=$module_expsym_cmds+	  else+	    eval test_cmds=\"$module_cmds\"+	    cmds=$module_cmds+	  fi+	else+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then+	    eval test_cmds=\"$archive_expsym_cmds\"+	    cmds=$archive_expsym_cmds+	  else+	    eval test_cmds=\"$archive_cmds\"+	    cmds=$archive_cmds+	  fi+	fi++	if test : != "$skipped_export" &&+	   func_len " $test_cmds" &&+	   len=$func_len_result &&+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then+	  :+	else+	  # The command line is too long to link in one step, link piecewise+	  # or, if using GNU ld and skipped_export is not :, use a linker+	  # script.++	  # Save the value of $output and $libobjs because we want to+	  # use them later.  If we have whole_archive_flag_spec, we+	  # want to use save_libobjs as it was before+	  # whole_archive_flag_spec was expanded, because we can't+	  # assume the linker understands whole_archive_flag_spec.+	  # This may have to be revisited, in case too many+	  # convenience libraries get linked in and end up exceeding+	  # the spec.+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then+	    save_libobjs=$libobjs+	  fi+	  save_output=$output+	  func_basename "$output"+	  output_la=$func_basename_result++	  # Clear the reloadable object creation command queue and+	  # initialize k to one.+	  test_cmds=+	  concat_cmds=+	  objlist=+	  last_robj=+	  k=1++	  if test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then+	    output=$output_objdir/$output_la.lnk+	    func_verbose "creating linker input file list: $output"+	    : > $output+	    set x $save_libobjs+	    shift+	    firstobj=+	    if test yes = "$compiler_needs_object"; then+	      firstobj="$1 "+	      shift+	    fi+	    for obj+	    do+	      func_to_tool_file "$obj"+	      $ECHO "$func_to_tool_file_result" >> $output+	    done+	    func_append delfiles " $output"+	    func_to_tool_file "$output"+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"+	  elif test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then+	    output=$output_objdir/$output_la.lnkscript+	    func_verbose "creating GNU ld script: $output"+	    echo 'INPUT (' > $output+	    for obj in $save_libobjs+	    do+	      func_to_tool_file "$obj"+	      $ECHO "$func_to_tool_file_result" >> $output+	    done+	    echo ')' >> $output+	    func_append delfiles " $output"+	    func_to_tool_file "$output"+	    output=$func_to_tool_file_result+	  else+	    if test -n "$save_libobjs"; then+	      func_verbose "creating reloadable object files..."+	      output=$output_objdir/$output_la-$k.$objext+	      eval test_cmds=\"$reload_cmds\"+	      func_len " $test_cmds"+	      len0=$func_len_result+	      len=$len0++	      # Loop over the list of objects to be linked.+	      for obj in $save_libobjs+	      do+		func_len " $obj"+		func_arith $len + $func_len_result+		len=$func_arith_result+		if test -z "$objlist" ||+		   test "$len" -lt "$max_cmd_len"; then+		  func_append objlist " $obj"+		else+		  # The command $test_cmds is almost too long, add a+		  # command to the queue.+		  if test 1 -eq "$k"; then+		    # The first file doesn't have a previous command to add.+		    reload_objs=$objlist+		    eval concat_cmds=\"$reload_cmds\"+		  else+		    # All subsequent reloadable object files will link in+		    # the last one created.+		    reload_objs="$objlist $last_robj"+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"+		  fi+		  last_robj=$output_objdir/$output_la-$k.$objext+		  func_arith $k + 1+		  k=$func_arith_result+		  output=$output_objdir/$output_la-$k.$objext+		  objlist=" $obj"+		  func_len " $last_robj"+		  func_arith $len0 + $func_len_result+		  len=$func_arith_result+		fi+	      done+	      # Handle the remaining objects by creating one last+	      # reloadable object file.  All subsequent reloadable object+	      # files will link in the last one created.+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~+	      reload_objs="$objlist $last_robj"+	      eval concat_cmds=\"\$concat_cmds$reload_cmds\"+	      if test -n "$last_robj"; then+	        eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"+	      fi+	      func_append delfiles " $output"++	    else+	      output=+	    fi++	    ${skipped_export-false} && {+	      func_verbose "generating symbol list for '$libname.la'"+	      export_symbols=$output_objdir/$libname.exp+	      $opt_dry_run || $RM $export_symbols+	      libobjs=$output+	      # Append the command to create the export file.+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"+	      if test -n "$last_robj"; then+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"+	      fi+	    }++	    test -n "$save_libobjs" &&+	      func_verbose "creating a temporary reloadable object file: $output"++	    # Loop through the commands generated above and execute them.+	    save_ifs=$IFS; IFS='~'+	    for cmd in $concat_cmds; do+	      IFS=$save_ifs+	      $opt_quiet || {+		  func_quote_arg expand,pretty "$cmd"+		  eval "func_echo $func_quote_arg_result"+	      }+	      $opt_dry_run || eval "$cmd" || {+		lt_exit=$?++		# Restore the uninstalled library and exit+		if test relink = "$opt_mode"; then+		  ( cd "$output_objdir" && \+		    $RM "${realname}T" && \+		    $MV "${realname}U" "$realname" )+		fi++		exit $lt_exit+	      }+	    done+	    IFS=$save_ifs++	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'+	    fi+	  fi++          ${skipped_export-false} && {+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then+	      tmp_export_symbols=$export_symbols+	      test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'+	    fi++	    if test -n "$orig_export_symbols"; then+	      # The given exports_symbols file has to be filtered, so filter it.+	      func_verbose "filter symbol list for '$libname.la' to tag DATA exports"+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of+	      # 's' commands, which not all seds can handle. GNU sed should be fine+	      # though. Also, the filter scales superlinearly with the number of+	      # global variables. join(1) would be nice here, but unfortunately+	      # isn't a blessed tool.+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"+	      export_symbols=$output_objdir/$libname.def+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols+	    fi+	  }++	  libobjs=$output+	  # Restore the value of output.+	  output=$save_output++	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"+	    test "X$libobjs" = "X " && libobjs=+	  fi+	  # Expand the library linking commands again to reset the+	  # value of $libobjs for piecewise linking.++	  # Do each of the archive commands.+	  if test yes = "$module" && test -n "$module_cmds"; then+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then+	      cmds=$module_expsym_cmds+	    else+	      cmds=$module_cmds+	    fi+	  else+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then+	      cmds=$archive_expsym_cmds+	    else+	      cmds=$archive_cmds+	    fi+	  fi+	fi++	if test -n "$delfiles"; then+	  # Append the command to remove temporary files to $cmds.+	  eval cmds=\"\$cmds~\$RM $delfiles\"+	fi++	# Add any objects from preloaded convenience libraries+	if test -n "$dlprefiles"; then+	  gentop=$output_objdir/${outputname}x+	  func_append generated " $gentop"++	  func_extract_archives $gentop $dlprefiles+	  func_append libobjs " $func_extract_archives_result"+	  test "X$libobjs" = "X " && libobjs=+	fi++	save_ifs=$IFS; IFS='~'+	for cmd in $cmds; do+	  IFS=$sp$nl+	  eval cmd=\"$cmd\"+	  IFS=$save_ifs+	  $opt_quiet || {+	    func_quote_arg expand,pretty "$cmd"+	    eval "func_echo $func_quote_arg_result"+	  }+	  $opt_dry_run || eval "$cmd" || {+	    lt_exit=$?++	    # Restore the uninstalled library and exit+	    if test relink = "$opt_mode"; then+	      ( cd "$output_objdir" && \+	        $RM "${realname}T" && \+		$MV "${realname}U" "$realname" )+	    fi++	    exit $lt_exit+	  }+	done+	IFS=$save_ifs++	# Restore the uninstalled library and exit+	if test relink = "$opt_mode"; then+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?++	  if test -n "$convenience"; then+	    if test -z "$whole_archive_flag_spec"; then+	      func_show_eval '${RM}r "$gentop"'+	    fi+	  fi++	  exit $EXIT_SUCCESS+	fi++	# Create links to the real library.+	for linkname in $linknames; do+	  if test "$realname" != "$linkname"; then+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'+	  fi+	done++	# If -module or -export-dynamic was specified, set the dlname.+	if test yes = "$module" || test yes = "$export_dynamic"; then+	  # On all known operating systems, these are identical.+	  dlname=$soname+	fi+      fi+      ;;++    obj)+      if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then+	func_warning "'-dlopen' is ignored for objects"+      fi++      case " $deplibs" in+      *\ -l* | *\ -L*)+	func_warning "'-l' and '-L' are ignored for objects" ;;+      esac++      test -n "$rpath" && \+	func_warning "'-rpath' is ignored for objects"++      test -n "$xrpath" && \+	func_warning "'-R' is ignored for objects"++      test -n "$vinfo" && \+	func_warning "'-version-info' is ignored for objects"++      test -n "$release" && \+	func_warning "'-release' is ignored for objects"++      case $output in+      *.lo)+	test -n "$objs$old_deplibs" && \+	  func_fatal_error "cannot build library object '$output' from non-libtool objects"++	libobj=$output+	func_lo2o "$libobj"+	obj=$func_lo2o_result+	;;+      *)+	libobj=+	obj=$output+	;;+      esac++      # Delete the old objects.+      $opt_dry_run || $RM $obj $libobj++      # Objects from convenience libraries.  This assumes+      # single-version convenience libraries.  Whenever we create+      # different ones for PIC/non-PIC, this we'll have to duplicate+      # the extraction.+      reload_conv_objs=+      gentop=+      # if reload_cmds runs $LD directly, get rid of -Wl from+      # whole_archive_flag_spec and hope we can get by with turning comma+      # into space.+      case $reload_cmds in+        *\$LD[\ \$]*) wl= ;;+      esac+      if test -n "$convenience"; then+	if test -n "$whole_archive_flag_spec"; then+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"+	  test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`+	  reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags+	else+	  gentop=$output_objdir/${obj}x+	  func_append generated " $gentop"++	  func_extract_archives $gentop $convenience+	  reload_conv_objs="$reload_objs $func_extract_archives_result"+	fi+      fi++      # If we're not building shared, we need to use non_pic_objs+      test yes = "$build_libtool_libs" || libobjs=$non_pic_objects++      # Create the old-style object.+      reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs++      output=$obj+      func_execute_cmds "$reload_cmds" 'exit $?'++      # Exit if we aren't doing a library object file.+      if test -z "$libobj"; then+	if test -n "$gentop"; then+	  func_show_eval '${RM}r "$gentop"'+	fi++	exit $EXIT_SUCCESS+      fi++      test yes = "$build_libtool_libs" || {+	if test -n "$gentop"; then+	  func_show_eval '${RM}r "$gentop"'+	fi++	# Create an invalid libtool object if no PIC, so that we don't+	# accidentally link it into a program.+	# $show "echo timestamp > $libobj"+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?+	exit $EXIT_SUCCESS+      }++      if test -n "$pic_flag" || test default != "$pic_mode"; then+	# Only do commands if we really have different PIC objects.+	reload_objs="$libobjs $reload_conv_objs"+	output=$libobj+	func_execute_cmds "$reload_cmds" 'exit $?'+      fi++      if test -n "$gentop"; then+	func_show_eval '${RM}r "$gentop"'+      fi++      exit $EXIT_SUCCESS+      ;;++    prog)+      case $host in+	*cygwin*) func_stripname '' '.exe' "$output"+	          output=$func_stripname_result.exe;;+      esac+      test -n "$vinfo" && \+	func_warning "'-version-info' is ignored for programs"++      test -n "$release" && \+	func_warning "'-release' is ignored for programs"++      $preload \+	&& test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \+	&& func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."++      case $host in+      *-*-rhapsody* | *-*-darwin1.[012])+	# On Rhapsody replace the C library is the System framework+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`+	;;+      esac++      case $host in+      *-*-darwin*)+	# Don't allow lazy linking, it breaks C++ global constructors+	# But is supposedly fixed on 10.4 or later (yay!).+	if test CXX = "$tagname"; then+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in+	    10.[0123])+	      func_append compile_command " $wl-bind_at_load"+	      func_append finalize_command " $wl-bind_at_load"+	    ;;+	  esac+	fi+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`+	;;+      esac+++      # move library search paths that coincide with paths to not yet+      # installed libraries to the beginning of the library search list+      new_libs=+      for path in $notinst_path; do+	case " $new_libs " in+	*" -L$path/$objdir "*) ;;+	*)+	  case " $compile_deplibs " in+	  *" -L$path/$objdir "*)+	    func_append new_libs " -L$path/$objdir" ;;+	  esac+	  ;;+	esac+      done+      for deplib in $compile_deplibs; do+	case $deplib in+	-L*)+	  case " $new_libs " in+	  *" $deplib "*) ;;+	  *) func_append new_libs " $deplib" ;;+	  esac+	  ;;+	*) func_append new_libs " $deplib" ;;+	esac+      done+      compile_deplibs=$new_libs+++      func_append compile_command " $compile_deplibs"+      func_append finalize_command " $finalize_deplibs"++      if test -n "$rpath$xrpath"; then+	# If the user specified any rpath flags, then add them.+	for libdir in $rpath $xrpath; do+	  # This is the magic to use -rpath.+	  case "$finalize_rpath " in+	  *" $libdir "*) ;;+	  *) func_append finalize_rpath " $libdir" ;;+	  esac+	done+      fi++      # Now hardcode the library paths+      rpath=+      hardcode_libdirs=+      for libdir in $compile_rpath $finalize_rpath; do+	if test -n "$hardcode_libdir_flag_spec"; then+	  if test -n "$hardcode_libdir_separator"; then+	    if test -z "$hardcode_libdirs"; then+	      hardcode_libdirs=$libdir+	    else+	      # Just accumulate the unique libdirs.+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)+		;;+	      *)+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"+		;;+	      esac+	    fi+	  else+	    eval flag=\"$hardcode_libdir_flag_spec\"+	    func_append rpath " $flag"+	  fi+	elif test -n "$runpath_var"; then+	  case "$perm_rpath " in+	  *" $libdir "*) ;;+	  *) func_append perm_rpath " $libdir" ;;+	  esac+	fi+	case $host in+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)+	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`+	  case :$dllsearchpath: in+	  *":$libdir:"*) ;;+	  ::) dllsearchpath=$libdir;;+	  *) func_append dllsearchpath ":$libdir";;+	  esac+	  case :$dllsearchpath: in+	  *":$testbindir:"*) ;;+	  ::) dllsearchpath=$testbindir;;+	  *) func_append dllsearchpath ":$testbindir";;+	  esac+	  ;;+	esac+      done+      # Substitute the hardcoded libdirs into the rpath.+      if test -n "$hardcode_libdir_separator" &&+	 test -n "$hardcode_libdirs"; then+	libdir=$hardcode_libdirs+	eval rpath=\" $hardcode_libdir_flag_spec\"+      fi+      compile_rpath=$rpath++      rpath=+      hardcode_libdirs=+      for libdir in $finalize_rpath; do+	if test -n "$hardcode_libdir_flag_spec"; then+	  if test -n "$hardcode_libdir_separator"; then+	    if test -z "$hardcode_libdirs"; then+	      hardcode_libdirs=$libdir+	    else+	      # Just accumulate the unique libdirs.+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)+		;;+	      *)+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"+		;;+	      esac+	    fi+	  else+	    eval flag=\"$hardcode_libdir_flag_spec\"+	    func_append rpath " $flag"+	  fi+	elif test -n "$runpath_var"; then+	  case "$finalize_perm_rpath " in+	  *" $libdir "*) ;;+	  *) func_append finalize_perm_rpath " $libdir" ;;+	  esac+	fi+      done+      # Substitute the hardcoded libdirs into the rpath.+      if test -n "$hardcode_libdir_separator" &&+	 test -n "$hardcode_libdirs"; then+	libdir=$hardcode_libdirs+	eval rpath=\" $hardcode_libdir_flag_spec\"+      fi+      finalize_rpath=$rpath++      if test -n "$libobjs" && test yes = "$build_old_libs"; then+	# Transform all the library objects into standard objects.+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`+      fi++      func_generate_dlsyms "$outputname" "@PROGRAM@" false++      # template prelinking step+      if test -n "$prelink_cmds"; then+	func_execute_cmds "$prelink_cmds" 'exit $?'+      fi++      wrappers_required=:+      case $host in+      *cegcc* | *mingw32ce*)+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.+        wrappers_required=false+        ;;+      *cygwin* | *mingw* | *windows* )+        test yes = "$build_libtool_libs" || wrappers_required=false+        ;;+      *)+        if test no = "$need_relink" || test yes != "$build_libtool_libs"; then+          wrappers_required=false+        fi+        ;;+      esac+      $wrappers_required || {+	# Replace the output file specification.+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`+	link_command=$compile_command$compile_rpath++	# We have no uninstalled library dependencies, so finalize right now.+	exit_status=0+	func_show_eval "$link_command" 'exit_status=$?'++	if test -n "$postlink_cmds"; then+	  func_to_tool_file "$output"+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`+	  func_execute_cmds "$postlink_cmds" 'exit $?'+	fi++	# Delete the generated files.+	if test -f "$output_objdir/${outputname}S.$objext"; then+	  func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'+	fi++	exit $exit_status+      }++      if test -n "$compile_shlibpath$finalize_shlibpath"; then+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"+      fi+      if test -n "$finalize_shlibpath"; then+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"+      fi++      compile_var=+      finalize_var=+      if test -n "$runpath_var"; then+	if test -n "$perm_rpath"; then+	  # We should set the runpath_var.+	  rpath=+	  for dir in $perm_rpath; do+	    func_append rpath "$dir:"+	  done+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "+	fi+	if test -n "$finalize_perm_rpath"; then+	  # We should set the runpath_var.+	  rpath=+	  for dir in $finalize_perm_rpath; do+	    func_append rpath "$dir:"+	  done+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "+	fi+      fi++      if test yes = "$no_install"; then+	# We don't need to create a wrapper script.+	link_command=$compile_var$compile_command$compile_rpath+	# Replace the output file specification.+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`+	# Delete the old output file.+	$opt_dry_run || $RM $output+	# Link the executable and exit+	func_show_eval "$link_command" 'exit $?'++	if test -n "$postlink_cmds"; then+	  func_to_tool_file "$output"+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`+	  func_execute_cmds "$postlink_cmds" 'exit $?'+	fi++	exit $EXIT_SUCCESS+      fi++      case $hardcode_action,$fast_install in+        relink,*)+	  # Fast installation is not supported+	  link_command=$compile_var$compile_command$compile_rpath+	  relink_command=$finalize_var$finalize_command$finalize_rpath++	  func_warning "this platform does not like uninstalled shared libraries"+	  func_warning "'$output' will be relinked during installation"+	  ;;+        *,yes)+	  link_command=$finalize_var$compile_command$finalize_rpath+	  relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`+          ;;+	*,no)+	  link_command=$compile_var$compile_command$compile_rpath+	  relink_command=$finalize_var$finalize_command$finalize_rpath+          ;;+	*,needless)+	  link_command=$finalize_var$compile_command$finalize_rpath+	  relink_command=+          ;;+      esac++      # Replace the output file specification.+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`++      # Delete the old output files.+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname++      func_show_eval "$link_command" 'exit $?'++      if test -n "$postlink_cmds"; then+	func_to_tool_file "$output_objdir/$outputname"+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`+	func_execute_cmds "$postlink_cmds" 'exit $?'+      fi++      # Now create the wrapper script.+      func_verbose "creating $output"++      # Quote the relink command for shipping.+      if test -n "$relink_command"; then+	# Preserve any variables that may affect compiler behavior+	for var in $variables_saved_for_relink; do+	  if eval test -z \"\${$var+set}\"; then+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"+	  elif eval var_value=\$$var; test -z "$var_value"; then+	    relink_command="$var=; export $var; $relink_command"+	  else+	    func_quote_arg pretty "$var_value"+	    relink_command="$var=$func_quote_arg_result; export $var; $relink_command"+	  fi+	done+	func_quote eval cd "`pwd`"+	func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"+	relink_command=$func_quote_arg_unquoted_result+      fi++      # Only actually do things if not in dry run mode.+      $opt_dry_run || {+	# win32 will think the script is a binary if it has+	# a .exe suffix, so we strip it off here.+	case $output in+	  *.exe) func_stripname '' '.exe' "$output"+	         output=$func_stripname_result ;;+	esac+	# test for cygwin because mv fails w/o .exe extensions+	case $host in+	  *cygwin*)+	    exeext=.exe+	    func_stripname '' '.exe' "$outputname"+	    outputname=$func_stripname_result ;;+	  *) exeext= ;;+	esac+	case $host in+	  *cygwin* | *mingw* | windows* )+	    func_dirname_and_basename "$output" "" "."+	    output_name=$func_basename_result+	    output_path=$func_dirname_result+	    cwrappersource=$output_path/$objdir/lt-$output_name.c+	    cwrapper=$output_path/$output_name.exe+	    $RM $cwrappersource $cwrapper+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15++	    func_emit_cwrapperexe_src > $cwrappersource++	    # The wrapper executable is built using the $host compiler,+	    # because it contains $host paths and files. If cross-+	    # compiling, it, like the target executable, must be+	    # executed on the $host or under an emulation environment.+	    $opt_dry_run || {+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource+	      $STRIP $cwrapper+	    }++	    # Now, create the wrapper script for func_source use:+	    func_ltwrapper_scriptname $cwrapper+	    $RM $func_ltwrapper_scriptname_result+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15+	    $opt_dry_run || {+	      # note: this script will not be executed, so do not chmod.+	      if test "x$build" = "x$host"; then+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result+	      else+		func_emit_wrapper no > $func_ltwrapper_scriptname_result+	      fi+	    }+	  ;;+	  * )+	    $RM $output+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15++	    func_emit_wrapper no > $output+	    chmod +x $output+	  ;;+	esac+      }+      exit $EXIT_SUCCESS+      ;;+    esac++    # See if we need to build an old-fashioned archive.+    for oldlib in $oldlibs; do++      case $build_libtool_libs in+        convenience)+	  oldobjs="$libobjs_save $symfileobj"+	  addlibs=$convenience+	  build_libtool_libs=no+	  ;;+	module)+	  oldobjs=$libobjs_save+	  addlibs=$old_convenience+	  build_libtool_libs=no+          ;;+	*)+	  oldobjs="$old_deplibs $non_pic_objects"+	  $preload && test -f "$symfileobj" \+	    && func_append oldobjs " $symfileobj"+	  addlibs=$old_convenience+	  ;;+      esac++      if test -n "$addlibs"; then+	gentop=$output_objdir/${outputname}x+	func_append generated " $gentop"++	func_extract_archives $gentop $addlibs+	func_append oldobjs " $func_extract_archives_result"+      fi++      # Do each command in the archive commands.+      if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then+	cmds=$old_archive_from_new_cmds+      else++	# Add any objects from preloaded convenience libraries+	if test -n "$dlprefiles"; then+	  gentop=$output_objdir/${outputname}x+	  func_append generated " $gentop"++	  func_extract_archives $gentop $dlprefiles+	  func_append oldobjs " $func_extract_archives_result"+	fi++	# POSIX demands no paths to be encoded in archives.  We have+	# to avoid creating archives with duplicate basenames if we+	# might have to extract them afterwards, e.g., when creating a+	# static archive out of a convenience library, or when linking+	# the entirety of a libtool archive into another (currently+	# not supported by libtool).+	if (for obj in $oldobjs+	    do+	      func_basename "$obj"+	      $ECHO "$func_basename_result"+	    done | sort | sort -uc >/dev/null 2>&1); then+	  :+	else+	  echo "copying selected object files to avoid basename conflicts..."+	  gentop=$output_objdir/${outputname}x+	  func_append generated " $gentop"+	  func_mkdir_p "$gentop"+	  save_oldobjs=$oldobjs+	  oldobjs=+	  counter=1+	  for obj in $save_oldobjs+	  do+	    func_basename "$obj"+	    objbase=$func_basename_result+	    case " $oldobjs " in+	    " ") oldobjs=$obj ;;+	    *[\ /]"$objbase "*)+	      while :; do+		# Make sure we don't pick an alternate name that also+		# overlaps.+		newobj=lt$counter-$objbase+		func_arith $counter + 1+		counter=$func_arith_result+		case " $oldobjs " in+		*[\ /]"$newobj "*) ;;+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;+		esac+	      done+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"+	      func_append oldobjs " $gentop/$newobj"+	      ;;+	    *) func_append oldobjs " $obj" ;;+	    esac+	  done+	fi+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32+	tool_oldlib=$func_to_tool_file_result+	eval cmds=\"$old_archive_cmds\"++	func_len " $cmds"+	len=$func_len_result+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then+	  cmds=$old_archive_cmds+	elif test -n "$archiver_list_spec"; then+	  func_verbose "using command file archive linking..."+	  for obj in $oldobjs+	  do+	    func_to_tool_file "$obj"+	    $ECHO "$func_to_tool_file_result"+	  done > $output_objdir/$libname.libcmd+	  func_to_tool_file "$output_objdir/$libname.libcmd"+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"+	  cmds=$old_archive_cmds+	else+	  # the command line is too long to link in one step, link in parts+	  func_verbose "using piecewise archive linking..."+	  save_RANLIB=$RANLIB+	  RANLIB=:+	  objlist=+	  concat_cmds=+	  save_oldobjs=$oldobjs+	  oldobjs=+	  # Is there a better way of finding the last object in the list?+	  for obj in $save_oldobjs+	  do+	    last_oldobj=$obj+	  done+	  eval test_cmds=\"$old_archive_cmds\"+	  func_len " $test_cmds"+	  len0=$func_len_result+	  len=$len0+	  for obj in $save_oldobjs+	  do+	    func_len " $obj"+	    func_arith $len + $func_len_result+	    len=$func_arith_result+	    func_append objlist " $obj"+	    if test "$len" -lt "$max_cmd_len"; then+	      :+	    else+	      # the above command should be used before it gets too long+	      oldobjs=$objlist+	      if test "$obj" = "$last_oldobj"; then+		RANLIB=$save_RANLIB+	      fi+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~+	      eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"+	      objlist=+	      len=$len0+	    fi+	  done+	  RANLIB=$save_RANLIB+	  oldobjs=$objlist+	  if test -z "$oldobjs"; then+	    eval cmds=\"\$concat_cmds\"+	  else+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"+	  fi+	fi+      fi+      func_execute_cmds "$cmds" 'exit $?'+    done++    test -n "$generated" && \+      func_show_eval "${RM}r$generated"++    # Now create the libtool archive.+    case $output in+    *.la)+      old_library=+      test yes = "$build_old_libs" && old_library=$libname.$libext+      func_verbose "creating $output"++      # Preserve any variables that may affect compiler behavior+      for var in $variables_saved_for_relink; do+	if eval test -z \"\${$var+set}\"; then+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"+	elif eval var_value=\$$var; test -z "$var_value"; then+	  relink_command="$var=; export $var; $relink_command"+	else+	  func_quote_arg pretty,unquoted "$var_value"+	  relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"+	fi+      done+      # Quote the link command for shipping.+      func_quote eval cd "`pwd`"+      relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"+      func_quote_arg pretty,unquoted "$relink_command"+      relink_command=$func_quote_arg_unquoted_result+      if test yes = "$hardcode_automatic"; then+	relink_command=+      fi++      # Only create the output if not a dry run.+      $opt_dry_run || {+	for installed in no yes; do+	  if test yes = "$installed"; then+	    if test -z "$install_libdir"; then+	      break+	    fi+	    output=$output_objdir/${outputname}i+	    # Replace all uninstalled libtool libraries with the installed ones+	    newdependency_libs=+	    for deplib in $dependency_libs; do+	      case $deplib in+	      *.la)+		func_basename "$deplib"+		name=$func_basename_result+		func_resolve_sysroot "$deplib"+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`+		test -z "$libdir" && \+		  func_fatal_error "'$deplib' is not a valid libtool archive"+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"+		;;+	      -L*)+		func_stripname -L '' "$deplib"+		func_replace_sysroot "$func_stripname_result"+		func_append newdependency_libs " -L$func_replace_sysroot_result"+		;;+	      -R*)+		func_stripname -R '' "$deplib"+		func_replace_sysroot "$func_stripname_result"+		func_append newdependency_libs " -R$func_replace_sysroot_result"+		;;+	      *) func_append newdependency_libs " $deplib" ;;+	      esac+	    done+	    dependency_libs=$newdependency_libs+	    newdlfiles=++	    for lib in $dlfiles; do+	      case $lib in+	      *.la)+	        func_basename "$lib"+		name=$func_basename_result+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`+		test -z "$libdir" && \+		  func_fatal_error "'$lib' is not a valid libtool archive"+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"+		;;+	      *) func_append newdlfiles " $lib" ;;+	      esac+	    done+	    dlfiles=$newdlfiles+	    newdlprefiles=+	    for lib in $dlprefiles; do+	      case $lib in+	      *.la)+		# Only pass preopened files to the pseudo-archive (for+		# eventual linking with the app. that links it) if we+		# didn't already link the preopened objects directly into+		# the library:+		func_basename "$lib"+		name=$func_basename_result+		eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`+		test -z "$libdir" && \+		  func_fatal_error "'$lib' is not a valid libtool archive"+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"+		;;+	      esac+	    done+	    dlprefiles=$newdlprefiles+	  else+	    newdlfiles=+	    for lib in $dlfiles; do+	      case $lib in+		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;+		*) abs=`pwd`"/$lib" ;;+	      esac+	      func_append newdlfiles " $abs"+	    done+	    dlfiles=$newdlfiles+	    newdlprefiles=+	    for lib in $dlprefiles; do+	      case $lib in+		[\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;+		*) abs=`pwd`"/$lib" ;;+	      esac+	      func_append newdlprefiles " $abs"+	    done+	    dlprefiles=$newdlprefiles+	  fi+	  $RM $output+	  # place dlname in correct position for cygwin+	  # In fact, it would be nice if we could use this code for all target+	  # systems that can't hard-code library paths into their executables+	  # and that have no shared library path variable independent of PATH,+	  # but it turns out we can't easily determine that from inspecting+	  # libtool variables, so we have to hard-code the OSs to which it+	  # applies here; at the moment, that means platforms that use the PE+	  # object format with DLL files.  See the long comment at the top of+	  # tests/bindir.at for full details.+	  tdlname=$dlname+	  case $host,$output,$installed,$module,$dlname in+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *windows*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)+	      # If a -bindir argument was supplied, place the dll there.+	      if test -n "$bindir"; then+		func_relative_path "$install_libdir" "$bindir"+		tdlname=$func_relative_path_result/$dlname+	      else+		# Otherwise fall back on heuristic.+		tdlname=../bin/$dlname+	      fi+	      ;;+	  esac+	  $ECHO > $output "\+# $outputname - a libtool library file+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION+#+# Please DO NOT delete this file!+# It is necessary for linking the library.++# The name that we can dlopen(3).+dlname='$tdlname'++# Names of this library.+library_names='$library_names'++# The name of the static archive.+old_library='$old_library'++# Linker flags that cannot go in dependency_libs.+inherited_linker_flags='$new_inherited_linker_flags'++# Libraries that this one depends upon.+dependency_libs='$dependency_libs'++# Names of additional weak libraries provided by this library+weak_library_names='$weak_libs'++# Version information for $libname.+current=$current+age=$age+revision=$revision++# Is this an already installed library?+installed=$installed++# Should we warn about portability when linking against -modules?+shouldnotlink=$module++# Files to dlopen/dlpreopen+dlopen='$dlfiles'+dlpreopen='$dlprefiles'++# Directory that this library needs to be installed in:+libdir='$install_libdir'"+	  if test no,yes = "$installed,$need_relink"; then+	    $ECHO >> $output "\+relink_command=\"$relink_command\""+	  fi+	done+      }++      # Do a symbolic link so that the libtool archive can be found in+      # LD_LIBRARY_PATH before the program is installed.+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'+      ;;+    esac+    exit $EXIT_SUCCESS+}++if test link = "$opt_mode" || test relink = "$opt_mode"; then+  func_mode_link ${1+"$@"}+fi+++# func_mode_uninstall arg...+func_mode_uninstall ()+{+    $debug_cmd++    RM=$nonopt+    files=+    rmforce=false+    exit_status=0++    # This variable tells wrapper scripts just to set variables rather+    # than running their programs.+    libtool_install_magic=$magic++    for arg+    do+      case $arg in+      -f) func_append RM " $arg"; rmforce=: ;;+      -*) func_append RM " $arg" ;;+      *) func_append files " $arg" ;;+      esac+    done++    test -z "$RM" && \+      func_fatal_help "you must specify an RM program"++    rmdirs=++    for file in $files; do+      func_dirname "$file" "" "."+      dir=$func_dirname_result+      if test . = "$dir"; then+	odir=$objdir+      else+	odir=$dir/$objdir+      fi+      func_basename "$file"+      name=$func_basename_result+      test uninstall = "$opt_mode" && odir=$dir++      # Remember odir for removal later, being careful to avoid duplicates+      if test clean = "$opt_mode"; then+	case " $rmdirs " in+	  *" $odir "*) ;;+	  *) func_append rmdirs " $odir" ;;+	esac+      fi++      # Don't error if the file doesn't exist and rm -f was used.+      if { test -L "$file"; } >/dev/null 2>&1 ||+	 { test -h "$file"; } >/dev/null 2>&1 ||+	 test -f "$file"; then+	:+      elif test -d "$file"; then+	exit_status=1+	continue+      elif $rmforce; then+	continue+      fi++      rmfiles=$file++      case $name in+      *.la)+	# Possibly a libtool archive, so verify it.+	if func_lalib_p "$file"; then+	  func_source $dir/$name++	  # Delete the libtool libraries and symlinks.+	  for n in $library_names; do+	    func_append rmfiles " $odir/$n"+	  done+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"++	  case $opt_mode in+	  clean)+	    case " $library_names " in+	    *" $dlname "*) ;;+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;+	    esac+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"+	    ;;+	  uninstall)+	    if test -n "$library_names"; then+	      # Do each command in the postuninstall commands.+	      func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'+	    fi++	    if test -n "$old_library"; then+	      # Do each command in the old_postuninstall commands.+	      func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'+	    fi+	    # FIXME: should reinstall the best remaining shared library.+	    ;;+	  esac+	fi+	;;++      *.lo)+	# Possibly a libtool object, so verify it.+	if func_lalib_p "$file"; then++	  # Read the .lo file+	  func_source $dir/$name++	  # Add PIC object to the list of files to remove.+	  if test -n "$pic_object" && test none != "$pic_object"; then+	    func_append rmfiles " $dir/$pic_object"+	  fi++	  # Add non-PIC object to the list of files to remove.+	  if test -n "$non_pic_object" && test none != "$non_pic_object"; then+	    func_append rmfiles " $dir/$non_pic_object"+	  fi+	fi+	;;++      *)+	if test clean = "$opt_mode"; then+	  noexename=$name+	  case $file in+	  *.exe)+	    func_stripname '' '.exe' "$file"+	    file=$func_stripname_result+	    func_stripname '' '.exe' "$name"+	    noexename=$func_stripname_result+	    # $file with .exe has already been added to rmfiles,+	    # add $file without .exe+	    func_append rmfiles " $file"+	    ;;+	  esac+	  # Do a test to see if this is a libtool program.+	  if func_ltwrapper_p "$file"; then+	    if func_ltwrapper_executable_p "$file"; then+	      func_ltwrapper_scriptname "$file"+	      relink_command=+	      func_source $func_ltwrapper_scriptname_result+	      func_append rmfiles " $func_ltwrapper_scriptname_result"+	    else+	      relink_command=+	      func_source $dir/$noexename+	    fi++	    # note $name still contains .exe if it was in $file originally+	    # as does the version of $file that was added into $rmfiles+	    func_append rmfiles " $odir/$name $odir/${name}S.$objext"+	    if test yes = "$fast_install" && test -n "$relink_command"; then+	      func_append rmfiles " $odir/lt-$name"+	    fi+	    if test "X$noexename" != "X$name"; then+	      func_append rmfiles " $odir/lt-$noexename.c"+	    fi+	  fi+	fi+	;;+      esac+      func_show_eval "$RM $rmfiles" 'exit_status=1'+    done++    # Try to remove the $objdir's in the directories where we deleted files+    for dir in $rmdirs; do+      if test -d "$dir"; then+	func_show_eval "rmdir $dir >/dev/null 2>&1"+      fi+    done++    exit $exit_status+}++if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then+  func_mode_uninstall ${1+"$@"}+fi++test -z "$opt_mode" && {+  help=$generic_help+  func_fatal_help "you must specify a MODE"+}++test -z "$exec_cmd" && \+  func_fatal_help "invalid operation mode '$opt_mode'"++if test -n "$exec_cmd"; then+  eval exec "$exec_cmd"+  exit $EXIT_FAILURE+fi++exit $exit_status+++# The TAGs below are defined such that we never get into a situation+# where we disable both kinds of libraries.  Given conflicting+# choices, we go for a static library, that is the most portable,+# since we can't tell whether shared libraries were disabled because+# the user asked for that or because the platform doesn't support+# them.  This is particularly important on AIX, because we don't+# support having both static and shared libraries enabled at the same+# time on that platform, so we default to a shared-only configuration.+# If a disable-shared tag is given, we'll fallback to a static-only+# configuration.  But we'll never go from static-only to shared-only.++# ### BEGIN LIBTOOL TAG CONFIG: disable-shared+build_libtool_libs=no+build_old_libs=yes+# ### END LIBTOOL TAG CONFIG: disable-shared++# ### BEGIN LIBTOOL TAG CONFIG: disable-static+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`+# ### END LIBTOOL TAG CONFIG: disable-static++# Local Variables:+# mode:shell-script+# sh-indentation:2+# End:
+ m4/asmcfi.m4 view
@@ -0,0 +1,30 @@+dnl ------------------------------------------------------------------+dnl  Check whether the assembler understands .cfi_* pseudo-ops.+dnl ------------------------------------------------------------------+AC_DEFUN([GCC_AS_CFI_PSEUDO_OP],+[+  AC_CACHE_CHECK([assembler .cfi pseudo-op support],+                 [gcc_cv_as_cfi_pseudo_op],+  [ AC_LANG_PUSH([C])+    AC_COMPILE_IFELSE(+      [AC_LANG_SOURCE([[+        #ifdef _MSC_VER+        Nope.+        #endif+        int foo (void)+        {+          __asm__ (".cfi_remember_state\n\t"+                   ".cfi_restore_state\n\t");+          return 0;+        }+      ]])],+      [gcc_cv_as_cfi_pseudo_op=yes],+      [gcc_cv_as_cfi_pseudo_op=no])+    AC_LANG_POP([C])+  ])++  if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then+    AC_DEFINE([HAVE_AS_CFI_PSEUDO_OP], [1],+              [Define if your assembler supports .cfi_* directives.])+  fi+])
+ m4/ax_cc_maxopt.m4 view
@@ -0,0 +1,198 @@+# ===========================================================================+#       https://www.gnu.org/software/autoconf-archive/ax_cc_maxopt.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_CC_MAXOPT+#+# DESCRIPTION+#+#   Try to turn on "good" C optimization flags for various compilers and+#   architectures, for some definition of "good". (In our case, good for+#   FFTW and hopefully for other scientific codes. Modify as needed.)+#+#   The user can override the flags by setting the CFLAGS environment+#   variable. The user can also specify --enable-portable-binary in order to+#   disable any optimization flags that might result in a binary that only+#   runs on the host architecture.+#+#   Note also that the flags assume that ANSI C aliasing rules are followed+#   by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point+#   computations can be re-ordered as needed.+#+#   Requires macros: AX_CHECK_COMPILE_FLAG, AX_COMPILER_VENDOR,+#   AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID.+#+# LICENSE+#+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>+#   Copyright (c) 2008 Matteo Frigo+#+#   This program is free software: you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation, either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 22++AC_DEFUN([AX_CC_MAXOPT],+[+AC_REQUIRE([AC_PROG_CC])+AC_REQUIRE([AX_COMPILER_VENDOR])+AC_REQUIRE([AC_CANONICAL_HOST])++AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],+	acx_maxopt_portable=$enableval, acx_maxopt_portable=no)++# Try to determine "good" native compiler flags if none specified via CFLAGS+if test "x$ac_test_CFLAGS" = "x"; then+  case $ax_cv_c_compiler_vendor in+    dec) CFLAGS="$CFLAGS -newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"+	 if test "x$acx_maxopt_portable" = xno; then+           CFLAGS="$CFLAGS -arch host"+         fi;;++    sun) CFLAGS="$CFLAGS -native -fast -xO5 -dalign"+	 if test "x$acx_maxopt_portable" = xyes; then+	   CFLAGS="$CFLAGS -xarch=generic"+         fi;;++    hp)  CFLAGS="$CFLAGS +Oall +Optrs_ansi +DSnative"+	 if test "x$acx_maxopt_portable" = xyes; then+	   CFLAGS="$CFLAGS +DAportable"+	 fi;;++    ibm) if test "x$acx_maxopt_portable" = xno; then+           xlc_opt="-qarch=auto -qtune=auto"+	 else+           xlc_opt="-qtune=auto"+	 fi+         AX_CHECK_COMPILE_FLAG($xlc_opt,+		CFLAGS="$CFLAGS -O3 -qansialias -w $xlc_opt",+               [CFLAGS="$CFLAGS -O3 -qansialias -w"+                echo "******************************************************"+                echo "*  You seem to have the IBM  C compiler.  It is      *"+                echo "*  recommended for best performance that you use:    *"+                echo "*                                                    *"+                echo "*    CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"+                echo "*                      ^^^        ^^^                *"+                echo "*  where xxx is pwr2, pwr3, 604, or whatever kind of *"+                echo "*  CPU you have.  (Set the CFLAGS environment var.   *"+                echo "*  and re-run configure.)  For more info, man cc.    *"+                echo "******************************************************"])+         ;;++    intel) CFLAGS="$CFLAGS -O3 -ansi_alias"+	if test "x$acx_maxopt_portable" = xno; then+	  icc_archflag=unknown+	  icc_flags=""+	  case $host_cpu in+	    i686*|x86_64*)+              # icc accepts gcc assembly syntax, so these should work:+	      AX_GCC_X86_CPUID(0)+              AX_GCC_X86_CPUID(1)+	      case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG+                *:756e6547:6c65746e:49656e69) # Intel+                  case $ax_cv_gcc_x86_cpuid_1 in+		    *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) icc_flags="-xK" ;;+		    *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) icc_flags="-xSSE2 -xB -xK" ;;+		    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) icc_flags="-xSSE3 -xP -xO -xB -xK" ;;+		    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) icc_flags="-xSSSE3 -xT -xB -xK" ;;+		    *1?6[[7d]]?:*:*:*) icc_flags="-xSSE4.1 -xS -xT -xB -xK" ;;+		    *1?6[[aef]]?:*:*:*|*2?6[[5cef]]?:*:*:*) icc_flags="-xSSE4.2 -xS -xT -xB -xK" ;;+		    *2?6[[ad]]?:*:*:*) icc_flags="-xAVX -SSE4.2 -xS -xT -xB -xK" ;;+		    *3?6[[ae]]?:*:*:*) icc_flags="-xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;+		    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) icc_flags="-xCORE-AVX2 -xCORE-AVX-I -xAVX -SSE4.2 -xS -xT -xB -xK" ;;+		    *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) icc_flags="-xSSE3 -xP -xO -xN -xW -xK" ;;+		    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) icc_flags="-xSSE2 -xN -xW -xK" ;;+                  esac ;;+              esac ;;+          esac+          if test "x$icc_flags" != x; then+            for flag in $icc_flags; do+              AX_CHECK_COMPILE_FLAG($flag, [icc_archflag=$flag; break])+            done+          fi+          AC_MSG_CHECKING([for icc architecture flag])+	  AC_MSG_RESULT($icc_archflag)+          if test "x$icc_archflag" != xunknown; then+            CFLAGS="$CFLAGS $icc_archflag"+          fi+        fi+	;;++    nvhpc)+     # default optimization flags for nvhpc+     CFLAGS="$CFLAGS -O3"+     ;;++    gnu)+     # default optimization flags for gcc on all systems+     CFLAGS="$CFLAGS -O3 -fomit-frame-pointer"++     # -malign-double for x86 systems+     # LIBFFI_LOCAL: don't do this.+     # The testsuite doesn't use these flags and we'll get test failures.+     # AX_CHECK_COMPILE_FLAG(-malign-double, CFLAGS="$CFLAGS -malign-double")++     #  -fstrict-aliasing for gcc-2.95++     AX_CHECK_COMPILE_FLAG(-fstrict-aliasing,+	CFLAGS="$CFLAGS -fstrict-aliasing")++     # note that we enable "unsafe" fp optimization with other compilers, too+     AX_CHECK_COMPILE_FLAG(-ffast-math, CFLAGS="$CFLAGS -ffast-math")++     AX_GCC_ARCHFLAG($acx_maxopt_portable)+     ;;++    microsoft)+     # default optimization flags for MSVC opt builds+     CFLAGS="$CFLAGS -O2"+     ;;+  esac++  if test -z "$CFLAGS"; then+	echo ""+	echo "********************************************************"+        echo "* WARNING: Don't know the best CFLAGS for this system  *"+        echo "* Use ./configure CFLAGS=... to specify your own flags *"+	echo "* (otherwise, a default of CFLAGS=-O3 will be used)    *"+	echo "********************************************************"+	echo ""+        CFLAGS="$CFLAGS -O3"+  fi++  AX_CHECK_COMPILE_FLAG($CFLAGS, [], [+	echo ""+        echo "********************************************************"+        echo "* WARNING: The guessed CFLAGS don't seem to work with  *"+        echo "* your compiler.                                       *"+        echo "* Use ./configure CFLAGS=... to specify your own flags *"+        echo "********************************************************"+        echo ""+  ])++fi+])
+ m4/ax_cflags_warn_all.m4 view
@@ -0,0 +1,158 @@+# ===========================================================================+#    https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_CFLAGS_WARN_ALL   [(shellvar[, default[, action-if-found[, action-if-not-found]]])]+#   AX_CXXFLAGS_WARN_ALL [(shellvar[, default[, action-if-found[, action-if-not-found]]])]+#   AX_FCFLAGS_WARN_ALL  [(shellvar[, default[, action-if-found[, action-if-not-found]]])]+#+# DESCRIPTION+#+#   Specify compiler options that enable most reasonable warnings.  For the+#   GNU Compiler Collection (GCC), for example, it will be "-Wall".  The+#   result is added to shellvar, one of CFLAGS, CXXFLAGS or FCFLAGS if the+#   first parameter is not specified.+#+#   Each of these macros accepts the following optional arguments:+#+#     - $1 - shellvar+#         shell variable to use (CFLAGS, CXXFLAGS or FCFLAGS if not+#         specified, depending on macro)+#+#     - $2 - default+#         value to use for flags if compiler vendor cannot be determined (by+#         default, "")+#+#     - $3 - action-if-found+#         action to take if the compiler vendor has been successfully+#         determined (by default, add the appropriate compiler flags to+#         shellvar)+#+#     - $4 - action-if-not-found+#         action to take if the compiler vendor has not been determined or+#         is unknown (by default, add the default flags, or "" if not+#         specified, to shellvar)+#+#   These macros use AX_COMPILER_VENDOR to determine which flags should be+#   returned for a given compiler.  Not all compilers currently have flags+#   defined for them; patches are welcome.  If need be, compiler flags may+#   be made language-dependent: use a construct like the following:+#+#     [vendor_name], [m4_if(_AC_LANG_PREFIX,[C],   VAR="--relevant-c-flags",dnl+#                     m4_if(_AC_LANG_PREFIX,[CXX], VAR="--relevant-c++-flags",dnl+#                     m4_if(_AC_LANG_PREFIX,[FC],  VAR="--relevant-fortran-flags",dnl+#                     VAR="$2"; FOUND="no")))],+#+#   Note: These macros also depend on AX_PREPEND_FLAG.+#+# LICENSE+#+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>+#   Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com>+#   Copyright (c) 2018 John Zaitseff <J.Zaitseff@zap.org.au>+#+#   This program is free software; you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation; either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 25++AC_DEFUN([AX_FLAGS_WARN_ALL], [+    AX_REQUIRE_DEFINED([AX_PREPEND_FLAG])dnl+    AC_REQUIRE([AX_COMPILER_VENDOR])dnl++    AS_VAR_PUSHDEF([FLAGS], [m4_default($1,_AC_LANG_PREFIX[]FLAGS)])dnl+    AS_VAR_PUSHDEF([VAR],   [ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl+    AS_VAR_PUSHDEF([FOUND], [ac_save_[]_AC_LANG_ABBREV[]flags_warn_all_found])dnl++    AC_CACHE_CHECK([FLAGS for most reasonable warnings], VAR, [+	VAR=""+	FOUND="yes"+	dnl  Cases are listed in the order found in ax_compiler_vendor.m4+	AS_CASE("$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor",+	    [intel],		[VAR="-w2"],+	    [ibm],		[VAR="-qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd"],+	    [pathscale],	[],+	    [clang],		[VAR="-Wall"],+	    [cray],		[VAR="-h msglevel 2"],+	    [fujitsu],		[],+	    [sdcc],		[],+	    [sx],		[VAR="-pvctl[,]fullmsg"],+	    [portland],		[],+	    [gnu],		[VAR="-Wall"],+	    [sun],		[VAR="-v"],+	    [hp],		[VAR="+w1"],+	    [dec],		[VAR="-verbose -w0 -warnprotos"],+	    [borland],		[],+	    [comeau],		[],+	    [kai],		[],+	    [lcc],		[],+	    [sgi],		[VAR="-fullwarn"],+	    [microsoft],	[],+	    [metrowerks],	[],+	    [watcom],		[],+	    [tcc],		[],+	    [unknown],		[+				    VAR="$2"+				    FOUND="no"+				],+				[+				    AC_MSG_WARN([Unknown compiler vendor returned by [AX_COMPILER_VENDOR]])+				    VAR="$2"+				    FOUND="no"+				]+	)++	AS_IF([test "x$FOUND" = "xyes"], [dnl+	    m4_default($3, [AS_IF([test "x$VAR" != "x"], [AX_PREPEND_FLAG([$VAR], [FLAGS])])])+	], [dnl+	    m4_default($4, [m4_ifval($2, [AX_PREPEND_FLAG([$VAR], [FLAGS])], [true])])+	])dnl+    ])dnl++    AS_VAR_POPDEF([FOUND])dnl+    AS_VAR_POPDEF([VAR])dnl+    AS_VAR_POPDEF([FLAGS])dnl+])dnl AX_FLAGS_WARN_ALL++AC_DEFUN([AX_CFLAGS_WARN_ALL], [dnl+    AC_LANG_PUSH([C])+    AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])+    AC_LANG_POP([C])+])dnl++AC_DEFUN([AX_CXXFLAGS_WARN_ALL], [dnl+    AC_LANG_PUSH([C++])+    AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])+    AC_LANG_POP([C++])+])dnl++AC_DEFUN([AX_FCFLAGS_WARN_ALL], [dnl+    AC_LANG_PUSH([Fortran])+    AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])+    AC_LANG_POP([Fortran])+])dnl
+ m4/ax_check_compile_flag.m4 view
@@ -0,0 +1,63 @@+# ===========================================================================+#  https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])+#+# DESCRIPTION+#+#   Check whether the given FLAG works with the current language's compiler+#   or gives an error.  (Warnings, however, are ignored)+#+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on+#   success/failure.+#+#   If EXTRA-FLAGS is defined, it is added to the current language's default+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to+#   force the compiler to issue an error when a bad flag is given.+#+#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.+#+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.+#+# LICENSE+#+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>+#+#   Copying and distribution of this file, with or without modification, are+#   permitted in any medium without royalty provided the copyright notice+#   and this notice are preserved.  This file is offered as-is, without any+#   warranty.++#serial 11++AC_DEFUN([AX_CHECK_COMPILE_FLAG],+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl+AC_CACHE_CHECK([whether the _AC_LANG compiler accepts $1], CACHEVAR, [+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS+  if test x"m4_case(_AC_LANG,+                     [C], [$GCC],+                     [C++], [$GXX],+                     [Fortran], [$GFC],+                     [Fortran 77], [$G77],+                     [Objective C], [$GOBJC],+                     [Objective C++], [$GOBJCXX],+                     [no])" = xyes ; then+    add_gnu_werror="-Werror"+  fi+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1 $add_gnu_werror"+  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],+    [AS_VAR_SET(CACHEVAR,[yes])],+    [AS_VAR_SET(CACHEVAR,[no])])+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])+AS_VAR_IF(CACHEVAR,yes,+  [m4_default([$2], :)],+  [m4_default([$3], :)])+AS_VAR_POPDEF([CACHEVAR])dnl+])dnl AX_CHECK_COMPILE_FLAGS
+ m4/ax_compiler_vendor.m4 view
@@ -0,0 +1,119 @@+# ===========================================================================+#    https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_COMPILER_VENDOR+#+# DESCRIPTION+#+#   Determine the vendor of the C, C++ or Fortran compiler.  The vendor is+#   returned in the cache variable $ax_cv_c_compiler_vendor for C,+#   $ax_cv_cxx_compiler_vendor for C++ or $ax_cv_fc_compiler_vendor for+#   (modern) Fortran.  The value is one of "intel", "ibm", "pathscale",+#   "clang" (LLVM), "cray", "fujitsu", "sdcc", "sx", "nvhpc" (NVIDIA HPC+#   Compiler), "portland" (PGI), "gnu" (GCC), "sun" (Oracle Developer+#   Studio), "hp", "dec", "borland", "comeau", "kai", "lcc", "sgi",+#   "microsoft", "metrowerks", "watcom", "tcc" (Tiny CC) or "unknown" (if+#   the compiler cannot be determined).+#+#   To check for a Fortran compiler, you must first call AC_FC_PP_SRCEXT+#   with an appropriate preprocessor-enabled extension.  For example:+#+#     AC_LANG_PUSH([Fortran])+#     AC_PROG_FC+#     AC_FC_PP_SRCEXT([F])+#     AX_COMPILER_VENDOR+#     AC_LANG_POP([Fortran])+#+# LICENSE+#+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>+#   Copyright (c) 2008 Matteo Frigo+#   Copyright (c) 2018-19 John Zaitseff <J.Zaitseff@zap.org.au>+#+#   This program is free software: you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation, either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 32++AC_DEFUN([AX_COMPILER_VENDOR], [dnl+    AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [dnl+	dnl  If you modify this list of vendors, please add similar support+	dnl  to ax_compiler_version.m4 if at all possible.+	dnl+	dnl  Note: Do NOT check for GCC first since some other compilers+	dnl  define __GNUC__ to remain compatible with it.  Compilers that+	dnl  are very slow to start (such as Intel) are listed first.++	vendors="+		intel:		__ICC,__ECC,__INTEL_COMPILER+		ibm:		__xlc__,__xlC__,__IBMC__,__IBMCPP__,__ibmxl__+		pathscale:	__PATHCC__,__PATHSCALE__+		clang:		__clang__+		cray:		_CRAYC+		fujitsu:	__FUJITSU+		sdcc:		SDCC,__SDCC+		sx:		_SX+		nvhpc:		__NVCOMPILER+		portland:	__PGI+		gnu:		__GNUC__+		sun:		__SUNPRO_C,__SUNPRO_CC,__SUNPRO_F90,__SUNPRO_F95+		hp:		__HP_cc,__HP_aCC+		dec:		__DECC,__DECCXX,__DECC_VER,__DECCXX_VER+		borland:	__BORLANDC__,__CODEGEARC__,__TURBOC__+		comeau:		__COMO__+		kai:		__KCC+		lcc:		__LCC__+		sgi:		__sgi,sgi+		microsoft:	_MSC_VER+		metrowerks:	__MWERKS__+		watcom:		__WATCOMC__+		tcc:		__TINYC__+		unknown:	UNKNOWN+	"+	for ventest in $vendors; do+	    case $ventest in+		*:)+		    vendor=$ventest+		    continue+		    ;;+		*)+		    vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")"+		    ;;+	    esac++	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[+#if !($vencpp)+      thisisanerror;+#endif+	    ]])], [break])+	done++	ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`+    ])+])dnl
+ m4/ax_configure_args.m4 view
@@ -0,0 +1,49 @@+# ===========================================================================+#    https://www.gnu.org/software/autoconf-archive/ax_configure_args.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_CONFIGURE_ARGS+#+# DESCRIPTION+#+#   Helper macro for AX_ENABLE_BUILDDIR.+#+#   The traditional way of starting a subdir-configure is running the script+#   with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have+#   to rely on eval'ing $ac_configure_args however some old autoconf+#   versions do not provide that. To ensure maximum portability of autoconf+#   extension macros this helper can be AC_REQUIRE'd so that+#   $ac_configure_args will always be present.+#+#   Sadly, the traditional "exec $SHELL" of the enable_builddir macros is+#   spoiled now and must be replaced by "eval + exit $?".+#+#   Example:+#+#     AC_DEFUN([AX_ENABLE_SUBDIR],[dnl+#       AC_REQUIRE([AX_CONFIGURE_ARGS])dnl+#       eval $SHELL $ac_configure_args || exit $?+#       ...])+#+# LICENSE+#+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>+#+#   Copying and distribution of this file, with or without modification, are+#   permitted in any medium without royalty provided the copyright notice+#   and this notice are preserved.  This file is offered as-is, without any+#   warranty.++#serial 14++AC_DEFUN([AX_CONFIGURE_ARGS],[+   # [$]@ is unusable in 2.60+ but earlier autoconf had no ac_configure_args+   if test "${ac_configure_args+set}" != "set" ; then+      ac_configure_args=+      for ac_arg in ${1+"[$]@"}; do+         ac_configure_args="$ac_configure_args '$ac_arg'"+      done+   fi+])
+ m4/ax_enable_builddir.m4 view
@@ -0,0 +1,302 @@+# ===========================================================================+#    https://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])]+#+# DESCRIPTION+#+#   If the current configure was run within the srcdir then we move all+#   configure-files into a subdir and let the configure steps continue+#   there. We provide an option --disable-builddir to suppress the move into+#   a separate builddir.+#+#   Defaults:+#+#     $1 = $host (overridden with $HOST)+#     $2 = Makefile.mk+#     $3 = -all+#+#   This macro must be called before AM_INIT_AUTOMAKE. It creates a default+#   toplevel srcdir Makefile from the information found in the created+#   toplevel builddir Makefile. It just copies the variables and+#   rule-targets, each extended with a default rule-execution that recurses+#   into the build directory of the current "HOST". You can override the+#   auto-detection through `config.guess` and build-time of course, as in+#+#     make HOST=i386-mingw-cross+#+#   which can of course set at configure time as well using+#+#     configure --host=i386-mingw-cross+#+#   After the default has been created, additional rules can be appended+#   that will not just recurse into the subdirectories and only ever exist+#   in the srcdir toplevel makefile - these parts are read from the $2 =+#   Makefile.mk file+#+#   The automatic rules are usually scanning the toplevel Makefile for lines+#   like '#### $host |$builddir' to recognize the place where to recurse+#   into. Usually, the last one is the only one used. However, almost all+#   targets have an additional "*-all" rule which makes the script to+#   recurse into _all_ variants of the current HOST (!!) setting. The "-all"+#   suffix can be overridden for the macro as well.+#+#   a special rule is only given for things like "dist" that will copy the+#   tarball from the builddir to the sourcedir (or $(PUB)) for reason of+#   convenience.+#+# LICENSE+#+#   Copyright (c) 2009 Guido U. Draheim <guidod@gmx.de>+#   Copyright (c) 2009 Alan Jenkins <alan-jenkins@tuffmail.co.uk>+#+#   This program is free software; you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation; either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 30++AC_DEFUN([AX_ENABLE_BUILDDIR],[+AC_REQUIRE([AC_CANONICAL_HOST])[]dnl+AC_REQUIRE([AC_CANONICAL_TARGET])[]dnl+AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl+AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl+AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl+AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl+AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl+AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl+SUB="."+AC_ARG_ENABLE([builddir], AS_HELP_STRING(+  [--disable-builddir],[disable automatic build in subdir of sources])+  ,[SUB="$enableval"], [SUB="auto"])+if test ".$ac_srcdir_defaulted" != ".no" ; then+if test ".$srcdir" = ".." ; then+  if test -f config.status ; then+    AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build)+  else+    test ".$SUB" = "."  && SUB="."+    test ".$SUB" = ".no"  && SUB="."+    test ".$TARGET" = "." && TARGET="$target"+    test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])"+    if test ".$SUB" != ".." ; then    # we know where to go and+      AS_MKDIR_P([$SUB])+      echo __.$SUB.__ > $SUB/conftest.tmp+      cd $SUB+      if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then+        rm conftest.tmp+        AC_MSG_RESULT([continue configure in default builddir "./$SUB"])+      else+        AC_MSG_ERROR([could not change to default builddir "./$SUB"])+      fi+      srcdir=`echo "$SUB" |+              sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'`+      # going to restart from subdirectory location+      test -f $srcdir/config.log   && mv $srcdir/config.log   .+      test -f $srcdir/confdefs.h   && mv $srcdir/confdefs.h   .+      test -f $srcdir/conftest.log && mv $srcdir/conftest.log .+      test -f $srcdir/$cache_file  && mv $srcdir/$cache_file  .+      AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"})+      case "[$]0" in # restart+       [[\\/]]* | ?:[[\\/]]*) # Absolute name+         eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;+       *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;+      esac ; exit $?+    fi+  fi+fi fi+test ".$SUB" = ".auto" && SUB="."+dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec"+AC_PATH_PROG(SED,gsed sed, sed)+AUX="$am_aux_dir"+AS_VAR_POPDEF([SED])dnl+AS_VAR_POPDEF([AUX])dnl+AS_VAR_POPDEF([SUB])dnl+AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status ..............+AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl+AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl+AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl+AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl+AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl+pushdef([END],[Makefile.mk])dnl+pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl+  SRC="$ax_enable_builddir_srcdir"+  if test ".$SUB" = ".." ; then+    if test -f "$TOP/Makefile" ; then+      AC_MSG_NOTICE([skipping TOP/Makefile - left untouched])+    else+      AC_MSG_NOTICE([skipping TOP/Makefile - not created])+    fi+  else+    if test -f "$SRC/Makefile" ; then+      a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile`+      test "$a" != "$b" && rm "$SRC/Makefile"+    fi+    if test -f "$SRC/Makefile" ; then+	echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk+	echo "	[]@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk+      eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"+      if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null+      then rm $SRC/Makefile ; fi+      cp $tmp/conftemp.mk $SRC/makefiles.mk~      ## DEBUGGING+    fi+    if test ! -f "$SRC/Makefile" ; then+      AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile])+      x='`' ; cat >$tmp/conftemp.sed <<_EOF+/^\$/n+x+/^\$/bS+x+/\\\\\$/{H;d;}+{H;s/.*//;x;}+bM+:S+x+/\\\\\$/{h;d;}+{h;s/.*//;x;}+:M+s/\\(\\n\\)	/\\1 /g+/^	/d+/^[[	 ]]*[[\\#]]/d+/^VPATH *=/d+s/^srcdir *=.*/srcdir = ./+s/^top_srcdir *=.*/top_srcdir = ./+/[[:=]]/!d+/^\\./d+dnl Now handle rules (i.e. lines containing ":" but not " = ").+/ = /b+/ .= /b+/:/!b+s/:.*/:/+s/ /  /g+s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g+s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/+s/  / /g+/^all all[]_ALL[[ :]]/i\\+all-configured : all[]_ALL+dnl dist-all exists... and would make for dist-all-all+s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g+/[]_ALL[]_ALL/d+a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\+	; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\+	; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\+	; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done+dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree)+/dist[]_ALL *:/a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\+	; if test "\$\$found" -eq "0" ; then : \\\\\\+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done+dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree)+/dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\+	; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\+	; found=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\+	; if test "\$\$found" -eq "0" ; then : \\\\\\+	; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\+	; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\+	; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done+dnl special rule add-on: "distclean" removes all local builddirs completely+/distclean[]_ALL *:/a\\+	@ HOST="\$(HOST)\" \\\\\\+	; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\+	; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\+	; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\+	; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\+	; test ".\$\$BUILD" = "." && BUILD="." \\\\\\+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\+	; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\+	; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\+	; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\+	; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile+_EOF+      cp "$tmp/conftemp.sed" "$SRC/makefile.sed~"            ## DEBUGGING+      $SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile+      if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then+        AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])])+        cat $SRC/END >>$SRC/Makefile+      fi ; xxxx="####"+      echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile+      # sanity check+      if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then+        AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts])+        $SED -e '/^@ HOST=/s/^/	/' -e '/^; /s/^/	/' $SRC/Makefile \+          >$SRC/Makefile~+        (test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null+      fi+    else+      xxxx="\\#\\#\\#\\#"+      # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed+      echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed+      $SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp+        cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~"         ## DEBUGGING+        cp "$tmp/mkfile.tmp"   "$SRC/makefiles.out~"         ## DEBUGGING+      if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then+        AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure])+        rm "$tmp/mkfile.tmp"+      else+        AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure])+        mv "$tmp/mkfile.tmp" "$SRC/Makefile"+      fi+    fi+    AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)])+    xxxx="####"+    echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile+  fi+popdef([END])dnl+AS_VAR_POPDEF([SED])dnl+AS_VAR_POPDEF([AUX])dnl+AS_VAR_POPDEF([SRC])dnl+AS_VAR_POPDEF([TOP])dnl+AS_VAR_POPDEF([SUB])dnl+],[dnl+ax_enable_builddir_srcdir="$srcdir"                    # $srcdir+ax_enable_builddir_host="$HOST"                        # $HOST / $host+ax_enable_builddir_version="$VERSION"                  # $VERSION+ax_enable_builddir_package="$PACKAGE"                  # $PACKAGE+ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX+ax_enable_builddir_sed="$ax_enable_builddir_sed"       # $SED+ax_enable_builddir="$ax_enable_builddir"               # $SUB+])dnl+])
+ m4/ax_gcc_archflag.m4 view
@@ -0,0 +1,267 @@+# ===========================================================================+#     https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])+#+# DESCRIPTION+#+#   This macro tries to guess the "native" arch corresponding to the target+#   architecture for use with gcc's -march=arch or -mtune=arch flags. If+#   found, the cache variable $ax_cv_gcc_archflag is set to this flag and+#   ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to+#   "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is+#   to add $ax_cv_gcc_archflag to the end of $CFLAGS.+#+#   PORTABLE? should be either [yes] (default) or [no]. In the former case,+#   the flag is set to -mtune (or equivalent) so that the architecture is+#   only used for tuning, but the instruction set used is still portable. In+#   the latter case, the flag is set to -march (or equivalent) so that+#   architecture-specific instructions are enabled.+#+#   The user can specify --with-gcc-arch=<arch> in order to override the+#   macro's choice of architecture, or --without-gcc-arch to disable this.+#+#   When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is+#   called unless the user specified --with-gcc-arch manually.+#+#   Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID+#+#   (The main emphasis here is on recent CPUs, on the principle that doing+#   high-performance computing on old hardware is uncommon.)+#+# LICENSE+#+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>+#   Copyright (c) 2008 Matteo Frigo+#   Copyright (c) 2014 Tsukasa Oi+#   Copyright (c) 2017-2018 Alexey Kopytov+#+#   This program is free software: you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation, either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 22++AC_DEFUN([AX_GCC_ARCHFLAG],+[AC_REQUIRE([AC_PROG_CC])+AC_REQUIRE([AC_CANONICAL_HOST])+AC_REQUIRE([AC_PROG_SED])+AC_REQUIRE([AX_COMPILER_VENDOR])++AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],+	ax_gcc_arch=$withval, ax_gcc_arch=yes)++AC_MSG_CHECKING([for gcc architecture flag])+AC_MSG_RESULT([])+AC_CACHE_VAL(ax_cv_gcc_archflag,+[+ax_cv_gcc_archflag="unknown"++if test "$GCC" = yes; then++if test "x$ax_gcc_arch" = xyes; then+ax_gcc_arch=""+if test "$cross_compiling" = no; then+case $host_cpu in+  i[[3456]]86*|x86_64*|amd64*) # use cpuid codes+     AX_GCC_X86_CPUID(0)+     AX_GCC_X86_CPUID(1)+     case $ax_cv_gcc_x86_cpuid_0 in+       *:756e6547:6c65746e:49656e69) # Intel+          case $ax_cv_gcc_x86_cpuid_1 in+	    *5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;+	    *5[[123]]?:*:*:*) ax_gcc_arch=pentium ;;+	    *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;;+	    *0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;+	    *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;+	    *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;+	    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;;+	    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;;+	    *1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;;+	    *1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;+	    *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;;+	    *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;;+	    *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;+	    *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;;+	    # fallback+	    *5??:*:*:*) ax_gcc_arch=pentium ;;+	    *??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;;+	    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;+	    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;+          esac ;;+       *:68747541:444d4163:69746e65) # AMD+          case $ax_cv_gcc_x86_cpuid_1 in+	    *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;+	    *5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;+	    *5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;+	    *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;+	    *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;+	    *6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;+	    *000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;+	    *002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;+	    *010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;+	    *050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;+	    *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;+	    *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;+	    *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;+	    *07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;+	    # fallback+	    *0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;+	    *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;+	    *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;+	    *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;+	    *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;+	    *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;+	    *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;+	    *???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;;+          esac ;;+	*:746e6543:736c7561:48727561) # IDT / VIA (Centaur)+	   case $ax_cv_gcc_x86_cpuid_1 in+	     *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;+	     *5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;;+	     *66?:*:*:*) ax_gcc_arch=winchip2 ;;+	     *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;+	     *6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;;+	   esac ;;+     esac+     if test x"$ax_gcc_arch" = x; then # fallback+	case $host_cpu in+	  i586*) ax_gcc_arch=pentium ;;+	  i686*) ax_gcc_arch=pentiumpro ;;+        esac+     fi+     ;;++  sparc*)+     AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])+     cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`+     cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters`+     case $cputype in+         *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;+         *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;+         *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;+         *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;+         *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;+         *cypress*) ax_gcc_arch=cypress ;;+     esac ;;++  alphaev5) ax_gcc_arch=ev5 ;;+  alphaev56) ax_gcc_arch=ev56 ;;+  alphapca56) ax_gcc_arch="pca56 ev56" ;;+  alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;+  alphaev6) ax_gcc_arch=ev6 ;;+  alphaev67) ax_gcc_arch=ev67 ;;+  alphaev68) ax_gcc_arch="ev68 ev67" ;;+  alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;+  alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;+  alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;++  powerpc*)+     cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`+     cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'`+     case $cputype in+       *750*) ax_gcc_arch="750 G3" ;;+       *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;+       *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;+       *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;+       *970*) ax_gcc_arch="970 G5 power4";;+       *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;+       *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;+       603ev|8240) ax_gcc_arch="$cputype 603e 603";;+       *POWER7*) ax_gcc_arch="power7";;+       *POWER8*) ax_gcc_arch="power8";;+       *POWER9*) ax_gcc_arch="power9";;+       *POWER10*) ax_gcc_arch="power10";;+       *) ax_gcc_arch=$cputype ;;+     esac+     ax_gcc_arch="$ax_gcc_arch powerpc"+     ;;+  aarch64)+     cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`+     cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`+     cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`+     case $cpuimpl in+       0x42) case $cpuarch in+               8) case $cpuvar in+                    0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;;+                  esac+                  ;;+             esac+             ;;+       0x43) case $cpuarch in+               8) case $cpuvar in+                    0x0) ax_gcc_arch="thunderx armv8-a native" ;;+                    0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;;+                  esac+                  ;;+             esac+             ;;+      esac+      ;;+esac+fi # not cross-compiling+fi # guess arch++if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then+if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code+  flag_prefixes="-mtune="+  if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi+  # -mcpu=$arch and m$arch generate nonportable code on every arch except+  # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.+  case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac+else+  flag_prefixes="-march= -mcpu= -m"+fi+for flag_prefix in $flag_prefixes; do+  for arch in $ax_gcc_arch; do+    flag="$flag_prefix$arch"+    AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then+      if test "x[]m4_default([$1],yes)" = xyes; then+	if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi+      fi+    fi; ax_cv_gcc_archflag=$flag; break])+  done+  test "x$ax_cv_gcc_archflag" = xunknown || break+done+fi++fi # $GCC=yes+])+AC_MSG_CHECKING([for gcc architecture flag])+AC_MSG_RESULT($ax_cv_gcc_archflag)+if test "x$ax_cv_gcc_archflag" = xunknown; then+  m4_default([$3],:)+else+  m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])+fi+])
+ m4/ax_gcc_x86_cpuid.m4 view
@@ -0,0 +1,89 @@+# ===========================================================================+#     https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_GCC_X86_CPUID(OP)+#   AX_GCC_X86_CPUID_COUNT(OP, COUNT)+#+# DESCRIPTION+#+#   On Pentium and later x86 processors, with gcc or a compiler that has a+#   compatible syntax for inline assembly instructions, run a small program+#   that executes the cpuid instruction with input OP. This can be used to+#   detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT+#   parameter that gets passed into register ECX before calling cpuid.+#+#   On output, the values of the eax, ebx, ecx, and edx registers are stored+#   as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable+#   ax_cv_gcc_x86_cpuid_OP.+#+#   If the cpuid instruction fails (because you are running a+#   cross-compiler, or because you are not using gcc, or because you are on+#   a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP+#   is set to the string "unknown".+#+#   This macro mainly exists to be used in AX_GCC_ARCHFLAG.+#+# LICENSE+#+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>+#   Copyright (c) 2008 Matteo Frigo+#   Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.com>+#+#   This program is free software: you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation, either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <https://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Archive. When you make and distribute a+#   modified version of the Autoconf Macro, you may extend this special+#   exception to the GPL to apply to your modified version as well.++#serial 10++AC_DEFUN([AX_GCC_X86_CPUID],+[AX_GCC_X86_CPUID_COUNT($1, 0)+])++AC_DEFUN([AX_GCC_X86_CPUID_COUNT],+[AC_REQUIRE([AC_PROG_CC])+AC_LANG_PUSH([C])+AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [+     int op = $1, level = $2, eax, ebx, ecx, edx;+     FILE *f;+      __asm__ __volatile__ ("xchg %%ebx, %1\n"+        "cpuid\n"+        "xchg %%ebx, %1\n"+        : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)+        : "a" (op), "2" (level));++     f = fopen("conftest_cpuid", "w"); if (!f) return 1;+     fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);+     fclose(f);+     return 0;+])],+     [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],+     [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],+     [ax_cv_gcc_x86_cpuid_$1=unknown])])+AC_LANG_POP([C])+])
+ m4/ax_prepend_flag.m4 view
@@ -0,0 +1,51 @@+# ===========================================================================+#     https://www.gnu.org/software/autoconf-archive/ax_prepend_flag.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_PREPEND_FLAG(FLAG, [FLAGS-VARIABLE])+#+# DESCRIPTION+#+#   FLAG is added to the front of the FLAGS-VARIABLE shell variable, with a+#   space added in between.+#+#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.+#   CFLAGS) is used.  FLAGS-VARIABLE is not changed if it already contains+#   FLAG.  If FLAGS-VARIABLE is unset in the shell, it is set to exactly+#   FLAG.+#+#   NOTE: Implementation based on AX_APPEND_FLAG.+#+# LICENSE+#+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>+#   Copyright (c) 2018 John Zaitseff <J.Zaitseff@zap.org.au>+#+#   Copying and distribution of this file, with or without modification, are+#   permitted in any medium without royalty provided the copyright notice+#   and this notice are preserved.  This file is offered as-is, without any+#   warranty.++#serial 2++AC_DEFUN([AX_PREPEND_FLAG],+[dnl+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])+AS_VAR_SET_IF(FLAGS,[+  AS_CASE([" AS_VAR_GET(FLAGS) "],+    [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],+    [+     FLAGS="$1 $FLAGS"+     AC_RUN_LOG([: FLAGS="$FLAGS"])+    ])+  ],+  [+  AS_VAR_SET(FLAGS,[$1])+  AC_RUN_LOG([: FLAGS="$FLAGS"])+  ])+AS_VAR_POPDEF([FLAGS])dnl+])dnl AX_PREPEND_FLAG
+ m4/ax_require_defined.m4 view
@@ -0,0 +1,37 @@+# ===========================================================================+#    https://www.gnu.org/software/autoconf-archive/ax_require_defined.html+# ===========================================================================+#+# SYNOPSIS+#+#   AX_REQUIRE_DEFINED(MACRO)+#+# DESCRIPTION+#+#   AX_REQUIRE_DEFINED is a simple helper for making sure other macros have+#   been defined and thus are available for use.  This avoids random issues+#   where a macro isn't expanded.  Instead the configure script emits a+#   non-fatal:+#+#     ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found+#+#   It's like AC_REQUIRE except it doesn't expand the required macro.+#+#   Here's an example:+#+#     AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])+#+# LICENSE+#+#   Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>+#+#   Copying and distribution of this file, with or without modification, are+#   permitted in any medium without royalty provided the copyright notice+#   and this notice are preserved. This file is offered as-is, without any+#   warranty.++#serial 2++AC_DEFUN([AX_REQUIRE_DEFINED], [dnl+  m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])+])dnl AX_REQUIRE_DEFINED
+ m4/libtool.m4 view
@@ -0,0 +1,8491 @@+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-+#+#   Copyright (C) 1996-2001, 2003-2019, 2021-2024 Free Software+#   Foundation, Inc.+#   Written by Gordon Matzigkeit, 1996+#+# This file is free software; the Free Software Foundation gives+# unlimited permission to copy and/or distribute it, with or without+# modifications, as long as this notice is preserved.++m4_define([_LT_COPYING], [dnl+# Copyright (C) 2024 Free Software Foundation, Inc.+# This is free software; see the source for copying conditions.  There is NO+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.++# GNU Libtool 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+# (at your option) any later version.+#+# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program or library that is built+# using GNU Libtool, you may include this file under the  same+# distribution terms that you use for the rest of that program.+#+# GNU Libtool is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+# GNU General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program.  If not, see <http://www.gnu.org/licenses/>.+])++# serial 63 LT_INIT+++# LT_PREREQ(VERSION)+# ------------------+# Complain and exit if this libtool version is less that VERSION.+m4_defun([LT_PREREQ],+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,+       [m4_default([$3],+		   [m4_fatal([Libtool version $1 or higher is required],+		             63)])],+       [$2])])+++# _LT_CHECK_BUILDDIR+# ------------------+# Complain if the absolute build directory name contains unusual characters+m4_defun([_LT_CHECK_BUILDDIR],+[case `pwd` in+  *\ * | *\	*)+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;+esac+])+++# LT_INIT([OPTIONS])+# ------------------+AC_DEFUN([LT_INIT],+[AC_PREREQ([2.64])dnl We use AC_PATH_PROGS_FEATURE_CHECK+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl+AC_BEFORE([$0], [LT_LANG])dnl+AC_BEFORE([$0], [LT_OUTPUT])dnl+AC_BEFORE([$0], [LTDL_INIT])dnl+m4_require([_LT_CHECK_BUILDDIR])dnl++dnl Autoconf doesn't catch unexpanded LT_ macros by default:+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4+dnl unless we require an AC_DEFUNed macro:+AC_REQUIRE([LTOPTIONS_VERSION])dnl+AC_REQUIRE([LTSUGAR_VERSION])dnl+AC_REQUIRE([LTVERSION_VERSION])dnl+AC_REQUIRE([LTOBSOLETE_VERSION])dnl+m4_require([_LT_PROG_LTMAIN])dnl++_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])++dnl Parse OPTIONS+_LT_SET_OPTIONS([$0], [$1])++# This can be used to rebuild libtool when needed+LIBTOOL_DEPS=$ltmain++# Always use our own libtool.+LIBTOOL='$(SHELL) $(top_builddir)/libtool'+AC_SUBST(LIBTOOL)dnl++_LT_SETUP++# Only expand once:+m4_define([LT_INIT])+])# LT_INIT++# Old names:+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])+++# _LT_PREPARE_CC_BASENAME+# -----------------------+m4_defun([_LT_PREPARE_CC_BASENAME], [+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.+func_cc_basename ()+{+    for cc_temp in @S|@*""; do+      case $cc_temp in+        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;+        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;+        \-*) ;;+        *) break;;+      esac+    done+    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`+}+])# _LT_PREPARE_CC_BASENAME+++# _LT_CC_BASENAME(CC)+# -------------------+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,+# but that macro is also expanded into generated libtool script, which+# arranges for $SED and $ECHO to be set by different means.+m4_defun([_LT_CC_BASENAME],+[m4_require([_LT_PREPARE_CC_BASENAME])dnl+AC_REQUIRE([_LT_DECL_SED])dnl+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl+func_cc_basename $1+cc_basename=$func_cc_basename_result+])+++# _LT_FILEUTILS_DEFAULTS+# ----------------------+# It is okay to use these file commands and assume they have been set+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.+m4_defun([_LT_FILEUTILS_DEFAULTS],+[: ${CP="cp -f"}+: ${MV="mv -f"}+: ${RM="rm -f"}+])# _LT_FILEUTILS_DEFAULTS+++# _LT_SETUP+# ---------+m4_defun([_LT_SETUP],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+AC_REQUIRE([AC_CANONICAL_BUILD])dnl+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl++_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl+dnl+_LT_DECL([], [host_alias], [0], [The host system])dnl+_LT_DECL([], [host], [0])dnl+_LT_DECL([], [host_os], [0])dnl+dnl+_LT_DECL([], [build_alias], [0], [The build system])dnl+_LT_DECL([], [build], [0])dnl+_LT_DECL([], [build_os], [0])dnl+dnl+AC_REQUIRE([AC_PROG_CC])dnl+AC_REQUIRE([LT_PATH_LD])dnl+AC_REQUIRE([LT_PATH_NM])dnl+dnl+AC_REQUIRE([AC_PROG_LN_S])dnl+test -z "$LN_S" && LN_S="ln -s"+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl+dnl+AC_REQUIRE([LT_CMD_MAX_LEN])dnl+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl+dnl+m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_CHECK_SHELL_FEATURES])dnl+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl+m4_require([_LT_CMD_RELOAD])dnl+m4_require([_LT_DECL_FILECMD])dnl+m4_require([_LT_CHECK_MAGIC_METHOD])dnl+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl+m4_require([_LT_CMD_OLD_ARCHIVE])dnl+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl+m4_require([_LT_WITH_SYSROOT])dnl+m4_require([_LT_CMD_TRUNCATE])dnl++_LT_CONFIG_LIBTOOL_INIT([+# See if we are running on zsh, and set the options that allow our+# commands through without removal of \ escapes INIT.+if test -n "\${ZSH_VERSION+set}"; then+   setopt NO_GLOB_SUBST+fi+])+if test -n "${ZSH_VERSION+set}"; then+   setopt NO_GLOB_SUBST+fi++_LT_CHECK_OBJDIR++m4_require([_LT_TAG_COMPILER])dnl++case $host_os in+aix3*)+  # AIX sometimes has problems with the GCC collect2 program.  For some+  # reason, if we set the COLLECT_NAMES environment variable, the problems+  # vanish in a puff of smoke.+  if test set != "${COLLECT_NAMES+set}"; then+    COLLECT_NAMES=+    export COLLECT_NAMES+  fi+  ;;+esac++# Global variables:+ofile=libtool+can_build_shared=yes++# All known linkers require a '.a' archive for static linking (except MSVC and+# ICC, which need '.lib').+libext=a++with_gnu_ld=$lt_cv_prog_gnu_ld++old_CC=$CC+old_CFLAGS=$CFLAGS++# Set sane defaults for various variables+test -z "$CC" && CC=cc+test -z "$LTCC" && LTCC=$CC+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS+test -z "$LD" && LD=ld+test -z "$ac_objext" && ac_objext=o++_LT_CC_BASENAME([$compiler])++# Only perform the check for file, if the check method requires it+test -z "$MAGIC_CMD" && MAGIC_CMD=file+case $deplibs_check_method in+file_magic*)+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then+    _LT_PATH_MAGIC+  fi+  ;;+esac++# Use C for the default configuration in the libtool script+LT_SUPPORTED_TAG([CC])+_LT_LANG_C_CONFIG+_LT_LANG_DEFAULT_CONFIG+_LT_CONFIG_COMMANDS+])# _LT_SETUP+++# _LT_PREPARE_SED_QUOTE_VARS+# --------------------------+# Define a few sed substitution that help us do robust quoting.+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],+[# Backslashify metacharacters that are still active within+# double-quoted strings.+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'++# Same as above, but do not quote variable references.+double_quote_subst='s/\([["`\\]]\)/\\\1/g'++# Sed substitution to delay expansion of an escaped shell variable in a+# double_quote_subst'ed string.+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'++# Sed substitution to delay expansion of an escaped single quote.+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'++# Sed substitution to avoid accidental globbing in evaled expressions+no_glob_subst='s/\*/\\\*/g'+])++# _LT_PROG_LTMAIN+# ---------------+# Note that this code is called both from 'configure', and 'config.status'+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,+# 'config.status' has no value for ac_aux_dir unless we are using Automake,+# so we pass a copy along to make sure it has a sensible value anyway.+m4_defun([_LT_PROG_LTMAIN],+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])+ltmain=$ac_aux_dir/ltmain.sh+])# _LT_PROG_LTMAIN+++## ------------------------------------- ##+## Accumulate code for creating libtool. ##+## ------------------------------------- ##++# So that we can recreate a full libtool script including additional+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS+# in macros and then make a single call at the end using the 'libtool'+# label.+++# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])+# ----------------------------------------+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.+m4_define([_LT_CONFIG_LIBTOOL_INIT],+[m4_ifval([$1],+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],+                     [$1+])])])++# Initialize.+m4_define([_LT_OUTPUT_LIBTOOL_INIT])+++# _LT_CONFIG_LIBTOOL([COMMANDS])+# ------------------------------+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.+m4_define([_LT_CONFIG_LIBTOOL],+[m4_ifval([$1],+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],+                     [$1+])])])++# Initialize.+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])+++# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])+# -----------------------------------------------------+m4_defun([_LT_CONFIG_SAVE_COMMANDS],+[_LT_CONFIG_LIBTOOL([$1])+_LT_CONFIG_LIBTOOL_INIT([$2])+])+++# _LT_FORMAT_COMMENT([COMMENT])+# -----------------------------+# Add leading comment marks to the start of each line, and a trailing+# full-stop to the whole comment if one is not present already.+m4_define([_LT_FORMAT_COMMENT],+[m4_ifval([$1], [+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])+)])++++## ------------------------ ##+## FIXME: Eliminate VARNAME ##+## ------------------------ ##+++# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])+# -------------------------------------------------------------------+# CONFIGNAME is the name given to the value in the libtool script.+# VARNAME is the (base) name used in the configure script.+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on+# VARNAME.  Any other value will be used directly.+m4_define([_LT_DECL],+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],+	[m4_ifval([$1], [$1], [$2])])+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])+    m4_ifval([$4],+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])+    lt_dict_add_subkey([lt_decl_dict], [$2],+	[tagged?], [m4_ifval([$5], [yes], [no])])])+])+++# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])+# --------------------------------------------------------+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])+++# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])+# ------------------------------------------------+m4_define([lt_decl_tag_varnames],+[_lt_decl_filter([tagged?], [yes], $@)])+++# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])+# ---------------------------------------------------------+m4_define([_lt_decl_filter],+[m4_case([$#],+  [0], [m4_fatal([$0: too few arguments: $#])],+  [1], [m4_fatal([$0: too few arguments: $#: $1])],+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl+])+++# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])+# --------------------------------------------------+m4_define([lt_decl_quote_varnames],+[_lt_decl_filter([value], [1], $@)])+++# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])+# ---------------------------------------------------+m4_define([lt_decl_dquote_varnames],+[_lt_decl_filter([value], [2], $@)])+++# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])+# ---------------------------------------------------+m4_define([lt_decl_varnames_tagged],+[m4_assert([$# <= 2])dnl+_$0(m4_quote(m4_default([$1], [[, ]])),+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])+m4_define([_lt_decl_varnames_tagged],+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])+++# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])+# ------------------------------------------------+m4_define([lt_decl_all_varnames],+[_$0(m4_quote(m4_default([$1], [[, ]])),+     m4_if([$2], [],+	   m4_quote(lt_decl_varnames),+	m4_quote(m4_shift($@))))[]dnl+])+m4_define([_lt_decl_all_varnames],+[lt_join($@, lt_decl_varnames_tagged([$1],+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl+])+++# _LT_CONFIG_STATUS_DECLARE([VARNAME])+# ------------------------------------+# Quote a variable value, and forward it to 'config.status' so that its+# declaration there will have the same value as in 'configure'.  VARNAME+# must have a single quote delimited value for this to work.+m4_define([_LT_CONFIG_STATUS_DECLARE],+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])+++# _LT_CONFIG_STATUS_DECLARATIONS+# ------------------------------+# We delimit libtool config variables with single quotes, so when+# we write them to config.status, we have to be sure to quote all+# embedded single quotes properly.  In configure, this macro expands+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:+#+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])+++# _LT_LIBTOOL_TAGS+# ----------------+# Output comment and list of tags supported by the script+m4_defun([_LT_LIBTOOL_TAGS],+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl+available_tags='_LT_TAGS'dnl+])+++# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])+# -----------------------------------+# Extract the dictionary values for VARNAME (optionally with TAG) and+# expand to a commented shell variable setting:+#+#    # Some comment about what VAR is for.+#    visible_name=$lt_internal_name+m4_define([_LT_LIBTOOL_DECLARE],+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],+					   [description])))[]dnl+m4_pushdef([_libtool_name],+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),+    [0], [_libtool_name=[$]$1],+    [1], [_libtool_name=$lt_[]$1],+    [2], [_libtool_name=$lt_[]$1],+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl+])+++# _LT_LIBTOOL_CONFIG_VARS+# -----------------------+# Produce commented declarations of non-tagged libtool config variables+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG+# section) are produced by _LT_LIBTOOL_TAG_VARS.+m4_defun([_LT_LIBTOOL_CONFIG_VARS],+[m4_foreach([_lt_var],+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])+++# _LT_LIBTOOL_TAG_VARS(TAG)+# -------------------------+m4_define([_LT_LIBTOOL_TAG_VARS],+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])+++# _LT_TAGVAR(VARNAME, [TAGNAME])+# ------------------------------+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])+++# _LT_CONFIG_COMMANDS+# -------------------+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of+# variables for single and double quote escaping we saved from calls+# to _LT_DECL, we can put quote escaped variables declarations+# into 'config.status', and then the shell code to quote escape them in+# for loops in 'config.status'.  Finally, any additional code accumulated+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.+m4_defun([_LT_CONFIG_COMMANDS],+[AC_PROVIDE_IFELSE([LT_OUTPUT],+	dnl If the libtool generation code has been placed in $CONFIG_LT,+	dnl instead of duplicating it all over again into config.status,+	dnl then we will have config.status run $CONFIG_LT later, so it+	dnl needs to know what name is stored there:+        [AC_CONFIG_COMMANDS([libtool],+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],+    dnl If the libtool generation code is destined for config.status,+    dnl expand the accumulated commands and init code now:+    [AC_CONFIG_COMMANDS([libtool],+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])+])#_LT_CONFIG_COMMANDS+++# Initialize.+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],+[++# The HP-UX ksh and POSIX shell print the target directory to stdout+# if CDPATH is set.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH++sed_quote_subst='$sed_quote_subst'+double_quote_subst='$double_quote_subst'+delay_variable_subst='$delay_variable_subst'+_LT_CONFIG_STATUS_DECLARATIONS+LTCC='$LTCC'+LTCFLAGS='$LTCFLAGS'+compiler='$compiler_DEFAULT'++# A function that is used when there is no print builtin or printf.+func_fallback_echo ()+{+  eval 'cat <<_LTECHO_EOF+\$[]1+_LTECHO_EOF'+}++# Quote evaled strings.+for var in lt_decl_all_varnames([[ \+]], lt_decl_quote_varnames); do+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in+    *[[\\\\\\\`\\"\\\$]]*)+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes+      ;;+    *)+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""+      ;;+    esac+done++# Double-quote double-evaled strings.+for var in lt_decl_all_varnames([[ \+]], lt_decl_dquote_varnames); do+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in+    *[[\\\\\\\`\\"\\\$]]*)+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes+      ;;+    *)+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""+      ;;+    esac+done++_LT_OUTPUT_LIBTOOL_INIT+])++# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])+# ------------------------------------+# Generate a child script FILE with all initialization necessary to+# reuse the environment learned by the parent script, and make the+# file executable.  If COMMENT is supplied, it is inserted after the+# '#!' sequence but before initialization text begins.  After this+# macro, additional text can be appended to FILE to form the body of+# the child script.  The macro ends with non-zero status if the+# file could not be fully written (such as if the disk is full).+m4_ifdef([AS_INIT_GENERATED],+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],+[m4_defun([_LT_GENERATED_FILE_INIT],+[m4_require([AS_PREPARE])]dnl+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl+[lt_write_fail=0+cat >$1 <<_ASEOF || lt_write_fail=1+#! $SHELL+# Generated by $as_me.+$2+SHELL=\${CONFIG_SHELL-$SHELL}+export SHELL+_ASEOF+cat >>$1 <<\_ASEOF || lt_write_fail=1+AS_SHELL_SANITIZE+_AS_PREPARE+exec AS_MESSAGE_FD>&1+_ASEOF+test 0 = "$lt_write_fail" && chmod +x $1[]dnl+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT++# LT_OUTPUT+# ---------+# This macro allows early generation of the libtool script (before+# AC_OUTPUT is called), in case it is used in configure for compilation+# tests.+AC_DEFUN([LT_OUTPUT],+[: ${CONFIG_LT=./config.lt}+AC_MSG_NOTICE([creating $CONFIG_LT])+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],+[# Run this file to recreate a libtool stub with the current configuration.])++cat >>"$CONFIG_LT" <<\_LTEOF+lt_cl_silent=false+exec AS_MESSAGE_LOG_FD>>config.log+{+  echo+  AS_BOX([Running $as_me.])+} >&AS_MESSAGE_LOG_FD++lt_cl_help="\+'$as_me' creates a local libtool stub from the current configuration,+for use in further configure time tests before the real libtool is+generated.++Usage: $[0] [[OPTIONS]]++  -h, --help      print this help, then exit+  -V, --version   print version number, then exit+  -q, --quiet     do not print progress messages+  -d, --debug     don't remove temporary files++Report bugs to <bug-libtool@gnu.org>."++lt_cl_version="\+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])+configured by $[0], generated by m4_PACKAGE_STRING.++Copyright (C) 2024 Free Software Foundation, Inc.+This config.lt script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it."++while test 0 != $[#]+do+  case $[1] in+    --version | --v* | -V )+      echo "$lt_cl_version"; exit 0 ;;+    --help | --h* | -h )+      echo "$lt_cl_help"; exit 0 ;;+    --debug | --d* | -d )+      debug=: ;;+    --quiet | --q* | --silent | --s* | -q )+      lt_cl_silent=: ;;++    -*) AC_MSG_ERROR([unrecognized option: $[1]+Try '$[0] --help' for more information.]) ;;++    *) AC_MSG_ERROR([unrecognized argument: $[1]+Try '$[0] --help' for more information.]) ;;+  esac+  shift+done++if $lt_cl_silent; then+  exec AS_MESSAGE_FD>/dev/null+fi+_LTEOF++cat >>"$CONFIG_LT" <<_LTEOF+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT+_LTEOF++cat >>"$CONFIG_LT" <<\_LTEOF+AC_MSG_NOTICE([creating $ofile])+_LT_OUTPUT_LIBTOOL_COMMANDS+AS_EXIT(0)+_LTEOF+chmod +x "$CONFIG_LT"++# configure is writing to config.log, but config.lt does its own redirection,+# appending to config.log, which fails on DOS, as config.log is still kept+# open by configure.  Here we exec the FD to /dev/null, effectively closing+# config.log, so it can be properly (re)opened and appended to by config.lt.+lt_cl_success=:+test yes = "$silent" &&+  lt_config_lt_args="$lt_config_lt_args --quiet"+exec AS_MESSAGE_LOG_FD>/dev/null+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false+exec AS_MESSAGE_LOG_FD>>config.log+$lt_cl_success || AS_EXIT(1)+])# LT_OUTPUT+++# _LT_CONFIG(TAG)+# ---------------+# If TAG is the built-in tag, create an initial libtool script with a+# default configuration from the untagged config vars.  Otherwise add code+# to config.status for appending the configuration named by TAG from the+# matching tagged config vars.+m4_defun([_LT_CONFIG],+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl+_LT_CONFIG_SAVE_COMMANDS([+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl+  m4_if(_LT_TAG, [C], [+    # See if we are running on zsh, and set the options that allow our+    # commands through without removal of \ escapes.+    if test -n "${ZSH_VERSION+set}"; then+      setopt NO_GLOB_SUBST+    fi++    cfgfile=${ofile}T+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15+    $RM "$cfgfile"++    cat <<_LT_EOF >> "$cfgfile"+#! $SHELL+# Generated automatically by $as_me ($PACKAGE) $VERSION+# NOTE: Changes made to this file will be lost: look at ltmain.sh.++# Provide generalized library-building support services.+# Written by Gordon Matzigkeit, 1996++_LT_COPYING+_LT_LIBTOOL_TAGS++# Configured defaults for sys_lib_dlsearch_path munging.+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}++# ### BEGIN LIBTOOL CONFIG+_LT_LIBTOOL_CONFIG_VARS+_LT_LIBTOOL_TAG_VARS+# ### END LIBTOOL CONFIG++_LT_EOF++    cat <<'_LT_EOF' >> "$cfgfile"++# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE++_LT_PREPARE_MUNGE_PATH_LIST+_LT_PREPARE_CC_BASENAME++# ### END FUNCTIONS SHARED WITH CONFIGURE++_LT_EOF++  case $host_os in+  aix3*)+    cat <<\_LT_EOF >> "$cfgfile"+# AIX sometimes has problems with the GCC collect2 program.  For some+# reason, if we set the COLLECT_NAMES environment variable, the problems+# vanish in a puff of smoke.+if test set != "${COLLECT_NAMES+set}"; then+  COLLECT_NAMES=+  export COLLECT_NAMES+fi+_LT_EOF+    ;;+  esac++  _LT_PROG_LTMAIN++  # We use sed instead of cat because bash on DJGPP gets confused if+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in+  # text mode, it properly converts lines to CR/LF.  This bash problem+  # is reportedly fixed, but why not run on old versions too?+  $SED '$q' "$ltmain" >> "$cfgfile" \+     || (rm -f "$cfgfile"; exit 1)++   mv -f "$cfgfile" "$ofile" ||+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")+  chmod +x "$ofile"+],+[cat <<_LT_EOF >> "$ofile"++dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded+dnl in a comment (ie after a #).+# ### BEGIN LIBTOOL TAG CONFIG: $1+_LT_LIBTOOL_TAG_VARS(_LT_TAG)+# ### END LIBTOOL TAG CONFIG: $1+_LT_EOF+])dnl /m4_if+],+[m4_if([$1], [], [+    PACKAGE='$PACKAGE'+    VERSION='$VERSION'+    RM='$RM'+    ofile='$ofile'], [])+])dnl /_LT_CONFIG_SAVE_COMMANDS+])# _LT_CONFIG+++# LT_SUPPORTED_TAG(TAG)+# ---------------------+# Trace this macro to discover what tags are supported by the libtool+# --tag option, using:+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'+AC_DEFUN([LT_SUPPORTED_TAG], [])+++# C support is built-in for now+m4_define([_LT_LANG_C_enabled], [])+m4_define([_LT_TAGS], [])+++# LT_LANG(LANG)+# -------------+# Enable libtool support for the given language if not already enabled.+AC_DEFUN([LT_LANG],+[AC_BEFORE([$0], [LT_OUTPUT])dnl+m4_case([$1],+  [C],			[_LT_LANG(C)],+  [C++],		[_LT_LANG(CXX)],+  [Go],			[_LT_LANG(GO)],+  [Java],		[_LT_LANG(GCJ)],+  [Fortran 77],		[_LT_LANG(F77)],+  [Fortran],		[_LT_LANG(FC)],+  [Windows Resource],	[_LT_LANG(RC)],+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],+    [_LT_LANG($1)],+    [m4_fatal([$0: unsupported language: "$1"])])])dnl+])# LT_LANG+++# _LT_LANG(LANGNAME)+# ------------------+m4_defun([_LT_LANG],+[m4_ifdef([_LT_LANG_]$1[_enabled], [],+  [LT_SUPPORTED_TAG([$1])dnl+  m4_append([_LT_TAGS], [$1 ])dnl+  m4_define([_LT_LANG_]$1[_enabled], [])dnl+  _LT_LANG_$1_CONFIG($1)])dnl+])# _LT_LANG+++m4_ifndef([AC_PROG_GO], [+############################################################+# NOTE: This macro has been submitted for inclusion into   #+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #+#  a released version of Autoconf we should remove this    #+#  macro and use it instead.                               #+############################################################+m4_defun([AC_PROG_GO],+[AC_LANG_PUSH(Go)dnl+AC_ARG_VAR([GOC],     [Go compiler command])dnl+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl+_AC_ARG_VAR_LDFLAGS()dnl+AC_CHECK_TOOL(GOC, gccgo)+if test -z "$GOC"; then+  if test -n "$ac_tool_prefix"; then+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])+  fi+fi+if test -z "$GOC"; then+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)+fi+])#m4_defun+])#m4_ifndef+++# _LT_LANG_DEFAULT_CONFIG+# -----------------------+m4_defun([_LT_LANG_DEFAULT_CONFIG],+[AC_PROVIDE_IFELSE([AC_PROG_CXX],+  [LT_LANG(CXX)],+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])++AC_PROVIDE_IFELSE([AC_PROG_F77],+  [LT_LANG(F77)],+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])++AC_PROVIDE_IFELSE([AC_PROG_FC],+  [LT_LANG(FC)],+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])++dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal+dnl pulling things in needlessly.+AC_PROVIDE_IFELSE([AC_PROG_GCJ],+  [LT_LANG(GCJ)],+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],+    [LT_LANG(GCJ)],+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],+      [LT_LANG(GCJ)],+      [m4_ifdef([AC_PROG_GCJ],+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])+       m4_ifdef([A][M_PROG_GCJ],+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])+       m4_ifdef([LT_PROG_GCJ],+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])++AC_PROVIDE_IFELSE([AC_PROG_GO],+  [LT_LANG(GO)],+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])++AC_PROVIDE_IFELSE([LT_PROG_RC],+  [LT_LANG(RC)],+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])+])# _LT_LANG_DEFAULT_CONFIG++# Obsolete macros:+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])+dnl AC_DEFUN([AC_LIBTOOL_F77], [])+dnl AC_DEFUN([AC_LIBTOOL_FC], [])+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])+dnl AC_DEFUN([AC_LIBTOOL_RC], [])+++# _LT_TAG_COMPILER+# ----------------+m4_defun([_LT_TAG_COMPILER],+[AC_REQUIRE([AC_PROG_CC])dnl++_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl++# If no C compiler was specified, use CC.+LTCC=${LTCC-"$CC"}++# If no C compiler flags were specified, use CFLAGS.+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}++# Allow CC to be a program name with arguments.+compiler=$CC+])# _LT_TAG_COMPILER+++# _LT_COMPILER_BOILERPLATE+# ------------------------+# Check for compiler boilerplate output or warnings with+# the simple compiler test code.+m4_defun([_LT_COMPILER_BOILERPLATE],+[m4_require([_LT_DECL_SED])dnl+ac_outfile=conftest.$ac_objext+echo "$lt_simple_compile_test_code" >conftest.$ac_ext+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err+_lt_compiler_boilerplate=`cat conftest.err`+$RM conftest*+])# _LT_COMPILER_BOILERPLATE+++# _LT_LINKER_BOILERPLATE+# ----------------------+# Check for linker boilerplate output or warnings with+# the simple link test code.+m4_defun([_LT_LINKER_BOILERPLATE],+[m4_require([_LT_DECL_SED])dnl+ac_outfile=conftest.$ac_objext+echo "$lt_simple_link_test_code" >conftest.$ac_ext+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err+_lt_linker_boilerplate=`cat conftest.err`+$RM -r conftest*+])# _LT_LINKER_BOILERPLATE+++# _LT_REQUIRED_DARWIN_CHECKS+# -------------------------+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[+  case $host_os in+    rhapsody* | darwin*)+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])+    AC_CHECK_TOOL([LIPO], [lipo], [:])+    AC_CHECK_TOOL([OTOOL], [otool], [:])+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])+    _LT_DECL([], [DSYMUTIL], [1],+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])+    _LT_DECL([], [NMEDIT], [1],+      [Tool to change global to local symbols on Mac OS X])+    _LT_DECL([], [LIPO], [1],+      [Tool to manipulate fat objects and archives on Mac OS X])+    _LT_DECL([], [OTOOL], [1],+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])+    _LT_DECL([], [OTOOL64], [1],+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])++    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],+      [lt_cv_apple_cc_single_mod=no+      if test -z "$LT_MULTI_MODULE"; then+	# By default we will add the -single_module flag. You can override+	# by either setting the environment variable LT_MULTI_MODULE+	# non-empty at configure time, or by adding -multi_module to the+	# link flags.+	rm -rf libconftest.dylib*+	echo "int foo(void){return 1;}" > conftest.c+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err+        _lt_result=$?+	# If there is a non-empty error log, and "single_module"+	# appears in it, assume the flag caused a linker warning+        if test -s conftest.err && $GREP single_module conftest.err; then+	  cat conftest.err >&AS_MESSAGE_LOG_FD+	# Otherwise, if the output was created with a 0 exit code from+	# the compiler, it worked.+	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then+	  lt_cv_apple_cc_single_mod=yes+	else+	  cat conftest.err >&AS_MESSAGE_LOG_FD+	fi+	rm -rf libconftest.dylib*+	rm -f conftest.*+      fi])++    # Feature test to disable chained fixups since it is not+    # compatible with '-undefined dynamic_lookup'+    AC_CACHE_CHECK([for -no_fixup_chains linker flag],+      [lt_cv_support_no_fixup_chains],+      [ save_LDFLAGS=$LDFLAGS+        LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains"+        AC_LINK_IFELSE(+          [AC_LANG_PROGRAM([],[])],+          lt_cv_support_no_fixup_chains=yes,+          lt_cv_support_no_fixup_chains=no+        )+        LDFLAGS=$save_LDFLAGS+      ]+    )++    AC_CACHE_CHECK([for -exported_symbols_list linker flag],+      [lt_cv_ld_exported_symbols_list],+      [lt_cv_ld_exported_symbols_list=no+      save_LDFLAGS=$LDFLAGS+      echo "_main" > conftest.sym+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],+	[lt_cv_ld_exported_symbols_list=yes],+	[lt_cv_ld_exported_symbols_list=no])+	LDFLAGS=$save_LDFLAGS+    ])++    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],+      [lt_cv_ld_force_load=no+      cat > conftest.c << _LT_EOF+int forced_loaded() { return 2;}+_LT_EOF+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD+      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD+      $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD+      cat > conftest.c << _LT_EOF+int main(void) { return 0;}+_LT_EOF+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err+      _lt_result=$?+      if test -s conftest.err && $GREP force_load conftest.err; then+	cat conftest.err >&AS_MESSAGE_LOG_FD+      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then+	lt_cv_ld_force_load=yes+      else+	cat conftest.err >&AS_MESSAGE_LOG_FD+      fi+        rm -f conftest.err libconftest.a conftest conftest.c+        rm -rf conftest.dSYM+    ])+    case $host_os in+    rhapsody* | darwin1.[[012]])+      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;+    darwin1.*)+      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;+    darwin*)+      case $MACOSX_DEPLOYMENT_TARGET,$host in+        10.[[012]],*|,*powerpc*-darwin[[5-8]]*)+          _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;+        *)+          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup'+          if test yes = "$lt_cv_support_no_fixup_chains"; then+            AS_VAR_APPEND([_lt_dar_allow_undefined], [' $wl-no_fixup_chains'])+          fi+        ;;+      esac+    ;;+  esac+    if test yes = "$lt_cv_apple_cc_single_mod"; then+      _lt_dar_single_mod='$single_module'+    fi+    _lt_dar_needs_single_mod=no+    case $host_os in+    rhapsody* | darwin1.*)+      _lt_dar_needs_single_mod=yes ;;+    darwin*)+      # When targeting Mac OS X 10.4 (darwin 8) or later,+      # -single_module is the default and -multi_module is unsupported.+      # The toolchain on macOS 10.14 (darwin 18) and later cannot+      # target any OS version that needs -single_module.+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in+      10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*)+        _lt_dar_needs_single_mod=yes ;;+      esac+    ;;+    esac+    if test yes = "$lt_cv_ld_exported_symbols_list"; then+      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'+    else+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'+    fi+    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then+      _lt_dsymutil='~$DSYMUTIL $lib || :'+    else+      _lt_dsymutil=+    fi+    ;;+  esac+])+++# _LT_DARWIN_LINKER_FEATURES([TAG])+# ---------------------------------+# Checks for linker and compiler features on darwin+m4_defun([_LT_DARWIN_LINKER_FEATURES],+[+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no+  _LT_TAGVAR(hardcode_direct, $1)=no+  _LT_TAGVAR(hardcode_automatic, $1)=yes+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported+  if test yes = "$lt_cv_ld_force_load"; then+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])+  else+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''+  fi+  _LT_TAGVAR(link_all_deplibs, $1)=yes+  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined+  case $cc_basename in+     ifort*|nagfor*) _lt_dar_can_shared=yes ;;+     *) _lt_dar_can_shared=$GCC ;;+  esac+  if test yes = "$_lt_dar_can_shared"; then+    output_verbose_link_cmd=func_echo_all+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"+    _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"+    _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"+    m4_if([$1], [CXX],+[   if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"+      _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"+    fi+],[])+  else+  _LT_TAGVAR(ld_shlibs, $1)=no+  fi+])++# _LT_SYS_MODULE_PATH_AIX([TAGNAME])+# ----------------------------------+# Links a minimal program and checks the executable+# for the system default hardcoded library path. In most cases,+# this is /usr/lib:/lib, but when the MPI compilers are used+# the location of the communication and MPI libs are included too.+# If we don't find anything, use the default library path according+# to the aix ld manual.+# Store the results from the different compilers for each TAGNAME.+# Allow to override them for all tags through lt_cv_aix_libpath.+m4_defun([_LT_SYS_MODULE_PATH_AIX],+[m4_require([_LT_DECL_SED])dnl+if test set = "${lt_cv_aix_libpath+set}"; then+  aix_libpath=$lt_cv_aix_libpath+else+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[+  lt_aix_libpath_sed='[+      /Import File Strings/,/^$/ {+	  /^0/ {+	      s/^0  *\([^ ]*\) *$/\1/+	      p+	  }+      }]'+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  # Check for a 64-bit object if we didn't find anything.+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`+  fi],[])+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib+  fi+  ])+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])+fi+])# _LT_SYS_MODULE_PATH_AIX+++# _LT_SHELL_INIT(ARG)+# -------------------+m4_define([_LT_SHELL_INIT],+[m4_divert_text([M4SH-INIT], [$1+])])# _LT_SHELL_INIT++++# _LT_PROG_ECHO_BACKSLASH+# -----------------------+# Find how we can fake an echo command that does not interpret backslash.+# In particular, with Autoconf 2.60 or later we add some code to the start+# of the generated configure script that will find a shell with a builtin+# printf (that we can use as an echo command).+m4_defun([_LT_PROG_ECHO_BACKSLASH],+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO++AC_MSG_CHECKING([how to print strings])+# Test print first, because it will be a builtin if present.+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then+  ECHO='print -r --'+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then+  ECHO='printf %s\n'+else+  # Use this function as a fallback that always works.+  func_fallback_echo ()+  {+    eval 'cat <<_LTECHO_EOF+$[]1+_LTECHO_EOF'+  }+  ECHO='func_fallback_echo'+fi++# func_echo_all arg...+# Invoke $ECHO with all args, space-separated.+func_echo_all ()+{+    $ECHO "$*"+}++case $ECHO in+  printf*) AC_MSG_RESULT([printf]) ;;+  print*) AC_MSG_RESULT([print -r]) ;;+  *) AC_MSG_RESULT([cat]) ;;+esac++m4_ifdef([_AS_DETECT_SUGGESTED],+[_AS_DETECT_SUGGESTED([+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO+    PATH=/empty FPATH=/empty; export PATH FPATH+    test "X`printf %s $ECHO`" = "X$ECHO" \+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])++_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])+])# _LT_PROG_ECHO_BACKSLASH+++# _LT_WITH_SYSROOT+# ----------------+AC_DEFUN([_LT_WITH_SYSROOT],+[m4_require([_LT_DECL_SED])dnl+AC_MSG_CHECKING([for sysroot])+AC_ARG_WITH([sysroot],+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],+  [Search for dependent libraries within DIR (or the compiler's sysroot+   if not specified).])],+[], [with_sysroot=no])++dnl lt_sysroot will always be passed unquoted.  We quote it here+dnl in case the user passed a directory name.+lt_sysroot=+case $with_sysroot in #(+ yes)+   if test yes = "$GCC"; then+     # Trim trailing / since we'll always append absolute paths and we want+     # to avoid //, if only for less confusing output for the user.+     lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'`+   fi+   ;; #(+ /*)+   lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"`+   ;; #(+ no|'')+   ;; #(+ *)+   AC_MSG_RESULT([$with_sysroot])+   AC_MSG_ERROR([The sysroot must be an absolute path.])+   ;;+esac++ AC_MSG_RESULT([${lt_sysroot:-no}])+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl+[dependent libraries, and where our libraries should be installed.])])++# _LT_ENABLE_LOCK+# ---------------+m4_defun([_LT_ENABLE_LOCK],+[AC_ARG_ENABLE([libtool-lock],+  [AS_HELP_STRING([--disable-libtool-lock],+    [avoid locking (might break parallel builds)])])+test no = "$enable_libtool_lock" || enable_libtool_lock=yes++# Some flags need to be propagated to the compiler or linker for good+# libtool support.+case $host in+ia64-*-hpux*)+  # Find out what ABI is being produced by ac_compile, and set mode+  # options accordingly.+  echo 'int i;' > conftest.$ac_ext+  if AC_TRY_EVAL(ac_compile); then+    case `$FILECMD conftest.$ac_objext` in+      *ELF-32*)+	HPUX_IA64_MODE=32+	;;+      *ELF-64*)+	HPUX_IA64_MODE=64+	;;+    esac+  fi+  rm -rf conftest*+  ;;+*-*-irix6*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext+  if AC_TRY_EVAL(ac_compile); then+    if test yes = "$lt_cv_prog_gnu_ld"; then+      case `$FILECMD conftest.$ac_objext` in+	*32-bit*)+	  LD="${LD-ld} -melf32bsmip"+	  ;;+	*N32*)+	  LD="${LD-ld} -melf32bmipn32"+	  ;;+	*64-bit*)+	  LD="${LD-ld} -melf64bmip"+	;;+      esac+    else+      case `$FILECMD conftest.$ac_objext` in+	*32-bit*)+	  LD="${LD-ld} -32"+	  ;;+	*N32*)+	  LD="${LD-ld} -n32"+	  ;;+	*64-bit*)+	  LD="${LD-ld} -64"+	  ;;+      esac+    fi+  fi+  rm -rf conftest*+  ;;++mips64*-*linux*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext+  if AC_TRY_EVAL(ac_compile); then+    emul=elf+    case `$FILECMD conftest.$ac_objext` in+      *32-bit*)+	emul="${emul}32"+	;;+      *64-bit*)+	emul="${emul}64"+	;;+    esac+    case `$FILECMD conftest.$ac_objext` in+      *MSB*)+	emul="${emul}btsmip"+	;;+      *LSB*)+	emul="${emul}ltsmip"+	;;+    esac+    case `$FILECMD conftest.$ac_objext` in+      *N32*)+	emul="${emul}n32"+	;;+    esac+    LD="${LD-ld} -m $emul"+  fi+  rm -rf conftest*+  ;;++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \+s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.  Note that the listed cases only cover the+  # situations where additional linker options are needed (such as when+  # doing 32-bit compilation for a host where ld defaults to 64-bit, or+  # vice versa); the common cases where no linker options are needed do+  # not appear in the list.+  echo 'int i;' > conftest.$ac_ext+  if AC_TRY_EVAL(ac_compile); then+    case `$FILECMD conftest.o` in+      *32-bit*)+	case $host in+	  x86_64-*kfreebsd*-gnu)+	    LD="${LD-ld} -m elf_i386_fbsd"+	    ;;+	  x86_64-*linux*|x86_64-gnu*)+	    case `$FILECMD conftest.o` in+	      *x86-64*)+		LD="${LD-ld} -m elf32_x86_64"+		;;+	      *)+		LD="${LD-ld} -m elf_i386"+		;;+	    esac+	    ;;+	  powerpc64le-*linux*)+	    LD="${LD-ld} -m elf32lppclinux"+	    ;;+	  powerpc64-*linux*)+	    LD="${LD-ld} -m elf32ppclinux"+	    ;;+	  s390x-*linux*)+	    LD="${LD-ld} -m elf_s390"+	    ;;+	  sparc64-*linux*)+	    LD="${LD-ld} -m elf32_sparc"+	    ;;+	esac+	;;+      *64-bit*)+	case $host in+	  x86_64-*kfreebsd*-gnu)+	    LD="${LD-ld} -m elf_x86_64_fbsd"+	    ;;+	  x86_64-*linux*|x86_64-gnu*)+	    LD="${LD-ld} -m elf_x86_64"+	    ;;+	  powerpcle-*linux*)+	    LD="${LD-ld} -m elf64lppc"+	    ;;+	  powerpc-*linux*)+	    LD="${LD-ld} -m elf64ppc"+	    ;;+	  s390*-*linux*|s390*-*tpf*)+	    LD="${LD-ld} -m elf64_s390"+	    ;;+	  sparc*-*linux*)+	    LD="${LD-ld} -m elf64_sparc"+	    ;;+	esac+	;;+    esac+  fi+  rm -rf conftest*+  ;;++*-*-sco3.2v5*)+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.+  SAVE_CFLAGS=$CFLAGS+  CFLAGS="$CFLAGS -belf"+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,+    [AC_LANG_PUSH(C)+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])+     AC_LANG_POP])+  if test yes != "$lt_cv_cc_needs_belf"; then+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf+    CFLAGS=$SAVE_CFLAGS+  fi+  ;;+*-*solaris*)+  # Find out what ABI is being produced by ac_compile, and set linker+  # options accordingly.+  echo 'int i;' > conftest.$ac_ext+  if AC_TRY_EVAL(ac_compile); then+    case `$FILECMD conftest.o` in+    *64-bit*)+      case $lt_cv_prog_gnu_ld in+      yes*)+        case $host in+        i?86-*-solaris*|x86_64-*-solaris*)+          LD="${LD-ld} -m elf_x86_64"+          ;;+        sparc*-*-solaris*)+          LD="${LD-ld} -m elf64_sparc"+          ;;+        esac+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then+          LD=${LD-ld}_sol2+        fi+        ;;+      *)+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then+	  LD="${LD-ld} -64"+	fi+	;;+      esac+      ;;+    esac+  fi+  rm -rf conftest*+  ;;+esac++need_locks=$enable_libtool_lock+])# _LT_ENABLE_LOCK+++# _LT_PROG_AR+# -----------+m4_defun([_LT_PROG_AR],+[AC_CHECK_TOOLS(AR, [ar], false)+: ${AR=ar}+_LT_DECL([], [AR], [1], [The archiver])++# Use ARFLAGS variable as AR's operation code to sync the variable naming with+# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have+# higher priority because that's what people were doing historically (setting+# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS+# variable obsoleted/removed.++test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}+lt_ar_flags=$AR_FLAGS+_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])++# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override+# by AR_FLAGS because that was never working and AR_FLAGS is about to die.+_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],+         [Flags to create an archive])++AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],+  [lt_cv_ar_at_file=no+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],+     [echo conftest.$ac_objext > conftest.lst+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'+      AC_TRY_EVAL([lt_ar_try])+      if test 0 -eq "$ac_status"; then+	# Ensure the archiver fails upon bogus file names.+	rm -f conftest.$ac_objext libconftest.a+	AC_TRY_EVAL([lt_ar_try])+	if test 0 -ne "$ac_status"; then+          lt_cv_ar_at_file=@+        fi+      fi+      rm -f conftest.* libconftest.a+     ])+  ])++if test no = "$lt_cv_ar_at_file"; then+  archiver_list_spec=+else+  archiver_list_spec=$lt_cv_ar_at_file+fi+_LT_DECL([], [archiver_list_spec], [1],+  [How to feed a file listing to the archiver])+])# _LT_PROG_AR+++# _LT_CMD_OLD_ARCHIVE+# -------------------+m4_defun([_LT_CMD_OLD_ARCHIVE],+[_LT_PROG_AR++AC_CHECK_TOOL(STRIP, strip, :)+test -z "$STRIP" && STRIP=:+_LT_DECL([], [STRIP], [1], [A symbol stripping program])++AC_REQUIRE([AC_PROG_RANLIB])+test -z "$RANLIB" && RANLIB=:+_LT_DECL([], [RANLIB], [1],+    [Commands used to install an old-style archive])++# Determine commands to create old-style static archives.+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'+old_postinstall_cmds='chmod 644 $oldlib'+old_postuninstall_cmds=++if test -n "$RANLIB"; then+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"+  old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"+fi++case $host_os in+  darwin*)+    lock_old_archive_extraction=yes ;;+  *)+    lock_old_archive_extraction=no ;;+esac+_LT_DECL([], [old_postinstall_cmds], [2])+_LT_DECL([], [old_postuninstall_cmds], [2])+_LT_TAGDECL([], [old_archive_cmds], [2],+    [Commands used to build an old-style archive])+_LT_DECL([], [lock_old_archive_extraction], [0],+    [Whether to use a lock for old archive extraction])+])# _LT_CMD_OLD_ARCHIVE+++# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])+# ----------------------------------------------------------------+# Check whether the given compiler option works+AC_DEFUN([_LT_COMPILER_OPTION],+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_DECL_SED])dnl+AC_CACHE_CHECK([$1], [$2],+  [$2=no+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext+   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   # The option is referenced via a variable to avoid confusing sed.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)+   (eval "$lt_compile" 2>conftest.err)+   ac_status=$?+   cat conftest.err >&AS_MESSAGE_LOG_FD+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD+   if (exit $ac_status) && test -s "$ac_outfile"; then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings other than the usual output.+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then+       $2=yes+     fi+   fi+   $RM conftest*+])++if test yes = "[$]$2"; then+    m4_if([$5], , :, [$5])+else+    m4_if([$6], , :, [$6])+fi+])# _LT_COMPILER_OPTION++# Old name:+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])+++# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,+#                  [ACTION-SUCCESS], [ACTION-FAILURE])+# ----------------------------------------------------+# Check whether the given linker option works+AC_DEFUN([_LT_LINKER_OPTION],+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_DECL_SED])dnl+AC_CACHE_CHECK([$1], [$2],+  [$2=no+   save_LDFLAGS=$LDFLAGS+   LDFLAGS="$LDFLAGS $3"+   echo "$lt_simple_link_test_code" > conftest.$ac_ext+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then+     # The linker can only warn and ignore the option if not recognized+     # So say no if there are warnings+     if test -s conftest.err; then+       # Append any errors to the config.log.+       cat conftest.err 1>&AS_MESSAGE_LOG_FD+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2+       if diff conftest.exp conftest.er2 >/dev/null; then+         $2=yes+       fi+     else+       $2=yes+     fi+   fi+   $RM -r conftest*+   LDFLAGS=$save_LDFLAGS+])++if test yes = "[$]$2"; then+    m4_if([$4], , :, [$4])+else+    m4_if([$5], , :, [$5])+fi+])# _LT_LINKER_OPTION++# Old name:+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])+++# LT_CMD_MAX_LEN+#---------------+AC_DEFUN([LT_CMD_MAX_LEN],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+# find the maximum length of command line arguments+AC_MSG_CHECKING([the maximum length of command line arguments])+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl+  i=0+  teststring=ABCD++  case $build_os in+  msdosdjgpp*)+    # On DJGPP, this test can blow up pretty badly due to problems in libc+    # (any single argument exceeding 2000 bytes causes a buffer overrun+    # during glob expansion).  Even if it were fixed, the result of this+    # check would be larger than it should be.+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right+    ;;++  gnu* | ironclad*)+    # Under GNU Hurd and Ironclad, this test is not required because there+    # is no limit to the length of command line arguments.+    # Libtool will interpret -1 as no limit whatsoever+    lt_cv_sys_max_cmd_len=-1;+    ;;++  cygwin* | mingw* | windows* | cegcc*)+    # On Win9x/ME, this test blows up -- it succeeds, but takes+    # about 5 minutes as the teststring grows exponentially.+    # Worse, since 9x/ME are not pre-emptively multitasking,+    # you end up with a "frozen" computer, even though with patience+    # the test eventually succeeds (with a max line length of 256k).+    # Instead, let's just punt: use the minimum linelength reported by+    # all of the supported platforms: 8192 (on NT/2K/XP).+    lt_cv_sys_max_cmd_len=8192;+    ;;++  mint*)+    # On MiNT this can take a long time and run out of memory.+    lt_cv_sys_max_cmd_len=8192;+    ;;++  amigaos*)+    # On AmigaOS with pdksh, this test takes hours, literally.+    # So we just punt and use a minimum line length of 8192.+    lt_cv_sys_max_cmd_len=8192;+    ;;++  darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)+    # This has been around since 386BSD, at least.  Likely further.+    if test -x /sbin/sysctl; then+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`+    elif test -x /usr/sbin/sysctl; then+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`+    else+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs+    fi+    # And add a safety zone+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`+    ;;++  interix*)+    # We know the value 262144 and hardcode it with a safety zone (like BSD)+    lt_cv_sys_max_cmd_len=196608+    ;;++  os2*)+    # The test takes a long time on OS/2.+    lt_cv_sys_max_cmd_len=8192+    ;;++  osf*)+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not+    # nice to cause kernel panics so lets avoid the loop below.+    # First set a reasonable default.+    lt_cv_sys_max_cmd_len=16384+    #+    if test -x /sbin/sysconfig; then+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in+        *1*) lt_cv_sys_max_cmd_len=-1 ;;+      esac+    fi+    ;;+  sco3.2v5*)+    lt_cv_sys_max_cmd_len=102400+    ;;+  sysv5* | sco5v6* | sysv4.2uw2*)+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`+    if test -n "$kargmax"; then+      lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[	 ]]//'`+    else+      lt_cv_sys_max_cmd_len=32768+    fi+    ;;+  *)+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`+    if test -n "$lt_cv_sys_max_cmd_len" && \+       test undefined != "$lt_cv_sys_max_cmd_len"; then+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`+    else+      # Make teststring a little bigger before we do anything with it.+      # a 1K string should be a reasonable start.+      for i in 1 2 3 4 5 6 7 8; do+        teststring=$teststring$teststring+      done+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}+      # If test is not a shell built-in, we'll probably end up computing a+      # maximum length that is only half of the actual maximum length, but+      # we can't tell.+      while { test X`env echo "$teststring$teststring" 2>/dev/null` \+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&+	      test 17 != "$i" # 1/2 MB should be enough+      do+        i=`expr $i + 1`+        teststring=$teststring$teststring+      done+      # Only check the string length outside the loop.+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`+      teststring=+      # Add a significant safety factor because C++ compilers can tack on+      # massive amounts of additional arguments before passing them to the+      # linker.  It appears as though 1/2 is a usable value.+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`+    fi+    ;;+  esac+])+if test -n "$lt_cv_sys_max_cmd_len"; then+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)+else+  AC_MSG_RESULT(none)+fi+max_cmd_len=$lt_cv_sys_max_cmd_len+_LT_DECL([], [max_cmd_len], [0],+    [What is the maximum length of a command?])+])# LT_CMD_MAX_LEN++# Old name:+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])+++# _LT_HEADER_DLFCN+# ----------------+m4_defun([_LT_HEADER_DLFCN],+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl+])# _LT_HEADER_DLFCN+++# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)+# ----------------------------------------------------------------+m4_defun([_LT_TRY_DLOPEN_SELF],+[m4_require([_LT_HEADER_DLFCN])dnl+if test yes = "$cross_compiling"; then :+  [$4]+else+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2+  lt_status=$lt_dlunknown+  cat > conftest.$ac_ext <<_LT_EOF+[#line $LINENO "configure"+#include "confdefs.h"++#if HAVE_DLFCN_H+#include <dlfcn.h>+#endif++#include <stdio.h>++#ifdef RTLD_GLOBAL+#  define LT_DLGLOBAL		RTLD_GLOBAL+#else+#  ifdef DL_GLOBAL+#    define LT_DLGLOBAL		DL_GLOBAL+#  else+#    define LT_DLGLOBAL		0+#  endif+#endif++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we+   find out it does not work in some platform. */+#ifndef LT_DLLAZY_OR_NOW+#  ifdef RTLD_LAZY+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY+#  else+#    ifdef DL_LAZY+#      define LT_DLLAZY_OR_NOW		DL_LAZY+#    else+#      ifdef RTLD_NOW+#        define LT_DLLAZY_OR_NOW	RTLD_NOW+#      else+#        ifdef DL_NOW+#          define LT_DLLAZY_OR_NOW	DL_NOW+#        else+#          define LT_DLLAZY_OR_NOW	0+#        endif+#      endif+#    endif+#  endif+#endif++/* When -fvisibility=hidden is used, assume the code has been annotated+   correspondingly for the symbols needed.  */+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))+int fnord (void) __attribute__((visibility("default")));+#endif++int fnord (void) { return 42; }+int main (void)+{+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);+  int status = $lt_dlunknown;++  if (self)+    {+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;+      else+        {+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;+          else puts (dlerror ());+	}+      /* dlclose (self); */+    }+  else+    puts (dlerror ());++  return status;+}]+_LT_EOF+  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null+    lt_status=$?+    case x$lt_status in+      x$lt_dlno_uscore) $1 ;;+      x$lt_dlneed_uscore) $2 ;;+      x$lt_dlunknown|x*) $3 ;;+    esac+  else :+    # compilation failed+    $3+  fi+fi+rm -fr conftest*+])# _LT_TRY_DLOPEN_SELF+++# LT_SYS_DLOPEN_SELF+# ------------------+AC_DEFUN([LT_SYS_DLOPEN_SELF],+[m4_require([_LT_HEADER_DLFCN])dnl+if test yes != "$enable_dlopen"; then+  enable_dlopen=unknown+  enable_dlopen_self=unknown+  enable_dlopen_self_static=unknown+else+  lt_cv_dlopen=no+  lt_cv_dlopen_libs=++  case $host_os in+  beos*)+    lt_cv_dlopen=load_add_on+    lt_cv_dlopen_libs=+    lt_cv_dlopen_self=yes+    ;;++  mingw* | windows* | pw32* | cegcc*)+    lt_cv_dlopen=LoadLibrary+    lt_cv_dlopen_libs=+    ;;++  cygwin*)+    lt_cv_dlopen=dlopen+    lt_cv_dlopen_libs=+    ;;++  darwin*)+    # if libdl is installed we need to link against it+    AC_CHECK_LIB([dl], [dlopen],+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[+    lt_cv_dlopen=dyld+    lt_cv_dlopen_libs=+    lt_cv_dlopen_self=yes+    ])+    ;;++  tpf*)+    # Don't try to run any link tests for TPF.  We know it's impossible+    # because TPF is a cross-compiler, and we know how we open DSOs.+    lt_cv_dlopen=dlopen+    lt_cv_dlopen_libs=+    lt_cv_dlopen_self=no+    ;;++  *)+    AC_CHECK_FUNC([shl_load],+	  [lt_cv_dlopen=shl_load],+      [AC_CHECK_LIB([dld], [shl_load],+	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],+	[AC_CHECK_FUNC([dlopen],+	      [lt_cv_dlopen=dlopen],+	  [AC_CHECK_LIB([dl], [dlopen],+		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],+	    [AC_CHECK_LIB([svld], [dlopen],+		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],+	      [AC_CHECK_LIB([dld], [dld_link],+		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])+	      ])+	    ])+	  ])+	])+      ])+    ;;+  esac++  if test no = "$lt_cv_dlopen"; then+    enable_dlopen=no+  else+    enable_dlopen=yes+  fi++  case $lt_cv_dlopen in+  dlopen)+    save_CPPFLAGS=$CPPFLAGS+    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"++    save_LDFLAGS=$LDFLAGS+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"++    save_LIBS=$LIBS+    LIBS="$lt_cv_dlopen_libs $LIBS"++    AC_CACHE_CHECK([whether a program can dlopen itself],+	  lt_cv_dlopen_self, [dnl+	  _LT_TRY_DLOPEN_SELF(+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)+    ])++    if test yes = "$lt_cv_dlopen_self"; then+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],+	  lt_cv_dlopen_self_static, [dnl+	  _LT_TRY_DLOPEN_SELF(+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)+      ])+    fi++    CPPFLAGS=$save_CPPFLAGS+    LDFLAGS=$save_LDFLAGS+    LIBS=$save_LIBS+    ;;+  esac++  case $lt_cv_dlopen_self in+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;+  *) enable_dlopen_self=unknown ;;+  esac++  case $lt_cv_dlopen_self_static in+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;+  *) enable_dlopen_self_static=unknown ;;+  esac+fi+_LT_DECL([dlopen_support], [enable_dlopen], [0],+	 [Whether dlopen is supported])+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],+	 [Whether dlopen of programs is supported])+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],+	 [Whether dlopen of statically linked programs is supported])+])# LT_SYS_DLOPEN_SELF++# Old name:+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])+++# _LT_COMPILER_C_O([TAGNAME])+# ---------------------------+# Check to see if options -c and -o are simultaneously supported by compiler.+# This macro does not hard code the compiler like AC_PROG_CC_C_O.+m4_defun([_LT_COMPILER_C_O],+[m4_require([_LT_DECL_SED])dnl+m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_TAG_COMPILER])dnl+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no+   $RM -r conftest 2>/dev/null+   mkdir conftest+   cd conftest+   mkdir out+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext++   lt_compiler_flag="-o out/conftest2.$ac_objext"+   # Insert the option either (1) after the last *FLAGS variable, or+   # (2) before a word containing "conftest.", or (3) at the end.+   # Note that $ac_compile itself does not contain backslashes and begins+   # with a dollar sign (not a hyphen), so the echo should work correctly.+   lt_compile=`echo "$ac_compile" | $SED \+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \+   -e 's:$: $lt_compiler_flag:'`+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)+   (eval "$lt_compile" 2>out/conftest.err)+   ac_status=$?+   cat out/conftest.err >&AS_MESSAGE_LOG_FD+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD+   if (exit $ac_status) && test -s out/conftest2.$ac_objext+   then+     # The compiler can only warn and ignore the option if not recognized+     # So say no if there are warnings+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes+     fi+   fi+   chmod u+w . 2>&AS_MESSAGE_LOG_FD+   $RM conftest*+   # SGI C++ compiler will create directory out/ii_files/ for+   # template instantiation+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files+   $RM out/* && rmdir out+   cd ..+   $RM -r conftest+   $RM conftest*+])+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],+	[Does compiler simultaneously support -c and -o options?])+])# _LT_COMPILER_C_O+++# _LT_COMPILER_FILE_LOCKS([TAGNAME])+# ----------------------------------+# Check to see if we can do hard links to lock some files if needed+m4_defun([_LT_COMPILER_FILE_LOCKS],+[m4_require([_LT_ENABLE_LOCK])dnl+m4_require([_LT_FILEUTILS_DEFAULTS])dnl+_LT_COMPILER_C_O([$1])++hard_links=nottested+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then+  # do not overwrite the value of need_locks provided by the user+  AC_MSG_CHECKING([if we can lock with hard links])+  hard_links=yes+  $RM conftest*+  ln conftest.a conftest.b 2>/dev/null && hard_links=no+  touch conftest.a+  ln conftest.a conftest.b 2>&5 || hard_links=no+  ln conftest.a conftest.b 2>/dev/null && hard_links=no+  AC_MSG_RESULT([$hard_links])+  if test no = "$hard_links"; then+    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])+    need_locks=warn+  fi+else+  need_locks=no+fi+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])+])# _LT_COMPILER_FILE_LOCKS+++# _LT_CHECK_OBJDIR+# ----------------+m4_defun([_LT_CHECK_OBJDIR],+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],+[rm -f .libs 2>/dev/null+mkdir .libs 2>/dev/null+if test -d .libs; then+  lt_cv_objdir=.libs+else+  # MS-DOS does not allow filenames that begin with a dot.+  lt_cv_objdir=_libs+fi+rmdir .libs 2>/dev/null])+objdir=$lt_cv_objdir+_LT_DECL([], [objdir], [0],+         [The name of the directory that contains temporary libtool files])dnl+m4_pattern_allow([LT_OBJDIR])dnl+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",+  [Define to the sub-directory where libtool stores uninstalled libraries.])+])# _LT_CHECK_OBJDIR+++# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])+# --------------------------------------+# Check hardcoding attributes.+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],+[AC_MSG_CHECKING([how to hardcode library paths into programs])+_LT_TAGVAR(hardcode_action, $1)=+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||+   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then++  # We can hardcode non-existent directories.+  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&+     # If the only mechanism to avoid hardcoding is shlibpath_var, we+     # have to relink, otherwise we might link with an installed library+     # when we should be linking with a yet-to-be-installed one+     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&+     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then+    # Linking always hardcodes the temporary library directory.+    _LT_TAGVAR(hardcode_action, $1)=relink+  else+    # We can link without hardcoding, and we can hardcode nonexisting dirs.+    _LT_TAGVAR(hardcode_action, $1)=immediate+  fi+else+  # We cannot hardcode anything, or else we can only hardcode existing+  # directories.+  _LT_TAGVAR(hardcode_action, $1)=unsupported+fi+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])++if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||+   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then+  # Fast installation is not supported+  enable_fast_install=no+elif test yes = "$shlibpath_overrides_runpath" ||+     test no = "$enable_shared"; then+  # Fast installation is not necessary+  enable_fast_install=needless+fi+_LT_TAGDECL([], [hardcode_action], [0],+    [How to hardcode a shared library path into an executable])+])# _LT_LINKER_HARDCODE_LIBPATH+++# _LT_CMD_STRIPLIB+# ----------------+m4_defun([_LT_CMD_STRIPLIB],+[m4_require([_LT_DECL_EGREP])+striplib=+old_striplib=+AC_MSG_CHECKING([whether stripping libraries is possible])+if test -z "$STRIP"; then+  AC_MSG_RESULT([no])+else+  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then+    old_striplib="$STRIP --strip-debug"+    striplib="$STRIP --strip-unneeded"+    AC_MSG_RESULT([yes])+  else+    case $host_os in+    darwin*)+      # FIXME - insert some real tests, host_os isn't really good enough+      striplib="$STRIP -x"+      old_striplib="$STRIP -S"+      AC_MSG_RESULT([yes])+      ;;+    freebsd*)+      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then+        old_striplib="$STRIP --strip-debug"+        striplib="$STRIP --strip-unneeded"+        AC_MSG_RESULT([yes])+      else+        AC_MSG_RESULT([no])+      fi+      ;;+    *)+      AC_MSG_RESULT([no])+      ;;+    esac+  fi+fi+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])+_LT_DECL([], [striplib], [1])+])# _LT_CMD_STRIPLIB+++# _LT_PREPARE_MUNGE_PATH_LIST+# ---------------------------+# Make sure func_munge_path_list() is defined correctly.+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],+[[# func_munge_path_list VARIABLE PATH+# -----------------------------------+# VARIABLE is name of variable containing _space_ separated list of+# directories to be munged by the contents of PATH, which is string+# having a format:+# "DIR[:DIR]:"+#       string "DIR[ DIR]" will be prepended to VARIABLE+# ":DIR[:DIR]"+#       string "DIR[ DIR]" will be appended to VARIABLE+# "DIRP[:DIRP]::[DIRA:]DIRA"+#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string+#       "DIRA[ DIRA]" will be appended to VARIABLE+# "DIR[:DIR]"+#       VARIABLE will be replaced by "DIR[ DIR]"+func_munge_path_list ()+{+    case x@S|@2 in+    x)+        ;;+    *:)+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"+        ;;+    x:*)+        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"+        ;;+    *::*)+        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"+        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"+        ;;+    *)+        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"+        ;;+    esac+}+]])# _LT_PREPARE_PATH_LIST+++# _LT_SYS_DYNAMIC_LINKER([TAG])+# -----------------------------+# PORTME Fill in your ld.so characteristics+m4_defun([_LT_SYS_DYNAMIC_LINKER],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+m4_require([_LT_DECL_EGREP])dnl+m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_DECL_OBJDUMP])dnl+m4_require([_LT_DECL_SED])dnl+m4_require([_LT_CHECK_SHELL_FEATURES])dnl+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl+AC_MSG_CHECKING([dynamic linker characteristics])+m4_if([$1],+	[], [+if test yes = "$GCC"; then+  case $host_os in+    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;+    *) lt_awk_arg='/^libraries:/' ;;+  esac+  case $host_os in+    mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;+    *) lt_sed_strip_eq='s|=/|/|g' ;;+  esac+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`+  case $lt_search_path_spec in+  *\;*)+    # if the path contains ";" then we assume it to be the separator+    # otherwise default to the standard path separator (i.e. ":") - it is+    # assumed that no part of a normal pathname contains ";" but that should+    # okay in the real world where ";" in dirpaths is itself problematic.+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`+    ;;+  *)+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`+    ;;+  esac+  # Ok, now we have the path, separated by spaces, we can step through it+  # and add multilib dir if necessary...+  lt_tmp_lt_search_path_spec=+  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`+  # ...but if some path component already ends with the multilib dir we assume+  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).+  case "$lt_multi_os_dir; $lt_search_path_spec " in+  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)+    lt_multi_os_dir=+    ;;+  esac+  for lt_sys_path in $lt_search_path_spec; do+    if test -d "$lt_sys_path$lt_multi_os_dir"; then+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"+    elif test -n "$lt_multi_os_dir"; then+      test -d "$lt_sys_path" && \+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"+    fi+  done+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '+BEGIN {RS = " "; FS = "/|\n";} {+  lt_foo = "";+  lt_count = 0;+  for (lt_i = NF; lt_i > 0; lt_i--) {+    if ($lt_i != "" && $lt_i != ".") {+      if ($lt_i == "..") {+        lt_count++;+      } else {+        if (lt_count == 0) {+          lt_foo = "/" $lt_i lt_foo;+        } else {+          lt_count--;+        }+      }+    }+  }+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }+}'`+  # AWK program above erroneously prepends '/' to C:/dos/paths+  # for these hosts.+  case $host_os in+    mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\+      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;+  esac+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`+else+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"+fi])+library_names_spec=+libname_spec='lib$name'+soname_spec=+shrext_cmds=.so+postinstall_cmds=+postuninstall_cmds=+finish_cmds=+finish_eval=+shlibpath_var=+shlibpath_overrides_runpath=unknown+version_type=none+dynamic_linker="$host_os ld.so"+sys_lib_dlsearch_path_spec="/lib /usr/lib"+need_lib_prefix=unknown+hardcode_into_libs=no++# when you set need_version to no, make sure it does not cause -set_version+# flags to be left without arguments+need_version=unknown++AC_ARG_VAR([LT_SYS_LIBRARY_PATH],+[User-defined run-time library search path.])++case $host_os in+aix3*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'+  shlibpath_var=LIBPATH++  # AIX 3 has no versioning support, so we append a major version to the name.+  soname_spec='$libname$release$shared_ext$major'+  ;;++aix[[4-9]]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  hardcode_into_libs=yes+  if test ia64 = "$host_cpu"; then+    # AIX 5 supports IA64+    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'+    shlibpath_var=LD_LIBRARY_PATH+  else+    # With GCC up to 2.95.x, collect2 would create an import file+    # for dependence libraries.  The import file would start with+    # the line '#! .'.  This would cause the generated library to+    # depend on '.', always an invalid library.  This was fixed in+    # development snapshots of GCC prior to 3.0.+    case $host_os in+      aix4 | aix4.[[01]] | aix4.[[01]].*)+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'+	   echo ' yes '+	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then+	:+      else+	can_build_shared=no+      fi+      ;;+    esac+    # Using Import Files as archive members, it is possible to support+    # filename-based versioning of shared library archives on AIX. While+    # this would work for both with and without runtime linking, it will+    # prevent static linking of such archives. So we do filename-based+    # shared library versioning with .so extension only, which is used+    # when both runtime linking and shared linking is enabled.+    # Unfortunately, runtime linking may impact performance, so we do+    # not want this to be the default eventually. Also, we use the+    # versioned .so libs for executables only if there is the -brtl+    # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only.+    # To allow for filename-based versioning support, we need to create+    # libNAME.so.V as an archive file, containing:+    # *) an Import File, referring to the versioned filename of the+    #    archive as well as the shared archive member, telling the+    #    bitwidth (32 or 64) of that shared object, and providing the+    #    list of exported symbols of that shared object, eventually+    #    decorated with the 'weak' keyword+    # *) the shared object with the F_LOADONLY flag set, to really avoid+    #    it being seen by the linker.+    # At run time we better use the real file rather than another symlink,+    # but for link time we create the symlink libNAME.so -> libNAME.so.V++    case $with_aix_soname,$aix_use_runtimelinking in+    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct+    # soname into executable. Probably we can add versioning support to+    # collect2, so additional links can be useful in future.+    aix,yes) # traditional libtool+      dynamic_linker='AIX unversionable lib.so'+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so+      # instead of lib<name>.a to let people know that these are not+      # typical AIX shared libraries.+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+      ;;+    aix,no) # traditional AIX only+      dynamic_linker='AIX lib.a[(]lib.so.V[)]'+      # We preserve .a as extension for shared libraries through AIX4.2+      # and later when we are not doing run time linking.+      library_names_spec='$libname$release.a $libname.a'+      soname_spec='$libname$release$shared_ext$major'+      ;;+    svr4,*) # full svr4 only+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'+      # We do not specify a path in Import Files, so LIBPATH fires.+      shlibpath_overrides_runpath=yes+      ;;+    *,yes) # both, prefer svr4+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"+      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'+      # unpreferred sharedlib libNAME.a needs extra handling+      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'+      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'+      # We do not specify a path in Import Files, so LIBPATH fires.+      shlibpath_overrides_runpath=yes+      ;;+    *,no) # both, prefer aix+      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"+      library_names_spec='$libname$release.a $libname.a'+      soname_spec='$libname$release$shared_ext$major'+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'+      ;;+    esac+    shlibpath_var=LIBPATH+  fi+  ;;++amigaos*)+  case $host_cpu in+  powerpc)+    # Since July 2007 AmigaOS4 officially supports .so libraries.+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    ;;+  m68k)+    library_names_spec='$libname.ixlibrary $libname.a'+    # Create ${libname}_ixlibrary.a entries in /sys/libs.+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'+    ;;+  esac+  ;;++beos*)+  library_names_spec='$libname$shared_ext'+  dynamic_linker="$host_os ld.so"+  shlibpath_var=LIBRARY_PATH+  ;;++bsdi[[45]]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"+  # the default ld.so.conf also contains /usr/contrib/lib and+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow+  # libtool to hard-code these into programs+  ;;++cygwin* | mingw* | windows* | pw32* | cegcc*)+  version_type=windows+  shrext_cmds=.dll+  need_version=no+  need_lib_prefix=no++  case $GCC,$cc_basename in+  yes,*)+    # gcc+    library_names_spec='$libname.dll.a'+    # DLL is installed to $(libdir)/../bin by postinstall_cmds+    # If user builds GCC with multilib enabled,+    # it should just install on $(libdir)+    # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones.+    if test xyes = x"$multilib"; then+      postinstall_cmds='base_file=`basename \$file`~+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+        dldir=$destdir/`dirname \$dlpath`~+        $install_prog $dir/$dlname $destdir/$dlname~+        chmod a+x $destdir/$dlname~+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+          eval '\''$striplib $destdir/$dlname'\'' || exit \$?;+        fi'+    else+      postinstall_cmds='base_file=`basename \$file`~+        dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+        dldir=$destdir/`dirname \$dlpath`~+        test -d \$dldir || mkdir -p \$dldir~+        $install_prog $dir/$dlname \$dldir/$dlname~+        chmod a+x \$dldir/$dlname~+        if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+          eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;+        fi'+    fi+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~+      dlpath=$dir/\$dldll~+       $RM \$dlpath'+    shlibpath_overrides_runpath=yes++    case $host_os in+    cygwin*)+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'+      soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'+m4_if([$1], [],[+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])+      ;;+    mingw* | windows* | cegcc*)+      # MinGW DLLs use traditional 'lib' prefix+      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'+      ;;+    pw32*)+      # pw32 DLLs use 'pw' prefix rather than 'lib'+      library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'+      ;;+    esac+    dynamic_linker='Win32 ld.exe'+    ;;++  *,cl* | *,icl*)+    # Native MSVC or ICC+    libname_spec='$name'+    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'+    library_names_spec='$libname.dll.lib'++    case $build_os in+    mingw* | windows*)+      sys_lib_search_path_spec=+      lt_save_ifs=$IFS+      IFS=';'+      for lt_path in $LIB+      do+        IFS=$lt_save_ifs+        # Let DOS variable expansion print the short 8.3 style file name.+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"+      done+      IFS=$lt_save_ifs+      # Convert to MSYS style.+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`+      ;;+    cygwin*)+      # Convert to unix form, then to dos form, then back to unix form+      # but this time dos style (no spaces!) so that the unix form looks+      # like /cygdrive/c/PROGRA~1:/cygdr...+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`+      ;;+    *)+      sys_lib_search_path_spec=$LIB+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then+        # It is most probably a Windows format PATH.+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`+      else+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`+      fi+      # FIXME: find the short name or the path components, as spaces are+      # common. (e.g. "Program Files" -> "PROGRA~1")+      ;;+    esac++    # DLL is installed to $(libdir)/../bin by postinstall_cmds+    postinstall_cmds='base_file=`basename \$file`~+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~+      dldir=$destdir/`dirname \$dlpath`~+      test -d \$dldir || mkdir -p \$dldir~+      $install_prog $dir/$dlname \$dldir/$dlname'+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~+      dlpath=$dir/\$dldll~+       $RM \$dlpath'+    shlibpath_overrides_runpath=yes+    dynamic_linker='Win32 link.exe'+    ;;++  *)+    # Assume MSVC and ICC wrapper+    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'+    dynamic_linker='Win32 ld.exe'+    ;;+  esac+  # FIXME: first we should search . and the directory the executable is in+  shlibpath_var=PATH+  ;;++darwin* | rhapsody*)+  dynamic_linker="$host_os dyld"+  version_type=darwin+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$major$shared_ext'+  shlibpath_overrides_runpath=yes+  shlibpath_var=DYLD_LIBRARY_PATH+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'+m4_if([$1], [],[+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'+  ;;++dgux*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  ;;++freebsd* | dragonfly* | midnightbsd*)+  # DragonFly does not have aout.  When/if they implement a new+  # versioning mechanism, adjust this.+  if test -x /usr/bin/objformat; then+    objformat=`/usr/bin/objformat`+  else+    case $host_os in+    freebsd[[23]].*) objformat=aout ;;+    *) objformat=elf ;;+    esac+  fi+  version_type=freebsd-$objformat+  case $version_type in+    freebsd-elf*)+      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+      soname_spec='$libname$release$shared_ext$major'+      need_version=no+      need_lib_prefix=no+      ;;+    freebsd-*)+      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+      need_version=yes+      ;;+  esac+  case $host_cpu in+    powerpc64)+      # On FreeBSD bi-arch platforms, a different variable is used for 32-bit+      # binaries.  See <https://man.freebsd.org/cgi/man.cgi?query=ld.so>.+      AC_COMPILE_IFELSE(+        [AC_LANG_SOURCE(+           [[int test_pointer_size[sizeof (void *) - 5];+           ]])],+        [shlibpath_var=LD_LIBRARY_PATH],+        [shlibpath_var=LD_32_LIBRARY_PATH])+      ;;+    *)+      shlibpath_var=LD_LIBRARY_PATH+      ;;+  esac+  case $host_os in+  freebsd2.*)+    shlibpath_overrides_runpath=yes+    ;;+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)+    shlibpath_overrides_runpath=yes+    hardcode_into_libs=yes+    ;;+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)+    shlibpath_overrides_runpath=no+    hardcode_into_libs=yes+    ;;+  *) # from 4.6 on, and DragonFly+    shlibpath_overrides_runpath=yes+    hardcode_into_libs=yes+    ;;+  esac+  ;;++haiku*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  dynamic_linker="$host_os runtime_loader"+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LIBRARY_PATH+  shlibpath_overrides_runpath=no+  sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib'+  sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib'+  hardcode_into_libs=no+  ;;++hpux9* | hpux10* | hpux11*)+  # Give a soname corresponding to the major version so that dld.sl refuses to+  # link against other versions.+  version_type=sunos+  need_lib_prefix=no+  need_version=no+  case $host_cpu in+  ia64*)+    shrext_cmds='.so'+    hardcode_into_libs=yes+    dynamic_linker="$host_os dld.so"+    shlibpath_var=LD_LIBRARY_PATH+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    if test 32 = "$HPUX_IA64_MODE"; then+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"+      sys_lib_dlsearch_path_spec=/usr/lib/hpux32+    else+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"+      sys_lib_dlsearch_path_spec=/usr/lib/hpux64+    fi+    ;;+  hppa*64*)+    shrext_cmds='.sl'+    hardcode_into_libs=yes+    dynamic_linker="$host_os dld.sl"+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+    ;;+  *)+    shrext_cmds='.sl'+    dynamic_linker="$host_os dld.sl"+    shlibpath_var=SHLIB_PATH+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    ;;+  esac+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...+  postinstall_cmds='chmod 555 $lib'+  # or fails outright, so override atomically:+  install_override_mode=555+  ;;++interix[[3-9]]*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++irix5* | irix6* | nonstopux*)+  case $host_os in+    nonstopux*) version_type=nonstopux ;;+    *)+	if test yes = "$lt_cv_prog_gnu_ld"; then+		version_type=linux # correct to gnu/linux during the next big refactor+	else+		version_type=irix+	fi ;;+  esac+  need_lib_prefix=no+  need_version=no+  soname_spec='$libname$release$shared_ext$major'+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'+  case $host_os in+  irix5* | nonstopux*)+    libsuff= shlibsuff=+    ;;+  *)+    case $LD in # libtool.m4 will add one of these switches to LD+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")+      libsuff= shlibsuff= libmagic=32-bit;;+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")+      libsuff=32 shlibsuff=N32 libmagic=N32;;+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")+      libsuff=64 shlibsuff=64 libmagic=64-bit;;+    *) libsuff= shlibsuff= libmagic=never-match;;+    esac+    ;;+  esac+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH+  shlibpath_overrides_runpath=no+  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"+  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"+  hardcode_into_libs=yes+  ;;++# No shared lib support for Linux oldld, aout, or coff.+linux*oldld* | linux*aout* | linux*coff*)+  dynamic_linker=no+  ;;++linux*android*)+  version_type=none # Android doesn't support versioned libraries.+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$shared_ext'+  finish_cmds=+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes++  # This implies no fast_install, which is unacceptable.+  # Some rework will be needed to allow for fast_install+  # before this can be enabled.+  hardcode_into_libs=yes++  dynamic_linker='Android linker'+  # -rpath works at least for libraries that are not overridden by+  # libraries installed in system locations.+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+  ;;++# This must be glibc/ELF.+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no++  # Some binutils ld are patched to set DT_RUNPATH+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],+    [lt_cv_shlibpath_overrides_runpath=no+    save_LDFLAGS=$LDFLAGS+    save_libdir=$libdir+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],+	 [lt_cv_shlibpath_overrides_runpath=yes])])+    LDFLAGS=$save_LDFLAGS+    libdir=$save_libdir+    ])+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath++  # This implies no fast_install, which is unacceptable.+  # Some rework will be needed to allow for fast_install+  # before this can be enabled.+  hardcode_into_libs=yes++  # Add ABI-specific directories to the system library path.+  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"++  # Ideally, we could use ldconfig to report *all* directories which are+  # searched for libraries, however this is still not possible.  Aside from not+  # being certain /sbin/ldconfig is available, command+  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,+  # even though it is searched at run-time.  Try to do the best guess by+  # appending ld.so.conf contents (and includes) to the search path.+  if test -f /etc/ld.so.conf; then+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`+    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"+  fi++  # We used to test for /lib/ld.so.1 and disable shared libraries on+  # powerpc, because MkLinux only supported shared libraries with the+  # GNU dynamic linker.  Since this was broken with cross compilers,+  # most powerpc-linux boxes support dynamic linking these days and+  # people can always --disable-shared, the test was removed, and we+  # assume the GNU/Linux dynamic linker is in use.+  dynamic_linker='GNU/Linux ld.so'+  ;;++netbsdelf*-gnu)+  version_type=linux+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  dynamic_linker='NetBSD ld.elf_so'+  ;;++netbsd*)+  version_type=sunos+  need_lib_prefix=no+  need_version=no+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'+    dynamic_linker='NetBSD (a.out) ld.so'+  else+    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+    soname_spec='$libname$release$shared_ext$major'+    dynamic_linker='NetBSD ld.elf_so'+  fi+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  ;;++*-mlibc)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  dynamic_linker='mlibc ld.so'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++newsos6)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  ;;++*nto* | *qnx*)+  version_type=qnx+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  dynamic_linker='ldqnx.so'+  ;;++openbsd*)+  version_type=sunos+  sys_lib_dlsearch_path_spec=/usr/lib+  need_lib_prefix=no+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+    need_version=no+  else+    need_version=yes+  fi+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  ;;++os2*)+  libname_spec='$name'+  version_type=windows+  shrext_cmds=.dll+  need_version=no+  need_lib_prefix=no+  # OS/2 can only load a DLL with a base name of 8 characters or less.+  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";+    v=$($ECHO $release$versuffix | tr -d .-);+    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);+    $ECHO $n$v`$shared_ext'+  library_names_spec='${libname}_dll.$libext'+  dynamic_linker='OS/2 ld.exe'+  shlibpath_var=BEGINLIBPATH+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+  postinstall_cmds='base_file=`basename \$file`~+    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~+    dldir=$destdir/`dirname \$dlpath`~+    test -d \$dldir || mkdir -p \$dldir~+    $install_prog $dir/$dlname \$dldir/$dlname~+    chmod a+x \$dldir/$dlname~+    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then+      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;+    fi'+  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~+    dlpath=$dir/\$dldll~+    $RM \$dlpath'+  ;;++osf3* | osf4* | osf5*)+  version_type=osf+  need_lib_prefix=no+  need_version=no+  soname_spec='$libname$release$shared_ext$major'+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"+  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec+  ;;++rdos*)+  dynamic_linker=no+  ;;++serenity*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  dynamic_linker='SerenityOS LibELF'+  ;;++solaris*)+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  # ldd complains unless libraries are executable+  postinstall_cmds='chmod +x $lib'+  ;;++sunos4*)+  version_type=sunos+  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  if test yes = "$with_gnu_ld"; then+    need_lib_prefix=no+  fi+  need_version=yes+  ;;++sysv4 | sysv4.3*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  case $host_vendor in+    sni)+      shlibpath_overrides_runpath=no+      need_lib_prefix=no+      runpath_var=LD_RUN_PATH+      ;;+    siemens)+      need_lib_prefix=no+      ;;+    motorola)+      need_lib_prefix=no+      need_version=no+      shlibpath_overrides_runpath=no+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'+      ;;+  esac+  ;;++sysv4*MP*)+  if test -d /usr/nec; then+    version_type=linux # correct to gnu/linux during the next big refactor+    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'+    soname_spec='$libname$shared_ext.$major'+    shlibpath_var=LD_LIBRARY_PATH+  fi+  ;;++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)+  version_type=sco+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=yes+  hardcode_into_libs=yes+  if test yes = "$with_gnu_ld"; then+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'+  else+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'+    case $host_os in+      sco3.2v5*)+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"+	;;+    esac+  fi+  sys_lib_dlsearch_path_spec='/usr/lib'+  ;;++tpf*)+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.+  version_type=linux # correct to gnu/linux during the next big refactor+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  shlibpath_var=LD_LIBRARY_PATH+  shlibpath_overrides_runpath=no+  hardcode_into_libs=yes+  ;;++uts4*)+  version_type=linux # correct to gnu/linux during the next big refactor+  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'+  soname_spec='$libname$release$shared_ext$major'+  shlibpath_var=LD_LIBRARY_PATH+  ;;++emscripten*)+  version_type=none+  need_lib_prefix=no+  need_version=no+  library_names_spec='$libname$release$shared_ext'+  soname_spec='$libname$release$shared_ext'+  finish_cmds=+  dynamic_linker="Emscripten linker"+  _LT_COMPILER_PIC($1)='-fPIC'+  _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib'+  _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym'+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no+  _LT_TAGVAR(no_undefined_flag, $1)=+  ;;++*)+  dynamic_linker=no+  ;;+esac+AC_MSG_RESULT([$dynamic_linker])+test no = "$dynamic_linker" && can_build_shared=no++variables_saved_for_relink="PATH $shlibpath_var $runpath_var"+if test yes = "$GCC"; then+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"+fi++if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then+  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec+fi++if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then+  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec+fi++# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec++# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"++# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH++_LT_DECL([], [variables_saved_for_relink], [1],+    [Variables whose values should be saved in libtool wrapper scripts and+    restored at link time])+_LT_DECL([], [need_lib_prefix], [0],+    [Do we need the "lib" prefix for modules?])+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])+_LT_DECL([], [version_type], [0], [Library versioning type])+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])+_LT_DECL([], [shlibpath_overrides_runpath], [0],+    [Is shlibpath searched before the hard-coded library search path?])+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])+_LT_DECL([], [library_names_spec], [1],+    [[List of archive names.  First name is the real one, the rest are links.+    The last name is the one that the linker finds with -lNAME]])+_LT_DECL([], [soname_spec], [1],+    [[The coded name of the library, if different from the real name]])+_LT_DECL([], [install_override_mode], [1],+    [Permission mode override for installation of shared libraries])+_LT_DECL([], [postinstall_cmds], [2],+    [Command to use after installation of a shared archive])+_LT_DECL([], [postuninstall_cmds], [2],+    [Command to use after uninstallation of a shared archive])+_LT_DECL([], [finish_cmds], [2],+    [Commands used to finish a libtool library installation in a directory])+_LT_DECL([], [finish_eval], [1],+    [[As "finish_cmds", except a single script fragment to be evaled but+    not shown]])+_LT_DECL([], [hardcode_into_libs], [0],+    [Whether we should hardcode library paths into libraries])+_LT_DECL([], [sys_lib_search_path_spec], [2],+    [Compile-time system search path for libraries])+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],+    [Detected run-time system search path for libraries])+_LT_DECL([], [configure_time_lt_sys_library_path], [2],+    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])+])# _LT_SYS_DYNAMIC_LINKER+++# _LT_PATH_TOOL_PREFIX(TOOL)+# --------------------------+# find a file program that can recognize shared library+AC_DEFUN([_LT_PATH_TOOL_PREFIX],+[m4_require([_LT_DECL_EGREP])dnl+AC_MSG_CHECKING([for $1])+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,+[case $MAGIC_CMD in+[[\\/*] |  ?:[\\/]*])+  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.+  ;;+*)+  lt_save_MAGIC_CMD=$MAGIC_CMD+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+dnl $ac_dummy forces splitting on constant user-supplied paths.+dnl POSIX.2 word splitting is done only on the output of word expansions,+dnl not every word.  This closes a longstanding sh security hole.+  ac_dummy="m4_if([$2], , $PATH, [$2])"+  for ac_dir in $ac_dummy; do+    IFS=$lt_save_ifs+    test -z "$ac_dir" && ac_dir=.+    if test -f "$ac_dir/$1"; then+      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"+      if test -n "$file_magic_test_file"; then+	case $deplibs_check_method in+	"file_magic "*)+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`+	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |+	    $EGREP "$file_magic_regex" > /dev/null; then+	    :+	  else+	    cat <<_LT_EOF 1>&2++*** Warning: the command libtool uses to detect shared libraries,+*** $file_magic_cmd, produces output that libtool cannot recognize.+*** The result is that libtool may fail to recognize shared libraries+*** as such.  This will affect the creation of libtool libraries that+*** depend on shared libraries, but programs linked with such libtool+*** libraries will work regardless of this problem.  Nevertheless, you+*** may want to report the problem to your system manager and/or to+*** bug-libtool@gnu.org++_LT_EOF+	  fi ;;+	esac+      fi+      break+    fi+  done+  IFS=$lt_save_ifs+  MAGIC_CMD=$lt_save_MAGIC_CMD+  ;;+esac])+MAGIC_CMD=$lt_cv_path_MAGIC_CMD+if test -n "$MAGIC_CMD"; then+  AC_MSG_RESULT($MAGIC_CMD)+else+  AC_MSG_RESULT(no)+fi+_LT_DECL([], [MAGIC_CMD], [0],+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl+])# _LT_PATH_TOOL_PREFIX++# Old name:+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])+++# _LT_PATH_MAGIC+# --------------+# find a file program that can recognize a shared library+m4_defun([_LT_PATH_MAGIC],+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)+if test -z "$lt_cv_path_MAGIC_CMD"; then+  if test -n "$ac_tool_prefix"; then+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)+  else+    MAGIC_CMD=:+  fi+fi+])# _LT_PATH_MAGIC+++# LT_PATH_LD+# ----------+# find the pathname to the GNU or non-GNU linker+AC_DEFUN([LT_PATH_LD],+[AC_REQUIRE([AC_PROG_CC])dnl+AC_REQUIRE([AC_CANONICAL_HOST])dnl+AC_REQUIRE([AC_CANONICAL_BUILD])dnl+m4_require([_LT_DECL_SED])dnl+m4_require([_LT_DECL_EGREP])dnl+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl++AC_ARG_WITH([gnu-ld],+    [AS_HELP_STRING([--with-gnu-ld],+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],+    [test no = "$withval" || with_gnu_ld=yes],+    [with_gnu_ld=no])dnl++ac_prog=ld+if test yes = "$GCC"; then+  # Check if gcc -print-prog-name=ld gives a path.+  AC_MSG_CHECKING([for ld used by $CC])+  case $host in+  *-*-mingw* | *-*-windows*)+    # gcc leaves a trailing carriage return, which upsets mingw+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;+  *)+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;+  esac+  case $ac_prog in+    # Accept absolute paths.+    [[\\/]]* | ?:[[\\/]]*)+      re_direlt='/[[^/]][[^/]]*/\.\./'+      # Canonicalize the pathname of ld+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`+      done+      test -z "$LD" && LD=$ac_prog+      ;;+  "")+    # If it fails, then pretend we aren't using GCC.+    ac_prog=ld+    ;;+  *)+    # If it is relative, then search for the first ld in PATH.+    with_gnu_ld=unknown+    ;;+  esac+elif test yes = "$with_gnu_ld"; then+  AC_MSG_CHECKING([for GNU ld])+else+  AC_MSG_CHECKING([for non-GNU ld])+fi+AC_CACHE_VAL(lt_cv_path_LD,+[if test -z "$LD"; then+  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+  for ac_dir in $PATH; do+    IFS=$lt_save_ifs+    test -z "$ac_dir" && ac_dir=.+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then+      lt_cv_path_LD=$ac_dir/$ac_prog+      # Check to see if the program is GNU ld.  I'd rather use --version,+      # but apparently some variants of GNU ld only accept -v.+      # Break only if it was the GNU/non-GNU ld that we prefer.+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in+      *GNU* | *'with BFD'*)+	test no != "$with_gnu_ld" && break+	;;+      *)+	test yes != "$with_gnu_ld" && break+	;;+      esac+    fi+  done+  IFS=$lt_save_ifs+else+  lt_cv_path_LD=$LD # Let the user override the test with a path.+fi])+LD=$lt_cv_path_LD+if test -n "$LD"; then+  AC_MSG_RESULT($LD)+else+  AC_MSG_RESULT(no)+fi+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])+_LT_PATH_LD_GNU+AC_SUBST([LD])++_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])+])# LT_PATH_LD++# Old names:+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AM_PROG_LD], [])+dnl AC_DEFUN([AC_PROG_LD], [])+++# _LT_PATH_LD_GNU+#- --------------+m4_defun([_LT_PATH_LD_GNU],+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,+[# I'd rather use --version here, but apparently some GNU lds only accept -v.+case `$LD -v 2>&1 </dev/null` in+*GNU* | *'with BFD'*)+  lt_cv_prog_gnu_ld=yes+  ;;+*)+  lt_cv_prog_gnu_ld=no+  ;;+esac])+with_gnu_ld=$lt_cv_prog_gnu_ld+])# _LT_PATH_LD_GNU+++# _LT_CMD_RELOAD+# --------------+# find reload flag for linker+#   -- PORTME Some linkers may need a different reload flag.+m4_defun([_LT_CMD_RELOAD],+[AC_CACHE_CHECK([for $LD option to reload object files],+  lt_cv_ld_reload_flag,+  [lt_cv_ld_reload_flag='-r'])+reload_flag=$lt_cv_ld_reload_flag+case $reload_flag in+"" | " "*) ;;+*) reload_flag=" $reload_flag" ;;+esac+reload_cmds='$LD$reload_flag -o $output$reload_objs'+case $host_os in+  cygwin* | mingw* | windows* | pw32* | cegcc*)+    if test yes != "$GCC"; then+      reload_cmds=false+    fi+    ;;+  darwin*)+    if test yes = "$GCC"; then+      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'+    else+      reload_cmds='$LD$reload_flag -o $output$reload_objs'+    fi+    ;;+esac+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl+_LT_TAGDECL([], [reload_cmds], [2])dnl+])# _LT_CMD_RELOAD+++# _LT_PATH_DD+# -----------+# find a working dd+m4_defun([_LT_PATH_DD],+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],+[printf 0123456789abcdef0123456789abcdef >conftest.i+cat conftest.i conftest.i >conftest2.i+: ${lt_DD:=$DD}+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then+  cmp -s conftest.i conftest.out \+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:+fi])+rm -f conftest.i conftest2.i conftest.out])+])# _LT_PATH_DD+++# _LT_CMD_TRUNCATE+# ----------------+# find command to truncate a binary pipe+m4_defun([_LT_CMD_TRUNCATE],+[m4_require([_LT_PATH_DD])+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],+[printf 0123456789abcdef0123456789abcdef >conftest.i+cat conftest.i conftest.i >conftest2.i+lt_cv_truncate_bin=+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then+  cmp -s conftest.i conftest.out \+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"+fi+rm -f conftest.i conftest2.i conftest.out+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],+  [Command to truncate a binary pipe])+])# _LT_CMD_TRUNCATE+++# _LT_CHECK_MAGIC_METHOD+# ----------------------+# how to check for library dependencies+#  -- PORTME fill in with the dynamic library characteristics+m4_defun([_LT_CHECK_MAGIC_METHOD],+[m4_require([_LT_DECL_EGREP])+m4_require([_LT_DECL_OBJDUMP])+AC_CACHE_CHECK([how to recognize dependent libraries],+lt_cv_deplibs_check_method,+[lt_cv_file_magic_cmd='$MAGIC_CMD'+lt_cv_file_magic_test_file=+lt_cv_deplibs_check_method='unknown'+# Need to set the preceding variable on all platforms that support+# interlibrary dependencies.+# 'none' -- dependencies not supported.+# 'unknown' -- same as none, but documents that we really don't know.+# 'pass_all' -- all dependencies passed with no checks.+# 'file_magic [[regex]]' -- check by looking for files in library path+# that responds to the $file_magic_cmd with a given extended regex.+# If you have 'file' or equivalent on your system and you're not sure+# whether 'pass_all' will *always* work, you probably want this one.++case $host_os in+aix[[4-9]]*)+  lt_cv_deplibs_check_method=pass_all+  ;;++beos*)+  lt_cv_deplibs_check_method=pass_all+  ;;++bsdi[[45]]*)+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'+  lt_cv_file_magic_cmd='$FILECMD -L'+  lt_cv_file_magic_test_file=/shlib/libc.so+  ;;++cygwin*)+  # func_win32_libid is a shell function defined in ltmain.sh+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'+  lt_cv_file_magic_cmd='func_win32_libid'+  ;;++mingw* | windows* | pw32*)+  # Base MSYS/MinGW do not provide the 'file' command needed by+  # func_win32_libid shell function, so use a weaker test based on 'objdump',+  # unless we find 'file', for example because we are cross-compiling.+  if ( file / ) >/dev/null 2>&1; then+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'+    lt_cv_file_magic_cmd='func_win32_libid'+  else+    # Keep this pattern in sync with the one in func_win32_libid.+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)'+    lt_cv_file_magic_cmd='$OBJDUMP -f'+  fi+  ;;++cegcc*)+  # use the weaker test based on 'objdump'. See mingw*.+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'+  lt_cv_file_magic_cmd='$OBJDUMP -f'+  ;;++darwin* | rhapsody*)+  lt_cv_deplibs_check_method=pass_all+  ;;++freebsd* | dragonfly* | midnightbsd*)+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then+    case $host_cpu in+    i*86 )+      # Not sure whether the presence of OpenBSD here was a mistake.+      # Let's accept both of them until this is cleared up.+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'+      lt_cv_file_magic_cmd=$FILECMD+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`+      ;;+    esac+  else+    lt_cv_deplibs_check_method=pass_all+  fi+  ;;++haiku*)+  lt_cv_deplibs_check_method=pass_all+  ;;++hpux10.20* | hpux11*)+  lt_cv_file_magic_cmd=$FILECMD+  case $host_cpu in+  ia64*)+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so+    ;;+  hppa*64*)+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl+    ;;+  *)+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'+    lt_cv_file_magic_test_file=/usr/lib/libc.sl+    ;;+  esac+  ;;++interix[[3-9]]*)+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'+  ;;++irix5* | irix6* | nonstopux*)+  case $LD in+  *-32|*"-32 ") libmagic=32-bit;;+  *-n32|*"-n32 ") libmagic=N32;;+  *-64|*"-64 ") libmagic=64-bit;;+  *) libmagic=never-match;;+  esac+  lt_cv_deplibs_check_method=pass_all+  ;;++# This must be glibc/ELF.+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+  lt_cv_deplibs_check_method=pass_all+  ;;++*-mlibc)+  lt_cv_deplibs_check_method=pass_all+  ;;++netbsd* | netbsdelf*-gnu)+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'+  else+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'+  fi+  ;;++newos6*)+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'+  lt_cv_file_magic_cmd=$FILECMD+  lt_cv_file_magic_test_file=/usr/lib/libnls.so+  ;;++*nto* | *qnx*)+  lt_cv_deplibs_check_method=pass_all+  ;;++openbsd*)+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'+  else+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'+  fi+  ;;++osf3* | osf4* | osf5*)+  lt_cv_deplibs_check_method=pass_all+  ;;++rdos*)+  lt_cv_deplibs_check_method=pass_all+  ;;++serenity*)+  lt_cv_deplibs_check_method=pass_all+  ;;++solaris*)+  lt_cv_deplibs_check_method=pass_all+  ;;++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)+  lt_cv_deplibs_check_method=pass_all+  ;;++sysv4 | sysv4.3*)+  case $host_vendor in+  motorola)+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`+    ;;+  ncr)+    lt_cv_deplibs_check_method=pass_all+    ;;+  sequent)+    lt_cv_file_magic_cmd='/bin/file'+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'+    ;;+  sni)+    lt_cv_file_magic_cmd='/bin/file'+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"+    lt_cv_file_magic_test_file=/lib/libc.so+    ;;+  siemens)+    lt_cv_deplibs_check_method=pass_all+    ;;+  pc)+    lt_cv_deplibs_check_method=pass_all+    ;;+  esac+  ;;++tpf*)+  lt_cv_deplibs_check_method=pass_all+  ;;+os2*)+  lt_cv_deplibs_check_method=pass_all+  ;;+esac+])++file_magic_glob=+want_nocaseglob=no+if test "$build" = "$host"; then+  case $host_os in+  mingw* | windows* | pw32*)+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then+      want_nocaseglob=yes+    else+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`+    fi+    ;;+  esac+fi++file_magic_cmd=$lt_cv_file_magic_cmd+deplibs_check_method=$lt_cv_deplibs_check_method+test -z "$deplibs_check_method" && deplibs_check_method=unknown++_LT_DECL([], [deplibs_check_method], [1],+    [Method to check whether dependent libraries are shared objects])+_LT_DECL([], [file_magic_cmd], [1],+    [Command to use when deplibs_check_method = "file_magic"])+_LT_DECL([], [file_magic_glob], [1],+    [How to find potential files when deplibs_check_method = "file_magic"])+_LT_DECL([], [want_nocaseglob], [1],+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])+])# _LT_CHECK_MAGIC_METHOD+++# LT_PATH_NM+# ----------+# find the pathname to a BSD- or MS-compatible name lister+AC_DEFUN([LT_PATH_NM],+[AC_REQUIRE([AC_PROG_CC])dnl+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,+[if test -n "$NM"; then+  # Let the user override the test.+  lt_cv_path_NM=$NM+else+  lt_nm_to_check=${ac_tool_prefix}nm+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then+    lt_nm_to_check="$lt_nm_to_check nm"+  fi+  for lt_tmp_nm in $lt_nm_to_check; do+    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do+      IFS=$lt_save_ifs+      test -z "$ac_dir" && ac_dir=.+      tmp_nm=$ac_dir/$lt_tmp_nm+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then+	# Check to see if the nm accepts a BSD-compat flag.+	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:+	#   nm: unknown option "B" ignored+	# Tru64's nm complains that /dev/null is an invalid object file+	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty+	case $build_os in+	mingw* | windows*) lt_bad_file=conftest.nm/nofile ;;+	*) lt_bad_file=/dev/null ;;+	esac+	case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in+	*$lt_bad_file* | *'Invalid file or object type'*)+	  lt_cv_path_NM="$tmp_nm -B"+	  break 2+	  ;;+	*)+	  case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in+	  */dev/null*)+	    lt_cv_path_NM="$tmp_nm -p"+	    break 2+	    ;;+	  *)+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but+	    continue # so that we can try to find one that supports BSD flags+	    ;;+	  esac+	  ;;+	esac+      fi+    done+    IFS=$lt_save_ifs+  done+  : ${lt_cv_path_NM=no}+fi])+if test no != "$lt_cv_path_NM"; then+  NM=$lt_cv_path_NM+else+  # Didn't find any BSD compatible name lister, look for dumpbin.+  if test -n "$DUMPBIN"; then :+    # Let the user override the test.+  else+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)+    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in+    *COFF*)+      DUMPBIN="$DUMPBIN -symbols -headers"+      ;;+    *)+      DUMPBIN=:+      ;;+    esac+  fi+  AC_SUBST([DUMPBIN])+  if test : != "$DUMPBIN"; then+    NM=$DUMPBIN+  fi+fi+test -z "$NM" && NM=nm+AC_SUBST([NM])+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl++AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],+  [lt_cv_nm_interface="BSD nm"+  echo "int some_variable = 0;" > conftest.$ac_ext+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)+  (eval "$ac_compile" 2>conftest.err)+  cat conftest.err >&AS_MESSAGE_LOG_FD+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)+  cat conftest.err >&AS_MESSAGE_LOG_FD+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)+  cat conftest.out >&AS_MESSAGE_LOG_FD+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then+    lt_cv_nm_interface="MS dumpbin"+  fi+  rm -f conftest*])+])# LT_PATH_NM++# Old names:+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AM_PROG_NM], [])+dnl AC_DEFUN([AC_PROG_NM], [])++# _LT_CHECK_SHAREDLIB_FROM_LINKLIB+# --------------------------------+# how to determine the name of the shared library+# associated with a specific link library.+#  -- PORTME fill in with the dynamic library characteristics+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],+[m4_require([_LT_DECL_EGREP])+m4_require([_LT_DECL_OBJDUMP])+m4_require([_LT_DECL_DLLTOOL])+AC_CACHE_CHECK([how to associate runtime and link libraries],+lt_cv_sharedlib_from_linklib_cmd,+[lt_cv_sharedlib_from_linklib_cmd='unknown'++case $host_os in+cygwin* | mingw* | windows* | pw32* | cegcc*)+  # two different shell functions defined in ltmain.sh;+  # decide which one to use based on capabilities of $DLLTOOL+  case `$DLLTOOL --help 2>&1` in+  *--identify-strict*)+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib+    ;;+  *)+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback+    ;;+  esac+  ;;+*)+  # fallback: assume linklib IS sharedlib+  lt_cv_sharedlib_from_linklib_cmd=$ECHO+  ;;+esac+])+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO++_LT_DECL([], [sharedlib_from_linklib_cmd], [1],+    [Command to associate shared and link libraries])+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB+++# _LT_PATH_MANIFEST_TOOL+# ----------------------+# locate the manifest tool+m4_defun([_LT_PATH_MANIFEST_TOOL],+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_manifest_tool],+  [lt_cv_path_manifest_tool=no+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out+  cat conftest.err >&AS_MESSAGE_LOG_FD+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then+    lt_cv_path_manifest_tool=yes+  fi+  rm -f conftest*])+if test yes != "$lt_cv_path_manifest_tool"; then+  MANIFEST_TOOL=:+fi+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl+])# _LT_PATH_MANIFEST_TOOL+++# _LT_DLL_DEF_P([FILE])+# ---------------------+# True iff FILE is a Windows DLL '.def' file.+# Keep in sync with func_dll_def_p in the libtool script+AC_DEFUN([_LT_DLL_DEF_P],+[dnl+  test DEF = "`$SED -n dnl+    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace+    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments+    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl+    -e q dnl                          Only consider the first "real" line+    $1`" dnl+])# _LT_DLL_DEF_P+++# LT_LIB_M+# --------+# check for math library+AC_DEFUN([LT_LIB_M],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+LIBM=+case $host in+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*)+  # These system don't have libm, or don't need it+  ;;+*-ncr-sysv4.3*)+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")+  ;;+*)+  AC_CHECK_LIB(m, cos, LIBM=-lm)+  ;;+esac+AC_SUBST([LIBM])+])# LT_LIB_M++# Old name:+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_CHECK_LIBM], [])+++# _LT_COMPILER_NO_RTTI([TAGNAME])+# -------------------------------+m4_defun([_LT_COMPILER_NO_RTTI],+[m4_require([_LT_TAG_COMPILER])dnl++_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=++if test yes = "$GCC"; then+  case $cc_basename in+  nvcc*)+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;+  *)+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;+  esac++  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],+    lt_cv_prog_compiler_rtti_exceptions,+    [-fno-rtti -fno-exceptions], [],+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])+fi+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],+	[Compiler flag to turn off builtin functions])+])# _LT_COMPILER_NO_RTTI+++# _LT_CMD_GLOBAL_SYMBOLS+# ----------------------+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+AC_REQUIRE([AC_PROG_CC])dnl+AC_REQUIRE([AC_PROG_AWK])dnl+AC_REQUIRE([LT_PATH_NM])dnl+AC_REQUIRE([LT_PATH_LD])dnl+m4_require([_LT_DECL_SED])dnl+m4_require([_LT_DECL_EGREP])dnl+m4_require([_LT_TAG_COMPILER])dnl++# Check for command to grab the raw symbol name followed by C symbol from nm.+AC_MSG_CHECKING([command to parse $NM output from $compiler object])+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],+[+# These are sane defaults that work on at least a few old systems.+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]++# Character class describing NM global symbol codes.+symcode='[[BCDEGRST]]'++# Regexp to match symbols that can be accessed directly from C.+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'++# Define system-specific variables.+case $host_os in+aix*)+  symcode='[[BCDT]]'+  ;;+cygwin* | mingw* | windows* | pw32* | cegcc*)+  symcode='[[ABCDGISTW]]'+  ;;+hpux*)+  if test ia64 = "$host_cpu"; then+    symcode='[[ABCDEGRST]]'+  fi+  ;;+irix* | nonstopux*)+  symcode='[[BCDEGRST]]'+  ;;+osf*)+  symcode='[[BCDEGQRST]]'+  ;;+solaris*)+  symcode='[[BCDRT]]'+  ;;+sco3.2v5*)+  symcode='[[DT]]'+  ;;+sysv4.2uw2*)+  symcode='[[DT]]'+  ;;+sysv5* | sco5v6* | unixware* | OpenUNIX*)+  symcode='[[ABDT]]'+  ;;+sysv4)+  symcode='[[DFNSTU]]'+  ;;+esac++# If we're using GNU nm, then use its standard symbol codes.+case `$NM -V 2>&1` in+*GNU* | *'with BFD'*)+  symcode='[[ABCDGIRSTW]]' ;;+esac++if test "$lt_cv_nm_interface" = "MS dumpbin"; then+  # Gets list of data symbols to import.+  lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'"+  # Adjust the below global symbol transforms to fixup imported variables.+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"+  lt_c_name_lib_hook="\+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"+else+  # Disable hooks by default.+  lt_cv_sys_global_symbol_to_import=+  lt_cdecl_hook=+  lt_c_name_hook=+  lt_c_name_lib_hook=+fi++# Transform an extracted symbol line into a proper C declaration.+# Some systems (esp. on ia64) link data and code symbols differently,+# so use this general approach.+lt_cv_sys_global_symbol_to_cdecl="$SED -n"\+$lt_cdecl_hook\+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"++# Transform an extracted symbol line into symbol name and symbol address+lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\+$lt_c_name_hook\+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"++# Transform an extracted symbol line into symbol name with lib prefix and+# symbol address.+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\+$lt_c_name_lib_hook\+" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\+" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\+" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"++# Handle CRLF in mingw tool chain+opt_cr=+case $build_os in+mingw* | windows*)+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp+  ;;+esac++# Try without a prefix underscore, then with it.+for ac_symprfx in "" "_"; do++  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.+  symxfrm="\\1 $ac_symprfx\\2 \\2"++  # Write the raw and C identifiers.+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then+    # Fake it for dumpbin and say T for any non-static function,+    # D for any global variable and I for any imported variable.+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,+    # which start with @ or ?.+    lt_cv_sys_global_symbol_pipe="$AWK ['"\+"     {last_section=section; section=\$ 3};"\+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\+"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\+"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\+"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\+"     \$ 0!~/External *\|/{next};"\+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\+"     {if(hide[section]) next};"\+"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\+"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\+"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\+"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\+"     ' prfx=^$ac_symprfx]"+  else+    lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"+  fi+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'"++  # Check to see that the pipe works correctly.+  pipe_works=no++  rm -f conftest*+  cat > conftest.$ac_ext <<_LT_EOF+#ifdef __cplusplus+extern "C" {+#endif+char nm_test_var;+void nm_test_func(void);+void nm_test_func(void){}+#ifdef __cplusplus+}+#endif+int main(void){nm_test_var='a';nm_test_func();return(0);}+_LT_EOF++  if AC_TRY_EVAL(ac_compile); then+    # Now try to grab the symbols.+    nlist=conftest.nm+    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD+    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then+      # Try sorting and uniquifying the output.+      if sort "$nlist" | uniq > "$nlist"T; then+	mv -f "$nlist"T "$nlist"+      else+	rm -f "$nlist"T+      fi++      # Make sure that we snagged all the symbols we need.+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then+	  cat <<_LT_EOF > conftest.$ac_ext+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE+/* DATA imports from DLLs on WIN32 can't be const, because runtime+   relocations are performed -- see ld's documentation on pseudo-relocs.  */+# define LT@&t@_DLSYM_CONST+#elif defined __osf__+/* This system does not cope well with relocations in const data.  */+# define LT@&t@_DLSYM_CONST+#else+# define LT@&t@_DLSYM_CONST const+#endif++#ifdef __cplusplus+extern "C" {+#endif++_LT_EOF+	  # Now generate the symbol file.+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'++	  cat <<_LT_EOF >> conftest.$ac_ext++/* The mapping between symbol names and symbols.  */+LT@&t@_DLSYM_CONST struct {+  const char *name;+  void       *address;+}+lt__PROGRAM__LTX_preloaded_symbols[[]] =+{+  { "@PROGRAM@", (void *) 0 },+_LT_EOF+	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext+	  cat <<\_LT_EOF >> conftest.$ac_ext+  {0, (void *) 0}+};++/* This works around a problem in FreeBSD linker */+#ifdef FREEBSD_WORKAROUND+static const void *lt_preloaded_setup() {+  return lt__PROGRAM__LTX_preloaded_symbols;+}+#endif++#ifdef __cplusplus+}+#endif+_LT_EOF+	  # Now try linking the two files.+	  mv conftest.$ac_objext conftstm.$ac_objext+	  lt_globsym_save_LIBS=$LIBS+	  lt_globsym_save_CFLAGS=$CFLAGS+	  LIBS=conftstm.$ac_objext+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"+	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then+	    pipe_works=yes+	  fi+	  LIBS=$lt_globsym_save_LIBS+	  CFLAGS=$lt_globsym_save_CFLAGS+	else+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD+	fi+      else+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD+      fi+    else+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD+    fi+  else+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD+    cat conftest.$ac_ext >&5+  fi+  rm -rf conftest* conftst*++  # Do not use the global_symbol_pipe unless it works.+  if test yes = "$pipe_works"; then+    break+  else+    lt_cv_sys_global_symbol_pipe=+  fi+done+])+if test -z "$lt_cv_sys_global_symbol_pipe"; then+  lt_cv_sys_global_symbol_to_cdecl=+fi+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then+  AC_MSG_RESULT(failed)+else+  AC_MSG_RESULT(ok)+fi++# Response file support.+if test "$lt_cv_nm_interface" = "MS dumpbin"; then+  nm_file_list_spec='@'+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then+  nm_file_list_spec='@'+fi++_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],+    [Take the output of nm and produce a listing of raw symbols and C names])+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],+    [Transform the output of nm in a proper C declaration])+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],+    [Transform the output of nm into a list of symbols to manually relocate])+_LT_DECL([global_symbol_to_c_name_address],+    [lt_cv_sys_global_symbol_to_c_name_address], [1],+    [Transform the output of nm in a C name address pair])+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],+    [Transform the output of nm in a C name address pair when lib prefix is needed])+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],+    [The name lister interface])+_LT_DECL([], [nm_file_list_spec], [1],+    [Specify filename containing input files for $NM])+]) # _LT_CMD_GLOBAL_SYMBOLS+++# _LT_COMPILER_PIC([TAGNAME])+# ---------------------------+m4_defun([_LT_COMPILER_PIC],+[m4_require([_LT_TAG_COMPILER])dnl+_LT_TAGVAR(lt_prog_compiler_wl, $1)=+_LT_TAGVAR(lt_prog_compiler_pic, $1)=+_LT_TAGVAR(lt_prog_compiler_static, $1)=++m4_if([$1], [CXX], [+  # C++ specific cases for pic, static, wl, etc.+  if test yes = "$GXX"; then+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'++    case $host_os in+    aix*)+      # All AIX code is PIC.+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      fi+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+        ;;+      m68k)+            # FIXME: we need at least 68020 code to build shared libraries, but+            # adding the '-m68020' flag to GCC prevents building anything better,+            # like '-m68040'.+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'+        ;;+      esac+      ;;++    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)+      # PIC is the default for these OSes.+      ;;+    mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      # Although the cygwin gcc ignores -fPIC, still need this for old-style+      # (--disable-auto-import) libraries+      m4_if([$1], [GCJ], [],+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])+      case $host_os in+      os2*)+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'+	;;+      esac+      ;;+    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'+      ;;+    *djgpp*)+      # DJGPP does not support shared libraries at all+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=+      ;;+    haiku*)+      # PIC is the default for Haiku.+      # The "-static" flag exists, but is broken.+      _LT_TAGVAR(lt_prog_compiler_static, $1)=+      ;;+    interix[[3-9]]*)+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.+      # Instead, we relocate shared libraries at runtime.+      ;;+    sysv4*MP*)+      if test -d /usr/nec; then+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic+      fi+      ;;+    hpux*)+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag+      # sets the default TLS model and affects inlining.+      case $host_cpu in+      hppa*64*)+	;;+      *)+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	;;+      esac+      ;;+    *qnx* | *nto*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'+      ;;+    *)+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+      ;;+    esac+  else+    case $host_os in+      aix[[4-9]]*)+	# All AIX code is PIC.+	if test ia64 = "$host_cpu"; then+	  # AIX 5 now supports IA64 processor+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	else+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'+	fi+	;;+      chorus*)+	case $cc_basename in+	cxch68*)+	  # Green Hills C++ Compiler+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"+	  ;;+	esac+	;;+      mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)+	# This hack is so that the source file can tell whether it is being+	# built for inclusion in a dll (and should export symbols for example).+	m4_if([$1], [GCJ], [],+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])+	;;+      dgux*)+	case $cc_basename in+	  ec++*)+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	    ;;+	  ghcx*)+	    # Green Hills C++ Compiler+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'+	    ;;+	  *)+	    ;;+	esac+	;;+      freebsd* | dragonfly* | midnightbsd*)+	# FreeBSD uses GNU C+++	;;+      hpux9* | hpux10* | hpux11*)+	case $cc_basename in+	  CC*)+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'+	    if test ia64 != "$host_cpu"; then+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'+	    fi+	    ;;+	  aCC*)+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'+	    case $host_cpu in+	    hppa*64*|ia64*)+	      # +Z the default+	      ;;+	    *)+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'+	      ;;+	    esac+	    ;;+	  *)+	    ;;+	esac+	;;+      interix*)+	# This is c89, which is MS Visual C++ (no shared libs)+	# Anyone wants to do a port?+	;;+      irix5* | irix6* | nonstopux*)+	case $cc_basename in+	  CC*)+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+	    # CC pic flag -KPIC is the default.+	    ;;+	  *)+	    ;;+	esac+	;;+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+	case $cc_basename in+	  KCC*)+	    # KAI C++ Compiler+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	    ;;+	  ecpc* )+	    # old Intel C++ for x86_64, which still supported -KPIC.+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+	    ;;+	  icpc* )+	    # Intel C++, used to be incompatible with GCC.+	    # ICC 10 doesn't accept -KPIC any more.+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+	    ;;+	  pgCC* | pgcpp*)+	    # Portland Group C++ compiler+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	    ;;+	  cxx*)+	    # Compaq C+++	    # Make sure the PIC flag is empty.  It appears that all Alpha+	    # Linux and Compaq Tru64 Unix objects are PIC.+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+	    ;;+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)+	    # IBM XL 8.0, 9.0 on PPC and BlueGene+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'+	    ;;+	  *)+	    case `$CC -V 2>&1 | $SED 5q` in+	    *Sun\ C*)+	      # Sun C++ 5.9+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '+	      ;;+	    esac+	    ;;+	esac+	;;+      lynxos*)+	;;+      m88k*)+	;;+      mvs*)+	case $cc_basename in+	  cxx*)+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'+	    ;;+	  *)+	    ;;+	esac+	;;+      netbsd* | netbsdelf*-gnu)+	;;+      *-mlibc)+	;;+      *qnx* | *nto*)+        # QNX uses GNU C++, but need to define -shared option too, otherwise+        # it will coredump.+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'+        ;;+      osf3* | osf4* | osf5*)+	case $cc_basename in+	  KCC*)+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'+	    ;;+	  RCC*)+	    # Rational C++ 2.4.1+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'+	    ;;+	  cxx*)+	    # Digital/Compaq C+++	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    # Make sure the PIC flag is empty.  It appears that all Alpha+	    # Linux and Compaq Tru64 Unix objects are PIC.+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+	    ;;+	  *)+	    ;;+	esac+	;;+      psos*)+	;;+      serenity*)+        ;;+      solaris*)+	case $cc_basename in+	  CC* | sunCC*)+	    # Sun C++ 4.2, 5.x and Centerline C+++	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '+	    ;;+	  gcx*)+	    # Green Hills C++ Compiler+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'+	    ;;+	  *)+	    ;;+	esac+	;;+      sunos4*)+	case $cc_basename in+	  CC*)+	    # Sun C++ 4.x+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	    ;;+	  lcc*)+	    # Lucid+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'+	    ;;+	  *)+	    ;;+	esac+	;;+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)+	case $cc_basename in+	  CC*)+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	    ;;+	esac+	;;+      tandem*)+	case $cc_basename in+	  NCC*)+	    # NonStop-UX NCC 3.20+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	    ;;+	  *)+	    ;;+	esac+	;;+      vxworks*)+	;;+      *)+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no+	;;+    esac+  fi+],+[+  if test yes = "$GCC"; then+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'++    case $host_os in+      aix*)+      # All AIX code is PIC.+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      fi+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+        ;;+      m68k)+            # FIXME: we need at least 68020 code to build shared libraries, but+            # adding the '-m68020' flag to GCC prevents building anything better,+            # like '-m68040'.+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'+        ;;+      esac+      ;;++    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)+      # PIC is the default for these OSes.+      ;;++    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      # Although the cygwin gcc ignores -fPIC, still need this for old-style+      # (--disable-auto-import) libraries+      m4_if([$1], [GCJ], [],+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])+      case $host_os in+      os2*)+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'+	;;+      esac+      ;;++    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'+      ;;++    haiku*)+      # PIC is the default for Haiku.+      # The "-static" flag exists, but is broken.+      _LT_TAGVAR(lt_prog_compiler_static, $1)=+      ;;++    hpux*)+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag+      # sets the default TLS model and affects inlining.+      case $host_cpu in+      hppa*64*)+	# +Z the default+	;;+      *)+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	;;+      esac+      ;;++    interix[[3-9]]*)+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.+      # Instead, we relocate shared libraries at runtime.+      ;;++    msdosdjgpp*)+      # Just because we use GCC doesn't mean we suddenly get shared libraries+      # on systems that don't support them.+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no+      enable_shared=no+      ;;++    *nto* | *qnx*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic+      fi+      ;;++    *)+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+      ;;+    esac++    case $cc_basename in+    nvcc*) # Cuda Compiler Driver 2.2+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"+      fi+      ;;+    esac+  else+    # PORTME Check for flag to pass linker flags through the system compiler.+    case $host_os in+    aix*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      if test ia64 = "$host_cpu"; then+	# AIX 5 now supports IA64 processor+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      else+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'+      fi+      ;;++    darwin* | rhapsody*)+      # PIC is the default on this platform+      # Common symbols not allowed in MH_DYLIB files+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'+      case $cc_basename in+      nagfor*)+        # NAG Fortran compiler+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+        ;;+      esac+      ;;++    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)+      # This hack is so that the source file can tell whether it is being+      # built for inclusion in a dll (and should export symbols for example).+      m4_if([$1], [GCJ], [],+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])+      case $host_os in+      os2*)+	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'+	;;+      esac+      ;;++    hpux9* | hpux10* | hpux11*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but+      # not for PA HP-UX.+      case $host_cpu in+      hppa*64*|ia64*)+	# +Z the default+	;;+      *)+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'+	;;+      esac+      # Is there a better lt_prog_compiler_static that works with the bundled CC?+      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'+      ;;++    irix5* | irix6* | nonstopux*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      # PIC (with -KPIC) is the default.+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+      ;;++    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+      case $cc_basename in+      # old Intel for x86_64, which still supported -KPIC.+      ecc*)+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+        ;;+      *flang* | ftn | f18* | f95*)+        # Flang compiler.+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+        ;;+      # icc used to be incompatible with GCC.+      # ICC 10 doesn't accept -KPIC any more.+      icc* | ifort*)+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+        ;;+      # Lahey Fortran 8.1.+      lf95*)+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'+	;;+      nagfor*)+	# NAG Fortran compiler+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	;;+      tcc*)+	# Fabrice Bellard et al's Tiny C Compiler+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+	;;+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)+        # Portland Group compilers (*not* the Pentium gcc compiler,+	# which looks to be a dead project)+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+        ;;+      ccc*)+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+        # All Alpha code is PIC.+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+        ;;+      xl* | bgxl* | bgf* | mpixl*)+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'+	;;+      *)+	case `$CC -V 2>&1 | $SED 5q` in+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''+	  ;;+	*Sun\ F* | *Sun*Fortran*)+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '+	  ;;+	*Sun\ C*)+	  # Sun C 5.9+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	  ;;+        *Intel*\ [[CF]]*Compiler*)+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+	  ;;+	*Portland\ Group*)+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+	  ;;+	esac+	;;+      esac+      ;;++    newsos6)+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      ;;++    *-mlibc)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'+      ;;++    *nto* | *qnx*)+      # QNX uses GNU C++, but need to define -shared option too, otherwise+      # it will coredump.+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'+      ;;++    osf3* | osf4* | osf5*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      # All OSF/1 code is PIC.+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+      ;;++    rdos*)+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'+      ;;++    serenity*)+      ;;++    solaris*)+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      case $cc_basename in+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;+      *)+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;+      esac+      ;;++    sunos4*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      ;;++    sysv4 | sysv4.2uw2* | sysv4.3*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      fi+      ;;++    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      ;;++    unicos*)+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no+      ;;++    uts4*)+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'+      ;;++    *)+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no+      ;;+    esac+  fi+])+case $host_os in+  # For platforms that do not support PIC, -DPIC is meaningless:+  *djgpp*)+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=+    ;;+  *)+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"+    ;;+esac++AC_CACHE_CHECK([for $compiler option to produce PIC],+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)++#+# Check to make sure the PIC flag actually works.+#+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in+     "" | " "*) ;;+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;+     esac],+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])+fi+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],+	[Additional compiler flags for building library objects])++_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],+	[How to pass a linker flag through the compiler])+#+# Check to make sure the static flag actually works.+#+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),+  $lt_tmp_static_flag,+  [],+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],+	[Compiler flag to prevent dynamic linking])+])# _LT_COMPILER_PIC+++# _LT_LINKER_SHLIBS([TAGNAME])+# ----------------------------+# See if the linker supports building shared libraries.+m4_defun([_LT_LINKER_SHLIBS],+[AC_REQUIRE([LT_PATH_LD])dnl+AC_REQUIRE([LT_PATH_NM])dnl+m4_require([_LT_PATH_MANIFEST_TOOL])dnl+m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_DECL_EGREP])dnl+m4_require([_LT_DECL_SED])dnl+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl+m4_require([_LT_TAG_COMPILER])dnl+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])+m4_if([$1], [CXX], [+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']+  case $host_os in+  aix[[4-9]]*)+    # If we're using GNU nm, then we don't want the "-C" option.+    # -C means demangle to GNU nm, but means don't demangle to AIX nm.+    # Without the "-l" option, or with the "-B" option, AIX nm treats+    # weak defined symbols like other global defined symbols, whereas+    # GNU nm marks them as "W".+    # While the 'weak' keyword is ignored in the Export File, we need+    # it in the Import File for the 'aix-soname' feature, so we have+    # to replace the "-B" option with "-P" for AIX nm.+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'+    else+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'+    fi+    ;;+  pw32*)+    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds+    ;;+  cygwin* | mingw* | windows* | cegcc*)+    case $cc_basename in+    cl* | icl*)+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'+      ;;+    *)+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']+      ;;+    esac+    ;;+  *)+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'+    ;;+  esac+], [+  runpath_var=+  _LT_TAGVAR(allow_undefined_flag, $1)=+  _LT_TAGVAR(always_export_symbols, $1)=no+  _LT_TAGVAR(archive_cmds, $1)=+  _LT_TAGVAR(archive_expsym_cmds, $1)=+  _LT_TAGVAR(compiler_needs_object, $1)=no+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'+  _LT_TAGVAR(hardcode_automatic, $1)=no+  _LT_TAGVAR(hardcode_direct, $1)=no+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=+  _LT_TAGVAR(hardcode_libdir_separator, $1)=+  _LT_TAGVAR(hardcode_minus_L, $1)=no+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported+  _LT_TAGVAR(inherit_rpath, $1)=no+  _LT_TAGVAR(link_all_deplibs, $1)=unknown+  _LT_TAGVAR(module_cmds, $1)=+  _LT_TAGVAR(module_expsym_cmds, $1)=+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=+  _LT_TAGVAR(thread_safe_flag_spec, $1)=+  _LT_TAGVAR(whole_archive_flag_spec, $1)=+  # include_expsyms should be a list of space-separated symbols to be *always*+  # included in the symbol list+  _LT_TAGVAR(include_expsyms, $1)=+  # exclude_expsyms can be an extended regexp of symbols to exclude+  # it will be wrapped by ' (' and ')$', so one must not match beginning or+  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',+  # as well as any symbol that contains 'd'.+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out+  # platforms (ab)use it in PIC code, but their linkers get confused if+  # the symbol is explicitly referenced.  Since portable code cannot+  # rely on this symbol name, it's probably fine to never include it in+  # preloaded symbol tables.+  # Exclude shared library initialization/finalization symbols.+dnl Note also adjust exclude_expsyms for C++ above.+  extract_expsyms_cmds=++  case $host_os in+  cygwin* | mingw* | windows* | pw32* | cegcc*)+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time+    # When not using gcc, we currently assume that we are using+    # Microsoft Visual C++ or Intel C++ Compiler.+    if test yes != "$GCC"; then+      with_gnu_ld=no+    fi+    ;;+  interix*)+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)+    with_gnu_ld=yes+    ;;+  esac++  _LT_TAGVAR(ld_shlibs, $1)=yes++  # On some targets, GNU ld is compatible enough with the native linker+  # that we're better off using the native interface for both.+  lt_use_gnu_ld_interface=no+  if test yes = "$with_gnu_ld"; then+    case $host_os in+      aix*)+	# The AIX port of GNU ld has always aspired to compatibility+	# with the native linker.  However, as the warning in the GNU ld+	# block says, versions before 2.19.5* couldn't really create working+	# shared libraries, regardless of the interface used.+	case `$LD -v 2>&1` in+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;+	  *)+	    lt_use_gnu_ld_interface=yes+	    ;;+	esac+	;;+      *)+	lt_use_gnu_ld_interface=yes+	;;+    esac+  fi++  if test yes = "$lt_use_gnu_ld_interface"; then+    # If archive_cmds runs LD, not CC, wlarc should be empty+    wlarc='$wl'++    # Set some defaults for GNU ld with shared library support. These+    # are reset later if shared libraries are not supported. Putting them+    # here allows them to be overridden if necessary.+    runpath_var=LD_RUN_PATH+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'+    # ancient GNU ld didn't support --whole-archive et. al.+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then+      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'+    else+      _LT_TAGVAR(whole_archive_flag_spec, $1)=+    fi+    supports_anon_versioning=no+    case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in+      *GNU\ gold*) supports_anon_versioning=yes ;;+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...+      *\ 2.11.*) ;; # other 2.11 versions+      *) supports_anon_versioning=yes ;;+    esac++    # See if GNU ld supports shared libraries.+    case $host_os in+    aix[[3-9]]*)+      # On AIX/PPC, the GNU linker is very broken+      if test ia64 != "$host_cpu"; then+	_LT_TAGVAR(ld_shlibs, $1)=no+	cat <<_LT_EOF 1>&2++*** Warning: the GNU linker, at least up to release 2.19, is reported+*** to be unable to reliably create shared libraries on AIX.+*** Therefore, libtool is disabling shared libraries support.  If you+*** really care for shared libraries, you may want to install binutils+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.+*** You will then need to restart the configuration process.++_LT_EOF+      fi+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+            _LT_TAGVAR(archive_expsym_cmds, $1)=''+        ;;+      m68k)+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+            _LT_TAGVAR(hardcode_minus_L, $1)=yes+        ;;+      esac+      ;;++    beos*)+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc+	# support --undefined.  This deserves some investigation.  FIXME+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+      else+	_LT_TAGVAR(ld_shlibs, $1)=no+      fi+      ;;++    cygwin* | mingw* | windows* | pw32* | cegcc*)+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,+      # as there is no search path for DLLs.+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+      _LT_TAGVAR(always_export_symbols, $1)=no+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']+      _LT_TAGVAR(file_list_spec, $1)='@'++      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+	# If the export-symbols file already is a .def file, use it as+	# is; otherwise, prepend EXPORTS...+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then+          cp $export_symbols $output_objdir/$soname.def;+        else+          echo EXPORTS > $output_objdir/$soname.def;+          cat $export_symbols >> $output_objdir/$soname.def;+        fi~+        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+      else+	_LT_TAGVAR(ld_shlibs, $1)=no+      fi+      ;;++    haiku*)+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+      _LT_TAGVAR(link_all_deplibs, $1)=no+      ;;++    os2*)+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+      _LT_TAGVAR(hardcode_minus_L, $1)=yes+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+      shrext_cmds=.dll+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	prefix_cmds="$SED"~+	if test EXPORTS = "`$SED 1q $export_symbols`"; then+	  prefix_cmds="$prefix_cmds -e 1d";+	fi~+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+      _LT_TAGVAR(file_list_spec, $1)='@'+      ;;++    interix[[3-9]]*)+      _LT_TAGVAR(hardcode_direct, $1)=no+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.+      # Instead, shared libraries are loaded at an image base (0x10000000 by+      # default) and relocated if they conflict, which is a slow very memory+      # consuming and fragmenting process.  To avoid this, we pick a random,+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+      _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+      ;;++    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)+      tmp_diet=no+      if test linux-dietlibc = "$host_os"; then+	case $cc_basename in+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)+	esac+      fi+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \+	 && test no = "$tmp_diet"+      then+	tmp_addflag=' $pic_flag'+	tmp_sharedflag='-shared'+	case $cc_basename,$host_cpu in+        pgcc*)				# Portland Group C compiler+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  tmp_addflag=' $pic_flag'+	  ;;+	pgf77* | pgf90* | pgf95* | pgfortran*)+					# Portland Group f77 and f90 compilers+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  tmp_addflag=' $pic_flag -Mnomain' ;;+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64+	  tmp_addflag=' -i_dynamic' ;;+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64+	  tmp_addflag=' -i_dynamic -nofor_main' ;;+	ifc* | ifort*)			# Intel Fortran compiler+	  tmp_addflag=' -nofor_main' ;;+	lf95*)				# Lahey Fortran 8.1+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=+	  tmp_sharedflag='--shared' ;;+        nagfor*)                        # NAGFOR 5.3+          tmp_sharedflag='-Wl,-shared' ;;+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)+	  tmp_sharedflag='-qmkshrobj'+	  tmp_addflag= ;;+	nvcc*)	# Cuda Compiler Driver 2.2+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  _LT_TAGVAR(compiler_needs_object, $1)=yes+	  ;;+	esac+	case `$CC -V 2>&1 | $SED 5q` in+	*Sun\ C*)			# Sun C 5.9+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	  _LT_TAGVAR(compiler_needs_object, $1)=yes+	  tmp_sharedflag='-G' ;;+	*Sun\ F*)			# Sun Fortran 8.3+	  tmp_sharedflag='-G' ;;+	esac+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'++        if test yes = "$supports_anon_versioning"; then+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~+            cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~+            echo "local: *; };" >> $output_objdir/$libname.ver~+            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'+        fi++	case $cc_basename in+	tcc*)+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'+	  ;;+	xlf* | bgf* | bgxlf* | mpixlf*)+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'+	  if test yes = "$supports_anon_versioning"; then+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~+              cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~+              echo "local: *; };" >> $output_objdir/$libname.ver~+              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'+	  fi+	  ;;+	esac+      else+        _LT_TAGVAR(ld_shlibs, $1)=no+      fi+      ;;++    *-mlibc)+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      ;;++    netbsd* | netbsdelf*-gnu)+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'+	wlarc=+      else+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      fi+      ;;++    solaris*)+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then+	_LT_TAGVAR(ld_shlibs, $1)=no+	cat <<_LT_EOF 1>&2++*** Warning: The releases 2.8.* of the GNU linker cannot reliably+*** create shared libraries on Solaris systems.  Therefore, libtool+*** is disabling shared libraries support.  We urge you to upgrade GNU+*** binutils to release 2.9.1 or newer.  Another option is to modify+*** your PATH or compiler configuration so that the native linker is+*** used, and then restart.++_LT_EOF+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      else+	_LT_TAGVAR(ld_shlibs, $1)=no+      fi+      ;;++    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)+      case `$LD -v 2>&1` in+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)+	_LT_TAGVAR(ld_shlibs, $1)=no+	cat <<_LT_EOF 1>&2++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot+*** reliably create shared libraries on SCO systems.  Therefore, libtool+*** is disabling shared libraries support.  We urge you to upgrade GNU+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify+*** your PATH or compiler configuration so that the native linker is+*** used, and then restart.++_LT_EOF+	;;+	*)+	  # For security reasons, it is highly recommended that you always+	  # use absolute paths for naming shared libraries, and exclude the+	  # DT_RUNPATH tag from executables and libraries.  But doing so+	  # requires that you compile everything twice, which is a pain.+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+	  else+	    _LT_TAGVAR(ld_shlibs, $1)=no+	  fi+	;;+      esac+      ;;++    sunos4*)+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'+      wlarc=+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    *)+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+      else+	_LT_TAGVAR(ld_shlibs, $1)=no+      fi+      ;;+    esac++    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then+      runpath_var=+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=+      _LT_TAGVAR(whole_archive_flag_spec, $1)=+    fi+  else+    # PORTME fill in a description of your system's linker (not GNU ld)+    case $host_os in+    aix3*)+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+      _LT_TAGVAR(always_export_symbols, $1)=yes+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'+      # Note: this linker hardcodes the directories in LIBPATH if there+      # are no directories specified by -L.+      _LT_TAGVAR(hardcode_minus_L, $1)=yes+      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then+	# Neither direct hardcoding nor static linking is supported with a+	# broken collect2.+	_LT_TAGVAR(hardcode_direct, $1)=unsupported+      fi+      ;;++    aix[[4-9]]*)+      if test ia64 = "$host_cpu"; then+	# On IA64, the linker does run time linking by default, so we don't+	# have to do anything special.+	aix_use_runtimelinking=no+	exp_sym_flag='-Bexport'+	no_entry_flag=+      else+	# If we're using GNU nm, then we don't want the "-C" option.+	# -C means demangle to GNU nm, but means don't demangle to AIX nm.+	# Without the "-l" option, or with the "-B" option, AIX nm treats+	# weak defined symbols like other global defined symbols, whereas+	# GNU nm marks them as "W".+	# While the 'weak' keyword is ignored in the Export File, we need+	# it in the Import File for the 'aix-soname' feature, so we have+	# to replace the "-B" option with "-P" for AIX nm.+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'+	else+	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'+	fi+	aix_use_runtimelinking=no++	# Test if we are trying to use run time linking or normal+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we+	# have runtime linking enabled, and use it for executables.+	# For shared libraries, we enable/disable runtime linking+	# depending on the kind of the shared library created -+	# when "with_aix_soname,aix_use_runtimelinking" is:+	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables+	# "aix,yes"  lib.so          shared, rtl:yes, for executables+	#            lib.a           static archive+	# "both,no"  lib.so.V(shr.o) shared, rtl:yes+	#            lib.a(lib.so.V) shared, rtl:no,  for executables+	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables+	#            lib.a(lib.so.V) shared, rtl:no+	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables+	#            lib.a           static archive+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)+	  for ld_flag in $LDFLAGS; do+	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then+	    aix_use_runtimelinking=yes+	    break+	  fi+	  done+	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then+	    # With aix-soname=svr4, we create the lib.so.V shared archives only,+	    # so we don't have lib.a shared libs to link our executables.+	    # We have to force runtime linking in this case.+	    aix_use_runtimelinking=yes+	    LDFLAGS="$LDFLAGS -Wl,-brtl"+	  fi+	  ;;+	esac++	exp_sym_flag='-bexport'+	no_entry_flag='-bnoentry'+      fi++      # When large executables or shared objects are built, AIX ld can+      # have problems creating the table of contents.  If linking a library+      # or program results in "error TOC overflow" add -mminimal-toc to+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.++      _LT_TAGVAR(archive_cmds, $1)=''+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'+      _LT_TAGVAR(link_all_deplibs, $1)=yes+      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'+      case $with_aix_soname,$aix_use_runtimelinking in+      aix,*) ;; # traditional, no import file+      svr4,* | *,yes) # use import file+	# The Import File defines what to hardcode.+	_LT_TAGVAR(hardcode_direct, $1)=no+	_LT_TAGVAR(hardcode_direct_absolute, $1)=no+	;;+      esac++      if test yes = "$GCC"; then+	case $host_os in aix4.[[012]]|aix4.[[012]].*)+	# We only want to do this on AIX 4.2 and lower, the check+	# below for broken collect2 doesn't work under 4.3++	  collect2name=`$CC -print-prog-name=collect2`+	  if test -f "$collect2name" &&+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null+	  then+	  # We have reworked collect2+	  :+	  else+	  # We have old collect2+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported+	  # It fails to find uninstalled libraries when the uninstalled+	  # path is not listed in the libpath.  Setting hardcode_minus_L+	  # to unsupported forces relinking+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=+	  fi+	  ;;+	esac+	shared_flag='-shared'+	if test yes = "$aix_use_runtimelinking"; then+	  shared_flag="$shared_flag "'$wl-G'+	fi+	# Need to ensure runtime linking is disabled for the traditional+	# shared library, or the linker may eventually find shared libraries+	# /with/ Import File - we do not want to mix them.+	shared_flag_aix='-shared'+	shared_flag_svr4='-shared $wl-G'+      else+	# not using gcc+	if test ia64 = "$host_cpu"; then+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release+	# chokes on -Wl,-G. The following line is correct:+	  shared_flag='-G'+	else+	  if test yes = "$aix_use_runtimelinking"; then+	    shared_flag='$wl-G'+	  else+	    shared_flag='$wl-bM:SRE'+	  fi+	  shared_flag_aix='$wl-bM:SRE'+	  shared_flag_svr4='$wl-G'+	fi+      fi++      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'+      # It seems that -bexpall does not export symbols beginning with+      # underscore (_), so it is better to generate a list of symbols to export.+      _LT_TAGVAR(always_export_symbols, $1)=yes+      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then+	# Warning - without using the other runtime loading flags (-brtl),+	# -berok will link without error, but may produce a broken library.+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'+        # Determine the default libpath from the value encoded in an+        # empty executable.+        _LT_SYS_MODULE_PATH_AIX([$1])+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag+      else+	if test ia64 = "$host_cpu"; then+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"+	else+	 # Determine the default libpath from the value encoded in an+	 # empty executable.+	 _LT_SYS_MODULE_PATH_AIX([$1])+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"+	  # Warning - without using the other run time loading flags,+	  # -berok will link without error, but may produce a broken library.+	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'+	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'+	  if test yes = "$with_gnu_ld"; then+	    # We only use this code for GNU lds that support --whole-archive.+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'+	  else+	    # Exported symbols can be pulled into shared objects from archives+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'+	  fi+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'+	  # -brtl affects multiple linker settings, -berok does not and is overridden later+	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'+	  if test svr4 != "$with_aix_soname"; then+	    # This is similar to how AIX traditionally builds its shared libraries.+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'+	  fi+	  if test aix != "$with_aix_soname"; then+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'+	  else+	    # used by -dlpreopen to get the symbols+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'+	  fi+	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'+	fi+      fi+      ;;++    amigaos*)+      case $host_cpu in+      powerpc)+            # see comment about AmigaOS4 .so support+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+            _LT_TAGVAR(archive_expsym_cmds, $1)=''+        ;;+      m68k)+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+            _LT_TAGVAR(hardcode_minus_L, $1)=yes+        ;;+      esac+      ;;++    bsdi[[45]]*)+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic+      ;;++    cygwin* | mingw* | windows* | pw32* | cegcc*)+      # When not using gcc, we currently assume that we are using+      # Microsoft Visual C++ or Intel C++ Compiler.+      # hardcode_libdir_flag_spec is actually meaningless, as there is+      # no search path for DLLs.+      case $cc_basename in+      cl* | icl*)+	# Native MSVC or ICC+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	_LT_TAGVAR(always_export_symbols, $1)=yes+	_LT_TAGVAR(file_list_spec, $1)='@'+	# Tell ltmain to make .lib files, not .a files.+	libext=lib+	# Tell ltmain to make .dll files, not .so files.+	shrext_cmds=.dll+	# FIXME: Setting linknames here is a bad hack.+	_LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='+	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then+            cp "$export_symbols" "$output_objdir/$soname.def";+            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";+          else+            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;+          fi~+          $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~+          linknames='+	# The linker will not automatically build a static lib if we build a DLL.+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'+	# Don't use ranlib+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~+          lt_tool_outputfile="@TOOL_OUTPUT@"~+          case $lt_outputfile in+            *.exe|*.EXE) ;;+            *)+              lt_outputfile=$lt_outputfile.exe+              lt_tool_outputfile=$lt_tool_outputfile.exe+              ;;+          esac~+          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then+            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;+            $RM "$lt_outputfile.manifest";+          fi'+	;;+      *)+	# Assume MSVC and ICC wrapper+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	# Tell ltmain to make .lib files, not .a files.+	libext=lib+	# Tell ltmain to make .dll files, not .so files.+	shrext_cmds=.dll+	# FIXME: Setting linknames here is a bad hack.+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='+	# The linker will automatically build a .lib file if we build a DLL.+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'+	# FIXME: Should let the user specify the lib program.+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+	;;+      esac+      ;;++    darwin* | rhapsody*)+      _LT_DARWIN_LINKER_FEATURES($1)+      ;;++    dgux*)+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor+    # support.  Future versions do this automatically, but an explicit c++rt0.o+    # does not break anything, and helps significantly (at the cost of a little+    # extra space).+    freebsd2.2*)+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    # Unfortunately, older versions of FreeBSD 2 do not have this feature.+    freebsd2.*)+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_minus_L, $1)=yes+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.+    freebsd* | dragonfly* | midnightbsd*)+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    hpux9*)+      if test yes = "$GCC"; then+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+      else+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+      fi+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:+      _LT_TAGVAR(hardcode_direct, $1)=yes++      # hardcode_minus_L: Not really in the search PATH,+      # but as the default location of the library.+      _LT_TAGVAR(hardcode_minus_L, $1)=yes+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+      ;;++    hpux10*)+      if test yes,no = "$GCC,$with_gnu_ld"; then+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'+      else+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'+      fi+      if test no = "$with_gnu_ld"; then+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:+	_LT_TAGVAR(hardcode_direct, $1)=yes+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+	# hardcode_minus_L: Not really in the search PATH,+	# but as the default location of the library.+	_LT_TAGVAR(hardcode_minus_L, $1)=yes+      fi+      ;;++    hpux11*)+      if test yes,no = "$GCC,$with_gnu_ld"; then+	case $host_cpu in+	hppa*64*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	ia64*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	esac+      else+	case $host_cpu in+	hppa*64*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	ia64*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	*)+	m4_if($1, [], [+	  # Older versions of the 11.00 compiler do not understand -b yet+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)+	  _LT_LINKER_OPTION([if $CC understands -b],+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])+	  ;;+	esac+      fi+      if test no = "$with_gnu_ld"; then+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:++	case $host_cpu in+	hppa*64*|ia64*)+	  _LT_TAGVAR(hardcode_direct, $1)=no+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	  ;;+	*)+	  _LT_TAGVAR(hardcode_direct, $1)=yes+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'++	  # hardcode_minus_L: Not really in the search PATH,+	  # but as the default location of the library.+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes+	  ;;+	esac+      fi+      ;;++    irix5* | irix6* | nonstopux*)+      if test yes = "$GCC"; then+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+	# Try to use the -exported_symbol ld option, if it does not+	# work, assume that -exports_file does not work either and+	# implicitly export all symbols.+	# This should be the same for all languages, so no per-tag cache variable.+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],+	  [lt_cv_irix_exported_symbol],+	  [save_LDFLAGS=$LDFLAGS+	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"+	   AC_LINK_IFELSE(+	     [AC_LANG_SOURCE(+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],+			      [C++], [[int foo (void) { return 0; }]],+			      [Fortran 77], [[+      subroutine foo+      end]],+			      [Fortran], [[+      subroutine foo+      end]])])],+	      [lt_cv_irix_exported_symbol=yes],+	      [lt_cv_irix_exported_symbol=no])+           LDFLAGS=$save_LDFLAGS])+	if test yes = "$lt_cv_irix_exported_symbol"; then+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'+	fi+      else+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'+      fi+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:+      _LT_TAGVAR(inherit_rpath, $1)=yes+      _LT_TAGVAR(link_all_deplibs, $1)=yes+      ;;++    linux*)+      case $cc_basename in+      tcc*)+	# Fabrice Bellard et al's Tiny C Compiler+	_LT_TAGVAR(ld_shlibs, $1)=yes+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+	;;+      esac+      ;;++    *-mlibc)+      ;;++    netbsd* | netbsdelf*-gnu)+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out+      else+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF+      fi+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    newsos6)+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    *nto* | *qnx*)+      ;;++    openbsd*)+      if test -f /usr/libexec/ld.so; then+	_LT_TAGVAR(hardcode_direct, $1)=yes+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+	else+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	fi+      else+	_LT_TAGVAR(ld_shlibs, $1)=no+      fi+      ;;++    os2*)+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+      _LT_TAGVAR(hardcode_minus_L, $1)=yes+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+      shrext_cmds=.dll+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	$ECHO EXPORTS >> $output_objdir/$libname.def~+	prefix_cmds="$SED"~+	if test EXPORTS = "`$SED 1q $export_symbols`"; then+	  prefix_cmds="$prefix_cmds -e 1d";+	fi~+	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~+	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~+	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	emximp -o $lib $output_objdir/$libname.def'+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+      _LT_TAGVAR(file_list_spec, $1)='@'+      ;;++    osf3*)+      if test yes = "$GCC"; then+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+      else+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+      fi+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:+      ;;++    osf4* | osf5*)	# as osf3* with the addition of -msym flag+      if test yes = "$GCC"; then+	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+      else+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~+          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'++	# Both c and cxx compiler support -rpath directly+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'+      fi+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:+      ;;++    serenity*)+      ;;++    solaris*)+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'+      if test yes = "$GCC"; then+	wlarc='$wl'+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'+      else+	case `$CC -V 2>&1` in+	*"Compilers 5.0"*)+	  wlarc=''+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'+	  ;;+	*)+	  wlarc='$wl'+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'+	  ;;+	esac+      fi+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      case $host_os in+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;+      *)+	# The compiler driver will combine and reorder linker options,+	# but understands '-z linker_flag'.  GCC discards it without '$wl',+	# but is careful enough not to reorder.+	# Supported since Solaris 2.6 (maybe 2.5.1?)+	if test yes = "$GCC"; then+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'+	else+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'+	fi+	;;+      esac+      _LT_TAGVAR(link_all_deplibs, $1)=yes+      ;;++    sunos4*)+      if test sequent = "$host_vendor"; then+	# Use $CC to link under sequent, because it throws in some extra .o+	# files that make .init and .fini sections work.+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'+      else+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'+      fi+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+      _LT_TAGVAR(hardcode_direct, $1)=yes+      _LT_TAGVAR(hardcode_minus_L, $1)=yes+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    sysv4)+      case $host_vendor in+	sni)+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???+	;;+	siemens)+	  ## LD is ld it makes a PLAMLIB+	  ## CC just makes a GrossModule.+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'+	  _LT_TAGVAR(hardcode_direct, $1)=no+        ;;+	motorola)+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie+	;;+      esac+      runpath_var='LD_RUN_PATH'+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    sysv4.3*)+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'+      ;;++    sysv4*MP*)+      if test -d /usr/nec; then+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	runpath_var=LD_RUN_PATH+	hardcode_runpath_var=yes+	_LT_TAGVAR(ld_shlibs, $1)=yes+      fi+      ;;++    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      runpath_var='LD_RUN_PATH'++      if test yes = "$GCC"; then+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      else+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      fi+      ;;++    sysv5* | sco3.2v5* | sco5v6*)+      # Note: We CANNOT use -z defs as we might desire, because we do not+      # link with -lc, and that would cause any symbols used from libc to+      # always be unresolved, which means just about no library would+      # ever link correctly.  If we're not using GNU ld we use -z text+      # though, which does catch some bad symbols but isn't as heavy-handed+      # as -z defs.+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'+      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'+      _LT_TAGVAR(link_all_deplibs, $1)=yes+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'+      runpath_var='LD_RUN_PATH'++      if test yes = "$GCC"; then+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      else+	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+      fi+      ;;++    uts4*)+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      ;;++    *)+      _LT_TAGVAR(ld_shlibs, $1)=no+      ;;+    esac++    if test sni = "$host_vendor"; then+      case $host in+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'+	;;+      esac+    fi+  fi+])+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no++_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld++_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl+_LT_DECL([], [extract_expsyms_cmds], [2],+    [The commands to extract the exported symbol list from a shared archive])++#+# Do we need to explicitly link libc?+#+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in+x|xyes)+  # Assume -lc should be added+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes++  if test yes,yes = "$GCC,$enable_shared"; then+    case $_LT_TAGVAR(archive_cmds, $1) in+    *'~'*)+      # FIXME: we may have to deal with multi-command sequences.+      ;;+    '$CC '*)+      # Test whether the compiler implicitly links with -lc since on some+      # systems, -lgcc has to come before -lc. If gcc already passes -lc+      # to ld, don't add -lc before -lgcc.+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),+	[$RM conftest*+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext++	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then+	  soname=conftest+	  lib=conftest+	  libobjs=conftest.$ac_objext+	  deplibs=+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)+	  compiler_flags=-v+	  linker_flags=-v+	  verstring=+	  output_objdir=.+	  libname=conftest+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)+	  _LT_TAGVAR(allow_undefined_flag, $1)=+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)+	  then+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no+	  else+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes+	  fi+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag+	else+	  cat conftest.err 1>&5+	fi+	$RM conftest*+	])+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)+      ;;+    esac+  fi+  ;;+esac++_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],+    [Whether or not to add -lc for building shared libraries])+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],+    [enable_shared_with_static_runtimes], [0],+    [Whether or not to disallow shared libs when runtime libs are static])+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],+    [Compiler flag to allow reflexive dlopens])+_LT_TAGDECL([], [whole_archive_flag_spec], [1],+    [Compiler flag to generate shared objects directly from archives])+_LT_TAGDECL([], [compiler_needs_object], [1],+    [Whether the compiler copes with passing no objects directly])+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],+    [Create an old-style archive from a shared archive])+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],+    [Create a temporary old-style archive to link instead of a shared archive])+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])+_LT_TAGDECL([], [archive_expsym_cmds], [2])+_LT_TAGDECL([], [module_cmds], [2],+    [Commands used to build a loadable module if different from building+    a shared archive.])+_LT_TAGDECL([], [module_expsym_cmds], [2])+_LT_TAGDECL([], [with_gnu_ld], [1],+    [Whether we are building with GNU ld or not])+_LT_TAGDECL([], [allow_undefined_flag], [1],+    [Flag that allows shared libraries with undefined symbols to be built])+_LT_TAGDECL([], [no_undefined_flag], [1],+    [Flag that enforces no undefined symbols])+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],+    [Flag to hardcode $libdir into a binary during linking.+    This must work even if $libdir does not exist])+_LT_TAGDECL([], [hardcode_libdir_separator], [1],+    [Whether we need a single "-rpath" flag with a separated argument])+_LT_TAGDECL([], [hardcode_direct], [0],+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes+    DIR into the resulting binary])+_LT_TAGDECL([], [hardcode_direct_absolute], [0],+    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes+    DIR into the resulting binary and the resulting library dependency is+    "absolute", i.e. impossible to change by setting $shlibpath_var if the+    library is relocated])+_LT_TAGDECL([], [hardcode_minus_L], [0],+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR+    into the resulting binary])+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR+    into the resulting binary])+_LT_TAGDECL([], [hardcode_automatic], [0],+    [Set to "yes" if building a shared library automatically hardcodes DIR+    into the library and all subsequent libraries and executables linked+    against it])+_LT_TAGDECL([], [inherit_rpath], [0],+    [Set to yes if linker adds runtime paths of dependent libraries+    to runtime path list])+_LT_TAGDECL([], [link_all_deplibs], [0],+    [Whether libtool must link a program against all its dependency libraries])+_LT_TAGDECL([], [always_export_symbols], [0],+    [Set to "yes" if exported symbols are required])+_LT_TAGDECL([], [export_symbols_cmds], [2],+    [The commands to list exported symbols])+_LT_TAGDECL([], [exclude_expsyms], [1],+    [Symbols that should not be listed in the preloaded symbols])+_LT_TAGDECL([], [include_expsyms], [1],+    [Symbols that must always be exported])+_LT_TAGDECL([], [prelink_cmds], [2],+    [Commands necessary for linking programs (against libraries) with templates])+_LT_TAGDECL([], [postlink_cmds], [2],+    [Commands necessary for finishing linking programs])+_LT_TAGDECL([], [file_list_spec], [1],+    [Specify filename containing input files])+dnl FIXME: Not yet implemented+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],+dnl    [Compiler flag to generate thread safe objects])+])# _LT_LINKER_SHLIBS+++# _LT_LANG_C_CONFIG([TAG])+# ------------------------+# Ensure that the configuration variables for a C compiler are suitably+# defined.  These variables are subsequently used by _LT_CONFIG to write+# the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_C_CONFIG],+[m4_require([_LT_DECL_EGREP])dnl+lt_save_CC=$CC+AC_LANG_PUSH(C)++# Source file extension for C test sources.+ac_ext=c++# Object file extension for compiled C test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# Code to be used in simple compile tests+lt_simple_compile_test_code="int some_variable = 0;"++# Code to be used in simple link tests+lt_simple_link_test_code='int main(void){return(0);}'++_LT_TAG_COMPILER+# Save the default compiler, since it gets overwritten when the other+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.+compiler_DEFAULT=$CC++# save warnings/boilerplate of simple test code+_LT_COMPILER_BOILERPLATE+_LT_LINKER_BOILERPLATE++## CAVEAT EMPTOR:+## There is no encapsulation within the following macros, do not change+## the running order or otherwise move them around unless you know exactly+## what you are doing...+if test -n "$compiler"; then+  _LT_COMPILER_NO_RTTI($1)+  _LT_COMPILER_PIC($1)+  _LT_COMPILER_C_O($1)+  _LT_COMPILER_FILE_LOCKS($1)+  _LT_LINKER_SHLIBS($1)+  _LT_SYS_DYNAMIC_LINKER($1)+  _LT_LINKER_HARDCODE_LIBPATH($1)+  LT_SYS_DLOPEN_SELF+  _LT_CMD_STRIPLIB++  # Report what library types will actually be built+  AC_MSG_CHECKING([if libtool supports shared libraries])+  AC_MSG_RESULT([$can_build_shared])++  AC_MSG_CHECKING([whether to build shared libraries])+  test no = "$can_build_shared" && enable_shared=no++  # On AIX, shared libraries and static libraries use the same namespace, and+  # are all built from PIC.+  case $host_os in+  aix3*)+    test yes = "$enable_shared" && enable_static=no+    if test -n "$RANLIB"; then+      archive_cmds="$archive_cmds~\$RANLIB \$lib"+      postinstall_cmds='$RANLIB $lib'+    fi+    ;;++  aix[[4-9]]*)+    if test ia64 != "$host_cpu"; then+      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in+      yes,aix,yes) ;;			# shared object as lib.so file only+      yes,svr4,*) ;;			# shared object as lib.so archive member only+      yes,*) enable_static=no ;;	# shared object in lib.a archive as well+      esac+    fi+    ;;+  esac+  AC_MSG_RESULT([$enable_shared])++  AC_MSG_CHECKING([whether to build static libraries])+  # Make sure either enable_shared or enable_static is yes.+  test yes = "$enable_shared" || enable_static=yes+  AC_MSG_RESULT([$enable_static])++  _LT_CONFIG($1)+fi+AC_LANG_POP+CC=$lt_save_CC+])# _LT_LANG_C_CONFIG+++# _LT_LANG_CXX_CONFIG([TAG])+# --------------------------+# Ensure that the configuration variables for a C++ compiler are suitably+# defined.  These variables are subsequently used by _LT_CONFIG to write+# the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_CXX_CONFIG],+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl+m4_require([_LT_DECL_EGREP])dnl+m4_require([_LT_PATH_MANIFEST_TOOL])dnl+if test -n "$CXX" && ( test no != "$CXX" &&+    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||+    (test g++ != "$CXX"))); then+  AC_PROG_CXXCPP+else+  _lt_caught_CXX_error=yes+fi++AC_LANG_PUSH(C++)+_LT_TAGVAR(archive_cmds_need_lc, $1)=no+_LT_TAGVAR(allow_undefined_flag, $1)=+_LT_TAGVAR(always_export_symbols, $1)=no+_LT_TAGVAR(archive_expsym_cmds, $1)=+_LT_TAGVAR(compiler_needs_object, $1)=no+_LT_TAGVAR(export_dynamic_flag_spec, $1)=+_LT_TAGVAR(hardcode_direct, $1)=no+_LT_TAGVAR(hardcode_direct_absolute, $1)=no+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=+_LT_TAGVAR(hardcode_libdir_separator, $1)=+_LT_TAGVAR(hardcode_minus_L, $1)=no+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported+_LT_TAGVAR(hardcode_automatic, $1)=no+_LT_TAGVAR(inherit_rpath, $1)=no+_LT_TAGVAR(module_cmds, $1)=+_LT_TAGVAR(module_expsym_cmds, $1)=+_LT_TAGVAR(link_all_deplibs, $1)=unknown+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds+_LT_TAGVAR(reload_flag, $1)=$reload_flag+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds+_LT_TAGVAR(no_undefined_flag, $1)=+_LT_TAGVAR(whole_archive_flag_spec, $1)=+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no++# Source file extension for C++ test sources.+ac_ext=cpp++# Object file extension for compiled C++ test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# No sense in running all these tests if we already determined that+# the CXX compiler isn't working.  Some variables (like enable_shared)+# are currently assumed to apply to all compilers on this platform,+# and will be corrupted by setting them based on a non-working compiler.+if test yes != "$_lt_caught_CXX_error"; then+  # Code to be used in simple compile tests+  lt_simple_compile_test_code="int some_variable = 0;"++  # Code to be used in simple link tests+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'++  # ltmain only uses $CC for tagged configurations so make sure $CC is set.+  _LT_TAG_COMPILER++  # save warnings/boilerplate of simple test code+  _LT_COMPILER_BOILERPLATE+  _LT_LINKER_BOILERPLATE++  # Allow CC to be a program name with arguments.+  lt_save_CC=$CC+  lt_save_CFLAGS=$CFLAGS+  lt_save_LD=$LD+  lt_save_GCC=$GCC+  GCC=$GXX+  lt_save_with_gnu_ld=$with_gnu_ld+  lt_save_path_LD=$lt_cv_path_LD+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx+  else+    $as_unset lt_cv_prog_gnu_ld+  fi+  if test -n "${lt_cv_path_LDCXX+set}"; then+    lt_cv_path_LD=$lt_cv_path_LDCXX+  else+    $as_unset lt_cv_path_LD+  fi+  test -z "${LDCXX+set}" || LD=$LDCXX+  CC=${CXX-"c++"}+  CFLAGS=$CXXFLAGS+  compiler=$CC+  _LT_TAGVAR(compiler, $1)=$CC+  _LT_CC_BASENAME([$compiler])++  if test -n "$compiler"; then+    # We don't want -fno-exception when compiling C++ code, so set the+    # no_builtin_flag separately+    if test yes = "$GXX"; then+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'+    else+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=+    fi++    if test yes = "$GXX"; then+      # Set up default GNU C++ configuration++      LT_PATH_LD++      # Check if GNU C++ uses GNU ld as the underlying linker, since the+      # archiving commands below assume that GNU ld is being used.+      if test yes = "$with_gnu_ld"; then+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'++        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'++        # If archive_cmds runs LD, not CC, wlarc should be empty+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to+        #     investigate it a little bit more. (MM)+        wlarc='$wl'++        # ancient GNU ld didn't support --whole-archive et. al.+        if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then+          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'+        else+          _LT_TAGVAR(whole_archive_flag_spec, $1)=+        fi+      else+        with_gnu_ld=no+        wlarc=++        # A generic and very simple default shared library creation+        # command for GNU C++ for the case where it uses the native+        # linker, instead of GNU ld.  If possible, this setting should+        # overridden to take advantage of the native linker features on+        # the platform it is being used on.+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'+      fi++      # Commands to make compiler produce verbose output that lists+      # what "hidden" libraries, object files and flags are used when+      # linking a shared library.+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'++    else+      GXX=no+      with_gnu_ld=no+      wlarc=+    fi++    # PORTME: fill in a description of your system's C++ link characteristics+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])+    _LT_TAGVAR(ld_shlibs, $1)=yes+    case $host_os in+      aix3*)+        # FIXME: insert proper C++ library support+        _LT_TAGVAR(ld_shlibs, $1)=no+        ;;+      aix[[4-9]]*)+        if test ia64 = "$host_cpu"; then+          # On IA64, the linker does run time linking by default, so we don't+          # have to do anything special.+          aix_use_runtimelinking=no+          exp_sym_flag='-Bexport'+          no_entry_flag=+        else+          aix_use_runtimelinking=no++          # Test if we are trying to use run time linking or normal+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we+          # have runtime linking enabled, and use it for executables.+          # For shared libraries, we enable/disable runtime linking+          # depending on the kind of the shared library created -+          # when "with_aix_soname,aix_use_runtimelinking" is:+          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables+          # "aix,yes"  lib.so          shared, rtl:yes, for executables+          #            lib.a           static archive+          # "both,no"  lib.so.V(shr.o) shared, rtl:yes+          #            lib.a(lib.so.V) shared, rtl:no,  for executables+          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables+          #            lib.a(lib.so.V) shared, rtl:no+          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables+          #            lib.a           static archive+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)+	    for ld_flag in $LDFLAGS; do+	      case $ld_flag in+	      *-brtl*)+	        aix_use_runtimelinking=yes+	        break+	        ;;+	      esac+	    done+	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then+	      # With aix-soname=svr4, we create the lib.so.V shared archives only,+	      # so we don't have lib.a shared libs to link our executables.+	      # We have to force runtime linking in this case.+	      aix_use_runtimelinking=yes+	      LDFLAGS="$LDFLAGS -Wl,-brtl"+	    fi+	    ;;+          esac++          exp_sym_flag='-bexport'+          no_entry_flag='-bnoentry'+        fi++        # When large executables or shared objects are built, AIX ld can+        # have problems creating the table of contents.  If linking a library+        # or program results in "error TOC overflow" add -mminimal-toc to+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.++        _LT_TAGVAR(archive_cmds, $1)=''+        _LT_TAGVAR(hardcode_direct, $1)=yes+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'+        _LT_TAGVAR(link_all_deplibs, $1)=yes+        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'+        case $with_aix_soname,$aix_use_runtimelinking in+        aix,*) ;;	# no import file+        svr4,* | *,yes) # use import file+          # The Import File defines what to hardcode.+          _LT_TAGVAR(hardcode_direct, $1)=no+          _LT_TAGVAR(hardcode_direct_absolute, $1)=no+          ;;+        esac++        if test yes = "$GXX"; then+          case $host_os in aix4.[[012]]|aix4.[[012]].*)+          # We only want to do this on AIX 4.2 and lower, the check+          # below for broken collect2 doesn't work under 4.3++	  collect2name=`$CC -print-prog-name=collect2`+	  if test -f "$collect2name" &&+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null+	  then+	    # We have reworked collect2+	    :+	  else+	    # We have old collect2+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported+	    # It fails to find uninstalled libraries when the uninstalled+	    # path is not listed in the libpath.  Setting hardcode_minus_L+	    # to unsupported forces relinking+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=+	  fi+          esac+          shared_flag='-shared'+	  if test yes = "$aix_use_runtimelinking"; then+	    shared_flag=$shared_flag' $wl-G'+	  fi+	  # Need to ensure runtime linking is disabled for the traditional+	  # shared library, or the linker may eventually find shared libraries+	  # /with/ Import File - we do not want to mix them.+	  shared_flag_aix='-shared'+	  shared_flag_svr4='-shared $wl-G'+        else+          # not using gcc+          if test ia64 = "$host_cpu"; then+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release+	  # chokes on -Wl,-G. The following line is correct:+	  shared_flag='-G'+          else+	    if test yes = "$aix_use_runtimelinking"; then+	      shared_flag='$wl-G'+	    else+	      shared_flag='$wl-bM:SRE'+	    fi+	    shared_flag_aix='$wl-bM:SRE'+	    shared_flag_svr4='$wl-G'+          fi+        fi++        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'+        # It seems that -bexpall does not export symbols beginning with+        # underscore (_), so it is better to generate a list of symbols to+	# export.+        _LT_TAGVAR(always_export_symbols, $1)=yes+	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then+          # Warning - without using the other runtime loading flags (-brtl),+          # -berok will link without error, but may produce a broken library.+          # The "-G" linker flag allows undefined symbols.+          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'+          # Determine the default libpath from the value encoded in an empty+          # executable.+          _LT_SYS_MODULE_PATH_AIX([$1])+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"++          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag+        else+          if test ia64 = "$host_cpu"; then+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"+          else+	    # Determine the default libpath from the value encoded in an+	    # empty executable.+	    _LT_SYS_MODULE_PATH_AIX([$1])+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"+	    # Warning - without using the other run time loading flags,+	    # -berok will link without error, but may produce a broken library.+	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'+	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'+	    if test yes = "$with_gnu_ld"; then+	      # We only use this code for GNU lds that support --whole-archive.+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'+	    else+	      # Exported symbols can be pulled into shared objects from archives+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'+	    fi+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'+	    # -brtl affects multiple linker settings, -berok does not and is overridden later+	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'+	    if test svr4 != "$with_aix_soname"; then+	      # This is similar to how AIX traditionally builds its shared+	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'+	    fi+	    if test aix != "$with_aix_soname"; then+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'+	    else+	      # used by -dlpreopen to get the symbols+	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'+	    fi+	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'+          fi+        fi+        ;;++      beos*)+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc+	  # support --undefined.  This deserves some investigation.  FIXME+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	else+	  _LT_TAGVAR(ld_shlibs, $1)=no+	fi+	;;++      chorus*)+        case $cc_basename in+          *)+	  # FIXME: insert proper C++ library support+	  _LT_TAGVAR(ld_shlibs, $1)=no+	  ;;+        esac+        ;;++      cygwin* | mingw* | windows* | pw32* | cegcc*)+	case $GXX,$cc_basename in+	,cl* | no,cl* | ,icl* | no,icl*)+	  # Native MSVC or ICC+	  # hardcode_libdir_flag_spec is actually meaningless, as there is+	  # no search path for DLLs.+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	  _LT_TAGVAR(always_export_symbols, $1)=yes+	  _LT_TAGVAR(file_list_spec, $1)='@'+	  # Tell ltmain to make .lib files, not .a files.+	  libext=lib+	  # Tell ltmain to make .dll files, not .so files.+	  shrext_cmds=.dll+	  # FIXME: Setting linknames here is a bad hack.+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then+              cp "$export_symbols" "$output_objdir/$soname.def";+              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";+            else+              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;+            fi~+            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~+            linknames='+	  # The linker will not automatically build a static lib if we build a DLL.+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+	  # Don't use ranlib+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~+            lt_tool_outputfile="@TOOL_OUTPUT@"~+            case $lt_outputfile in+              *.exe|*.EXE) ;;+              *)+                lt_outputfile=$lt_outputfile.exe+                lt_tool_outputfile=$lt_tool_outputfile.exe+                ;;+            esac~+            func_to_tool_file "$lt_outputfile"~+            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then+              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;+              $RM "$lt_outputfile.manifest";+            fi'+	  ;;+	*)+	  # g+++	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,+	  # as there is no search path for DLLs.+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	  _LT_TAGVAR(always_export_symbols, $1)=no+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+	  _LT_TAGVAR(file_list_spec, $1)='@'++	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+	    # If the export-symbols file already is a .def file, use it as+	    # is; otherwise, prepend EXPORTS...+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then+              cp $export_symbols $output_objdir/$soname.def;+            else+              echo EXPORTS > $output_objdir/$soname.def;+              cat $export_symbols >> $output_objdir/$soname.def;+            fi~+            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'+	  else+	    _LT_TAGVAR(ld_shlibs, $1)=no+	  fi+	  ;;+	esac+	;;+      darwin* | rhapsody*)+        _LT_DARWIN_LINKER_FEATURES($1)+	;;++      os2*)+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'+	_LT_TAGVAR(hardcode_minus_L, $1)=yes+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported+	shrext_cmds=.dll+	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	  $ECHO EXPORTS >> $output_objdir/$libname.def~+	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	  emximp -o $lib $output_objdir/$libname.def'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~+	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~+	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~+	  $ECHO EXPORTS >> $output_objdir/$libname.def~+	  prefix_cmds="$SED"~+	  if test EXPORTS = "`$SED 1q $export_symbols`"; then+	    prefix_cmds="$prefix_cmds -e 1d";+	  fi~+	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~+	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~+	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~+	  emximp -o $lib $output_objdir/$libname.def'+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes+	_LT_TAGVAR(file_list_spec, $1)='@'+	;;++      dgux*)+        case $cc_basename in+          ec++*)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          ghcx*)+	    # Green Hills C++ Compiler+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          *)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+        esac+        ;;++      freebsd2.*)+        # C++ shared libraries reported to be fairly broken before+	# switch to ELF+        _LT_TAGVAR(ld_shlibs, $1)=no+        ;;++      freebsd-elf*)+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no+        ;;++      freebsd* | dragonfly* | midnightbsd*)+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF+        # conventions+        _LT_TAGVAR(ld_shlibs, $1)=yes+        ;;++      haiku*)+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+        _LT_TAGVAR(link_all_deplibs, $1)=no+        ;;++      hpux9*)+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+        _LT_TAGVAR(hardcode_direct, $1)=yes+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,+				             # but as the default+				             # location of the library.++        case $cc_basename in+          CC*)+            # FIXME: insert proper C++ library support+            _LT_TAGVAR(ld_shlibs, $1)=no+            ;;+          aCC*)+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+            # Commands to make compiler produce verbose output that lists+            # what "hidden" libraries, object files and flags are used when+            # linking a shared library.+            #+            # There doesn't appear to be a way to prevent this compiler from+            # explicitly linking system object files so we need to strip them+            # from the output so that they don't get included in the library+            # dependencies.+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'+            ;;+          *)+            if test yes = "$GXX"; then+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'+            else+              # FIXME: insert proper C++ library support+              _LT_TAGVAR(ld_shlibs, $1)=no+            fi+            ;;+        esac+        ;;++      hpux10*|hpux11*)+        if test no = "$with_gnu_ld"; then+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:++          case $host_cpu in+            hppa*64*|ia64*)+              ;;+            *)+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+              ;;+          esac+        fi+        case $host_cpu in+          hppa*64*|ia64*)+            _LT_TAGVAR(hardcode_direct, $1)=no+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+            ;;+          *)+            _LT_TAGVAR(hardcode_direct, $1)=yes+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,+					         # but as the default+					         # location of the library.+            ;;+        esac++        case $cc_basename in+          CC*)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          aCC*)+	    case $host_cpu in+	      hppa*64*)+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	        ;;+	      ia64*)+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	        ;;+	      *)+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	        ;;+	    esac+	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'+	    ;;+          *)+	    if test yes = "$GXX"; then+	      if test no = "$with_gnu_ld"; then+	        case $host_cpu in+	          hppa*64*)+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	            ;;+	          ia64*)+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	            ;;+	          *)+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	            ;;+	        esac+	      fi+	    else+	      # FIXME: insert proper C++ library support+	      _LT_TAGVAR(ld_shlibs, $1)=no+	    fi+	    ;;+        esac+        ;;++      interix[[3-9]]*)+	_LT_TAGVAR(hardcode_direct, $1)=no+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.+	# Instead, shared libraries are loaded at an image base (0x10000000 by+	# default) and relocated if they conflict, which is a slow very memory+	# consuming and fragmenting process.  To avoid this, we pick a random,+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+	_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'+	;;+      irix5* | irix6*)+        case $cc_basename in+          CC*)+	    # SGI C+++	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'++	    # Archives containing C++ object files must be created using+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is+	    # necessary to make sure instantiated templates are included+	    # in the archive.+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'+	    ;;+          *)+	    if test yes = "$GXX"; then+	      if test no = "$with_gnu_ld"; then+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+	      else+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'+	      fi+	    fi+	    _LT_TAGVAR(link_all_deplibs, $1)=yes+	    ;;+        esac+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:+        _LT_TAGVAR(inherit_rpath, $1)=yes+        ;;++      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)+        case $cc_basename in+          KCC*)+	    # Kuck and Associates, Inc. (KAI) C++ Compiler++	    # KCC will only create a shared library if the output file+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library+	    # to its proper name (with version) after linking.+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'+	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'++	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'++	    # Archives containing C++ object files must be created using+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'+	    ;;+	  icpc* | ecpc* )+	    # Intel C+++	    with_gnu_ld=yes+	    # version 8.0 and above of icpc choke on multiply defined symbols+	    # if we add $predep_objects and $postdep_objects, however 7.1 and+	    # earlier do not add the objects themselves.+	    case `$CC -V 2>&1` in+	      *"Version 7."*)+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+		;;+	      *)  # Version 8.0 or newer+	        tmp_idyn=+	        case $host_cpu in+		  ia64*) tmp_idyn=' -i_dynamic';;+		esac+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+		;;+	    esac+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'+	    ;;+          pgCC* | pgcpp*)+            # Portland Group C++ compiler+	    case `$CC -V` in+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~+               rm -rf $tpldir~+               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~+               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~+                rm -rf $tpldir~+                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~+                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~+                $RANLIB $oldlib'+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~+                rm -rf $tpldir~+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~+                rm -rf $tpldir~+                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~+                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+	      ;;+	    *) # Version 6 and above use weak symbols+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'+	      ;;+	    esac++	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+            ;;+	  cxx*)+	    # Compaq C+++	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'++	    runpath_var=LD_RUN_PATH+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:++	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'+	    ;;+	  xl* | mpixl* | bgxl*)+	    # IBM XL 8.0 on PPC, with GNU ld+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'+	    if test yes = "$supports_anon_versioning"; then+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~+                cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~+                echo "local: *; };" >> $output_objdir/$libname.ver~+                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'+	    fi+	    ;;+	  *)+	    case `$CC -V 2>&1 | $SED 5q` in+	    *Sun\ C*)+	      # Sun C++ 5.9+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'+	      _LT_TAGVAR(compiler_needs_object, $1)=yes++	      # Not sure whether something based on+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1+	      # would be better.+	      output_verbose_link_cmd='func_echo_all'++	      # Archives containing C++ object files must be created using+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is+	      # necessary to make sure instantiated templates are included+	      # in the archive.+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'+	      ;;+	    esac+	    ;;+	esac+	;;++      lynxos*)+        # FIXME: insert proper C++ library support+	_LT_TAGVAR(ld_shlibs, $1)=no+	;;++      m88k*)+        # FIXME: insert proper C++ library support+        _LT_TAGVAR(ld_shlibs, $1)=no+	;;++      mvs*)+        case $cc_basename in+          cxx*)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+	  *)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+	esac+	;;++      *-mlibc)+        _LT_TAGVAR(ld_shlibs, $1)=yes+	;;++      netbsd*)+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'+	  wlarc=+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+	  _LT_TAGVAR(hardcode_direct, $1)=yes+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	fi+	# Workaround some broken pre-1.5 toolchains+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'+	;;++      *nto* | *qnx*)+        _LT_TAGVAR(ld_shlibs, $1)=yes+	;;++      openbsd*)+	if test -f /usr/libexec/ld.so; then+	  _LT_TAGVAR(hardcode_direct, $1)=yes+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'+	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'+	  fi+	  output_verbose_link_cmd=func_echo_all+	else+	  _LT_TAGVAR(ld_shlibs, $1)=no+	fi+	;;++      osf3* | osf4* | osf5*)+        case $cc_basename in+          KCC*)+	    # Kuck and Associates, Inc. (KAI) C++ Compiler++	    # KCC will only create a shared library if the output file+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library+	    # to its proper name (with version) after linking.+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'++	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:++	    # Archives containing C++ object files must be created using+	    # the KAI C++ compiler.+	    case $host in+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;+	    esac+	    ;;+          RCC*)+	    # Rational C++ 2.4.1+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          cxx*)+	    case $host in+	      osf3*)+	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+		;;+	      *)+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~+                  echo "-hidden">> $lib.exp~+                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~+                  $RM $lib.exp'+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'+		;;+	    esac++	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:++	    # Commands to make compiler produce verbose output that lists+	    # what "hidden" libraries, object files and flags are used when+	    # linking a shared library.+	    #+	    # There doesn't appear to be a way to prevent this compiler from+	    # explicitly linking system object files so we need to strip them+	    # from the output so that they don't get included in the library+	    # dependencies.+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'+	    ;;+	  *)+	    if test yes,no = "$GXX,$with_gnu_ld"; then+	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'+	      case $host in+	        osf3*)+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+		  ;;+	        *)+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'+		  ;;+	      esac++	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:++	      # Commands to make compiler produce verbose output that lists+	      # what "hidden" libraries, object files and flags are used when+	      # linking a shared library.+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'++	    else+	      # FIXME: insert proper C++ library support+	      _LT_TAGVAR(ld_shlibs, $1)=no+	    fi+	    ;;+        esac+        ;;++      psos*)+        # FIXME: insert proper C++ library support+        _LT_TAGVAR(ld_shlibs, $1)=no+        ;;++      serenity*)+        ;;++      sunos4*)+        case $cc_basename in+          CC*)+	    # Sun C++ 4.x+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          lcc*)+	    # Lucid+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          *)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+        esac+        ;;++      solaris*)+        case $cc_basename in+          CC* | sunCC*)+	    # Sun C++ 4.2, 5.x and Centerline C+++            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'++	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	    case $host_os in+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;+	      *)+		# The compiler driver will combine and reorder linker options,+		# but understands '-z linker_flag'.+	        # Supported since Solaris 2.6 (maybe 2.5.1?)+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'+	        ;;+	    esac+	    _LT_TAGVAR(link_all_deplibs, $1)=yes++	    output_verbose_link_cmd='func_echo_all'++	    # Archives containing C++ object files must be created using+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is+	    # necessary to make sure instantiated templates are included+	    # in the archive.+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'+	    ;;+          gcx*)+	    # Green Hills C++ Compiler+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'++	    # The C++ compiler must be used to create the archive.+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'+	    ;;+          *)+	    # GNU C++ compiler with Solaris linker+	    if test yes,no = "$GXX,$with_gnu_ld"; then+	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'++	        # Commands to make compiler produce verbose output that lists+	        # what "hidden" libraries, object files and flags are used when+	        # linking a shared library.+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'+	      else+	        # g++ 2.7 appears to require '-G' NOT '-shared' on this+	        # platform.+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~+                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'++	        # Commands to make compiler produce verbose output that lists+	        # what "hidden" libraries, object files and flags are used when+	        # linking a shared library.+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"'+	      fi++	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'+	      case $host_os in+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;+		*)+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'+		  ;;+	      esac+	    fi+	    ;;+        esac+        ;;++    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)+      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no+      runpath_var='LD_RUN_PATH'++      case $cc_basename in+        CC*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+	*)+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	  ;;+      esac+      ;;++      sysv5* | sco3.2v5* | sco5v6*)+	# Note: We CANNOT use -z defs as we might desire, because we do not+	# link with -lc, and that would cause any symbols used from libc to+	# always be unresolved, which means just about no library would+	# ever link correctly.  If we're not using GNU ld we use -z text+	# though, which does catch some bad symbols but isn't as heavy-handed+	# as -z defs.+	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'+	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'+	_LT_TAGVAR(link_all_deplibs, $1)=yes+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'+	runpath_var='LD_RUN_PATH'++	case $cc_basename in+          CC*)+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~+              '"$_LT_TAGVAR(old_archive_cmds, $1)"+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~+              '"$_LT_TAGVAR(reload_cmds, $1)"+	    ;;+	  *)+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'+	    ;;+	esac+      ;;++      tandem*)+        case $cc_basename in+          NCC*)+	    # NonStop-UX NCC 3.20+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+          *)+	    # FIXME: insert proper C++ library support+	    _LT_TAGVAR(ld_shlibs, $1)=no+	    ;;+        esac+        ;;++      vxworks*)+        # FIXME: insert proper C++ library support+        _LT_TAGVAR(ld_shlibs, $1)=no+        ;;++      *)+        # FIXME: insert proper C++ library support+        _LT_TAGVAR(ld_shlibs, $1)=no+        ;;+    esac++    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])+    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no++    _LT_TAGVAR(GCC, $1)=$GXX+    _LT_TAGVAR(LD, $1)=$LD++    ## CAVEAT EMPTOR:+    ## There is no encapsulation within the following macros, do not change+    ## the running order or otherwise move them around unless you know exactly+    ## what you are doing...+    _LT_SYS_HIDDEN_LIBDEPS($1)+    _LT_COMPILER_PIC($1)+    _LT_COMPILER_C_O($1)+    _LT_COMPILER_FILE_LOCKS($1)+    _LT_LINKER_SHLIBS($1)+    _LT_SYS_DYNAMIC_LINKER($1)+    _LT_LINKER_HARDCODE_LIBPATH($1)++    _LT_CONFIG($1)+  fi # test -n "$compiler"++  CC=$lt_save_CC+  CFLAGS=$lt_save_CFLAGS+  LDCXX=$LD+  LD=$lt_save_LD+  GCC=$lt_save_GCC+  with_gnu_ld=$lt_save_with_gnu_ld+  lt_cv_path_LDCXX=$lt_cv_path_LD+  lt_cv_path_LD=$lt_save_path_LD+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld+fi # test yes != "$_lt_caught_CXX_error"++AC_LANG_POP+])# _LT_LANG_CXX_CONFIG+++# _LT_FUNC_STRIPNAME_CNF+# ----------------------+# func_stripname_cnf prefix suffix name+# strip PREFIX and SUFFIX off of NAME.+# PREFIX and SUFFIX must not contain globbing or regex special+# characters, hashes, percent signs, but SUFFIX may contain a leading+# dot (in which case that matches only a dot).+#+# This function is identical to the (non-XSI) version of func_stripname,+# except this one can be used by m4 code that may be executed by configure,+# rather than the libtool script.+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl+AC_REQUIRE([_LT_DECL_SED])+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])+func_stripname_cnf ()+{+  case @S|@2 in+  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;+  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;+  esac+} # func_stripname_cnf+])# _LT_FUNC_STRIPNAME_CNF+++# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])+# ---------------------------------+# Figure out "hidden" library dependencies from verbose+# compiler output when linking a shared library.+# Parse the compiler output and extract the necessary+# objects, libraries and library flags.+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl+# Dependencies to place before and after the object being linked:+_LT_TAGVAR(predep_objects, $1)=+_LT_TAGVAR(postdep_objects, $1)=+_LT_TAGVAR(predeps, $1)=+_LT_TAGVAR(postdeps, $1)=+_LT_TAGVAR(compiler_lib_search_path, $1)=++dnl we can't use the lt_simple_compile_test_code here,+dnl because it contains code intended for an executable,+dnl not a library.  It's possible we should let each+dnl tag define a new lt_????_link_test_code variable,+dnl but it's only used here...+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF+int a;+void foo (void) { a = 0; }+_LT_EOF+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF+class Foo+{+public:+  Foo (void) { a = 0; }+private:+  int a;+};+_LT_EOF+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF+      subroutine foo+      implicit none+      integer*4 a+      a=0+      return+      end+_LT_EOF+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF+      subroutine foo+      implicit none+      integer a+      a=0+      return+      end+_LT_EOF+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF+public class foo {+  private int a;+  public void bar (void) {+    a = 0;+  }+};+_LT_EOF+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF+package foo+func foo() {+}+_LT_EOF+])++_lt_libdeps_save_CFLAGS=$CFLAGS+case "$CC $CFLAGS " in #(+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;+esac++dnl Parse the compiler output and extract the necessary+dnl objects, libraries and library flags.+if AC_TRY_EVAL(ac_compile); then+  # Parse the compiler output and extract the necessary+  # objects, libraries and library flags.++  # Sentinel used to keep track of whether or not we are before+  # the conftest object file.+  pre_test_object_deps_done=no++  for p in `eval "$output_verbose_link_cmd"`; do+    case $prev$p in++    -L* | -R* | -l*)+       # Some compilers place space between "-{L,R,l}" and the path.+       # Remove the space.+       if test x-L = x"$p" ||+          test x-R = x"$p" ||+          test x-l = x"$p"; then+	 prev=$p+	 continue+       fi++       # Expand the sysroot to ease extracting the directories later.+       if test -z "$prev"; then+         case $p in+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;+         esac+       fi+       case $p in+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;+       esac+       if test no = "$pre_test_object_deps_done"; then+	 case $prev in+	 -L | -R)+	   # Internal compiler library paths should come after those+	   # provided the user.  The postdeps already come after the+	   # user supplied libs so there is no need to process them.+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then+	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p+	   else+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"+	   fi+	   ;;+	 # The "-l" case would never come before the object being+	 # linked, so don't bother handling this case.+	 esac+       else+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then+	   _LT_TAGVAR(postdeps, $1)=$prev$p+	 else+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"+	 fi+       fi+       prev=+       ;;++    *.lto.$objext) ;; # Ignore GCC LTO objects+    *.$objext)+       # This assumes that the test object file only shows up+       # once in the compiler output.+       if test "$p" = "conftest.$objext"; then+	 pre_test_object_deps_done=yes+	 continue+       fi++       if test no = "$pre_test_object_deps_done"; then+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then+	   _LT_TAGVAR(predep_objects, $1)=$p+	 else+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"+	 fi+       else+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then+	   _LT_TAGVAR(postdep_objects, $1)=$p+	 else+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"+	 fi+       fi+       ;;++    *) ;; # Ignore the rest.++    esac+  done++  # Clean up.+  rm -f a.out a.exe+else+  echo "libtool.m4: error: problem compiling $1 test program"+fi++$RM -f confest.$objext+CFLAGS=$_lt_libdeps_save_CFLAGS++# PORTME: override above test on systems where it is broken+m4_if([$1], [CXX],+[case $host_os in+interix[[3-9]]*)+  # Interix 3.5 installs completely hosed .la files for C++, so rather than+  # hack all around it, let's just trust "g++" to DTRT.+  _LT_TAGVAR(predep_objects,$1)=+  _LT_TAGVAR(postdep_objects,$1)=+  _LT_TAGVAR(postdeps,$1)=+  ;;+esac+])++case " $_LT_TAGVAR(postdeps, $1) " in+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;+esac+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`+fi+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],+    [The directories searched by this compiler when creating a shared library])+_LT_TAGDECL([], [predep_objects], [1],+    [Dependencies to place before and after the objects being linked to+    create a shared library])+_LT_TAGDECL([], [postdep_objects], [1])+_LT_TAGDECL([], [predeps], [1])+_LT_TAGDECL([], [postdeps], [1])+_LT_TAGDECL([], [compiler_lib_search_path], [1],+    [The library search path used internally by the compiler when linking+    a shared library])+])# _LT_SYS_HIDDEN_LIBDEPS+++# _LT_LANG_F77_CONFIG([TAG])+# --------------------------+# Ensure that the configuration variables for a Fortran 77 compiler are+# suitably defined.  These variables are subsequently used by _LT_CONFIG+# to write the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_F77_CONFIG],+[AC_LANG_PUSH(Fortran 77)+if test -z "$F77" || test no = "$F77"; then+  _lt_disable_F77=yes+fi++_LT_TAGVAR(archive_cmds_need_lc, $1)=no+_LT_TAGVAR(allow_undefined_flag, $1)=+_LT_TAGVAR(always_export_symbols, $1)=no+_LT_TAGVAR(archive_expsym_cmds, $1)=+_LT_TAGVAR(export_dynamic_flag_spec, $1)=+_LT_TAGVAR(hardcode_direct, $1)=no+_LT_TAGVAR(hardcode_direct_absolute, $1)=no+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=+_LT_TAGVAR(hardcode_libdir_separator, $1)=+_LT_TAGVAR(hardcode_minus_L, $1)=no+_LT_TAGVAR(hardcode_automatic, $1)=no+_LT_TAGVAR(inherit_rpath, $1)=no+_LT_TAGVAR(module_cmds, $1)=+_LT_TAGVAR(module_expsym_cmds, $1)=+_LT_TAGVAR(link_all_deplibs, $1)=unknown+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds+_LT_TAGVAR(reload_flag, $1)=$reload_flag+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds+_LT_TAGVAR(no_undefined_flag, $1)=+_LT_TAGVAR(whole_archive_flag_spec, $1)=+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no++# Source file extension for f77 test sources.+ac_ext=f++# Object file extension for compiled f77 test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# No sense in running all these tests if we already determined that+# the F77 compiler isn't working.  Some variables (like enable_shared)+# are currently assumed to apply to all compilers on this platform,+# and will be corrupted by setting them based on a non-working compiler.+if test yes != "$_lt_disable_F77"; then+  # Code to be used in simple compile tests+  lt_simple_compile_test_code="\+      subroutine t+      return+      end+"++  # Code to be used in simple link tests+  lt_simple_link_test_code="\+      program t+      end+"++  # ltmain only uses $CC for tagged configurations so make sure $CC is set.+  _LT_TAG_COMPILER++  # save warnings/boilerplate of simple test code+  _LT_COMPILER_BOILERPLATE+  _LT_LINKER_BOILERPLATE++  # Allow CC to be a program name with arguments.+  lt_save_CC=$CC+  lt_save_GCC=$GCC+  lt_save_CFLAGS=$CFLAGS+  CC=${F77-"f77"}+  CFLAGS=$FFLAGS+  compiler=$CC+  _LT_TAGVAR(compiler, $1)=$CC+  _LT_CC_BASENAME([$compiler])+  GCC=$G77+  if test -n "$compiler"; then+    AC_MSG_CHECKING([if libtool supports shared libraries])+    AC_MSG_RESULT([$can_build_shared])++    AC_MSG_CHECKING([whether to build shared libraries])+    test no = "$can_build_shared" && enable_shared=no++    # On AIX, shared libraries and static libraries use the same namespace, and+    # are all built from PIC.+    case $host_os in+      aix3*)+        test yes = "$enable_shared" && enable_static=no+        if test -n "$RANLIB"; then+          archive_cmds="$archive_cmds~\$RANLIB \$lib"+          postinstall_cmds='$RANLIB $lib'+        fi+        ;;+      aix[[4-9]]*)+	if test ia64 != "$host_cpu"; then+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in+	  yes,aix,yes) ;;		# shared object as lib.so file only+	  yes,svr4,*) ;;		# shared object as lib.so archive member only+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well+	  esac+	fi+        ;;+    esac+    AC_MSG_RESULT([$enable_shared])++    AC_MSG_CHECKING([whether to build static libraries])+    # Make sure either enable_shared or enable_static is yes.+    test yes = "$enable_shared" || enable_static=yes+    AC_MSG_RESULT([$enable_static])++    _LT_TAGVAR(GCC, $1)=$G77+    _LT_TAGVAR(LD, $1)=$LD++    ## CAVEAT EMPTOR:+    ## There is no encapsulation within the following macros, do not change+    ## the running order or otherwise move them around unless you know exactly+    ## what you are doing...+    _LT_COMPILER_PIC($1)+    _LT_COMPILER_C_O($1)+    _LT_COMPILER_FILE_LOCKS($1)+    _LT_LINKER_SHLIBS($1)+    _LT_SYS_DYNAMIC_LINKER($1)+    _LT_LINKER_HARDCODE_LIBPATH($1)++    _LT_CONFIG($1)+  fi # test -n "$compiler"++  GCC=$lt_save_GCC+  CC=$lt_save_CC+  CFLAGS=$lt_save_CFLAGS+fi # test yes != "$_lt_disable_F77"++AC_LANG_POP+])# _LT_LANG_F77_CONFIG+++# _LT_LANG_FC_CONFIG([TAG])+# -------------------------+# Ensure that the configuration variables for a Fortran compiler are+# suitably defined.  These variables are subsequently used by _LT_CONFIG+# to write the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_FC_CONFIG],+[AC_LANG_PUSH(Fortran)++if test -z "$FC" || test no = "$FC"; then+  _lt_disable_FC=yes+fi++_LT_TAGVAR(archive_cmds_need_lc, $1)=no+_LT_TAGVAR(allow_undefined_flag, $1)=+_LT_TAGVAR(always_export_symbols, $1)=no+_LT_TAGVAR(archive_expsym_cmds, $1)=+_LT_TAGVAR(export_dynamic_flag_spec, $1)=+_LT_TAGVAR(hardcode_direct, $1)=no+_LT_TAGVAR(hardcode_direct_absolute, $1)=no+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=+_LT_TAGVAR(hardcode_libdir_separator, $1)=+_LT_TAGVAR(hardcode_minus_L, $1)=no+_LT_TAGVAR(hardcode_automatic, $1)=no+_LT_TAGVAR(inherit_rpath, $1)=no+_LT_TAGVAR(module_cmds, $1)=+_LT_TAGVAR(module_expsym_cmds, $1)=+_LT_TAGVAR(link_all_deplibs, $1)=unknown+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds+_LT_TAGVAR(reload_flag, $1)=$reload_flag+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds+_LT_TAGVAR(no_undefined_flag, $1)=+_LT_TAGVAR(whole_archive_flag_spec, $1)=+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no++# Source file extension for fc test sources.+ac_ext=${ac_fc_srcext-f}++# Object file extension for compiled fc test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# No sense in running all these tests if we already determined that+# the FC compiler isn't working.  Some variables (like enable_shared)+# are currently assumed to apply to all compilers on this platform,+# and will be corrupted by setting them based on a non-working compiler.+if test yes != "$_lt_disable_FC"; then+  # Code to be used in simple compile tests+  lt_simple_compile_test_code="\+      subroutine t+      return+      end+"++  # Code to be used in simple link tests+  lt_simple_link_test_code="\+      program t+      end+"++  # ltmain only uses $CC for tagged configurations so make sure $CC is set.+  _LT_TAG_COMPILER++  # save warnings/boilerplate of simple test code+  _LT_COMPILER_BOILERPLATE+  _LT_LINKER_BOILERPLATE++  # Allow CC to be a program name with arguments.+  lt_save_CC=$CC+  lt_save_GCC=$GCC+  lt_save_CFLAGS=$CFLAGS+  CC=${FC-"f95"}+  CFLAGS=$FCFLAGS+  compiler=$CC+  GCC=$ac_cv_fc_compiler_gnu++  _LT_TAGVAR(compiler, $1)=$CC+  _LT_CC_BASENAME([$compiler])++  if test -n "$compiler"; then+    AC_MSG_CHECKING([if libtool supports shared libraries])+    AC_MSG_RESULT([$can_build_shared])++    AC_MSG_CHECKING([whether to build shared libraries])+    test no = "$can_build_shared" && enable_shared=no++    # On AIX, shared libraries and static libraries use the same namespace, and+    # are all built from PIC.+    case $host_os in+      aix3*)+        test yes = "$enable_shared" && enable_static=no+        if test -n "$RANLIB"; then+          archive_cmds="$archive_cmds~\$RANLIB \$lib"+          postinstall_cmds='$RANLIB $lib'+        fi+        ;;+      aix[[4-9]]*)+	if test ia64 != "$host_cpu"; then+	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in+	  yes,aix,yes) ;;		# shared object as lib.so file only+	  yes,svr4,*) ;;		# shared object as lib.so archive member only+	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well+	  esac+	fi+        ;;+    esac+    AC_MSG_RESULT([$enable_shared])++    AC_MSG_CHECKING([whether to build static libraries])+    # Make sure either enable_shared or enable_static is yes.+    test yes = "$enable_shared" || enable_static=yes+    AC_MSG_RESULT([$enable_static])++    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu+    _LT_TAGVAR(LD, $1)=$LD++    ## CAVEAT EMPTOR:+    ## There is no encapsulation within the following macros, do not change+    ## the running order or otherwise move them around unless you know exactly+    ## what you are doing...+    _LT_SYS_HIDDEN_LIBDEPS($1)+    _LT_COMPILER_PIC($1)+    _LT_COMPILER_C_O($1)+    _LT_COMPILER_FILE_LOCKS($1)+    _LT_LINKER_SHLIBS($1)+    _LT_SYS_DYNAMIC_LINKER($1)+    _LT_LINKER_HARDCODE_LIBPATH($1)++    _LT_CONFIG($1)+  fi # test -n "$compiler"++  GCC=$lt_save_GCC+  CC=$lt_save_CC+  CFLAGS=$lt_save_CFLAGS+fi # test yes != "$_lt_disable_FC"++AC_LANG_POP+])# _LT_LANG_FC_CONFIG+++# _LT_LANG_GCJ_CONFIG([TAG])+# --------------------------+# Ensure that the configuration variables for the GNU Java Compiler compiler+# are suitably defined.  These variables are subsequently used by _LT_CONFIG+# to write the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_GCJ_CONFIG],+[AC_REQUIRE([LT_PROG_GCJ])dnl+AC_LANG_SAVE++# Source file extension for Java test sources.+ac_ext=java++# Object file extension for compiled Java test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# Code to be used in simple compile tests+lt_simple_compile_test_code="class foo {}"++# Code to be used in simple link tests+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'++# ltmain only uses $CC for tagged configurations so make sure $CC is set.+_LT_TAG_COMPILER++# save warnings/boilerplate of simple test code+_LT_COMPILER_BOILERPLATE+_LT_LINKER_BOILERPLATE++# Allow CC to be a program name with arguments.+lt_save_CC=$CC+lt_save_CFLAGS=$CFLAGS+lt_save_GCC=$GCC+GCC=yes+CC=${GCJ-"gcj"}+CFLAGS=$GCJFLAGS+compiler=$CC+_LT_TAGVAR(compiler, $1)=$CC+_LT_TAGVAR(LD, $1)=$LD+_LT_CC_BASENAME([$compiler])++# GCJ did not exist at the time GCC didn't implicitly link libc in.+_LT_TAGVAR(archive_cmds_need_lc, $1)=no++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds+_LT_TAGVAR(reload_flag, $1)=$reload_flag+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds++## CAVEAT EMPTOR:+## There is no encapsulation within the following macros, do not change+## the running order or otherwise move them around unless you know exactly+## what you are doing...+if test -n "$compiler"; then+  _LT_COMPILER_NO_RTTI($1)+  _LT_COMPILER_PIC($1)+  _LT_COMPILER_C_O($1)+  _LT_COMPILER_FILE_LOCKS($1)+  _LT_LINKER_SHLIBS($1)+  _LT_LINKER_HARDCODE_LIBPATH($1)++  _LT_CONFIG($1)+fi++AC_LANG_RESTORE++GCC=$lt_save_GCC+CC=$lt_save_CC+CFLAGS=$lt_save_CFLAGS+])# _LT_LANG_GCJ_CONFIG+++# _LT_LANG_GO_CONFIG([TAG])+# --------------------------+# Ensure that the configuration variables for the GNU Go compiler+# are suitably defined.  These variables are subsequently used by _LT_CONFIG+# to write the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_GO_CONFIG],+[AC_REQUIRE([LT_PROG_GO])dnl+AC_LANG_SAVE++# Source file extension for Go test sources.+ac_ext=go++# Object file extension for compiled Go test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# Code to be used in simple compile tests+lt_simple_compile_test_code="package main; func main() { }"++# Code to be used in simple link tests+lt_simple_link_test_code='package main; func main() { }'++# ltmain only uses $CC for tagged configurations so make sure $CC is set.+_LT_TAG_COMPILER++# save warnings/boilerplate of simple test code+_LT_COMPILER_BOILERPLATE+_LT_LINKER_BOILERPLATE++# Allow CC to be a program name with arguments.+lt_save_CC=$CC+lt_save_CFLAGS=$CFLAGS+lt_save_GCC=$GCC+GCC=yes+CC=${GOC-"gccgo"}+CFLAGS=$GOFLAGS+compiler=$CC+_LT_TAGVAR(compiler, $1)=$CC+_LT_TAGVAR(LD, $1)=$LD+_LT_CC_BASENAME([$compiler])++# Go did not exist at the time GCC didn't implicitly link libc in.+_LT_TAGVAR(archive_cmds_need_lc, $1)=no++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds+_LT_TAGVAR(reload_flag, $1)=$reload_flag+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds++## CAVEAT EMPTOR:+## There is no encapsulation within the following macros, do not change+## the running order or otherwise move them around unless you know exactly+## what you are doing...+if test -n "$compiler"; then+  _LT_COMPILER_NO_RTTI($1)+  _LT_COMPILER_PIC($1)+  _LT_COMPILER_C_O($1)+  _LT_COMPILER_FILE_LOCKS($1)+  _LT_LINKER_SHLIBS($1)+  _LT_LINKER_HARDCODE_LIBPATH($1)++  _LT_CONFIG($1)+fi++AC_LANG_RESTORE++GCC=$lt_save_GCC+CC=$lt_save_CC+CFLAGS=$lt_save_CFLAGS+])# _LT_LANG_GO_CONFIG+++# _LT_LANG_RC_CONFIG([TAG])+# -------------------------+# Ensure that the configuration variables for the Windows resource compiler+# are suitably defined.  These variables are subsequently used by _LT_CONFIG+# to write the compiler configuration to 'libtool'.+m4_defun([_LT_LANG_RC_CONFIG],+[AC_REQUIRE([LT_PROG_RC])dnl+AC_LANG_SAVE++# Source file extension for RC test sources.+ac_ext=rc++# Object file extension for compiled RC test sources.+objext=o+_LT_TAGVAR(objext, $1)=$objext++# Code to be used in simple compile tests+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'++# Code to be used in simple link tests+lt_simple_link_test_code=$lt_simple_compile_test_code++# ltmain only uses $CC for tagged configurations so make sure $CC is set.+_LT_TAG_COMPILER++# save warnings/boilerplate of simple test code+_LT_COMPILER_BOILERPLATE+_LT_LINKER_BOILERPLATE++# Allow CC to be a program name with arguments.+lt_save_CC=$CC+lt_save_CFLAGS=$CFLAGS+lt_save_GCC=$GCC+GCC=+CC=${RC-"windres"}+CFLAGS=+compiler=$CC+_LT_TAGVAR(compiler, $1)=$CC+_LT_CC_BASENAME([$compiler])+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes++if test -n "$compiler"; then+  :+  _LT_CONFIG($1)+fi++GCC=$lt_save_GCC+AC_LANG_RESTORE+CC=$lt_save_CC+CFLAGS=$lt_save_CFLAGS+])# _LT_LANG_RC_CONFIG+++# LT_PROG_GCJ+# -----------+AC_DEFUN([LT_PROG_GCJ],+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],+    [AC_CHECK_TOOL(GCJ, gcj,)+      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"+      AC_SUBST(GCJFLAGS)])])[]dnl+])++# Old name:+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])+++# LT_PROG_GO+# ----------+AC_DEFUN([LT_PROG_GO],+[AC_CHECK_TOOL(GOC, gccgo,)+])+++# LT_PROG_RC+# ----------+AC_DEFUN([LT_PROG_RC],+[AC_CHECK_TOOL(RC, windres,)+])++# Old name:+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([LT_AC_PROG_RC], [])+++# _LT_DECL_EGREP+# --------------+# If we don't have a new enough Autoconf to choose the best grep+# available, choose the one first in the user's PATH.+m4_defun([_LT_DECL_EGREP],+[AC_REQUIRE([AC_PROG_EGREP])dnl+AC_REQUIRE([AC_PROG_FGREP])dnl+test -z "$GREP" && GREP=grep+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])+_LT_DECL([], [EGREP], [1], [An ERE matcher])+_LT_DECL([], [FGREP], [1], [A literal string matcher])+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too+AC_SUBST([GREP])+])+++# _LT_DECL_OBJDUMP+# --------------+# If we don't have a new enough Autoconf to choose the best objdump+# available, choose the one first in the user's PATH.+m4_defun([_LT_DECL_OBJDUMP],+[AC_CHECK_TOOL(OBJDUMP, objdump, false)+test -z "$OBJDUMP" && OBJDUMP=objdump+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])+AC_SUBST([OBJDUMP])+])++# _LT_DECL_DLLTOOL+# ----------------+# Ensure DLLTOOL variable is set.+m4_defun([_LT_DECL_DLLTOOL],+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)+test -z "$DLLTOOL" && DLLTOOL=dlltool+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])+AC_SUBST([DLLTOOL])+])++# _LT_DECL_FILECMD+# ----------------+# Check for a file(cmd) program that can be used to detect file type and magic+m4_defun([_LT_DECL_FILECMD],+[AC_CHECK_PROG([FILECMD], [file], [file], [:])+_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types])+])# _LD_DECL_FILECMD++# _LT_DECL_SED+# ------------+# Check for a fully-functional sed program, that truncates+# as few characters as possible.  Prefer GNU sed if found.+m4_defun([_LT_DECL_SED],+[AC_PROG_SED+test -z "$SED" && SED=sed+Xsed="$SED -e 1s/^X//"+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])+])# _LT_DECL_SED+dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([LT_AC_PROG_SED], [])+++# _LT_CHECK_SHELL_FEATURES+# ------------------------+# Find out whether the shell is Bourne or XSI compatible,+# or has some other useful features.+m4_defun([_LT_CHECK_SHELL_FEATURES],+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then+  lt_unset=unset+else+  lt_unset=false+fi+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl++# test EBCDIC or ASCII+case `echo X|tr X '\101'` in+ A) # ASCII based system+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr+  lt_SP2NL='tr \040 \012'+  lt_NL2SP='tr \015\012 \040\040'+  ;;+ *) # EBCDIC based system+  lt_SP2NL='tr \100 \n'+  lt_NL2SP='tr \r\n \100\100'+  ;;+esac+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl+])# _LT_CHECK_SHELL_FEATURES+++# _LT_PATH_CONVERSION_FUNCTIONS+# -----------------------------+# Determine what file name conversion functions should be used by+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed+# for certain cross-compile configurations and native mingw.+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+AC_REQUIRE([AC_CANONICAL_BUILD])dnl+AC_MSG_CHECKING([how to convert $build file names to $host format])+AC_CACHE_VAL(lt_cv_to_host_file_cmd,+[case $host in+  *-*-mingw* )+    case $build in+      *-*-mingw* | *-*-windows* ) # actually msys+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32+        ;;+      *-*-cygwin* )+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32+        ;;+      * ) # otherwise, assume *nix+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32+        ;;+    esac+    ;;+  *-*-cygwin* )+    case $build in+      *-*-mingw* | *-*-windows* ) # actually msys+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin+        ;;+      *-*-cygwin* )+        lt_cv_to_host_file_cmd=func_convert_file_noop+        ;;+      * ) # otherwise, assume *nix+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin+        ;;+    esac+    ;;+  * ) # unhandled hosts (and "normal" native builds)+    lt_cv_to_host_file_cmd=func_convert_file_noop+    ;;+esac+])+to_host_file_cmd=$lt_cv_to_host_file_cmd+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],+         [0], [convert $build file names to $host format])dnl++AC_MSG_CHECKING([how to convert $build file names to toolchain format])+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,+[#assume ordinary cross tools, or native build.+lt_cv_to_tool_file_cmd=func_convert_file_noop+case $host in+  *-*-mingw* | *-*-windows* )+    case $build in+      *-*-mingw* | *-*-windows* ) # actually msys+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32+        ;;+    esac+    ;;+esac+])+to_tool_file_cmd=$lt_cv_to_tool_file_cmd+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],+         [0], [convert $build files to toolchain format])dnl+])# _LT_PATH_CONVERSION_FUNCTIONS
+ m4/lt_undescore.m4 view
@@ -0,0 +1,38 @@+# LT_SYS_SYMBOL_USCORE+# --------------------+# does the compiler prefix global symbols with an underscore?+AC_DEFUN([LT_SYS_SYMBOL_USCORE],+[m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl+AC_CACHE_CHECK([for _ prefix in compiled symbols],+  [lt_cv_sys_symbol_underscore],+  [lt_cv_sys_symbol_underscore=no+  cat > conftest.$ac_ext <<_LT_EOF+void nm_test_func(){}+int main(void){nm_test_func;return 0;}+_LT_EOF+  if AC_TRY_EVAL(ac_compile); then+    # Now try to grab the symbols.+    ac_nlist=conftest.nm+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then+      # See whether the symbols have a leading underscore.+      if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then+        lt_cv_sys_symbol_underscore=yes+      else+        if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then+	  :+        else+	  echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD+        fi+      fi+    else+      echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD+    fi+  else+    echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD+    cat conftest.c >&AS_MESSAGE_LOG_FD+  fi+  rm -rf conftest*+  ])+  sys_symbol_underscore=$lt_cv_sys_symbol_underscore+  AC_SUBST([sys_symbol_underscore])+])# LT_SYS_SYMBOL_USCORE
+ m4/ltoptions.m4 view
@@ -0,0 +1,467 @@+# Helper functions for option handling.                    -*- Autoconf -*-+#+#   Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2024 Free+#   Software Foundation, Inc.+#   Written by Gary V. Vaughan, 2004+#+# This file is free software; the Free Software Foundation gives+# unlimited permission to copy and/or distribute it, with or without+# modifications, as long as this notice is preserved.++# serial 10 ltoptions.m4++# This is to help aclocal find these macros, as it can't see m4_define.+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])+++# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)+# ------------------------------------------+m4_define([_LT_MANGLE_OPTION],+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])+++# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)+# ---------------------------------------+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are+# saved as a flag.+m4_define([_LT_SET_OPTION],+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),+        _LT_MANGLE_DEFUN([$1], [$2]),+    [m4_warning([Unknown $1 option '$2'])])[]dnl+])+++# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])+# ------------------------------------------------------------+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.+m4_define([_LT_IF_OPTION],+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])+++# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)+# -------------------------------------------------------+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME+# are set.+m4_define([_LT_UNLESS_OPTIONS],+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),+		      [m4_define([$0_found])])])[]dnl+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3+])[]dnl+])+++# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)+# ----------------------------------------+# OPTION-LIST is a space-separated list of Libtool options associated+# with MACRO-NAME.  If any OPTION has a matching handler declared with+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about+# the unknown option and exit.+m4_defun([_LT_SET_OPTIONS],+[# Set options+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),+    [_LT_SET_OPTION([$1], _LT_Option)])++m4_if([$1],[LT_INIT],[+  dnl+  dnl Simply set some default values (i.e off) if boolean options were not+  dnl specified:+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no+  ])+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no+  ])+  dnl+  dnl If no reference was made to various pairs of opposing options, then+  dnl we run the default mode handler for the pair.  For example, if neither+  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared+  dnl archives by default:+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],+		   [_LT_ENABLE_FAST_INSTALL])+  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],+		   [_LT_WITH_AIX_SONAME([aix])])+  ])+])# _LT_SET_OPTIONS+++## --------------------------------- ##+## Macros to handle LT_INIT options. ##+## --------------------------------- ##++# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)+# -----------------------------------------+m4_define([_LT_MANGLE_DEFUN],+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])+++# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)+# -----------------------------------------------+m4_define([LT_OPTION_DEFINE],+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl+])# LT_OPTION_DEFINE+++# dlopen+# ------+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes+])++AU_DEFUN([AC_LIBTOOL_DLOPEN],+[_LT_SET_OPTION([LT_INIT], [dlopen])+AC_DIAGNOSE([obsolete],+[$0: Remove this warning and the call to _LT_SET_OPTION when you+put the 'dlopen' option into LT_INIT's first parameter.])+])++dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])+++# win32-dll+# ---------+# Declare package support for building win32 dll's.+LT_OPTION_DEFINE([LT_INIT], [win32-dll],+[enable_win32_dll=yes++case $host in+*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*)+  AC_CHECK_TOOL(AS, as, false)+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)+  AC_CHECK_TOOL(OBJDUMP, objdump, false)+  ;;+esac++test -z "$AS" && AS=as+_LT_DECL([], [AS],      [1], [Assembler program])dnl++test -z "$DLLTOOL" && DLLTOOL=dlltool+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl++test -z "$OBJDUMP" && OBJDUMP=objdump+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl+])# win32-dll++AU_DEFUN([AC_LIBTOOL_WIN32_DLL],+[AC_REQUIRE([AC_CANONICAL_HOST])dnl+_LT_SET_OPTION([LT_INIT], [win32-dll])+AC_DIAGNOSE([obsolete],+[$0: Remove this warning and the call to _LT_SET_OPTION when you+put the 'win32-dll' option into LT_INIT's first parameter.])+])++dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])+++# _LT_ENABLE_SHARED([DEFAULT])+# ----------------------------+# implement the --enable-shared flag, and supports the 'shared' and+# 'disable-shared' LT_INIT options.+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.+m4_define([_LT_ENABLE_SHARED],+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl+AC_ARG_ENABLE([shared],+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],+    [p=${PACKAGE-default}+    case $enableval in+    yes) enable_shared=yes ;;+    no) enable_shared=no ;;+    *)+      enable_shared=no+      # Look at the argument we got.  We use all the common list separators.+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+      for pkg in $enableval; do+	IFS=$lt_save_ifs+	if test "X$pkg" = "X$p"; then+	  enable_shared=yes+	fi+      done+      IFS=$lt_save_ifs+      ;;+    esac],+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)++    _LT_DECL([build_libtool_libs], [enable_shared], [0],+	[Whether or not to build shared libraries])+])# _LT_ENABLE_SHARED++LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])++# Old names:+AC_DEFUN([AC_ENABLE_SHARED],+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])+])++AC_DEFUN([AC_DISABLE_SHARED],+[_LT_SET_OPTION([LT_INIT], [disable-shared])+])++AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])++dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AM_ENABLE_SHARED], [])+dnl AC_DEFUN([AM_DISABLE_SHARED], [])++++# _LT_ENABLE_STATIC([DEFAULT])+# ----------------------------+# implement the --enable-static flag, and support the 'static' and+# 'disable-static' LT_INIT options.+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.+m4_define([_LT_ENABLE_STATIC],+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl+AC_ARG_ENABLE([static],+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],+    [p=${PACKAGE-default}+    case $enableval in+    yes) enable_static=yes ;;+    no) enable_static=no ;;+    *)+     enable_static=no+      # Look at the argument we got.  We use all the common list separators.+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+      for pkg in $enableval; do+	IFS=$lt_save_ifs+	if test "X$pkg" = "X$p"; then+	  enable_static=yes+	fi+      done+      IFS=$lt_save_ifs+      ;;+    esac],+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)++    _LT_DECL([build_old_libs], [enable_static], [0],+	[Whether or not to build static libraries])+])# _LT_ENABLE_STATIC++LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])++# Old names:+AC_DEFUN([AC_ENABLE_STATIC],+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])+])++AC_DEFUN([AC_DISABLE_STATIC],+[_LT_SET_OPTION([LT_INIT], [disable-static])+])++AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])++dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AM_ENABLE_STATIC], [])+dnl AC_DEFUN([AM_DISABLE_STATIC], [])++++# _LT_ENABLE_FAST_INSTALL([DEFAULT])+# ----------------------------------+# implement the --enable-fast-install flag, and support the 'fast-install'+# and 'disable-fast-install' LT_INIT options.+# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.+m4_define([_LT_ENABLE_FAST_INSTALL],+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl+AC_ARG_ENABLE([fast-install],+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],+    [p=${PACKAGE-default}+    case $enableval in+    yes) enable_fast_install=yes ;;+    no) enable_fast_install=no ;;+    *)+      enable_fast_install=no+      # Look at the argument we got.  We use all the common list separators.+      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+      for pkg in $enableval; do+	IFS=$lt_save_ifs+	if test "X$pkg" = "X$p"; then+	  enable_fast_install=yes+	fi+      done+      IFS=$lt_save_ifs+      ;;+    esac],+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)++_LT_DECL([fast_install], [enable_fast_install], [0],+	 [Whether or not to optimize for fast installation])dnl+])# _LT_ENABLE_FAST_INSTALL++LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])++# Old names:+AU_DEFUN([AC_ENABLE_FAST_INSTALL],+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])+AC_DIAGNOSE([obsolete],+[$0: Remove this warning and the call to _LT_SET_OPTION when you put+the 'fast-install' option into LT_INIT's first parameter.])+])++AU_DEFUN([AC_DISABLE_FAST_INSTALL],+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])+AC_DIAGNOSE([obsolete],+[$0: Remove this warning and the call to _LT_SET_OPTION when you put+the 'disable-fast-install' option into LT_INIT's first parameter.])+])++dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])+++# _LT_WITH_AIX_SONAME([DEFAULT])+# ----------------------------------+# implement the --enable-aix-soname configure option, and support the+# `aix-soname=aix' and `aix-soname=both' and `aix-soname=svr4' LT_INIT options.+# DEFAULT is either `aix', `both', or `svr4'.  If omitted, it defaults to `aix'.+m4_define([_LT_WITH_AIX_SONAME],+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl+shared_archive_member_spec=+case $host,$enable_shared in+power*-*-aix[[5-9]]*,yes)+  AC_MSG_CHECKING([which variant of shared library versioning to provide])+  AC_ARG_ENABLE([aix-soname],+    [AS_HELP_STRING([--enable-aix-soname=aix|svr4|both],+      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],+    [case $enableval in+     aix|svr4|both)+       ;;+     *)+       AC_MSG_ERROR([Unknown argument to --enable-aix-soname])+       ;;+     esac+     lt_cv_with_aix_soname=$enable_aix_soname],+    [_AC_ENABLE_IF([with], [aix-soname],+        [case $withval in+         aix|svr4|both)+           ;;+         *)+           AC_MSG_ERROR([Unknown argument to --with-aix-soname])+           ;;+         esac+         lt_cv_with_aix_soname=$with_aix_soname],+        [AC_CACHE_VAL([lt_cv_with_aix_soname],+           [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)])+     enable_aix_soname=$lt_cv_with_aix_soname])+  with_aix_soname=$enable_aix_soname+  AC_MSG_RESULT([$with_aix_soname])+  if test aix != "$with_aix_soname"; then+    # For the AIX way of multilib, we name the shared archive member+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,+    # the AIX toolchain works better with OBJECT_MODE set (default 32).+    if test 64 = "${OBJECT_MODE-32}"; then+      shared_archive_member_spec=shr_64+    else+      shared_archive_member_spec=shr+    fi+  fi+  ;;+*)+  with_aix_soname=aix+  ;;+esac++_LT_DECL([], [shared_archive_member_spec], [0],+    [Shared archive member basename, for filename based shared library versioning on AIX])dnl+])# _LT_WITH_AIX_SONAME++LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])+++# _LT_WITH_PIC([MODE])+# --------------------+# implement the --enable-pic flag, and support the 'pic-only' and 'no-pic'+# LT_INIT options.+# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.+m4_define([_LT_WITH_PIC],+[AC_ARG_ENABLE([pic],+    [AS_HELP_STRING([--enable-pic@<:@=PKGS@:>@],+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],+    [lt_p=${PACKAGE-default}+     case $enableval in+     yes|no) pic_mode=$enableval ;;+     *)+       pic_mode=default+       # Look at the argument we got.  We use all the common list separators.+       lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+       for lt_pkg in $enableval; do+	 IFS=$lt_save_ifs+	 if test "X$lt_pkg" = "X$lt_p"; then+	   pic_mode=yes+	 fi+       done+       IFS=$lt_save_ifs+       ;;+     esac],+    [dnl Continue to support --with-pic and --without-pic, for backward+     dnl compatibility.+     _AC_ENABLE_IF([with], [pic],+	[lt_p=${PACKAGE-default}+	 case $withval in+	 yes|no) pic_mode=$withval ;;+	 *)+	   pic_mode=default+	   # Look at the argument we got.  We use all the common list separators.+	   lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,+	   for lt_pkg in $withval; do+	     IFS=$lt_save_ifs+	     if test "X$lt_pkg" = "X$lt_p"; then+	       pic_mode=yes+	     fi+	   done+	   IFS=$lt_save_ifs+	   ;;+	 esac],+	[pic_mode=m4_default([$1], [default])])]+    )++_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl+])# _LT_WITH_PIC++LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])++# Old name:+AU_DEFUN([AC_LIBTOOL_PICMODE],+[_LT_SET_OPTION([LT_INIT], [pic-only])+AC_DIAGNOSE([obsolete],+[$0: Remove this warning and the call to _LT_SET_OPTION when you+put the 'pic-only' option into LT_INIT's first parameter.])+])++dnl aclocal-1.4 backwards compatibility:+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])++## ----------------- ##+## LTDL_INIT Options ##+## ----------------- ##++m4_define([_LTDL_MODE], [])+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],+		 [m4_define([_LTDL_MODE], [nonrecursive])])+LT_OPTION_DEFINE([LTDL_INIT], [recursive],+		 [m4_define([_LTDL_MODE], [recursive])])+LT_OPTION_DEFINE([LTDL_INIT], [subproject],+		 [m4_define([_LTDL_MODE], [subproject])])++m4_define([_LTDL_TYPE], [])+LT_OPTION_DEFINE([LTDL_INIT], [installable],+		 [m4_define([_LTDL_TYPE], [installable])])+LT_OPTION_DEFINE([LTDL_INIT], [convenience],+		 [m4_define([_LTDL_TYPE], [convenience])])
+ m4/ltsugar.m4 view
@@ -0,0 +1,124 @@+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-+#+# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2024 Free Software+# Foundation, Inc.+# Written by Gary V. Vaughan, 2004+#+# This file is free software; the Free Software Foundation gives+# unlimited permission to copy and/or distribute it, with or without+# modifications, as long as this notice is preserved.++# serial 6 ltsugar.m4++# This is to help aclocal find these macros, as it can't see m4_define.+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])+++# lt_join(SEP, ARG1, [ARG2...])+# -----------------------------+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their+# associated separator.+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier+# versions in m4sugar had bugs.+m4_define([lt_join],+[m4_if([$#], [1], [],+       [$#], [2], [[$2]],+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])+m4_define([_lt_join],+[m4_if([$#$2], [2], [],+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])+++# lt_car(LIST)+# lt_cdr(LIST)+# ------------+# Manipulate m4 lists.+# These macros are necessary as long as will still need to support+# Autoconf-2.59, which quotes differently.+m4_define([lt_car], [[$1]])+m4_define([lt_cdr],+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],+       [$#], 1, [],+       [m4_dquote(m4_shift($@))])])+m4_define([lt_unquote], $1)+++# lt_append(MACRO-NAME, STRING, [SEPARATOR])+# ------------------------------------------+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.+# Note that neither SEPARATOR nor STRING are expanded; they are appended+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).+# No SEPARATOR is output if MACRO-NAME was previously undefined (different+# than defined and empty).+#+# This macro is needed until we can rely on Autoconf 2.62, since earlier+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.+m4_define([lt_append],+[m4_define([$1],+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])++++# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])+# ----------------------------------------------------------+# Produce a SEP delimited list of all paired combinations of elements of+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list+# has the form PREFIXmINFIXSUFFIXn.+# Needed until we can rely on m4_combine added in Autoconf 2.62.+m4_define([lt_combine],+[m4_if(m4_eval([$# > 3]), [1],+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl+[[m4_foreach([_Lt_prefix], [$2],+	     [m4_foreach([_Lt_suffix],+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])+++# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])+# -----------------------------------------------------------------------+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.+m4_define([lt_if_append_uniq],+[m4_ifdef([$1],+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],+		 [lt_append([$1], [$2], [$3])$4],+		 [$5])],+	  [lt_append([$1], [$2], [$3])$4])])+++# lt_dict_add(DICT, KEY, VALUE)+# -----------------------------+m4_define([lt_dict_add],+[m4_define([$1($2)], [$3])])+++# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)+# --------------------------------------------+m4_define([lt_dict_add_subkey],+[m4_define([$1($2:$3)], [$4])])+++# lt_dict_fetch(DICT, KEY, [SUBKEY])+# ----------------------------------+m4_define([lt_dict_fetch],+[m4_ifval([$3],+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])+++# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])+# -----------------------------------------------------------------+m4_define([lt_if_dict_fetch],+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],+	[$5],+    [$6])])+++# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])+# --------------------------------------------------------------+m4_define([lt_dict_filter],+[m4_if([$5], [], [],+  [lt_join(m4_quote(m4_default([$4], [[, ]])),+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl+])
+ m4/ltversion.m4 view
@@ -0,0 +1,24 @@+# ltversion.m4 -- version numbers			-*- Autoconf -*-+#+#   Copyright (C) 2004, 2011-2019, 2021-2024 Free Software Foundation,+#   Inc.+#   Written by Scott James Remnant, 2004+#+# This file is free software; the Free Software Foundation gives+# unlimited permission to copy and/or distribute it, with or without+# modifications, as long as this notice is preserved.++# @configure_input@++# serial 4441 ltversion.m4+# This file is part of GNU Libtool++m4_define([LT_PACKAGE_VERSION], [2.5.4])+m4_define([LT_PACKAGE_REVISION], [2.5.4])++AC_DEFUN([LTVERSION_VERSION],+[macro_version='2.5.4'+macro_revision='2.5.4'+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])+_LT_DECL(, macro_revision, 0)+])
+ m4/lt~obsolete.m4 view
@@ -0,0 +1,99 @@+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-+#+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2024 Free+#   Software Foundation, Inc.+#   Written by Scott James Remnant, 2004.+#+# This file is free software; the Free Software Foundation gives+# unlimited permission to copy and/or distribute it, with or without+# modifications, as long as this notice is preserved.++# serial 5 lt~obsolete.m4++# These exist entirely to fool aclocal when bootstrapping libtool.+#+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),+# which have later been changed to m4_define as they aren't part of the+# exported API, or moved to Autoconf or Automake where they belong.+#+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us+# using a macro with the same name in our local m4/libtool.m4 it'll+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define+# and doesn't know about Autoconf macros at all.)+#+# So we provide this file, which has a silly filename so it's always+# included after everything else.  This provides aclocal with the+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything+# because those macros already exist, or will be overwritten later.+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.+#+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.+# Yes, that means every name once taken will need to remain here until+# we give up compatibility with versions before 1.7, at which point+# we need to keep only those names which we still refer to.++# This is to help aclocal find these macros, as it can't see m4_define.+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])++m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
+ src/aarch64/ffi.c view
@@ -0,0 +1,1145 @@+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#if defined(__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)+#include <stdio.h>+#include <stdlib.h>+#include <stdint.h>+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_common.h>+#include "internal.h"+#ifdef _WIN32+#include <windows.h> /* FlushInstructionCache */+#endif+#include <tramp.h>++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;+   all further uses in this file will refer to the 128-bit type.  */+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE+# if FFI_TYPE_LONGDOUBLE != 4+#  error FFI_TYPE_LONGDOUBLE out of date+# endif+#else+# undef FFI_TYPE_LONGDOUBLE+# define FFI_TYPE_LONGDOUBLE 4+#endif++union _d+{+  UINT64 d;+  UINT32 s[2];+};++struct _v+{+  union _d d[2] __attribute__((aligned(16)));+};++struct call_context+{+  struct _v v[N_V_ARG_REG];+  UINT64 x[N_X_ARG_REG];+};++#if FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__+#ifdef HAVE_ARM64E_PTRAUTH+#include <ptrauth.h>+#endif+#include <mach/vm_param.h>+#endif++#else++#if defined (__clang__) && defined (__APPLE__)+extern void sys_icache_invalidate (void *start, size_t len);+#endif++static inline void+ffi_clear_cache (void *start, void *end)+{+#if defined (__clang__) && defined (__APPLE__)+  sys_icache_invalidate (start, (char *)end - (char *)start);+#elif defined (__GNUC__)+  __builtin___clear_cache (start, end);+#elif defined (_WIN32)+  FlushInstructionCache(GetCurrentProcess(), start, (char*)end - (char*)start);+#else+#error "Missing builtin to flush instruction cache"+#endif+}++#endif++/* A subroutine of is_vfp_type.  Given a structure type, return the type code+   of the first non-structure element.  Recurse for structure elements.+   Return -1 if the structure is in fact empty, i.e. no nested elements.  */++static int+is_hfa0 (const ffi_type *ty)+{+  ffi_type **elements = ty->elements;+  int i, ret = -1;++  if (elements != NULL)+    for (i = 0; elements[i]; ++i)+      {+        ret = elements[i]->type;+        if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)+          {+            ret = is_hfa0 (elements[i]);+            if (ret < 0)+              continue;+          }+        break;+      }++  return ret;+}++/* A subroutine of is_vfp_type.  Given a structure type, return true if all+   of the non-structure elements are the same as CANDIDATE.  */++static int+is_hfa1 (const ffi_type *ty, int candidate)+{+  ffi_type **elements = ty->elements;+  int i;++  if (elements != NULL)+    for (i = 0; elements[i]; ++i)+      {+        int t = elements[i]->type;+        if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)+          {+            if (!is_hfa1 (elements[i], candidate))+              return 0;+          }+        else if (t != candidate)+          return 0;+      }++  return 1;+}++/* Determine if TY may be allocated to the FP registers.  This is both an+   fp scalar type as well as an homogenous floating point aggregate (HFA).+   That is, a structure consisting of 1 to 4 members of all the same type,+   where that type is an fp scalar.++   Returns non-zero iff TY is an HFA.  The result is the AARCH64_RET_*+   constant for the type.  */++static int+is_vfp_type (const ffi_type *ty)+{+  ffi_type **elements;+  int candidate, i;+  size_t size, ele_count;++  /* Quickest tests first.  */+  candidate = ty->type;+  switch (candidate)+    {+    default:+      return 0;+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_LONGDOUBLE:+      ele_count = 1;+      goto done;+    case FFI_TYPE_COMPLEX:+      candidate = ty->elements[0]->type;+      switch (candidate)+	{+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	  ele_count = 2;+	  goto done;+	}+      return 0;+    case FFI_TYPE_STRUCT:+      break;+    }++  /* No HFA types are smaller than 4 bytes, or larger than 64 bytes.  */+  size = ty->size;+  if (size < 4 || size > 64)+    return 0;++  /* Find the type of the first non-structure member.  */+  elements = ty->elements;+  candidate = elements[0]->type;+  if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)+    {+      for (i = 0; ; ++i)+        {+          candidate = is_hfa0 (elements[i]);+          if (candidate >= 0)+            break;+        }+    }++  /* If the first member is not a floating point type, it's not an HFA.+     Also quickly re-check the size of the structure.  */+  switch (candidate)+    {+    case FFI_TYPE_FLOAT:+      ele_count = size / sizeof(float);+      if (size != ele_count * sizeof(float))+        return 0;+      break;+    case FFI_TYPE_DOUBLE:+      ele_count = size / sizeof(double);+      if (size != ele_count * sizeof(double))+        return 0;+      break;+    case FFI_TYPE_LONGDOUBLE:+      ele_count = size / sizeof(long double);+      if (size != ele_count * sizeof(long double))+        return 0;+      break;+    default:+      return 0;+    }+  if (ele_count > 4)+    return 0;++  /* Finally, make sure that all scalar elements are the same type.  */+  for (i = 0; elements[i]; ++i)+    {+      int t = elements[i]->type;+      if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)+        {+          if (!is_hfa1 (elements[i], candidate))+            return 0;+        }+      else if (t != candidate)+        return 0;+    }++  /* All tests succeeded.  Encode the result.  */+ done:+  return candidate * 4 + (4 - (int)ele_count);+}++/* Representation of the procedure call argument marshalling+   state.++   The terse state variable names match the names used in the AARCH64+   PCS.++   The struct area is allocated downwards from the top of the argument+   area.  It is used to hold copies of structures passed by value that are+   bigger than 16 bytes.  */++struct arg_state+{+  unsigned ngrn;                /* Next general-purpose register number. */+  unsigned nsrn;                /* Next vector register number. */+  size_t nsaa;                  /* Next stack offset. */+  size_t next_struct_area;	/* Place to allocate big structs. */++#if defined (__APPLE__)+  unsigned allocating_variadic;+#endif+};++/* Initialize a procedure call argument marshalling state.  */+static void+arg_init (struct arg_state *state, size_t size)+{+  state->ngrn = 0;+  state->nsrn = 0;+  state->nsaa = 0;+  state->next_struct_area = size;+#if defined (__APPLE__)+  state->allocating_variadic = 0;+#endif+}++/* Allocate an aligned slot on the stack and return a pointer to it.  */+static void *+allocate_to_stack (struct arg_state *state, void *stack,+		   size_t alignment, size_t size)+{+  size_t nsaa = state->nsaa;++  /* Round up the NSAA to the larger of 8 or the natural+     alignment of the argument's type.  */+#if defined (__APPLE__)+  if (state->allocating_variadic && alignment < 8)+    alignment = 8;+#else+  if (alignment < 8)+    alignment = 8;+#endif++  nsaa = FFI_ALIGN (nsaa, alignment);+  state->nsaa = nsaa + size;++  return (char *)stack + nsaa;+}++/* Allocate and copy a structure that is passed by value on the stack and+   return a pointer to it.  */+static void *+allocate_and_copy_struct_to_stack (struct arg_state *state, void *stack,+				   size_t alignment, size_t size, void *value)+{+  size_t dest = state->next_struct_area - size;++  /* Round down to the natural alignment of the value.  */+  dest = FFI_ALIGN_DOWN (dest, alignment);+  state->next_struct_area = dest;++  return memcpy ((char *) stack + dest, value, size);+}++static ffi_arg+extend_integer_type (void *source, int type)+{+  switch (type)+    {+    case FFI_TYPE_UINT8:+      {+        UINT8 u8;+        memcpy (&u8, source, sizeof (u8));+        return u8;+      }+    case FFI_TYPE_SINT8:+      {+        SINT8 s8;+        memcpy (&s8, source, sizeof (s8));+        return s8;+      }+    case FFI_TYPE_UINT16:+      {+        UINT16 u16;+        memcpy (&u16, source, sizeof (u16));+        return u16;+      }+    case FFI_TYPE_SINT16:+      {+        SINT16 s16;+        memcpy (&s16, source, sizeof (s16));+        return s16;+      }+    case FFI_TYPE_UINT32:+      {+        UINT32 u32;+        memcpy (&u32, source, sizeof (u32));+        return u32;+      }+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+      {+        SINT32 s32;+        memcpy (&s32, source, sizeof (s32));+        return s32;+      }+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      {+        UINT64 u64;+        memcpy (&u64, source, sizeof (u64));+        return u64;+      }+    case FFI_TYPE_POINTER:+      {+        uintptr_t uptr;+        memcpy (&uptr, source, sizeof (uptr));+        return uptr;+      }+    default:+      abort();+    }+}++#if defined(_MSC_VER)+void extend_hfa_type (void *dest, void *src, int h);+#else+static void+extend_hfa_type (void *dest, void *src, int h)+{+  ssize_t f = h - AARCH64_RET_S4;+  void *x0;++#define BTI_J "hint #36"+  asm volatile (+	"adr	%0, 0f\n"+"	add	%0, %0, %1\n"+"	br	%0\n"+"0:	"BTI_J"\n"			/* S4 */+"	ldp	s16, s17, [%3]\n"+"	ldp	s18, s19, [%3, #8]\n"+"	b	4f\n"+"	"BTI_J"\n"			/* S3 */+"	ldp	s16, s17, [%3]\n"+"	ldr	s18, [%3, #8]\n"+"	b	3f\n"+"	"BTI_J"\n"			/* S2 */+"	ldp	s16, s17, [%3]\n"+"	b	2f\n"+"	nop\n"+"	"BTI_J"\n"			/* S1 */+"	ldr	s16, [%3]\n"+"	b	1f\n"+"	nop\n"+"	"BTI_J"\n"			/* D4 */+"	ldp	d16, d17, [%3]\n"+"	ldp	d18, d19, [%3, #16]\n"+"	b	4f\n"+"	"BTI_J"\n"			/* D3 */+"	ldp	d16, d17, [%3]\n"+"	ldr	d18, [%3, #16]\n"+"	b	3f\n"+"	"BTI_J"\n"			/* D2 */+"	ldp	d16, d17, [%3]\n"+"	b	2f\n"+"	nop\n"+"	"BTI_J"\n"			/* D1 */+"	ldr	d16, [%3]\n"+"	b	1f\n"+"	nop\n"+"	"BTI_J"\n"			/* Q4 */+"	ldp	q16, q17, [%3]\n"+"	ldp	q18, q19, [%3, #32]\n"+"	b	4f\n"+"	"BTI_J"\n"			/* Q3 */+"	ldp	q16, q17, [%3]\n"+"	ldr	q18, [%3, #32]\n"+"	b	3f\n"+"	"BTI_J"\n"			/* Q2 */+"	ldp	q16, q17, [%3]\n"+"	b	2f\n"+"	nop\n"+"	"BTI_J"\n"			/* Q1 */+"	ldr	q16, [%3]\n"+"	b	1f\n"+"4:	str	q19, [%2, #48]\n"+"3:	str	q18, [%2, #32]\n"+"2:	str	q17, [%2, #16]\n"+"1:	str	q16, [%2]"+    : "=&r"(x0)+    : "r"(f * 16), "r"(dest), "r"(src)+    : "memory", "v16", "v17", "v18", "v19");+}+#endif++#if defined(_MSC_VER)+void* compress_hfa_type (void *dest, void *src, int h);+#else+static void *+compress_hfa_type (void *dest, void *reg, int h)+{+  switch (h)+    {+    case AARCH64_RET_S1:+      if (dest == reg)+	{+#ifdef __AARCH64EB__+	  dest += 12;+#endif+	}+      else+	*(float *)dest = *(float *)reg;+      break;+    case AARCH64_RET_S2:+      asm ("ldp q16, q17, [%1]\n\t"+	   "st2 { v16.s, v17.s }[0], [%0]"+	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17");+      break;+    case AARCH64_RET_S3:+      asm ("ldp q16, q17, [%1]\n\t"+	   "ldr q18, [%1, #32]\n\t"+	   "st3 { v16.s, v17.s, v18.s }[0], [%0]"+	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18");+      break;+    case AARCH64_RET_S4:+      asm ("ldp q16, q17, [%1]\n\t"+	   "ldp q18, q19, [%1, #32]\n\t"+	   "st4 { v16.s, v17.s, v18.s, v19.s }[0], [%0]"+	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19");+      break;++    case AARCH64_RET_D1:+      if (dest == reg)+	{+#ifdef __AARCH64EB__+	  dest += 8;+#endif+	}+      else+	*(double *)dest = *(double *)reg;+      break;+    case AARCH64_RET_D2:+      asm ("ldp q16, q17, [%1]\n\t"+	   "st2 { v16.d, v17.d }[0], [%0]"+	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17");+      break;+    case AARCH64_RET_D3:+      asm ("ldp q16, q17, [%1]\n\t"+	   "ldr q18, [%1, #32]\n\t"+	   "st3 { v16.d, v17.d, v18.d }[0], [%0]"+	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18");+      break;+    case AARCH64_RET_D4:+      asm ("ldp q16, q17, [%1]\n\t"+	   "ldp q18, q19, [%1, #32]\n\t"+	   "st4 { v16.d, v17.d, v18.d, v19.d }[0], [%0]"+	   : : "r"(dest), "r"(reg) : "memory", "v16", "v17", "v18", "v19");+      break;++    default:+      if (dest != reg)+	return memcpy (dest, reg, 16 * (4 - (h & 3)));+      break;+    }+  return dest;+}+#endif++/* Either allocate an appropriate register for the argument type, or if+   none are available, allocate a stack slot and return a pointer+   to the allocated space.  */++static void *+allocate_int_to_reg_or_stack (struct call_context *context,+			      struct arg_state *state,+			      void *stack, size_t size)+{+  if (state->ngrn < N_X_ARG_REG)+    return &context->x[state->ngrn++];++  state->ngrn = N_X_ARG_REG;+  return allocate_to_stack (state, stack, size, size);+}++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep (ffi_cif *cif)+{+  ffi_type *rtype = cif->rtype;+  size_t bytes = cif->bytes;+  int flags, i, n;++  switch (rtype->type)+    {+    case FFI_TYPE_VOID:+      flags = AARCH64_RET_VOID;+      break;+    case FFI_TYPE_UINT8:+      flags = AARCH64_RET_UINT8;+      break;+    case FFI_TYPE_UINT16:+      flags = AARCH64_RET_UINT16;+      break;+    case FFI_TYPE_UINT32:+      flags = AARCH64_RET_UINT32;+      break;+    case FFI_TYPE_SINT8:+      flags = AARCH64_RET_SINT8;+      break;+    case FFI_TYPE_SINT16:+      flags = AARCH64_RET_SINT16;+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+      flags = AARCH64_RET_SINT32;+      break;+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      flags = AARCH64_RET_INT64;+      break;+    case FFI_TYPE_POINTER:+      flags = (sizeof(void *) == 4 ? AARCH64_RET_UINT32 : AARCH64_RET_INT64);+      break;++    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_LONGDOUBLE:+    case FFI_TYPE_STRUCT:+    case FFI_TYPE_COMPLEX:+      flags = is_vfp_type (rtype);+      if (flags == 0)+	{+	  size_t s = rtype->size;+	  if (s > 16)+	    {+	      flags = AARCH64_RET_VOID | AARCH64_RET_IN_MEM;+	      bytes += 8;+	    }+	  else if (s == 16)+	    flags = AARCH64_RET_INT128;+	  else if (s == 8)+	    flags = AARCH64_RET_INT64;+	  else+	    flags = AARCH64_RET_INT128 | AARCH64_RET_NEED_COPY;+	}+      break;++    default:+      abort();+    }++  for (i = 0, n = cif->nargs; i < n; i++)+    if (is_vfp_type (cif->arg_types[i]))+      {+	flags |= AARCH64_FLAG_ARG_V;+	break;+      }++  /* Round the stack up to a multiple of the stack alignment requirement. */+  cif->bytes = (unsigned) FFI_ALIGN(bytes, 16);+  cif->flags = flags;+#if defined (__APPLE__)+  cif->aarch64_nfixedargs = 0;+#endif++  return FFI_OK;+}++#if defined (__APPLE__)+/* Perform Apple-specific cif processing for variadic calls */+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,+			 unsigned int ntotalargs)+{+  ffi_status status = ffi_prep_cif_machdep (cif);+  cif->aarch64_nfixedargs = nfixedargs;+  return status;+}+#else+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs)+{+  ffi_status status = ffi_prep_cif_machdep (cif);+  cif->flags |= AARCH64_FLAG_VARARG;+  return status;+}+#endif /* __APPLE__ */++extern void ffi_call_SYSV (struct call_context *context, void *frame,+			   void (*fn)(void), void *rvalue, int flags,+			   void *closure) FFI_HIDDEN;++/* Call a function with the provided arguments and capture the return+   value.+   n.b. ffi_call_SYSV will steal the alloca'd `stack` variable here for use+   _as its own stack_ - so we need to compile this function without ASAN */+FFI_ASAN_NO_SANITIZE+static void+ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,+	      void **avalue, void *closure)+{+  struct call_context *context;+  void *stack, *frame, *rvalue;+  struct arg_state state;+  size_t stack_bytes, rtype_size, rsize;+  int i, nargs, flags, isvariadic = 0;+  ffi_type *rtype;++  flags = cif->flags;+  rtype = cif->rtype;+  rtype_size = rtype->size;+  stack_bytes = cif->bytes;++  if (flags & AARCH64_FLAG_VARARG)+  {+    isvariadic = 1;+    flags &= ~AARCH64_FLAG_VARARG;+  }++  /* If the target function returns a structure via hidden pointer,+     then we cannot allow a null rvalue.  Otherwise, mash a null+     rvalue to void return type.  */+  rsize = 0;+  if (flags & AARCH64_RET_IN_MEM)+    {+      if (orig_rvalue == NULL)+	rsize = rtype_size;+    }+  else if (orig_rvalue == NULL)+    flags &= AARCH64_FLAG_ARG_V;+  else if (flags & AARCH64_RET_NEED_COPY)+    rsize = 16;++  /* Allocate consecutive stack for everything we'll need.+     The frame uses 40 bytes for: lr, fp, rvalue, flags, sp */+  context = alloca (sizeof(struct call_context) + stack_bytes + 40 + rsize);+  stack = context + 1;+  frame = (void*)((uintptr_t)stack + (uintptr_t)stack_bytes);+  rvalue = (rsize ? (void*)((uintptr_t)frame + 40) : orig_rvalue);++  arg_init (&state, stack_bytes);+  for (i = 0, nargs = cif->nargs; i < nargs; i++)+    {+      ffi_type *ty = cif->arg_types[i];+      size_t s = ty->size;+      void *a = avalue[i];+      int h, t;+      void *dest;++      t = ty->type;+      switch (t)+	{+	case FFI_TYPE_VOID:+	  FFI_ASSERT (0);+	  break;++	/* If the argument is a basic type the argument is allocated to an+	   appropriate register, or if none are available, to the stack.  */+	case FFI_TYPE_INT:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_POINTER:+	do_pointer:+	  {+	    ffi_arg ext = extend_integer_type (a, t);+	    if (state.ngrn < N_X_ARG_REG)+	      context->x[state.ngrn++] = ext;+	    else+	      {+		void *d = allocate_to_stack (&state, stack, ty->alignment, s);+		state.ngrn = N_X_ARG_REG;+		/* Note that the default abi extends each argument+		   to a full 64-bit slot, while the iOS abi allocates+		   only enough space. */+#ifdef __APPLE__+		memcpy(d, a, s);+#else+		*(ffi_arg *)d = ext;+#endif+	      }+	  }+	  break;++	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	case FFI_TYPE_STRUCT:+	case FFI_TYPE_COMPLEX:+	  {+	    h = is_vfp_type (ty);+	    if (h)+	      {+              int elems = 4 - (h & 3);+              if (cif->abi == FFI_WIN64 && isvariadic)+              {+                if (state.ngrn + elems <= N_X_ARG_REG)+                {+                  dest = &context->x[state.ngrn];+                  state.ngrn += elems;+                  extend_hfa_type(dest, a, h);+                  break;+                }+                state.nsrn = N_X_ARG_REG;+                dest = allocate_to_stack(&state, stack, ty->alignment, s);+              }+              else+              {+                if (state.nsrn + elems <= N_V_ARG_REG)+                {+                  dest = &context->v[state.nsrn];+                  state.nsrn += elems;+                  extend_hfa_type (dest, a, h);+                  break;+                }+                state.nsrn = N_V_ARG_REG;+                dest = allocate_to_stack (&state, stack, ty->alignment, s);+              }+	      }+	    else if (s > 16)+	      {+		/* If the argument is a composite type that is larger than 16+		   bytes, then the argument is copied to memory, and+		   the argument is replaced by a pointer to the copy.  */+		dest = allocate_and_copy_struct_to_stack (&state, stack,+							  ty->alignment, s,+							  avalue[i]);+		a = &dest;+		t = FFI_TYPE_POINTER;+		s = sizeof (void *);+		goto do_pointer;+	      }+	    else+	      {+		size_t n = (s + 7) / 8;+		if (state.ngrn + n <= N_X_ARG_REG)+		  {+		    /* If the argument is a composite type and the size in+		       double-words is not more than the number of available+		       X registers, then the argument is copied into+		       consecutive X registers.  */+		    dest = &context->x[state.ngrn];+                    state.ngrn += (unsigned int)n;+		  }+		else+		  {+		    /* Otherwise, there are insufficient X registers. Further+		       X register allocations are prevented, the NSAA is+		       adjusted and the argument is copied to memory at the+		       adjusted NSAA.  */+		    state.ngrn = N_X_ARG_REG;+		    dest = allocate_to_stack (&state, stack, ty->alignment, s);+		  }+		}+	      memcpy (dest, a, s);+	    }+	  break;++	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+    }++  ffi_call_SYSV (context, frame, fn, rvalue, flags, closure);++  if (flags & AARCH64_RET_NEED_COPY)+    memcpy (orig_rvalue, rvalue, rtype_size);+}++void+ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++#if FFI_CLOSURES++#ifdef FFI_GO_CLOSURES+void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}+#endif /* FFI_GO_CLOSURES */++/* Build a trampoline.  */++extern void ffi_closure_SYSV (void) FFI_HIDDEN;+extern void ffi_closure_SYSV_V (void) FFI_HIDDEN;+#if defined(FFI_EXEC_STATIC_TRAMP)+extern void ffi_closure_SYSV_alt (void) FFI_HIDDEN;+extern void ffi_closure_SYSV_V_alt (void) FFI_HIDDEN;+#endif++ffi_status+ffi_prep_closure_loc (ffi_closure *closure,+                      ffi_cif* cif,+                      void (*fun)(ffi_cif*,void*,void**,void*),+                      void *user_data,+                      void *codeloc)+{+  if (cif->abi != FFI_SYSV && cif->abi != FFI_WIN64)+    return FFI_BAD_ABI;++  void (*start)(void);++  if (cif->flags & AARCH64_FLAG_ARG_V)+    start = ffi_closure_SYSV_V;+  else+    start = ffi_closure_SYSV;++#if FFI_EXEC_TRAMPOLINE_TABLE+# ifdef __MACH__+#  ifdef HAVE_ARM64E_PTRAUTH+  codeloc = ptrauth_auth_data(codeloc, ptrauth_key_function_pointer, 0);+#  endif+  void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);+  config[0] = closure;+  config[1] = start;+# endif+#else+  static const unsigned char trampoline[16] = {+    0x90, 0x00, 0x00, 0x58,	/* ldr	x16, tramp+16	*/+    0xf1, 0xff, 0xff, 0x10,	/* adr	x17, tramp+0	*/+    0x00, 0x02, 0x1f, 0xd6	/* br	x16		*/+  };+  char *tramp = closure->tramp;++# if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      if (start == ffi_closure_SYSV_V)+          start = ffi_closure_SYSV_V_alt;+      else+          start = ffi_closure_SYSV_alt;+      ffi_tramp_set_parms (closure->ftramp, start, closure);+      goto out;+    }+# endif++  /* Initialize the dynamic trampoline. */+  memcpy (tramp, trampoline, sizeof(trampoline));++  *(UINT64 *)(tramp + 16) = (uintptr_t)start;++  ffi_clear_cache(tramp, tramp + FFI_TRAMPOLINE_SIZE);++  /* Also flush the cache for code mapping.  */+# ifdef _WIN32+  // Not using dlmalloc.c for Windows ARM64 builds+  // so calling ffi_data_to_code_pointer() isn't necessary+  unsigned char *tramp_code = tramp;+# else+  unsigned char *tramp_code = ffi_data_to_code_pointer (tramp);+# endif+  ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE);+# if defined(FFI_EXEC_STATIC_TRAMP)+out:+# endif+#endif++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++#ifdef FFI_GO_CLOSURES+extern void ffi_go_closure_SYSV (void) FFI_HIDDEN;+extern void ffi_go_closure_SYSV_V (void) FFI_HIDDEN;++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif* cif,+                     void (*fun)(ffi_cif*,void*,void**,void*))+{+  void (*start)(void);++  if (cif->abi != FFI_SYSV && cif->abi != FFI_WIN64)+    return FFI_BAD_ABI;++  if (cif->flags & AARCH64_FLAG_ARG_V)+    start = ffi_go_closure_SYSV_V;+  else+    start = ffi_go_closure_SYSV;++  closure->tramp = start;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}+#endif /* FFI_GO_CLOSURES */++/* Primary handler to setup and invoke a function within a closure.++   A closure when invoked enters via the assembler wrapper+   ffi_closure_SYSV(). The wrapper allocates a call context on the+   stack, saves the interesting registers (from the perspective of+   the calling convention) into the context then passes control to+   ffi_closure_SYSV_inner() passing the saved context and a pointer to+   the stack at the point ffi_closure_SYSV() was invoked.++   On the return path the assembler wrapper will reload call context+   registers.++   ffi_closure_SYSV_inner() marshalls the call context into ffi value+   descriptors, invokes the wrapped function, then marshalls the return+   value back into the call context.  */++int FFI_HIDDEN+ffi_closure_SYSV_inner (ffi_cif *cif,+			void (*fun)(ffi_cif*,void*,void**,void*),+			void *user_data,+			struct call_context *context,+			void *stack, void *rvalue, void *struct_rvalue)+{+  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));+  int i, h, nargs, flags, isvariadic = 0;+  struct arg_state state;++  arg_init (&state, cif->bytes);++  flags = cif->flags;+  if (flags & AARCH64_FLAG_VARARG)+  {+    isvariadic = 1;+    flags &= ~AARCH64_FLAG_VARARG;+  }++  for (i = 0, nargs = cif->nargs; i < nargs; i++)+    {+      ffi_type *ty = cif->arg_types[i];+      int t = ty->type;+      size_t n, s = ty->size;++      switch (t)+	{+	case FFI_TYPE_VOID:+	  FFI_ASSERT (0);+	  break;++	case FFI_TYPE_INT:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_POINTER:+	  avalue[i] = allocate_int_to_reg_or_stack (context, &state, stack, s);+	  break;++	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	case FFI_TYPE_STRUCT:+	case FFI_TYPE_COMPLEX:+	  h = is_vfp_type (ty);+	  if (h)+	    {+	      n = 4 - (h & 3);+              if (cif->abi == FFI_WIN64 && isvariadic)+                {+                  if (state.ngrn + n <= N_X_ARG_REG)+                    {+                      void *reg = &context->x[state.ngrn];+                      state.ngrn += (unsigned int)n;++                      /* Eeek! We need a pointer to the structure, however the+                       homogeneous float elements are being passed in individual+                       registers, therefore for float and double the structure+                       is not represented as a contiguous sequence of bytes in+                       our saved register context.  We don't need the original+                       contents of the register storage, so we reformat the+                       structure into the same memory.  */+                      avalue[i] = compress_hfa_type(reg, reg, h);+                    }+                  else+                    {+                      state.ngrn = N_X_ARG_REG;+                      state.nsrn = N_V_ARG_REG;+                      avalue[i] = allocate_to_stack(&state, stack,+                             ty->alignment, s);+                    }+                }+              else+                {+                  if (state.nsrn + n <= N_V_ARG_REG)+                    {+                      void *reg = &context->v[state.nsrn];+                      state.nsrn += (unsigned int)n;+                      avalue[i] = compress_hfa_type(reg, reg, h);+                    }+                  else+                    {+                      state.nsrn = N_V_ARG_REG;+                      avalue[i] = allocate_to_stack(&state, stack,+                                                   ty->alignment, s);+                    }+                }+            }+          else if (s > 16)+            {+              /* Replace Composite type of size greater than 16 with a+                  pointer.  */+#ifdef __ILP32__+             UINT64 avalue_tmp;+             memcpy (&avalue_tmp,+                  allocate_int_to_reg_or_stack (context, &state,+                                               stack, sizeof (void *)),+                  sizeof (UINT64));+             avalue[i] = (void *)(UINT32)avalue_tmp;+#else+              avalue[i] = *(void **)+              allocate_int_to_reg_or_stack (context, &state, stack,+                                         sizeof (void *));+#endif+            }+          else+            {+              n = (s + 7) / 8;+              if (state.ngrn + n <= N_X_ARG_REG)+                {+                  avalue[i] = &context->x[state.ngrn];+                  state.ngrn += (unsigned int)n;+                }+              else+                {+                  state.ngrn = N_X_ARG_REG;+                  avalue[i] = allocate_to_stack(&state, stack,+                                           ty->alignment, s);+                }+            }+          break;++        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+    }++  if (flags & AARCH64_RET_IN_MEM)+    rvalue = struct_rvalue;++  fun (cif, rvalue, avalue, user_data);++  return flags;+}++#if defined(FFI_EXEC_STATIC_TRAMP)+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;++  *tramp_size = AARCH64_TRAMP_SIZE;+  *map_size = AARCH64_TRAMP_MAP_SIZE;+  return &trampoline_code_table;+}+#endif++#endif /* FFI_CLOSURES */++#endif /* (__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)*/
+ src/aarch64/ffitarget.h view
@@ -0,0 +1,97 @@+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#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;+#elif defined(_WIN32)+#define FFI_SIZEOF_ARG 8+typedef unsigned long long ffi_arg;+typedef signed long long ffi_sarg;+#else+typedef unsigned long ffi_arg;+typedef signed long ffi_sarg;+#endif++typedef enum ffi_abi+  {+    FFI_FIRST_ABI = 0,+    FFI_SYSV,+    FFI_WIN64,+    FFI_LAST_ABI,+#if defined(_WIN32)+    FFI_DEFAULT_ABI = FFI_WIN64+#else+    FFI_DEFAULT_ABI = FFI_SYSV+#endif+  } ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__+#define FFI_TRAMPOLINE_SIZE 16+#define FFI_TRAMPOLINE_CLOSURE_OFFSET 16+#else+#error "No trampoline table implementation"+#endif++#else+#define FFI_TRAMPOLINE_SIZE 24+#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE+#endif++#ifdef _WIN32+#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic+#endif+#define FFI_TARGET_SPECIFIC_VARIADIC++/* ---- Internal ---- */++#if defined (__APPLE__)+#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs+#elif !defined(_WIN32) && !defined(__ANDROID__)+/* iOS, Windows and Android reserve x18 for the system.  Disable Go closures until+   a new static chain is chosen.  */+#define FFI_GO_CLOSURES 1+#endif++#ifndef _WIN32+/* No complex type on Windows */+#define FFI_TARGET_HAS_COMPLEX_TYPE+#endif++#endif
+ src/aarch64/internal.h view
@@ -0,0 +1,146 @@+/* +Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#define AARCH64_RET_VOID	0+#define AARCH64_RET_INT64	1+#define AARCH64_RET_INT128	2++#define AARCH64_RET_UNUSED3	3+#define AARCH64_RET_UNUSED4	4+#define AARCH64_RET_UNUSED5	5+#define AARCH64_RET_UNUSED6	6+#define AARCH64_RET_UNUSED7	7++/* Note that FFI_TYPE_FLOAT == 2, _DOUBLE == 3, _LONGDOUBLE == 4,+   so _S4 through _Q1 are layed out as (TYPE * 4) + (4 - COUNT).  */+#define AARCH64_RET_S4		8+#define AARCH64_RET_S3		9+#define AARCH64_RET_S2		10+#define AARCH64_RET_S1		11++#define AARCH64_RET_D4		12+#define AARCH64_RET_D3		13+#define AARCH64_RET_D2		14+#define AARCH64_RET_D1		15++#define AARCH64_RET_Q4		16+#define AARCH64_RET_Q3		17+#define AARCH64_RET_Q2		18+#define AARCH64_RET_Q1		19++/* Note that each of the sub-64-bit integers gets two entries.  */+#define AARCH64_RET_UINT8	20+#define AARCH64_RET_UINT16	22+#define AARCH64_RET_UINT32	24++#define AARCH64_RET_SINT8	26+#define AARCH64_RET_SINT16	28+#define AARCH64_RET_SINT32	30++#define AARCH64_RET_MASK	31++#define AARCH64_RET_IN_MEM	(1 << 5)+#define AARCH64_RET_NEED_COPY	(1 << 6)++#define AARCH64_FLAG_ARG_V_BIT	7+#define AARCH64_FLAG_ARG_V	(1 << AARCH64_FLAG_ARG_V_BIT)+#define AARCH64_FLAG_VARARG	(1 << 8)++#define N_X_ARG_REG		8+#define N_V_ARG_REG		8+#define CALL_CONTEXT_SIZE	(N_V_ARG_REG * 16 + N_X_ARG_REG * 8)++#if defined(FFI_EXEC_STATIC_TRAMP)+/*+ * For the trampoline code table mapping, a mapping size of 16K is chosen to+ * cover the base page sizes of 4K and 16K.+ */+#define AARCH64_TRAMP_MAP_SHIFT	14+#define AARCH64_TRAMP_MAP_SIZE	(1 << AARCH64_TRAMP_MAP_SHIFT)+#define AARCH64_TRAMP_SIZE	32++#endif++/* Helpers for writing assembly compatible with arm ptr auth */+#ifdef LIBFFI_ASM++  #if defined(HAVE_ARM64E_PTRAUTH)+  /* ARM64E ABI For Darwin */+  #define SIGN_LR pacibsp+  #define SIGN_LR_WITH_REG(x) pacib lr, x+  #define AUTH_LR_AND_RET retab+  #define AUTH_LR_WITH_REG(x) autib lr, x+  #define BRANCH_AND_LINK_TO_REG blraaz+  #define SIGN_LR_LINUX_ONLY+  #define BRANCH_TO_REG braaz+  #define PAC_CFI_WINDOW_SAVE+  #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0+  /* Linux PAC Support */+  #elif defined(__ARM_FEATURE_PAC_DEFAULT)+    #define GNU_PROPERTY_AARCH64_POINTER_AUTH (1 << 1)+    #define PAC_CFI_WINDOW_SAVE cfi_window_save+    #define TMP_REG x9+    #define BRANCH_TO_REG br+    #define BRANCH_AND_LINK_TO_REG blr+	#define SIGN_LR_LINUX_ONLY SIGN_LR+    /* Which key to sign with? */+    #if (__ARM_FEATURE_PAC_DEFAULT & 1) == 1+      /* Signed with A-key */+      #define SIGN_LR            hint #25  /* paciasp */+      #define AUTH_LR            hint #29  /* autiasp */+    #else+      /* Signed with B-key */+      #define SIGN_LR            hint #27  /* pacibsp */+      #define AUTH_LR            hint #31  /* autibsp */+    #endif /* __ARM_FEATURE_PAC_DEFAULT */+    #define AUTH_LR_WITH_REG(x) _auth_lr_with_reg x+.macro _auth_lr_with_reg modifier+    mov TMP_REG, sp+    mov sp, \modifier+    AUTH_LR+    mov sp, TMP_REG+.endm+  #define SIGN_LR_WITH_REG(x) _sign_lr_with_reg x+.macro _sign_lr_with_reg modifier+    mov TMP_REG, sp+    mov sp, \modifier+    SIGN_LR+    mov sp, TMP_REG+.endm+  #define AUTH_LR_AND_RET _auth_lr_and_ret modifier+.macro _auth_lr_and_ret modifier+    AUTH_LR+    ret+.endm+  #undef TMP_REG++  /* No Pointer Auth */+  #else+    #define SIGN_LR+    #define SIGN_LR_WITH_REG(x)+    #define AUTH_LR_AND_RET ret+    #define AUTH_LR_WITH_REG(x)+    #define BRANCH_AND_LINK_TO_REG blr+    #define SIGN_LR_LINUX_ONLY+    #define BRANCH_TO_REG br+    #define PAC_CFI_WINDOW_SAVE+    #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0+  #endif /* HAVE_ARM64E_PTRAUTH */+#endif /* LIBFFI_ASM */
+ src/aarch64/sysv.S view
@@ -0,0 +1,699 @@+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#if defined(__aarch64__) || defined(__arm64__)+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "internal.h"++#ifdef HAVE_MACHINE_ASM_H+#include <machine/asm.h>+#else+#ifdef __USER_LABEL_PREFIX__+#define CONCAT1(a, b) CONCAT2(a, b)+#define CONCAT2(a, b) a ## b++/* Use the right prefix for global labels.  */+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)+#else+#define CNAME(x) x+#endif+#endif++#ifdef __APPLE__+# define L(X)     CONCAT1(L, X)+#else+# define L(X)     CONCAT1(.L, X)+#endif++#ifdef __AARCH64EB__+# define BE(X)	X+#else+# define BE(X)	0+#endif++#ifdef __ILP32__+#define PTR_REG(n)      w##n+#else+#define PTR_REG(n)      x##n+#endif++#ifdef __ILP32__+#define PTR_SIZE	4+#else+#define PTR_SIZE	8+#endif++#define BTI_C hint #34+#define BTI_J hint #36+/*+ * The ELF Notes section needs to indicate if BTI is supported, as the first ELF loaded that doesn't+ * declare this support disables it for memory region containing the loaded library.+ */+# define GNU_PROPERTY_AARCH64_BTI (1 << 0)         /* Has Branch Target Identification */+	.text+	.align 4++/* ffi_call_SYSV+   extern void ffi_call_SYSV (void *stack, void *frame,+			      void (*fn)(void), void *rvalue,+			      int flags, void *closure);++   Therefore on entry we have:++   x0 stack+   x1 frame+   x2 fn+   x3 rvalue+   x4 flags+   x5 closure+*/++CNAME(ffi_call_SYSV):+	cfi_startproc+	BTI_C+	PAC_CFI_WINDOW_SAVE+	/* Sign the lr with x1 since that is the CFA which is the modifer used in auth instructions */+	SIGN_LR_WITH_REG(x1)++#if defined(HAVE_ARM64E_PTRAUTH) && defined(__APPLE__)+	/* darwin's libunwind assumes that the cfa is the sp and that's the data+	 * used to sign the lr.  In order to allow unwinding through this+	 * function it is necessary to point the cfa at the signing register.+	 */+	cfi_def_cfa(x1, 0);+#endif+	/* Use a stack frame allocated by our caller.  */+	stp	x29, x30, [x1]+	cfi_def_cfa_register(x1)+	cfi_rel_offset (x29, 0)+	cfi_rel_offset (x30, 8)+	mov	x9, sp+	str	x9, [x1, #32]+	mov	x29, x1+	cfi_def_cfa_register(x29)+	mov	sp, x0++	mov	x9, x2			/* save fn */+	mov	x8, x3			/* install structure return */+#ifdef FFI_GO_CLOSURES+	mov	x18, x5			/* install static chain */+#endif+	stp	x3, x4, [x29, #16]	/* save rvalue and flags */++	/* Load the vector argument passing registers, if necessary.  */+	tbz	w4, #AARCH64_FLAG_ARG_V_BIT, 1f+	ldp     q0, q1, [sp, #0]+	ldp     q2, q3, [sp, #32]+	ldp     q4, q5, [sp, #64]+	ldp     q6, q7, [sp, #96]+1:+	/* Load the core argument passing registers, including+	   the structure return pointer.  */+	ldp     x0, x1, [sp, #16*N_V_ARG_REG + 0]+	ldp     x2, x3, [sp, #16*N_V_ARG_REG + 16]+	ldp     x4, x5, [sp, #16*N_V_ARG_REG + 32]+	ldp     x6, x7, [sp, #16*N_V_ARG_REG + 48]++	/* Deallocate the context, leaving the stacked arguments.  */+	add	sp, sp, #CALL_CONTEXT_SIZE++	BRANCH_AND_LINK_TO_REG     x9			/* call fn */++	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */++	/* Partially deconstruct the stack frame.  */+	ldr	x9, [x29, #32]+	mov	sp, x9+	cfi_def_cfa_register (sp)+	mov	x2, x29			/* Preserve for auth */+	ldp     x29, x30, [x29]++	/* Save the return value as directed.  */+	adr	x5, 0f+	and	w4, w4, #AARCH64_RET_MASK+	add	x5, x5, x4, lsl #4+	br	x5++	/* Note that each table entry is 4 insns, and thus 16 bytes.+	   For integer data, note that we're storing into ffi_arg+	   and therefore we want to extend to 64 bits; these types+	   have two consecutive entries allocated for them.  */+	.align	4+0:	BTI_J				/* VOID */+	b 99f+	nop +	nop+1:	BTI_J				/* INT64 */+	str	x0, [x3]+	b 99f+	nop+2:	BTI_J				/* INT128 */+	stp	x0, x1, [x3]+	b 99f+	nop+3:	brk	#1000			/* UNUSED */+	b 99f+	nop+	nop+4:	brk	#1000			/* UNUSED */+	b 99f+	nop+	nop+5:	brk	#1000			/* UNUSED */+	b 99f+	nop+	nop+6:	brk	#1000			/* UNUSED */+	b 99f+	nop+	nop+7:	brk	#1000			/* UNUSED */+	b 99f+	nop+	nop+8:	BTI_J				/* S4 */+	st4	{ v0.s, v1.s, v2.s, v3.s }[0], [x3]+	b 99f+	nop+9:	BTI_J				/* S3 */+	st3	{ v0.s, v1.s, v2.s }[0], [x3]+	b 99f+	nop+10:	BTI_J				/* S2 */+	stp	s0, s1, [x3]+	b 99f+	nop+11:	BTI_J+	str	s0, [x3]		/* S1 */+	b 99f+	nop+12:	BTI_J				/* D4 */+	st4	{ v0.d, v1.d, v2.d, v3.d }[0], [x3]+	b 99f+	nop+13:	BTI_J				/* D3 */+	st3	{ v0.d, v1.d, v2.d }[0], [x3]+	b 99f+	nop+14:	BTI_J				/* D2 */+	stp	d0, d1, [x3]+	b 99f+	nop+15:	BTI_J				/* D1 */+	str	d0, [x3]+	b 99f+	nop+16:	BTI_J				/* Q4 */+	str	q3, [x3, #48]+	nop+	nop+17:	BTI_J				/* Q3 */+	str	q2, [x3, #32]+	nop+	nop+18:	BTI_J				/* Q2 */+	stp	q0, q1, [x3]+	b 99f+	nop+19:	BTI_J				/* Q1 */+	str	q0, [x3]+	b 99f+	nop+20:	BTI_J				/* UINT8 */+	uxtb	w0, w0+	str	x0, [x3]+	nop+21:	b 99f				/* reserved */+	nop+	nop+	nop+22:	BTI_J				/* UINT16 */+	uxth	w0, w0+	str	x0, [x3]+	nop+23:	b 99f				/* reserved */+	nop+	nop+	nop+24:	BTI_J				/* UINT32 */+	mov	w0, w0+	str	x0, [x3]+	nop+25:	b 99f				/* reserved */+	nop+	nop+	nop+26:	BTI_J				/* SINT8 */+	sxtb	x0, w0+	str	x0, [x3]+	nop+27:	b 99f				/* reserved */+	nop+	nop+	nop+28:	BTI_J				/* SINT16 */+	sxth	x0, w0+	str	x0, [x3]+	nop+29:	b 99f				/* reserved */+	nop+	nop+	nop+30:	BTI_J				/* SINT32 */+	sxtw	x0, w0+	str	x0, [x3]+	nop+31:	b 99f				/* reserved */+	nop+	nop+	nop++	/* Return now that result has been populated. */+99:+	AUTH_LR_WITH_REG(x2)+	ret++	cfi_endproc++	.globl	CNAME(ffi_call_SYSV)+	FFI_HIDDEN(CNAME(ffi_call_SYSV))+#ifdef __ELF__+	.type	CNAME(ffi_call_SYSV), #function+	.size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)+#endif++#if FFI_CLOSURES++/* ffi_closure_SYSV++   Closure invocation glue. This is the low level code invoked directly by+   the closure trampoline to setup and call a closure.++   On entry x17 points to a struct ffi_closure, x16 has been clobbered+   all other registers are preserved.++   We allocate a call context and save the argument passing registers,+   then invoked the generic C ffi_closure_SYSV_inner() function to do all+   the real work, on return we load the result passing registers back from+   the call context.+*/++#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)++	.align 4+CNAME(ffi_closure_SYSV_V):+	cfi_startproc+	BTI_C+	SIGN_LR+	PAC_CFI_WINDOW_SAVE+	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!+	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)+	cfi_rel_offset (x29, 0)+	cfi_rel_offset (x30, 8)++	/* Save the argument passing vector registers.  */+	stp     q0, q1, [sp, #16 + 0]+	stp     q2, q3, [sp, #16 + 32]+	stp     q4, q5, [sp, #16 + 64]+	stp     q6, q7, [sp, #16 + 96]+	b	0f+	cfi_endproc++	.globl	CNAME(ffi_closure_SYSV_V)+	FFI_HIDDEN(CNAME(ffi_closure_SYSV_V))+#ifdef __ELF__+	.type	CNAME(ffi_closure_SYSV_V), #function+	.size	CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V)+#endif++	.align	4+CNAME(ffi_closure_SYSV):+	cfi_startproc+	BTI_C+	SIGN_LR+	PAC_CFI_WINDOW_SAVE+	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!+	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)+	cfi_rel_offset (x29, 0)+	cfi_rel_offset (x30, 8)+0:+	mov     x29, sp++	/* Save the argument passing core registers.  */+	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]+	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]+	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]+	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]++	/* Load ffi_closure_inner arguments.  */+	ldp	PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	/* load cif, fn */+	ldr	PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2]	/* load user_data */+#ifdef FFI_GO_CLOSURES+L(do_closure):+#endif+	add	x3, sp, #16				/* load context */+	add	x4, sp, #ffi_closure_SYSV_FS		/* load stack */+	add	x5, sp, #16+CALL_CONTEXT_SIZE		/* load rvalue */+	mov	x6, x8					/* load struct_rval */+	bl      CNAME(ffi_closure_SYSV_inner)++	/* Load the return value as directed.  */+	adr	x1, 0f+	and	w0, w0, #AARCH64_RET_MASK+	add	x1, x1, x0, lsl #4+	add	x3, sp, #16+CALL_CONTEXT_SIZE+	br	x1++	/* Note that each table entry is 4 insns, and thus 16 bytes.  */+	.align	4+0:	BTI_J				/* VOID */+	b	99f+	nop+	nop+1:	BTI_J				/* INT64 */+	ldr	x0, [x3]+	b	99f+	nop+2:	BTI_J				/* INT128 */+	ldp	x0, x1, [x3]+	b	99f+	nop+3:	brk	#1000			/* UNUSED */+	nop+	nop+	nop+4:	brk	#1000			/* UNUSED */+	nop+	nop+	nop+5:	brk	#1000			/* UNUSED */+	nop+	nop+	nop+6:	brk	#1000			/* UNUSED */+	nop+	nop+	nop+7:	brk	#1000			/* UNUSED */+	nop+	nop+	nop+8:	BTI_J				/* S4 */+	ldr	s3, [x3, #12]+	nop+	nop+9:	BTI_J				/* S3 */+	ldr	s2, [x3, #8]+	nop+	nop+10:	BTI_J				/* S2 */+	ldp	s0, s1, [x3]+	b	99f+	nop+11:	BTI_J				/* S1 */+	ldr	s0, [x3]+	b	99f+	nop+12:	BTI_J				/* D4 */+	ldr	d3, [x3, #24]+	nop+	nop+13:	BTI_J				/* D3 */+	ldr	d2, [x3, #16]+	nop+	nop+14:	BTI_J				/* D2 */+	ldp	d0, d1, [x3]+	b	99f+	nop+15:	BTI_J				/* D1 */+	ldr	d0, [x3]+	b	99f+	nop+16:	BTI_J				/* Q4 */+	ldr	q3, [x3, #48]+	nop+	nop+17:	BTI_J				/* Q3 */+	ldr	q2, [x3, #32]+	nop+	nop+18:	BTI_J				/* Q2 */+	ldp	q0, q1, [x3]+	b	99f+	nop+19:	BTI_J				/* Q1 */+	ldr	q0, [x3]+	b	99f+	nop+20:	BTI_J				/* UINT8 */+	ldrb	w0, [x3, #BE(7)]+	b	99f+	nop+21:	brk	#1000			/* reserved */+	nop+	nop+	nop+22:	BTI_J				/* UINT16 */+	ldrh	w0, [x3, #BE(6)]+	b	99f+	nop+23:	brk	#1000			/* reserved */+	nop+	nop+	nop+24:	BTI_J				/* UINT32 */+	ldr	w0, [x3, #BE(4)]+	b	99f+	nop+25:	brk	#1000			/* reserved */+	nop+	nop+	nop+26:	BTI_J				/* SINT8 */+	ldrsb	x0, [x3, #BE(7)]+	b	99f+	nop+27:	brk	#1000			/* reserved */+	nop+	nop+	nop+28:	BTI_J				/* SINT16 */+	ldrsh	x0, [x3, #BE(6)]+	b	99f+	nop+29:	brk	#1000			/* reserved */+	nop+	nop+	nop+30:	BTI_J				/* SINT32 */+	ldrsw	x0, [x3, #BE(4)]+	nop+	nop+31:					/* reserved */+99:	ldp     x29, x30, [sp], #ffi_closure_SYSV_FS+	cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)+	cfi_restore (x29)+	cfi_restore (x30)+	AUTH_LR_AND_RET+	cfi_endproc++	.globl	CNAME(ffi_closure_SYSV)+	FFI_HIDDEN(CNAME(ffi_closure_SYSV))+#ifdef __ELF__+	.type	CNAME(ffi_closure_SYSV), #function+	.size	CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV)+#endif++#if defined(FFI_EXEC_STATIC_TRAMP)+	.align 4+CNAME(ffi_closure_SYSV_V_alt):+	BTI_C+	/* See the comments above trampoline_code_table. */+	ldr	x17, [sp, #8]			/* Load closure in x17 */+	add	sp, sp, #16			/* Restore the stack */+	b	CNAME(ffi_closure_SYSV_V)++	.globl	CNAME(ffi_closure_SYSV_V_alt)+	FFI_HIDDEN(CNAME(ffi_closure_SYSV_V_alt))+#ifdef __ELF__+	.type	CNAME(ffi_closure_SYSV_V_alt), #function+	.size	CNAME(ffi_closure_SYSV_V_alt), . - CNAME(ffi_closure_SYSV_V_alt)+#endif++	.align 4+CNAME(ffi_closure_SYSV_alt):+	BTI_C+	/* See the comments above trampoline_code_table. */+	ldr	x17, [sp, #8]			/* Load closure in x17 */+	add	sp, sp, #16			/* Restore the stack */+	b	CNAME(ffi_closure_SYSV)++	.globl	CNAME(ffi_closure_SYSV_alt)+	FFI_HIDDEN(CNAME(ffi_closure_SYSV_alt))+#ifdef __ELF__+	.type	CNAME(ffi_closure_SYSV_alt), #function+	.size	CNAME(ffi_closure_SYSV_alt), . - CNAME(ffi_closure_SYSV_alt)+#endif++/*+ * Below is the definition of the trampoline code table. Each element in+ * the code table is a trampoline.+ */+/*+ * The trampoline uses register x17. It saves the original value of x17 on+ * the stack.+ *+ * The trampoline has two parameters - target code to jump to and data for+ * the target code. The trampoline extracts the parameters from its parameter+ * block (see tramp_table_map()). The trampoline saves the data address on+ * the stack. Finally, it jumps to the target code.+ *+ * The target code can choose to:+ *+ * - restore the value of x17+ * - load the data address in a register+ * - restore the stack pointer to what it was when the trampoline was invoked.+ */+	.align	AARCH64_TRAMP_MAP_SHIFT+CNAME(trampoline_code_table):+	.rept	AARCH64_TRAMP_MAP_SIZE / AARCH64_TRAMP_SIZE+	sub	sp, sp, #16		/* Make space on the stack */+	str	x17, [sp]		/* Save x17 on stack */+	adr	x17, #16376		/* Get data address */+	ldr	x17, [x17]		/* Copy data into x17 */+	str	x17, [sp, #8]		/* Save data on stack */+	adr	x17, #16372		/* Get code address */+	ldr	x17, [x17]		/* Load code address into x17 */+	br	x17			/* Jump to code */+	.endr++	.globl CNAME(trampoline_code_table)+	FFI_HIDDEN(CNAME(trampoline_code_table))+#ifdef __ELF__+	.type	CNAME(trampoline_code_table), #function+	.size	CNAME(trampoline_code_table), . - CNAME(trampoline_code_table)+#endif+	.align	AARCH64_TRAMP_MAP_SHIFT+#endif /* FFI_EXEC_STATIC_TRAMP */++#if FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__+#include <mach/machine/vm_param.h>+    .align PAGE_MAX_SHIFT+CNAME(ffi_closure_trampoline_table_page):+    .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE+    adr x16, -PAGE_MAX_SIZE+    ldp x17, x16, [x16]+    br x16+	nop		/* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller than 16 bytes */+    .endr++    .globl CNAME(ffi_closure_trampoline_table_page)+    FFI_HIDDEN(CNAME(ffi_closure_trampoline_table_page))+    #ifdef __ELF__+    	.type	CNAME(ffi_closure_trampoline_table_page), #function+    	.size	CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page)+    #endif+#endif++#endif /* FFI_EXEC_TRAMPOLINE_TABLE */++#ifdef FFI_GO_CLOSURES+	.align 4+CNAME(ffi_go_closure_SYSV_V):+	cfi_startproc+	BTI_C+	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!+	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)+	cfi_rel_offset (x29, 0)+	cfi_rel_offset (x30, 8)++	/* Save the argument passing vector registers.  */+	stp     q0, q1, [sp, #16 + 0]+	stp     q2, q3, [sp, #16 + 32]+	stp     q4, q5, [sp, #16 + 64]+	stp     q6, q7, [sp, #16 + 96]+	b	0f+	cfi_endproc++	.globl	CNAME(ffi_go_closure_SYSV_V)+	FFI_HIDDEN(CNAME(ffi_go_closure_SYSV_V))+#ifdef __ELF__+	.type	CNAME(ffi_go_closure_SYSV_V), #function+	.size	CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V)+#endif++	.align	4+CNAME(ffi_go_closure_SYSV):+	cfi_startproc+	BTI_C+	SIGN_LR_LINUX_ONLY+	PAC_CFI_WINDOW_SAVE+	stp     x29, x30, [sp, #-ffi_closure_SYSV_FS]!+	cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)+	cfi_rel_offset (x29, 0)+	cfi_rel_offset (x30, 8)+0:+	mov     x29, sp++	/* Save the argument passing core registers.  */+	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]+	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]+	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]+	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]++	/* Load ffi_closure_inner arguments.  */+	ldp	PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */+	mov	x2, x18					/* load user_data */+	b	L(do_closure)+	cfi_endproc++	.globl	CNAME(ffi_go_closure_SYSV)+	FFI_HIDDEN(CNAME(ffi_go_closure_SYSV))+#ifdef __ELF__+	.type	CNAME(ffi_go_closure_SYSV), #function+	.size	CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV)+#endif+#endif /* FFI_GO_CLOSURES */+#endif /* FFI_CLOSURES */+#endif /* __arm64__ */++#if defined __ELF__ && defined __linux__+	.section .note.GNU-stack,"",%progbits++	.pushsection .note.gnu.property, "a";+	.balign 8;+	.long 4;+	.long 0x10;+	.long 0x5;+	.asciz "GNU";+	.long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */+	.long 4;+	.long GNU_PROPERTY_AARCH64_BTI | GNU_PROPERTY_AARCH64_POINTER_AUTH;+	.long 0;+	.popsection;+#endif+
+ src/aarch64/win64_armasm.S view
@@ -0,0 +1,506 @@+/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.+Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:+The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "internal.h"++	OPT	2 /*disable listing */+/* For some macros to add unwind information */+#include "ksarm64.h"+	OPT	1 /*re-enable listing */++#define BE(X)	0+#define PTR_REG(n)      x##n+#define PTR_SIZE	8++	IMPORT ffi_closure_SYSV_inner+	EXPORT	ffi_call_SYSV+	EXPORT	ffi_closure_SYSV_V+	EXPORT	ffi_closure_SYSV+	EXPORT	extend_hfa_type+	EXPORT	compress_hfa_type+#ifdef FFI_GO_CLOSURES+	EXPORT	ffi_go_closure_SYSV_V+	EXPORT	ffi_go_closure_SYSV+#endif++	TEXTAREA, ALIGN=8++/* ffi_call_SYSV+   extern void ffi_call_SYSV (void *stack, void *frame,+			      void (*fn)(void), void *rvalue,+			      int flags, void *closure);+   Therefore on entry we have:+   x0 stack+   x1 frame+   x2 fn+   x3 rvalue+   x4 flags+   x5 closure+*/++	NESTED_ENTRY ffi_call_SYSV_fake++	/* For unwind information, Windows has to store fp and lr  */+	PROLOG_SAVE_REG_PAIR	x29, x30, #-32!++	ALTERNATE_ENTRY ffi_call_SYSV+	/* Use a stack frame allocated by our caller. */+	stp	x29, x30, [x1]+	mov	x29, x1+	mov	sp, x0++	mov	x9, x2			/* save fn */+	mov	x8, x3			/* install structure return */+#ifdef FFI_GO_CLOSURES+	/*mov	x18, x5			install static chain */+#endif+	stp	x3, x4, [x29, #16]	/* save rvalue and flags */+	+	/* Load the vector argument passing registers, if necessary.  */+	tbz	x4, #AARCH64_FLAG_ARG_V_BIT, ffi_call_SYSV_L1+	ldp	q0, q1, [sp, #0]+	ldp	q2, q3, [sp, #32]+	ldp	q4, q5, [sp, #64]+	ldp	q6, q7, [sp, #96]++ffi_call_SYSV_L1+	/* Load the core argument passing registers, including+	   the structure return pointer.  */+	ldp     x0, x1, [sp, #16*N_V_ARG_REG + 0]+	ldp     x2, x3, [sp, #16*N_V_ARG_REG + 16]+	ldp     x4, x5, [sp, #16*N_V_ARG_REG + 32]+	ldp     x6, x7, [sp, #16*N_V_ARG_REG + 48]++	/* Deallocate the context, leaving the stacked arguments.  */+	add	sp, sp, #CALL_CONTEXT_SIZE	++	blr     x9			/* call fn */++	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */++	/* Partially deconstruct the stack frame. */+	mov     sp, x29 +	ldp     x29, x30, [x29]++	/* Save the return value as directed.  */+	adr	x5, ffi_call_SYSV_return+	and	w4, w4, #AARCH64_RET_MASK+	add	x5, x5, x4, lsl #3+	br	x5+	+	/* Note that each table entry is 2 insns, and thus 8 bytes.+	   For integer data, note that we're storing into ffi_arg+	   and therefore we want to extend to 64 bits; these types+	   have two consecutive entries allocated for them.  */+	ALIGN 4+ffi_call_SYSV_return+	ret				/* VOID */+	nop+	str	x0, [x3]		/* INT64 */+	ret+	stp	x0, x1, [x3]		/* INT128 */+	ret+	brk	#1000			/* UNUSED */+	ret+	brk	#1000			/* UNUSED */+	ret+	brk	#1000			/* UNUSED */+	ret+	brk	#1000			/* UNUSED */+	ret+	brk	#1000			/* UNUSED */+	ret+	st4	{ v0.s, v1.s, v2.s, v3.s }[0], [x3]	/* S4 */+	ret+	st3	{ v0.s, v1.s, v2.s }[0], [x3]	/* S3 */+	ret+	stp	s0, s1, [x3]		/* S2 */+	ret+	str	s0, [x3]		/* S1 */+	ret+	st4	{ v0.d, v1.d, v2.d, v3.d }[0], [x3]	/* D4 */+	ret+	st3	{ v0.d, v1.d, v2.d }[0], [x3]	/* D3 */+	ret+	stp	d0, d1, [x3]		/* D2 */+	ret+	str	d0, [x3]		/* D1 */+	ret+	str	q3, [x3, #48]		/* Q4 */+	nop+	str	q2, [x3, #32]		/* Q3 */+	nop+	stp	q0, q1, [x3]		/* Q2 */+	ret+	str	q0, [x3]		/* Q1 */+	ret+	uxtb	w0, w0			/* UINT8 */+	str	x0, [x3]+	ret				/* reserved */+	nop+	uxth	w0, w0			/* UINT16 */+	str	x0, [x3]+	ret				/* reserved */+	nop+	mov	w0, w0			/* UINT32 */+	str	x0, [x3]+	ret				/* reserved */+	nop+	sxtb	x0, w0			/* SINT8 */+	str	x0, [x3]+	ret				/* reserved */+	nop+	sxth	x0, w0			/* SINT16 */+	str	x0, [x3]+	ret				/* reserved */+	nop+	sxtw	x0, w0			/* SINT32 */+	str	x0, [x3]+	ret				/* reserved */+	nop+	+	+	NESTED_END ffi_call_SYSV_fake+	++/* ffi_closure_SYSV+   Closure invocation glue. This is the low level code invoked directly by+   the closure trampoline to setup and call a closure.+   On entry x17 points to a struct ffi_closure, x16 has been clobbered+   all other registers are preserved.+   We allocate a call context and save the argument passing registers,+   then invoked the generic C ffi_closure_SYSV_inner() function to do all+   the real work, on return we load the result passing registers back from+   the call context.+*/++#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)++	NESTED_ENTRY	ffi_closure_SYSV_V+	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!++	/* Save the argument passing vector registers.  */+	stp	q0, q1, [sp, #16 + 0]+	stp	q2, q3, [sp, #16 + 32]+	stp	q4, q5, [sp, #16 + 64]+	stp	q6, q7, [sp, #16 + 96]++	b	ffi_closure_SYSV_save_argument+	NESTED_END	ffi_closure_SYSV_V++	NESTED_ENTRY	ffi_closure_SYSV+	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!++ffi_closure_SYSV_save_argument+	/* Save the argument passing core registers.  */+	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]+	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]+	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]+	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]++	/* Load ffi_closure_inner arguments.  */+	ldp	PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	/* load cif, fn */+	ldr	PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2]	/* load user_data */++do_closure+	add	x3, sp, #16							/* load context */+	add	x4, sp, #ffi_closure_SYSV_FS		/* load stack */+	add	x5, sp, #16+CALL_CONTEXT_SIZE		/* load rvalue */+	mov	x6, x8					/* load struct_rval */++	bl	ffi_closure_SYSV_inner++	/* Load the return value as directed.  */+	adr	x1, ffi_closure_SYSV_return_base+	and	w0, w0, #AARCH64_RET_MASK+	add	x1, x1, x0, lsl #3+	add	x3, sp, #16+CALL_CONTEXT_SIZE+	br	x1++	/* Note that each table entry is 2 insns, and thus 8 bytes.  */+	ALIGN	8+ffi_closure_SYSV_return_base+	b	ffi_closure_SYSV_epilog			/* VOID */+	nop+	ldr	x0, [x3]		/* INT64 */+	b	ffi_closure_SYSV_epilog+	ldp	x0, x1, [x3]		/* INT128 */+	b	ffi_closure_SYSV_epilog+	brk	#1000			/* UNUSED */+	nop+	brk	#1000			/* UNUSED */+	nop+	brk	#1000			/* UNUSED */+	nop+	brk	#1000			/* UNUSED */+	nop+	brk	#1000			/* UNUSED */+	nop+	ldr	s3, [x3, #12]		/* S4 */+	nop+	ldr	s2, [x3, #8]		/* S3 */+	nop+	ldp	s0, s1, [x3]		/* S2 */+	b	ffi_closure_SYSV_epilog+	ldr	s0, [x3]		/* S1 */+	b	ffi_closure_SYSV_epilog+	ldr	d3, [x3, #24]		/* D4 */+	nop+	ldr	d2, [x3, #16]		/* D3 */+	nop+	ldp	d0, d1, [x3]		/* D2 */+	b	ffi_closure_SYSV_epilog+	ldr	d0, [x3]		/* D1 */+	b	ffi_closure_SYSV_epilog+	ldr	q3, [x3, #48]		/* Q4 */+	nop+	ldr	q2, [x3, #32]		/* Q3 */+	nop+	ldp	q0, q1, [x3]		/* Q2 */+	b	ffi_closure_SYSV_epilog+	ldr	q0, [x3]		/* Q1 */+	b	ffi_closure_SYSV_epilog+	ldrb	w0, [x3, #BE(7)]	/* UINT8 */+	b	ffi_closure_SYSV_epilog+	brk	#1000			/* reserved */+	nop+	ldrh	w0, [x3, #BE(6)]	/* UINT16 */+	b	ffi_closure_SYSV_epilog+	brk	#1000			/* reserved */+	nop+	ldr	w0, [x3, #BE(4)]	/* UINT32 */+	b	ffi_closure_SYSV_epilog+	brk	#1000			/* reserved */+	nop+	ldrsb	x0, [x3, #BE(7)]	/* SINT8 */+	b	ffi_closure_SYSV_epilog+	brk	#1000			/* reserved */+	nop+	ldrsh	x0, [x3, #BE(6)]	/* SINT16 */+	b	ffi_closure_SYSV_epilog+	brk	#1000			/* reserved */+	nop+	ldrsw	x0, [x3, #BE(4)]	/* SINT32 */+	nop+					/* reserved */++ffi_closure_SYSV_epilog+	EPILOG_RESTORE_REG_PAIR	x29, x30, #ffi_closure_SYSV_FS!+	EPILOG_RETURN+	NESTED_END	ffi_closure_SYSV+++#ifdef FFI_GO_CLOSURES+	NESTED_ENTRY	ffi_go_closure_SYSV_V+	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!++	/* Save the argument passing vector registers.  */+	stp	q0, q1, [sp, #16 + 0]+	stp	q2, q3, [sp, #16 + 32]+	stp	q4, q5, [sp, #16 + 64]+	stp	q6, q7, [sp, #16 + 96]+	b	ffi_go_closure_SYSV_save_argument+	NESTED_END	ffi_go_closure_SYSV_V++	NESTED_ENTRY	ffi_go_closure_SYSV+	PROLOG_SAVE_REG_PAIR	x29, x30, #-ffi_closure_SYSV_FS!++ffi_go_closure_SYSV_save_argument+	/* Save the argument passing core registers.  */+	stp     x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]+	stp     x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]+	stp     x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]+	stp     x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]++	/* Load ffi_closure_inner arguments.  */+	ldp	PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */+	mov	x2, x18					/* load user_data */+	b	do_closure+	NESTED_END	ffi_go_closure_SYSV++#endif /* FFI_GO_CLOSURES */+++/* void extend_hfa_type (void *dest, void *src, int h) */++	LEAF_ENTRY	extend_hfa_type++	adr	x3, extend_hfa_type_jump_base+	and	w2, w2, #AARCH64_RET_MASK+	sub	x2, x2, #AARCH64_RET_S4+	add	x3, x3, x2, lsl #4+	br	x3++	ALIGN	4+extend_hfa_type_jump_base+	ldp	s16, s17, [x1]		/* S4 */+	ldp	s18, s19, [x1, #8]+	b	extend_hfa_type_store_4+	nop++	ldp	s16, s17, [x1]		/* S3 */+	ldr	s18, [x1, #8]+	b	extend_hfa_type_store_3+	nop++	ldp	s16, s17, [x1]		/* S2 */+	b	extend_hfa_type_store_2+	nop+	nop++	ldr	s16, [x1]		/* S1 */+	b	extend_hfa_type_store_1+	nop+	nop++	ldp	d16, d17, [x1]		/* D4 */+	ldp	d18, d19, [x1, #16]+	b       extend_hfa_type_store_4+	nop++	ldp     d16, d17, [x1]		/* D3 */+	ldr     d18, [x1, #16]+	b	extend_hfa_type_store_3+	nop++	ldp	d16, d17, [x1]		/* D2 */+	b	extend_hfa_type_store_2+	nop+	nop++	ldr	d16, [x1]		/* D1 */+	b	extend_hfa_type_store_1+	nop+	nop++	ldp	q16, q17, [x1]		/* Q4 */+	ldp	q18, q19, [x1, #16]+	b	extend_hfa_type_store_4+	nop++	ldp	q16, q17, [x1]		/* Q3 */+	ldr	q18, [x1, #16]+	b	extend_hfa_type_store_3+	nop++	ldp	q16, q17, [x1]		/* Q2 */+	b	extend_hfa_type_store_2+	nop+	nop++	ldr	q16, [x1]		/* Q1 */+	b	extend_hfa_type_store_1++extend_hfa_type_store_4+	str	q19, [x0, #48]+extend_hfa_type_store_3+	str	q18, [x0, #32]+extend_hfa_type_store_2+	str	q17, [x0, #16]+extend_hfa_type_store_1+	str	q16, [x0]+	ret++	LEAF_END	extend_hfa_type+++/* void compress_hfa_type (void *dest, void *reg, int h) */++	LEAF_ENTRY	compress_hfa_type++	adr	x3, compress_hfa_type_jump_base+	and	w2, w2, #AARCH64_RET_MASK+	sub	x2, x2, #AARCH64_RET_S4+	add	x3, x3, x2, lsl #4+	br	x3++	ALIGN	4+compress_hfa_type_jump_base+	ldp	q16, q17, [x1]		/* S4 */+	ldp	q18, q19, [x1, #32]+	st4	{ v16.s, v17.s, v18.s, v19.s }[0], [x0]+	ret++	ldp	q16, q17, [x1]		/* S3 */+	ldr	q18, [x1, #32]+	st3	{ v16.s, v17.s, v18.s }[0], [x0]+	ret++	ldp	q16, q17, [x1]		/* S2 */+	st2	{ v16.s, v17.s }[0], [x0]+	ret+	nop++	ldr	q16, [x1]		/* S1 */+	st1	{ v16.s }[0], [x0]+	ret+	nop++	ldp	q16, q17, [x1]		/* D4 */+	ldp	q18, q19, [x1, #32]+	st4	{ v16.d, v17.d, v18.d, v19.d }[0], [x0]+	ret++	ldp	q16, q17, [x1]		/* D3 */+	ldr	q18, [x1, #32]+	st3	{ v16.d, v17.d, v18.d }[0], [x0]+	ret++	ldp	q16, q17, [x1]		/* D2 */+	st2	{ v16.d, v17.d }[0], [x0]+	ret+	nop++	ldr	q16, [x1]		/* D1 */+	st1	{ v16.d }[0], [x0]+	ret+	nop++	ldp	q16, q17, [x1]		/* Q4 */+	ldp	q18, q19, [x1, #32]+	b	compress_hfa_type_store_q4+	nop++	ldp	q16, q17, [x1]		/* Q3 */+	ldr	q18, [x1, #32]+	b	compress_hfa_type_store_q3+	nop++	ldp	q16, q17, [x1]		/* Q2 */+	stp	q16, q17, [x0]+	ret+	nop++	ldr	q16, [x1]		/* Q1 */+	str	q16, [x0]+	ret++compress_hfa_type_store_q4+	str	q19, [x0, #48]+compress_hfa_type_store_q3+	str	q18, [x0, #32]+	stp	q16, q17, [x0]+	ret++	LEAF_END	compress_hfa_type++	END
+ src/alpha/ffi.c view
@@ -0,0 +1,521 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2012  Anthony Green+	   Copyright (c) 1998, 2001, 2007, 2008  Red Hat, Inc.++   Alpha Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>+#include "internal.h"++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;+   all further uses in this file will refer to the 128-bit type.  */+#if defined(__LONG_DOUBLE_128__)+# if FFI_TYPE_LONGDOUBLE != 4+#  error FFI_TYPE_LONGDOUBLE out of date+# endif+#else+# undef FFI_TYPE_LONGDOUBLE+# define FFI_TYPE_LONGDOUBLE 4+#endif++extern void ffi_call_osf(void *stack, void *frame, unsigned flags,+			 void *raddr, void (*fn)(void), void *closure)+	FFI_HIDDEN;+extern void ffi_closure_osf(void) FFI_HIDDEN;+extern void ffi_go_closure_osf(void) FFI_HIDDEN;++/* Promote a float value to its in-register double representation.+   Unlike actually casting to double, this does not trap on NaN.  */+static inline UINT64 lds(void *ptr)+{+  UINT64 ret;+  asm("lds %0,%1" : "=f"(ret) : "m"(*(UINT32 *)ptr));+  return ret;+}++/* And the reverse.  */+static inline void sts(void *ptr, UINT64 val)+{+  asm("sts %1,%0" : "=m"(*(UINT32 *)ptr) : "f"(val));+}++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep(ffi_cif *cif)+{+  size_t bytes = 0;+  int flags, i, avn;+  ffi_type *rtype, *itype;++  if (cif->abi != FFI_OSF)+    return FFI_BAD_ABI;++  /* Compute the size of the argument area.  */+  for (i = 0, avn = cif->nargs; i < avn; i++)+    {+      itype = cif->arg_types[i];+      switch (itype->type)+	{+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_POINTER:+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	  /* All take one 8 byte slot.  */+	  bytes += 8;+	  break;++	case FFI_TYPE_VOID:+	case FFI_TYPE_STRUCT:+	  /* Passed by value in N slots.  */+	  bytes += FFI_ALIGN(itype->size, FFI_SIZEOF_ARG);+	  break;++	case FFI_TYPE_COMPLEX:+	  /* _Complex long double passed by reference; others in 2 slots.  */+	  if (itype->elements[0]->type == FFI_TYPE_LONGDOUBLE)+	    bytes += 8;+	  else+	    bytes += 16;+	  break;++	default:+	  abort();+	}+    }++  /* Set the return type flag */+  rtype = cif->rtype;+  switch (rtype->type)+    {+    case FFI_TYPE_VOID:+      flags = ALPHA_FLAGS(ALPHA_ST_VOID, ALPHA_LD_VOID);+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_SINT32:+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT32);+      break;+    case FFI_TYPE_FLOAT:+      flags = ALPHA_FLAGS(ALPHA_ST_FLOAT, ALPHA_LD_FLOAT);+      break;+    case FFI_TYPE_DOUBLE:+      flags = ALPHA_FLAGS(ALPHA_ST_DOUBLE, ALPHA_LD_DOUBLE);+      break;+    case FFI_TYPE_UINT8:+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT8);+      break;+    case FFI_TYPE_SINT8:+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT8);+      break;+    case FFI_TYPE_UINT16:+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT16);+      break;+    case FFI_TYPE_SINT16:+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT16);+      break;+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_POINTER:+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);+      break;+    case FFI_TYPE_LONGDOUBLE:+    case FFI_TYPE_STRUCT:+      /* Passed in memory, with a hidden pointer.  */+      flags = ALPHA_RET_IN_MEM;+      break;+    case FFI_TYPE_COMPLEX:+      itype = rtype->elements[0];+      switch (itype->type)+	{+	case FFI_TYPE_FLOAT:+	  flags = ALPHA_FLAGS(ALPHA_ST_CPLXF, ALPHA_LD_CPLXF);+	  break;+	case FFI_TYPE_DOUBLE:+	  flags = ALPHA_FLAGS(ALPHA_ST_CPLXD, ALPHA_LD_CPLXD);+	  break;+	default:+	  if (rtype->size <= 8)+	    flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);+	  else+	    flags = ALPHA_RET_IN_MEM;+	  break;+	}+      break;+    default:+      abort();+    }+  cif->flags = flags;++  /* Include the hidden structure pointer in args requirement.  */+  if (flags == ALPHA_RET_IN_MEM)+    bytes += 8;+  /* Minimum size is 6 slots, so that ffi_call_osf can pop them.  */+  if (bytes < 6*8)+    bytes = 6*8;+  cif->bytes = bytes;++  return FFI_OK;+}++static unsigned long+extend_basic_type(void *valp, int type, int argn)+{+  switch (type)+    {+    case FFI_TYPE_SINT8:+      return *(SINT8 *)valp;+    case FFI_TYPE_UINT8:+      return *(UINT8 *)valp;+    case FFI_TYPE_SINT16:+      return *(SINT16 *)valp;+    case FFI_TYPE_UINT16:+      return *(UINT16 *)valp;++    case FFI_TYPE_FLOAT:+      if (argn < 6)+	return lds(valp);+      /* FALLTHRU */++    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+      /* Note that unsigned 32-bit quantities are sign extended.  */+      return *(SINT32 *)valp;++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_POINTER:+    case FFI_TYPE_DOUBLE:+      return *(UINT64 *)valp;++    default:+      abort();+    }+}++static void+ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,+	      void **avalue, void *closure)+{+  unsigned long *argp;+  long i, avn, argn, flags = cif->flags;+  ffi_type **arg_types;+  void *frame;++  /* 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 && flags == ALPHA_RET_IN_MEM)+    rvalue = alloca(cif->rtype->size);++  /* Allocate the space for the arguments, plus 4 words of temp+     space for ffi_call_osf.  */+  argp = frame = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);+  frame += cif->bytes;++  argn = 0;+  if (flags == ALPHA_RET_IN_MEM)+    argp[argn++] = (unsigned long)rvalue;++  avn = cif->nargs;+  arg_types = cif->arg_types;++  for (i = 0, avn = cif->nargs; i < avn; i++)+    {+      ffi_type *ty = arg_types[i];+      void *valp = avalue[i];+      int type = ty->type;+      size_t size;++      switch (type)+	{+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_POINTER:+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	  argp[argn] = extend_basic_type(valp, type, argn);+	  argn++;+	  break;++	case FFI_TYPE_LONGDOUBLE:+	by_reference:+	  /* Note that 128-bit long double is passed by reference.  */+	  argp[argn++] = (unsigned long)valp;+	  break;++	case FFI_TYPE_VOID:+	case FFI_TYPE_STRUCT:+	  size = ty->size;+	  memcpy(argp + argn, valp, size);+	  argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;+	  break;++	case FFI_TYPE_COMPLEX:+	  type = ty->elements[0]->type;+	  if (type == FFI_TYPE_LONGDOUBLE)+	    goto by_reference;++	  /* Most complex types passed as two separate arguments.  */+	  size = ty->elements[0]->size;+	  argp[argn] = extend_basic_type(valp, type, argn);+	  argp[argn + 1] = extend_basic_type(valp + size, type, argn + 1);+	  argn += 2;+	  break;++	default:+	  abort();+	}+    }++  flags = (flags >> ALPHA_ST_SHIFT) & 0xff;+  ffi_call_osf(argp, frame, flags, rvalue, fn, closure);+}++void+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int(cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int(cif, fn, rvalue, avalue, closure);+}++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;++  if (cif->abi != FFI_OSF)+    return FFI_BAD_ABI;++  tramp = (unsigned int *) &closure->tramp[0];+  tramp[0] = 0x47fb0401;	/* mov $27,$1		*/+  tramp[1] = 0xa77b0010;	/* ldq $27,16($27)	*/+  tramp[2] = 0x6bfb0000;	/* jmp $31,($27),0	*/+  tramp[3] = 0x47ff041f;	/* nop			*/+  *(void **) &tramp[4] = ffi_closure_osf;++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  /* Flush the Icache.++     Tru64 UNIX as doesn't understand the imb mnemonic, so use call_pal+     instead, since both Compaq as and gas can handle it.++     0x86 is PAL_imb in Tru64 UNIX <alpha/pal.h>.  */+  asm volatile ("call_pal 0x86" : : : "memory");++  return FFI_OK;+}++ffi_status+ffi_prep_go_closure (ffi_go_closure* closure,+		     ffi_cif* cif,+		     void (*fun)(ffi_cif*, void*, void**, void*))+{+  if (cif->abi != FFI_OSF)+    return FFI_BAD_ABI;++  closure->tramp = (void *)ffi_go_closure_osf;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++long FFI_HIDDEN+ffi_closure_osf_inner (ffi_cif *cif,+		       void (*fun)(ffi_cif*, void*, void**, void*),+		       void *user_data,+		       void *rvalue, unsigned long *argp)+{+  void **avalue;+  ffi_type **arg_types;+  long i, avn, argn, flags;++  avalue = alloca(cif->nargs * sizeof(void *));+  flags = cif->flags;+  argn = 0;++  /* Copy the caller's structure return address to that the closure+     returns the data directly to the caller.  */+  if (flags == ALPHA_RET_IN_MEM)+    {+      rvalue = (void *) argp[0];+      argn = 1;+    }++  arg_types = cif->arg_types;++  /* Grab the addresses of the arguments from the stack frame.  */+  for (i = 0, avn = cif->nargs; i < avn; i++)+    {+      ffi_type *ty = arg_types[i];+      int type = ty->type;+      void *valp = &argp[argn];+      size_t size;++      switch (type)+	{+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_POINTER:+	  argn += 1;+	  break;++	case FFI_TYPE_VOID:+	case FFI_TYPE_STRUCT:+	  size = ty->size;+	  argn += FFI_ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;+	  break;++	case FFI_TYPE_FLOAT:+	  /* Floats coming from registers need conversion from double+	     back to float format.  */+	  if (argn < 6)+	    {+	      valp = &argp[argn - 6];+	      sts(valp, argp[argn - 6]);+	    }+	  argn += 1;+	  break;++	case FFI_TYPE_DOUBLE:+	  if (argn < 6)+	    valp = &argp[argn - 6];+	  argn += 1;+	  break;++	case FFI_TYPE_LONGDOUBLE:+	by_reference:+	  /* 128-bit long double is passed by reference.  */+	  valp = (void *)argp[argn];+	  argn += 1;+	  break;++	case FFI_TYPE_COMPLEX:+	  type = ty->elements[0]->type;+	  switch (type)+	    {+	    case FFI_TYPE_SINT64:+	    case FFI_TYPE_UINT64:+	      /* Passed as separate arguments, but they wind up sequential.  */+	      break;++	    case FFI_TYPE_INT:+	    case FFI_TYPE_SINT8:+	    case FFI_TYPE_UINT8:+	    case FFI_TYPE_SINT16:+	    case FFI_TYPE_UINT16:+	    case FFI_TYPE_SINT32:+	    case FFI_TYPE_UINT32:+	      /* Passed as separate arguments.  Disjoint, but there's room+		 enough in one slot to hold the pair.  */+	      size = ty->elements[0]->size;+	      memcpy(valp + size, valp + 8, size);+	      break;++	    case FFI_TYPE_FLOAT:+	      /* Passed as separate arguments.  Disjoint, and each piece+		 may need conversion back to float.  */+	      if (argn < 6)+		{+		  valp = &argp[argn - 6];+		  sts(valp, argp[argn - 6]);+		}+	      if (argn + 1 < 6)+		sts(valp + 4, argp[argn + 1 - 6]);+	      else+		*(UINT32 *)(valp + 4) = argp[argn + 1];+	      break;++	    case FFI_TYPE_DOUBLE:+	      /* Passed as separate arguments.  Only disjoint if one part+		 is in fp regs and the other is on the stack.  */+	      if (argn < 5)+		valp = &argp[argn - 6];+	      else if (argn == 5)+		{+		  valp = alloca(16);+		  ((UINT64 *)valp)[0] = argp[5 - 6];+		  ((UINT64 *)valp)[1] = argp[6];+		}+	      break;++	    case FFI_TYPE_LONGDOUBLE:+	      goto by_reference;++	    default:+	      abort();+	    }+	  argn += 2;+	  break;++	default:+	  abort ();+	}++      avalue[i] = valp;+    }++  /* Invoke the closure.  */+  fun (cif, rvalue, avalue, user_data);++  /* Tell ffi_closure_osf how to perform return type promotions.  */+  return (flags >> ALPHA_LD_SHIFT) & 0xff;+}
+ src/alpha/ffitarget.h view
@@ -0,0 +1,57 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for Alpha.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_OSF,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_OSF+} ffi_abi;+#endif++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION+#define FFI_TARGET_HAS_COMPLEX_TYPE++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 24+#define FFI_NATIVE_RAW_API 0++#endif
+ src/alpha/internal.h view
@@ -0,0 +1,23 @@+#define ALPHA_ST_VOID	0+#define ALPHA_ST_INT	1+#define ALPHA_ST_FLOAT	2+#define ALPHA_ST_DOUBLE	3+#define ALPHA_ST_CPLXF	4+#define ALPHA_ST_CPLXD	5++#define ALPHA_LD_VOID	0+#define ALPHA_LD_INT64	1+#define ALPHA_LD_INT32	2+#define ALPHA_LD_UINT16	3+#define ALPHA_LD_SINT16	4+#define ALPHA_LD_UINT8	5+#define ALPHA_LD_SINT8	6+#define ALPHA_LD_FLOAT	7+#define ALPHA_LD_DOUBLE	8+#define ALPHA_LD_CPLXF	9+#define ALPHA_LD_CPLXD	10++#define ALPHA_ST_SHIFT		0+#define ALPHA_LD_SHIFT		8+#define ALPHA_RET_IN_MEM	0x10000+#define ALPHA_FLAGS(S, L)	(((L) << ALPHA_LD_SHIFT) | (S))
+ src/alpha/osf.S view
@@ -0,0 +1,282 @@+/* -----------------------------------------------------------------------+   osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat++   Alpha/OSF Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "internal.h"++	.arch ev6+	.text++/* Aid in building a direct addressed jump table, 4 insns per entry.  */+.macro E index+	.align	4+	.org	99b + \index * 16+.endm++/* ffi_call_osf (void *stack, void *frame, unsigned flags,+		 void *raddr, void (*fnaddr)(void), void *closure)++   Bit o trickiness here -- FRAME is the base of the stack frame+   for this function.  This has been allocated by ffi_call.  We also+   deallocate some of the stack that has been alloca'd.  */++	.align	4+	.globl	ffi_call_osf+	.ent	ffi_call_osf+	FFI_HIDDEN(ffi_call_osf)++ffi_call_osf:+	cfi_startproc+	cfi_def_cfa($17, 32)+	mov	$16, $30+	stq	$26, 0($17)+	stq	$15, 8($17)+	mov	$17, $15+	.prologue 0+	cfi_def_cfa_register($15)+	cfi_rel_offset($26, 0)+	cfi_rel_offset($15, 8)++	stq	$18, 16($17)		# save flags into frame+	stq	$19, 24($17)		# save rvalue into frame+	mov	$20, $27		# fn into place for call+	mov	$21, $1			# closure into static chain++	# Load up all of the (potential) argument registers.+	ldq	$16, 0($30)+	ldt	$f16, 0($30)+	ldt	$f17, 8($30)+	ldq	$17, 8($30)+	ldt	$f18, 16($30)+	ldq	$18, 16($30)+	ldt	$f19, 24($30)+	ldq	$19, 24($30)+	ldt	$f20, 32($30)+	ldq	$20, 32($30)+	ldt	$f21, 40($30)+	ldq	$21, 40($30)++	# Deallocate the register argument area.+	lda	$30, 48($30)++	jsr	$26, ($27), 0+0:+	ldah	$29, 0($26)		!gpdisp!1+	ldq	$2, 24($15)		# reload rvalue+	lda	$29, 0($29)		!gpdisp!1+	ldq	$3, 16($15)		# reload flags+	lda	$1, 99f-0b($26)+	ldq	$26, 0($15)+	ldq	$15, 8($15)+	cfi_restore($26)+	cfi_restore($15)+	cfi_def_cfa($sp, 0)+	cmoveq	$2, ALPHA_ST_VOID, $3	# mash null rvalue to void+	addq	$3, $3, $3+	s8addq	$3, $1, $1		# 99f + stcode * 16+	jmp	$31, ($1), $st_int++	.align	4+99:+E ALPHA_ST_VOID+	ret+E ALPHA_ST_INT+$st_int:+	stq	$0, 0($2)+	ret+E ALPHA_ST_FLOAT+	sts	$f0, 0($2)+	ret+E ALPHA_ST_DOUBLE+	stt	$f0, 0($2)+	ret+E ALPHA_ST_CPLXF+	sts	$f0, 0($2)+	sts	$f1, 4($2)+	ret+E ALPHA_ST_CPLXD+	stt	$f0, 0($2)+	stt	$f1, 8($2)+	ret++	cfi_endproc+	.end	ffi_call_osf++/* ffi_closure_osf(...)++   Receives the closure argument in $1.   */++#define CLOSURE_FS	(16*8)++	.align	4+	.globl	ffi_go_closure_osf+	.ent	ffi_go_closure_osf+	FFI_HIDDEN(ffi_go_closure_osf)++ffi_go_closure_osf:+	cfi_startproc+	ldgp	$29, 0($27)+	subq	$30, CLOSURE_FS, $30+	cfi_adjust_cfa_offset(CLOSURE_FS)+	stq	$26, 0($30)+	.prologue 1+	cfi_rel_offset($26, 0)++	stq	$16, 10*8($30)+	stq	$17, 11*8($30)+	stq	$18, 12*8($30)++	ldq	$16, 8($1)			# load cif+	ldq	$17, 16($1)			# load fun+	mov	$1, $18				# closure is user_data+	br	$do_closure++	cfi_endproc+	.end	ffi_go_closure_osf++	.align	4+	.globl	ffi_closure_osf+	.ent	ffi_closure_osf+	FFI_HIDDEN(ffi_closure_osf)++ffi_closure_osf:+	cfi_startproc+	ldgp	$29, 0($27)+	subq	$30, CLOSURE_FS, $30+	cfi_adjust_cfa_offset(CLOSURE_FS)+	stq	$26, 0($30)+	.prologue 1+	cfi_rel_offset($26, 0)++	# Store all of the potential argument registers in va_list format.+	stq	$16, 10*8($30)+	stq	$17, 11*8($30)+	stq	$18, 12*8($30)++	ldq	$16, 24($1)			# load cif+	ldq	$17, 32($1)			# load fun+	ldq	$18, 40($1)			# load user_data++$do_closure:+	stq	$19, 13*8($30)+	stq	$20, 14*8($30)+	stq	$21, 15*8($30)+	stt	$f16, 4*8($30)+	stt	$f17, 5*8($30)+	stt	$f18, 6*8($30)+	stt	$f19, 7*8($30)+	stt	$f20, 8*8($30)+	stt	$f21, 9*8($30)++	# Call ffi_closure_osf_inner to do the bulk of the work.+	lda	$19, 2*8($30)+	lda	$20, 10*8($30)+	jsr	$26, ffi_closure_osf_inner+0:+	ldah	$29, 0($26)			!gpdisp!2+	lda	$2, 99f-0b($26)+	s4addq	$0, 0, $1			# ldcode * 4+	ldq	$0, 16($30)			# preload return value+	s4addq	$1, $2, $1			# 99f + ldcode * 16+	lda	$29, 0($29)			!gpdisp!2+	ldq	$26, 0($30)+	cfi_restore($26)+	jmp	$31, ($1), $load_32++.macro epilogue+	addq	$30, CLOSURE_FS, $30+	cfi_adjust_cfa_offset(-CLOSURE_FS)+	ret+	.align	4+	cfi_adjust_cfa_offset(CLOSURE_FS)+.endm++	.align 4+99:+E ALPHA_LD_VOID+	epilogue++E ALPHA_LD_INT64+	epilogue++E ALPHA_LD_INT32+$load_32:+	sextl	$0, $0+	epilogue++E ALPHA_LD_UINT16+	zapnot	$0, 3, $0+	epilogue++E ALPHA_LD_SINT16+#ifdef __alpha_bwx__+	sextw	$0, $0+#else+	sll	$0, 48, $0+	sra	$0, 48, $0+#endif+	epilogue++E ALPHA_LD_UINT8+	and	$0, 0xff, $0+	epilogue++E ALPHA_LD_SINT8+#ifdef __alpha_bwx__+	sextb	$0, $0+#else+	sll	$0, 56, $0+	sra	$0, 56, $0+#endif+	epilogue++E ALPHA_LD_FLOAT+	lds	$f0, 16($sp)+	epilogue++E ALPHA_LD_DOUBLE+	ldt	$f0, 16($sp)+	epilogue++E ALPHA_LD_CPLXF+	lds	$f0, 16($sp)+	lds	$f1, 20($sp)+	epilogue++E ALPHA_LD_CPLXD+	ldt	$f0, 16($sp)+	ldt	$f1, 24($sp)+	epilogue++	cfi_endproc+	.end	ffi_closure_osf++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/arc/arcompact.S view
@@ -0,0 +1,210 @@+/* -----------------------------------------------------------------------+   arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com)+   +   ARCompact 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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#ifdef HAVE_MACHINE_ASM_H+#include <machine/asm.h>+#else+#define CNAME(x) x+#define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x):+#endif++#if __SIZEOF_POINTER__ == 8+#define PTRS 8+#define FLTS 8+#define LARG ldl+#define SARG stl+#define ADDPTR addl+#define MOVPTR movl+#else+#define PTRS 4+#define FLTS 4+#define LARG ld+#define SARG st+#define ADDPTR add+#define MOVPTR mov+#endif++#define FRAME_LEN (8 * PTRS + 16)++.text++ENTRY(ffi_call_asm)+        .cfi_startproc++        /* Save registers.  */+        .cfi_def_cfa r1, FRAME_LEN+        SARG    fp, [r1, FRAME_LEN - 2*PTRS]+        .cfi_offset fp, -2*PTRS+        SARG    blink, [r1, FRAME_LEN - 1*PTRS]+        .cfi_offset blink, -1*PTRS+        ADDPTR  fp, r1, FRAME_LEN+        MOVPTR  sp, r0+        .cfi_def_cfa fp, 0++        /* Load arguments.  */+        MOVPTR  r11, r2      /* fn */+        MOVPTR  r12, r3      /* closure */++        /* Save arguments.  */+        LARG    r0, [fp, -FRAME_LEN+0*PTRS]+        LARG    r1, [fp, -FRAME_LEN+1*PTRS]+        LARG    r2, [fp, -FRAME_LEN+2*PTRS]+        LARG    r3, [fp, -FRAME_LEN+3*PTRS]+        LARG    r4, [fp, -FRAME_LEN+4*PTRS]+        LARG    r5, [fp, -FRAME_LEN+5*PTRS]+        LARG    r6, [fp, -FRAME_LEN+6*PTRS]+        LARG    r7, [fp, -FRAME_LEN+7*PTRS]++        /* Call the function.  */+        jl         [r11] ++        /* Save return value (r0/r1)  */+        SARG    r0, [fp, -FRAME_LEN+0*PTRS]+        SARG    r1, [fp, -FRAME_LEN+1*PTRS]++        /* Restore and return.  */+        add     sp, fp, -FRAME_LEN+        .cfi_def_cfa sp, FRAME_LEN+        LARG    blink, [fp, -1*PTRS]+        .cfi_restore blink+        LARG    fp, [fp, -2*PTRS]+        .cfi_restore fp+        j_s     [blink]+        .cfi_endproc+        .size   ffi_call_asm, .-ffi_call_asm++/*+  ffi_closure_asm. Expects address of the passed-in ffi_closure in r8.+  void ffi_closure_inner (ffi_cif *cif,+		          void (*fun) (ffi_cif *, void *, void **, void *),+		          void *user_data,+		          size_t *stackargs, struct call_context *regargs)+*/++ENTRY(ffi_closure_asm)+        .cfi_startproc++        ADDPTR  sp, sp, -FRAME_LEN+        .cfi_def_cfa_offset FRAME_LEN++        /* Make a frame.  */+        SARG    fp, [sp, FRAME_LEN-2*PTRS]+        .cfi_offset fp, -2*PTRS+        SARG    blink, [sp, FRAME_LEN-1*PTRS]+        .cfi_offset blink, -1*PTRS+        ADDPTR  fp, sp, FRAME_LEN++        /* Save arguments.  */+        SARG    r0, [sp, 0*PTRS]+        SARG    r1, [sp, 1*PTRS]+        SARG    r2, [sp, 2*PTRS]+        SARG    r3, [sp, 3*PTRS]+        SARG    r4, [sp, 4*PTRS]+        SARG    r5, [sp, 5*PTRS]+        SARG    r6, [sp, 6*PTRS]+        SARG    r7, [sp, 7*PTRS]++        /* Enter C.  */+        LARG    r0, [r8, FFI_TRAMPOLINE_SIZE+0*PTRS]+        LARG    r1, [r8, FFI_TRAMPOLINE_SIZE+1*PTRS]+        LARG    r2, [r8, FFI_TRAMPOLINE_SIZE+2*PTRS]+        ADDPTR  r3, sp, FRAME_LEN+        MOVPTR  r4, sp++        /* Call the C code.  */+        bl      ffi_closure_inner+        +        /* Return values.  */+        LARG    r0, [sp, 0*PTRS]+        LARG    r1, [sp, 1*PTRS]++        /* Restore and return.  */+        LARG    blink, [sp, FRAME_LEN-1*PTRS]+        .cfi_restore blink+        LARG    fp, [sp, FRAME_LEN-2*PTRS]+        .cfi_restore fp+        ADDPTR  sp, sp, FRAME_LEN+        .cfi_def_cfa_offset 0+        j_s     [blink]+        .cfi_endproc+        .size ffi_closure_asm, .-ffi_closure_asm++/*+  ffi_go_closure_asm.  Expects address of the passed-in ffi_go_closure in r12.+  void ffi_closure_inner (ffi_cif *cif,+		          void (*fun) (ffi_cif *, void *, void **, void *),+		          void *user_data,+		          size_t *stackargs, struct call_context *regargs)+*/++ENTRY(ffi_go_closure_asm)+        .cfi_startproc++        ADDPTR  sp, sp, -FRAME_LEN+        .cfi_def_cfa_offset FRAME_LEN++        /* make a frame */+        SARG    fp, [sp, FRAME_LEN-2*PTRS]+        .cfi_offset fp, -2*PTRS+        SARG    blink, [sp, FRAME_LEN-1*PTRS]+        .cfi_offset blink, -1*PTRS+        ADDPTR  fp, sp, FRAME_LEN++        /* save arguments */+        SARG    r0, [sp, 0*PTRS]+        SARG    r1, [sp, 1*PTRS]+        SARG    r2, [sp, 2*PTRS]+        SARG    r3, [sp, 3*PTRS]+        SARG    r4, [sp, 4*PTRS]+        SARG    r5, [sp, 5*PTRS]+        SARG    r6, [sp, 6*PTRS]+        SARG    r7, [sp, 7*PTRS]++        /* enter C */+        LARG    r0, [r12, 1*PTRS]+        LARG    r1, [r12, 2*PTRS]+        MOVPTR  r2, r12+        ADDPTR  r3, sp, FRAME_LEN+        MOVPTR  r4, sp++        bl      ffi_closure_inner++        /* Return values. */+        LARG    r0, [sp, 0*PTRS]+        LARG    r1, [sp, 1*PTRS]+++        LARG    blink, [sp, FRAME_LEN-1*PTRS]+        .cfi_restore blink+        LARG    fp, [sp, FRAME_LEN-2*PTRS]+        .cfi_restore fp+        ADDPTR  sp, sp, FRAME_LEN+        .cfi_def_cfa_offset 0+        j_s     [blink]+        .cfi_endproc+        .size ffi_go_closure_asm, .-ffi_go_closure_asm
+ src/arc/ffi.c view
@@ -0,0 +1,447 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2013  Synopsys, Inc. (www.synopsys.com)+   +   ARC 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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdint.h>++#include <sys/cachectl.h>++#define NARGREG 8+#define STKALIGN 4+#define MAXCOPYARG (2 * sizeof(double))++typedef struct call_context+{+  size_t r[8];+  /* used by the assembly code to in-place construct its own stack frame */+  char frame[16];+} call_context;++typedef struct call_builder+{+  call_context *aregs;+  int used_integer;+  //int used_float;+  size_t *used_stack;+  void *struct_stack;+} call_builder;++/* integer (not pointer) less than ABI XLEN */+/* FFI_TYPE_INT does not appear to be used */+#if defined(__ARC64_ARCH64__)+#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)+#else+#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)+#endif++/* for little endian ARC, the code is in fact stored as mixed endian for+   performance reasons */+#if __BIG_ENDIAN__+#define CODE_ENDIAN(x) (x)+#else+#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16))+#endif++/* Perform machine dependent cif processing.  */+ffi_status+ffi_prep_cif_machdep (ffi_cif * cif)+{+  /* Set the return type flag.  */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      cif->flags = (unsigned) cif->rtype->type;+      break;++    case FFI_TYPE_STRUCT:+      cif->flags = (unsigned) cif->rtype->type;+      break;++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_DOUBLE:+      cif->flags = FFI_TYPE_DOUBLE;+      break;++    case FFI_TYPE_FLOAT:+    default:+      cif->flags = FFI_TYPE_INT;+      break;+    }++  return FFI_OK;+}++/* allocates a single register, float register, or XLEN-sized stack slot to a datum */+static void marshal_atom(call_builder *cb, int type, void *data) {+  size_t value = 0;+  switch (type) {+    case FFI_TYPE_UINT8: value = *(uint8_t *)data; break;+    case FFI_TYPE_SINT8: value = *(int8_t *)data; break;+    case FFI_TYPE_UINT16: value = *(uint16_t *)data; break;+    case FFI_TYPE_SINT16: value = *(int16_t *)data; break;+    /* 32-bit quantities are always sign-extended in the ABI */+    case FFI_TYPE_UINT32: value = *(int32_t *)data; break;+    case FFI_TYPE_SINT32: value = *(int32_t *)data; break;+#if defined(__ARC64_ARCH64__)+    case FFI_TYPE_UINT64: value = *(uint64_t *)data; break;+    case FFI_TYPE_SINT64: value = *(int64_t *)data; break;+#endif+    case FFI_TYPE_POINTER: value = *(size_t *)data; break;+    default: FFI_ASSERT(0); break;+  }++  if (cb->used_integer == NARGREG) {+    *cb->used_stack++ = value;+  } else {+    cb->aregs->r[cb->used_integer++] = value;+  }+}++/* adds an argument to a call, or a not by reference return value */+static void marshal(call_builder *cb, ffi_type *type, int var, void *data) {+  size_t realign[2];++#if (defined(__ARC64_ARCH64__) || defined(__ARC64_ARCH32__))+  if (type->size > 2 * __SIZEOF_POINTER__) {+    if (var) {+      marshal_atom(cb, FFI_TYPE_POINTER, &data);+    } else {+      /* copy to stack and pass by reference */+      data = memcpy (cb->struct_stack, data, type->size);+      cb->struct_stack = (size_t *) FFI_ALIGN ((char *) cb->struct_stack + type->size, __SIZEOF_POINTER__);+      marshal_atom(cb, FFI_TYPE_POINTER, &data);+    }+  }+#else+  if (type->type == FFI_TYPE_STRUCT) {+    if (var) {+      if (type->size > 0)+        marshal_atom(cb, FFI_TYPE_POINTER, data);+    } else {+      int i;+      +      for (i = 0; i < type->size; i += sizeof(size_t)) {+        marshal_atom(cb, FFI_TYPE_POINTER, data);+        data += sizeof(size_t);+      }+    }+  }+#endif+  else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {+    marshal_atom(cb, type->type, data);+  } else {+      memcpy(realign, data, type->size);+      if (type->size > 0)+        marshal_atom(cb, FFI_TYPE_POINTER, realign);+      if (type->size > __SIZEOF_POINTER__)+        marshal_atom(cb, FFI_TYPE_POINTER, realign + 1);+  }+}++static void unmarshal_atom(call_builder *cb, int type, void *data) {+  size_t value;++  if (cb->used_integer == NARGREG) {+    value = *cb->used_stack++;+  } else {+    value = cb->aregs->r[cb->used_integer++];+  }++  switch (type) {+    case FFI_TYPE_UINT8: *(uint8_t *)data = value; break;+    case FFI_TYPE_SINT8: *(uint8_t *)data = value; break;+    case FFI_TYPE_UINT16: *(uint16_t *)data = value; break;+    case FFI_TYPE_SINT16: *(uint16_t *)data = value; break;+    case FFI_TYPE_UINT32: *(uint32_t *)data = value; break;+    case FFI_TYPE_SINT32: *(uint32_t *)data = value; break;+#if defined(__ARC64_ARCH64__)+    case FFI_TYPE_UINT64: *(uint64_t *)data = value; break;+    case FFI_TYPE_SINT64: *(uint64_t *)data = value; break;+#endif+    case FFI_TYPE_POINTER: *(size_t *)data = value; break;+    default: FFI_ASSERT(0); break;+  }+}++/* for arguments passed by reference returns the pointer, otherwise the arg is copied (up to MAXCOPYARG bytes) */+static void *unmarshal(call_builder *cb, ffi_type *type, int var, void *data) {+  size_t realign[2];++#if defined(__ARC64_ARCH64__)+  void *pointer;++  if (type->size > 2 * __SIZEOF_POINTER__) {+        /* pass by reference */+        unmarshal_atom(cb, FFI_TYPE_POINTER, (char*)&pointer);+        return pointer;+    }+#elif defined(__ARC64_ARCH32__)+  if (type->type == FFI_TYPE_STRUCT) {+    if (type->size > 2 * __SIZEOF_POINTER__) {+      unmarshal_atom(cb, FFI_TYPE_POINTER, &realign[0]);+      memcpy(data, (const void*)realign[0], type->size);+      return data;+    } else {+      int i;+      void *pdata = data;++      for (i = 0; i < type->size; i += sizeof(size_t)) {+        unmarshal_atom(cb, FFI_TYPE_POINTER, pdata);+        pdata += sizeof(size_t);+      }+      return data;+    }+  }+#else+  if (type->type == FFI_TYPE_STRUCT) {++      if (var) {+        int i;+        void *pdata = data;++        for (i = 0; i < type->size; i += sizeof(size_t)) {+          unmarshal_atom(cb, FFI_TYPE_POINTER, pdata);+          pdata += sizeof(size_t);+        }+        return data;+      } else {+        if (type->size > 0)+          unmarshal_atom(cb, FFI_TYPE_POINTER, &realign[0]);+        memcpy(data, (const void*)realign[0], type->size);+        return data;+      }+  }+#endif+  else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {+    unmarshal_atom(cb, type->type, data);+    return data;+  } else {+      if (type->size > 0)+        unmarshal_atom(cb, FFI_TYPE_POINTER, realign);+      if (type->size > __SIZEOF_POINTER__)+        unmarshal_atom(cb, FFI_TYPE_POINTER, realign + 1);+      memcpy(data, realign, type->size);+      return data;+  }+}++static int passed_by_ref(ffi_type *type, int var) {+  if (type->type == FFI_TYPE_STRUCT)+	  return 1;+  +  return type->size > 2 * __SIZEOF_POINTER__;+}++/* Low level routine for calling functions */+extern void ffi_call_asm (void *stack, struct call_context *regs,+			  void (*fn) (void), void *closure) FFI_HIDDEN;++static void+ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,+	      void *closure)+{+  int return_by_ref = passed_by_ref(cif->rtype, 0);++  /* Allocate space for stack arg parameters.  */+  size_t arg_bytes = FFI_ALIGN(2 * sizeof(size_t) * cif->nargs, STKALIGN);+  /* Allocate space for copies of big structures.  */+  size_t struct_bytes = FFI_ALIGN(cif->bytes, STKALIGN);+  // size_t rval_bytes = 0;+  // if (rvalue == NULL && cif->rtype->size > 2*__SIZEOF_POINTER__)+  //   rval_bytes = FFI_ALIGN(cif->rtype->size, STKALIGN);+  size_t alloc_size = arg_bytes + /*rval_bytes +*/ struct_bytes + sizeof(call_context);+  size_t alloc_base = (size_t)alloca(alloc_size);++  // if (rval_bytes)+  //   rvalue = (void*)(alloc_base + arg_bytes);++  call_builder cb;+  cb.used_integer = 0;+  cb.aregs = (call_context*)(alloc_base + arg_bytes /*+ rval_bytes*/ + struct_bytes);+  cb.used_stack = (void*)alloc_base;+  cb.struct_stack = (void *)(alloc_base + arg_bytes /*+ rval_bytes*/);++  // if (cif->rtype->type == FFI_TYPE_STRUCT)+  //   marshal(&cb, &ffi_type_pointer, 0, &rvalue);++  if (return_by_ref)+	  marshal(&cb, &ffi_type_pointer, 0, &rvalue);++  int i;+  for (i = 0; i < cif->nargs; i++)+    marshal(&cb, cif->arg_types[i], 0, avalue[i]);++  ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure);++  cb.used_integer = 0;+  if (!return_by_ref && rvalue)+    {+	    if (IS_INT(cif->rtype->type)+	        && cif->rtype->size < sizeof (ffi_arg))+	    {+        /* Integer types smaller than ffi_arg need to be extended.  */+	    switch (cif->rtype->type) {+	      case FFI_TYPE_SINT8:+	      case FFI_TYPE_SINT16:+	      case FFI_TYPE_SINT32:+		      unmarshal_atom (&cb, (sizeof (ffi_arg) > 4+                          ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32),+				                  rvalue);+		      break;+	      case FFI_TYPE_UINT8:+	      case FFI_TYPE_UINT16:+	      case FFI_TYPE_UINT32:+		      unmarshal_atom (&cb, (sizeof (ffi_arg) > 4+				                  ? FFI_TYPE_UINT64 : FFI_TYPE_UINT32),+				                  rvalue);+		      break;+	      }+	    }+	    else+	      unmarshal(&cb, cif->rtype, 0, rvalue);+    }+}++void+ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)+{+  ffi_call_int(cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int(cif, fn, rvalue, avalue, closure);+}++extern void ffi_closure_asm(void) FFI_HIDDEN;++ffi_status+ffi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif,+		      void (*fun) (ffi_cif *, void *, void **, void *),+		      void *user_data, void *codeloc)+{+  uint32_t *tramp = (uint32_t *) & (closure->tramp[0]);++#if defined(__ARC64_ARCH64__)+  size_t address_ffi_closure = (size_t) ffi_closure_asm;+#endif++  switch (cif->abi)+    {+#if defined(__ARC64_ARCH64__)+    case FFI_ARC64:+      FFI_ASSERT (tramp == codeloc);+      tramp[0] = CODE_ENDIAN (0x580a1fc0);	/* movl r8, pcl  */+      tramp[1] = CODE_ENDIAN (0x5c0b1f80);	/* movhl r12, limm */+      tramp[2] = CODE_ENDIAN ((uint32_t)(address_ffi_closure >> 32));+      tramp[3] = CODE_ENDIAN (0x5c051f8c);	/* orl r12, r12, limm */+      tramp[4] = CODE_ENDIAN ((uint32_t)(address_ffi_closure & 0xffffffff));+      tramp[5] = CODE_ENDIAN (0x20200300);	/* j [r12] */+      break;+#else+    case FFI_ARCOMPACT:+      FFI_ASSERT (tramp == codeloc);+      tramp[0] = CODE_ENDIAN (0x200a1fc0);	/* mov r8, pcl  */+      tramp[1] = CODE_ENDIAN (0x20200f80);	/* j [long imm] */+      tramp[2] = CODE_ENDIAN ((uint32_t) ffi_closure_asm);+      break;+#endif++    default:+      return FFI_BAD_ABI;+    }++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;+  cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE);++  return FFI_OK;+}++extern void ffi_go_closure_asm (void) FFI_HIDDEN;++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,+		     void (*fun) (ffi_cif *, void *, void **, void *))+{+  if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)+    return FFI_BAD_ABI;++  closure->tramp = (void *) ffi_go_closure_asm;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++/* Called by the assembly code with aregs pointing to saved argument registers+   and stack pointing to the stacked arguments.  Return values passed in+   registers will be reloaded from aregs. */+void FFI_HIDDEN+ffi_closure_inner (ffi_cif *cif,+		   void (*fun) (ffi_cif *, void *, void **, void *),+		   void *user_data,+		   size_t *stack, call_context *aregs)+{+    void **avalue = alloca(cif->nargs * sizeof(void*));+    /* storage for arguments which will be copied by unmarshal().  We could+       theoretically avoid the copies in many cases and use at most 128 bytes+       of memory, but allocating disjoint storage for each argument is+       simpler. */+    char *astorage = alloca(cif->bytes);+    char *ptr = astorage;+    void *rvalue;+    call_builder cb;+    int i;++    cb.aregs = aregs;+    cb.used_integer = 0;+    cb.used_stack = stack;+    +    /* handle hidden argument */+    if (cif->flags == FFI_TYPE_STRUCT)+      unmarshal(&cb, &ffi_type_pointer, 0, &rvalue);+    else+      rvalue = alloca(cif->rtype->size);++    for (i = 0; i < cif->nargs; i++) {+      avalue[i] = unmarshal(&cb, cif->arg_types[i], 1, ptr);+      ptr += cif->arg_types[i]->size;+    }++    fun (cif, rvalue, avalue, user_data);++    if (cif->rtype->type != FFI_TYPE_VOID) {+        cb.used_integer = 0;+        marshal(&cb, cif->rtype, 1, rvalue);+    }+}
+ src/arc/ffitarget.h view
@@ -0,0 +1,67 @@+/* -----------------------------------------------------------------------+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 2013  Synopsys, Inc. (www.synopsys.com)+   Target configuration macros for ARC.++   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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- Generic type definitions ----------------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long ffi_arg;+typedef signed long ffi_sarg;++typedef enum ffi_abi+{+  FFI_FIRST_ABI = 0,+#if __SIZEOF_POINTER__ == 8+  FFI_ARC64,+#else+  FFI_ARCOMPACT,+#endif+  FFI_LAST_ABI,+#if __SIZEOF_POINTER__ == 8+  FFI_DEFAULT_ABI = FFI_ARC64+#else+  FFI_DEFAULT_ABI = FFI_ARCOMPACT+#endif+} ffi_abi;+#endif++#define FFI_CLOSURES 		1+#define FFI_GO_CLOSURES 1+#if __SIZEOF_POINTER__ == 8+#define FFI_TRAMPOLINE_SIZE	24+#else+#define FFI_TRAMPOLINE_SIZE	12+#endif++#define FFI_NATIVE_RAW_API 	0++#endif
+ src/arm/ffi.c view
@@ -0,0 +1,921 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2011 Timothy Wall+           Copyright (c) 2011 Plausible Labs Cooperative, Inc.+           Copyright (c) 2011 Anthony Green+	   Copyright (c) 2011 Free Software Foundation+           Copyright (c) 1998, 2008, 2011  Red Hat, Inc.++   ARM Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#if defined(__arm__) || defined(_M_ARM)+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_common.h>+#include <stdint.h>+#include <stdlib.h>+#include <tramp.h>+#include "internal.h"++#if defined(_WIN32)+#define WIN32_LEAN_AND_MEAN+#include <windows.h>+#endif++#if FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__+#include <mach/machine/vm_param.h>+#endif++#else+#ifndef _WIN32+extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;+#else+// Declare this as an array of char, instead of array of int,+// otherwise Clang optimizes out the "& 0xFFFFFFFE" for clearing+// the thumb bit.+extern unsigned char ffi_arm_trampoline[12] FFI_HIDDEN;+#endif+#endif++#if defined(__FreeBSD__) && defined(__arm__)+#include <sys/types.h>+#include <machine/sysarch.h>+#endif++#if defined(__QNX__)+#include <sys/mman.h>+#endif++/* Forward declares. */+static int vfp_type_p (const ffi_type *);+static void layout_vfp_args (ffi_cif *);++static void *+ffi_align (ffi_type *ty, void *p)+{+  /* Align if necessary */+  size_t alignment;+#ifdef _WIN32_WCE+  alignment = 4;+#else+  alignment = ty->alignment;+  if (alignment < 4)+    alignment = 4;+#endif+  return (void *) FFI_ALIGN (p, alignment);+}++static size_t+ffi_put_arg (ffi_type *ty, void *src, void *dst)+{+  size_t z = ty->size;++  switch (ty->type)+    {+    case FFI_TYPE_SINT8:+      *(UINT32 *)dst = *(SINT8 *)src;+      break;+    case FFI_TYPE_UINT8:+      *(UINT32 *)dst = *(UINT8 *)src;+      break;+    case FFI_TYPE_SINT16:+      *(UINT32 *)dst = *(SINT16 *)src;+      break;+    case FFI_TYPE_UINT16:+      *(UINT32 *)dst = *(UINT16 *)src;+      break;++    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_POINTER:+#ifndef _WIN32+    case FFI_TYPE_FLOAT:+#endif+      *(UINT32 *)dst = *(UINT32 *)src;+      break;++#ifdef _WIN32+    // casting a float* to a UINT32* doesn't work on Windows+    case FFI_TYPE_FLOAT:+        *(uintptr_t *)dst = 0;+        *(float *)dst = *(float *)src;+        break;+#endif++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_DOUBLE:+      *(UINT64 *)dst = *(UINT64 *)src;+      break;++    case FFI_TYPE_STRUCT:+    case FFI_TYPE_COMPLEX:+      memcpy (dst, src, z);+      break;++    default:+      abort();+    }++  return FFI_ALIGN (z, 4);+}++/* ffi_prep_args is called once stack space has been allocated+   for the function's arguments.++   The vfp_space parameter is the load area for VFP regs, the return+   value is cif->vfp_used (word bitset of VFP regs used for passing+   arguments). These are only used for the VFP hard-float ABI.+*/+static void+ffi_prep_args_SYSV (ffi_cif *cif, int flags, void *rvalue,+		    void **avalue, char *argp)+{+  ffi_type **arg_types = cif->arg_types;+  int i, n;++  if (flags == ARM_TYPE_STRUCT)+    {+      *(void **) argp = rvalue;+      argp += 4;+    }++  for (i = 0, n = cif->nargs; i < n; i++)+    {+      ffi_type *ty = arg_types[i];+      argp = ffi_align (ty, argp);+      argp += ffi_put_arg (ty, avalue[i], argp);+    }+}++static void+ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,+                   void **avalue, char *stack, char *vfp_space)+{+  ffi_type **arg_types = cif->arg_types;+  int i, n, vi = 0;+  char *argp, *regp, *eo_regp;+  char stack_used = 0;+  char done_with_regs = 0;++  /* The first 4 words on the stack are used for values+     passed in core registers.  */+  regp = stack;+  eo_regp = argp = regp + 16;++  /* If the function returns an FFI_TYPE_STRUCT in memory,+     that address is passed in r0 to the function.  */+  if (flags == ARM_TYPE_STRUCT)+    {+      *(void **) regp = rvalue;+      regp += 4;+    }++  for (i = 0, n = cif->nargs; i < n; i++)+    {+      ffi_type *ty = arg_types[i];+      void *a = avalue[i];+      int is_vfp_type = vfp_type_p (ty);++      /* Allocated in VFP registers. */+      if (vi < cif->vfp_nargs && is_vfp_type)+	{+	  char *vfp_slot = vfp_space + cif->vfp_args[vi++] * 4;+	  ffi_put_arg (ty, a, vfp_slot);+	  continue;+	}+      /* Try allocating in core registers. */+      else if (!done_with_regs && !is_vfp_type)+	{+	  char *tregp = ffi_align (ty, regp);+	  size_t size = ty->size;+	  size = (size < 4) ? 4 : size;	// pad+	  /* Check if there is space left in the aligned register+	     area to place the argument.  */+	  if (tregp + size <= eo_regp)+	    {+	      regp = tregp + ffi_put_arg (ty, a, tregp);+	      done_with_regs = (regp == argp);+	      // ensure we did not write into the stack area+	      FFI_ASSERT (regp <= argp);+	      continue;+	    }+	  /* In case there are no arguments in the stack area yet,+	     the argument is passed in the remaining core registers+	     and on the stack.  */+	  else if (!stack_used)+	    {+	      stack_used = 1;+	      done_with_regs = 1;+	      argp = tregp + ffi_put_arg (ty, a, tregp);+	      FFI_ASSERT (eo_regp < argp);+	      continue;+	    }+	}+      /* Base case, arguments are passed on the stack */+      stack_used = 1;+      argp = ffi_align (ty, argp);+      argp += ffi_put_arg (ty, a, argp);+    }+}++/* Perform machine dependent cif processing */+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep (ffi_cif *cif)+{+  int flags = 0, cabi = cif->abi;+  size_t bytes = cif->bytes;++  /* Map out the register placements of VFP register args.  The VFP+     hard-float calling conventions are slightly more sophisticated+     than the base calling conventions, so we do it here instead of+     in ffi_prep_args(). */+  if (cabi == FFI_VFP)+    layout_vfp_args (cif);++  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      flags = ARM_TYPE_VOID;+      break;++    case FFI_TYPE_INT:+    case FFI_TYPE_UINT8:+    case FFI_TYPE_SINT8:+    case FFI_TYPE_UINT16:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_POINTER:+      flags = ARM_TYPE_INT;+      break;++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      flags = ARM_TYPE_INT64;+      break;++    case FFI_TYPE_FLOAT:+      flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_S : ARM_TYPE_INT);+      break;+    case FFI_TYPE_DOUBLE:+      flags = (cabi == FFI_VFP ? ARM_TYPE_VFP_D : ARM_TYPE_INT64);+      break;++    case FFI_TYPE_STRUCT:+    case FFI_TYPE_COMPLEX:+      if (cabi == FFI_VFP)+	{+	  int h = vfp_type_p (cif->rtype);++	  flags = ARM_TYPE_VFP_N;+	  if (h == 0x100 + FFI_TYPE_FLOAT)+	    flags = ARM_TYPE_VFP_S;+	  if (h == 0x100 + FFI_TYPE_DOUBLE)+	    flags = ARM_TYPE_VFP_D;+	  if (h != 0)+	      break;+	}++      /* A Composite Type not larger than 4 bytes is returned in r0.+	 A Composite Type larger than 4 bytes, or whose size cannot+	 be determined statically ... is stored in memory at an+	 address passed [in r0].  */+      if (cif->rtype->size <= 4)+	flags = ARM_TYPE_INT;+      else+	{+	  flags = ARM_TYPE_STRUCT;+	  bytes += 4;+	}+      break;++    default:+      abort();+    }++  /* Round the stack up to a multiple of 8 bytes.  This isn't needed+     everywhere, but it is on some platforms, and it doesn't harm anything+     when it isn't needed.  */+  bytes = FFI_ALIGN (bytes, 8);++  /* Minimum stack space is the 4 register arguments that we pop.  */+  if (bytes < 4*4)+    bytes = 4*4;++  cif->bytes = bytes;+  cif->flags = flags;++  return FFI_OK;+}++/* Perform machine dependent cif processing for variadic calls */+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep_var (ffi_cif * cif,+			  unsigned int nfixedargs, unsigned int ntotalargs)+{+  /* VFP variadic calls actually use the SYSV ABI */+  if (cif->abi == FFI_VFP)+    cif->abi = FFI_SYSV;++  return ffi_prep_cif_machdep (cif);+}++/* Prototypes for assembly functions, in sysv.S.  */++struct call_frame+{+  void *fp;+  void *lr;+  void *rvalue;+  int flags;+  void *closure;+};++extern void ffi_call_SYSV (void *stack, struct call_frame *,+			   void (*fn) (void)) FFI_HIDDEN;+extern void ffi_call_VFP (void *vfp_space, struct call_frame *,+			   void (*fn) (void), unsigned vfp_used) FFI_HIDDEN;++static void+ffi_call_int (ffi_cif * cif, void (*fn) (void), void *rvalue,+	      void **avalue, void *closure)+{+  int flags = cif->flags;+  ffi_type *rtype = cif->rtype;+  size_t bytes, rsize, vfp_size;+  char *stack, *vfp_space, *new_rvalue;+  struct call_frame *frame;++  rsize = 0;+  if (rvalue == NULL)+    {+      /* If the return value is a struct and we don't have a return+	 value address then we need to make one.  Otherwise the return+	 value is in registers and we can ignore them.  */+      if (flags == ARM_TYPE_STRUCT)+	rsize = rtype->size;+      else+	flags = ARM_TYPE_VOID;+    }+  else if (flags == ARM_TYPE_VFP_N)+    {+      /* Largest case is double x 4. */+      rsize = 32;+    }+  else if (flags == ARM_TYPE_INT && rtype->type == FFI_TYPE_STRUCT)+    rsize = 4;++  /* Largest case.  */+  vfp_size = (cif->abi == FFI_VFP && cif->vfp_used ? 8*8: 0);++  bytes = cif->bytes;+  stack = alloca (vfp_size + bytes + sizeof(struct call_frame) + rsize);++  vfp_space = NULL;+  if (vfp_size)+    {+      vfp_space = stack;+      stack += vfp_size;+    }++  frame = (struct call_frame *)(stack + bytes);++  new_rvalue = rvalue;+  if (rsize)+    new_rvalue = (void *)(frame + 1);++  frame->rvalue = new_rvalue;+  frame->flags = flags;+  frame->closure = closure;++  if (vfp_space)+    {+      ffi_prep_args_VFP (cif, flags, new_rvalue, avalue, stack, vfp_space);+      ffi_call_VFP (vfp_space, frame, fn, cif->vfp_used);+    }+  else+    {+      ffi_prep_args_SYSV (cif, flags, new_rvalue, avalue, stack);+      ffi_call_SYSV (stack, frame, fn);+    }++  if (rvalue && rvalue != new_rvalue)+    memcpy (rvalue, new_rvalue, rtype->size);+}++void+ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++#ifdef FFI_GO_CLOSURES+void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}+#endif++static void *+ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,+			     char *argp, void **avalue)+{+  ffi_type **arg_types = cif->arg_types;+  int i, n;++  if (cif->flags == ARM_TYPE_STRUCT)+    {+      rvalue = *(void **) argp;+      argp += 4;+    }+  else+    {+      if (cif->rtype->size && cif->rtype->size < 4)+        *(uint32_t *) rvalue = 0;+    }++  for (i = 0, n = cif->nargs; i < n; i++)+    {+      ffi_type *ty = arg_types[i];+      size_t z = ty->size;++      argp = ffi_align (ty, argp);+      avalue[i] = (void *) argp;+      argp += z;+    }++  return rvalue;+}++static void *+ffi_prep_incoming_args_VFP (ffi_cif *cif, void *rvalue, char *stack,+			    char *vfp_space, void **avalue)+{+  ffi_type **arg_types = cif->arg_types;+  int i, n, vi = 0;+  char *argp, *regp, *eo_regp;+  char done_with_regs = 0;+  char stack_used = 0;++  regp = stack;+  eo_regp = argp = regp + 16;++  if (cif->flags == ARM_TYPE_STRUCT)+    {+      rvalue = *(void **) regp;+      regp += 4;+    }++  for (i = 0, n = cif->nargs; i < n; i++)+    {+      ffi_type *ty = arg_types[i];+      int is_vfp_type = vfp_type_p (ty);+      size_t z = ty->size;++      if (vi < cif->vfp_nargs && is_vfp_type)+	{+	  avalue[i] = vfp_space + cif->vfp_args[vi++] * 4;+	  continue;+	}+      else if (!done_with_regs && !is_vfp_type)+	{+	  char *tregp = ffi_align (ty, regp);++	  z = (z < 4) ? 4 : z;	// pad++	  /* If the arguments either fits into the registers or uses registers+	     and stack, while we haven't read other things from the stack */+	  if (tregp + z <= eo_regp || !stack_used)+	    {+	      /* Because we're little endian, this is what it turns into.  */+	      avalue[i] = (void *) tregp;+	      regp = tregp + z;++	      /* If we read past the last core register, make sure we+		 have not read from the stack before and continue+		 reading after regp.  */+	      if (regp > eo_regp)+		{+		  FFI_ASSERT (!stack_used);+		  argp = regp;+		}+	      if (regp >= eo_regp)+		{+		  done_with_regs = 1;+		  stack_used = 1;+		}+	      continue;+	    }+	}++      stack_used = 1;+      argp = ffi_align (ty, argp);+      avalue[i] = (void *) argp;+      argp += z;+    }++  return rvalue;+}++#if FFI_CLOSURES++struct closure_frame+{+  char vfp_space[8*8] __attribute__((aligned(8)));+  char result[8*4];+  char argp[];+};++int FFI_HIDDEN+ffi_closure_inner_SYSV (ffi_cif *cif,+		        void (*fun) (ffi_cif *, void *, void **, void *),+		        void *user_data,+		        struct closure_frame *frame)+{+  void **avalue = (void **) alloca (cif->nargs * sizeof (void *));+  void *rvalue = ffi_prep_incoming_args_SYSV (cif, frame->result,+					      frame->argp, avalue);+  fun (cif, rvalue, avalue, user_data);+  return cif->flags;+}++int FFI_HIDDEN+ffi_closure_inner_VFP (ffi_cif *cif,+		       void (*fun) (ffi_cif *, void *, void **, void *),+		       void *user_data,+		       struct closure_frame *frame)+{+  void **avalue = (void **) alloca (cif->nargs * sizeof (void *));+  void *rvalue = ffi_prep_incoming_args_VFP (cif, frame->result, frame->argp,+					     frame->vfp_space, avalue);+  fun (cif, rvalue, avalue, user_data);+  return cif->flags;+}++void ffi_closure_SYSV (void) FFI_HIDDEN;+void ffi_closure_VFP (void) FFI_HIDDEN;+#if defined(FFI_EXEC_STATIC_TRAMP)+void ffi_closure_SYSV_alt (void) FFI_HIDDEN;+void ffi_closure_VFP_alt (void) FFI_HIDDEN;+#endif++#ifdef FFI_GO_CLOSURES+void ffi_go_closure_SYSV (void) FFI_HIDDEN;+void ffi_go_closure_VFP (void) FFI_HIDDEN;+#endif++/* the cif must already be prep'ed */++#if defined(__FreeBSD__) && defined(__arm__)+#define __clear_cache(start, end) do { \+		struct arm_sync_icache_args ua; 		\+								\+		ua.addr = (uintptr_t)(start);			\+		ua.len = (char *)(end) - (char *)start;		\+		sysarch(ARM_SYNC_ICACHE, &ua);			\+	} while (0);+#endif++ffi_status+ffi_prep_closure_loc (ffi_closure * closure,+		      ffi_cif * cif,+		      void (*fun) (ffi_cif *, void *, void **, void *),+		      void *user_data, void *codeloc)+{+  void (*closure_func) (void) = ffi_closure_SYSV;++  if (cif->abi == FFI_VFP)+    {+      /* We only need take the vfp path if there are vfp arguments.  */+      if (cif->vfp_used)+	closure_func = ffi_closure_VFP;+    }+  else if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++#if FFI_EXEC_TRAMPOLINE_TABLE+  void **config = (void **)((uint8_t *)codeloc - PAGE_MAX_SIZE);+  config[0] = closure;+  config[1] = closure_func;+#else++# if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      if (closure_func == ffi_closure_SYSV)+        closure_func = ffi_closure_SYSV_alt;+      else+        closure_func = ffi_closure_VFP_alt;+      ffi_tramp_set_parms (closure->ftramp, closure_func, closure);+      goto out;+    }+# endif++  /* Initialize the dynamic trampoline. */+# ifndef _WIN32+  memcpy(closure->tramp, ffi_arm_trampoline, 8);+# else+  // cast away function type so MSVC doesn't set the lower bit of the function pointer+  memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);+# endif++# if defined(__QNX__)+  msync (closure->tramp, 8, MS_INVALIDATE_ICACHE);	/* clear data map */+  msync (codeloc, 8, MS_INVALIDATE_ICACHE);		/* clear insn map */+# elif defined(_WIN32)+  FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);+# else+  __clear_cache(closure->tramp, closure->tramp + 8);	/* clear data map */+  __clear_cache(codeloc, codeloc + 8);			/* clear insn map */+# endif+# ifdef _WIN32+  *(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;+# else+  *(void (**)(void))(closure->tramp + 8) = closure_func;+# endif+# if defined(FFI_EXEC_STATIC_TRAMP)+out:+# endif+#endif++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++#ifdef FFI_GO_CLOSURES+ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,+		     void (*fun) (ffi_cif *, void *, void **, void *))+{+  void (*closure_func) (void) = ffi_go_closure_SYSV;++  if (cif->abi == FFI_VFP)+    {+      /* We only need take the vfp path if there are vfp arguments.  */+      if (cif->vfp_used)+	closure_func = ffi_go_closure_VFP;+    }+  else if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  closure->tramp = closure_func;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}+#endif++#endif /* FFI_CLOSURES */++/* Below are routines for VFP hard-float support. */++/* A subroutine of vfp_type_p.  Given a structure type, return the type code+   of the first non-structure element.  Recurse for structure elements.+   Return -1 if the structure is in fact empty, i.e. no nested elements.  */++static int+is_hfa0 (const ffi_type *ty)+{+  ffi_type **elements = ty->elements;+  int i, ret = -1;++  if (elements != NULL)+    for (i = 0; elements[i]; ++i)+      {+        ret = elements[i]->type;+        if (ret == FFI_TYPE_STRUCT || ret == FFI_TYPE_COMPLEX)+          {+            ret = is_hfa0 (elements[i]);+            if (ret < 0)+              continue;+          }+        break;+      }++  return ret;+}++/* A subroutine of vfp_type_p.  Given a structure type, return true if all+   of the non-structure elements are the same as CANDIDATE.  */++static int+is_hfa1 (const ffi_type *ty, int candidate)+{+  ffi_type **elements = ty->elements;+  int i;++  if (elements != NULL)+    for (i = 0; elements[i]; ++i)+      {+        int t = elements[i]->type;+        if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)+          {+            if (!is_hfa1 (elements[i], candidate))+              return 0;+          }+        else if (t != candidate)+          return 0;+      }++  return 1;+}++/* Determine if TY is an homogenous floating point aggregate (HFA).+   That is, a structure consisting of 1 to 4 members of all the same type,+   where that type is a floating point scalar.++   Returns non-zero iff TY is an HFA.  The result is an encoded value where+   bits 0-7 contain the type code, and bits 8-10 contain the element count.  */++static int+vfp_type_p (const ffi_type *ty)+{+  ffi_type **elements;+  int candidate, i;+  size_t size, ele_count;++  /* Quickest tests first.  */+  candidate = ty->type;+  switch (ty->type)+    {+    default:+      return 0;+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+      ele_count = 1;+      goto done;+    case FFI_TYPE_COMPLEX:+      candidate = ty->elements[0]->type;+      if (candidate != FFI_TYPE_FLOAT && candidate != FFI_TYPE_DOUBLE)+	return 0;+      ele_count = 2;+      goto done;+    case FFI_TYPE_STRUCT:+      break;+    }++  /* No HFA types are smaller than 4 bytes, or larger than 32 bytes.  */+  size = ty->size;+  if (size < 4 || size > 32)+    return 0;++  /* Find the type of the first non-structure member.  */+  elements = ty->elements;+  candidate = elements[0]->type;+  if (candidate == FFI_TYPE_STRUCT || candidate == FFI_TYPE_COMPLEX)+    {+      for (i = 0; ; ++i)+        {+          candidate = is_hfa0 (elements[i]);+          if (candidate >= 0)+            break;+        }+    }++  /* If the first member is not a floating point type, it's not an HFA.+     Also quickly re-check the size of the structure.  */+  switch (candidate)+    {+    case FFI_TYPE_FLOAT:+      ele_count = size / sizeof(float);+      if (size != ele_count * sizeof(float))+        return 0;+      break;+    case FFI_TYPE_DOUBLE:+      ele_count = size / sizeof(double);+      if (size != ele_count * sizeof(double))+        return 0;+      break;+    default:+      return 0;+    }+  if (ele_count > 4)+    return 0;++  /* Finally, make sure that all scalar elements are the same type.  */+  for (i = 0; elements[i]; ++i)+    {+      int t = elements[i]->type;+      if (t == FFI_TYPE_STRUCT || t == FFI_TYPE_COMPLEX)+        {+          if (!is_hfa1 (elements[i], candidate))+            return 0;+        }+      else if (t != candidate)+        return 0;+    }++  /* All tests succeeded.  Encode the result.  */+ done:+  return (ele_count << 8) | candidate;+}++static int+place_vfp_arg (ffi_cif *cif, int h)+{+  unsigned short reg = cif->vfp_reg_free;+  int align = 1, nregs = h >> 8;++  if ((h & 0xff) == FFI_TYPE_DOUBLE)+    align = 2, nregs *= 2;++  /* Align register number. */+  if ((reg & 1) && align == 2)+    reg++;++  while (reg + nregs <= 16)+    {+      int s, new_used = 0;+      for (s = reg; s < reg + nregs; s++)+	{+	  new_used |= (1 << s);+	  if (cif->vfp_used & (1 << s))+	    {+	      reg += align;+	      goto next_reg;+	    }+	}+      /* Found regs to allocate. */+      cif->vfp_used |= new_used;+      cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;++      /* Update vfp_reg_free. */+      if (cif->vfp_used & (1 << cif->vfp_reg_free))+	{+	  reg += nregs;+	  while (cif->vfp_used & (1 << reg))+	    reg += 1;+	  cif->vfp_reg_free = reg;+	}+      return 0;+    next_reg:;+    }+  // done, mark all regs as used+  cif->vfp_reg_free = 16;+  cif->vfp_used = 0xFFFF;+  return 1;+}++static void+layout_vfp_args (ffi_cif * cif)+{+  unsigned int i;+  /* Init VFP fields */+  cif->vfp_used = 0;+  cif->vfp_nargs = 0;+  cif->vfp_reg_free = 0;+  memset (cif->vfp_args, -1, 16);	/* Init to -1. */++  for (i = 0; i < cif->nargs; i++)+    {+      int h = vfp_type_p (cif->arg_types[i]);+      if (h && place_vfp_arg (cif, h) == 1)+	break;+    }+}++#if defined(FFI_EXEC_STATIC_TRAMP)+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;++  *tramp_size = ARM_TRAMP_SIZE;+  *map_size = ARM_TRAMP_MAP_SIZE;+  return &trampoline_code_table;+}+#endif++#endif /* __arm__ or _M_ARM */
+ src/arm/ffitarget.h view
@@ -0,0 +1,89 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 2010  CodeSourcery+                 Copyright (c) 1996-2003  Red Hat, Inc.++   Target configuration macros for ARM.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_VFP,+  FFI_LAST_ABI,+#if defined(__ARM_PCS_VFP) || defined(_WIN32)+  FFI_DEFAULT_ABI = FFI_VFP,+#else+  FFI_DEFAULT_ABI = FFI_SYSV,+#endif+} ffi_abi;+#endif++#define FFI_EXTRA_CIF_FIELDS			\+  int vfp_used;					\+  unsigned short vfp_reg_free, vfp_nargs;	\+  signed char vfp_args[16]			\++#define FFI_TARGET_SPECIFIC_VARIADIC+#ifndef _WIN32+#define FFI_TARGET_HAS_COMPLEX_TYPE+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__+#define FFI_TRAMPOLINE_SIZE 12+#define FFI_TRAMPOLINE_CLOSURE_OFFSET 8+#else+#error "No trampoline table implementation"+#endif++#else+#ifdef _WIN32+#define FFI_TRAMPOLINE_SIZE 16+#define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12+#else+#define FFI_TRAMPOLINE_SIZE 12+#endif+#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE+#endif++#endif
+ src/arm/internal.h view
@@ -0,0 +1,17 @@+#define ARM_TYPE_VFP_S	0+#define ARM_TYPE_VFP_D	1+#define ARM_TYPE_VFP_N	2+#define ARM_TYPE_INT64	3+#define ARM_TYPE_INT	4+#define ARM_TYPE_VOID	5+#define ARM_TYPE_STRUCT	6++#if defined(FFI_EXEC_STATIC_TRAMP)+/*+ * For the trampoline table mapping, a mapping size of 4K (base page size)+ * is chosen.+ */+#define ARM_TRAMP_MAP_SHIFT	12+#define ARM_TRAMP_MAP_SIZE	(1 << ARM_TRAMP_MAP_SHIFT)+#define ARM_TRAMP_SIZE		20+#endif
+ src/arm/sysv.S view
@@ -0,0 +1,456 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.+	    Copyright (c) 2011 Plausible Labs Cooperative, Inc.++   ARM Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifdef __arm__+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "internal.h"++/* GCC 4.8 provides __ARM_ARCH; construct it otherwise.  */+#ifndef __ARM_ARCH+# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \+     || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \+     || defined(__ARM_ARCH_7EM__)+#  define __ARM_ARCH 7+# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \+        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \+        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \+	|| defined(__ARM_ARCH_6M__)+#  define __ARM_ARCH 6+# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \+	|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \+	|| defined(__ARM_ARCH_5TEJ__)+#  define __ARM_ARCH 5+# else+#  define __ARM_ARCH 4+# endif+#endif++/* Conditionally compile unwinder directives.  */+#ifdef __ARM_EABI__+# define UNWIND(...)	__VA_ARGS__+#else+# define UNWIND(...)+#endif++#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__)+	.cfi_sections	.debug_frame+#endif++#define CONCAT(a, b)	CONCAT2(a, b)+#define CONCAT2(a, b)	a ## b++#ifdef __USER_LABEL_PREFIX__+# define CNAME(X)	CONCAT (__USER_LABEL_PREFIX__, X)+#else+# define CNAME(X)	X+#endif+#ifdef __ELF__+# define SIZE(X)	.size CNAME(X), . - CNAME(X)+# define TYPE(X, Y)	.type CNAME(X), Y+#else+# define SIZE(X)+# define TYPE(X, Y)+#endif++#define ARM_FUNC_START_LOCAL(name)	\+	.align	3;			\+	TYPE(CNAME(name), %function);	\+	CNAME(name):++#define ARM_FUNC_START(name)		\+	.globl CNAME(name);		\+	FFI_HIDDEN(CNAME(name));	\+	ARM_FUNC_START_LOCAL(name)++#define ARM_FUNC_END(name) \+	SIZE(name)++	.text+	.syntax unified+#if defined(_WIN32)+	/* Windows on ARM is thumb-only */+	.thumb+#else+	/* Keep the assembly in ARM mode in other cases, for simplicity+	 * (to avoid interworking issues). */+#undef __thumb__+	.arm+#endif++/* Aid in defining a jump table with 8 bytes between entries.  */+#ifdef __thumb__+/* In thumb mode, instructions can be shorter than expected in arm mode, so+ * we need to align the start of each case. */+# define E(index) .align 3+#elif defined(__clang__)+/* ??? The clang assembler doesn't handle .if with symbolic expressions.  */+# define E(index)+#else+# define E(index)				\+	.if . - 0b - 8*index;			\+	.error "type table out of sync";	\+	.endif+#endif+++#ifndef __clang__+	/* We require interworking on LDM, which implies ARMv5T,+	   which implies the existance of BLX.  */+ 	.arch	armv5t+#endif++	/* Note that we use STC and LDC to encode VFP instructions,+	   so that we do not need ".fpu vfp", nor get that added to+	   the object file attributes.  These will not be executed+	   unless the FFI_VFP abi is used.  */++	@ r0:   stack+	@ r1:   frame+	@ r2:   fn+	@ r3:	vfp_used++ARM_FUNC_START(ffi_call_VFP)+	UNWIND(.fnstart)+	cfi_startproc++	cmp	r3, #3			@ load only d0 if possible+	ite	le+	ldcle	p11, cr0, [r0]		@ vldrle d0, [r0]+	ldcgt	p11, cr0, [r0], {16}	@ vldmgt r0, {d0-d7}+	add	r0, r0, #64		@ discard the vfp register args+	/* FALLTHRU */+ARM_FUNC_END(ffi_call_VFP)++ARM_FUNC_START(ffi_call_SYSV)+	stm	r1, {fp, lr}+	mov	fp, r1++	@ This is a bit of a lie wrt the origin of the unwind info, but+	@ now we've got the usual frame pointer and two saved registers.+	UNWIND(.save {fp,lr})+	UNWIND(.setfp fp, sp)+	cfi_def_cfa(fp, 8)+	cfi_rel_offset(fp, 0)+	cfi_rel_offset(lr, 4)++	mov	sp, r0		@ install the stack pointer+	mov	lr, r2		@ move the fn pointer out of the way+	ldr	ip, [fp, #16]	@ install the static chain+	ldmia	sp!, {r0-r3}	@ move first 4 parameters in registers.+	blx	lr		@ call fn++	@ Load r2 with the pointer to storage for the return value+	@ Load r3 with the return type code+	ldr	r2, [fp, #8]+	ldr	r3, [fp, #12]++	@ Deallocate the stack with the arguments.+	mov	sp, fp+	cfi_def_cfa_register(sp)++	@ Store values stored in registers.+#ifndef __thumb__+	.align	3+	add	pc, pc, r3, lsl #3+	nop+#else+	adr	ip, 0f+	add	ip, ip, r3, lsl #3+	mov	pc, ip+	.align	3+#endif+0:+E(ARM_TYPE_VFP_S)+	stc	p10, cr0, [r2]		@ vstr s0, [r2]+	pop	{fp,pc}+E(ARM_TYPE_VFP_D)+	stc	p11, cr0, [r2]		@ vstr d0, [r2]+	pop	{fp,pc}+E(ARM_TYPE_VFP_N)+	stc	p11, cr0, [r2], {8}	@ vstm r2, {d0-d3}+	pop	{fp,pc}+E(ARM_TYPE_INT64)+	str	r1, [r2, #4]+	nop+E(ARM_TYPE_INT)+	str	r0, [r2]+	pop	{fp,pc}+E(ARM_TYPE_VOID)+	pop	{fp,pc}+	nop+E(ARM_TYPE_STRUCT)+	pop	{fp,pc}++	cfi_endproc+	UNWIND(.fnend)+ARM_FUNC_END(ffi_call_SYSV)++#if FFI_CLOSURES++/*+	int ffi_closure_inner_* (cif, fun, user_data, frame)+*/++ARM_FUNC_START(ffi_go_closure_SYSV)+	cfi_startproc+	stmdb	sp!, {r0-r3}			@ save argument regs+	cfi_adjust_cfa_offset(16)+	ldr	r0, [ip, #4]			@ load cif+	ldr	r1, [ip, #8]			@ load fun+	mov	r2, ip				@ load user_data+	b	0f+	cfi_endproc+ARM_FUNC_END(ffi_go_closure_SYSV)++ARM_FUNC_START(ffi_closure_SYSV)+	UNWIND(.fnstart)+	cfi_startproc+#ifdef _WIN32+	ldmfd	sp!, {r0, ip}			@ restore fp (r0 is used for stack alignment)+#endif+	stmdb	sp!, {r0-r3}			@ save argument regs+	cfi_adjust_cfa_offset(16)++#if FFI_EXEC_TRAMPOLINE_TABLE+	ldr ip, [ip]				@ ip points to the config page, dereference to get the ffi_closure*+#endif+	ldr	r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	@ load cif+	ldr	r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  @ load fun+	ldr	r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  @ load user_data+0:+	add	ip, sp, #16			@ compute entry sp+	sub	sp, sp, #64+32			@ allocate frame+	cfi_adjust_cfa_offset(64+32)+	stmdb	sp!, {ip,lr}++	/* Remember that EABI unwind info only applies at call sites.+	   We need do nothing except note the save of the stack pointer+	   and the link registers.  */+	UNWIND(.save {sp,lr})+	cfi_adjust_cfa_offset(8)+	cfi_rel_offset(lr, 4)++	add	r3, sp, #8			@ load frame+	bl	CNAME(ffi_closure_inner_SYSV)++	@ Load values returned in registers.+	add	r2, sp, #8+64			@ load result+	adr	r3, CNAME(ffi_closure_ret)+#ifndef __thumb__+	add	pc, r3, r0, lsl #3+#else+	add	r3, r3, r0, lsl #3+	mov	pc, r3+#endif+	cfi_endproc+	UNWIND(.fnend)+ARM_FUNC_END(ffi_closure_SYSV)++ARM_FUNC_START(ffi_go_closure_VFP)+	cfi_startproc+	stmdb	sp!, {r0-r3}			@ save argument regs+	cfi_adjust_cfa_offset(16)+	ldr	r0, [ip, #4]			@ load cif+	ldr	r1, [ip, #8]			@ load fun+	mov	r2, ip				@ load user_data+	b	0f+	cfi_endproc+ARM_FUNC_END(ffi_go_closure_VFP)++ARM_FUNC_START(ffi_closure_VFP)+	UNWIND(.fnstart)+	cfi_startproc+#ifdef _WIN32+	ldmfd	sp!, {r0, ip}			@ restore fp (r0 is used for stack alignment)+#endif+	stmdb	sp!, {r0-r3}			@ save argument regs+	cfi_adjust_cfa_offset(16)++#if FFI_EXEC_TRAMPOLINE_TABLE+	ldr ip, [ip]				@ ip points to the config page, dereference to get the ffi_closure*+#endif+	ldr	r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]	@ load cif+	ldr	r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  @ load fun+	ldr	r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  @ load user_data+0:+	add	ip, sp, #16+	sub	sp, sp, #64+32			@ allocate frame+	cfi_adjust_cfa_offset(64+32)+	stc	p11, cr0, [sp], {16}		@ vstm sp, {d0-d7}+	stmdb	sp!, {ip,lr}++	/* See above.  */+	UNWIND(.save {sp,lr})+	cfi_adjust_cfa_offset(8)+	cfi_rel_offset(lr, 4)++	add	r3, sp, #8			@ load frame+	bl	CNAME(ffi_closure_inner_VFP)++	@ Load values returned in registers.+	add	r2, sp, #8+64			@ load result+	adr	r3, CNAME(ffi_closure_ret)+#ifndef __thumb__+	add	pc, r3, r0, lsl #3+#else+	add	r3, r3, r0, lsl #3+	mov	pc, r3+#endif+	cfi_endproc+	UNWIND(.fnend)+ARM_FUNC_END(ffi_closure_VFP)++/* Load values returned in registers for both closure entry points.+   Note that we use LDM with SP in the register set.  This is deprecated+   by ARM, but not yet unpredictable.  */++ARM_FUNC_START_LOCAL(ffi_closure_ret)+	cfi_startproc+	cfi_rel_offset(sp, 0)+	cfi_rel_offset(lr, 4)+0:+E(ARM_TYPE_VFP_S)+	ldc	p10, cr0, [r2]			@ vldr s0, [r2]+	b	call_epilogue+E(ARM_TYPE_VFP_D)+	ldc	p11, cr0, [r2]			@ vldr d0, [r2]+	b	call_epilogue+E(ARM_TYPE_VFP_N)+	ldc	p11, cr0, [r2], {8}		@ vldm r2, {d0-d3}+	b	call_epilogue+E(ARM_TYPE_INT64)+	ldr	r1, [r2, #4]+	nop+E(ARM_TYPE_INT)+	ldr	r0, [r2]+	b	call_epilogue+E(ARM_TYPE_VOID)+	b	call_epilogue+	nop+E(ARM_TYPE_STRUCT)+	b	call_epilogue+call_epilogue:+#ifndef __thumb__+	ldm	sp, {sp,pc}+#else+	ldm	sp, {ip,lr}+	mov	sp, ip+	bx	lr+#endif+	cfi_endproc+ARM_FUNC_END(ffi_closure_ret)++#if defined(FFI_EXEC_STATIC_TRAMP)+ARM_FUNC_START(ffi_closure_SYSV_alt)+	/* See the comments above trampoline_code_table. */+	ldr	ip, [sp, #4]			/* Load closure in ip */+	add	sp, sp, 8			/* Restore the stack */+	b	CNAME(ffi_closure_SYSV)+ARM_FUNC_END(ffi_closure_SYSV_alt)++ARM_FUNC_START(ffi_closure_VFP_alt)+	/* See the comments above trampoline_code_table. */+	ldr	ip, [sp, #4]			/* Load closure in ip */+	add	sp, sp, 8			/* Restore the stack */+	b	CNAME(ffi_closure_VFP)+ARM_FUNC_END(ffi_closure_VFP_alt)++/*+ * Below is the definition of the trampoline code table. Each element in+ * the code table is a trampoline.+ */+/*+ * The trampoline uses register ip (r12). It saves the original value of ip+ * on the stack.+ *+ * The trampoline has two parameters - target code to jump to and data for+ * the target code. The trampoline extracts the parameters from its parameter+ * block (see tramp_table_map()). The trampoline saves the data address on+ * the stack. Finally, it jumps to the target code.+ *+ * The target code can choose to:+ *+ * - restore the value of ip+ * - load the data address in a register+ * - restore the stack pointer to what it was when the trampoline was invoked.+ */+	.align	ARM_TRAMP_MAP_SHIFT+ARM_FUNC_START(trampoline_code_table)+	.rept	ARM_TRAMP_MAP_SIZE / ARM_TRAMP_SIZE+	sub	sp, sp, #8		/* Make space on the stack */+	str	ip, [sp]		/* Save ip on stack */+	ldr	ip, [pc, #4080]		/* Copy data into ip */+	str	ip, [sp, #4]		/* Save data on stack */+	ldr	pc, [pc, #4076]		/* Copy code into PC */+	.endr+ARM_FUNC_END(trampoline_code_table)+	.align	ARM_TRAMP_MAP_SHIFT+#endif /* FFI_EXEC_STATIC_TRAMP */++#endif /* FFI_CLOSURES */++#if FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__+#include <mach/machine/vm_param.h>++.align	PAGE_MAX_SHIFT+ARM_FUNC_START(ffi_closure_trampoline_table_page)+.rept	PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE+	adr ip, #-PAGE_MAX_SIZE   @ the config page is PAGE_MAX_SIZE behind the trampoline page+	sub ip, #8				  @ account for pc bias+	ldr	pc, [ip, #4]		  @ jump to ffi_closure_SYSV or ffi_closure_VFP+.endr+ARM_FUNC_END(ffi_closure_trampoline_table_page)+#endif++#elif defined(_WIN32)++ARM_FUNC_START(ffi_arm_trampoline)+0:	adr	ip, 0b+	stmdb	sp!, {r0, ip}+	ldr	pc, 1f+1:	.long	0+ARM_FUNC_END(ffi_arm_trampoline)++#else++ARM_FUNC_START(ffi_arm_trampoline)+0:	adr	ip, 0b+	ldr	pc, 1f+1:	.long	0+ARM_FUNC_END(ffi_arm_trampoline)++#endif /* FFI_EXEC_TRAMPOLINE_TABLE */+#endif /* __arm__ */++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",%progbits+#endif
+ src/arm/sysv_msvc_arm32.S view
@@ -0,0 +1,311 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.+        Copyright (c) 2011 Plausible Labs Cooperative, Inc.+        Copyright (c) 2019 Microsoft Corporation.++   ARM Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "internal.h"+#include "ksarm.h"+++        ; 8 byte aligned AREA to support 8 byte aligned jump tables+        MACRO+        NESTED_ENTRY_FFI $FuncName, $AreaName, $ExceptHandler++        ; compute the function's labels+        __DeriveFunctionLabels $FuncName++        ; determine the area we will put the function into+__FuncArea   SETS    "|.text|"+        IF "$AreaName" != ""+__FuncArea   SETS    "$AreaName"+        ENDIF++        ; set up the exception handler itself+__FuncExceptionHandler SETS ""+        IF "$ExceptHandler" != ""+__FuncExceptionHandler SETS    "|$ExceptHandler|"+        ENDIF++        ; switch to the specified area, jump tables require 8 byte alignment+        AREA    $__FuncArea,CODE,CODEALIGN,ALIGN=3,READONLY++        ; export the function name+        __ExportProc $FuncName++        ; flush any pending literal pool stuff+        ROUT++        ; reset the state of the unwind code tracking+        __ResetUnwindState++        MEND++;        MACRO+;        TABLE_ENTRY $Type, $Table+;$Type_$Table+;        MEND++#define E(index,table) return_##index##_##table++    ; r0:   stack+    ; r1:   frame+    ; r2:   fn+    ; r3:   vfp_used++    ; fake entry point exists only to generate exists only to +    ; generate .pdata for exception unwinding+    NESTED_ENTRY_FFI ffi_call_VFP_fake+    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind++    ALTERNATE_ENTRY ffi_call_VFP+    cmp    r3, #3                   ; load only d0 if possible+    vldrle d0, [r0]+    vldmgt r0, {d0-d7}+    add    r0, r0, #64              ; discard the vfp register args+    b ffi_call_SYSV+    NESTED_END ffi_call_VFP_fake++    ; fake entry point exists only to generate exists only to +    ; generate .pdata for exception unwinding+    NESTED_ENTRY_FFI ffi_call_SYSV_fake+    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind++    ALTERNATE_ENTRY ffi_call_SYSV+    stm    r1, {fp, lr}+    mov    fp, r1++    mov    sp, r0                   ; install the stack pointer+    mov    lr, r2                   ; move the fn pointer out of the way+    ldr    ip, [fp, #16]            ; install the static chain+    ldmia  sp!, {r0-r3}             ; move first 4 parameters in registers.+    blx    lr                       ; call fn++    ; Load r2 with the pointer to storage for the return value+    ; Load r3 with the return type code+    ldr    r2, [fp, #8]+    ldr    r3, [fp, #12]++    ; Deallocate the stack with the arguments.+    mov    sp, fp++    ; Store values stored in registers.+    ALIGN 8+    lsl     r3, #3+    add     r3, r3, pc+    add     r3, #8+    mov     pc, r3+++E(ARM_TYPE_VFP_S, ffi_call)+    ALIGN 8+    vstr s0, [r2]+    pop    {fp,pc}+E(ARM_TYPE_VFP_D, ffi_call)+    ALIGN 8+    vstr d0, [r2]+    pop    {fp,pc}+E(ARM_TYPE_VFP_N, ffi_call)+    ALIGN 8+    vstm r2, {d0-d3}+    pop    {fp,pc}+E(ARM_TYPE_INT64, ffi_call)+    ALIGN 8+    str    r1, [r2, #4]+    nop+E(ARM_TYPE_INT, ffi_call)+    ALIGN 8+    str    r0, [r2]+    pop    {fp,pc}+E(ARM_TYPE_VOID, ffi_call)+    ALIGN 8+    pop    {fp,pc}+    nop+E(ARM_TYPE_STRUCT, ffi_call)+    ALIGN 8+    cmp r3, #ARM_TYPE_STRUCT+    pop    {fp,pc}+    NESTED_END ffi_call_SYSV_fake++    IMPORT |ffi_closure_inner_SYSV|+    /*+    int ffi_closure_inner_SYSV+    (+        cif,        ; r0+        fun,        ; r1+        user_data,  ; r2+        frame       ; r3+    )+    */++    NESTED_ENTRY_FFI ffi_go_closure_SYSV+    stmdb   sp!, {r0-r3}            ; save argument regs+    ldr     r0, [ip, #4]            ; load cif+    ldr     r1, [ip, #8]            ; load fun+    mov     r2, ip                  ; load user_data+    b       ffi_go_closure_SYSV_0+    NESTED_END ffi_go_closure_SYSV++    ; r3:    ffi_closure++    ; fake entry point exists only to generate exists only to +    ; generate .pdata for exception unwinding+    NESTED_ENTRY_FFI ffi_closure_SYSV_fake  +    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind+    ALTERNATE_ENTRY ffi_closure_SYSV+    ldmfd   sp!, {ip,r0}            ; restore fp (r0 is used for stack alignment)+    stmdb   sp!, {r0-r3}            ; save argument regs++    ldr     r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]    ; ffi_closure->cif+    ldr     r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  ; ffi_closure->fun+    ldr     r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  ; ffi_closure->user_data++    ALTERNATE_ENTRY ffi_go_closure_SYSV_0+    add     ip, sp, #16             ; compute entry sp++    sub     sp, sp, #64+32          ; allocate frame parameter (sizeof(vfp_space) = 64, sizeof(result) = 32)+    mov     r3, sp                  ; set frame parameter+    stmdb   sp!, {ip,lr}++    bl      ffi_closure_inner_SYSV  ; call the Python closure++                                    ; Load values returned in registers.+    add     r2, sp, #64+8           ; address of closure_frame->result+    bl      ffi_closure_ret         ; move result to correct register or memory for type++    ldmfd   sp!, {ip,lr}+    mov     sp, ip                  ; restore stack pointer+    mov     pc, lr+    NESTED_END ffi_closure_SYSV_fake++    IMPORT |ffi_closure_inner_VFP|+    /*+    int ffi_closure_inner_VFP+    (+        cif,        ; r0+        fun,        ; r1+        user_data,  ; r2+        frame       ; r3+    )+    */++    NESTED_ENTRY_FFI ffi_go_closure_VFP+    stmdb   sp!, {r0-r3}			; save argument regs+    ldr	r0, [ip, #4]			; load cif+    ldr	r1, [ip, #8]			; load fun+    mov	r2, ip				; load user_data+    b	ffi_go_closure_VFP_0+    NESTED_END ffi_go_closure_VFP++    ; fake entry point exists only to generate exists only to +    ; generate .pdata for exception unwinding+    ; r3:    closure+    NESTED_ENTRY_FFI ffi_closure_VFP_fake+    PROLOG_PUSH  {r11, lr}          ; save fp and lr for unwind++    ALTERNATE_ENTRY ffi_closure_VFP+    ldmfd   sp!, {ip,r0}            ; restore fp (r0 is used for stack alignment)+    stmdb   sp!, {r0-r3}            ; save argument regs++    ldr     r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET]    ; load cif+    ldr     r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4]  ; load fun+    ldr     r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8]  ; load user_data++    ALTERNATE_ENTRY ffi_go_closure_VFP_0+    add     ip, sp, #16             ; compute entry sp+    sub     sp, sp, #32             ; save space for closure_frame->result+    vstmdb  sp!, {d0-d7}            ; push closure_frame->vfp_space++    mov     r3, sp                  ; save closure_frame+    stmdb   sp!, {ip,lr}++    bl      ffi_closure_inner_VFP++    ; Load values returned in registers.+    add     r2, sp, #64+8           ; load result+    bl      ffi_closure_ret+    ldmfd   sp!, {ip,lr}+    mov     sp, ip                  ; restore stack pointer+    mov     pc, lr+    NESTED_END ffi_closure_VFP_fake++/* Load values returned in registers for both closure entry points.+   Note that we use LDM with SP in the register set.  This is deprecated+   by ARM, but not yet unpredictable.  */++    NESTED_ENTRY_FFI ffi_closure_ret+    stmdb sp!, {fp,lr}++    ALIGN 8+    lsl     r0, #3+    add     r0, r0, pc+    add     r0, #8+    mov     pc, r0++E(ARM_TYPE_VFP_S, ffi_closure)+    ALIGN 8+    vldr s0, [r2]+    b call_epilogue+E(ARM_TYPE_VFP_D, ffi_closure)+    ALIGN 8+    vldr d0, [r2]+    b call_epilogue+E(ARM_TYPE_VFP_N, ffi_closure)+    ALIGN 8+    vldm r2, {d0-d3}+    b call_epilogue+E(ARM_TYPE_INT64, ffi_closure)+    ALIGN 8+    ldr    r1, [r2, #4]+    nop+E(ARM_TYPE_INT, ffi_closure)+    ALIGN 8+    ldr    r0, [r2]+    b call_epilogue+E(ARM_TYPE_VOID, ffi_closure)+    ALIGN 8+    b call_epilogue+    nop+E(ARM_TYPE_STRUCT, ffi_closure)+    ALIGN 8+    b call_epilogue+call_epilogue+    ldmfd sp!, {fp,pc}+    NESTED_END ffi_closure_ret++    AREA |.trampoline|, DATA, THUMB, READONLY+    EXPORT |ffi_arm_trampoline|+|ffi_arm_trampoline| DATA+thisproc    adr    ip, thisproc+            stmdb  sp!, {ip, r0}+            ldr    pc, [pc, #0]+            DCD    0+            ;ENDP++    END
+ src/avr32/ffi.c view
@@ -0,0 +1,423 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2011  Anthony Green+           Copyright (c) 2009  Bradley Smith <brad@brad-smith.co.uk>++   AVR32 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdio.h>+#include <unistd.h>+#include <asm/unistd.h>++/* #define DEBUG */++extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,+    unsigned int, unsigned int, unsigned int*, unsigned int,+    void (*fn)(void));+extern void ffi_closure_SYSV (ffi_closure *);++unsigned int pass_struct_on_stack(ffi_type *type)+{+    if(type->type != FFI_TYPE_STRUCT)+        return 0;++    if(type->alignment < type->size &&+        !(type->size == 4 || type->size == 8) &&+        !(type->size == 8 && type->alignment >= 4))+        return 1;++    if(type->size == 3 || type->size == 5 || type->size == 6 ||+        type->size == 7)+        return 1;++    return 0;+}++/* ffi_prep_args is called by the assembly routine once stack space+ * has been allocated for the function's arguments+ *+ * This is annoyingly complex since we need to keep track of used+ * registers.+ */++void ffi_prep_args(char *stack, extended_cif *ecif)+{+    unsigned int i;+    void **p_argv;+    ffi_type **p_arg;+    char *reg_base = stack;+    char *stack_base = stack + 20;+    unsigned int stack_offset = 0;+    unsigned int reg_mask = 0;++    p_argv = ecif->avalue;++    /* If cif->flags is struct then we know it's not passed in registers */+    if(ecif->cif->flags == FFI_TYPE_STRUCT)+    {+        *(void**)reg_base = ecif->rvalue;+        reg_mask |= 1;+    }++    for(i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;+        i++, p_arg++)+    {+        size_t z = (*p_arg)->size;+        int alignment = (*p_arg)->alignment;+        int type = (*p_arg)->type;+        char *addr = 0;++        if(z % 4 != 0)+            z += (4 - z % 4);++        if(reg_mask != 0x1f)+        {+            if(pass_struct_on_stack(*p_arg))+            {+                addr = stack_base + stack_offset;+                stack_offset += z;+            }+            else if(z == sizeof(int))+            {+                char index = 0;++                while((reg_mask >> index) & 1)+                    index++;++                addr = reg_base + (index * 4);+                reg_mask |= (1 << index);+            }+            else if(z == 2 * sizeof(int))+            {+                if(!((reg_mask >> 1) & 1))+                {+                    addr = reg_base + 4;+                    reg_mask |= (3 << 1);+                }+                else if(!((reg_mask >> 3) & 1))+                {+                    addr = reg_base + 12;+                    reg_mask |= (3 << 3);+                }+            }+        }++        if(!addr)+        {+            addr = stack_base + stack_offset;+            stack_offset += z;+        }++        if(type == FFI_TYPE_STRUCT && (*p_arg)->elements[1] == NULL)+            type = (*p_arg)->elements[0]->type;++        switch(type)+        {+        case FFI_TYPE_UINT8:+            *(unsigned int *)addr = (unsigned int)*(UINT8 *)(*p_argv);+            break;+        case FFI_TYPE_SINT8:+            *(signed int *)addr = (signed int)*(SINT8 *)(*p_argv);+            break;+        case FFI_TYPE_UINT16:+            *(unsigned int *)addr = (unsigned int)*(UINT16 *)(*p_argv);+            break;+        case FFI_TYPE_SINT16:+            *(signed int *)addr = (signed int)*(SINT16 *)(*p_argv);+            break;+        default:+            memcpy(addr, *p_argv, z);+        }++        p_argv++;+    }++#ifdef DEBUG+    /* Debugging */+    for(i = 0; i < 5; i++)+    {+        if((reg_mask & (1 << i)) == 0)+            printf("r%d: (unused)\n", 12 - i);+        else+            printf("r%d: 0x%08x\n", 12 - i, ((unsigned int*)reg_base)[i]);+    }++    for(i = 0; i < stack_offset / 4; i++)+    {+        printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack_base)[i]);+    }+#endif+}++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+    /* Round the stack up to a multiple of 8 bytes.  This isn't needed+     * everywhere, but it is on some platforms, and it doesn't harm+     * anything when it isn't needed. */+    cif->bytes = (cif->bytes + 7) & ~7;++    /* Flag to indicate that he return value is in fact a struct */+    cif->rstruct_flag = 0;++    /* Set the return type flag */+    switch(cif->rtype->type)+    {+    case FFI_TYPE_SINT8:+    case FFI_TYPE_UINT8:+        cif->flags = (unsigned)FFI_TYPE_UINT8;+        break;+    case FFI_TYPE_SINT16:+    case FFI_TYPE_UINT16:+        cif->flags = (unsigned)FFI_TYPE_UINT16;+        break;+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_POINTER:+        cif->flags = (unsigned)FFI_TYPE_UINT32;+        break;+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+        cif->flags = (unsigned)FFI_TYPE_UINT64;+        break;+    case FFI_TYPE_STRUCT:+        cif->rstruct_flag = 1;+        if(!pass_struct_on_stack(cif->rtype))+        {+            if(cif->rtype->size <= 1)+                cif->flags = (unsigned)FFI_TYPE_UINT8;+            else if(cif->rtype->size <= 2)+                cif->flags = (unsigned)FFI_TYPE_UINT16;+            else if(cif->rtype->size <= 4)+                cif->flags = (unsigned)FFI_TYPE_UINT32;+            else if(cif->rtype->size <= 8)+                cif->flags = (unsigned)FFI_TYPE_UINT64;+            else+                cif->flags = (unsigned)cif->rtype->type;+        }+        else+            cif->flags = (unsigned)cif->rtype->type;+        break;+    default:+        cif->flags = (unsigned)cif->rtype->type;+        break;+    }++    return FFI_OK;+}++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+    extended_cif ecif;++    unsigned int size = 0, i = 0;+    ffi_type **p_arg;++    ecif.cif = cif;+    ecif.avalue = avalue;++    for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)+        size += (*p_arg)->size + (4 - (*p_arg)->size % 4);++    /* If the return value is a struct and we don't have a return value+     * address then we need to make one */++    /* If cif->flags is struct then it's not suitable for registers */+    if((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT))+        ecif.rvalue = alloca(cif->rtype->size);+    else+        ecif.rvalue = rvalue;++    switch(cif->abi)+    {+    case FFI_SYSV:+        ffi_call_SYSV(ffi_prep_args, &ecif, size, cif->flags,+            ecif.rvalue, cif->rstruct_flag, fn);+        break;+    default:+        FFI_ASSERT(0);+        break;+    }+}++static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,+    void **avalue, ffi_cif *cif)+{+    register unsigned int i, reg_mask = 0;+    register void **p_argv;+    register ffi_type **p_arg;+    register char *reg_base = stack;+    register char *stack_base = stack + 20;+    register unsigned int stack_offset = 0;++#ifdef DEBUG+    /* Debugging */+    for(i = 0; i < cif->nargs + 7; i++)+    {+        printf("sp+%d: 0x%08x\n", i*4, ((unsigned int*)stack)[i]);+    }+#endif++    /* If cif->flags is struct then we know it's not passed in registers */+    if(cif->flags == FFI_TYPE_STRUCT)+    {+        *rvalue = *(void **)reg_base;+        reg_mask |= 1;+    }++    p_argv = avalue;++    for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)+    {+        size_t z = (*p_arg)->size;+        int alignment = (*p_arg)->alignment;++        *p_argv = 0;++        if(z % 4 != 0)+            z += (4 - z % 4);++        if(reg_mask != 0x1f)+        {+            if(pass_struct_on_stack(*p_arg))+            {+                *p_argv = (void*)stack_base + stack_offset;+                stack_offset += z;+            }+            else if(z <= sizeof(int))+            {+                char index = 0;++                while((reg_mask >> index) & 1)+                    index++;++                *p_argv = (void*)reg_base + (index * 4);+                reg_mask |= (1 << index);+            }+            else if(z == 2 * sizeof(int))+            {+                if(!((reg_mask >> 1) & 1))+                {+                    *p_argv = (void*)reg_base + 4;+                    reg_mask |= (3 << 1);+                }+                else if(!((reg_mask >> 3) & 1))+                {+                    *p_argv = (void*)reg_base + 12;+                    reg_mask |= (3 << 3);+                }+            }+        }++        if(!*p_argv)+        {+            *p_argv = (void*)stack_base + stack_offset;+            stack_offset += z;+        }++        if((*p_arg)->type != FFI_TYPE_STRUCT ||+            (*p_arg)->elements[1] == NULL)+        {+            if(alignment == 1)+                **(unsigned int**)p_argv <<= 24;+            else if(alignment == 2)+                **(unsigned int**)p_argv <<= 16;+        }++        p_argv++;+    }++#ifdef DEBUG+    /* Debugging */+    for(i = 0; i < cif->nargs; i++)+    {+        printf("sp+%d: 0x%08x\n", i*4, *(((unsigned int**)avalue)[i]));+    }+#endif+}++/* This function is jumped to by the trampoline */++unsigned int ffi_closure_SYSV_inner(ffi_closure *closure, void **respp,+    void *args)+{+    ffi_cif *cif;+    void **arg_area;+    unsigned int i, size = 0;+    ffi_type **p_arg;++    cif = closure->cif;++    for(i = 0, p_arg = cif->arg_types; i < cif->nargs; i++, p_arg++)+        size += (*p_arg)->size + (4 - (*p_arg)->size % 4);++    arg_area = (void **)alloca(size);++    /* this call will initialize ARG_AREA, such that each element in that+     * array points to the corresponding value on the stack; and if the+     * function returns a structure, it will re-set RESP to point to the+     * structure return address. */++    ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);++    (closure->fun)(cif, *respp, arg_area, closure->user_data);++    return cif->flags;+}++ffi_status ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,+    void (*fun)(ffi_cif*, void*, void**, void*), void *user_data,+    void *codeloc)+{+    if (cif->abi != FFI_SYSV)+      return FFI_BAD_ABI;++    unsigned char *__tramp = (unsigned char*)(&closure->tramp[0]);+    unsigned int  __fun = (unsigned int)(&ffi_closure_SYSV);+    unsigned int  __ctx = (unsigned int)(codeloc);+    unsigned int  __rstruct_flag = (unsigned int)(cif->rstruct_flag);+    unsigned int  __inner = (unsigned int)(&ffi_closure_SYSV_inner);+    *(unsigned int*) &__tramp[0] = 0xebcd1f00;    /* pushm  r8-r12 */+    *(unsigned int*) &__tramp[4] = 0xfefc0010;    /* ld.w   r12, pc[16] */+    *(unsigned int*) &__tramp[8] = 0xfefb0010;    /* ld.w   r11, pc[16] */+    *(unsigned int*) &__tramp[12] = 0xfefa0010;   /* ld.w   r10, pc[16] */+    *(unsigned int*) &__tramp[16] = 0xfeff0010;   /* ld.w   pc, pc[16] */+    *(unsigned int*) &__tramp[20] = __ctx;+    *(unsigned int*) &__tramp[24] = __rstruct_flag;+    *(unsigned int*) &__tramp[28] = __inner;+    *(unsigned int*) &__tramp[32] = __fun;+    syscall(__NR_cacheflush, 0, (&__tramp[0]), 36);++    closure->cif = cif;+    closure->user_data = user_data;+    closure->fun  = fun;++    return FFI_OK;+}+
+ src/avr32/ffitarget.h view
@@ -0,0 +1,55 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 2009  Bradley Smith <brad@brad-smith.co.uk>+   Target configuration macros for AVR32.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++#define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag++/* Definitions for closures */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 36+#define FFI_NATIVE_RAW_API 0++#endif
+ src/avr32/sysv.S view
@@ -0,0 +1,208 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2009  Bradley Smith <brad@brad-smith.co.uk>++   AVR32 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+   --------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++    /* r12:  ffi_prep_args+     * r11:  &ecif+     * r10:  size+     * r9:   cif->flags+     * r8:   ecif.rvalue+     * sp+0: cif->rstruct_flag+     * sp+4: fn */++    .text+    .align  1+    .globl  ffi_call_SYSV+    .type   ffi_call_SYSV, @function+ffi_call_SYSV:+    stm     --sp, r0,r1,lr+    stm     --sp, r8-r12+    mov     r0, sp++    /* Make room for all of the new args. */+    sub     sp, r10+    /* Pad to make way for potential skipped registers */+    sub     sp, 20++    /* Call ffi_prep_args(stack, &ecif). */+    /* r11 already set */+    mov     r1, r12+    mov     r12, sp+    icall   r1++    /* Save new argument size */+    mov     r1, r12++    /* Move first 5 parameters in registers. */+    ldm     sp++, r8-r12++    /* call (fn) (...). */+    ld.w    r1, r0[36]+    icall   r1++    /* Remove the space we pushed for the args. */+    mov     sp, r0++    /* Load r1 with the rstruct flag. */+    ld.w    r1, sp[32]++    /* Load r9 with the return type code. */+    ld.w    r9, sp[12]++    /* Load r8 with the return value pointer. */+    ld.w    r8, sp[16]++    /* If the return value pointer is NULL, assume no return value. */+    cp.w    r8, 0+    breq    .Lend++    /* Check if return type is actually a struct */+    cp.w    r1, 0+    breq    1f++    /* Return 8bit */+    cp.w    r9, FFI_TYPE_UINT8+    breq    .Lstore8++    /* Return 16bit */+    cp.w    r9, FFI_TYPE_UINT16+    breq    .Lstore16++1:+    /* Return 32bit */+    cp.w    r9, FFI_TYPE_UINT32+    breq    .Lstore32+    cp.w    r9, FFI_TYPE_UINT16+    breq    .Lstore32+    cp.w    r9, FFI_TYPE_UINT8+    breq    .Lstore32++    /* Return 64bit */+    cp.w    r9, FFI_TYPE_UINT64+    breq    .Lstore64++    /* Didn't match anything */+    bral    .Lend++.Lstore64:+    st.w    r8[0], r11+    st.w    r8[4], r10+    bral    .Lend++.Lstore32:+    st.w    r8[0], r12+    bral    .Lend++.Lstore16:+    st.h    r8[0], r12+    bral    .Lend++.Lstore8:+    st.b    r8[0], r12+    bral    .Lend++.Lend:+    sub     sp, -20+    ldm     sp++, r0,r1,pc++    .size   ffi_call_SYSV, . - ffi_call_SYSV+++    /* r12:  __ctx+     * r11:  __rstruct_flag+     * r10:  __inner */++    .align  1+    .globl  ffi_closure_SYSV+    .type   ffi_closure_SYSV, @function+ffi_closure_SYSV:+    stm     --sp, r0,lr+    mov     r0, r11+    mov     r8, r10+    sub     r10, sp, -8+    sub     sp, 12+    st.w    sp[8], sp+    sub     r11, sp, -8+    icall   r8++    /* Check if return type is actually a struct */+    cp.w    r0, 0+    breq    1f++    /* Return 8bit */+    cp.w    r12, FFI_TYPE_UINT8+    breq    .Lget8++    /* Return 16bit */+    cp.w    r12, FFI_TYPE_UINT16+    breq    .Lget16++1:+    /* Return 32bit */+    cp.w    r12, FFI_TYPE_UINT32+    breq    .Lget32+    cp.w    r12, FFI_TYPE_UINT16+    breq    .Lget32+    cp.w    r12, FFI_TYPE_UINT8+    breq    .Lget32++    /* Return 64bit */+    cp.w    r12, FFI_TYPE_UINT64+    breq    .Lget64++    /* Didn't match anything */+    bral    .Lclend++.Lget64:+    ld.w    r11, sp[0]+    ld.w    r10, sp[4]+    bral    .Lclend++.Lget32:+    ld.w    r12, sp[0]+    bral    .Lclend++.Lget16:+    ld.uh   r12, sp[0]+    bral    .Lclend++.Lget8:+    ld.ub   r12, sp[0]+    bral    .Lclend++.Lclend:+    sub     sp, -12+    ldm     sp++, r0,lr+    sub     sp, -20+    mov     pc, lr++    .size   ffi_closure_SYSV, . - ffi_closure_SYSV++#if defined __ELF__ && defined __linux__+    .section    .note.GNU-stack,"",@progbits+#endif
+ src/bfin/ffi.c view
@@ -0,0 +1,196 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2012  Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>,+							   Paulo Pizarro <paulo.pizarro@gmail.com>++   Blackfin Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */+#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdio.h>++/* Maximum number of GPRs available for argument passing.  */+#define MAX_GPRARGS 3++/*+ * Return types+ */+#define FFIBFIN_RET_VOID 0+#define FFIBFIN_RET_BYTE 1+#define FFIBFIN_RET_HALFWORD 2+#define FFIBFIN_RET_INT64 3+#define FFIBFIN_RET_INT32 4++/*====================================================================*/+/*                          PROTOTYPE          *+ /*====================================================================*/+void ffi_prep_args(unsigned char *, extended_cif *);++/*====================================================================*/+/*                          Externals                                 */+/*                          (Assembly)                                */+/*====================================================================*/++extern void ffi_call_SYSV(unsigned, extended_cif *, void(*)(unsigned char *, extended_cif *), unsigned, void *, void(*fn)(void));++/*====================================================================*/+/*                          Implementation                            */+/*                                                            */+/*====================================================================*/+++/*+ * This function calculates the return type (size) based on type.+ */++ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+   /* --------------------------------------*+    *   Return handling                *+    * --------------------------------------*/+   switch (cif->rtype->type) {+      case FFI_TYPE_VOID:+         cif->flags = FFIBFIN_RET_VOID;+         break;+      case FFI_TYPE_UINT16:+      case FFI_TYPE_SINT16:+         cif->flags = FFIBFIN_RET_HALFWORD;+         break;+      case FFI_TYPE_UINT8:+         cif->flags = FFIBFIN_RET_BYTE;+         break;+      case FFI_TYPE_INT:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_SINT32:+      case FFI_TYPE_FLOAT:+      case FFI_TYPE_POINTER:+      case FFI_TYPE_SINT8:+         cif->flags = FFIBFIN_RET_INT32;+         break;+      case FFI_TYPE_SINT64:+      case FFI_TYPE_UINT64:+      case FFI_TYPE_DOUBLE:+          cif->flags = FFIBFIN_RET_INT64;+          break;+      case FFI_TYPE_STRUCT:+         if (cif->rtype->size <= 4){+        	 cif->flags = FFIBFIN_RET_INT32;+         }else if (cif->rtype->size == 8){+        	 cif->flags = FFIBFIN_RET_INT64;+         }else{+        	 //it will return via a hidden pointer in P0+        	 cif->flags = FFIBFIN_RET_VOID;+         }+         break;+      default:+         FFI_ASSERT(0);+         break;+   }+   return FFI_OK;+}++/*+ * This will prepare the arguments and will call the assembly routine+ * cif = the call interface+ * fn = the function to be called+ * rvalue = the return value+ * avalue = the arguments+ */+void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)+{+   int ret_type = cif->flags;+   extended_cif ecif;+   ecif.cif = cif;+   ecif.avalue = avalue;+   ecif.rvalue = rvalue;++   switch (cif->abi) {+      case FFI_SYSV:+         ffi_call_SYSV(cif->bytes, &ecif, ffi_prep_args, ret_type, ecif.rvalue, fn);+         break;+      default:+         FFI_ASSERT(0);+         break;+   }+}+++/*+* This function prepares the parameters (copies them from the ecif to the stack)+*  to call the function (ffi_prep_args is called by the assembly routine in file+*  sysv.S, which also calls the actual function)+*/+void ffi_prep_args(unsigned char *stack, extended_cif *ecif)+{+   register unsigned int i = 0;+   void **p_argv;+   unsigned char *argp;+   ffi_type **p_arg;+   argp = stack;+   p_argv = ecif->avalue;+   for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+        (i != 0);+        i--, p_arg++) {+      size_t z;+      z = (*p_arg)->size;+      if (z < sizeof(int)) {+         z = sizeof(int);+         switch ((*p_arg)->type) {+            case FFI_TYPE_SINT8: {+                  signed char v = *(SINT8 *)(* p_argv);+                  signed int t = v;+                  *(signed int *) argp = t;+               }+               break;+            case FFI_TYPE_UINT8: {+                  unsigned char v = *(UINT8 *)(* p_argv);+                  unsigned int t = v;+                  *(unsigned int *) argp = t;+               }+               break;+            case FFI_TYPE_SINT16:+               *(signed int *) argp = (signed int) * (SINT16 *)(* p_argv);+               break;+            case FFI_TYPE_UINT16:+               *(unsigned int *) argp = (unsigned int) * (UINT16 *)(* p_argv);+               break;+            case FFI_TYPE_STRUCT:+               memcpy(argp, *p_argv, (*p_arg)->size);+               break;+            default:+               FFI_ASSERT(0);+               break;+         }+      } else if (z == sizeof(int)) {+         *(unsigned int *) argp = (unsigned int) * (UINT32 *)(* p_argv);+      } else {+         memcpy(argp, *p_argv, z);+      }+      p_argv++;+      argp += z;+   }+}+++
+ src/bfin/ffitarget.h view
@@ -0,0 +1,43 @@+/* -----------------------------------------------------------------------+   ffitarget.h - Copyright (c) 2012  Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>++   Blackfin 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.+   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed 	 long          ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++#endif+
+ src/bfin/sysv.S view
@@ -0,0 +1,179 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2012  Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>,+                                Paulo Pizarro <paulo.pizarro@gmail.com>++   Blackfin Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++.text+.align 4++	/*+	 There is a "feature" in the bfin toolchain that it puts a _ before function names+	 that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV+	 */+	.global _ffi_call_SYSV;+	.type _ffi_call_SYSV, STT_FUNC;+	.func ffi_call_SYSV++	/*+         cif->bytes    = R0    (fp+8)+         &ecif         = R1    (fp+12)+         ffi_prep_args = R2    (fp+16)+         ret_type      = stack (fp+20)+         ecif.rvalue   = stack (fp+24)+         fn            = stack (fp+28)+                           got (fp+32)++        There is room for improvement here (we can use temporary registers+        instead of saving the values in the memory)+        REGS:+        P5 => Stack pointer (function arguments)+        R5 => cif->bytes+        R4 => ret->type++        FP-20 = P3+        FP-16 = SP (parameters area)+        FP-12 = SP (temp)+        FP-08 = function return part 1 [R0]+        FP-04 = function return part 2 [R1]+	*/++_ffi_call_SYSV:+.prologue:+	LINK 20;+	[FP-20] = P3;+	[FP+8] = R0;+	[FP+12] = R1;+	[FP+16] = R2;++.allocate_stack:+	//alocate cif->bytes into the stack+	R1 = [FP+8];+	R0 = SP;+	R0 = R0 - R1;+	R1 = 4;+	R0 = R0 - R1;+	[FP-12] = SP;+	SP = R0;+	[FP-16] = SP;++.call_prep_args:+	//get the addr of prep_args+	P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4];+	P1 = [P0];+	P3 = [P0+4];+	R0 = [FP-16];//SP (parameter area)+	R1 = [FP+12];//ecif+	call (P1);++.call_user_function:+	//ajust SP so as to allow the user function access the parameters on the stack+	SP = [FP-16]; //point to function parameters+	R0 = [SP];+	R1 = [SP+4];+	R2 = [SP+8];+	//load user function address+	P0 = FP;+	P0 +=28;+	P1 = [P0];+	P1 = [P1];+	P3 = [P0+4];+	/*+		For functions returning aggregate values (struct) occupying more than 8 bytes,+		the caller allocates the return value object on the stack and the address+		of this object is passed to the callee as a hidden argument in register P0.+	*/+	P0 = [FP+24];++	call (P1);+	SP = [FP-12];+.compute_return:+	P2 = [FP-20];+	[FP-8] = R0;+	[FP-4] = R1;++	R0 = [FP+20];+	R1 = R0 << 2;++	R0 = [P2+.rettable@GOT17M4];+	R0 = R1 + R0;+	P2 = R0;+	R1 = [P2];++	P2 = [FP+-20];+	R0 = [P2+.rettable@GOT17M4];+	R0 = R1 + R0;+	P2 = R0;+	R0 = [FP-8];+	R1 = [FP-4];+	jump (P2);++/*+#define FFIBFIN_RET_VOID 0+#define FFIBFIN_RET_BYTE 1+#define FFIBFIN_RET_HALFWORD 2+#define FFIBFIN_RET_INT64 3+#define FFIBFIN_RET_INT32 4+*/+.align 4+.align 4+.rettable:+	.dd .epilogue - .rettable+	.dd	.rbyte - .rettable;+	.dd	.rhalfword - .rettable;+	.dd	.rint64 - .rettable;+	.dd	.rint32 - .rettable;++.rbyte:+	P0 = [FP+24];+	R0 = R0.B (Z);+	[P0] = R0;+	JUMP .epilogue+.rhalfword:+	P0 = [FP+24];+	R0 = R0.L;+	[P0] = R0;+	JUMP .epilogue+.rint64:+	P0 = [FP+24];// &rvalue+	[P0] = R0;+	[P0+4] = R1;+	JUMP .epilogue+.rint32:+	P0 = [FP+24];+	[P0] = R0;+.epilogue:+	R0 = [FP+8];+	R1 = [FP+12];+	R2 = [FP+16];+	P3 = [FP-20];+	UNLINK;+	RTS;++.size _ffi_call_SYSV,.-_ffi_call_SYSV;+.endfunc
+ src/closures.c view
@@ -0,0 +1,1107 @@+/* -----------------------------------------------------------------------+   closures.c - Copyright (c) 2019, 2022 Anthony Green+                Copyright (c) 2007, 2009, 2010 Red Hat, Inc.+                Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc+                Copyright (c) 2011 Plausible Labs Cooperative, Inc.++   Code to allocate and deallocate memory for closures.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#if (defined __linux__ || defined __CYGWIN__) && !defined _GNU_SOURCE+#define _GNU_SOURCE 1+#endif++#ifndef __EMSCRIPTEN__++#include <fficonfig.h>+#include <ffi.h>+#include <ffi_common.h>+#include <tramp.h>++#ifdef __NetBSD__+#include <sys/param.h>+#endif++#if __NetBSD_Version__ - 0 >= 799007200+/* NetBSD with PROT_MPROTECT */+#include <sys/mman.h>++#include <stddef.h>+#include <unistd.h>+#ifdef  HAVE_SYS_MEMFD_H+#include <sys/memfd.h>+#endif++static const size_t overhead =+  (sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?+    sizeof(max_align_t)+    : sizeof(void *) + sizeof(size_t);++#define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))++void *+ffi_closure_alloc (size_t size, void **code)+{+  static size_t page_size;+  size_t rounded_size;+  void *codeseg, *dataseg;+  int prot;++  /* Expect that PAX mprotect is active and a separate code mapping is necessary. */+  if (!code)+    return NULL;++  /* Obtain system page size. */+  if (!page_size)+    page_size = sysconf(_SC_PAGESIZE);++  /* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */+  rounded_size = (size + overhead + page_size - 1) & ~(page_size - 1);++  /* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */+  prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);+  dataseg = mmap(NULL, rounded_size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);+  if (dataseg == MAP_FAILED)+    return NULL;++  /* Create secondary mapping and switch it to RX. */+  codeseg = mremap(dataseg, rounded_size, NULL, rounded_size, MAP_REMAPDUP);+  if (codeseg == MAP_FAILED) {+    munmap(dataseg, rounded_size);+    return NULL;+  }+  if (mprotect(codeseg, rounded_size, PROT_READ | PROT_EXEC) == -1) {+    munmap(codeseg, rounded_size);+    munmap(dataseg, rounded_size);+    return NULL;+  }++  /* Remember allocation size and location of the secondary mapping for ffi_closure_free. */+  memcpy(dataseg, &rounded_size, sizeof(rounded_size));+  memcpy(ADD_TO_POINTER(dataseg, sizeof(size_t)), &codeseg, sizeof(void *));+  *code = ADD_TO_POINTER(codeseg, overhead);+  return ADD_TO_POINTER(dataseg, overhead);+}++void+ffi_closure_free (void *ptr)+{+  void *codeseg, *dataseg;+  size_t rounded_size;++  dataseg = ADD_TO_POINTER(ptr, -overhead);+  memcpy(&rounded_size, dataseg, sizeof(rounded_size));+  memcpy(&codeseg, ADD_TO_POINTER(dataseg, sizeof(size_t)), sizeof(void *));+  munmap(dataseg, rounded_size);+  munmap(codeseg, rounded_size);+}++int+ffi_tramp_is_present (__attribute__((unused)) void *ptr)+{+  return 0;+}+#else /* !NetBSD with PROT_MPROTECT */++#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE+# 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+   fails, it falls back to creating a temporary file in a writable and+   executable filesystem and mapping pages from it into separate+   locations in the virtual memory space, one location writable and+   another executable.  */+#  define FFI_MMAP_EXEC_WRIT 1+#  define HAVE_MNTENT 1+# endif+# if defined(__CYGWIN__) || defined(_WIN32) || defined(__OS2__)+/* Windows systems may have Data Execution Protection (DEP) enabled,+   which requires the use of VirtualMalloc/VirtualFree to alloc/free+   executable memory. */+#  define FFI_MMAP_EXEC_WRIT 1+# endif+#endif++#if FFI_MMAP_EXEC_WRIT && defined(__linux__) && !defined(__ANDROID__)+# if !defined FFI_MMAP_EXEC_SELINUX+/* When defined to 1 check for SELinux and if SELinux is active,+   don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that+   might cause audit messages.  */+#  define FFI_MMAP_EXEC_SELINUX 1+# endif /* !defined FFI_MMAP_EXEC_SELINUX */+# if !defined FFI_MMAP_PAX+/* Also check for PaX MPROTECT */+#  define FFI_MMAP_PAX 1+# endif /* !defined FFI_MMAP_PAX */+#endif /* FFI_MMAP_EXEC_WRIT && defined(__linux__) && !defined(__ANDROID__) */++#if FFI_CLOSURES++#if FFI_EXEC_TRAMPOLINE_TABLE++#ifdef __MACH__++#include <mach/mach.h>+#include <pthread.h>+#ifdef HAVE_ARM64E_PTRAUTH+#include <ptrauth.h>+#endif+#include <stdio.h>+#include <stdlib.h>++extern void *ffi_closure_trampoline_table_page;++typedef struct ffi_trampoline_table ffi_trampoline_table;+typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;++struct ffi_trampoline_table+{+  /* contiguous writable and executable pages */+  vm_address_t config_page;++  /* free list tracking */+  uint16_t free_count;+  ffi_trampoline_table_entry *free_list;+  ffi_trampoline_table_entry *free_list_pool;++  ffi_trampoline_table *prev;+  ffi_trampoline_table *next;+};++struct ffi_trampoline_table_entry+{+  void *(*trampoline) (void);+  ffi_trampoline_table_entry *next;+};++/* Total number of trampolines that fit in one trampoline table */+#define FFI_TRAMPOLINE_COUNT (PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE)++static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;+static ffi_trampoline_table *ffi_trampoline_tables = NULL;++static ffi_trampoline_table *+ffi_trampoline_table_alloc (void)+{+  ffi_trampoline_table *table;+  vm_address_t config_page;+  vm_address_t trampoline_page;+  vm_address_t trampoline_page_template;+  vm_prot_t cur_prot;+  vm_prot_t max_prot;+  kern_return_t kt;+  uint16_t i;++  /* Allocate two pages -- a config page and a placeholder page */+  config_page = 0x0;+  kt = vm_allocate (mach_task_self (), &config_page, PAGE_MAX_SIZE * 2,+		    VM_FLAGS_ANYWHERE);+  if (kt != KERN_SUCCESS)+    return NULL;++  /* Remap the trampoline table on top of the placeholder page */+  trampoline_page = config_page + PAGE_MAX_SIZE;++#ifdef HAVE_ARM64E_PTRAUTH+  trampoline_page_template = (vm_address_t)(uintptr_t)ptrauth_auth_data((void *)&ffi_closure_trampoline_table_page, ptrauth_key_function_pointer, 0);+#else+  trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;+#endif++#ifdef __arm__+  /* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */+  trampoline_page_template &= ~1UL;+#endif+  kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0,+		 VM_FLAGS_OVERWRITE, mach_task_self (), trampoline_page_template,+		 FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);+  if (kt != KERN_SUCCESS)+    {+      vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);+      return NULL;+    }++  if (!(cur_prot & VM_PROT_EXECUTE))+    {+      /* If VM_PROT_EXECUTE isn't set on the remapped trampoline page, set it */+      kt = vm_protect (mach_task_self (), trampoline_page, PAGE_MAX_SIZE,+         FALSE, cur_prot | VM_PROT_EXECUTE);+      if (kt != KERN_SUCCESS)+        {+          vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);+          return NULL;+        }+    }++  /* We have valid trampoline and config pages */+  table = calloc (1, sizeof (ffi_trampoline_table));+  table->free_count = FFI_TRAMPOLINE_COUNT;+  table->config_page = config_page;++  /* Create and initialize the free list */+  table->free_list_pool =+    calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));++  for (i = 0; i < table->free_count; i++)+    {+      ffi_trampoline_table_entry *entry = &table->free_list_pool[i];+      entry->trampoline =+	(void *) (trampoline_page + (i * FFI_TRAMPOLINE_SIZE));+#ifdef HAVE_ARM64E_PTRAUTH+      entry->trampoline = ptrauth_sign_unauthenticated(entry->trampoline, ptrauth_key_function_pointer, 0);+#endif++      if (i < table->free_count - 1)+	entry->next = &table->free_list_pool[i + 1];+    }++  table->free_list = table->free_list_pool;++  return table;+}++static void+ffi_trampoline_table_free (ffi_trampoline_table *table)+{+  /* Remove from the list */+  if (table->prev != NULL)+    table->prev->next = table->next;++  if (table->next != NULL)+    table->next->prev = table->prev;++  /* Deallocate pages */+  vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);++  /* Deallocate free list */+  free (table->free_list_pool);+  free (table);+}++void *+ffi_closure_alloc (size_t size, void **code)+{+  /* Create the closure */+  ffi_closure *closure = malloc (size);+  if (closure == NULL)+    return NULL;++  pthread_mutex_lock (&ffi_trampoline_lock);++  /* Check for an active trampoline table with available entries. */+  ffi_trampoline_table *table = ffi_trampoline_tables;+  if (table == NULL || table->free_list == NULL)+    {+      table = ffi_trampoline_table_alloc ();+      if (table == NULL)+	{+	  pthread_mutex_unlock (&ffi_trampoline_lock);+	  free (closure);+	  return NULL;+	}++      /* Insert the new table at the top of the list */+      table->next = ffi_trampoline_tables;+      if (table->next != NULL)+	table->next->prev = table;++      ffi_trampoline_tables = table;+    }++  /* Claim the free entry */+  ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;+  ffi_trampoline_tables->free_list = entry->next;+  ffi_trampoline_tables->free_count--;+  entry->next = NULL;++  pthread_mutex_unlock (&ffi_trampoline_lock);++  /* Initialize the return values */+  *code = entry->trampoline;+  closure->trampoline_table = table;+  closure->trampoline_table_entry = entry;++  return closure;+}++void+ffi_closure_free (void *ptr)+{+  ffi_closure *closure = ptr;++  pthread_mutex_lock (&ffi_trampoline_lock);++  /* Fetch the table and entry references */+  ffi_trampoline_table *table = closure->trampoline_table;+  ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;++  /* Return the entry to the free list */+  entry->next = table->free_list;+  table->free_list = entry;+  table->free_count++;++  /* If all trampolines within this table are free, and at least one other table exists, deallocate+   * the table */+  if (table->free_count == FFI_TRAMPOLINE_COUNT+      && ffi_trampoline_tables != table)+    {+      ffi_trampoline_table_free (table);+    }+  else if (ffi_trampoline_tables != table)+    {+      /* Otherwise, bump this table to the top of the list */+      table->prev = NULL;+      table->next = ffi_trampoline_tables;+      if (ffi_trampoline_tables != NULL)+	ffi_trampoline_tables->prev = table;++      ffi_trampoline_tables = table;+    }++  pthread_mutex_unlock (&ffi_trampoline_lock);++  /* Free the closure */+  free (closure);+}++#endif++// Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.++#elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */++#define USE_LOCKS 1+#define USE_DL_PREFIX 1+#ifdef __GNUC__+#ifndef USE_BUILTIN_FFS+#define USE_BUILTIN_FFS 1+#endif+#endif++/* We need to use mmap, not sbrk.  */+#define HAVE_MORECORE 0++/* We could, in theory, support mremap, but it wouldn't buy us anything.  */+#define HAVE_MREMAP 0++/* We have no use for this, so save some code and data.  */+#define NO_MALLINFO 1++/* We need all allocations to be in regular segments, otherwise we+   lose track of the corresponding code address.  */+#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T++/* Don't allocate more than a page unless needed.  */+#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)++#include <sys/types.h>+#include <sys/stat.h>+#include <fcntl.h>+#include <errno.h>+#ifndef _MSC_VER+#include <unistd.h>+#endif+#include <string.h>+#include <stdio.h>+#if !defined(_WIN32)+#ifdef HAVE_MNTENT+#include <mntent.h>+#endif /* HAVE_MNTENT */+#include <sys/param.h>+#include <pthread.h>++/* We don't want sys/mman.h to be included after we redefine mmap and+   dlmunmap.  */+#include <sys/mman.h>+#define LACKS_SYS_MMAN_H 1++#if FFI_MMAP_EXEC_SELINUX+#include <sys/statfs.h>+#include <stdlib.h>++static int selinux_enabled = -1;++static int+selinux_enabled_check (void)+{+  struct statfs sfs;+  FILE *f;+  char *buf = NULL;+  size_t len = 0;++  if (statfs ("/selinux", &sfs) >= 0+      && (unsigned int) sfs.f_type == 0xf97cff8cU)+    return 1;+  f = fopen ("/proc/mounts", "r");+  if (f == NULL)+    return 0;+  while (getline (&buf, &len, f) >= 0)+    {+      char *p = strchr (buf, ' ');+      if (p == NULL)+        break;+      p = strchr (p + 1, ' ');+      if (p == NULL)+        break;+      if (strncmp (p + 1, "selinuxfs ", 10) == 0)+        {+          free (buf);+          fclose (f);+          return 1;+        }+    }+  free (buf);+  fclose (f);+  return 0;+}++#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \+			      : (selinux_enabled = selinux_enabled_check ()))++#else++#define is_selinux_enabled() 0++#endif /* !FFI_MMAP_EXEC_SELINUX */++/* On PaX enable kernels that have MPROTECT enabled we can't use PROT_EXEC. */+#if defined FFI_MMAP_PAX+#include <stdlib.h>++enum {+  PAX_MPROTECT = (1 << 0),+  PAX_EMUTRAMP = (1 << 1),+};+static int cached_pax_flags = -1;++static int+pax_flags_check (void)+{+  char *buf = NULL;+  size_t len = 0;+  FILE *f;+  int ret;+  f = fopen ("/proc/self/status", "r");+  if (f == NULL)+    return 0;+  ret = 0;++  while (getline (&buf, &len, f) != -1)+    if (!strncmp (buf, "PaX:", 4))+      {+        if (NULL != strchr (buf + 4, 'M'))+          ret |= PAX_MPROTECT;+        if (NULL != strchr (buf + 4, 'E'))+          ret |= PAX_EMUTRAMP;+        break;+      }+  free (buf);+  fclose (f);+  return ret;+}++#define get_pax_flags() (cached_pax_flags >= 0 ? cached_pax_flags \+                               : (cached_pax_flags = pax_flags_check ()))+#define has_pax_flags(flags) ((flags) == ((flags) & get_pax_flags ()))+#define is_mprotect_enabled() (has_pax_flags (PAX_MPROTECT))+#define is_emutramp_enabled() (has_pax_flags (PAX_EMUTRAMP))++#endif /* defined FFI_MMAP_PAX */++#elif defined (__CYGWIN__) || defined(__INTERIX)++#include <sys/mman.h>++/* Cygwin is Linux-like, but not quite that Linux-like.  */+#define is_selinux_enabled() 0++#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */++#if !defined FFI_MMAP_PAX+# define is_mprotect_enabled() 0+# define is_emutramp_enabled() 0+#endif /* !defined FFI_MMAP_PAX */++/* Declare all functions defined in dlmalloc.c as static.  */+static void *dlmalloc(size_t);+static void dlfree(void*);+static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;+static void *dlrealloc(void *, size_t) MAYBE_UNUSED;+static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;+static void *dlvalloc(size_t) MAYBE_UNUSED;+static int dlmallopt(int, int) MAYBE_UNUSED;+static size_t dlmalloc_footprint(void) MAYBE_UNUSED;+static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;+static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;+static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;+static void *dlpvalloc(size_t) MAYBE_UNUSED;+static int dlmalloc_trim(size_t) MAYBE_UNUSED;+static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;+static void dlmalloc_stats(void) MAYBE_UNUSED;++#if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)+/* Use these for mmap and munmap within dlmalloc.c.  */+static void *dlmmap(void *, size_t, int, int, int, off_t);+static int dlmunmap(void *, size_t);+#endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */++#define mmap dlmmap+#define munmap dlmunmap++#include "dlmalloc.c"++#undef mmap+#undef munmap++#if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)++/* A mutex used to synchronize access to *exec* variables in this file.  */+static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;++/* A file descriptor of a temporary file from which we'll map+   executable pages.  */+static int execfd = -1;++/* The amount of space already allocated from the temporary file.  */+static size_t execsize = 0;++#ifdef HAVE_MEMFD_CREATE+/* Open a temporary file name, and immediately unlink it.  */+static int+open_temp_exec_file_memfd (const char *name)+{+  int fd;+  fd = memfd_create (name, MFD_CLOEXEC);+  return fd;+}+#endif++/* Open a temporary file name, and immediately unlink it.  */+static int+open_temp_exec_file_name (char *name, int flags MAYBE_UNUSED)+{+  int fd;++#ifdef HAVE_MKOSTEMP+  fd = mkostemp (name, flags);+#else+  fd = mkstemp (name);+#endif++  if (fd != -1)+    unlink (name);++  return fd;+}++/* Open a temporary file in the named directory.  */+static int+open_temp_exec_file_dir (const char *dir)+{+  static const char suffix[] = "/ffiXXXXXX";+  int lendir, flags;+  char *tempname;+#ifdef O_TMPFILE+  int fd;+#endif++#ifdef O_CLOEXEC+  flags = O_CLOEXEC;+#else+  flags = 0;+#endif++#ifdef O_TMPFILE+  fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700);+  /* If the running system does not support the O_TMPFILE flag then retry without it. */+  if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) {+    return fd;+  } else {+    errno = 0;+  }+#endif++  lendir = (int) strlen (dir);+  tempname = __builtin_alloca (lendir + sizeof (suffix));++  if (!tempname)+    return -1;++  memcpy (tempname, dir, lendir);+  memcpy (tempname + lendir, suffix, sizeof (suffix));++  return open_temp_exec_file_name (tempname, flags);+}++/* Open a temporary file in the directory in the named environment+   variable.  */+static int+open_temp_exec_file_env (const char *envvar)+{+  const char *value = getenv (envvar);++  if (!value)+    return -1;++  return open_temp_exec_file_dir (value);+}++#ifdef HAVE_MNTENT+/* Open a temporary file in an executable and writable mount point+   listed in the mounts file.  Subsequent calls with the same mounts+   keep searching for mount points in the same file.  Providing NULL+   as the mounts file closes the file.  */+static int+open_temp_exec_file_mnt (const char *mounts)+{+  static const char *last_mounts;+  static FILE *last_mntent;++  if (mounts != last_mounts)+    {+      if (last_mntent)+	endmntent (last_mntent);++      last_mounts = mounts;++      if (mounts)+	last_mntent = setmntent (mounts, "r");+      else+	last_mntent = NULL;+    }++  if (!last_mntent)+    return -1;++  for (;;)+    {+      int fd;+      struct mntent mnt;+      char buf[MAXPATHLEN * 3];++      if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)+	return -1;++      if (hasmntopt (&mnt, "ro")+	  || hasmntopt (&mnt, "noexec")+	  || access (mnt.mnt_dir, W_OK))+	continue;++      fd = open_temp_exec_file_dir (mnt.mnt_dir);++      if (fd != -1)+	return fd;+    }+}+#endif /* HAVE_MNTENT */++/* Instructions to look for a location to hold a temporary file that+   can be mapped in for execution.  */+static struct+{+  int (*func)(const char *);+  const char *arg;+  int repeat;+} open_temp_exec_file_opts[] = {+#ifdef HAVE_MEMFD_CREATE+  { open_temp_exec_file_memfd, "libffi", 0 },+#endif+  { open_temp_exec_file_env, "LIBFFI_TMPDIR", 0 },+  { open_temp_exec_file_env, "TMPDIR", 0 },+  { open_temp_exec_file_dir, "/tmp", 0 },+  { open_temp_exec_file_dir, "/var/tmp", 0 },+  { open_temp_exec_file_dir, "/dev/shm", 0 },+  { open_temp_exec_file_env, "HOME", 0 },+#ifdef HAVE_MNTENT+  { open_temp_exec_file_mnt, "/etc/mtab", 1 },+  { open_temp_exec_file_mnt, "/proc/mounts", 1 },+#endif /* HAVE_MNTENT */+};++/* Current index into open_temp_exec_file_opts.  */+static int open_temp_exec_file_opts_idx = 0;++/* Reset a current multi-call func, then advances to the next entry.+   If we're at the last, go back to the first and return nonzero,+   otherwise return zero.  */+static int+open_temp_exec_file_opts_next (void)+{+  if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)+    open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);++  open_temp_exec_file_opts_idx++;+  if (open_temp_exec_file_opts_idx+      == (sizeof (open_temp_exec_file_opts)+	  / sizeof (*open_temp_exec_file_opts)))+    {+      open_temp_exec_file_opts_idx = 0;+      return 1;+    }++  return 0;+}++/* Return a file descriptor of a temporary zero-sized file in a+   writable and executable filesystem.  */+int+open_temp_exec_file (void)+{+  int fd;++  do+    {+      fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func+	(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);++      if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat+	  || fd == -1)+	{+	  if (open_temp_exec_file_opts_next ())+	    break;+	}+    }+  while (fd == -1);++  return fd;+}++/* We need to allocate space in a file that will be backing a writable+   mapping.  Several problems exist with the usual approaches:+   - fallocate() is Linux-only+   - posix_fallocate() is not available on all platforms+   - ftruncate() does not allocate space on filesystems with sparse files+   Failure to allocate the space will cause SIGBUS to be thrown when+   the mapping is subsequently written to.  */+static int+allocate_space (int fd, off_t len)+{+  static long page_size;++  /* Obtain system page size. */+  if (!page_size)+    page_size = sysconf(_SC_PAGESIZE);++  unsigned char buf[page_size];+  memset (buf, 0, page_size);++  while (len > 0)+    {+      off_t to_write = (len < page_size) ? len : page_size;+      if (write (fd, buf, to_write) < to_write)+        return -1;+      len -= to_write;+    }++  return 0;+}++/* Map in a chunk of memory from the temporary exec file into separate+   locations in the virtual memory address space, one writable and one+   executable.  Returns the address of the writable portion, after+   storing an offset to the corresponding executable portion at the+   last word of the requested chunk.  */+static void *+dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)+{+  void *ptr;++  if (execfd == -1)+    {+      open_temp_exec_file_opts_idx = 0;+    retry_open:+      execfd = open_temp_exec_file ();+      if (execfd == -1)+	return MFAIL;+    }++  offset = execsize;++  if (allocate_space (execfd, length))+    return MFAIL;++  flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);+  flags |= MAP_SHARED;++  ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,+	      flags, execfd, offset);+  if (ptr == MFAIL)+    {+      if (!offset)+	{+	  close (execfd);+	  goto retry_open;+	}+      if (ftruncate (execfd, offset) != 0)+      {+        /* Fixme : Error logs can be added here. Returning an error for+         * ftruncte() will not add any advantage as it is being+         * validating in the error case. */+      }++      return MFAIL;+    }+  else if (!offset+	   && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)+    open_temp_exec_file_opts_next ();++  start = mmap (start, length, prot, flags, execfd, offset);++  if (start == MFAIL)+    {+      munmap (ptr, length);+      if (ftruncate (execfd, offset) != 0)+      {+        /* Fixme : Error logs can be added here. Returning an error for+         * ftruncte() will not add any advantage as it is being+         * validating in the error case. */+      }+      return start;+    }++  mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;++  execsize += length;++  return start;+}++/* Map in a writable and executable chunk of memory if possible.+   Failing that, fall back to dlmmap_locked.  */+static void *+dlmmap (void *start, size_t length, int prot,+	int flags, int fd, off_t offset)+{+  void *ptr;++  assert (start == NULL && length % malloc_getpagesize == 0+	  && prot == (PROT_READ | PROT_WRITE)+	  && flags == (MAP_PRIVATE | MAP_ANONYMOUS)+	  && fd == -1 && offset == 0);++  if (execfd == -1 && ffi_tramp_is_supported ())+    {+      ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);+      return ptr;+    }++  /* -1 != execfd hints that we already decided to use dlmmap_locked+     last time.  */+  if (execfd == -1 && is_mprotect_enabled ())+    {+#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX+      if (is_emutramp_enabled ())+        {+          /* emutramp requires the kernel recognizing the trampoline pattern+             generated by ffi_prep_closure_loc; there is no way to test+             in advance whether this will work, so this is experimental.  */+          ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);+          return ptr;+        }+#endif+      /* fallback to dlmmap_locked.  */+    }+  else if (execfd == -1 && !is_selinux_enabled ())+    {+      ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);++      if (ptr != MFAIL || (errno != EPERM && errno != EACCES))+	/* Cool, no need to mess with separate segments.  */+	return ptr;++      /* If MREMAP_DUP is ever introduced and implemented, try mmap+	 with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with+	 MREMAP_DUP and prot at this point.  */+    }++  pthread_mutex_lock (&open_temp_exec_file_mutex);+  ptr = dlmmap_locked (start, length, prot, flags, offset);+  pthread_mutex_unlock (&open_temp_exec_file_mutex);++  return ptr;+}++/* Release memory at the given address, as well as the corresponding+   executable page if it's separate.  */+static int+dlmunmap (void *start, size_t length)+{+  /* We don't bother decreasing execsize or truncating the file, since+     we can't quite tell whether we're unmapping the end of the file.+     We don't expect frequent deallocation anyway.  If we did, we+     could locate pages in the file by writing to the pages being+     deallocated and checking that the file contents change.+     Yuck.  */+  msegmentptr seg = segment_holding (gm, start);+  void *code;++  if (seg && (code = add_segment_exec_offset (start, seg)) != start)+    {+      int ret = munmap (code, length);+      if (ret)+	return ret;+    }++  return munmap (start, length);+}++#if FFI_CLOSURE_FREE_CODE+/* Return segment holding given code address.  */+static msegmentptr+segment_holding_code (mstate m, char* addr)+{+  msegmentptr sp = &m->seg;+  for (;;) {+    if (addr >= add_segment_exec_offset (sp->base, sp)+	&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)+      return sp;+    if ((sp = sp->next) == 0)+      return 0;+  }+}+#endif++#endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */++/* Allocate a chunk of memory with the given size.  Returns a pointer+   to the writable address, and sets *CODE to the executable+   corresponding virtual address.  */+void *+ffi_closure_alloc (size_t size, void **code)+{+  void *ptr, *ftramp;++  if (!code)+    return NULL;++  ptr = dlmalloc (size);++  if (ptr)+    {+      msegmentptr seg = segment_holding (gm, ptr);++      *code = FFI_FN (add_segment_exec_offset (ptr, seg));+      if (!ffi_tramp_is_supported ())+        return ptr;++      ftramp = ffi_tramp_alloc (0);+      if (ftramp == NULL)+      {+        dlfree (ptr);+        return NULL;+      }+      *code = FFI_FN (ffi_tramp_get_addr (ftramp));+      ((ffi_closure *) ptr)->ftramp = ftramp;+    }++  return ptr;+}++void *+ffi_data_to_code_pointer (void *data)+{+  msegmentptr seg = segment_holding (gm, data);+  /* We expect closures to be allocated with ffi_closure_alloc(), in+     which case seg will be non-NULL.  However, some users take on the+     burden of managing this memory themselves, in which case this+     we'll just return data. */+  if (seg)+    {+      if (!ffi_tramp_is_supported ())+        return add_segment_exec_offset (data, seg);+      return ffi_tramp_get_addr (((ffi_closure *) data)->ftramp);+    }+  else+    return data;+}++/* Release a chunk of memory allocated with ffi_closure_alloc.  If+   FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the+   writable or the executable address given.  Otherwise, only the+   writable address can be provided here.  */+void+ffi_closure_free (void *ptr)+{+#if FFI_CLOSURE_FREE_CODE+  msegmentptr seg = segment_holding_code (gm, ptr);++  if (seg)+    ptr = sub_segment_exec_offset (ptr, seg);+#endif+  if (ffi_tramp_is_supported ())+    ffi_tramp_free (((ffi_closure *) ptr)->ftramp);++  dlfree (ptr);+}++int+ffi_tramp_is_present (void *ptr)+{+  msegmentptr seg = segment_holding (gm, ptr);+  return seg != NULL && ffi_tramp_is_supported();+}++# else /* ! FFI_MMAP_EXEC_WRIT */++/* On many systems, memory returned by malloc is writable and+   executable, so just use it.  */++#include <stdlib.h>++void *+ffi_closure_alloc (size_t size, void **code)+{+  void *c;++  if (!code)+    return NULL;++  c = malloc (size);+  *code = FFI_FN (c);+  return c;+}++void+ffi_closure_free (void *ptr)+{+  free (ptr);+}++void *+ffi_data_to_code_pointer (void *data)+{+  return data;+}++int+ffi_tramp_is_present (__attribute__((unused)) void *ptr)+{+  return 0;+}++# endif /* ! FFI_MMAP_EXEC_WRIT */+#endif /* FFI_CLOSURES */++#endif /* NetBSD with PROT_MPROTECT */+#endif /* __EMSCRIPTEN__ */
+ src/cris/ffi.c view
@@ -0,0 +1,386 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 1998 Cygnus Solutions+           Copyright (c) 2004 Simon Posnjak+	   Copyright (c) 2005 Axis Communications AB+	   Copyright (C) 2007 Free Software Foundation, Inc.++   CRIS Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)++static ffi_status+initialize_aggregate_packed_struct (ffi_type * arg)+{+  ffi_type **ptr;++  FFI_ASSERT (arg != NULL);++  FFI_ASSERT (arg->elements != NULL);+  FFI_ASSERT (arg->size == 0);+  FFI_ASSERT (arg->alignment == 0);++  ptr = &(arg->elements[0]);++  while ((*ptr) != NULL)+    {+      if (((*ptr)->size == 0)+	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))+	return FFI_BAD_TYPEDEF;++      FFI_ASSERT (ffi_type_test ((*ptr)));++      arg->size += (*ptr)->size;++      arg->alignment = (arg->alignment > (*ptr)->alignment) ?+	arg->alignment : (*ptr)->alignment;++      ptr++;+    }++  if (arg->size == 0)+    return FFI_BAD_TYPEDEF;+  else+    return FFI_OK;+}++int+ffi_prep_args (char *stack, extended_cif * ecif)+{+  unsigned int i;+  unsigned int struct_count = 0;+  void **p_argv;+  char *argp;+  ffi_type **p_arg;++  argp = stack;++  p_argv = ecif->avalue;++  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+       (i != 0); i--, p_arg++)+    {+      size_t z;++      switch ((*p_arg)->type)+	{+	case FFI_TYPE_STRUCT:+	  {+	    z = (*p_arg)->size;+	    if (z <= 4)+	      {+		memcpy (argp, *p_argv, z);+		z = 4;+	      }+	    else if (z <= 8)+	      {+		memcpy (argp, *p_argv, z);+		z = 8;+	      }+	    else+	      {+		unsigned int uiLocOnStack;+		z = sizeof (void *);+		uiLocOnStack = 4 * ecif->cif->nargs + struct_count;+		struct_count = struct_count + (*p_arg)->size;+		*(unsigned int *) argp =+		  (unsigned int) (UINT32 *) (stack + uiLocOnStack);+		memcpy ((stack + uiLocOnStack), *p_argv, (*p_arg)->size);+	      }+	    break;+	  }+	default:+	  z = (*p_arg)->size;+	  if (z < sizeof (int))+	    {+	      switch ((*p_arg)->type)+		{+		case FFI_TYPE_SINT8:+		  *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv);+		  break;++		case FFI_TYPE_UINT8:+		  *(unsigned int *) argp =+		    (unsigned int) *(UINT8 *) (*p_argv);+		  break;++		case FFI_TYPE_SINT16:+		  *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv);+		  break;++		case FFI_TYPE_UINT16:+		  *(unsigned int *) argp =+		    (unsigned int) *(UINT16 *) (*p_argv);+		  break;++		default:+		  FFI_ASSERT (0);+		}+	      z = sizeof (int);+	    }+	  else if (z == sizeof (int))+	    *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv);+	  else+	    memcpy (argp, *p_argv, z);+	  break;+	}+      p_argv++;+      argp += z;+    }++  return (struct_count);+}++ffi_status FFI_HIDDEN+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)+{+  unsigned bytes = 0;+  unsigned int i;+  ffi_type **ptr;++  FFI_ASSERT (cif != NULL);+  FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));+  FFI_ASSERT(nfixedargs <= ntotalargs);+  FFI_ASSERT (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI);++  cif->abi = abi;+  cif->arg_types = atypes;+  cif->nargs = ntotalargs;+  cif->rtype = rtype;++  cif->flags = 0;++  if ((cif->rtype->size == 0)+      && (initialize_aggregate_packed_struct (cif->rtype) != FFI_OK))+    return FFI_BAD_TYPEDEF;++  FFI_ASSERT_VALID_TYPE (cif->rtype);++  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)+    {+      if (((*ptr)->size == 0)+	  && (initialize_aggregate_packed_struct ((*ptr)) != FFI_OK))+	return FFI_BAD_TYPEDEF;++      FFI_ASSERT_VALID_TYPE (*ptr);++      if (((*ptr)->alignment - 1) & bytes)+	bytes = FFI_ALIGN (bytes, (*ptr)->alignment);+      if ((*ptr)->type == FFI_TYPE_STRUCT)+	{+	  if ((*ptr)->size > 8)+	    {+	      bytes += (*ptr)->size;+	      bytes += sizeof (void *);+	    }+	  else+	    {+	      if ((*ptr)->size > 4)+		bytes += 8;+	      else+		bytes += 4;+	    }+	}+      else+	bytes += STACK_ARG_SIZE ((*ptr)->size);+    }++  cif->bytes = bytes;++  return ffi_prep_cif_machdep (cif);+}++ffi_status+ffi_prep_cif_machdep (ffi_cif * cif)+{+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+    case FFI_TYPE_STRUCT:+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      cif->flags = (unsigned) cif->rtype->type;+      break;++    default:+      cif->flags = FFI_TYPE_INT;+      break;+    }++  return FFI_OK;+}++extern void ffi_call_SYSV (int (*)(char *, extended_cif *),+			   extended_cif *,+			   unsigned, unsigned, unsigned *, void (*fn) ())+     __attribute__ ((__visibility__ ("hidden")));++void+ffi_call (ffi_cif * cif, void (*fn) (), void *rvalue, void **avalue)+{+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;++  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))+    {+      ecif.rvalue = alloca (cif->rtype->size);+    }+  else+    ecif.rvalue = rvalue;++  switch (cif->abi)+    {+    case FFI_SYSV:+      ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,+		     cif->flags, ecif.rvalue, fn);+      break;+    default:+      FFI_ASSERT (0);+      break;+    }+}++/* Because the following variables are not exported outside libffi, we+   mark them hidden.  */++/* Assembly code for the jump stub.  */+extern const char ffi_cris_trampoline_template[]+ __attribute__ ((__visibility__ ("hidden")));++/* Offset into ffi_cris_trampoline_template of where to put the+   ffi_prep_closure_inner function.  */+extern const int ffi_cris_trampoline_fn_offset+ __attribute__ ((__visibility__ ("hidden")));++/* Offset into ffi_cris_trampoline_template of where to put the+   closure data.  */+extern const int ffi_cris_trampoline_closure_offset+ __attribute__ ((__visibility__ ("hidden")));++/* This function is sibling-called (jumped to) by the closure+   trampoline.  We get R10..R13 at PARAMS[0..3] and a copy of [SP] at+   PARAMS[4] to simplify handling of a straddling parameter.  A copy+   of R9 is at PARAMS[5] and SP at PARAMS[6].  These parameters are+   put at the appropriate place in CLOSURE which is then executed and+   the return value is passed back to the caller.  */++static unsigned long long+ffi_prep_closure_inner (void **params, ffi_closure* closure)+{+  char *register_args = (char *) params;+  void *struct_ret = params[5];+  char *stack_args = params[6];+  char *ptr = register_args;+  ffi_cif *cif = closure->cif;+  ffi_type **arg_types = cif->arg_types;++  /* Max room needed is number of arguments as 64-bit values.  */+  void **avalue = alloca (closure->cif->nargs * sizeof(void *));+  int i;+  int doing_regs;+  long long llret = 0;++  /* Find the address of each argument.  */+  for (i = 0, doing_regs = 1; i < cif->nargs; i++)+    {+      /* Types up to and including 8 bytes go by-value.  */+      if (arg_types[i]->size <= 4)+	{+	  avalue[i] = ptr;+	  ptr += 4;+	}+      else if (arg_types[i]->size <= 8)+	{+	  avalue[i] = ptr;+	  ptr += 8;+	}+      else+	{+	  FFI_ASSERT (arg_types[i]->type == FFI_TYPE_STRUCT);++	  /* Passed by-reference, so copy the pointer.  */+	  avalue[i] = *(void **) ptr;+	  ptr += 4;+	}++      /* If we've handled more arguments than fit in registers, start+	 looking at the those passed on the stack.  Step over the+	 first one if we had a straddling parameter.  */+      if (doing_regs && ptr >= register_args + 4*4)+	{+	  ptr = stack_args + ((ptr > register_args + 4*4) ? 4 : 0);+	  doing_regs = 0;+	}+    }++  /* Invoke the closure.  */+  (closure->fun) (cif,++		  cif->rtype->type == FFI_TYPE_STRUCT+		  /* The caller allocated space for the return+		     structure, and passed a pointer to this space in+		     R9.  */+		  ? struct_ret++		  /* We take advantage of being able to ignore that+		     the high part isn't set if the return value is+		     not in R10:R11, but in R10 only.  */+		  : (void *) &llret,++		  avalue, closure->user_data);++  return llret;+}++/* API function: Prepare the trampoline.  */++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif *, void *, void **, void*),+		      void *user_data,+		      void *codeloc)+{+  void *innerfn = ffi_prep_closure_inner;+  FFI_ASSERT (cif->abi == FFI_SYSV);+  closure->cif  = cif;+  closure->user_data = user_data;+  closure->fun  = fun;+  memcpy (closure->tramp, ffi_cris_trampoline_template,+	  FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE);+  memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,+	  &innerfn, sizeof (void *));+  memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,+	  &codeloc, sizeof (void *));++  return FFI_OK;+}
+ src/cris/ffitarget.h view
@@ -0,0 +1,56 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for CRIS.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE 36+#define FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE (7*4)+#define FFI_TRAMPOLINE_SIZE \+ (FFI_CRIS_TRAMPOLINE_CODE_PART_SIZE + FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE)+#define FFI_NATIVE_RAW_API 0++#endif
+ src/cris/sysv.S view
@@ -0,0 +1,215 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2004 Simon Posnjak+	    Copyright (c) 2005 Axis Communications AB++   CRIS Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <ffi.h>+#define CONCAT(x,y) x ## y+#define XCONCAT(x,y) CONCAT (x, y)+#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)++	.text++	;; OK, when we get called we should have this (according to+	;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).+	;;+	;; R10:	 ffi_prep_args (func. pointer)+	;; R11:  &ecif+	;; R12:  cif->bytes+	;; R13:  fig->flags+	;; sp+0: ecif.rvalue+	;; sp+4: fn (function pointer to the function that we need to call)++	.globl  L(ffi_call_SYSV)+	.type   L(ffi_call_SYSV),@function+	.hidden	L(ffi_call_SYSV)++L(ffi_call_SYSV):+	;; Save the regs to the stack.+	push $srp+	;; Used for stack pointer saving.+	push $r6+	;; Used for function address pointer.+	push $r7+	;; Used for stack pointer saving.+	push $r8+	;; We save fig->flags to stack we will need them after we+	;; call The Function.+	push $r13++	;; Saving current stack pointer.+	move.d $sp,$r8+	move.d $sp,$r6++	;; Move address of ffi_prep_args to r13.+	move.d $r10,$r13++	;; Make room on the stack for the args of fn.+	sub.d  $r12,$sp++	;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:+	;; 	r10 <-- stack pointer+	;; 	r11 <-- &ecif (already there)+	move.d $sp,$r10++	;; Call the function.+	jsr $r13++	;; Save the size of the structures which are passed on stack.+	move.d $r10,$r7++	;; Move first four args in to r10..r13.+	move.d [$sp+0],$r10+	move.d [$sp+4],$r11+	move.d [$sp+8],$r12+	move.d [$sp+12],$r13++	;; Adjust the stack and check if any parameters are given on stack.+	addq 16,$sp+	sub.d $r7,$r6+	cmp.d $sp,$r6++	bpl go_on+	nop++go_on_no_params_on_stack:+	move.d $r6,$sp++go_on:+	;; Discover if we need to put rval address in to r9.+	move.d [$r8+0],$r7+	cmpq FFI_TYPE_STRUCT,$r7+	bne call_now+	nop++	;; Move rval address to $r9.+	move.d [$r8+20],$r9++call_now:+	;; Move address of The Function in to r7.+	move.d [$r8+24],$r7++	;; Call The Function.+	jsr $r7++	;; Reset stack.+	move.d $r8,$sp++	;; Load rval type (fig->flags) in to r13.+	pop $r13++	;; Detect rval type.+	cmpq FFI_TYPE_VOID,$r13+	beq epilogue++	cmpq FFI_TYPE_STRUCT,$r13+	beq epilogue++	cmpq FFI_TYPE_DOUBLE,$r13+	beq return_double_or_longlong++	cmpq FFI_TYPE_UINT64,$r13+	beq return_double_or_longlong++	cmpq FFI_TYPE_SINT64,$r13+	beq return_double_or_longlong+	nop++	;; Just return the 32 bit value.+	ba return+	nop++return_double_or_longlong:+	;; Load half of the rval to r10 and the other half to r11.+	move.d [$sp+16],$r13+	move.d $r10,[$r13]+	addq 4,$r13+	move.d $r11,[$r13]+	ba epilogue+	nop++return:+	;; Load the rval to r10.+	move.d [$sp+16],$r13+	move.d $r10,[$r13]++epilogue:+	pop $r8+	pop $r7+	pop $r6+	Jump [$sp+]++	.size   ffi_call_SYSV,.-ffi_call_SYSV++/* Save R10..R13 into an array, somewhat like varargs.  Copy the next+   argument too, to simplify handling of any straddling parameter.+   Save R9 and SP after those.  Jump to function handling the rest.+   Since this is a template, copied and the main function filled in by+   the user.  */++	.globl	L(ffi_cris_trampoline_template)+	.type	L(ffi_cris_trampoline_template),@function+	.hidden	L(ffi_cris_trampoline_template)++L(ffi_cris_trampoline_template):+0:+	/* The value we get for "PC" is right after the prefix instruction,+	   two bytes from the beginning, i.e. 0b+2. */+	move.d $r10,[$pc+2f-(0b+2)]+	move.d $pc,$r10+1:+	addq 2f-1b+4,$r10+	move.d $r11,[$r10+]+	move.d $r12,[$r10+]+	move.d $r13,[$r10+]+	move.d [$sp],$r11+	move.d $r11,[$r10+]+	move.d $r9,[$r10+]+	move.d $sp,[$r10+]+	subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10+	move.d 0,$r11+3:+        jump 0+2:+	.size	ffi_cris_trampoline_template,.-0b++/* This macro create a constant usable as "extern const int \name" in+   C from within libffi, when \name has no prefix decoration.  */++	.macro const name,value+	.globl	\name+	.type	\name,@object+	.hidden	\name+\name:+	.dword  \value+	.size	\name,4+	.endm++/* Constants for offsets within the trampoline.  We could do this with+   just symbols, avoiding memory contents and memory accesses, but the+   C usage code would look a bit stranger.  */++	const L(ffi_cris_trampoline_fn_offset),2b-4-0b+	const L(ffi_cris_trampoline_closure_offset),3b-4-0b
+ src/csky/ffi.c view
@@ -0,0 +1,395 @@+/* -----------------------------------------------------------------------+   ffi.c++   CSKY Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments+*/+void ffi_prep_args(char *stack, extended_cif *ecif)+{+ register unsigned int i;+ register void **p_argv;+ register char *argp;+ register ffi_type **p_arg;++ argp = stack;++ if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {+  *(void **) argp = ecif->rvalue;+  argp += 4;+ }++ p_argv = ecif->avalue;++ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+   (i != 0);+   i--, p_arg++)+ {+  size_t z;+  size_t alignment;++  /* Align if necessary */+  alignment = (*p_arg)->alignment;+#ifdef __CSKYABIV1__+  /*+   * Adapt ABIV1 bug.+   * If struct's size is larger than 8 bytes, then it always alignment as 4 bytes.+   */+  if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && (alignment == 8)) {+   alignment = 4;+  }+#endif++  if ((alignment - 1) & (unsigned) argp) {+   argp = (char *) FFI_ALIGN(argp, alignment);+  }++  if ((*p_arg)->type == FFI_TYPE_STRUCT)+   argp = (char *) FFI_ALIGN(argp, 4);++  z = (*p_arg)->size;+  if (z < sizeof(int))+  {+   z = sizeof(int);+   switch ((*p_arg)->type)+   {+   case FFI_TYPE_SINT8:+    *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);+    break;++   case FFI_TYPE_UINT8:+    *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);+    break;++   case FFI_TYPE_SINT16:+    *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);+    break;++   case FFI_TYPE_UINT16:+    *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);+    break;++   case FFI_TYPE_STRUCT:+#ifdef __CSKYBE__+    memcpy((argp + 4 - (*p_arg)->size), *p_argv, (*p_arg)->size);+#else+    memcpy(argp, *p_argv, (*p_arg)->size);+#endif+    break;++   default:+    FFI_ASSERT(0);+   }+  }+  else if (z == sizeof(int))+  {+   *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+  }+  else+  {+   memcpy(argp, *p_argv, z);+  }+  p_argv++;+  argp += z;+ }++ return;+}++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+  /* Round the stack up to a multiple of 8 bytes.  This isn't needed+     everywhere, but it is on some platforms, and it doesn't hcsky anything+     when it isn't needed.  */+  cif->bytes = (cif->bytes + 7) & ~7;++  /* Set the return type flag */+  switch (cif->rtype->type)+    {++    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      cif->flags = (unsigned) FFI_TYPE_SINT64;+      break;++    case FFI_TYPE_STRUCT:+      if (cif->rtype->size <= 4)+ /* A Composite Type not larger than 4 bytes is returned in r0.  */+ cif->flags = (unsigned)FFI_TYPE_INT;+      else if (cif->rtype->size <= 8)+ /* A Composite Type not larger than 8 bytes is returned in r0, r1.  */+ cif->flags = (unsigned)FFI_TYPE_SINT64;+      else+ /* A Composite Type larger than 8 bytes, or whose size cannot+    be determined statically ... is stored in memory at an+    address passed [in r0].  */+ cif->flags = (unsigned)FFI_TYPE_STRUCT;+      break;++    default:+      cif->flags = FFI_TYPE_INT;+      break;+    }++  return FFI_OK;+}++/* Perform machine dependent cif processing for variadic calls */+ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,+        unsigned int nfixedargs,+        unsigned int ntotalargs)+{+  return ffi_prep_cif_machdep(cif);+}++/* Prototypes for assembly functions, in sysv.S */+extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  extended_cif ecif;++  int small_struct = (cif->flags == FFI_TYPE_INT+        && cif->rtype->type == FFI_TYPE_STRUCT);++  ecif.cif = cif;+  ecif.avalue = avalue;++  unsigned int temp;++  /* If the return value is a struct and we don't have a return */+  /* value address then we need to make one          */++  if ((rvalue == NULL) &&+      (cif->flags == FFI_TYPE_STRUCT))+    {+      ecif.rvalue = alloca(cif->rtype->size);+    }+  else if (small_struct)+    ecif.rvalue = &temp;+  else+    ecif.rvalue = rvalue;++  switch (cif->abi)+    {+    case FFI_SYSV:+      ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);+      break;++    default:+      FFI_ASSERT(0);+      break;+    }+  if (small_struct)+#ifdef __CSKYBE__+    memcpy (rvalue, ((unsigned char *)&temp + (4 - cif->rtype->size)), cif->rtype->size);+#else+    memcpy (rvalue, &temp, cif->rtype->size);+#endif+}++/** private members **/++static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,+      void** args, ffi_cif* cif);++void ffi_closure_SYSV (ffi_closure *);++/* This function is jumped to by the trampoline */++unsigned int+ffi_closure_SYSV_inner (closure, respp, args)+     ffi_closure *closure;+     void **respp;+     void *args;+{+  // our various things...+  ffi_cif       *cif;+  void         **arg_area;++  cif         = closure->cif;+  arg_area    = (void**) alloca (cif->nargs * sizeof (void*));++  /* this call will initialize ARG_AREA, such that each+   * element in that array points to the corresponding+   * value on the stack; and if the function returns+   * a structure, it will re-set RESP to point to the+   * structure return address.  */++  ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);++  (closure->fun) (cif, *respp, arg_area, closure->user_data);++#ifdef __CSKYBE__+  if (cif->flags == FFI_TYPE_INT && cif->rtype->type == FFI_TYPE_STRUCT) {+      unsigned int tmp = 0;+      tmp = *(unsigned int *)(*respp);+      *(unsigned int *)(*respp) = (tmp >> ((4 - cif->rtype->size) * 8));+  }+#endif++  return cif->flags;+}+++static void+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,+       void **avalue, ffi_cif *cif)+{+  register unsigned int i;+  register void **p_argv;+  register char *argp;+  register ffi_type **p_arg;++  argp = stack;++  if ( cif->flags == FFI_TYPE_STRUCT ) {+    *rvalue = *(void **) argp;+    argp += 4;+  }++  p_argv = avalue;++  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)+    {+      size_t z;+      size_t alignment;++      alignment = (*p_arg)->alignment;+      if (alignment < 4)+ alignment = 4;++#ifdef __CSKYABIV1__+      /*+       * Adapt ABIV1 bug.+       * If struct's size is larger than 8 bytes, then it always alignment as 4 bytes.+       */+      if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && (alignment == 8)) {+        alignment = 4;+      }+#endif++      /* Align if necessary */+      if ((alignment - 1) & (unsigned) argp) {+ argp = (char *) FFI_ALIGN(argp, alignment);+      }++      z = (*p_arg)->size;++#ifdef __CSKYBE__+      unsigned int tmp = 0;+      if ((*p_arg)->size < 4) {+        tmp = *(unsigned int *)argp;+        memcpy(argp, ((unsigned char *)&tmp + (4 - (*p_arg)->size)), (*p_arg)->size);+      }+#else+      /* because we're little endian, this is what it turns into.   */+#endif+      *p_argv = (void*) argp;++      p_argv++;+      argp += z;+    }++  return;+}++/* How to make a trampoline.  */++extern unsigned char ffi_csky_trampoline[TRAMPOLINE_SIZE];++/*+ * Since there is no __clear_cache in libgcc in csky toolchain.+ * define ffi_csky_cacheflush in sysv.S.+ * void ffi_csky_cacheflush(uint32 start_addr, uint32 size, int cache)+ */+#define CACHEFLUSH_IN_FFI 1+#if CACHEFLUSH_IN_FFI+extern void ffi_csky_cacheflush(unsigned char *__tramp, unsigned int k,+  int i);+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX)                              \+({ unsigned char *__tramp = (unsigned char*)(TRAMP);                    \+   unsigned int  __fun = (unsigned int)(FUN);                           \+   unsigned int  __ctx = (unsigned int)(CTX);                           \+   unsigned char *insns = (unsigned char *)(CTX);                       \+   memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE);              \+   *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx;                  \+   *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun;              \+   ffi_csky_cacheflush(&__tramp[0], TRAMPOLINE_SIZE, 3); /* Clear data mapping.  */ \+   ffi_csky_cacheflush(insns, TRAMPOLINE_SIZE, 3);                       \+                                                 /* Clear instruction   \+                                                    mapping.  */        \+ })+#else+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX)                              \+({ unsigned char *__tramp = (unsigned char*)(TRAMP);                    \+   unsigned int  __fun = (unsigned int)(FUN);                           \+   unsigned int  __ctx = (unsigned int)(CTX);                           \+   unsigned char *insns = (unsigned char *)(CTX);                       \+   memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE);              \+   *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx;                  \+   *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun;              \+   __clear_cache((&__tramp[0]), (&__tramp[TRAMPOLINE_SIZE-1])); /* Clear data mapping.  */ \+   __clear_cache(insns, insns + TRAMPOLINE_SIZE);                       \+                                                 /* Clear instruction   \+                                                    mapping.  */        \+ })+#endif++/* the cif must already be prep'ed */++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+        ffi_cif* cif,+        void (*fun)(ffi_cif*,void*,void**,void*),+        void *user_data,+        void *codeloc)+{+  void (*closure_func)(ffi_closure*) = NULL;++  if (cif->abi == FFI_SYSV)+    closure_func = &ffi_closure_SYSV;+  else+    return FFI_BAD_ABI;++  FFI_INIT_TRAMPOLINE (&closure->tramp[0], \+         closure_func,  \+         codeloc);++  closure->cif  = cif;+  closure->user_data = user_data;+  closure->fun  = fun;++  return FFI_OK;+}++
+ src/csky/ffitarget.h view
@@ -0,0 +1,63 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 2010  CodeSourcery+                 Copyright (c) 1996-2003  Red Hat, Inc.++   Target configuration macros for CSKY.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV,+} ffi_abi;+#endif++#ifdef __CSKYABIV2__+#define FFI_ASM_ARGREG_SIZE 16+#define TRAMPOLINE_SIZE 16+#define FFI_TRAMPOLINE_SIZE 24+#else+#define FFI_ASM_ARGREG_SIZE 24+#define TRAMPOLINE_SIZE 20+#define FFI_TRAMPOLINE_SIZE 28+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0+#endif
+ src/csky/sysv.S view
@@ -0,0 +1,371 @@+/* -----------------------------------------------------------------------+   sysv.S++   CSKY Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++.macro CSKY_FUNC_START name+ .text+ .align 2+ .globl \name+ .type \name, @function+ \name:+.endm++#ifdef __CSKYABIV2__++ /*+  * a0:   fn+  * a1:   &ecif+  * a2:   cif->bytes+  * a3:   fig->flags+  * sp+0: ecif.rvalue+  */+CSKY_FUNC_START ffi_call_SYSV+ /* Save registers */+ .cfi_startproc+ subi sp, 28+ .cfi_def_cfa_offset 28+ stw a0, (sp, 0x0)+ .cfi_offset 0, -28+ stw a1, (sp, 0x4)+ .cfi_offset 1, -24+ stw a2, (sp, 0x8)+ .cfi_offset 2, -20+ stw a3, (sp, 0xC)+ .cfi_offset 3, -16+ stw l0, (sp, 0x10)+ .cfi_offset 4, -12+ stw l1, (sp, 0x14)+ .cfi_offset 5, -8+ stw lr, (sp, 0x18)+ .cfi_offset 15, -4++ mov l0, sp+ .cfi_def_cfa_register 4++ /* Make room for all of the new args. */+ subu sp, sp, a2++ /* Place all of the ffi_prep_args in position */+ mov a0, sp+ /*     a1 already set */++ /* Call ffi_prep_args(stack, &ecif) */+ jsri ffi_prep_args++ /* move first 4 parameters in registers */+ ldw a0, (sp, 0x0)+ ldw a1, (sp, 0x4)+ ldw a2, (sp, 0x8)+ ldw a3, (sp, 0xC)++ /* and adjust stack */+ subu lr, l0, sp /* cif->bytes == l0 - sp */+ cmphsi lr, 16+ movi l1, 16+ movt lr, l1+ addu sp, sp, lr++ ldw l1, (l0, 0) /* load fn() in advance */++ /* call (fn) (...) */+ jsr l1++ /* Remove the space we pushed for the args */+ mov sp, l0++ /* Load r2 with the pointer to storage for the return value */+ ldw a2, (sp, 0x1C)++ /* Load r3 with the return type code */+ ldw a3, (sp, 0xC)++ /* If the return value pointer is NULL, assume no return value. */+ cmpnei a2, 0+ bf .Lepilogue++ cmpnei a3, FFI_TYPE_STRUCT+ bf .Lepilogue++ /* return INT64 */+ cmpnei a3, FFI_TYPE_SINT64+ bt .Lretint+ /* stw a0, (a2, 0x0) at .Lretint */+ stw a1, (a2, 0x4)++.Lretint:+ /* return INT */+ stw a0, (a2, 0x0)++.Lepilogue:+ ldw a0, (sp, 0x0)+ ldw a1, (sp, 0x4)+ ldw a2, (sp, 0x8)+ ldw a3, (sp, 0xC)+ ldw l0, (sp, 0x10)+ ldw l1, (sp, 0x14)+ ldw lr, (sp, 0x18)+ addi sp, sp, 28+ rts+ .cfi_endproc+        .size    ffi_call_SYSV, .-ffi_call_SYSV+++ /*+  * unsigned int FFI_HIDDEN+  * ffi_closure_SYSV_inner (closure, respp, args)+  *      ffi_closure *closure;+  *      void **respp;+  *      void *args;+  */+CSKY_FUNC_START ffi_closure_SYSV+ .cfi_startproc+ mov a2, sp+ addi a1, sp, 16+ subi sp, sp, 24+ .cfi_def_cfa_offset 40+ stw a1, (sp, 0x10)+ .cfi_offset 1, -24+ stw lr, (sp, 0x14)+ .cfi_offset 15, -20+ stw sp, (sp, 0x8)+ addi a1, sp, 8+ jsri ffi_closure_SYSV_inner+ ldw a0, (sp, 0x0)+ /*+  * if FFI_TYPE_SINT64, need a1.+  * if FFI_TYPE_INT, ignore a1.+  */+ ldw a1, (sp, 0x4)++ ldw lr, (sp, 0x14)+ addi sp, sp, 40+ rts+ .cfi_endproc+        .size    ffi_closure_SYSV, .-ffi_closure_SYSV++CSKY_FUNC_START ffi_csky_trampoline+ subi sp, sp, 16+ stw a0, (sp, 0x0)+ stw a1, (sp, 0x4)+ stw a2, (sp, 0x8)+ stw a3, (sp, 0xC)+ lrw a0, [.Lctx]+ lrw a1, [.Lfun]+ jmp a1+.Lctx:+ mov a0, a0+ mov a0, a0+.Lfun:++        .size    ffi_csky_trampoline, .-ffi_csky_trampoline++CSKY_FUNC_START ffi_csky_cacheflush+ mov t0, r7+ movi r7, 123+ trap 0+ mov r7, t0+ rts++        .size    ffi_csky_cacheflush, .-ffi_csky_cacheflush++#else /* !__CSKYABIV2__ */++ /*+  * a0:   fn+  * a1:   &ecif+  * a2:   cif->bytes+  * a3:   fig->flags+  * a4:   ecif.rvalue+  */+CSKY_FUNC_START ffi_call_SYSV+ /* Save registers */+ .cfi_startproc+ subi sp, 32+ subi sp, 8+ .cfi_def_cfa_offset 40+ stw a0, (sp, 0x0)+ .cfi_offset 2, -40+ stw a1, (sp, 0x4)+ .cfi_offset 3, -36+ stw a2, (sp, 0x8)+ .cfi_offset 4, -32+ stw a3, (sp, 0xC)+ .cfi_offset 5, -28+ stw a4, (sp, 0x10)+ .cfi_offset 6, -24+ stw a5, (sp, 0x14)+ .cfi_offset 7, -20+ stw l0, (sp, 0x18)+ .cfi_offset 8, -16+ stw l1, (sp, 0x1C)+ .cfi_offset 9, -12+ stw lr, (sp, 0x20)+ .cfi_offset 15, -8++ mov l0, sp+ .cfi_def_cfa_register 8++ /* Make room for all of the new args. */+ subu sp, sp, a2++ /* Place all of the ffi_prep_args in position */+ mov a0, sp+ /*     a1 already set */++ /* Call ffi_prep_args(stack, &ecif) */+ jsri ffi_prep_args++ /* move first 4 parameters in registers */+ ldw a0, (sp, 0x0)+ ldw a1, (sp, 0x4)+ ldw a2, (sp, 0x8)+ ldw a3, (sp, 0xC)+ ldw a4, (sp, 0x10)+ ldw a5, (sp, 0x14)++ /* and adjust stack */+ mov lr, l0+ subu lr, sp  /* cif->bytes == l0 - sp */+ movi l1, 24+ cmphs lr, l1+ movt lr, l1+ addu sp, sp, lr++ ldw l1, (l0, 0) /* load fn() in advance */++ /* call (fn) (...) */+ jsr l1++ /* Remove the space we pushed for the args */+ mov sp, l0++ /* Load r2 with the pointer to storage for the return value */+ ldw a2, (sp, 0x10)++ /* Load r3 with the return type code */+ ldw a3, (sp, 0xC)++ /* If the return value pointer is NULL, assume no return value. */+ cmpnei a2, 0+ bf .Lepilogue++ cmpnei a3, FFI_TYPE_STRUCT+ bf .Lepilogue++ /* return INT64 */+ cmpnei a3, FFI_TYPE_SINT64+ bt .Lretint+ /* stw a0, (a2, 0x0) at .Lretint */+ stw a1, (a2, 0x4)++.Lretint:+ /* return INT */+ stw a0, (a2, 0x0)++.Lepilogue:+ ldw a0, (sp, 0x0)+ ldw a1, (sp, 0x4)+ ldw a2, (sp, 0x8)+ ldw a3, (sp, 0xC)+ ldw a4, (sp, 0x10)+ ldw a5, (sp, 0x14)+ ldw l0, (sp, 0x18)+ ldw l1, (sp, 0x1C)+ ldw lr, (sp, 0x20)+ addi sp, sp, 32+ addi sp, sp, 8+ rts+ .cfi_endproc++        .size    ffi_call_SYSV, .-ffi_call_SYSV+++ /*+  * unsigned int FFI_HIDDEN+  * ffi_closure_SYSV_inner (closure, respp, args)+  *      ffi_closure *closure;+  *      void **respp;+  *      void *args;+  */+CSKY_FUNC_START ffi_closure_SYSV+ .cfi_startproc+ mov a2, sp+ mov a1, sp+ addi a1, 24+ subi sp, sp, 24+ .cfi_def_cfa_offset 48+ stw a1, (sp, 0x10)+ .cfi_offset 3, -32+ stw lr, (sp, 0x14)+ .cfi_offset 15, -28+ stw sp, (sp, 0x8)+ mov a1, sp+ addi a1, 8+ jsri ffi_closure_SYSV_inner+ ldw a0, (sp, 0x0)+ /*+  * if FFI_TYPE_SINT64, need a1.+  * if FFI_TYPE_INT, ignore a1.+  */+ ldw a1, (sp, 0x4)++ ldw lr, (sp, 0x14)+ addi sp, sp, 24+ addi sp, sp, 24+ rts+ .cfi_endproc++        .size    ffi_closure_SYSV, .-ffi_closure_SYSV++CSKY_FUNC_START ffi_csky_trampoline+ subi sp, 24+ stw a0, (sp, 0x0)+ stw a1, (sp, 0x4)+ stw a2, (sp, 0x8)+ stw a3, (sp, 0xC)+ stw a4, (sp, 0x10)+ stw a5, (sp, 0x14)+ lrw a0, [.Lctx]+ lrw a1, [.Lfun]+ jmp a1+.Lctx:+ mov a0, a0+ mov a0, a0+.Lfun:++        .size    ffi_csky_trampoline, .-ffi_csky_trampoline++CSKY_FUNC_START ffi_csky_cacheflush+ lrw r1, 123+ trap 0+ rts++        .size    ffi_csky_cacheflush, .-ffi_csky_cacheflush++#endif /* __CSKYABIV2__ */
+ src/debug.c view
@@ -0,0 +1,64 @@+/* -----------------------------------------------------------------------+   debug.c - Copyright (c) 1996 Red Hat, Inc.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>+#include <stdio.h>++/* General debugging routines */++void ffi_stop_here(void)+{+  /* This function is only useful for debugging purposes.+     Place a breakpoint on ffi_stop_here to be notified of+     significant events. */+}++/* This function should only be called via the FFI_ASSERT() macro */++NORETURN void ffi_assert(const char *expr, const char *file, int line)+{+  fprintf(stderr, "ASSERTION FAILURE: %s at %s:%d\n", expr, file, line);+  ffi_stop_here();+  abort();+}++/* Perform a sanity check on an ffi_type structure */++void ffi_type_test(ffi_type *a, const char *file, int line)+{+  FFI_ASSERT_AT(a != NULL, file, line);++  FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);+  FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);+  FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);+  FFI_ASSERT_AT((a->type != FFI_TYPE_STRUCT && a->type != FFI_TYPE_COMPLEX)+		|| a->elements != NULL, file, line);+  FFI_ASSERT_AT(a->type != FFI_TYPE_COMPLEX+		|| (a->elements != NULL+		    && a->elements[0] != NULL && a->elements[1] == NULL),+		file, line);++}
+ src/dlmalloc.c view
@@ -0,0 +1,5172 @@+/*+  This is a version (aka dlmalloc) of malloc/free/realloc written by+  Doug Lea and released to the public domain, as explained at+  http://creativecommons.org/licenses/publicdomain.  Send questions,+  comments, complaints, performance data, etc to dl@cs.oswego.edu++* Version 2.8.3 Thu Sep 22 11:16:15 2005  Doug Lea  (dl at gee)++   Note: There may be an updated version of this malloc obtainable at+           ftp://gee.cs.oswego.edu/pub/misc/malloc.c+         Check before installing!++* Quickstart++  This library is all in one file to simplify the most common usage:+  ftp it, compile it (-O3), and link it into another program. All of+  the compile-time options default to reasonable values for use on+  most platforms.  You might later want to step through various+  compile-time and dynamic tuning options.++  For convenience, an include file for code using this malloc is at:+     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h+  You don't really need this .h file unless you call functions not+  defined in your system include files.  The .h file contains only the+  excerpts from this file needed for using this malloc on ANSI C/C+++  systems, so long as you haven't changed compile-time options about+  naming and tuning parameters.  If you do, then you can create your+  own malloc.h that does include all settings by cutting at the point+  indicated below. Note that you may already by default be using a C+  library containing a malloc that is based on some version of this+  malloc (for example in linux). You might still want to use the one+  in this file to customize settings or to avoid overheads associated+  with library versions.++* Vital statistics:++  Supported pointer/size_t representation:       4 or 8 bytes+       size_t MUST be an unsigned type of the same width as+       pointers. (If you are using an ancient system that declares+       size_t as a signed type, or need it to be a different width+       than pointers, you can use a previous release of this malloc+       (e.g. 2.7.2) supporting these.)++  Alignment:                                     8 bytes (default)+       This suffices for nearly all current machines and C compilers.+       However, you can define MALLOC_ALIGNMENT to be wider than this+       if necessary (up to 128bytes), at the expense of using more space.++  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)+                                          8 or 16 bytes (if 8byte sizes)+       Each malloced chunk has a hidden word of overhead holding size+       and status information, and additional cross-check word+       if FOOTERS is defined.++  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)+                          8-byte ptrs:  32 bytes    (including overhead)++       Even a request for zero bytes (i.e., malloc(0)) returns a+       pointer to something of the minimum allocatable size.+       The maximum overhead wastage (i.e., number of extra bytes+       allocated than were requested in malloc) is less than or equal+       to the minimum size, except for requests >= mmap_threshold that+       are serviced via mmap(), where the worst case wastage is about+       32 bytes plus the remainder from a system page (the minimal+       mmap unit); typically 4096 or 8192 bytes.++  Security: static-safe; optionally more or less+       The "security" of malloc refers to the ability of malicious+       code to accentuate the effects of errors (for example, freeing+       space that is not currently malloc'ed or overwriting past the+       ends of chunks) in code that calls malloc.  This malloc+       guarantees not to modify any memory locations below the base of+       heap, i.e., static variables, even in the presence of usage+       errors.  The routines additionally detect most improper frees+       and reallocs.  All this holds as long as the static bookkeeping+       for malloc itself is not corrupted by some other means.  This+       is only one aspect of security -- these checks do not, and+       cannot, detect all possible programming errors.++       If FOOTERS is defined nonzero, then each allocated chunk+       carries an additional check word to verify that it was malloced+       from its space.  These check words are the same within each+       execution of a program using malloc, but differ across+       executions, so externally crafted fake chunks cannot be+       freed. This improves security by rejecting frees/reallocs that+       could corrupt heap memory, in addition to the checks preventing+       writes to statics that are always on.  This may further improve+       security at the expense of time and space overhead.  (Note that+       FOOTERS may also be worth using with MSPACES.)++       By default detected errors cause the program to abort (calling+       "abort()"). You can override this to instead proceed past+       errors by defining PROCEED_ON_ERROR.  In this case, a bad free+       has no effect, and a malloc that encounters a bad address+       caused by user overwrites will ignore the bad address by+       dropping pointers and indices to all known memory. This may+       be appropriate for programs that should continue if at all+       possible in the face of programming errors, although they may+       run out of memory because dropped memory is never reclaimed.++       If you don't like either of these options, you can define+       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything+       else. And if if you are sure that your program using malloc has+       no errors or vulnerabilities, you can define INSECURE to 1,+       which might (or might not) provide a small performance improvement.++  Thread-safety: NOT thread-safe unless USE_LOCKS defined+       When USE_LOCKS is defined, each public call to malloc, free,+       etc is surrounded with either a pthread mutex or a win32+       spinlock (depending on WIN32). This is not especially fast, and+       can be a major bottleneck.  It is designed only to provide+       minimal protection in concurrent environments, and to provide a+       basis for extensions.  If you are using malloc in a concurrent+       program, consider instead using ptmalloc, which is derived from+       a version of this malloc. (See http://www.malloc.de).++  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP+       This malloc can use unix sbrk or any emulation (invoked using+       the CALL_MORECORE macro) and/or mmap/munmap or any emulation+       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system+       memory.  On most unix systems, it tends to work best if both+       MORECORE and MMAP are enabled.  On Win32, it uses emulations+       based on VirtualAlloc. It also uses common C library functions+       like memset.++  Compliance: I believe it is compliant with the Single Unix Specification+       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably+       others as well.++* Overview of algorithms++  This is not the fastest, most space-conserving, most portable, or+  most tunable malloc ever written. However it is among the fastest+  while also being among the most space-conserving, portable and+  tunable.  Consistent balance across these factors results in a good+  general-purpose allocator for malloc-intensive programs.++  In most ways, this malloc is a best-fit allocator. Generally, it+  chooses the best-fitting existing chunk for a request, with ties+  broken in approximately least-recently-used order. (This strategy+  normally maintains low fragmentation.) However, for requests less+  than 256bytes, it deviates from best-fit when there is not an+  exactly fitting available chunk by preferring to use space adjacent+  to that used for the previous small request, as well as by breaking+  ties in approximately most-recently-used order. (These enhance+  locality of series of small allocations.)  And for very large requests+  (>= 256Kb by default), it relies on system memory mapping+  facilities, if supported.  (This helps avoid carrying around and+  possibly fragmenting memory used only for large chunks.)++  All operations (except malloc_stats and mallinfo) have execution+  times that are bounded by a constant factor of the number of bits in+  a size_t, not counting any clearing in calloc or copying in realloc,+  or actions surrounding MORECORE and MMAP that have times+  proportional to the number of non-contiguous regions returned by+  system allocation routines, which is often just 1.++  The implementation is not very modular and seriously overuses+  macros. Perhaps someday all C compilers will do as good a job+  inlining modular code as can now be done by brute-force expansion,+  but now, enough of them seem not to.++  Some compilers issue a lot of warnings about code that is+  dead/unreachable only on some platforms, and also about intentional+  uses of negation on unsigned types. All known cases of each can be+  ignored.++  For a longer but out of date high-level description, see+     http://gee.cs.oswego.edu/dl/html/malloc.html++* MSPACES+  If MSPACES is defined, then in addition to malloc, free, etc.,+  this file also defines mspace_malloc, mspace_free, etc. These+  are versions of malloc routines that take an "mspace" argument+  obtained using create_mspace, to control all internal bookkeeping.+  If ONLY_MSPACES is defined, only these versions are compiled.+  So if you would like to use this allocator for only some allocations,+  and your system malloc for others, you can compile with+  ONLY_MSPACES and then do something like...+    static mspace mymspace = create_mspace(0,0); // for example+    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)++  (Note: If you only need one instance of an mspace, you can instead+  use "USE_DL_PREFIX" to relabel the global malloc.)++  You can similarly create thread-local allocators by storing+  mspaces as thread-locals. For example:+    static __thread mspace tlms = 0;+    void*  tlmalloc(size_t bytes) {+      if (tlms == 0) tlms = create_mspace(0, 0);+      return mspace_malloc(tlms, bytes);+    }+    void  tlfree(void* mem) { mspace_free(tlms, mem); }++  Unless FOOTERS is defined, each mspace is completely independent.+  You cannot allocate from one and free to another (although+  conformance is only weakly checked, so usage errors are not always+  caught). If FOOTERS is defined, then each chunk carries around a tag+  indicating its originating mspace, and frees are directed to their+  originating spaces.++ -------------------------  Compile-time options ---------------------------++Be careful in setting #define values for numerical constants of type+size_t. On some systems, literal values are not automatically extended+to size_t precision unless they are explicitly casted.++WIN32                    default: defined if _WIN32 defined+  Defining WIN32 sets up defaults for MS environment and compilers.+  Otherwise defaults are for unix.++MALLOC_ALIGNMENT         default: (size_t)8+  Controls the minimum alignment for malloc'ed chunks.  It must be a+  power of two and at least 8, even on machines for which smaller+  alignments would suffice. It may be defined as larger than this+  though. Note however that code and data structures are optimized for+  the case of 8-byte alignment.++MSPACES                  default: 0 (false)+  If true, compile in support for independent allocation spaces.+  This is only supported if HAVE_MMAP is true.++ONLY_MSPACES             default: 0 (false)+  If true, only compile in mspace versions, not regular versions.++USE_LOCKS                default: 0 (false)+  Causes each call to each public routine to be surrounded with+  pthread or WIN32 mutex lock/unlock. (If set true, this can be+  overridden on a per-mspace basis for mspace versions.)++FOOTERS                  default: 0+  If true, provide extra checking and dispatching by placing+  information in the footers of allocated chunks. This adds+  space and time overhead.++INSECURE                 default: 0+  If true, omit checks for usage errors and heap space overwrites.++USE_DL_PREFIX            default: NOT defined+  Causes compiler to prefix all public routines with the string 'dl'.+  This can be useful when you only want to use this malloc in one part+  of a program, using your regular system malloc elsewhere.++ABORT                    default: defined as abort()+  Defines how to abort on failed checks.  On most systems, a failed+  check cannot die with an "assert" or even print an informative+  message, because the underlying print routines in turn call malloc,+  which will fail again.  Generally, the best policy is to simply call+  abort(). It's not very useful to do more than this because many+  errors due to overwriting will show up as address faults (null, odd+  addresses etc) rather than malloc-triggered checks, so will also+  abort.  Also, most compilers know that abort() does not return, so+  can better optimize code conditionally calling it.++PROCEED_ON_ERROR           default: defined as 0 (false)+  Controls whether detected bad addresses cause them to bypassed+  rather than aborting. If set, detected bad arguments to free and+  realloc are ignored. And all bookkeeping information is zeroed out+  upon a detected overwrite of freed heap space, thus losing the+  ability to ever return it from malloc again, but enabling the+  application to proceed. If PROCEED_ON_ERROR is defined, the+  static variable malloc_corruption_error_count is compiled in+  and can be examined to see if errors have occurred. This option+  generates slower code than the default abort policy.++DEBUG                    default: NOT defined+  The DEBUG setting is mainly intended for people trying to modify+  this code or diagnose problems when porting to new platforms.+  However, it may also be able to better isolate user errors than just+  using runtime checks.  The assertions in the check routines spell+  out in more detail the assumptions and invariants underlying the+  algorithms.  The checking is fairly extensive, and will slow down+  execution noticeably. Calling malloc_stats or mallinfo with DEBUG+  set will attempt to check every non-mmapped allocated and free chunk+  in the course of computing the summaries.++ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)+  Debugging assertion failures can be nearly impossible if your+  version of the assert macro causes malloc to be called, which will+  lead to a cascade of further failures, blowing the runtime stack.+  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),+  which will usually make debugging easier.++MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32+  The action to take before "return 0" when malloc fails to be able to+  return memory because there is none available.++HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES+  True if this system supports sbrk or an emulation of it.++MORECORE                  default: sbrk+  The name of the sbrk-style system routine to call to obtain more+  memory.  See below for guidance on writing custom MORECORE+  functions. The type of the argument to sbrk/MORECORE varies across+  systems.  It cannot be size_t, because it supports negative+  arguments, so it is normally the signed type of the same width as+  size_t (sometimes declared as "intptr_t").  It doesn't much matter+  though. Internally, we only call it with arguments less than half+  the max value of a size_t, which should work across all reasonable+  possibilities, although sometimes generating compiler warnings.  See+  near the end of this file for guidelines for creating a custom+  version of MORECORE.++MORECORE_CONTIGUOUS       default: 1 (true)+  If true, take advantage of fact that consecutive calls to MORECORE+  with positive arguments always return contiguous increasing+  addresses.  This is true of unix sbrk. It does not hurt too much to+  set it true anyway, since malloc copes with non-contiguities.+  Setting it false when definitely non-contiguous saves time+  and possibly wasted space it would take to discover this though.++MORECORE_CANNOT_TRIM      default: NOT defined+  True if MORECORE cannot release space back to the system when given+  negative arguments. This is generally necessary only if you are+  using a hand-crafted MORECORE function that cannot handle negative+  arguments.++HAVE_MMAP                 default: 1 (true)+  True if this system supports mmap or an emulation of it.  If so, and+  HAVE_MORECORE is not true, MMAP is used for all system+  allocation. If set and HAVE_MORECORE is true as well, MMAP is+  primarily used to directly allocate very large blocks. It is also+  used as a backup strategy in cases where MORECORE fails to provide+  space from system. Note: A single call to MUNMAP is assumed to be+  able to unmap memory that may have be allocated using multiple calls+  to MMAP, so long as they are adjacent.++HAVE_MREMAP               default: 1 on linux, else 0+  If true realloc() uses mremap() to re-allocate large blocks and+  extend or shrink allocation spaces.++MMAP_CLEARS               default: 1 on unix+  True if mmap clears memory so calloc doesn't need to. This is true+  for standard unix mmap using /dev/zero.++USE_BUILTIN_FFS            default: 0 (i.e., not used)+  Causes malloc to use the builtin ffs() function to compute indices.+  Some compilers may recognize and intrinsify ffs to be faster than the+  supplied C version. Also, the case of x86 using gcc is special-cased+  to an asm instruction, so is already as fast as it can be, and so+  this setting has no effect. (On most x86s, the asm version is only+  slightly faster than the C version.)++malloc_getpagesize         default: derive from system includes, or 4096.+  The system page size. To the extent possible, this malloc manages+  memory from the system in page-size units.  This may be (and+  usually is) a function rather than a constant. This is ignored+  if WIN32, where page size is determined using getSystemInfo during+  initialization.++USE_DEV_RANDOM             default: 0 (i.e., not used)+  Causes malloc to use /dev/random to initialize secure magic seed for+  stamping footers. Otherwise, the current time is used.++NO_MALLINFO                default: 0+  If defined, don't compile "mallinfo". This can be a simple way+  of dealing with mismatches between system declarations and+  those in this file.++MALLINFO_FIELD_TYPE        default: size_t+  The type of the fields in the mallinfo struct. This was originally+  defined as "int" in SVID etc, but is more usefully defined as+  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set++REALLOC_ZERO_BYTES_FREES    default: not defined+  This should be set if a call to realloc with zero bytes should +  be the same as a call to free. Some people think it should. Otherwise, +  since this malloc returns a unique pointer for malloc(0), so does +  realloc(p, 0).++LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H+LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H+LACKS_STDLIB_H                default: NOT defined unless on WIN32+  Define these if your system does not have these header files.+  You might need to manually insert some of the declarations they provide.++DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,+                                system_info.dwAllocationGranularity in WIN32,+                                otherwise 64K.+      Also settable using mallopt(M_GRANULARITY, x)+  The unit for allocating and deallocating memory from the system.  On+  most systems with contiguous MORECORE, there is no reason to+  make this more than a page. However, systems with MMAP tend to+  either require or encourage larger granularities.  You can increase+  this value to prevent system allocation functions to be called so+  often, especially if they are slow.  The value must be at least one+  page and must be a power of two.  Setting to 0 causes initialization+  to either page size or win32 region size.  (Note: In previous+  versions of malloc, the equivalent of this option was called+  "TOP_PAD")++DEFAULT_TRIM_THRESHOLD    default: 2MB+      Also settable using mallopt(M_TRIM_THRESHOLD, x)+  The maximum amount of unused top-most memory to keep before+  releasing via malloc_trim in free().  Automatic trimming is mainly+  useful in long-lived programs using contiguous MORECORE.  Because+  trimming via sbrk can be slow on some systems, and can sometimes be+  wasteful (in cases where programs immediately afterward allocate+  more large chunks) the value should be high enough so that your+  overall system performance would improve by releasing this much+  memory.  As a rough guide, you might set to a value close to the+  average size of a process (program) running on your system.+  Releasing this much memory would allow such a process to run in+  memory.  Generally, it is worth tuning trim thresholds when a+  program undergoes phases where several large chunks are allocated+  and released in ways that can reuse each other's storage, perhaps+  mixed with phases where there are no such chunks at all. The trim+  value must be greater than page size to have any useful effect.  To+  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick+  some people use of mallocing a huge space and then freeing it at+  program startup, in an attempt to reserve system memory, doesn't+  have the intended effect under automatic trimming, since that memory+  will immediately be returned to the system.++DEFAULT_MMAP_THRESHOLD       default: 256K+      Also settable using mallopt(M_MMAP_THRESHOLD, x)+  The request size threshold for using MMAP to directly service a+  request. Requests of at least this size that cannot be allocated+  using already-existing space will be serviced via mmap.  (If enough+  normal freed space already exists it is used instead.)  Using mmap+  segregates relatively large chunks of memory so that they can be+  individually obtained and released from the host system. A request+  serviced through mmap is never reused by any other request (at least+  not directly; the system may just so happen to remap successive+  requests to the same locations).  Segregating space in this way has+  the benefits that: Mmapped space can always be individually released+  back to the system, which helps keep the system level memory demands+  of a long-lived program low.  Also, mapped memory doesn't become+  `locked' between other chunks, as can happen with normally allocated+  chunks, which means that even trimming via malloc_trim would not+  release them.  However, it has the disadvantage that the space+  cannot be reclaimed, consolidated, and then used to service later+  requests, as happens with normal chunks.  The advantages of mmap+  nearly always outweigh disadvantages for "large" chunks, but the+  value of "large" may vary across systems.  The default is an+  empirically derived value that works well in most systems. You can+  disable mmap by setting to MAX_SIZE_T.++*/++#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+#endif  /* _WIN32 */+#endif  /* WIN32 */+#ifdef WIN32+#define WIN32_LEAN_AND_MEAN+#include <windows.h>+#define HAVE_MMAP 1+#define HAVE_MORECORE 0+#define LACKS_UNISTD_H+#define LACKS_SYS_PARAM_H+#define LACKS_SYS_MMAN_H+#define LACKS_STRING_H+#define LACKS_STRINGS_H+#define LACKS_SYS_TYPES_H+#define LACKS_ERRNO_H+#define MALLOC_FAILURE_ACTION+#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */+#endif  /* WIN32 */++#ifdef __OS2__+#define INCL_DOS+#include <os2.h>+#define HAVE_MMAP 1+#define HAVE_MORECORE 0+#define LACKS_SYS_MMAN_H+#endif  /* __OS2__ */++#if defined(DARWIN) || defined(_DARWIN)+/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */+#ifndef HAVE_MORECORE+#define HAVE_MORECORE 0+#define HAVE_MMAP 1+#endif  /* HAVE_MORECORE */+#endif  /* DARWIN */++#ifndef LACKS_SYS_TYPES_H+#include <sys/types.h>  /* For size_t */+#endif  /* LACKS_SYS_TYPES_H */++/* The maximum possible size_t value has all bits set */+#define MAX_SIZE_T           (~(size_t)0)++#ifndef ONLY_MSPACES+#define ONLY_MSPACES 0+#endif  /* ONLY_MSPACES */+#ifndef MSPACES+#if ONLY_MSPACES+#define MSPACES 1+#else   /* ONLY_MSPACES */+#define MSPACES 0+#endif  /* ONLY_MSPACES */+#endif  /* MSPACES */+#ifndef MALLOC_ALIGNMENT+#define MALLOC_ALIGNMENT ((size_t)8U)+#endif  /* MALLOC_ALIGNMENT */+#ifndef FOOTERS+#define FOOTERS 0+#endif  /* FOOTERS */+#ifndef ABORT+#define ABORT  abort()+#endif  /* ABORT */+#ifndef ABORT_ON_ASSERT_FAILURE+#define ABORT_ON_ASSERT_FAILURE 1+#endif  /* ABORT_ON_ASSERT_FAILURE */+#ifndef PROCEED_ON_ERROR+#define PROCEED_ON_ERROR 0+#endif  /* PROCEED_ON_ERROR */+#ifndef USE_LOCKS+#define USE_LOCKS 0+#endif  /* USE_LOCKS */+#ifndef INSECURE+#define INSECURE 0+#endif  /* INSECURE */+#ifndef HAVE_MMAP+#define HAVE_MMAP 1+#endif  /* HAVE_MMAP */+#ifndef MMAP_CLEARS+#define MMAP_CLEARS 1+#endif  /* MMAP_CLEARS */+#ifndef HAVE_MREMAP+#ifdef linux+#define HAVE_MREMAP 1+#else   /* linux */+#define HAVE_MREMAP 0+#endif  /* linux */+#endif  /* HAVE_MREMAP */+#ifndef MALLOC_FAILURE_ACTION+#define MALLOC_FAILURE_ACTION  errno = ENOMEM;+#endif  /* MALLOC_FAILURE_ACTION */+#ifndef HAVE_MORECORE+#if ONLY_MSPACES+#define HAVE_MORECORE 0+#else   /* ONLY_MSPACES */+#define HAVE_MORECORE 1+#endif  /* ONLY_MSPACES */+#endif  /* HAVE_MORECORE */+#if !HAVE_MORECORE+#define MORECORE_CONTIGUOUS 0+#else   /* !HAVE_MORECORE */+#ifndef MORECORE+#define MORECORE sbrk+#endif  /* MORECORE */+#ifndef MORECORE_CONTIGUOUS+#define MORECORE_CONTIGUOUS 1+#endif  /* MORECORE_CONTIGUOUS */+#endif  /* HAVE_MORECORE */+#ifndef DEFAULT_GRANULARITY+#if MORECORE_CONTIGUOUS+#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */+#else   /* MORECORE_CONTIGUOUS */+#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)+#endif  /* MORECORE_CONTIGUOUS */+#endif  /* DEFAULT_GRANULARITY */+#ifndef DEFAULT_TRIM_THRESHOLD+#ifndef MORECORE_CANNOT_TRIM+#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)+#else   /* MORECORE_CANNOT_TRIM */+#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T+#endif  /* MORECORE_CANNOT_TRIM */+#endif  /* DEFAULT_TRIM_THRESHOLD */+#ifndef DEFAULT_MMAP_THRESHOLD+#if HAVE_MMAP+#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)+#else   /* HAVE_MMAP */+#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T+#endif  /* HAVE_MMAP */+#endif  /* DEFAULT_MMAP_THRESHOLD */+#ifndef USE_BUILTIN_FFS+#define USE_BUILTIN_FFS 0+#endif  /* USE_BUILTIN_FFS */+#ifndef USE_DEV_RANDOM+#define USE_DEV_RANDOM 0+#endif  /* USE_DEV_RANDOM */+#ifndef NO_MALLINFO+#define NO_MALLINFO 0+#endif  /* NO_MALLINFO */+#ifndef MALLINFO_FIELD_TYPE+#define MALLINFO_FIELD_TYPE size_t+#endif  /* MALLINFO_FIELD_TYPE */++/*+  mallopt tuning options.  SVID/XPG defines four standard parameter+  numbers for mallopt, normally defined in malloc.h.  None of these+  are used in this malloc, so setting them has no effect. But this+  malloc does support the following options.+*/++/* The system's malloc.h may have conflicting defines. */+#undef M_TRIM_THRESHOLD+#undef M_GRANULARITY+#undef M_MMAP_THRESHOLD++#define M_TRIM_THRESHOLD     (-1)+#define M_GRANULARITY        (-2)+#define M_MMAP_THRESHOLD     (-3)++/* ------------------------ Mallinfo declarations ------------------------ */++#if !NO_MALLINFO+/*+  This version of malloc supports the standard SVID/XPG mallinfo+  routine that returns a struct containing usage properties and+  statistics. It should work on any system that has a+  /usr/include/malloc.h defining struct mallinfo.  The main+  declaration needed is the mallinfo struct that is returned (by-copy)+  by mallinfo().  The malloinfo struct contains a bunch of fields that+  are not even meaningful in this version of malloc.  These fields are+  are instead filled by mallinfo() with other numbers that might be of+  interest.++  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a+  /usr/include/malloc.h file that includes a declaration of struct+  mallinfo.  If so, it is included; else a compliant version is+  declared below.  These must be precisely the same for mallinfo() to+  work.  The original SVID version of this struct, defined on most+  systems with mallinfo, declares all fields as ints. But some others+  define as unsigned long. If your system defines the fields using a+  type of different width than listed here, you MUST #include your+  system version and #define HAVE_USR_INCLUDE_MALLOC_H.+*/++/* #define HAVE_USR_INCLUDE_MALLOC_H */++#ifdef HAVE_USR_INCLUDE_MALLOC_H+#include "/usr/include/malloc.h"+#else /* HAVE_USR_INCLUDE_MALLOC_H */++/* HP-UX's stdlib.h redefines mallinfo unless _STRUCT_MALLINFO is defined */+#define _STRUCT_MALLINFO++struct mallinfo {+  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */+  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */+  MALLINFO_FIELD_TYPE smblks;   /* always 0 */+  MALLINFO_FIELD_TYPE hblks;    /* always 0 */+  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */+  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */+  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */+  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */+  MALLINFO_FIELD_TYPE fordblks; /* total free space */+  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */+};++#endif /* HAVE_USR_INCLUDE_MALLOC_H */+#endif /* NO_MALLINFO */++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++#if !ONLY_MSPACES++/* ------------------- Declarations of public routines ------------------- */++#ifndef USE_DL_PREFIX+#define dlcalloc               calloc+#define dlfree                 free+#define dlmalloc               malloc+#define dlmemalign             memalign+#define dlrealloc              realloc+#define dlvalloc               valloc+#define dlpvalloc              pvalloc+#define dlmallinfo             mallinfo+#define dlmallopt              mallopt+#define dlmalloc_trim          malloc_trim+#define dlmalloc_stats         malloc_stats+#define dlmalloc_usable_size   malloc_usable_size+#define dlmalloc_footprint     malloc_footprint+#define dlmalloc_max_footprint malloc_max_footprint+#define dlindependent_calloc   independent_calloc+#define dlindependent_comalloc independent_comalloc+#endif /* USE_DL_PREFIX */+++/*+  malloc(size_t n)+  Returns a pointer to a newly allocated chunk of at least n bytes, or+  null if no space is available, in which case errno is set to ENOMEM+  on ANSI C systems.++  If n is zero, malloc returns a minimum-sized chunk. (The minimum+  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit+  systems.)  Note that size_t is an unsigned type, so calls with+  arguments that would be negative if signed are interpreted as+  requests for huge amounts of space, which will often fail. The+  maximum supported value of n differs across systems, but is in all+  cases less than the maximum representable value of a size_t.+*/+void* dlmalloc(size_t);++/*+  free(void* p)+  Releases the chunk of memory pointed to by p, that had been previously+  allocated using malloc or a related routine such as realloc.+  It has no effect if p is null. If p was not malloced or already+  freed, free(p) will by default cause the current program to abort.+*/+void  dlfree(void*);++/*+  calloc(size_t n_elements, size_t element_size);+  Returns a pointer to n_elements * element_size bytes, with all locations+  set to zero.+*/+void* dlcalloc(size_t, size_t);++/*+  realloc(void* p, size_t n)+  Returns a pointer to a chunk of size n that contains the same data+  as does chunk p up to the minimum of (n, p's size) bytes, or null+  if no space is available.++  The returned pointer may or may not be the same as p. The algorithm+  prefers extending p in most cases when possible, otherwise it+  employs the equivalent of a malloc-copy-free sequence.++  If p is null, realloc is equivalent to malloc.++  If space is not available, realloc returns null, errno is set (if on+  ANSI) and p is NOT freed.++  if n is for fewer bytes than already held by p, the newly unused+  space is lopped off and freed if possible.  realloc with a size+  argument of zero (re)allocates a minimum-sized chunk.++  The old unix realloc convention of allowing the last-free'd chunk+  to be used as an argument to realloc is not supported.+*/++void* dlrealloc(void*, size_t);++/*+  memalign(size_t alignment, size_t n);+  Returns a pointer to a newly allocated chunk of n bytes, aligned+  in accord with the alignment argument.++  The alignment argument should be a power of two. If the argument is+  not a power of two, the nearest greater power is used.+  8-byte alignment is guaranteed by normal malloc calls, so don't+  bother calling memalign with an argument of 8 or less.++  Overreliance on memalign is a sure way to fragment space.+*/+void* dlmemalign(size_t, size_t);++/*+  valloc(size_t n);+  Equivalent to memalign(pagesize, n), where pagesize is the page+  size of the system. If the pagesize is unknown, 4096 is used.+*/+void* dlvalloc(size_t);++/*+  mallopt(int parameter_number, int parameter_value)+  Sets tunable parameters The format is to provide a+  (parameter-number, parameter-value) pair.  mallopt then sets the+  corresponding parameter to the argument value if it can (i.e., so+  long as the value is meaningful), and returns 1 if successful else+  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,+  normally defined in malloc.h.  None of these are use in this malloc,+  so setting them has no effect. But this malloc also supports other+  options in mallopt. See below for details.  Briefly, supported+  parameters are as follows (listed defaults are for "typical"+  configurations).++  Symbol            param #  default    allowed param values+  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (MAX_SIZE_T disables)+  M_GRANULARITY        -2     page size   any power of 2 >= page size+  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)+*/+int dlmallopt(int, int);++/*+  malloc_footprint();+  Returns the number of bytes obtained from the system.  The total+  number of bytes allocated by malloc, realloc etc., is less than this+  value. Unlike mallinfo, this function returns only a precomputed+  result, so can be called frequently to monitor memory consumption.+  Even if locks are otherwise defined, this function does not use them,+  so results might not be up to date.+*/+size_t dlmalloc_footprint(void);++/*+  malloc_max_footprint();+  Returns the maximum number of bytes obtained from the system. This+  value will be greater than current footprint if deallocated space+  has been reclaimed by the system. The peak number of bytes allocated+  by malloc, realloc etc., is less than this value. Unlike mallinfo,+  this function returns only a precomputed result, so can be called+  frequently to monitor memory consumption.  Even if locks are+  otherwise defined, this function does not use them, so results might+  not be up to date.+*/+size_t dlmalloc_max_footprint(void);++#if !NO_MALLINFO+/*+  mallinfo()+  Returns (by copy) a struct containing various summary statistics:++  arena:     current total non-mmapped bytes allocated from system+  ordblks:   the number of free chunks+  smblks:    always zero.+  hblks:     current number of mmapped regions+  hblkhd:    total bytes held in mmapped regions+  usmblks:   the maximum total allocated space. This will be greater+                than current total if trimming has occurred.+  fsmblks:   always zero+  uordblks:  current total allocated space (normal or mmapped)+  fordblks:  total free space+  keepcost:  the maximum number of bytes that could ideally be released+               back to system via malloc_trim. ("ideally" means that+               it ignores page restrictions etc.)++  Because these fields are ints, but internal bookkeeping may+  be kept as longs, the reported values may wrap around zero and+  thus be inaccurate.+*/+struct mallinfo dlmallinfo(void);+#endif /* NO_MALLINFO */++/*+  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);++  independent_calloc is similar to calloc, but instead of returning a+  single cleared space, it returns an array of pointers to n_elements+  independent elements that can hold contents of size elem_size, each+  of which starts out cleared, and can be independently freed,+  realloc'ed etc. The elements are guaranteed to be adjacently+  allocated (this is not guaranteed to occur with multiple callocs or+  mallocs), which may also improve cache locality in some+  applications.++  The "chunks" argument is optional (i.e., may be null, which is+  probably the most typical usage). If it is null, the returned array+  is itself dynamically allocated and should also be freed when it is+  no longer needed. Otherwise, the chunks array must be of at least+  n_elements in length. It is filled in with the pointers to the+  chunks.++  In either case, independent_calloc returns this pointer array, or+  null if the allocation failed.  If n_elements is zero and "chunks"+  is null, it returns a chunk representing an array with zero elements+  (which should be freed if not wanted).++  Each element must be individually freed when it is no longer+  needed. If you'd like to instead be able to free all at once, you+  should instead use regular calloc and assign pointers into this+  space to represent elements.  (In this case though, you cannot+  independently free elements.)++  independent_calloc simplifies and speeds up implementations of many+  kinds of pools.  It may also be useful when constructing large data+  structures that initially have a fixed number of fixed-sized nodes,+  but the number is not known at compile time, and some of the nodes+  may later need to be freed. For example:++  struct Node { int item; struct Node* next; };++  struct Node* build_list() {+    struct Node** pool;+    int n = read_number_of_nodes_needed();+    if (n <= 0) return 0;+    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);+    if (pool == 0) die();+    // organize into a linked list...+    struct Node* first = pool[0];+    for (i = 0; i < n-1; ++i)+      pool[i]->next = pool[i+1];+    free(pool);     // Can now free the array (or not, if it is needed later)+    return first;+  }+*/+void** dlindependent_calloc(size_t, size_t, void**);++/*+  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);++  independent_comalloc allocates, all at once, a set of n_elements+  chunks with sizes indicated in the "sizes" array.    It returns+  an array of pointers to these elements, each of which can be+  independently freed, realloc'ed etc. The elements are guaranteed to+  be adjacently allocated (this is not guaranteed to occur with+  multiple callocs or mallocs), which may also improve cache locality+  in some applications.++  The "chunks" argument is optional (i.e., may be null). If it is null+  the returned array is itself dynamically allocated and should also+  be freed when it is no longer needed. Otherwise, the chunks array+  must be of at least n_elements in length. It is filled in with the+  pointers to the chunks.++  In either case, independent_comalloc returns this pointer array, or+  null if the allocation failed.  If n_elements is zero and chunks is+  null, it returns a chunk representing an array with zero elements+  (which should be freed if not wanted).++  Each element must be individually freed when it is no longer+  needed. If you'd like to instead be able to free all at once, you+  should instead use a single regular malloc, and assign pointers at+  particular offsets in the aggregate space. (In this case though, you+  cannot independently free elements.)++  independent_comallac differs from independent_calloc in that each+  element may have a different size, and also that it does not+  automatically clear elements.++  independent_comalloc can be used to speed up allocation in cases+  where several structs or objects must always be allocated at the+  same time.  For example:++  struct Head { ... }+  struct Foot { ... }++  void send_message(char* msg) {+    int msglen = strlen(msg);+    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };+    void* chunks[3];+    if (independent_comalloc(3, sizes, chunks) == 0)+      die();+    struct Head* head = (struct Head*)(chunks[0]);+    char*        body = (char*)(chunks[1]);+    struct Foot* foot = (struct Foot*)(chunks[2]);+    // ...+  }++  In general though, independent_comalloc is worth using only for+  larger values of n_elements. For small values, you probably won't+  detect enough difference from series of malloc calls to bother.++  Overuse of independent_comalloc can increase overall memory usage,+  since it cannot reuse existing noncontiguous small chunks that+  might be available for some of the elements.+*/+void** dlindependent_comalloc(size_t, size_t*, void**);+++/*+  pvalloc(size_t n);+  Equivalent to valloc(minimum-page-that-holds(n)), that is,+  round up n to nearest pagesize.+ */+void*  dlpvalloc(size_t);++/*+  malloc_trim(size_t pad);++  If possible, gives memory back to the system (via negative arguments+  to sbrk) if there is unused memory at the `high' end of the malloc+  pool or in unused MMAP segments. You can call this after freeing+  large blocks of memory to potentially reduce the system-level memory+  requirements of a program. However, it cannot guarantee to reduce+  memory. Under some allocation patterns, some large free blocks of+  memory will be locked between two used chunks, so they cannot be+  given back to the system.++  The `pad' argument to malloc_trim represents the amount of free+  trailing space to leave untrimmed. If this argument is zero, only+  the minimum amount of memory to maintain internal data structures+  will be left. Non-zero arguments can be supplied to maintain enough+  trailing space to service future expected allocations without having+  to re-obtain memory from the system.++  Malloc_trim returns 1 if it actually released any memory, else 0.+*/+int  dlmalloc_trim(size_t);++/*+  malloc_usable_size(void* p);++  Returns the number of bytes you can actually use in+  an allocated chunk, which may be more than you requested (although+  often not) due to alignment and minimum size constraints.+  You can use this many bytes without worrying about+  overwriting other allocated objects. This is not a particularly great+  programming practice. malloc_usable_size can be more useful in+  debugging and assertions, for example:++  p = malloc(n);+  assert(malloc_usable_size(p) >= 256);+*/+size_t dlmalloc_usable_size(void*);++/*+  malloc_stats();+  Prints on stderr the amount of space obtained from the system (both+  via sbrk and mmap), the maximum amount (which may be more than+  current if malloc_trim and/or munmap got called), and the current+  number of bytes allocated via malloc (or realloc, etc) but not yet+  freed. Note that this is the number of bytes allocated, not the+  number requested. It will be larger than the number requested+  because of alignment and bookkeeping overhead. Because it includes+  alignment wastage as being in use, this figure may be greater than+  zero even when no user-level chunks are allocated.++  The reported current and maximum system memory can be inaccurate if+  a program makes other calls to system memory allocation functions+  (normally sbrk) outside of malloc.++  malloc_stats prints only the most commonly interesting statistics.+  More information can be obtained by calling mallinfo.+*/+void  dlmalloc_stats(void);++#endif /* ONLY_MSPACES */++#if MSPACES++/*+  mspace is an opaque type representing an independent+  region of space that supports mspace_malloc, etc.+*/+typedef void* mspace;++/*+  create_mspace creates and returns a new independent space with the+  given initial capacity, or, if 0, the default granularity size.  It+  returns null if there is no system memory available to create the+  space.  If argument locked is non-zero, the space uses a separate+  lock to control access. The capacity of the space will grow+  dynamically as needed to service mspace_malloc requests.  You can+  control the sizes of incremental increases of this space by+  compiling with a different DEFAULT_GRANULARITY or dynamically+  setting with mallopt(M_GRANULARITY, value).+*/+mspace create_mspace(size_t capacity, int locked);++/*+  destroy_mspace destroys the given space, and attempts to return all+  of its memory back to the system, returning the total number of+  bytes freed. After destruction, the results of access to all memory+  used by the space become undefined.+*/+size_t destroy_mspace(mspace msp);++/*+  create_mspace_with_base uses the memory supplied as the initial base+  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this+  space is used for bookkeeping, so the capacity must be at least this+  large. (Otherwise 0 is returned.) When this initial space is+  exhausted, additional memory will be obtained from the system.+  Destroying this space will deallocate all additionally allocated+  space (if possible) but not the initial base.+*/+mspace create_mspace_with_base(void* base, size_t capacity, int locked);++/*+  mspace_malloc behaves as malloc, but operates within+  the given space.+*/+void* mspace_malloc(mspace msp, size_t bytes);++/*+  mspace_free behaves as free, but operates within+  the given space.++  If compiled with FOOTERS==1, mspace_free is not actually needed.+  free may be called instead of mspace_free because freed chunks from+  any space are handled by their originating spaces.+*/+void mspace_free(mspace msp, void* mem);++/*+  mspace_realloc behaves as realloc, but operates within+  the given space.++  If compiled with FOOTERS==1, mspace_realloc is not actually+  needed.  realloc may be called instead of mspace_realloc because+  realloced chunks from any space are handled by their originating+  spaces.+*/+void* mspace_realloc(mspace msp, void* mem, size_t newsize);++/*+  mspace_calloc behaves as calloc, but operates within+  the given space.+*/+void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);++/*+  mspace_memalign behaves as memalign, but operates within+  the given space.+*/+void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);++/*+  mspace_independent_calloc behaves as independent_calloc, but+  operates within the given space.+*/+void** mspace_independent_calloc(mspace msp, size_t n_elements,+                                 size_t elem_size, void* chunks[]);++/*+  mspace_independent_comalloc behaves as independent_comalloc, but+  operates within the given space.+*/+void** mspace_independent_comalloc(mspace msp, size_t n_elements,+                                   size_t sizes[], void* chunks[]);++/*+  mspace_footprint() returns the number of bytes obtained from the+  system for this space.+*/+size_t mspace_footprint(mspace msp);++/*+  mspace_max_footprint() returns the peak number of bytes obtained from the+  system for this space.+*/+size_t mspace_max_footprint(mspace msp);+++#if !NO_MALLINFO+/*+  mspace_mallinfo behaves as mallinfo, but reports properties of+  the given space.+*/+struct mallinfo mspace_mallinfo(mspace msp);+#endif /* NO_MALLINFO */++/*+  mspace_malloc_stats behaves as malloc_stats, but reports+  properties of the given space.+*/+void mspace_malloc_stats(mspace msp);++/*+  mspace_trim behaves as malloc_trim, but+  operates within the given space.+*/+int mspace_trim(mspace msp, size_t pad);++/*+  An alias for mallopt.+*/+int mspace_mallopt(int, int);++#endif /* MSPACES */++#ifdef __cplusplus+};  /* end of extern "C" */+#endif /* __cplusplus */++/*+  ========================================================================+  To make a fully customizable malloc.h header file, cut everything+  above this line, put into file malloc.h, edit to suit, and #include it+  on the next line, as well as in programs that use this malloc.+  ========================================================================+*/++/* #include "malloc.h" */++/*------------------------------ internal #includes ---------------------- */++#ifdef _MSC_VER+#pragma warning( disable : 4146 ) /* no "unsigned" warnings */+#endif /* _MSC_VER */++#include <stdio.h>       /* for printing in malloc_stats */++#ifndef LACKS_ERRNO_H+#include <errno.h>       /* for MALLOC_FAILURE_ACTION */+#endif /* LACKS_ERRNO_H */+#if FOOTERS+#include <time.h>        /* for magic initialization */+#endif /* FOOTERS */+#ifndef LACKS_STDLIB_H+#include <stdlib.h>      /* for abort() */+#endif /* LACKS_STDLIB_H */+#ifdef DEBUG+#if ABORT_ON_ASSERT_FAILURE+#define assert(x) if(!(x)) ABORT+#else /* ABORT_ON_ASSERT_FAILURE */+#include <assert.h>+#endif /* ABORT_ON_ASSERT_FAILURE */+#else  /* DEBUG */+#define assert(x)+#endif /* DEBUG */+#ifndef LACKS_STRING_H+#include <string.h>      /* for memset etc */+#endif  /* LACKS_STRING_H */+#if USE_BUILTIN_FFS+#ifndef LACKS_STRINGS_H+#include <strings.h>     /* for ffs */+#endif /* LACKS_STRINGS_H */+#endif /* USE_BUILTIN_FFS */+#if HAVE_MMAP+#ifndef LACKS_SYS_MMAN_H+#include <sys/mman.h>    /* for mmap */+#endif /* LACKS_SYS_MMAN_H */+#ifndef LACKS_FCNTL_H+#include <fcntl.h>+#endif /* LACKS_FCNTL_H */+#endif /* HAVE_MMAP */+#if HAVE_MORECORE+#ifndef LACKS_UNISTD_H+#include <unistd.h>     /* for sbrk */+#else /* LACKS_UNISTD_H */+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)+extern void*     sbrk(ptrdiff_t);+#endif /* FreeBSD etc */+#endif /* LACKS_UNISTD_H */+#endif /* HAVE_MMAP */++#ifndef WIN32+#ifndef malloc_getpagesize+#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */+#    ifndef _SC_PAGE_SIZE+#      define _SC_PAGE_SIZE _SC_PAGESIZE+#    endif+#  endif+#  ifdef _SC_PAGE_SIZE+#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)+#  else+#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)+       extern size_t getpagesize();+#      define malloc_getpagesize getpagesize()+#    else+#      ifdef WIN32 /* use supplied emulation of getpagesize */+#        define malloc_getpagesize getpagesize()+#      else+#        ifndef LACKS_SYS_PARAM_H+#          include <sys/param.h>+#        endif+#        ifdef EXEC_PAGESIZE+#          define malloc_getpagesize EXEC_PAGESIZE+#        else+#          ifdef NBPG+#            ifndef CLSIZE+#              define malloc_getpagesize NBPG+#            else+#              define malloc_getpagesize (NBPG * CLSIZE)+#            endif+#          else+#            ifdef NBPC+#              define malloc_getpagesize NBPC+#            else+#              ifdef PAGESIZE+#                define malloc_getpagesize PAGESIZE+#              else /* just guess */+#                define malloc_getpagesize ((size_t)4096U)+#              endif+#            endif+#          endif+#        endif+#      endif+#    endif+#  endif+#endif+#endif++/* ------------------- size_t and alignment properties -------------------- */++/* The byte and bit size of a size_t */+#define SIZE_T_SIZE         (sizeof(size_t))+#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)++/* Some constants coerced to size_t */+/* Annoying but necessary to avoid errors on some platforms */+#define SIZE_T_ZERO         ((size_t)0)+#define SIZE_T_ONE          ((size_t)1)+#define SIZE_T_TWO          ((size_t)2)+#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)+#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)+#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)+#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)++/* The bit mask value corresponding to MALLOC_ALIGNMENT */+#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)++/* True if address a has acceptable alignment */+#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)++/* the number of bytes to offset an address to align it */+#define align_offset(A)\+ ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\+  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))++/* -------------------------- MMAP preliminaries ------------------------- */++/*+   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and+   checks to fail so compiler optimizer can delete code rather than+   using so many "#if"s.+*/+++/* MORECORE and MMAP must return MFAIL on failure */+#define MFAIL                ((void*)(MAX_SIZE_T))+#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */++#if !HAVE_MMAP+#define IS_MMAPPED_BIT       (SIZE_T_ZERO)+#define USE_MMAP_BIT         (SIZE_T_ZERO)+#define CALL_MMAP(s)         MFAIL+#define CALL_MUNMAP(a, s)    (-1)+#define DIRECT_MMAP(s)       MFAIL++#else /* HAVE_MMAP */+#define IS_MMAPPED_BIT       (SIZE_T_ONE)+#define USE_MMAP_BIT         (SIZE_T_ONE)++#if !defined(WIN32) && !defined (__OS2__)+#define CALL_MUNMAP(a, s)    munmap((a), (s))+#define MMAP_PROT            (PROT_READ|PROT_WRITE)+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)+#define MAP_ANONYMOUS        MAP_ANON+#endif /* MAP_ANON */+#ifdef MAP_ANONYMOUS+#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)+#define CALL_MMAP(s)         mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)+#else /* MAP_ANONYMOUS */+/*+   Nearly all versions of mmap support MAP_ANONYMOUS, so the following+   is unlikely to be needed, but is supplied just in case.+*/+#define MMAP_FLAGS           (MAP_PRIVATE)+static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */+#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \+           (dev_zero_fd = open("/dev/zero", O_RDWR), \+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))+#endif /* MAP_ANONYMOUS */++#define DIRECT_MMAP(s)       CALL_MMAP(s)++#elif defined(__OS2__)++/* OS/2 MMAP via DosAllocMem */+static void* os2mmap(size_t size) {+  void* ptr;+  if (DosAllocMem(&ptr, size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) &&+      DosAllocMem(&ptr, size, PAG_COMMIT|PAG_READ|PAG_WRITE))+    return MFAIL;+  return ptr;+}++#define os2direct_mmap(n)     os2mmap(n)++/* This function supports releasing coalesed segments */+static int os2munmap(void* ptr, size_t size) {+  while (size) {+    ULONG ulSize = size;+    ULONG ulFlags = 0;+    if (DosQueryMem(ptr, &ulSize, &ulFlags) != 0)+      return -1;+    if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 ||+        ulSize > size)+      return -1;+    if (DosFreeMem(ptr) != 0)+      return -1;+    ptr = ( void * ) ( ( char * ) ptr + ulSize );+    size -= ulSize;+  }+  return 0;+}++#define CALL_MMAP(s)         os2mmap(s)+#define CALL_MUNMAP(a, s)    os2munmap((a), (s))+#define DIRECT_MMAP(s)       os2direct_mmap(s)++#else /* WIN32 */++/* Win32 MMAP via VirtualAlloc */+static void* win32mmap(size_t size) {+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);+  return (ptr != 0)? ptr: MFAIL;+}++/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */+static void* win32direct_mmap(size_t size) {+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,+                           PAGE_EXECUTE_READWRITE);+  return (ptr != 0)? ptr: MFAIL;+}++/* This function supports releasing coalesed segments */+static int win32munmap(void* ptr, size_t size) {+  MEMORY_BASIC_INFORMATION minfo;+  char* cptr = ptr;+  while (size) {+    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)+      return -1;+    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||+        minfo.State != MEM_COMMIT || minfo.RegionSize > size)+      return -1;+    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)+      return -1;+    cptr += minfo.RegionSize;+    size -= minfo.RegionSize;+  }+  return 0;+}++#define CALL_MMAP(s)         win32mmap(s)+#define CALL_MUNMAP(a, s)    win32munmap((a), (s))+#define DIRECT_MMAP(s)       win32direct_mmap(s)+#endif /* WIN32 */+#endif /* HAVE_MMAP */++#if HAVE_MMAP && HAVE_MREMAP+#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))+#else  /* HAVE_MMAP && HAVE_MREMAP */+#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL+#endif /* HAVE_MMAP && HAVE_MREMAP */++#if HAVE_MORECORE+#define CALL_MORECORE(S)     MORECORE(S)+#else  /* HAVE_MORECORE */+#define CALL_MORECORE(S)     MFAIL+#endif /* HAVE_MORECORE */++/* mstate bit set if contiguous morecore disabled or failed */+#define USE_NONCONTIGUOUS_BIT (4U)++/* segment bit set in create_mspace_with_base */+#define EXTERN_BIT            (8U)+++/* --------------------------- Lock preliminaries ------------------------ */++#if USE_LOCKS++/*+  When locks are defined, there are up to two global locks:++  * If HAVE_MORECORE, morecore_mutex protects sequences of calls to+    MORECORE.  In many cases sys_alloc requires two calls, that should+    not be interleaved with calls by other threads.  This does not+    protect against direct calls to MORECORE by other threads not+    using this lock, so there is still code to cope the best we can on+    interference.++  * magic_init_mutex ensures that mparams.magic and other+    unique mparams values are initialized only once.+*/++#if !defined(WIN32) && !defined(__OS2__)+/* By default use posix locks */+#include <pthread.h>+#define MLOCK_T pthread_mutex_t+#define INITIAL_LOCK(l)      pthread_mutex_init(l, NULL)+#define ACQUIRE_LOCK(l)      pthread_mutex_lock(l)+#define RELEASE_LOCK(l)      pthread_mutex_unlock(l)++#if HAVE_MORECORE+static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER;+#endif /* HAVE_MORECORE */++static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;++#elif defined(__OS2__)+#define MLOCK_T HMTX+#define INITIAL_LOCK(l)      DosCreateMutexSem(0, l, 0, FALSE)+#define ACQUIRE_LOCK(l)      DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT)+#define RELEASE_LOCK(l)      DosReleaseMutexSem(*l)+#if HAVE_MORECORE+static MLOCK_T morecore_mutex;+#endif /* HAVE_MORECORE */+static MLOCK_T magic_init_mutex;++#else /* WIN32 */+/*+   Because lock-protected regions have bounded times, and there+   are no recursive lock calls, we can use simple spinlocks.+*/++#define MLOCK_T long+static int win32_acquire_lock (MLOCK_T *sl) {+  for (;;) {+#ifdef InterlockedCompareExchangePointer+    if (!InterlockedCompareExchange(sl, 1, 0))+      return 0;+#else  /* Use older void* version */+    if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0))+      return 0;+#endif /* InterlockedCompareExchangePointer */+    Sleep (0);+  }+}++static void win32_release_lock (MLOCK_T *sl) {+  InterlockedExchange (sl, 0);+}++#define INITIAL_LOCK(l)      *(l)=0+#define ACQUIRE_LOCK(l)      win32_acquire_lock(l)+#define RELEASE_LOCK(l)      win32_release_lock(l)+#if HAVE_MORECORE+static MLOCK_T morecore_mutex;+#endif /* HAVE_MORECORE */+static MLOCK_T magic_init_mutex;+#endif /* WIN32 */++#define USE_LOCK_BIT               (2U)+#else  /* USE_LOCKS */+#define USE_LOCK_BIT               (0U)+#define INITIAL_LOCK(l)+#endif /* USE_LOCKS */++#if USE_LOCKS && HAVE_MORECORE+#define ACQUIRE_MORECORE_LOCK()    ACQUIRE_LOCK(&morecore_mutex);+#define RELEASE_MORECORE_LOCK()    RELEASE_LOCK(&morecore_mutex);+#else /* USE_LOCKS && HAVE_MORECORE */+#define ACQUIRE_MORECORE_LOCK()+#define RELEASE_MORECORE_LOCK()+#endif /* USE_LOCKS && HAVE_MORECORE */++#if USE_LOCKS+#define ACQUIRE_MAGIC_INIT_LOCK()  ACQUIRE_LOCK(&magic_init_mutex);+#define RELEASE_MAGIC_INIT_LOCK()  RELEASE_LOCK(&magic_init_mutex);+#else  /* USE_LOCKS */+#define ACQUIRE_MAGIC_INIT_LOCK()+#define RELEASE_MAGIC_INIT_LOCK()+#endif /* USE_LOCKS */+++/* -----------------------  Chunk representations ------------------------ */++/*+  (The following includes lightly edited explanations by Colin Plumb.)++  The malloc_chunk declaration below is misleading (but accurate and+  necessary).  It declares a "view" into memory allowing access to+  necessary fields at known offsets from a given base.++  Chunks of memory are maintained using a `boundary tag' method as+  originally described by Knuth.  (See the paper by Paul Wilson+  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such+  techniques.)  Sizes of free chunks are stored both in the front of+  each chunk and at the end.  This makes consolidating fragmented+  chunks into bigger chunks fast.  The head fields also hold bits+  representing whether chunks are free or in use.++  Here are some pictures to make it clearer.  They are "exploded" to+  show that the state of a chunk can be thought of as extending from+  the high 31 bits of the head field of its header through the+  prev_foot and PINUSE_BIT bit of the following chunk header.++  A chunk that's in use looks like:++   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++           | Size of previous chunk (if P = 1)                             |+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|+         | Size of this chunk                                         1| +-++   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         |                                                               |+         +-                                                             -++         |                                                               |+         +-                                                             -++         |                                                               :+         +-      size - sizeof(size_t) available payload bytes          -++         :                                                               |+ chunk-> +-                                                             -++         |                                                               |+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|+       | Size of next chunk (may or may not be in use)               | +-++ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++    And if it's free, it looks like this:++   chunk-> +-                                                             -++           | User payload (must be in use, or we would have merged!)       |+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|+         | Size of this chunk                                         0| +-++   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         | Next pointer                                                  |+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         | Prev pointer                                                  |+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         |                                                               :+         +-      size - sizeof(struct chunk) unused bytes               -++         :                                                               |+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++         | Size of this chunk                                            |+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|+       | Size of next chunk (must be in use, or we would have merged)| +-++ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++       |                                                               :+       +- User payload                                                -++       :                                                               |+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++                                                                     |0|+                                                                     +-++  Note that since we always merge adjacent free chunks, the chunks+  adjacent to a free chunk must be in use.++  Given a pointer to a chunk (which can be derived trivially from the+  payload pointer) we can, in O(1) time, find out whether the adjacent+  chunks are free, and if so, unlink them from the lists that they+  are on and merge them with the current chunk.++  Chunks always begin on even word boundaries, so the mem portion+  (which is returned to the user) is also on an even word boundary, and+  thus at least double-word aligned.++  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the+  chunk size (which is always a multiple of two words), is an in-use+  bit for the *previous* chunk.  If that bit is *clear*, then the+  word before the current chunk size contains the previous chunk+  size, and can be used to find the front of the previous chunk.+  The very first chunk allocated always has this bit set, preventing+  access to non-existent (or non-owned) memory. If pinuse is set for+  any given chunk, then you CANNOT determine the size of the+  previous chunk, and might even get a memory addressing fault when+  trying to do so.++  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of+  the chunk size redundantly records whether the current chunk is+  inuse. This redundancy enables usage checks within free and realloc,+  and reduces indirection when freeing and consolidating chunks.++  Each freshly allocated chunk must have both cinuse and pinuse set.+  That is, each allocated chunk borders either a previously allocated+  and still in-use chunk, or the base of its memory arena. This is+  ensured by making all allocations from the the `lowest' part of any+  found chunk.  Further, no free chunk physically borders another one,+  so each free chunk is known to be preceded and followed by either+  inuse chunks or the ends of memory.++  Note that the `foot' of the current chunk is actually represented+  as the prev_foot of the NEXT chunk. This makes it easier to+  deal with alignments etc but can be very confusing when trying+  to extend or adapt this code.++  The exceptions to all this are++     1. The special chunk `top' is the top-most available chunk (i.e.,+        the one bordering the end of available memory). It is treated+        specially.  Top is never included in any bin, is used only if+        no other chunk is available, and is released back to the+        system if it is very large (see M_TRIM_THRESHOLD).  In effect,+        the top chunk is treated as larger (and thus less well+        fitting) than any other available chunk.  The top chunk+        doesn't update its trailing size field since there is no next+        contiguous chunk that would have to index off it. However,+        space is still allocated for it (TOP_FOOT_SIZE) to enable+        separation or merging when space is extended.++     3. Chunks allocated via mmap, which have the lowest-order bit+        (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set+        PINUSE_BIT in their head fields.  Because they are allocated+        one-by-one, each must carry its own prev_foot field, which is+        also used to hold the offset this chunk has within its mmapped+        region, which is needed to preserve alignment. Each mmapped+        chunk is trailed by the first two fields of a fake next-chunk+        for sake of usage checks.++*/++struct malloc_chunk {+  size_t               prev_foot;  /* Size of previous chunk (if free).  */+  size_t               head;       /* Size and inuse bits. */+  struct malloc_chunk* fd;         /* double links -- used only if free. */+  struct malloc_chunk* bk;+};++typedef struct malloc_chunk  mchunk;+typedef struct malloc_chunk* mchunkptr;+typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */+typedef size_t bindex_t;               /* Described below */+typedef unsigned int binmap_t;         /* Described below */+typedef unsigned int flag_t;           /* The type of various bit flag sets */++/* ------------------- Chunks sizes and alignments ----------------------- */++#define MCHUNK_SIZE         (sizeof(mchunk))++#if FOOTERS+#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)+#else /* FOOTERS */+#define CHUNK_OVERHEAD      (SIZE_T_SIZE)+#endif /* FOOTERS */++/* MMapped chunks need a second word of overhead ... */+#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)+/* ... and additional padding for fake next-chunk at foot */+#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)++/* The smallest size we can malloc is an aligned minimal chunk */+#define MIN_CHUNK_SIZE\+  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)++/* conversion from malloc headers to user pointers, and back */+#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))+#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))+/* chunk associated with aligned address A */+#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))++/* Bounds on request (not chunk) sizes. */+#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)+#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)++/* pad request bytes into a usable size */+#define pad_request(req) \+   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)++/* pad request, checking for minimum (but not maximum) */+#define request2size(req) \+  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))+++/* ------------------ Operations on head and foot fields ----------------- */++/*+  The head field of a chunk is or'ed with PINUSE_BIT when previous+  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in+  use. If the chunk was obtained with mmap, the prev_foot field has+  IS_MMAPPED_BIT set, otherwise holding the offset of the base of the+  mmapped region to the base of the chunk.+*/++#define PINUSE_BIT          (SIZE_T_ONE)+#define CINUSE_BIT          (SIZE_T_TWO)+#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)++/* Head value for fenceposts */+#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)++/* extraction of fields from head words */+#define cinuse(p)           ((p)->head & CINUSE_BIT)+#define pinuse(p)           ((p)->head & PINUSE_BIT)+#define chunksize(p)        ((p)->head & ~(INUSE_BITS))++#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)+#define clear_cinuse(p)     ((p)->head &= ~CINUSE_BIT)++/* Treat space at ptr +/- offset as a chunk */+#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))+#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))++/* Ptr to next or previous physical malloc_chunk. */+#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS)))+#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))++/* extract next chunk's pinuse bit */+#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)++/* Get/set size at footer */+#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)+#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))++/* Set size, pinuse bit, and foot */+#define set_size_and_pinuse_of_free_chunk(p, s)\+  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))++/* Set size, pinuse bit, foot, and clear next pinuse */+#define set_free_with_pinuse(p, s, n)\+  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))++#define is_mmapped(p)\+  (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT))++/* Get the internal overhead associated with chunk p */+#define overhead_for(p)\+ (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)++/* Return true if malloced space is not necessarily cleared */+#if MMAP_CLEARS+#define calloc_must_clear(p) (!is_mmapped(p))+#else /* MMAP_CLEARS */+#define calloc_must_clear(p) (1)+#endif /* MMAP_CLEARS */++/* ---------------------- Overlaid data structures ----------------------- */++/*+  When chunks are not in use, they are treated as nodes of either+  lists or trees.++  "Small"  chunks are stored in circular doubly-linked lists, and look+  like this:++    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Size of previous chunk                            |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++    `head:' |             Size of chunk, in bytes                         |P|+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Forward pointer to next chunk in list             |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Back pointer to previous chunk in list            |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Unused space (may be 0 bytes long)                .+            .                                                               .+            .                                                               |+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++    `foot:' |             Size of chunk, in bytes                           |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++  Larger chunks are kept in a form of bitwise digital trees (aka+  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for+  free chunks greater than 256 bytes, their size doesn't impose any+  constraints on user chunk sizes.  Each node looks like:++    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Size of previous chunk                            |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++    `head:' |             Size of chunk, in bytes                         |P|+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Forward pointer to next chunk of same size        |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Back pointer to previous chunk of same size       |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Pointer to left child (child[0])                  |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Pointer to right child (child[1])                 |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Pointer to parent                                 |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             bin index of this chunk                           |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++            |             Unused space                                      .+            .                                                               |+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++    `foot:' |             Size of chunk, in bytes                           |+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks+  of the same size are arranged in a circularly-linked list, with only+  the oldest chunk (the next to be used, in our FIFO ordering)+  actually in the tree.  (Tree members are distinguished by a non-null+  parent pointer.)  If a chunk with the same size an an existing node+  is inserted, it is linked off the existing node using pointers that+  work in the same way as fd/bk pointers of small chunks.++  Each tree contains a power of 2 sized range of chunk sizes (the+  smallest is 0x100 <= x < 0x180), which is is divided in half at each+  tree level, with the chunks in the smaller half of the range (0x100+  <= x < 0x140 for the top nose) in the left subtree and the larger+  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,+  done by inspecting individual bits.++  Using these rules, each node's left subtree contains all smaller+  sizes than its right subtree.  However, the node at the root of each+  subtree has no particular ordering relationship to either.  (The+  dividing line between the subtree sizes is based on trie relation.)+  If we remove the last chunk of a given size from the interior of the+  tree, we need to replace it with a leaf node.  The tree ordering+  rules permit a node to be replaced by any leaf below it.++  The smallest chunk in a tree (a common operation in a best-fit+  allocator) can be found by walking a path to the leftmost leaf in+  the tree.  Unlike a usual binary tree, where we follow left child+  pointers until we reach a null, here we follow the right child+  pointer any time the left one is null, until we reach a leaf with+  both child pointers null. The smallest chunk in the tree will be+  somewhere along that path.++  The worst case number of steps to add, find, or remove a node is+  bounded by the number of bits differentiating chunks within+  bins. Under current bin calculations, this ranges from 6 up to 21+  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case+  is of course much better.+*/++struct malloc_tree_chunk {+  /* The first four fields must be compatible with malloc_chunk */+  size_t                    prev_foot;+  size_t                    head;+  struct malloc_tree_chunk* fd;+  struct malloc_tree_chunk* bk;++  struct malloc_tree_chunk* child[2];+  struct malloc_tree_chunk* parent;+  bindex_t                  index;+};++typedef struct malloc_tree_chunk  tchunk;+typedef struct malloc_tree_chunk* tchunkptr;+typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */++/* A little helper macro for trees */+#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])++/* ----------------------------- Segments -------------------------------- */++/*+  Each malloc space may include non-contiguous segments, held in a+  list headed by an embedded malloc_segment record representing the+  top-most space. Segments also include flags holding properties of+  the space. Large chunks that are directly allocated by mmap are not+  included in this list. They are instead independently created and+  destroyed without otherwise keeping track of them.++  Segment management mainly comes into play for spaces allocated by+  MMAP.  Any call to MMAP might or might not return memory that is+  adjacent to an existing segment.  MORECORE normally contiguously+  extends the current space, so this space is almost always adjacent,+  which is simpler and faster to deal with. (This is why MORECORE is+  used preferentially to MMAP when both are available -- see+  sys_alloc.)  When allocating using MMAP, we don't use any of the+  hinting mechanisms (inconsistently) supported in various+  implementations of unix mmap, or distinguish reserving from+  committing memory. Instead, we just ask for space, and exploit+  contiguity when we get it.  It is probably possible to do+  better than this on some systems, but no general scheme seems+  to be significantly better.++  Management entails a simpler variant of the consolidation scheme+  used for chunks to reduce fragmentation -- new adjacent memory is+  normally prepended or appended to an existing segment. However,+  there are limitations compared to chunk consolidation that mostly+  reflect the fact that segment processing is relatively infrequent+  (occurring only when getting memory from system) and that we+  don't expect to have huge numbers of segments:++  * Segments are not indexed, so traversal requires linear scans.  (It+    would be possible to index these, but is not worth the extra+    overhead and complexity for most programs on most platforms.)+  * New segments are only appended to old ones when holding top-most+    memory; if they cannot be prepended to others, they are held in+    different segments.++  Except for the top-most segment of an mstate, each segment record+  is kept at the tail of its segment. Segments are added by pushing+  segment records onto the list headed by &mstate.seg for the+  containing mstate.++  Segment flags control allocation/merge/deallocation policies:+  * If EXTERN_BIT set, then we did not allocate this segment,+    and so should not try to deallocate or merge with others.+    (This currently holds only for the initial segment passed+    into create_mspace_with_base.)+  * If IS_MMAPPED_BIT set, the segment may be merged with+    other surrounding mmapped segments and trimmed/de-allocated+    using munmap.+  * If neither bit is set, then the segment was obtained using+    MORECORE so can be merged with surrounding MORECORE'd segments+    and deallocated/trimmed using MORECORE with negative arguments.+*/++struct malloc_segment {+  char*        base;             /* base address */+  size_t       size;             /* allocated size */+  struct malloc_segment* next;   /* ptr to next segment */+#if FFI_MMAP_EXEC_WRIT+  /* The mmap magic is supposed to store the address of the executable+     segment at the very end of the requested block.  */++# define mmap_exec_offset(b,s) (*(ptrdiff_t*)((b)+(s)-sizeof(ptrdiff_t)))++  /* We can only merge segments if their corresponding executable+     segments are at identical offsets.  */+# define check_segment_merge(S,b,s) \+  (mmap_exec_offset((b),(s)) == (S)->exec_offset)++# define add_segment_exec_offset(p,S) ((char*)(p) + (S)->exec_offset)+# define sub_segment_exec_offset(p,S) ((char*)(p) - (S)->exec_offset)++  /* The removal of sflags only works with HAVE_MORECORE == 0.  */++# define get_segment_flags(S)   (IS_MMAPPED_BIT)+# define set_segment_flags(S,v) \+  (((v) != IS_MMAPPED_BIT) ? (ABORT, (v)) :				\+   (((S)->exec_offset =							\+     mmap_exec_offset((S)->base, (S)->size)),				\+    (mmap_exec_offset((S)->base + (S)->exec_offset, (S)->size) !=	\+     (S)->exec_offset) ? (ABORT, (v)) :					\+   (mmap_exec_offset((S)->base, (S)->size) = 0), (v)))++  /* We use an offset here, instead of a pointer, because then, when+     base changes, we don't have to modify this.  On architectures+     with segmented addresses, this might not work.  */+  ptrdiff_t    exec_offset;+#else++# define get_segment_flags(S)   ((S)->sflags)+# define set_segment_flags(S,v) ((S)->sflags = (v))+# define check_segment_merge(S,b,s) (1)++  flag_t       sflags;           /* mmap and extern flag */+#endif+};++#define is_mmapped_segment(S)  (get_segment_flags(S) & IS_MMAPPED_BIT)+#define is_extern_segment(S)   (get_segment_flags(S) & EXTERN_BIT)++typedef struct malloc_segment  msegment;+typedef struct malloc_segment* msegmentptr;++/* ---------------------------- malloc_state ----------------------------- */++/*+   A malloc_state holds all of the bookkeeping for a space.+   The main fields are:++  Top+    The topmost chunk of the currently active segment. Its size is+    cached in topsize.  The actual size of topmost space is+    topsize+TOP_FOOT_SIZE, which includes space reserved for adding+    fenceposts and segment records if necessary when getting more+    space from the system.  The size at which to autotrim top is+    cached from mparams in trim_check, except that it is disabled if+    an autotrim fails.++  Designated victim (dv)+    This is the preferred chunk for servicing small requests that+    don't have exact fits.  It is normally the chunk split off most+    recently to service another small request.  Its size is cached in+    dvsize. The link fields of this chunk are not maintained since it+    is not kept in a bin.++  SmallBins+    An array of bin headers for free chunks.  These bins hold chunks+    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains+    chunks of all the same size, spaced 8 bytes apart.  To simplify+    use in double-linked lists, each bin header acts as a malloc_chunk+    pointing to the real first node, if it exists (else pointing to+    itself).  This avoids special-casing for headers.  But to avoid+    waste, we allocate only the fd/bk pointers of bins, and then use+    repositioning tricks to treat these as the fields of a chunk.++  TreeBins+    Treebins are pointers to the roots of trees holding a range of+    sizes. There are 2 equally spaced treebins for each power of two+    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything+    larger.++  Bin maps+    There is one bit map for small bins ("smallmap") and one for+    treebins ("treemap).  Each bin sets its bit when non-empty, and+    clears the bit when empty.  Bit operations are then used to avoid+    bin-by-bin searching -- nearly all "search" is done without ever+    looking at bins that won't be selected.  The bit maps+    conservatively use 32 bits per map word, even if on 64bit system.+    For a good description of some of the bit-based techniques used+    here, see Henry S. Warren Jr's book "Hacker's Delight" (and+    supplement at http://hackersdelight.org/). Many of these are+    intended to reduce the branchiness of paths through malloc etc, as+    well as to reduce the number of memory locations read or written.++  Segments+    A list of segments headed by an embedded malloc_segment record+    representing the initial space.++  Address check support+    The least_addr field is the least address ever obtained from+    MORECORE or MMAP. Attempted frees and reallocs of any address less+    than this are trapped (unless INSECURE is defined).++  Magic tag+    A cross-check field that should always hold same value as mparams.magic.++  Flags+    Bits recording whether to use MMAP, locks, or contiguous MORECORE++  Statistics+    Each space keeps track of current and maximum system memory+    obtained via MORECORE or MMAP.++  Locking+    If USE_LOCKS is defined, the "mutex" lock is acquired and released+    around every public call using this mspace.+*/++/* Bin types, widths and sizes */+#define NSMALLBINS        (32U)+#define NTREEBINS         (32U)+#define SMALLBIN_SHIFT    (3U)+#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)+#define TREEBIN_SHIFT     (8U)+#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)+#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)+#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)++struct malloc_state {+  binmap_t   smallmap;+  binmap_t   treemap;+  size_t     dvsize;+  size_t     topsize;+  char*      least_addr;+  mchunkptr  dv;+  mchunkptr  top;+  size_t     trim_check;+  size_t     magic;+  mchunkptr  smallbins[(NSMALLBINS+1)*2];+  tbinptr    treebins[NTREEBINS];+  size_t     footprint;+  size_t     max_footprint;+  flag_t     mflags;+#if USE_LOCKS+  MLOCK_T    mutex;     /* locate lock among fields that rarely change */+#endif /* USE_LOCKS */+  msegment   seg;+};++typedef struct malloc_state*    mstate;++/* ------------- Global malloc_state and malloc_params ------------------- */++/*+  malloc_params holds global properties, including those that can be+  dynamically set using mallopt. There is a single instance, mparams,+  initialized in init_mparams.+*/++struct malloc_params {+  size_t magic;+  size_t page_size;+  size_t granularity;+  size_t mmap_threshold;+  size_t trim_threshold;+  flag_t default_mflags;+};++static struct malloc_params mparams;++/* The global malloc_state used for all non-"mspace" calls */+static struct malloc_state _gm_;+#define gm                 (&_gm_)+#define is_global(M)       ((M) == &_gm_)+#define is_initialized(M)  ((M)->top != 0)++/* -------------------------- system alloc setup ------------------------- */++/* Operations on mflags */++#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)+#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)+#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)++#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)+#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)+#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)++#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)+#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)++#define set_lock(M,L)\+ ((M)->mflags = (L)?\+  ((M)->mflags | USE_LOCK_BIT) :\+  ((M)->mflags & ~USE_LOCK_BIT))++/* page-align a size */+#define page_align(S)\+ (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE))++/* granularity-align a size */+#define granularity_align(S)\+  (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE))++#define is_page_aligned(S)\+   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)+#define is_granularity_aligned(S)\+   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)++/*  True if segment S holds address A */+#define segment_holds(S, A)\+  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)++/* Return segment holding given address */+static msegmentptr segment_holding(mstate m, char* addr) {+  msegmentptr sp = &m->seg;+  for (;;) {+    if (addr >= sp->base && addr < sp->base + sp->size)+      return sp;+    if ((sp = sp->next) == 0)+      return 0;+  }+}++/* Return true if segment contains a segment link */+static int has_segment_link(mstate m, msegmentptr ss) {+  msegmentptr sp = &m->seg;+  for (;;) {+    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)+      return 1;+    if ((sp = sp->next) == 0)+      return 0;+  }+}++#ifndef MORECORE_CANNOT_TRIM+#define should_trim(M,s)  ((s) > (M)->trim_check)+#else  /* MORECORE_CANNOT_TRIM */+#define should_trim(M,s)  (0)+#endif /* MORECORE_CANNOT_TRIM */++/*+  TOP_FOOT_SIZE is padding at the end of a segment, including space+  that may be needed to place segment records and fenceposts when new+  noncontiguous segments are added.+*/+#define TOP_FOOT_SIZE\+  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)+++/* -------------------------------  Hooks -------------------------------- */++/*+  PREACTION should be defined to return 0 on success, and nonzero on+  failure. If you are not using locking, you can redefine these to do+  anything you like.+*/++#if USE_LOCKS++/* Ensure locks are initialized */+#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams())++#define PREACTION(M)  ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)+#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }+#else /* USE_LOCKS */++#ifndef PREACTION+#define PREACTION(M) (0)+#endif  /* PREACTION */++#ifndef POSTACTION+#define POSTACTION(M)+#endif  /* POSTACTION */++#endif /* USE_LOCKS */++/*+  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.+  USAGE_ERROR_ACTION is triggered on detected bad frees and+  reallocs. The argument p is an address that might have triggered the+  fault. It is ignored by the two predefined actions, but might be+  useful in custom actions that try to help diagnose errors.+*/++#if PROCEED_ON_ERROR++/* A count of the number of corruption errors causing resets */+int malloc_corruption_error_count;++/* default corruption action */+static void reset_on_error(mstate m);++#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)+#define USAGE_ERROR_ACTION(m, p)++#else /* PROCEED_ON_ERROR */++#ifndef CORRUPTION_ERROR_ACTION+#define CORRUPTION_ERROR_ACTION(m) ABORT+#endif /* CORRUPTION_ERROR_ACTION */++#ifndef USAGE_ERROR_ACTION+#define USAGE_ERROR_ACTION(m,p) ABORT+#endif /* USAGE_ERROR_ACTION */++#endif /* PROCEED_ON_ERROR */++/* -------------------------- Debugging setup ---------------------------- */++#if ! DEBUG++#define check_free_chunk(M,P)+#define check_inuse_chunk(M,P)+#define check_malloced_chunk(M,P,N)+#define check_mmapped_chunk(M,P)+#define check_malloc_state(M)+#define check_top_chunk(M,P)++#else /* DEBUG */+#define check_free_chunk(M,P)       do_check_free_chunk(M,P)+#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)+#define check_top_chunk(M,P)        do_check_top_chunk(M,P)+#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)+#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)+#define check_malloc_state(M)       do_check_malloc_state(M)++static void   do_check_any_chunk(mstate m, mchunkptr p);+static void   do_check_top_chunk(mstate m, mchunkptr p);+static void   do_check_mmapped_chunk(mstate m, mchunkptr p);+static void   do_check_inuse_chunk(mstate m, mchunkptr p);+static void   do_check_free_chunk(mstate m, mchunkptr p);+static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);+static void   do_check_tree(mstate m, tchunkptr t);+static void   do_check_treebin(mstate m, bindex_t i);+static void   do_check_smallbin(mstate m, bindex_t i);+static void   do_check_malloc_state(mstate m);+static int    bin_find(mstate m, mchunkptr x);+static size_t traverse_and_check(mstate m);+#endif /* DEBUG */++/* ---------------------------- Indexing Bins ---------------------------- */++#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)+#define small_index(s)      ((s)  >> SMALLBIN_SHIFT)+#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)+#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))++/* addressing by index. See above about smallbin repositioning */+#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))+#define treebin_at(M,i)     (&((M)->treebins[i]))++/* assign tree index for size S to variable I */+#if defined(__GNUC__) && defined(__i386__)+#define compute_tree_index(S, I)\+{\+  size_t X = S >> TREEBIN_SHIFT;\+  if (X == 0)\+    I = 0;\+  else if (X > 0xFFFF)\+    I = NTREEBINS-1;\+  else {\+    unsigned int K;\+    __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm"  (X));\+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\+  }\+}+#else /* GNUC */+#define compute_tree_index(S, I)\+{\+  size_t X = S >> TREEBIN_SHIFT;\+  if (X == 0)\+    I = 0;\+  else if (X > 0xFFFF)\+    I = NTREEBINS-1;\+  else {\+    unsigned int Y = (unsigned int)X;\+    unsigned int N = ((Y - 0x100) >> 16) & 8;\+    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\+    N += K;\+    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\+    K = 14 - N + ((Y <<= K) >> 15);\+    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\+  }\+}+#endif /* GNUC */++/* Bit representing maximum resolved size in a treebin at i */+#define bit_for_tree_index(i) \+   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)++/* Shift placing maximum resolved bit in a treebin at i as sign bit */+#define leftshift_for_tree_index(i) \+   ((i == NTREEBINS-1)? 0 : \+    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))++/* The size of the smallest chunk held in bin with index i */+#define minsize_for_tree_index(i) \+   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \+   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))+++/* ------------------------ Operations on bin maps ----------------------- */++/* bit corresponding to given index */+#define idx2bit(i)              ((binmap_t)(1) << (i))++/* Mark/Clear bits with given index */+#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))+#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))+#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))++#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))+#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))+#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))++/* index corresponding to given bit */++#if defined(__GNUC__) && defined(__i386__)+#define compute_bit2idx(X, I)\+{\+  unsigned int J;\+  __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\+  I = (bindex_t)J;\+}++#else /* GNUC */+#if  USE_BUILTIN_FFS+#define compute_bit2idx(X, I) I = __builtin_ffs(X)-1++#else /* USE_BUILTIN_FFS */+#define compute_bit2idx(X, I)\+{\+  unsigned int Y = X - 1;\+  unsigned int K = Y >> (16-4) & 16;\+  unsigned int N = K;        Y >>= K;\+  N += K = Y >> (8-3) &  8;  Y >>= K;\+  N += K = Y >> (4-2) &  4;  Y >>= K;\+  N += K = Y >> (2-1) &  2;  Y >>= K;\+  N += K = Y >> (1-0) &  1;  Y >>= K;\+  I = (bindex_t)(N + Y);\+}+#endif /* USE_BUILTIN_FFS */+#endif /* GNUC */++/* isolate the least set bit of a bitmap */+#define least_bit(x)         ((x) & -(x))++/* mask with all bits to left of least bit of x on */+#define left_bits(x)         ((x<<1) | -(x<<1))++/* mask with all bits to left of or equal to least bit of x on */+#define same_or_left_bits(x) ((x) | -(x))+++/* ----------------------- Runtime Check Support ------------------------- */++/*+  For security, the main invariant is that malloc/free/etc never+  writes to a static address other than malloc_state, unless static+  malloc_state itself has been corrupted, which cannot occur via+  malloc (because of these checks). In essence this means that we+  believe all pointers, sizes, maps etc held in malloc_state, but+  check all of those linked or offsetted from other embedded data+  structures.  These checks are interspersed with main code in a way+  that tends to minimize their run-time cost.++  When FOOTERS is defined, in addition to range checking, we also+  verify footer fields of inuse chunks, which can be used guarantee+  that the mstate controlling malloc/free is intact.  This is a+  streamlined version of the approach described by William Robertson+  et al in "Run-time Detection of Heap-based Overflows" LISA'03+  http://www.usenix.org/events/lisa03/tech/robertson.html The footer+  of an inuse chunk holds the xor of its mstate and a random seed,+  that is checked upon calls to free() and realloc().  This is+  (probablistically) unguessable from outside the program, but can be+  computed by any code successfully malloc'ing any chunk, so does not+  itself provide protection against code that has already broken+  security through some other means.  Unlike Robertson et al, we+  always dynamically check addresses of all offset chunks (previous,+  next, etc). This turns out to be cheaper than relying on hashes.+*/++#if !INSECURE+/* Check if address a is at least as high as any from MORECORE or MMAP */+#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)+/* Check if address of next chunk n is higher than base chunk p */+#define ok_next(p, n)    ((char*)(p) < (char*)(n))+/* Check if p has its cinuse bit on */+#define ok_cinuse(p)     cinuse(p)+/* Check if p has its pinuse bit on */+#define ok_pinuse(p)     pinuse(p)++#else /* !INSECURE */+#define ok_address(M, a) (1)+#define ok_next(b, n)    (1)+#define ok_cinuse(p)     (1)+#define ok_pinuse(p)     (1)+#endif /* !INSECURE */++#if (FOOTERS && !INSECURE)+/* Check if (alleged) mstate m has expected magic field */+#define ok_magic(M)      ((M)->magic == mparams.magic)+#else  /* (FOOTERS && !INSECURE) */+#define ok_magic(M)      (1)+#endif /* (FOOTERS && !INSECURE) */+++/* In gcc, use __builtin_expect to minimize impact of checks */+#if !INSECURE+#if defined(__GNUC__) && __GNUC__ >= 3+#define RTCHECK(e)  __builtin_expect(e, 1)+#else /* GNUC */+#define RTCHECK(e)  (e)+#endif /* GNUC */+#else /* !INSECURE */+#define RTCHECK(e)  (1)+#endif /* !INSECURE */++/* macros to set up inuse chunks with or without footers */++#if !FOOTERS++#define mark_inuse_foot(M,p,s)++/* Set cinuse bit and pinuse bit of next chunk */+#define set_inuse(M,p,s)\+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)++/* Set cinuse and pinuse of this chunk and pinuse of next chunk */+#define set_inuse_and_pinuse(M,p,s)\+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)++/* Set size, cinuse and pinuse bit of this chunk */+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))++#else /* FOOTERS */++/* Set foot of inuse chunk to be xor of mstate and seed */+#define mark_inuse_foot(M,p,s)\+  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))++#define get_mstate_for(p)\+  ((mstate)(((mchunkptr)((char*)(p) +\+    (chunksize(p))))->prev_foot ^ mparams.magic))++#define set_inuse(M,p,s)\+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \+  mark_inuse_foot(M,p,s))++#define set_inuse_and_pinuse(M,p,s)\+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\+ mark_inuse_foot(M,p,s))++#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\+  mark_inuse_foot(M, p, s))++#endif /* !FOOTERS */++/* ---------------------------- setting mparams -------------------------- */++/* Initialize mparams */+static int init_mparams(void) {+  if (mparams.page_size == 0) {+    size_t s;++    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;+    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;+#if MORECORE_CONTIGUOUS+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;+#else  /* MORECORE_CONTIGUOUS */+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;+#endif /* MORECORE_CONTIGUOUS */++#if (FOOTERS && !INSECURE)+    {+#if USE_DEV_RANDOM+      int fd;+      unsigned char buf[sizeof(size_t)];+      /* Try to use /dev/urandom, else fall back on using time */+      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&+          read(fd, buf, sizeof(buf)) == sizeof(buf)) {+        s = *((size_t *) buf);+        close(fd);+      }+      else+#endif /* USE_DEV_RANDOM */+        s = (size_t)(time(0) ^ (size_t)0x55555555U);++      s |= (size_t)8U;    /* ensure nonzero */+      s &= ~(size_t)7U;   /* improve chances of fault for bad values */++    }+#else /* (FOOTERS && !INSECURE) */+    s = (size_t)0x58585858U;+#endif /* (FOOTERS && !INSECURE) */+    ACQUIRE_MAGIC_INIT_LOCK();+    if (mparams.magic == 0) {+      mparams.magic = s;+      /* Set up lock for main malloc area */+      INITIAL_LOCK(&gm->mutex);+      gm->mflags = mparams.default_mflags;+    }+    RELEASE_MAGIC_INIT_LOCK();++#if !defined(WIN32) && !defined(__OS2__)+    mparams.page_size = malloc_getpagesize;+    mparams.granularity = ((DEFAULT_GRANULARITY != 0)?+                           DEFAULT_GRANULARITY : mparams.page_size);+#elif defined (__OS2__)+ /* if low-memory is used, os2munmap() would break+    if it were anything other than 64k */+    mparams.page_size = 4096u;+    mparams.granularity = 65536u;+#else /* WIN32 */+    {+      SYSTEM_INFO system_info;+      GetSystemInfo(&system_info);+      mparams.page_size = system_info.dwPageSize;+      mparams.granularity = system_info.dwAllocationGranularity;+    }+#endif /* WIN32 */++    /* Sanity-check configuration:+       size_t must be unsigned and as wide as pointer type.+       ints must be at least 4 bytes.+       alignment must be at least 8.+       Alignment, min chunk size, and page size must all be powers of 2.+    */+    if ((sizeof(size_t) != sizeof(char*)) ||+        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||+        (sizeof(int) < 4)  ||+        (MALLOC_ALIGNMENT < (size_t)8U) ||+        ((MALLOC_ALIGNMENT    & (MALLOC_ALIGNMENT-SIZE_T_ONE))    != 0) ||+        ((MCHUNK_SIZE         & (MCHUNK_SIZE-SIZE_T_ONE))         != 0) ||+        ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) ||+        ((mparams.page_size   & (mparams.page_size-SIZE_T_ONE))   != 0))+      ABORT;+  }+  return 0;+}++/* support for mallopt */+static int change_mparam(int param_number, int value) {+  size_t val = (size_t)value;+  init_mparams();+  switch(param_number) {+  case M_TRIM_THRESHOLD:+    mparams.trim_threshold = val;+    return 1;+  case M_GRANULARITY:+    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {+      mparams.granularity = val;+      return 1;+    }+    else+      return 0;+  case M_MMAP_THRESHOLD:+    mparams.mmap_threshold = val;+    return 1;+  default:+    return 0;+  }+}++#if DEBUG+/* ------------------------- Debugging Support --------------------------- */++/* Check properties of any chunk, whether free, inuse, mmapped etc  */+static void do_check_any_chunk(mstate m, mchunkptr p) {+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));+  assert(ok_address(m, p));+}++/* Check properties of top chunk */+static void do_check_top_chunk(mstate m, mchunkptr p) {+  msegmentptr sp = segment_holding(m, (char*)p);+  size_t  sz = chunksize(p);+  assert(sp != 0);+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));+  assert(ok_address(m, p));+  assert(sz == m->topsize);+  assert(sz > 0);+  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);+  assert(pinuse(p));+  assert(!next_pinuse(p));+}++/* Check properties of (inuse) mmapped chunks */+static void do_check_mmapped_chunk(mstate m, mchunkptr p) {+  size_t  sz = chunksize(p);+  size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD);+  assert(is_mmapped(p));+  assert(use_mmap(m));+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));+  assert(ok_address(m, p));+  assert(!is_small(sz));+  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);+  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);+  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);+}++/* Check properties of inuse chunks */+static void do_check_inuse_chunk(mstate m, mchunkptr p) {+  do_check_any_chunk(m, p);+  assert(cinuse(p));+  assert(next_pinuse(p));+  /* If not pinuse and not mmapped, previous chunk has OK offset */+  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);+  if (is_mmapped(p))+    do_check_mmapped_chunk(m, p);+}++/* Check properties of free chunks */+static void do_check_free_chunk(mstate m, mchunkptr p) {+  size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);+  mchunkptr next = chunk_plus_offset(p, sz);+  do_check_any_chunk(m, p);+  assert(!cinuse(p));+  assert(!next_pinuse(p));+  assert (!is_mmapped(p));+  if (p != m->dv && p != m->top) {+    if (sz >= MIN_CHUNK_SIZE) {+      assert((sz & CHUNK_ALIGN_MASK) == 0);+      assert(is_aligned(chunk2mem(p)));+      assert(next->prev_foot == sz);+      assert(pinuse(p));+      assert (next == m->top || cinuse(next));+      assert(p->fd->bk == p);+      assert(p->bk->fd == p);+    }+    else  /* markers are always of size SIZE_T_SIZE */+      assert(sz == SIZE_T_SIZE);+  }+}++/* Check properties of malloced chunks at the point they are malloced */+static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {+  if (mem != 0) {+    mchunkptr p = mem2chunk(mem);+    size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);+    do_check_inuse_chunk(m, p);+    assert((sz & CHUNK_ALIGN_MASK) == 0);+    assert(sz >= MIN_CHUNK_SIZE);+    assert(sz >= s);+    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */+    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));+  }+}++/* Check a tree and its subtrees.  */+static void do_check_tree(mstate m, tchunkptr t) {+  tchunkptr head = 0;+  tchunkptr u = t;+  bindex_t tindex = t->index;+  size_t tsize = chunksize(t);+  bindex_t idx;+  compute_tree_index(tsize, idx);+  assert(tindex == idx);+  assert(tsize >= MIN_LARGE_SIZE);+  assert(tsize >= minsize_for_tree_index(idx));+  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));++  do { /* traverse through chain of same-sized nodes */+    do_check_any_chunk(m, ((mchunkptr)u));+    assert(u->index == tindex);+    assert(chunksize(u) == tsize);+    assert(!cinuse(u));+    assert(!next_pinuse(u));+    assert(u->fd->bk == u);+    assert(u->bk->fd == u);+    if (u->parent == 0) {+      assert(u->child[0] == 0);+      assert(u->child[1] == 0);+    }+    else {+      assert(head == 0); /* only one node on chain has parent */+      head = u;+      assert(u->parent != u);+      assert (u->parent->child[0] == u ||+              u->parent->child[1] == u ||+              *((tbinptr*)(u->parent)) == u);+      if (u->child[0] != 0) {+        assert(u->child[0]->parent == u);+        assert(u->child[0] != u);+        do_check_tree(m, u->child[0]);+      }+      if (u->child[1] != 0) {+        assert(u->child[1]->parent == u);+        assert(u->child[1] != u);+        do_check_tree(m, u->child[1]);+      }+      if (u->child[0] != 0 && u->child[1] != 0) {+        assert(chunksize(u->child[0]) < chunksize(u->child[1]));+      }+    }+    u = u->fd;+  } while (u != t);+  assert(head != 0);+}++/*  Check all the chunks in a treebin.  */+static void do_check_treebin(mstate m, bindex_t i) {+  tbinptr* tb = treebin_at(m, i);+  tchunkptr t = *tb;+  int empty = (m->treemap & (1U << i)) == 0;+  if (t == 0)+    assert(empty);+  if (!empty)+    do_check_tree(m, t);+}++/*  Check all the chunks in a smallbin.  */+static void do_check_smallbin(mstate m, bindex_t i) {+  sbinptr b = smallbin_at(m, i);+  mchunkptr p = b->bk;+  unsigned int empty = (m->smallmap & (1U << i)) == 0;+  if (p == b)+    assert(empty);+  if (!empty) {+    for (; p != b; p = p->bk) {+      size_t size = chunksize(p);+      mchunkptr q;+      /* each chunk claims to be free */+      do_check_free_chunk(m, p);+      /* chunk belongs in bin */+      assert(small_index(size) == i);+      assert(p->bk == b || chunksize(p->bk) == chunksize(p));+      /* chunk is followed by an inuse chunk */+      q = next_chunk(p);+      if (q->head != FENCEPOST_HEAD)+        do_check_inuse_chunk(m, q);+    }+  }+}++/* Find x in a bin. Used in other check functions. */+static int bin_find(mstate m, mchunkptr x) {+  size_t size = chunksize(x);+  if (is_small(size)) {+    bindex_t sidx = small_index(size);+    sbinptr b = smallbin_at(m, sidx);+    if (smallmap_is_marked(m, sidx)) {+      mchunkptr p = b;+      do {+        if (p == x)+          return 1;+      } while ((p = p->fd) != b);+    }+  }+  else {+    bindex_t tidx;+    compute_tree_index(size, tidx);+    if (treemap_is_marked(m, tidx)) {+      tchunkptr t = *treebin_at(m, tidx);+      size_t sizebits = size << leftshift_for_tree_index(tidx);+      while (t != 0 && chunksize(t) != size) {+        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];+        sizebits <<= 1;+      }+      if (t != 0) {+        tchunkptr u = t;+        do {+          if (u == (tchunkptr)x)+            return 1;+        } while ((u = u->fd) != t);+      }+    }+  }+  return 0;+}++/* Traverse each chunk and check it; return total */+static size_t traverse_and_check(mstate m) {+  size_t sum = 0;+  if (is_initialized(m)) {+    msegmentptr s = &m->seg;+    sum += m->topsize + TOP_FOOT_SIZE;+    while (s != 0) {+      mchunkptr q = align_as_chunk(s->base);+      mchunkptr lastq = 0;+      assert(pinuse(q));+      while (segment_holds(s, q) &&+             q != m->top && q->head != FENCEPOST_HEAD) {+        sum += chunksize(q);+        if (cinuse(q)) {+          assert(!bin_find(m, q));+          do_check_inuse_chunk(m, q);+        }+        else {+          assert(q == m->dv || bin_find(m, q));+          assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */+          do_check_free_chunk(m, q);+        }+        lastq = q;+        q = next_chunk(q);+      }+      s = s->next;+    }+  }+  return sum;+}++/* Check all properties of malloc_state. */+static void do_check_malloc_state(mstate m) {+  bindex_t i;+  size_t total;+  /* check bins */+  for (i = 0; i < NSMALLBINS; ++i)+    do_check_smallbin(m, i);+  for (i = 0; i < NTREEBINS; ++i)+    do_check_treebin(m, i);++  if (m->dvsize != 0) { /* check dv chunk */+    do_check_any_chunk(m, m->dv);+    assert(m->dvsize == chunksize(m->dv));+    assert(m->dvsize >= MIN_CHUNK_SIZE);+    assert(bin_find(m, m->dv) == 0);+  }++  if (m->top != 0) {   /* check top chunk */+    do_check_top_chunk(m, m->top);+    assert(m->topsize == chunksize(m->top));+    assert(m->topsize > 0);+    assert(bin_find(m, m->top) == 0);+  }++  total = traverse_and_check(m);+  assert(total <= m->footprint);+  assert(m->footprint <= m->max_footprint);+}+#endif /* DEBUG */++/* ----------------------------- statistics ------------------------------ */++#if !NO_MALLINFO+static struct mallinfo internal_mallinfo(mstate m) {+  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };+  if (!PREACTION(m)) {+    check_malloc_state(m);+    if (is_initialized(m)) {+      size_t nfree = SIZE_T_ONE; /* top always free */+      size_t mfree = m->topsize + TOP_FOOT_SIZE;+      size_t sum = mfree;+      msegmentptr s = &m->seg;+      while (s != 0) {+        mchunkptr q = align_as_chunk(s->base);+        while (segment_holds(s, q) &&+               q != m->top && q->head != FENCEPOST_HEAD) {+          size_t sz = chunksize(q);+          sum += sz;+          if (!cinuse(q)) {+            mfree += sz;+            ++nfree;+          }+          q = next_chunk(q);+        }+        s = s->next;+      }++      nm.arena    = sum;+      nm.ordblks  = nfree;+      nm.hblkhd   = m->footprint - sum;+      nm.usmblks  = m->max_footprint;+      nm.uordblks = m->footprint - mfree;+      nm.fordblks = mfree;+      nm.keepcost = m->topsize;+    }++    POSTACTION(m);+  }+  return nm;+}+#endif /* !NO_MALLINFO */++static void internal_malloc_stats(mstate m) {+  if (!PREACTION(m)) {+    size_t maxfp = 0;+    size_t fp = 0;+    size_t used = 0;+    check_malloc_state(m);+    if (is_initialized(m)) {+      msegmentptr s = &m->seg;+      maxfp = m->max_footprint;+      fp = m->footprint;+      used = fp - (m->topsize + TOP_FOOT_SIZE);++      while (s != 0) {+        mchunkptr q = align_as_chunk(s->base);+        while (segment_holds(s, q) &&+               q != m->top && q->head != FENCEPOST_HEAD) {+          if (!cinuse(q))+            used -= chunksize(q);+          q = next_chunk(q);+        }+        s = s->next;+      }+    }++    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));+    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));+    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));++    POSTACTION(m);+  }+}++/* ----------------------- Operations on smallbins ----------------------- */++/*+  Various forms of linking and unlinking are defined as macros.  Even+  the ones for trees, which are very long but have very short typical+  paths.  This is ugly but reduces reliance on inlining support of+  compilers.+*/++/* Link a free chunk into a smallbin  */+#define insert_small_chunk(M, P, S) {\+  bindex_t I  = small_index(S);\+  mchunkptr B = smallbin_at(M, I);\+  mchunkptr F = B;\+  assert(S >= MIN_CHUNK_SIZE);\+  if (!smallmap_is_marked(M, I))\+    mark_smallmap(M, I);\+  else if (RTCHECK(ok_address(M, B->fd)))\+    F = B->fd;\+  else {\+    CORRUPTION_ERROR_ACTION(M);\+  }\+  B->fd = P;\+  F->bk = P;\+  P->fd = F;\+  P->bk = B;\+}++/* Unlink a chunk from a smallbin  */+#define unlink_small_chunk(M, P, S) {\+  mchunkptr F = P->fd;\+  mchunkptr B = P->bk;\+  bindex_t I = small_index(S);\+  assert(P != B);\+  assert(P != F);\+  assert(chunksize(P) == small_index2size(I));\+  if (F == B)\+    clear_smallmap(M, I);\+  else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\+                   (B == smallbin_at(M,I) || ok_address(M, B)))) {\+    F->bk = B;\+    B->fd = F;\+  }\+  else {\+    CORRUPTION_ERROR_ACTION(M);\+  }\+}++/* Unlink the first chunk from a smallbin */+#define unlink_first_small_chunk(M, B, P, I) {\+  mchunkptr F = P->fd;\+  assert(P != B);\+  assert(P != F);\+  assert(chunksize(P) == small_index2size(I));\+  if (B == F)\+    clear_smallmap(M, I);\+  else if (RTCHECK(ok_address(M, F))) {\+    B->fd = F;\+    F->bk = B;\+  }\+  else {\+    CORRUPTION_ERROR_ACTION(M);\+  }\+}++/* Replace dv node, binning the old one */+/* Used only when dvsize known to be small */+#define replace_dv(M, P, S) {\+  size_t DVS = M->dvsize;\+  if (DVS != 0) {\+    mchunkptr DV = M->dv;\+    assert(is_small(DVS));\+    insert_small_chunk(M, DV, DVS);\+  }\+  M->dvsize = S;\+  M->dv = P;\+}++/* ------------------------- Operations on trees ------------------------- */++/* Insert chunk into tree */+#define insert_large_chunk(M, X, S) {\+  tbinptr* H;\+  bindex_t I;\+  compute_tree_index(S, I);\+  H = treebin_at(M, I);\+  X->index = I;\+  X->child[0] = X->child[1] = 0;\+  if (!treemap_is_marked(M, I)) {\+    mark_treemap(M, I);\+    *H = X;\+    X->parent = (tchunkptr)H;\+    X->fd = X->bk = X;\+  }\+  else {\+    tchunkptr T = *H;\+    size_t K = S << leftshift_for_tree_index(I);\+    for (;;) {\+      if (chunksize(T) != S) {\+        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\+        K <<= 1;\+        if (*C != 0)\+          T = *C;\+        else if (RTCHECK(ok_address(M, C))) {\+          *C = X;\+          X->parent = T;\+          X->fd = X->bk = X;\+          break;\+        }\+        else {\+          CORRUPTION_ERROR_ACTION(M);\+          break;\+        }\+      }\+      else {\+        tchunkptr F = T->fd;\+        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\+          T->fd = F->bk = X;\+          X->fd = F;\+          X->bk = T;\+          X->parent = 0;\+          break;\+        }\+        else {\+          CORRUPTION_ERROR_ACTION(M);\+          break;\+        }\+      }\+    }\+  }\+}++/*+  Unlink steps:++  1. If x is a chained node, unlink it from its same-sized fd/bk links+     and choose its bk node as its replacement.+  2. If x was the last node of its size, but not a leaf node, it must+     be replaced with a leaf node (not merely one with an open left or+     right), to make sure that lefts and rights of descendants+     correspond properly to bit masks.  We use the rightmost descendant+     of x.  We could use any other leaf, but this is easy to locate and+     tends to counteract removal of leftmosts elsewhere, and so keeps+     paths shorter than minimally guaranteed.  This doesn't loop much+     because on average a node in a tree is near the bottom.+  3. If x is the base of a chain (i.e., has parent links) relink+     x's parent and children to x's replacement (or null if none).+*/++#define unlink_large_chunk(M, X) {\+  tchunkptr XP = X->parent;\+  tchunkptr R;\+  if (X->bk != X) {\+    tchunkptr F = X->fd;\+    R = X->bk;\+    if (RTCHECK(ok_address(M, F))) {\+      F->bk = R;\+      R->fd = F;\+    }\+    else {\+      CORRUPTION_ERROR_ACTION(M);\+    }\+  }\+  else {\+    tchunkptr* RP;\+    if (((R = *(RP = &(X->child[1]))) != 0) ||\+        ((R = *(RP = &(X->child[0]))) != 0)) {\+      tchunkptr* CP;\+      while ((*(CP = &(R->child[1])) != 0) ||\+             (*(CP = &(R->child[0])) != 0)) {\+        R = *(RP = CP);\+      }\+      if (RTCHECK(ok_address(M, RP)))\+        *RP = 0;\+      else {\+        CORRUPTION_ERROR_ACTION(M);\+      }\+    }\+  }\+  if (XP != 0) {\+    tbinptr* H = treebin_at(M, X->index);\+    if (X == *H) {\+      if ((*H = R) == 0) \+        clear_treemap(M, X->index);\+    }\+    else if (RTCHECK(ok_address(M, XP))) {\+      if (XP->child[0] == X) \+        XP->child[0] = R;\+      else \+        XP->child[1] = R;\+    }\+    else\+      CORRUPTION_ERROR_ACTION(M);\+    if (R != 0) {\+      if (RTCHECK(ok_address(M, R))) {\+        tchunkptr C0, C1;\+        R->parent = XP;\+        if ((C0 = X->child[0]) != 0) {\+          if (RTCHECK(ok_address(M, C0))) {\+            R->child[0] = C0;\+            C0->parent = R;\+          }\+          else\+            CORRUPTION_ERROR_ACTION(M);\+        }\+        if ((C1 = X->child[1]) != 0) {\+          if (RTCHECK(ok_address(M, C1))) {\+            R->child[1] = C1;\+            C1->parent = R;\+          }\+          else\+            CORRUPTION_ERROR_ACTION(M);\+        }\+      }\+      else\+        CORRUPTION_ERROR_ACTION(M);\+    }\+  }\+}++/* Relays to large vs small bin operations */++#define insert_chunk(M, P, S)\+  if (is_small(S)) insert_small_chunk(M, P, S)\+  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }++#define unlink_chunk(M, P, S)\+  if (is_small(S)) unlink_small_chunk(M, P, S)\+  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }+++/* Relays to internal calls to malloc/free from realloc, memalign etc */++#if ONLY_MSPACES+#define internal_malloc(m, b) mspace_malloc(m, b)+#define internal_free(m, mem) mspace_free(m,mem);+#else /* ONLY_MSPACES */+#if MSPACES+#define internal_malloc(m, b)\+   (m == gm)? dlmalloc(b) : mspace_malloc(m, b)+#define internal_free(m, mem)\+   if (m == gm) dlfree(mem); else mspace_free(m,mem);+#else /* MSPACES */+#define internal_malloc(m, b) dlmalloc(b)+#define internal_free(m, mem) dlfree(mem)+#endif /* MSPACES */+#endif /* ONLY_MSPACES */++/* -----------------------  Direct-mmapping chunks ----------------------- */++/*+  Directly mmapped chunks are set up with an offset to the start of+  the mmapped region stored in the prev_foot field of the chunk. This+  allows reconstruction of the required argument to MUNMAP when freed,+  and also allows adjustment of the returned chunk to meet alignment+  requirements (especially in memalign).  There is also enough space+  allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain+  the PINUSE bit so frees can be checked.+*/++/* Malloc using mmap */+static void* mmap_alloc(mstate m, size_t nb) {+  size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);+  if (mmsize > nb) {     /* Check for wrap around 0 */+    char* mm = (char*)(DIRECT_MMAP(mmsize));+    if (mm != CMFAIL) {+      size_t offset = align_offset(chunk2mem(mm));+      size_t psize = mmsize - offset - MMAP_FOOT_PAD;+      mchunkptr p = (mchunkptr)(mm + offset);+      p->prev_foot = offset | IS_MMAPPED_BIT;+      (p)->head = (psize|CINUSE_BIT);+      mark_inuse_foot(m, p, psize);+      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;+      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;++      if (mm < m->least_addr)+        m->least_addr = mm;+      if ((m->footprint += mmsize) > m->max_footprint)+        m->max_footprint = m->footprint;+      assert(is_aligned(chunk2mem(p)));+      check_mmapped_chunk(m, p);+      return chunk2mem(p);+    }+  }+  return 0;+}++/* Realloc using mmap */+static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) {+  size_t oldsize = chunksize(oldp);+  if (is_small(nb)) /* Can't shrink mmap regions below small size */+    return 0;+  /* Keep old chunk if big enough but not too big */+  if (oldsize >= nb + SIZE_T_SIZE &&+      (oldsize - nb) <= (mparams.granularity << 1))+    return oldp;+  else {+    size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT;+    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;+    size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES ++                                         CHUNK_ALIGN_MASK);+    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,+                                  oldmmsize, newmmsize, 1);+    if (cp != CMFAIL) {+      mchunkptr newp = (mchunkptr)(cp + offset);+      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;+      newp->head = (psize|CINUSE_BIT);+      mark_inuse_foot(m, newp, psize);+      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;+      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;++      if (cp < m->least_addr)+        m->least_addr = cp;+      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)+        m->max_footprint = m->footprint;+      check_mmapped_chunk(m, newp);+      return newp;+    }+  }+  return 0;+}++/* -------------------------- mspace management -------------------------- */++/* Initialize top chunk and its size */+static void init_top(mstate m, mchunkptr p, size_t psize) {+  /* Ensure alignment */+  size_t offset = align_offset(chunk2mem(p));+  p = (mchunkptr)((char*)p + offset);+  psize -= offset;++  m->top = p;+  m->topsize = psize;+  p->head = psize | PINUSE_BIT;+  /* set size of fake trailing chunk holding overhead space only once */+  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;+  m->trim_check = mparams.trim_threshold; /* reset on each update */+}++/* Initialize bins for a new mstate that is otherwise zeroed out */+static void init_bins(mstate m) {+  /* Establish circular links for smallbins */+  bindex_t i;+  for (i = 0; i < NSMALLBINS; ++i) {+    sbinptr bin = smallbin_at(m,i);+    bin->fd = bin->bk = bin;+  }+}++#if PROCEED_ON_ERROR++/* default corruption action */+static void reset_on_error(mstate m) {+  int i;+  ++malloc_corruption_error_count;+  /* Reinitialize fields to forget about all memory */+  m->smallbins = m->treebins = 0;+  m->dvsize = m->topsize = 0;+  m->seg.base = 0;+  m->seg.size = 0;+  m->seg.next = 0;+  m->top = m->dv = 0;+  for (i = 0; i < NTREEBINS; ++i)+    *treebin_at(m, i) = 0;+  init_bins(m);+}+#endif /* PROCEED_ON_ERROR */++/* Allocate chunk and prepend remainder with chunk in successor base. */+static void* prepend_alloc(mstate m, char* newbase, char* oldbase,+                           size_t nb) {+  mchunkptr p = align_as_chunk(newbase);+  mchunkptr oldfirst = align_as_chunk(oldbase);+  size_t psize = (char*)oldfirst - (char*)p;+  mchunkptr q = chunk_plus_offset(p, nb);+  size_t qsize = psize - nb;+  set_size_and_pinuse_of_inuse_chunk(m, p, nb);++  assert((char*)oldfirst > (char*)q);+  assert(pinuse(oldfirst));+  assert(qsize >= MIN_CHUNK_SIZE);++  /* consolidate remainder with first chunk of old base */+  if (oldfirst == m->top) {+    size_t tsize = m->topsize += qsize;+    m->top = q;+    q->head = tsize | PINUSE_BIT;+    check_top_chunk(m, q);+  }+  else if (oldfirst == m->dv) {+    size_t dsize = m->dvsize += qsize;+    m->dv = q;+    set_size_and_pinuse_of_free_chunk(q, dsize);+  }+  else {+    if (!cinuse(oldfirst)) {+      size_t nsize = chunksize(oldfirst);+      unlink_chunk(m, oldfirst, nsize);+      oldfirst = chunk_plus_offset(oldfirst, nsize);+      qsize += nsize;+    }+    set_free_with_pinuse(q, qsize, oldfirst);+    insert_chunk(m, q, qsize);+    check_free_chunk(m, q);+  }++  check_malloced_chunk(m, chunk2mem(p), nb);+  return chunk2mem(p);+}+++/* Add a segment to hold a new noncontiguous region */+static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {+  /* Determine locations and sizes of segment, fenceposts, old top */+  char* old_top = (char*)m->top;+  msegmentptr oldsp = segment_holding(m, old_top);+  char* old_end = oldsp->base + oldsp->size;+  size_t ssize = pad_request(sizeof(struct malloc_segment));+  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);+  size_t offset = align_offset(chunk2mem(rawsp));+  char* asp = rawsp + offset;+  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;+  mchunkptr sp = (mchunkptr)csp;+  msegmentptr ss = (msegmentptr)(chunk2mem(sp));+  mchunkptr tnext = chunk_plus_offset(sp, ssize);+  mchunkptr p = tnext;+  int nfences = 0;+  (void)nfences; // Suppress unused variable warning++  /* reset top to new space */+  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);++  /* Set up segment record */+  assert(is_aligned(ss));+  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);+  *ss = m->seg; /* Push current record */+  m->seg.base = tbase;+  m->seg.size = tsize;+  (void)set_segment_flags(&m->seg, mmapped);+  m->seg.next = ss;++  /* Insert trailing fenceposts */+  for (;;) {+    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);+    p->head = FENCEPOST_HEAD;+    ++nfences;+    if ((char*)(&(nextp->head)) < old_end)+      p = nextp;+    else+      break;+  }+  assert(nfences >= 2);++  /* Insert the rest of old top into a bin as an ordinary free chunk */+  if (csp != old_top) {+    mchunkptr q = (mchunkptr)old_top;+    size_t psize = csp - old_top;+    mchunkptr tn = chunk_plus_offset(q, psize);+    set_free_with_pinuse(q, psize, tn);+    insert_chunk(m, q, psize);+  }++  check_top_chunk(m, m->top);+}++/* -------------------------- System allocation -------------------------- */++/* Get memory from system using MORECORE or MMAP */+static void* sys_alloc(mstate m, size_t nb) {+  char* tbase = CMFAIL;+  size_t tsize = 0;+  flag_t mmap_flag = 0;++  init_mparams();++  /* Directly map large chunks */+  if (use_mmap(m) && nb >= mparams.mmap_threshold) {+    void* mem = mmap_alloc(m, nb);+    if (mem != 0)+      return mem;+  }++  /*+    Try getting memory in any of three ways (in most-preferred to+    least-preferred order):+    1. A call to MORECORE that can normally contiguously extend memory.+       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or+       or main space is mmapped or a previous contiguous call failed)+    2. A call to MMAP new space (disabled if not HAVE_MMAP).+       Note that under the default settings, if MORECORE is unable to+       fulfill a request, and HAVE_MMAP is true, then mmap is+       used as a noncontiguous system allocator. This is a useful backup+       strategy for systems with holes in address spaces -- in this case+       sbrk cannot contiguously expand the heap, but mmap may be able to+       find space.+    3. A call to MORECORE that cannot usually contiguously extend memory.+       (disabled if not HAVE_MORECORE)+  */++  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {+    char* br = CMFAIL;+    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);+    size_t asize = 0;+    ACQUIRE_MORECORE_LOCK();++    if (ss == 0) {  /* First time through or recovery */+      char* base = (char*)CALL_MORECORE(0);+      if (base != CMFAIL) {+        asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);+        /* Adjust to end on a page boundary */+        if (!is_page_aligned(base))+          asize += (page_align((size_t)base) - (size_t)base);+        /* Can't call MORECORE if size is negative when treated as signed */+        if (asize < HALF_MAX_SIZE_T &&+            (br = (char*)(CALL_MORECORE(asize))) == base) {+          tbase = base;+          tsize = asize;+        }+      }+    }+    else {+      /* Subtract out existing available top space from MORECORE request. */+      asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE);+      /* Use mem here only if it did continuously extend old space */+      if (asize < HALF_MAX_SIZE_T &&+          (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {+        tbase = br;+        tsize = asize;+      }+    }++    if (tbase == CMFAIL) {    /* Cope with partial failure */+      if (br != CMFAIL) {    /* Try to use/extend the space we did get */+        if (asize < HALF_MAX_SIZE_T &&+            asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) {+          size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize);+          if (esize < HALF_MAX_SIZE_T) {+            char* end = (char*)CALL_MORECORE(esize);+            if (end != CMFAIL)+              asize += esize;+            else {            /* Can't use; try to release */+              (void)CALL_MORECORE(-asize);+              br = CMFAIL;+            }+          }+        }+      }+      if (br != CMFAIL) {    /* Use the space we did get */+        tbase = br;+        tsize = asize;+      }+      else+        disable_contiguous(m); /* Don't try contiguous path in the future */+    }++    RELEASE_MORECORE_LOCK();+  }++  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */+    size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;+    size_t rsize = granularity_align(req);+    if (rsize > nb) { /* Fail if wraps around zero */+      char* mp = (char*)(CALL_MMAP(rsize));+      if (mp != CMFAIL) {+        tbase = mp;+        tsize = rsize;+        mmap_flag = IS_MMAPPED_BIT;+      }+    }+  }++  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */+    size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);+    if (asize < HALF_MAX_SIZE_T) {+      char* br = CMFAIL;+      char* end = CMFAIL;+      ACQUIRE_MORECORE_LOCK();+      br = (char*)(CALL_MORECORE(asize));+      end = (char*)(CALL_MORECORE(0));+      RELEASE_MORECORE_LOCK();+      if (br != CMFAIL && end != CMFAIL && br < end) {+        size_t ssize = end - br;+        if (ssize > nb + TOP_FOOT_SIZE) {+          tbase = br;+          tsize = ssize;+        }+      }+    }+  }++  if (tbase != CMFAIL) {++    if ((m->footprint += tsize) > m->max_footprint)+      m->max_footprint = m->footprint;++    if (!is_initialized(m)) { /* first-time initialization */+      m->seg.base = m->least_addr = tbase;+      m->seg.size = tsize;+      (void)set_segment_flags(&m->seg, mmap_flag);+      m->magic = mparams.magic;+      init_bins(m);+      if (is_global(m)) +        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);+      else {+        /* Offset top by embedded malloc_state */+        mchunkptr mn = next_chunk(mem2chunk(m));+        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);+      }+    }++    else {+      /* Try to merge with an existing segment */+      msegmentptr sp = &m->seg;+      while (sp != 0 && tbase != sp->base + sp->size)+        sp = sp->next;+      if (sp != 0 &&+          !is_extern_segment(sp) &&+	  check_segment_merge(sp, tbase, tsize) &&+          (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag &&+          segment_holds(sp, m->top)) { /* append */+        sp->size += tsize;+        init_top(m, m->top, m->topsize + tsize);+      }+      else {+        if (tbase < m->least_addr)+          m->least_addr = tbase;+        sp = &m->seg;+        while (sp != 0 && sp->base != tbase + tsize)+          sp = sp->next;+        if (sp != 0 &&+            !is_extern_segment(sp) &&+	    check_segment_merge(sp, tbase, tsize) &&+            (get_segment_flags(sp) & IS_MMAPPED_BIT) == mmap_flag) {+          char* oldbase = sp->base;+          sp->base = tbase;+          sp->size += tsize;+          return prepend_alloc(m, tbase, oldbase, nb);+        }+        else+          add_segment(m, tbase, tsize, mmap_flag);+      }+    }++    if (nb < m->topsize) { /* Allocate from new or extended top space */+      size_t rsize = m->topsize -= nb;+      mchunkptr p = m->top;+      mchunkptr r = m->top = chunk_plus_offset(p, nb);+      r->head = rsize | PINUSE_BIT;+      set_size_and_pinuse_of_inuse_chunk(m, p, nb);+      check_top_chunk(m, m->top);+      check_malloced_chunk(m, chunk2mem(p), nb);+      return chunk2mem(p);+    }+  }++  MALLOC_FAILURE_ACTION;+  return 0;+}++/* -----------------------  system deallocation -------------------------- */++/* Unmap and unlink any mmapped segments that don't contain used chunks */+static size_t release_unused_segments(mstate m) {+  size_t released = 0;+  msegmentptr pred = &m->seg;+  msegmentptr sp = pred->next;+  while (sp != 0) {+    char* base = sp->base;+    size_t size = sp->size;+    msegmentptr next = sp->next;+    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {+      mchunkptr p = align_as_chunk(base);+      size_t psize = chunksize(p);+      /* Can unmap if first chunk holds entire segment and not pinned */+      if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {+        tchunkptr tp = (tchunkptr)p;+        assert(segment_holds(sp, (char*)sp));+        if (p == m->dv) {+          m->dv = 0;+          m->dvsize = 0;+        }+        else {+          unlink_large_chunk(m, tp);+        }+        if (CALL_MUNMAP(base, size) == 0) {+          released += size;+          m->footprint -= size;+          /* unlink obsoleted record */+          sp = pred;+          sp->next = next;+        }+        else { /* back out if cannot unmap */+          insert_large_chunk(m, tp, psize);+        }+      }+    }+    pred = sp;+    sp = next;+  }+  return released;+}++static int sys_trim(mstate m, size_t pad) {+  size_t released = 0;+  if (pad < MAX_REQUEST && is_initialized(m)) {+    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */++    if (m->topsize > pad) {+      /* Shrink top space in granularity-size units, keeping at least one */+      size_t unit = mparams.granularity;+      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -+                      SIZE_T_ONE) * unit;+      msegmentptr sp = segment_holding(m, (char*)m->top);++      if (!is_extern_segment(sp)) {+        if (is_mmapped_segment(sp)) {+          if (HAVE_MMAP &&+              sp->size >= extra &&+              !has_segment_link(m, sp)) { /* can't shrink if pinned */+            size_t newsize = sp->size - extra;+            /* Prefer mremap, fall back to munmap */+            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||+                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {+              released = extra;+            }+          }+        }+        else if (HAVE_MORECORE) {+          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */+            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;+          ACQUIRE_MORECORE_LOCK();+          {+            /* Make sure end of memory is where we last set it. */+            char* old_br = (char*)(CALL_MORECORE(0));+            if (old_br == sp->base + sp->size) {+              char* rel_br = (char*)(CALL_MORECORE(-extra));+              char* new_br = (char*)(CALL_MORECORE(0));+              if (rel_br != CMFAIL && new_br < old_br)+                released = old_br - new_br;+            }+          }+          RELEASE_MORECORE_LOCK();+        }+      }++      if (released != 0) {+        sp->size -= released;+        m->footprint -= released;+        init_top(m, m->top, m->topsize - released);+        check_top_chunk(m, m->top);+      }+    }++    /* Unmap any unused mmapped segments */+    if (HAVE_MMAP) +      released += release_unused_segments(m);++    /* On failure, disable autotrim to avoid repeated failed future calls */+    if (released == 0)+      m->trim_check = MAX_SIZE_T;+  }++  return (released != 0)? 1 : 0;+}++/* ---------------------------- malloc support --------------------------- */++/* allocate a large request from the best fitting chunk in a treebin */+static void* tmalloc_large(mstate m, size_t nb) {+  tchunkptr v = 0;+  size_t rsize = -nb; /* Unsigned negation */+  tchunkptr t;+  bindex_t idx;+  compute_tree_index(nb, idx);++  if ((t = *treebin_at(m, idx)) != 0) {+    /* Traverse tree for this bin looking for node with size == nb */+    size_t sizebits = nb << leftshift_for_tree_index(idx);+    tchunkptr rst = 0;  /* The deepest untaken right subtree */+    for (;;) {+      tchunkptr rt;+      size_t trem = chunksize(t) - nb;+      if (trem < rsize) {+        v = t;+        if ((rsize = trem) == 0)+          break;+      }+      rt = t->child[1];+      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];+      if (rt != 0 && rt != t)+        rst = rt;+      if (t == 0) {+        t = rst; /* set t to least subtree holding sizes > nb */+        break;+      }+      sizebits <<= 1;+    }+  }++  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */+    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;+    if (leftbits != 0) {+      bindex_t i;+      binmap_t leastbit = least_bit(leftbits);+      compute_bit2idx(leastbit, i);+      t = *treebin_at(m, i);+    }+  }++  while (t != 0) { /* find smallest of tree or subtree */+    size_t trem = chunksize(t) - nb;+    if (trem < rsize) {+      rsize = trem;+      v = t;+    }+    t = leftmost_child(t);+  }++  /*  If dv is a better fit, return 0 so malloc will use it */+  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {+    if (RTCHECK(ok_address(m, v))) { /* split */+      mchunkptr r = chunk_plus_offset(v, nb);+      assert(chunksize(v) == rsize + nb);+      if (RTCHECK(ok_next(v, r))) {+        unlink_large_chunk(m, v);+        if (rsize < MIN_CHUNK_SIZE)+          set_inuse_and_pinuse(m, v, (rsize + nb));+        else {+          set_size_and_pinuse_of_inuse_chunk(m, v, nb);+          set_size_and_pinuse_of_free_chunk(r, rsize);+          insert_chunk(m, r, rsize);+        }+        return chunk2mem(v);+      }+    }+    CORRUPTION_ERROR_ACTION(m);+  }+  return 0;+}++/* allocate a small request from the best fitting chunk in a treebin */+static void* tmalloc_small(mstate m, size_t nb) {+  tchunkptr t, v;+  size_t rsize;+  bindex_t i;+  binmap_t leastbit = least_bit(m->treemap);+  compute_bit2idx(leastbit, i);++  v = t = *treebin_at(m, i);+  rsize = chunksize(t) - nb;++  while ((t = leftmost_child(t)) != 0) {+    size_t trem = chunksize(t) - nb;+    if (trem < rsize) {+      rsize = trem;+      v = t;+    }+  }++  if (RTCHECK(ok_address(m, v))) {+    mchunkptr r = chunk_plus_offset(v, nb);+    assert(chunksize(v) == rsize + nb);+    if (RTCHECK(ok_next(v, r))) {+      unlink_large_chunk(m, v);+      if (rsize < MIN_CHUNK_SIZE)+        set_inuse_and_pinuse(m, v, (rsize + nb));+      else {+        set_size_and_pinuse_of_inuse_chunk(m, v, nb);+        set_size_and_pinuse_of_free_chunk(r, rsize);+        replace_dv(m, r, rsize);+      }+      return chunk2mem(v);+    }+  }++  CORRUPTION_ERROR_ACTION(m);+  return 0;+}++/* --------------------------- realloc support --------------------------- */++static void* internal_realloc(mstate m, void* oldmem, size_t bytes) {+  if (bytes >= MAX_REQUEST) {+    MALLOC_FAILURE_ACTION;+    return 0;+  }+  if (!PREACTION(m)) {+    mchunkptr oldp = mem2chunk(oldmem);+    size_t oldsize = chunksize(oldp);+    mchunkptr next = chunk_plus_offset(oldp, oldsize);+    mchunkptr newp = 0;+    void* extra = 0;++    /* Try to either shrink or extend into top. Else malloc-copy-free */++    if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) &&+                ok_next(oldp, next) && ok_pinuse(next))) {+      size_t nb = request2size(bytes);+      if (is_mmapped(oldp))+        newp = mmap_resize(m, oldp, nb);+      else if (oldsize >= nb) { /* already big enough */+        size_t rsize = oldsize - nb;+        newp = oldp;+        if (rsize >= MIN_CHUNK_SIZE) {+          mchunkptr remainder = chunk_plus_offset(newp, nb);+          set_inuse(m, newp, nb);+          set_inuse(m, remainder, rsize);+          extra = chunk2mem(remainder);+        }+      }+      else if (next == m->top && oldsize + m->topsize > nb) {+        /* Expand into top */+        size_t newsize = oldsize + m->topsize;+        size_t newtopsize = newsize - nb;+        mchunkptr newtop = chunk_plus_offset(oldp, nb);+        set_inuse(m, oldp, nb);+        newtop->head = newtopsize |PINUSE_BIT;+        m->top = newtop;+        m->topsize = newtopsize;+        newp = oldp;+      }+    }+    else {+      USAGE_ERROR_ACTION(m, oldmem);+      POSTACTION(m);+      return 0;+    }++    POSTACTION(m);++    if (newp != 0) {+      if (extra != 0) {+        internal_free(m, extra);+      }+      check_inuse_chunk(m, newp);+      return chunk2mem(newp);+    }+    else {+      void* newmem = internal_malloc(m, bytes);+      if (newmem != 0) {+        size_t oc = oldsize - overhead_for(oldp);+        memcpy(newmem, oldmem, (oc < bytes)? oc : bytes);+        internal_free(m, oldmem);+      }+      return newmem;+    }+  }+  return 0;+}++/* --------------------------- memalign support -------------------------- */++static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {+  if (alignment <= MALLOC_ALIGNMENT)    /* Can just use malloc */+    return internal_malloc(m, bytes);+  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */+    alignment = MIN_CHUNK_SIZE;+  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */+    size_t a = MALLOC_ALIGNMENT << 1;+    while (a < alignment) a <<= 1;+    alignment = a;+  }+  +  if (bytes >= MAX_REQUEST - alignment) {+    if (m != 0)  { /* Test isn't needed but avoids compiler warning */+      MALLOC_FAILURE_ACTION;+    }+  }+  else {+    size_t nb = request2size(bytes);+    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;+    char* mem = (char*)internal_malloc(m, req);+    if (mem != 0) {+      void* leader = 0;+      void* trailer = 0;+      mchunkptr p = mem2chunk(mem);++      if (PREACTION(m)) return 0;+      if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */+        /*+          Find an aligned spot inside chunk.  Since we need to give+          back leading space in a chunk of at least MIN_CHUNK_SIZE, if+          the first calculation places us at a spot with less than+          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.+          We've allocated enough total room so that this is always+          possible.+        */+        char* br = (char*)mem2chunk((size_t)(((size_t)(mem ++                                                       alignment -+                                                       SIZE_T_ONE)) &+                                             -alignment));+        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?+          br : br+alignment;+        mchunkptr newp = (mchunkptr)pos;+        size_t leadsize = pos - (char*)(p);+        size_t newsize = chunksize(p) - leadsize;++        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */+          newp->prev_foot = p->prev_foot + leadsize;+          newp->head = (newsize|CINUSE_BIT);+        }+        else { /* Otherwise, give back leader, use the rest */+          set_inuse(m, newp, newsize);+          set_inuse(m, p, leadsize);+          leader = chunk2mem(p);+        }+        p = newp;+      }++      /* Give back spare room at the end */+      if (!is_mmapped(p)) {+        size_t size = chunksize(p);+        if (size > nb + MIN_CHUNK_SIZE) {+          size_t remainder_size = size - nb;+          mchunkptr remainder = chunk_plus_offset(p, nb);+          set_inuse(m, p, nb);+          set_inuse(m, remainder, remainder_size);+          trailer = chunk2mem(remainder);+        }+      }++      assert (chunksize(p) >= nb);+      assert((((size_t)(chunk2mem(p))) % alignment) == 0);+      check_inuse_chunk(m, p);+      POSTACTION(m);+      if (leader != 0) {+        internal_free(m, leader);+      }+      if (trailer != 0) {+        internal_free(m, trailer);+      }+      return chunk2mem(p);+    }+  }+  return 0;+}++/* ------------------------ comalloc/coalloc support --------------------- */++static void** ialloc(mstate m,+                     size_t n_elements,+                     size_t* sizes,+                     int opts,+                     void* chunks[]) {+  /*+    This provides common support for independent_X routines, handling+    all of the combinations that can result.++    The opts arg has:+    bit 0 set if all elements are same size (using sizes[0])+    bit 1 set if elements should be zeroed+  */++  size_t    element_size;   /* chunksize of each element, if all same */+  size_t    contents_size;  /* total size of elements */+  size_t    array_size;     /* request size of pointer array */+  void*     mem;            /* malloced aggregate space */+  mchunkptr p;              /* corresponding chunk */+  size_t    remainder_size; /* remaining bytes while splitting */+  void**    marray;         /* either "chunks" or malloced ptr array */+  mchunkptr array_chunk;    /* chunk for malloced ptr array */+  flag_t    was_enabled;    /* to disable mmap */+  size_t    size;+  size_t    i;++  /* compute array length, if needed */+  if (chunks != 0) {+    if (n_elements == 0)+      return chunks; /* nothing to do */+    marray = chunks;+    array_size = 0;+  }+  else {+    /* if empty req, must still return chunk representing empty array */+    if (n_elements == 0)+      return (void**)internal_malloc(m, 0);+    marray = 0;+    array_size = request2size(n_elements * (sizeof(void*)));+  }++  /* compute total element size */+  if (opts & 0x1) { /* all-same-size */+    element_size = request2size(*sizes);+    contents_size = n_elements * element_size;+  }+  else { /* add up all the sizes */+    element_size = 0;+    contents_size = 0;+    for (i = 0; i != n_elements; ++i)+      contents_size += request2size(sizes[i]);+  }++  size = contents_size + array_size;++  /*+     Allocate the aggregate chunk.  First disable direct-mmapping so+     malloc won't use it, since we would not be able to later+     free/realloc space internal to a segregated mmap region.+  */+  was_enabled = use_mmap(m);+  disable_mmap(m);+  mem = internal_malloc(m, size - CHUNK_OVERHEAD);+  if (was_enabled)+    enable_mmap(m);+  if (mem == 0)+    return 0;++  if (PREACTION(m)) return 0;+  p = mem2chunk(mem);+  remainder_size = chunksize(p);++  assert(!is_mmapped(p));++  if (opts & 0x2) {       /* optionally clear the elements */+    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);+  }++  /* If not provided, allocate the pointer array as final part of chunk */+  if (marray == 0) {+    size_t  array_chunk_size;+    array_chunk = chunk_plus_offset(p, contents_size);+    array_chunk_size = remainder_size - contents_size;+    marray = (void**) (chunk2mem(array_chunk));+    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);+    remainder_size = contents_size;+  }++  /* split out elements */+  for (i = 0; ; ++i) {+    marray[i] = chunk2mem(p);+    if (i != n_elements-1) {+      if (element_size != 0)+        size = element_size;+      else+        size = request2size(sizes[i]);+      remainder_size -= size;+      set_size_and_pinuse_of_inuse_chunk(m, p, size);+      p = chunk_plus_offset(p, size);+    }+    else { /* the final element absorbs any overallocation slop */+      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);+      break;+    }+  }++#if DEBUG+  if (marray != chunks) {+    /* final element must have exactly exhausted chunk */+    if (element_size != 0) {+      assert(remainder_size == element_size);+    }+    else {+      assert(remainder_size == request2size(sizes[i]));+    }+    check_inuse_chunk(m, mem2chunk(marray));+  }+  for (i = 0; i != n_elements; ++i)+    check_inuse_chunk(m, mem2chunk(marray[i]));++#endif /* DEBUG */++  POSTACTION(m);+  return marray;+}+++/* -------------------------- public routines ---------------------------- */++#if !ONLY_MSPACES++void* dlmalloc(size_t bytes) {+  /*+     Basic algorithm:+     If a small request (< 256 bytes minus per-chunk overhead):+       1. If one exists, use a remainderless chunk in associated smallbin.+          (Remainderless means that there are too few excess bytes to+          represent as a chunk.)+       2. If it is big enough, use the dv chunk, which is normally the+          chunk adjacent to the one used for the most recent small request.+       3. If one exists, split the smallest available chunk in a bin,+          saving remainder in dv.+       4. If it is big enough, use the top chunk.+       5. If available, get memory from system and use it+     Otherwise, for a large request:+       1. Find the smallest available binned chunk that fits, and use it+          if it is better fitting than dv chunk, splitting if necessary.+       2. If better fitting than any binned chunk, use the dv chunk.+       3. If it is big enough, use the top chunk.+       4. If request size >= mmap threshold, try to directly mmap this chunk.+       5. If available, get memory from system and use it++     The ugly goto's here ensure that postaction occurs along all paths.+  */++  if (!PREACTION(gm)) {+    void* mem;+    size_t nb;+    if (bytes <= MAX_SMALL_REQUEST) {+      bindex_t idx;+      binmap_t smallbits;+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);+      idx = small_index(nb);+      smallbits = gm->smallmap >> idx;++      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */+        mchunkptr b, p;+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */+        b = smallbin_at(gm, idx);+        p = b->fd;+        assert(chunksize(p) == small_index2size(idx));+        unlink_first_small_chunk(gm, b, p, idx);+        set_inuse_and_pinuse(gm, p, small_index2size(idx));+        mem = chunk2mem(p);+        check_malloced_chunk(gm, mem, nb);+        goto postaction;+      }++      else if (nb > gm->dvsize) {+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */+          mchunkptr b, p, r;+          size_t rsize;+          bindex_t i;+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));+          binmap_t leastbit = least_bit(leftbits);+          compute_bit2idx(leastbit, i);+          b = smallbin_at(gm, i);+          p = b->fd;+          assert(chunksize(p) == small_index2size(i));+          unlink_first_small_chunk(gm, b, p, i);+          rsize = small_index2size(i) - nb;+          /* Fit here cannot be remainderless if 4byte sizes */+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)+            set_inuse_and_pinuse(gm, p, small_index2size(i));+          else {+            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);+            r = chunk_plus_offset(p, nb);+            set_size_and_pinuse_of_free_chunk(r, rsize);+            replace_dv(gm, r, rsize);+          }+          mem = chunk2mem(p);+          check_malloced_chunk(gm, mem, nb);+          goto postaction;+        }++        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {+          check_malloced_chunk(gm, mem, nb);+          goto postaction;+        }+      }+    }+    else if (bytes >= MAX_REQUEST)+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */+    else {+      nb = pad_request(bytes);+      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {+        check_malloced_chunk(gm, mem, nb);+        goto postaction;+      }+    }++    if (nb <= gm->dvsize) {+      size_t rsize = gm->dvsize - nb;+      mchunkptr p = gm->dv;+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */+        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);+        gm->dvsize = rsize;+        set_size_and_pinuse_of_free_chunk(r, rsize);+        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);+      }+      else { /* exhaust dv */+        size_t dvs = gm->dvsize;+        gm->dvsize = 0;+        gm->dv = 0;+        set_inuse_and_pinuse(gm, p, dvs);+      }+      mem = chunk2mem(p);+      check_malloced_chunk(gm, mem, nb);+      goto postaction;+    }++    else if (nb < gm->topsize) { /* Split top */+      size_t rsize = gm->topsize -= nb;+      mchunkptr p = gm->top;+      mchunkptr r = gm->top = chunk_plus_offset(p, nb);+      r->head = rsize | PINUSE_BIT;+      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);+      mem = chunk2mem(p);+      check_top_chunk(gm, gm->top);+      check_malloced_chunk(gm, mem, nb);+      goto postaction;+    }++    mem = sys_alloc(gm, nb);++  postaction:+    POSTACTION(gm);+    return mem;+  }++  return 0;+}++void dlfree(void* mem) {+  /*+     Consolidate freed chunks with preceding or succeeding bordering+     free chunks, if they exist, and then place in a bin.  Intermixed+     with special cases for top, dv, mmapped chunks, and usage errors.+  */++  if (mem != 0) {+    mchunkptr p  = mem2chunk(mem);+#if FOOTERS+    mstate fm = get_mstate_for(p);+    if (!ok_magic(fm)) {+      USAGE_ERROR_ACTION(fm, p);+      return;+    }+#else /* FOOTERS */+#define fm gm+#endif /* FOOTERS */+    if (!PREACTION(fm)) {+      check_inuse_chunk(fm, p);+      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {+        size_t psize = chunksize(p);+        mchunkptr next = chunk_plus_offset(p, psize);+        if (!pinuse(p)) {+          size_t prevsize = p->prev_foot;+          if ((prevsize & IS_MMAPPED_BIT) != 0) {+            prevsize &= ~IS_MMAPPED_BIT;+            psize += prevsize + MMAP_FOOT_PAD;+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)+              fm->footprint -= psize;+            goto postaction;+          }+          else {+            mchunkptr prev = chunk_minus_offset(p, prevsize);+            psize += prevsize;+            p = prev;+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */+              if (p != fm->dv) {+                unlink_chunk(fm, p, prevsize);+              }+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {+                fm->dvsize = psize;+                set_free_with_pinuse(p, psize, next);+                goto postaction;+              }+            }+            else+              goto erroraction;+          }+        }++        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {+          if (!cinuse(next)) {  /* consolidate forward */+            if (next == fm->top) {+              size_t tsize = fm->topsize += psize;+              fm->top = p;+              p->head = tsize | PINUSE_BIT;+              if (p == fm->dv) {+                fm->dv = 0;+                fm->dvsize = 0;+              }+              if (should_trim(fm, tsize))+                sys_trim(fm, 0);+              goto postaction;+            }+            else if (next == fm->dv) {+              size_t dsize = fm->dvsize += psize;+              fm->dv = p;+              set_size_and_pinuse_of_free_chunk(p, dsize);+              goto postaction;+            }+            else {+              size_t nsize = chunksize(next);+              psize += nsize;+              unlink_chunk(fm, next, nsize);+              set_size_and_pinuse_of_free_chunk(p, psize);+              if (p == fm->dv) {+                fm->dvsize = psize;+                goto postaction;+              }+            }+          }+          else+            set_free_with_pinuse(p, psize, next);+          insert_chunk(fm, p, psize);+          check_free_chunk(fm, p);+          goto postaction;+        }+      }+    erroraction:+      USAGE_ERROR_ACTION(fm, p);+    postaction:+      POSTACTION(fm);+    }+  }+#if !FOOTERS+#undef fm+#endif /* FOOTERS */+}++void* dlcalloc(size_t n_elements, size_t elem_size) {+  void* mem;+  size_t req = 0;+  if (n_elements != 0) {+    req = n_elements * elem_size;+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&+        (req / n_elements != elem_size))+      req = MAX_SIZE_T; /* force downstream failure on overflow */+  }+  mem = dlmalloc(req);+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))+    memset(mem, 0, req);+  return mem;+}++void* dlrealloc(void* oldmem, size_t bytes) {+  if (oldmem == 0)+    return dlmalloc(bytes);+#ifdef REALLOC_ZERO_BYTES_FREES+  if (bytes == 0) {+    dlfree(oldmem);+    return 0;+  }+#endif /* REALLOC_ZERO_BYTES_FREES */+  else {+#if ! FOOTERS+    mstate m = gm;+#else /* FOOTERS */+    mstate m = get_mstate_for(mem2chunk(oldmem));+    if (!ok_magic(m)) {+      USAGE_ERROR_ACTION(m, oldmem);+      return 0;+    }+#endif /* FOOTERS */+    return internal_realloc(m, oldmem, bytes);+  }+}++void* dlmemalign(size_t alignment, size_t bytes) {+  return internal_memalign(gm, alignment, bytes);+}++void** dlindependent_calloc(size_t n_elements, size_t elem_size,+                                 void* chunks[]) {+  size_t sz = elem_size; /* serves as 1-element array */+  return ialloc(gm, n_elements, &sz, 3, chunks);+}++void** dlindependent_comalloc(size_t n_elements, size_t sizes[],+                                   void* chunks[]) {+  return ialloc(gm, n_elements, sizes, 0, chunks);+}++void* dlvalloc(size_t bytes) {+  size_t pagesz;+  init_mparams();+  pagesz = mparams.page_size;+  return dlmemalign(pagesz, bytes);+}++void* dlpvalloc(size_t bytes) {+  size_t pagesz;+  init_mparams();+  pagesz = mparams.page_size;+  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));+}++int dlmalloc_trim(size_t pad) {+  int result = 0;+  if (!PREACTION(gm)) {+    result = sys_trim(gm, pad);+    POSTACTION(gm);+  }+  return result;+}++size_t dlmalloc_footprint(void) {+  return gm->footprint;+}++size_t dlmalloc_max_footprint(void) {+  return gm->max_footprint;+}++#if !NO_MALLINFO+struct mallinfo dlmallinfo(void) {+  return internal_mallinfo(gm);+}+#endif /* NO_MALLINFO */++void dlmalloc_stats(void) {+  internal_malloc_stats(gm);+}++size_t dlmalloc_usable_size(void* mem) {+  if (mem != 0) {+    mchunkptr p = mem2chunk(mem);+    if (cinuse(p))+      return chunksize(p) - overhead_for(p);+  }+  return 0;+}++int dlmallopt(int param_number, int value) {+  return change_mparam(param_number, value);+}++#endif /* !ONLY_MSPACES */++/* ----------------------------- user mspaces ---------------------------- */++#if MSPACES++static mstate init_user_mstate(char* tbase, size_t tsize) {+  size_t msize = pad_request(sizeof(struct malloc_state));+  mchunkptr mn;+  mchunkptr msp = align_as_chunk(tbase);+  mstate m = (mstate)(chunk2mem(msp));+  memset(m, 0, msize);+  INITIAL_LOCK(&m->mutex);+  msp->head = (msize|PINUSE_BIT|CINUSE_BIT);+  m->seg.base = m->least_addr = tbase;+  m->seg.size = m->footprint = m->max_footprint = tsize;+  m->magic = mparams.magic;+  m->mflags = mparams.default_mflags;+  disable_contiguous(m);+  init_bins(m);+  mn = next_chunk(mem2chunk(m));+  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);+  check_top_chunk(m, m->top);+  return m;+}++mspace create_mspace(size_t capacity, int locked) {+  mstate m = 0;+  size_t msize = pad_request(sizeof(struct malloc_state));+  init_mparams(); /* Ensure pagesize etc initialized */++  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {+    size_t rs = ((capacity == 0)? mparams.granularity :+                 (capacity + TOP_FOOT_SIZE + msize));+    size_t tsize = granularity_align(rs);+    char* tbase = (char*)(CALL_MMAP(tsize));+    if (tbase != CMFAIL) {+      m = init_user_mstate(tbase, tsize);+      set_segment_flags(&m->seg, IS_MMAPPED_BIT);+      set_lock(m, locked);+    }+  }+  return (mspace)m;+}++mspace create_mspace_with_base(void* base, size_t capacity, int locked) {+  mstate m = 0;+  size_t msize = pad_request(sizeof(struct malloc_state));+  init_mparams(); /* Ensure pagesize etc initialized */++  if (capacity > msize + TOP_FOOT_SIZE &&+      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {+    m = init_user_mstate((char*)base, capacity);+    set_segment_flags(&m->seg, EXTERN_BIT);+    set_lock(m, locked);+  }+  return (mspace)m;+}++size_t destroy_mspace(mspace msp) {+  size_t freed = 0;+  mstate ms = (mstate)msp;+  if (ok_magic(ms)) {+    msegmentptr sp = &ms->seg;+    while (sp != 0) {+      char* base = sp->base;+      size_t size = sp->size;+      flag_t flag = get_segment_flags(sp);+      sp = sp->next;+      if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) &&+          CALL_MUNMAP(base, size) == 0)+        freed += size;+    }+  }+  else {+    USAGE_ERROR_ACTION(ms,ms);+  }+  return freed;+}++/*+  mspace versions of routines are near-clones of the global+  versions. This is not so nice but better than the alternatives.+*/+++void* mspace_malloc(mspace msp, size_t bytes) {+  mstate ms = (mstate)msp;+  if (!ok_magic(ms)) {+    USAGE_ERROR_ACTION(ms,ms);+    return 0;+  }+  if (!PREACTION(ms)) {+    void* mem;+    size_t nb;+    if (bytes <= MAX_SMALL_REQUEST) {+      bindex_t idx;+      binmap_t smallbits;+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);+      idx = small_index(nb);+      smallbits = ms->smallmap >> idx;++      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */+        mchunkptr b, p;+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */+        b = smallbin_at(ms, idx);+        p = b->fd;+        assert(chunksize(p) == small_index2size(idx));+        unlink_first_small_chunk(ms, b, p, idx);+        set_inuse_and_pinuse(ms, p, small_index2size(idx));+        mem = chunk2mem(p);+        check_malloced_chunk(ms, mem, nb);+        goto postaction;+      }++      else if (nb > ms->dvsize) {+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */+          mchunkptr b, p, r;+          size_t rsize;+          bindex_t i;+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));+          binmap_t leastbit = least_bit(leftbits);+          compute_bit2idx(leastbit, i);+          b = smallbin_at(ms, i);+          p = b->fd;+          assert(chunksize(p) == small_index2size(i));+          unlink_first_small_chunk(ms, b, p, i);+          rsize = small_index2size(i) - nb;+          /* Fit here cannot be remainderless if 4byte sizes */+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)+            set_inuse_and_pinuse(ms, p, small_index2size(i));+          else {+            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);+            r = chunk_plus_offset(p, nb);+            set_size_and_pinuse_of_free_chunk(r, rsize);+            replace_dv(ms, r, rsize);+          }+          mem = chunk2mem(p);+          check_malloced_chunk(ms, mem, nb);+          goto postaction;+        }++        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {+          check_malloced_chunk(ms, mem, nb);+          goto postaction;+        }+      }+    }+    else if (bytes >= MAX_REQUEST)+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */+    else {+      nb = pad_request(bytes);+      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {+        check_malloced_chunk(ms, mem, nb);+        goto postaction;+      }+    }++    if (nb <= ms->dvsize) {+      size_t rsize = ms->dvsize - nb;+      mchunkptr p = ms->dv;+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */+        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);+        ms->dvsize = rsize;+        set_size_and_pinuse_of_free_chunk(r, rsize);+        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);+      }+      else { /* exhaust dv */+        size_t dvs = ms->dvsize;+        ms->dvsize = 0;+        ms->dv = 0;+        set_inuse_and_pinuse(ms, p, dvs);+      }+      mem = chunk2mem(p);+      check_malloced_chunk(ms, mem, nb);+      goto postaction;+    }++    else if (nb < ms->topsize) { /* Split top */+      size_t rsize = ms->topsize -= nb;+      mchunkptr p = ms->top;+      mchunkptr r = ms->top = chunk_plus_offset(p, nb);+      r->head = rsize | PINUSE_BIT;+      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);+      mem = chunk2mem(p);+      check_top_chunk(ms, ms->top);+      check_malloced_chunk(ms, mem, nb);+      goto postaction;+    }++    mem = sys_alloc(ms, nb);++  postaction:+    POSTACTION(ms);+    return mem;+  }++  return 0;+}++void mspace_free(mspace msp, void* mem) {+  if (mem != 0) {+    mchunkptr p  = mem2chunk(mem);+#if FOOTERS+    mstate fm = get_mstate_for(p);+#else /* FOOTERS */+    mstate fm = (mstate)msp;+#endif /* FOOTERS */+    if (!ok_magic(fm)) {+      USAGE_ERROR_ACTION(fm, p);+      return;+    }+    if (!PREACTION(fm)) {+      check_inuse_chunk(fm, p);+      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {+        size_t psize = chunksize(p);+        mchunkptr next = chunk_plus_offset(p, psize);+        if (!pinuse(p)) {+          size_t prevsize = p->prev_foot;+          if ((prevsize & IS_MMAPPED_BIT) != 0) {+            prevsize &= ~IS_MMAPPED_BIT;+            psize += prevsize + MMAP_FOOT_PAD;+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)+              fm->footprint -= psize;+            goto postaction;+          }+          else {+            mchunkptr prev = chunk_minus_offset(p, prevsize);+            psize += prevsize;+            p = prev;+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */+              if (p != fm->dv) {+                unlink_chunk(fm, p, prevsize);+              }+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {+                fm->dvsize = psize;+                set_free_with_pinuse(p, psize, next);+                goto postaction;+              }+            }+            else+              goto erroraction;+          }+        }++        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {+          if (!cinuse(next)) {  /* consolidate forward */+            if (next == fm->top) {+              size_t tsize = fm->topsize += psize;+              fm->top = p;+              p->head = tsize | PINUSE_BIT;+              if (p == fm->dv) {+                fm->dv = 0;+                fm->dvsize = 0;+              }+              if (should_trim(fm, tsize))+                sys_trim(fm, 0);+              goto postaction;+            }+            else if (next == fm->dv) {+              size_t dsize = fm->dvsize += psize;+              fm->dv = p;+              set_size_and_pinuse_of_free_chunk(p, dsize);+              goto postaction;+            }+            else {+              size_t nsize = chunksize(next);+              psize += nsize;+              unlink_chunk(fm, next, nsize);+              set_size_and_pinuse_of_free_chunk(p, psize);+              if (p == fm->dv) {+                fm->dvsize = psize;+                goto postaction;+              }+            }+          }+          else+            set_free_with_pinuse(p, psize, next);+          insert_chunk(fm, p, psize);+          check_free_chunk(fm, p);+          goto postaction;+        }+      }+    erroraction:+      USAGE_ERROR_ACTION(fm, p);+    postaction:+      POSTACTION(fm);+    }+  }+}++void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {+  void* mem;+  size_t req = 0;+  mstate ms = (mstate)msp;+  if (!ok_magic(ms)) {+    USAGE_ERROR_ACTION(ms,ms);+    return 0;+  }+  if (n_elements != 0) {+    req = n_elements * elem_size;+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&+        (req / n_elements != elem_size))+      req = MAX_SIZE_T; /* force downstream failure on overflow */+  }+  mem = internal_malloc(ms, req);+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))+    memset(mem, 0, req);+  return mem;+}++void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {+  if (oldmem == 0)+    return mspace_malloc(msp, bytes);+#ifdef REALLOC_ZERO_BYTES_FREES+  if (bytes == 0) {+    mspace_free(msp, oldmem);+    return 0;+  }+#endif /* REALLOC_ZERO_BYTES_FREES */+  else {+#if FOOTERS+    mchunkptr p  = mem2chunk(oldmem);+    mstate ms = get_mstate_for(p);+#else /* FOOTERS */+    mstate ms = (mstate)msp;+#endif /* FOOTERS */+    if (!ok_magic(ms)) {+      USAGE_ERROR_ACTION(ms,ms);+      return 0;+    }+    return internal_realloc(ms, oldmem, bytes);+  }+}++void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {+  mstate ms = (mstate)msp;+  if (!ok_magic(ms)) {+    USAGE_ERROR_ACTION(ms,ms);+    return 0;+  }+  return internal_memalign(ms, alignment, bytes);+}++void** mspace_independent_calloc(mspace msp, size_t n_elements,+                                 size_t elem_size, void* chunks[]) {+  size_t sz = elem_size; /* serves as 1-element array */+  mstate ms = (mstate)msp;+  if (!ok_magic(ms)) {+    USAGE_ERROR_ACTION(ms,ms);+    return 0;+  }+  return ialloc(ms, n_elements, &sz, 3, chunks);+}++void** mspace_independent_comalloc(mspace msp, size_t n_elements,+                                   size_t sizes[], void* chunks[]) {+  mstate ms = (mstate)msp;+  if (!ok_magic(ms)) {+    USAGE_ERROR_ACTION(ms,ms);+    return 0;+  }+  return ialloc(ms, n_elements, sizes, 0, chunks);+}++int mspace_trim(mspace msp, size_t pad) {+  int result = 0;+  mstate ms = (mstate)msp;+  if (ok_magic(ms)) {+    if (!PREACTION(ms)) {+      result = sys_trim(ms, pad);+      POSTACTION(ms);+    }+  }+  else {+    USAGE_ERROR_ACTION(ms,ms);+  }+  return result;+}++void mspace_malloc_stats(mspace msp) {+  mstate ms = (mstate)msp;+  if (ok_magic(ms)) {+    internal_malloc_stats(ms);+  }+  else {+    USAGE_ERROR_ACTION(ms,ms);+  }+}++size_t mspace_footprint(mspace msp) {+  size_t result;+  mstate ms = (mstate)msp;+  if (ok_magic(ms)) {+    result = ms->footprint;+  }+  USAGE_ERROR_ACTION(ms,ms);+  return result;+}+++size_t mspace_max_footprint(mspace msp) {+  size_t result;+  mstate ms = (mstate)msp;+  if (ok_magic(ms)) {+    result = ms->max_footprint;+  }+  USAGE_ERROR_ACTION(ms,ms);+  return result;+}+++#if !NO_MALLINFO+struct mallinfo mspace_mallinfo(mspace msp) {+  mstate ms = (mstate)msp;+  if (!ok_magic(ms)) {+    USAGE_ERROR_ACTION(ms,ms);+  }+  return internal_mallinfo(ms);+}+#endif /* NO_MALLINFO */++int mspace_mallopt(int param_number, int value) {+  return change_mparam(param_number, value);+}++#endif /* MSPACES */++/* -------------------- Alternative MORECORE functions ------------------- */++/*+  Guidelines for creating a custom version of MORECORE:++  * For best performance, MORECORE should allocate in multiples of pagesize.+  * MORECORE may allocate more memory than requested. (Or even less,+      but this will usually result in a malloc failure.)+  * MORECORE must not allocate memory when given argument zero, but+      instead return one past the end address of memory from previous+      nonzero call.+  * For best performance, consecutive calls to MORECORE with positive+      arguments should return increasing addresses, indicating that+      space has been contiguously extended.+  * Even though consecutive calls to MORECORE need not return contiguous+      addresses, it must be OK for malloc'ed chunks to span multiple+      regions in those cases where they do happen to be contiguous.+  * MORECORE need not handle negative arguments -- it may instead+      just return MFAIL when given negative arguments.+      Negative arguments are always multiples of pagesize. MORECORE+      must not misinterpret negative args as large positive unsigned+      args. You can suppress all such calls from even occurring by defining+      MORECORE_CANNOT_TRIM,++  As an example alternative MORECORE, here is a custom allocator+  kindly contributed for pre-OSX macOS.  It uses virtually but not+  necessarily physically contiguous non-paged memory (locked in,+  present and won't get swapped out).  You can use it by uncommenting+  this section, adding some #includes, and setting up the appropriate+  defines above:++      #define MORECORE osMoreCore++  There is also a shutdown routine that should somehow be called for+  cleanup upon program exit.++  #define MAX_POOL_ENTRIES 100+  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)+  static int next_os_pool;+  void *our_os_pools[MAX_POOL_ENTRIES];++  void *osMoreCore(int size)+  {+    void *ptr = 0;+    static void *sbrk_top = 0;++    if (size > 0)+    {+      if (size < MINIMUM_MORECORE_SIZE)+         size = MINIMUM_MORECORE_SIZE;+      if (CurrentExecutionLevel() == kTaskLevel)+         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);+      if (ptr == 0)+      {+        return (void *) MFAIL;+      }+      // save ptrs so they can be freed during cleanup+      our_os_pools[next_os_pool] = ptr;+      next_os_pool++;+      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);+      sbrk_top = (char *) ptr + size;+      return ptr;+    }+    else if (size < 0)+    {+      // we don't currently support shrink behavior+      return (void *) MFAIL;+    }+    else+    {+      return sbrk_top;+    }+  }++  // cleanup any allocated memory pools+  // called as last thing before shutting down driver++  void osCleanupMem(void)+  {+    void **ptr;++    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)+      if (*ptr)+      {+         PoolDeallocate(*ptr);+         *ptr = 0;+      }+  }++*/+++/* -----------------------------------------------------------------------+History:+    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)+      * Add max_footprint functions+      * Ensure all appropriate literals are size_t+      * Fix conditional compilation problem for some #define settings+      * Avoid concatenating segments with the one provided+        in create_mspace_with_base+      * Rename some variables to avoid compiler shadowing warnings+      * Use explicit lock initialization.+      * Better handling of sbrk interference.+      * Simplify and fix segment insertion, trimming and mspace_destroy+      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x+      * Thanks especially to Dennis Flanagan for help on these.++    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)+      * Fix memalign brace error.++    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)+      * Fix improper #endif nesting in C+++      * Add explicit casts needed for C++++    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)+      * Use trees for large bins+      * Support mspaces+      * Use segments to unify sbrk-based and mmap-based system allocation,+        removing need for emulation on most platforms without sbrk.+      * Default safety checks+      * Optional footer checks. Thanks to William Robertson for the idea.+      * Internal code refactoring+      * Incorporate suggestions and platform-specific changes.+        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,+        Aaron Bachmann,  Emery Berger, and others.+      * Speed up non-fastbin processing enough to remove fastbins.+      * Remove useless cfree() to avoid conflicts with other apps.+      * Remove internal memcpy, memset. Compilers handle builtins better.+      * Remove some options that no one ever used and rename others.++    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)+      * Fix malloc_state bitmap array misdeclaration++    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)+      * Allow tuning of FIRST_SORTED_BIN_SIZE+      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.+      * Better detection and support for non-contiguousness of MORECORE.+        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger+      * Bypass most of malloc if no frees. Thanks To Emery Berger.+      * Fix freeing of old top non-contiguous chunk im sysmalloc.+      * Raised default trim and map thresholds to 256K.+      * Fix mmap-related #defines. Thanks to Lubos Lunak.+      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.+      * Branch-free bin calculation+      * Default trim and mmap thresholds now 256K.++    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)+      * Introduce independent_comalloc and independent_calloc.+        Thanks to Michael Pachos for motivation and help.+      * Make optional .h file available+      * Allow > 2GB requests on 32bit systems.+      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.+        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,+        and Anonymous.+      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for+        helping test this.)+      * memalign: check alignment arg+      * realloc: don't try to shift chunks backwards, since this+        leads to  more fragmentation in some programs and doesn't+        seem to help in any others.+      * Collect all cases in malloc requiring system memory into sysmalloc+      * Use mmap as backup to sbrk+      * Place all internal state in malloc_state+      * Introduce fastbins (although similar to 2.5.1)+      * Many minor tunings and cosmetic improvements+      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK+      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS+        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.+      * Include errno.h to support default failure action.++    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)+      * return null for negative arguments+      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>+         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'+          (e.g. WIN32 platforms)+         * Cleanup header file inclusion for WIN32 platforms+         * Cleanup code to avoid Microsoft Visual C++ compiler complaints+         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing+           memory allocation routines+         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)+         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to+           usage of 'assert' in non-WIN32 code+         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to+           avoid infinite loop+      * Always call 'fREe()' rather than 'free()'++    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)+      * Fixed ordering problem with boundary-stamping++    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)+      * Added pvalloc, as recommended by H.J. Liu+      * Added 64bit pointer support mainly from Wolfram Gloger+      * Added anonymously donated WIN32 sbrk emulation+      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen+      * malloc_extend_top: fix mask error that caused wastage after+        foreign sbrks+      * Add linux mremap support code from HJ Liu++    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)+      * Integrated most documentation with the code.+      * Add support for mmap, with help from+        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).+      * Use last_remainder in more cases.+      * Pack bins using idea from  colin@nyx10.cs.du.edu+      * Use ordered bins instead of best-fit threshold+      * Eliminate block-local decls to simplify tracing and debugging.+      * Support another case of realloc via move into top+      * Fix error occurring when initial sbrk_base not word-aligned.+      * Rely on page size for units instead of SBRK_UNIT to+        avoid surprises about sbrk alignment conventions.+      * Add mallinfo, mallopt. Thanks to Raymond Nijssen+        (raymond@es.ele.tue.nl) for the suggestion.+      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.+      * More precautions for cases where other routines call sbrk,+        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).+      * Added macros etc., allowing use in linux libc from+        H.J. Lu (hjl@gnu.ai.mit.edu)+      * Inverted this history list++    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)+      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.+      * Removed all preallocation code since under current scheme+        the work required to undo bad preallocations exceeds+        the work saved in good cases for most test programs.+      * No longer use return list or unconsolidated bins since+        no scheme using them consistently outperforms those that don't+        given above changes.+      * Use best fit for very large chunks to prevent some worst-cases.+      * Added some support for debugging++    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)+      * Removed footers when chunks are in use. Thanks to+        Paul Wilson (wilson@cs.texas.edu) for the suggestion.++    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)+      * Added malloc_trim, with help from Wolfram Gloger+        (wmglo@Dent.MED.Uni-Muenchen.DE).++    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)++    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)+      * realloc: try to expand in both directions+      * malloc: swap order of clean-bin strategy;+      * realloc: only conditionally expand backwards+      * Try not to scavenge used bins+      * Use bin counts as a guide to preallocation+      * Occasionally bin return list chunks in first scan+      * Add a few optimizations from colin@nyx10.cs.du.edu++    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)+      * faster bin computation & slightly different binning+      * merged all consolidations to one part of malloc proper+         (eliminating old malloc_find_space & malloc_clean_bin)+      * Scan 2 returns chunks (not just 1)+      * Propagate failure in realloc if malloc returns 0+      * Add stuff to allow compilation on non-ANSI compilers+          from kpv@research.att.com++    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)+      * removed potential for odd address access in prev_chunk+      * removed dependency on getpagesize.h+      * misc cosmetics and a bit more internal documentation+      * anticosmetics: mangled names in macros to evade debugger strangeness+      * tested on sparc, hp-700, dec-mips, rs6000+          with gcc & native cc (hp, dec only) allowing+          Detlefs & Zorn comparison study (in SIGPLAN Notices.)++    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)+      * Based loosely on libg++-1.2X malloc. (It retains some of the overall+         structure of old version,  but most details differ.)+ +*/
+ src/frv/eabi.S view
@@ -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+	
+ src/frv/ffi.c view
@@ -0,0 +1,292 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (C) 2004  Anthony Green+   Copyright (C) 2007  Free Software Foundation, Inc.+	   Copyright (C) 2008  Red Hat, Inc.+   +   FR-V Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments */++void *ffi_prep_args(char *stack, extended_cif *ecif)+{+  register unsigned int i;+  register void **p_argv;+  register char *argp;+  register ffi_type **p_arg;+  register int count = 0;++  p_argv = ecif->avalue;+  argp = stack;++  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+       (i != 0);+       i--, p_arg++)+    {+      size_t z;+      +      z = (*p_arg)->size;++      if ((*p_arg)->type == FFI_TYPE_STRUCT)+	{+	  z = sizeof(void*);+	  *(void **) argp = *p_argv;+	} +      /*      if ((*p_arg)->type == FFI_TYPE_FLOAT)+	{+	  if (count > 24)+	    {+	      // This is going on the stack.  Turn it into a double.  +	      *(double *) argp = (double) *(float*)(* p_argv);+	      z = sizeof(double);+	    }+	  else+	    *(void **) argp = *(void **)(* p_argv);+	}  */+      else if (z < sizeof(int))+	{+	  z = sizeof(int);+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);+	      break;+	      +	    case FFI_TYPE_UINT8:+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);+	      break;+	      +	    case FFI_TYPE_SINT16:+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);+	      break;+		  +	    case FFI_TYPE_UINT16:+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);+	      break;+		  +	    default:+	      FFI_ASSERT(0);+	    }+	}+      else if (z == sizeof(int))+	{+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+	}+      else+	{+	  memcpy(argp, *p_argv, z);+	}+      p_argv++;+      argp += z;+      count += z;+    }++  return (stack + ((count > 24) ? 24 : FFI_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 = FFI_ALIGN (cif->bytes, 8);++  return FFI_OK;+}++extern void ffi_call_EABI(void *(*)(char *, extended_cif *), +			  extended_cif *, +			  unsigned, unsigned, +			  unsigned *, +			  void (*fn)(void));++void ffi_call(ffi_cif *cif, +	      void (*fn)(void), +	      void *rvalue, +	      void **avalue)+{+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;+  +  /* If the return value is a struct and we don't have a return	*/+  /* value address then we need to make one		        */++  if ((rvalue == NULL) && +      (cif->rtype->type == FFI_TYPE_STRUCT))+    {+      ecif.rvalue = alloca(cif->rtype->size);+    }+  else+    ecif.rvalue = rvalue;+    +  +  switch (cif->abi) +    {+    case FFI_EABI:+      ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes, +		    cif->flags, ecif.rvalue, fn);+      break;+    default:+      FFI_ASSERT(0);+      break;+    }+}++void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,+		       unsigned arg4, unsigned arg5, unsigned arg6)+{+  /* This function is called by a trampoline.  The trampoline stows a+     pointer to the ffi_closure object in gr7.  We must save this+     pointer in a place that will persist while we do our work.  */+  register ffi_closure *creg __asm__ ("gr7");+  ffi_closure *closure = creg;++  /* Arguments that don't fit in registers are found on the stack+     at a fixed offset above the current frame pointer.  */+  register char *frame_pointer __asm__ ("fp");+  char *stack_args = frame_pointer + 16;++  /* Lay the register arguments down in a continuous chunk of memory.  */+  unsigned register_args[6] =+    { arg1, arg2, arg3, arg4, arg5, arg6 };++  ffi_cif *cif = closure->cif;+  ffi_type **arg_types = cif->arg_types;+  void **avalue = alloca (cif->nargs * sizeof(void *));+  char *ptr = (char *) register_args;+  int i;++  /* Find the address of each argument.  */+  for (i = 0; i < cif->nargs; i++)+    {+      switch (arg_types[i]->type)+	{+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	  avalue[i] = ptr + 3;+	  break;+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	  avalue[i] = ptr + 2;+	  break;+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_FLOAT:+	  avalue[i] = ptr;+	  break;+	case FFI_TYPE_STRUCT:+	  avalue[i] = *(void**)ptr;+	  break;+	default:+	  /* This is an 8-byte value.  */+	  avalue[i] = ptr;+	  ptr += 4;+	  break;+	}+      ptr += 4;++      /* If we've handled more arguments than fit in registers,+	 start looking at the those passed on the stack.  */+      if (ptr == ((char *)register_args + (6*4)))+	ptr = stack_args;+    }++  /* Invoke the closure.  */+  if (cif->rtype->type == FFI_TYPE_STRUCT)+    {+      /* The caller allocates space for the return structure, and+       passes a pointer to this space in gr3.  Use this value directly+       as the return value.  */+      register void *return_struct_ptr __asm__("gr3");+      (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data);+    }+  else+    {+      /* Allocate space for the return value and call the function.  */+      long long rvalue;+      (closure->fun) (cif, &rvalue, avalue, closure->user_data);++      /* Functions return 4-byte or smaller results in gr8.  8-byte+	 values also use gr9.  We fill the both, even for small return+	 values, just to avoid a branch.  */ +      asm ("ldi  @(%0, #0), gr8" : : "r" (&rvalue));+      asm ("ldi  @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1]));+    }+}++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif*, void*, void**, void*),+		      void *user_data,+		      void *codeloc)+{+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];+  unsigned long fn = (long) ffi_closure_eabi;+  unsigned long cls = (long) codeloc;+#ifdef __FRV_FDPIC__+  register void *got __asm__("gr15");+#endif+  int i;++  fn = (unsigned long) ffi_closure_eabi;++#ifdef __FRV_FDPIC__+  tramp[0] = &((unsigned int *)codeloc)[2];+  tramp[1] = got;+  tramp[2] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */+  tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */+  tramp[4] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */+  tramp[5] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */+  tramp[6] = 0x9cc86000;                  /* ldi @(gr6, #0), gr14  */+  tramp[7] = 0x8030e000;                  /* jmpl @(gr14, gr0)     */+#else+  tramp[0] = 0x8cfc0000 + (fn  & 0xffff); /* setlos lo(fn), gr6    */+  tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7   */+  tramp[2] = 0x8cf80000 + (fn  >> 16);	  /* sethi hi(fn), gr6     */+  tramp[3] = 0x8ef80000 + (cls >> 16);    /* sethi hi(cls), gr7    */+  tramp[4] = 0x80300006;                  /* jmpl @(gr0, gr6)      */+#endif++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  /* Cache flushing.  */+  for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)+    __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),+		      "r" (codeloc));++  return FFI_OK;+}
+ src/frv/ffitarget.h view
@@ -0,0 +1,62 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2004  Red Hat, Inc.+   Target configuration macros for FR-V++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_EABI,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_EABI+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++#ifdef __FRV_FDPIC__+/* Trampolines are 8 4-byte instructions long.  */+#define FFI_TRAMPOLINE_SIZE (8*4)+#else+/* Trampolines are 5 4-byte instructions long.  */+#define FFI_TRAMPOLINE_SIZE (5*4)+#endif++#endif
+ src/ia64/ffi.c view
@@ -0,0 +1,616 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 1998, 2007, 2008, 2012 Red Hat, Inc.+	   Copyright (c) 2000 Hewlett Packard Company+	   Copyright (c) 2011 Anthony Green+   +   IA64 Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdbool.h>+#include <float.h>++#include "ia64_flags.h"++/* A 64-bit pointer value.  In LP64 mode, this is effectively a plain+   pointer.  In ILP32 mode, it's a pointer that's been extended to +   64 bits by "addp4".  */+#ifdef __hpux+typedef void *PTR64;+#else // some other unix+typedef void *PTR64 __attribute__((mode(DI)));+#endif++/* Memory image of fp register contents.  This is the implementation+   specific format used by ldf.fill/stf.spill.  All we care about is+   that it wants a 16 byte aligned slot.  */+typedef struct+{+  UINT64 x[2] __attribute__((aligned(16)));+} fpreg;+++/* The stack layout given to ffi_call_unix and ffi_closure_unix_inner.  */++struct ia64_args+{+  fpreg fp_regs[8];	/* Contents of 8 fp arg registers.  */+  UINT64 gp_regs[8];	/* Contents of 8 gp arg registers.  */+  UINT64 other_args[];	/* Arguments passed on stack, variable size.  */+};+++/* Adjust ADDR, a pointer to an 8 byte slot, to point to the low LEN bytes.  */++static inline void *+endian_adjust (void *addr, size_t len)+{+#ifdef __BIG_ENDIAN__+  return addr + (8 - len);+#else+  return addr;+#endif+}++/* Store VALUE to ADDR in the current cpu implementation's fp spill format.+   This is a macro instead of a function, so that it works for all 3 floating+   point types without type conversions.  Type conversion to long double breaks+   the denorm support.  */++#ifdef __hpux+#define stf_spill(addr, value)+#else+#define stf_spill(addr, value)	\+  asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));+#endif++/* Load a value from ADDR, which is in the current cpu implementation's+   fp spill format.  As above, this must also be a macro.  */++#ifdef __hpux+#define ldf_fill(result, addr)+#else+#define ldf_fill(result, addr)	\+  asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr));+#endif++/* Return the size of the C type associated with with TYPE.  Which will+   be one of the FFI_IA64_TYPE_HFA_* values.  */++static size_t+hfa_type_size (int type)+{+  switch (type)+    {+    case FFI_IA64_TYPE_HFA_FLOAT:+      return sizeof(float);+    case FFI_IA64_TYPE_HFA_DOUBLE:+      return sizeof(double);+    case FFI_IA64_TYPE_HFA_LDOUBLE:+      return sizeof(__float80);+    default:+      abort ();+    }+}++/* Load from ADDR a value indicated by TYPE.  Which will be one of+   the FFI_IA64_TYPE_HFA_* values.  */++static void+hfa_type_load (fpreg *fpaddr, int type, void *addr)+{+  switch (type)+    {+    case FFI_IA64_TYPE_HFA_FLOAT:+      stf_spill (fpaddr, *(float *) addr);+      return;+    case FFI_IA64_TYPE_HFA_DOUBLE:+      stf_spill (fpaddr, *(double *) addr);+      return;+    case FFI_IA64_TYPE_HFA_LDOUBLE:+      stf_spill (fpaddr, *(__float80 *) addr);+      return;+    default:+      abort ();+    }+}++/* Load VALUE into ADDR as indicated by TYPE.  Which will be one of+   the FFI_IA64_TYPE_HFA_* values.  */++static void+hfa_type_store (int type, void *addr, fpreg *fpaddr)+{+  switch (type)+    {+    case FFI_IA64_TYPE_HFA_FLOAT:+      {+	float result;+	ldf_fill (result, fpaddr);+	*(float *) addr = result;+	break;+      }+    case FFI_IA64_TYPE_HFA_DOUBLE:+      {+	double result;+	ldf_fill (result, fpaddr);+	*(double *) addr = result;+	break;+      }+    case FFI_IA64_TYPE_HFA_LDOUBLE:+      {+	__float80 result;+	ldf_fill (result, fpaddr);+	*(__float80 *) addr = result;+	break;+      }+    default:+      abort ();+    }+}++/* Is TYPE a struct containing floats, doubles, or extended doubles,+   all of the same fp type?  If so, return the element type.  Return+   FFI_TYPE_VOID if not.  */++static int+hfa_element_type (ffi_type *type, int nested)+{+  int element = FFI_TYPE_VOID;++  switch (type->type)+    {+    case FFI_TYPE_FLOAT:+      /* We want to return VOID for raw floating-point types, but the+	 synthetic HFA type if we're nested within an aggregate.  */+      if (nested)+	element = FFI_IA64_TYPE_HFA_FLOAT;+      break;++    case FFI_TYPE_DOUBLE:+      /* Similarly.  */+      if (nested)+	element = FFI_IA64_TYPE_HFA_DOUBLE;+      break;++    case FFI_TYPE_LONGDOUBLE:+      /* Similarly, except that that HFA is true for double extended,+	 but not quad precision.  Both have sizeof == 16, so tell the+	 difference based on the precision.  */+      if (LDBL_MANT_DIG == 64 && nested)+	element = FFI_IA64_TYPE_HFA_LDOUBLE;+      break;++    case FFI_TYPE_STRUCT:+      {+	ffi_type **ptr = &type->elements[0];++	for (ptr = &type->elements[0]; *ptr ; ptr++)+	  {+	    int sub_element = hfa_element_type (*ptr, 1);+	    if (sub_element == FFI_TYPE_VOID)+	      return FFI_TYPE_VOID;++	    if (element == FFI_TYPE_VOID)+	      element = sub_element;+	    else if (element != sub_element)+	      return FFI_TYPE_VOID;+	  }+      }+      break;++    default:+      return FFI_TYPE_VOID;+    }++  return element;+}+++/* Perform machine dependent cif processing. */++static ffi_status+ffi_prep_cif_machdep_core(ffi_cif *cif)+{+  int flags;++  /* Adjust cif->bytes to include space for the bits of the ia64_args frame+     that precedes the integer register portion.  The estimate that the+     generic bits did for the argument space required is good enough for the+     integer component.  */+  cif->bytes += offsetof(struct ia64_args, gp_regs[0]);+  if (cif->bytes < sizeof(struct ia64_args))+    cif->bytes = sizeof(struct ia64_args);++  /* Set the return type flag. */+  flags = cif->rtype->type;+  switch (cif->rtype->type)+    {+    case FFI_TYPE_LONGDOUBLE:+      /* Leave FFI_TYPE_LONGDOUBLE as meaning double extended precision,+	 and encode quad precision as a two-word integer structure.  */+      if (LDBL_MANT_DIG != 64)+	flags = FFI_IA64_TYPE_SMALL_STRUCT | (16 << 8);+      break;++    case FFI_TYPE_STRUCT:+      {+        size_t size = cif->rtype->size;+  	int hfa_type = hfa_element_type (cif->rtype, 0);++	if (hfa_type != FFI_TYPE_VOID)+	  {+	    size_t nelts = size / hfa_type_size (hfa_type);+	    if (nelts <= 8)+	      flags = hfa_type | (size << 8);+	  }+	else+	  {+	    if (size <= 32)+	      flags = FFI_IA64_TYPE_SMALL_STRUCT | (size << 8);+	  }+      }+      break;++    default:+      break;+    }+  cif->flags = flags;++  return FFI_OK;+}++ffi_status+ffi_prep_cif_machdep(ffi_cif *cif)+{+  cif->nfixedargs = cif->nargs;+  return ffi_prep_cif_machdep_core(cif);+}++ffi_status+ffi_prep_cif_machdep_var(ffi_cif *cif,+			 unsigned int nfixedargs,+			 unsigned int ntotalargs MAYBE_UNUSED)+{+  cif->nfixedargs = nfixedargs;+  return ffi_prep_cif_machdep_core(cif);+}++extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);++void+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  struct ia64_args *stack;+  long i, avn, gpcount, fpcount;+  ffi_type **p_arg;++  FFI_ASSERT (cif->abi == FFI_UNIX);++  /* If we have no spot for a return value, make one.  */+  if (rvalue == NULL && cif->rtype->type != FFI_TYPE_VOID)+    rvalue = alloca (cif->rtype->size);+    +  /* Allocate the stack frame.  */+  stack = alloca (cif->bytes);++  gpcount = fpcount = 0;+  avn = cif->nargs;+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)+    {+      switch ((*p_arg)->type)+	{+	case FFI_TYPE_SINT8:+	  stack->gp_regs[gpcount++] = *(SINT8 *)avalue[i];+	  break;+	case FFI_TYPE_UINT8:+	  stack->gp_regs[gpcount++] = *(UINT8 *)avalue[i];+	  break;+	case FFI_TYPE_SINT16:+	  stack->gp_regs[gpcount++] = *(SINT16 *)avalue[i];+	  break;+	case FFI_TYPE_UINT16:+	  stack->gp_regs[gpcount++] = *(UINT16 *)avalue[i];+	  break;+	case FFI_TYPE_SINT32:+	  stack->gp_regs[gpcount++] = *(SINT32 *)avalue[i];+	  break;+	case FFI_TYPE_UINT32:+	  stack->gp_regs[gpcount++] = *(UINT32 *)avalue[i];+	  break;+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	  stack->gp_regs[gpcount++] = *(UINT64 *)avalue[i];+	  break;++	case FFI_TYPE_POINTER:+	  stack->gp_regs[gpcount++] = (UINT64)(PTR64) *(void **)avalue[i];+	  break;++	case FFI_TYPE_FLOAT:+	  if (gpcount < 8 && fpcount < 8)+	    stf_spill (&stack->fp_regs[fpcount++], *(float *)avalue[i]);+	  {+	    UINT32 tmp;+	    memcpy (&tmp, avalue[i], sizeof (UINT32));+	    stack->gp_regs[gpcount++] = tmp;+	  }+	  break;++	case FFI_TYPE_DOUBLE:+	  if (gpcount < 8 && fpcount < 8)+	    stf_spill (&stack->fp_regs[fpcount++], *(double *)avalue[i]);+	  memcpy (&stack->gp_regs[gpcount++], avalue[i], sizeof (UINT64));+	  break;++	case FFI_TYPE_LONGDOUBLE:+	  if (gpcount & 1)+	    gpcount++;+	  if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)+	    stf_spill (&stack->fp_regs[fpcount++], *(__float80 *)avalue[i]);+	  memcpy (&stack->gp_regs[gpcount], avalue[i], 16);+	  gpcount += 2;+	  break;++	case FFI_TYPE_STRUCT:+	  {+	    size_t size = (*p_arg)->size;+	    size_t align = (*p_arg)->alignment;+	    int hfa_type = hfa_element_type (*p_arg, 0);++	    FFI_ASSERT (align <= 16);+	    if (align == 16 && (gpcount & 1))+	      gpcount++;++	    if (hfa_type != FFI_TYPE_VOID)+	      {+		size_t hfa_size = hfa_type_size (hfa_type);+		size_t offset = 0;+		size_t gp_offset = gpcount * 8;++		while (fpcount < 8+		       && offset < size+		       && gp_offset < 8 * 8)+		  {+		    hfa_type_load (&stack->fp_regs[fpcount], hfa_type,+				   avalue[i] + offset);+		    offset += hfa_size;+		    gp_offset += hfa_size;+		    fpcount += 1;+		  }+	      }++	    memcpy (&stack->gp_regs[gpcount], avalue[i], size);+	    gpcount += (size + 7) / 8;+	  }+	  break;++	default:+	  abort ();+	}+    }++  ffi_call_unix (stack, rvalue, fn, cif->flags);+}++/* Closures represent a pair consisting of a function pointer, and+   some user data.  A closure is invoked by reinterpreting the closure+   as a function pointer, and branching to it.  Thus we can make an+   interpreted function callable as a C function: We turn the+   interpreter itself, together with a pointer specifying the+   interpreted procedure, into a closure.++   For IA64, function pointer are already pairs consisting of a code+   pointer, and a gp pointer.  The latter is needed to access global+   variables.  Here we set up such a pair as the first two words of+   the closure (in the "trampoline" area), but we replace the gp+   pointer with a pointer to the closure itself.  We also add the real+   gp pointer to the closure.  This allows the function entry code to+   both retrieve the user data, and to restore the correct gp pointer.  */++extern void ffi_closure_unix ();++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif*,void*,void**,void*),+		      void *user_data,+		      void *codeloc)+{+  /* The layout of a function descriptor.  A C function pointer really +     points to one of these.  */+  struct ia64_fd+  {+    UINT64 code_pointer;+    UINT64 gp;+  };++  struct ffi_ia64_trampoline_struct+  {+    UINT64 code_pointer;	/* Pointer to ffi_closure_unix.  */+    UINT64 fake_gp;		/* Pointer to closure, installed as gp.  */+    UINT64 real_gp;		/* Real gp value.  */+  };++  struct ffi_ia64_trampoline_struct *tramp;+  struct ia64_fd *fd;++  if (cif->abi != FFI_UNIX)+    return FFI_BAD_ABI;++  tramp = (struct ffi_ia64_trampoline_struct *)closure->tramp;+  fd = (struct ia64_fd *)(void *)ffi_closure_unix;++  tramp->code_pointer = fd->code_pointer;+  tramp->real_gp = fd->gp;+  tramp->fake_gp = (UINT64)(PTR64)codeloc;+  closure->cif = cif;+  closure->user_data = user_data;+  closure->fun = fun;++  return FFI_OK;+}+++UINT64+ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,+			void *rvalue, void *r8)+{+  ffi_cif *cif;+  void **avalue;+  ffi_type **p_arg;+  long i, avn, gpcount, fpcount, nfixedargs;++  cif = closure->cif;+  avn = cif->nargs;+  nfixedargs = cif->nfixedargs;+  avalue = alloca (avn * sizeof (void *));++  /* If the structure return value is passed in memory get that location+     from r8 so as to pass the value directly back to the caller.  */+  if (cif->flags == FFI_TYPE_STRUCT)+    rvalue = r8;++  gpcount = fpcount = 0;+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)+    {+      int named = i < nfixedargs;+      switch ((*p_arg)->type)+	{+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 1);+	  break;+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 2);+	  break;+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], 4);+	  break;+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	  avalue[i] = &stack->gp_regs[gpcount++];+	  break;+	case FFI_TYPE_POINTER:+	  avalue[i] = endian_adjust(&stack->gp_regs[gpcount++], sizeof(void*));+	  break;++	case FFI_TYPE_FLOAT:+	  if (named && gpcount < 8 && fpcount < 8)+	    {+	      fpreg *addr = &stack->fp_regs[fpcount++];+	      float result;+	      avalue[i] = addr;+	      ldf_fill (result, addr);+	      *(float *)addr = result;+	    }+	  else+	    avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4);+	  gpcount++;+	  break;++	case FFI_TYPE_DOUBLE:+	  if (named && gpcount < 8 && fpcount < 8)+	    {+	      fpreg *addr = &stack->fp_regs[fpcount++];+	      double result;+	      avalue[i] = addr;+	      ldf_fill (result, addr);+	      *(double *)addr = result;+	    }+	  else+	    avalue[i] = &stack->gp_regs[gpcount];+	  gpcount++;+	  break;++	case FFI_TYPE_LONGDOUBLE:+	  if (gpcount & 1)+	    gpcount++;+	  if (LDBL_MANT_DIG == 64 && named && gpcount < 8 && fpcount < 8)+	    {+	      fpreg *addr = &stack->fp_regs[fpcount++];+	      __float80 result;+	      avalue[i] = addr;+	      ldf_fill (result, addr);+	      *(__float80 *)addr = result;+	    }+	  else+	    avalue[i] = &stack->gp_regs[gpcount];+	  gpcount += 2;+	  break;++	case FFI_TYPE_STRUCT:+	  {+	    size_t size = (*p_arg)->size;+	    size_t align = (*p_arg)->alignment;+	    int hfa_type = hfa_element_type (*p_arg, 0);++	    FFI_ASSERT (align <= 16);+	    if (align == 16 && (gpcount & 1))+	      gpcount++;++	    if (hfa_type != FFI_TYPE_VOID)+	      {+		size_t hfa_size = hfa_type_size (hfa_type);+		size_t offset = 0;+		size_t gp_offset = gpcount * 8;+		void *addr = alloca (size);++		avalue[i] = addr;++		while (fpcount < 8+		       && offset < size+		       && gp_offset < 8 * 8)+		  {+		    hfa_type_store (hfa_type, addr + offset,+				    &stack->fp_regs[fpcount]);+		    offset += hfa_size;+		    gp_offset += hfa_size;+		    fpcount += 1;+		  }++		if (offset < size)+		  memcpy (addr + offset, (char *)stack->gp_regs + gp_offset,+			  size - offset);+	      }+	    else+	      avalue[i] = &stack->gp_regs[gpcount];++	    gpcount += (size + 7) / 8;+	  }+	  break;++	default:+	  abort ();+	}+    }++  closure->fun (cif, rvalue, avalue, closure->user_data);++  return cif->flags;+}
+ src/ia64/ffitarget.h view
@@ -0,0 +1,56 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for IA-64.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long long          ffi_arg;+typedef signed long long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_UNIX,   	/* Linux and all Unix variants use the same conventions	*/+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_UNIX+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which 	*/+				/* can be interpreted as a C function	*/+				/* descriptor:				*/+#define FFI_TARGET_SPECIFIC_VARIADIC 1+#define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs++#endif
+ src/ia64/ia64_flags.h view
@@ -0,0 +1,40 @@+/* -----------------------------------------------------------------------+   ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company+   +   IA64/unix Foreign Function Interface ++   Original author: Hans Boehm, HP Labs++   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.+   ----------------------------------------------------------------------- */++/* "Type" codes used between assembly and C.  When used as a part of+   a cfi->flags value, the low byte will be these extra type codes,+   and bits 8-31 will be the actual size of the type.  */++/* Small structures containing N words in integer registers.  */+#define FFI_IA64_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 1)++/* Homogeneous Floating Point Aggregates (HFAs) which are returned+   in FP registers.  */+#define FFI_IA64_TYPE_HFA_FLOAT		(FFI_TYPE_LAST + 2)+#define FFI_IA64_TYPE_HFA_DOUBLE	(FFI_TYPE_LAST + 3)+#define FFI_IA64_TYPE_HFA_LDOUBLE	(FFI_TYPE_LAST + 4)
+ src/ia64/unix.S view
@@ -0,0 +1,585 @@+/* -----------------------------------------------------------------------+   unix.S - Copyright (c) 1998, 2008 Red Hat, Inc.+            Copyright (c) 2000 Hewlett Packard Company+   +   IA64/unix Foreign Function Interface ++   Primary author: Hans Boehm, HP Labs++   Loosely modeled on Cygnus code for other platforms.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>+#include "ia64_flags.h"++	.pred.safe_across_calls p1-p5,p16-p63+.text+/* HPUX assembler needs to see these symbols, otherwise compilation+   fails */+#ifdef __hpux+      .global memcpy+      .global ffi_closure_unix_inner+#endif++/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,+		      void (*fn)(void), int flags);+ */++        .align 16+        .global	ffi_call_unix+        .proc	ffi_call_unix+ffi_call_unix:+	.prologue+	/* Bit o trickiness.  We actually share a stack frame with ffi_call.+	   Rely on the fact that ffi_call uses a vframe and don't bother+	   tracking one here at all.  */+	.fframe	0+	.save	ar.pfs, r36 // loc0+	alloc   loc0 = ar.pfs, 4, 3, 8, 0+	.save	rp, loc1+	mov 	loc1 = b0+	.body+	add	r16 = 16, in0+	mov	loc2 = gp+	mov	r8 = in1+	;;++	/* Load up all of the argument registers.  */+	ldf.fill f8 = [in0], 32+	ldf.fill f9 = [r16], 32+	;;+	ldf.fill f10 = [in0], 32+	ldf.fill f11 = [r16], 32+	;;+	ldf.fill f12 = [in0], 32+	ldf.fill f13 = [r16], 32+	;;+	ldf.fill f14 = [in0], 32+	ldf.fill f15 = [r16], 24+	;;+	ld8	out0 = [in0], 16+	ld8	out1 = [r16], 16+	;;+	ld8	out2 = [in0], 16+	ld8	out3 = [r16], 16+	;;+	ld8	out4 = [in0], 16+	ld8	out5 = [r16], 16+	;;+	ld8	out6 = [in0]+	ld8	out7 = [r16]+	;;++	/* Deallocate the register save area from the stack frame.  */+	mov	sp = in0++	/* Call the target function.  */+	ld8	r16 = [in2], 8+	;;+	ld8	gp = [in2]+	mov	b6 = r16+	br.call.sptk.many b0 = b6+	;;++	/* Dispatch to handle return value.  */+	mov	gp = loc2+	zxt1	r16 = in3+	;;+	mov	ar.pfs = loc0+	addl	r18 = @ltoffx(.Lst_table), gp+	;;+	/* default assembler on HP-UX does not support LDXMOV */+#ifdef __hpux+	ld8	r18 = [r18]+#else+	ld8.mov	r18 = [r18], .Lst_table+#endif+	mov	b0 = loc1+	;;+	shladd	r18 = r16, 3, r18+	;;+	ld8	r17 = [r18]+	shr	in3 = in3, 8+	;;+	add	r17 = r17, r18+	;;+	mov	b6 = r17+	br	b6+	;;++.Lst_void:+	br.ret.sptk.many b0+	;;+.Lst_uint8:+	zxt1	r8 = r8+	;;+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_sint8:+	sxt1	r8 = r8+	;;+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_uint16:+	zxt2	r8 = r8+	;;+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_sint16:+	sxt2	r8 = r8+	;;+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_uint32:+	zxt4	r8 = r8+	;;+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_sint32:+	sxt4	r8 = r8+	;;+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_int64:+	st8	[in1] = r8+	br.ret.sptk.many b0+	;;+.Lst_float:+	stfs	[in1] = f8+	br.ret.sptk.many b0+	;;+.Lst_double:+	stfd	[in1] = f8+	br.ret.sptk.many b0+	;;+.Lst_ldouble:+	stfe	[in1] = f8+	br.ret.sptk.many b0+	;;++.Lst_small_struct:+	cmp.lt	p6, p0 = 8, in3+	cmp.lt	p7, p0 = 16, in3+	cmp.lt	p8, p0 = 24, in3+	;;+	add	r16 = 8, sp+	add	r17 = 16, sp+	add	r18 = 24, sp+	;;+	st8	[sp] = r8+(p6)	st8	[r16] = r9+	mov	out0 = in1+(p7)	st8	[r17] = r10+(p8)	st8	[r18] = r11+	mov	out1 = sp+	mov	out2 = in3+	;;+	// ia64 software calling convention requires+	// top 16 bytes of stack to be scratch space+	// PLT resolver uses that scratch space at+	// 'memcpy' symbol reolution time+	add	sp = -16, sp+	br.call.sptk.many b0 = memcpy#+	;;+	mov	ar.pfs = loc0+	mov	b0 = loc1+	mov	gp = loc2+	br.ret.sptk.many b0++.Lst_hfa_float:+	add	r16 = 4, in1+	cmp.lt	p6, p0 = 4, in3+	;;+	stfs	[in1] = f8, 8+(p6)	stfs	[r16] = f9, 8+	cmp.lt	p7, p0 = 8, in3+	cmp.lt	p8, p0 = 12, in3+	;;+(p7)	stfs	[in1] = f10, 8+(p8)	stfs	[r16] = f11, 8+	cmp.lt	p9, p0 = 16, in3+	cmp.lt	p10, p0 = 20, in3+	;;+(p9)	stfs	[in1] = f12, 8+(p10)	stfs	[r16] = f13, 8+	cmp.lt	p6, p0 = 24, in3+	cmp.lt	p7, p0 = 28, in3+	;;+(p6)	stfs	[in1] = f14+(p7)	stfs	[r16] = f15+	br.ret.sptk.many b0+	;;++.Lst_hfa_double:+	add	r16 = 8, in1+	cmp.lt	p6, p0 = 8, in3+	;;+	stfd	[in1] = f8, 16+(p6)	stfd	[r16] = f9, 16+	cmp.lt	p7, p0 = 16, in3+	cmp.lt	p8, p0 = 24, in3+	;;+(p7)	stfd	[in1] = f10, 16+(p8)	stfd	[r16] = f11, 16+	cmp.lt	p9, p0 = 32, in3+	cmp.lt	p10, p0 = 40, in3+	;;+(p9)	stfd	[in1] = f12, 16+(p10)	stfd	[r16] = f13, 16+	cmp.lt	p6, p0 = 48, in3+	cmp.lt	p7, p0 = 56, in3+	;;+(p6)	stfd	[in1] = f14+(p7)	stfd	[r16] = f15+	br.ret.sptk.many b0+	;;++.Lst_hfa_ldouble:+	add	r16 = 16, in1+	cmp.lt	p6, p0 = 16, in3+	;;+	stfe	[in1] = f8, 32+(p6)	stfe	[r16] = f9, 32+	cmp.lt	p7, p0 = 32, in3+	cmp.lt	p8, p0 = 48, in3+	;;+(p7)	stfe	[in1] = f10, 32+(p8)	stfe	[r16] = f11, 32+	cmp.lt	p9, p0 = 64, in3+	cmp.lt	p10, p0 = 80, in3+	;;+(p9)	stfe	[in1] = f12, 32+(p10)	stfe	[r16] = f13, 32+	cmp.lt	p6, p0 = 96, in3+	cmp.lt	p7, p0 = 112, in3+	;;+(p6)	stfe	[in1] = f14+(p7)	stfe	[r16] = f15+	br.ret.sptk.many b0+	;;++        .endp ffi_call_unix++        .align 16+        .global ffi_closure_unix+        .proc ffi_closure_unix++#define FRAME_SIZE	(8*16 + 8*8 + 8*16)++ffi_closure_unix:+	.prologue+	.save	ar.pfs, r40 // loc0+	alloc   loc0 = ar.pfs, 8, 4, 4, 0+	.fframe	FRAME_SIZE+	add	r12 = -FRAME_SIZE, r12+	.save	rp, loc1+	mov	loc1 = b0+	.save	ar.unat, loc2+	mov	loc2 = ar.unat+	.body++	/* Retrieve closure pointer and real gp.  */+#ifdef _ILP32+	addp4	out0 = 0, gp+	addp4	gp = 16, gp+#else+	mov	out0 = gp+	add	gp = 16, gp+#endif+	;;+	ld8	gp = [gp]++	/* Spill all of the possible argument registers.  */+	add	r16 = 16 + 8*16, sp+	add	r17 = 16 + 8*16 + 16, sp+	;;+	stf.spill [r16] = f8, 32+	stf.spill [r17] = f9, 32+	mov	loc3 = gp+	;;+	stf.spill [r16] = f10, 32+	stf.spill [r17] = f11, 32+	;;+	stf.spill [r16] = f12, 32+	stf.spill [r17] = f13, 32+	;;+	stf.spill [r16] = f14, 32+	stf.spill [r17] = f15, 24+	;;+	.mem.offset 0, 0+	st8.spill [r16] = in0, 16+	.mem.offset 8, 0+	st8.spill [r17] = in1, 16+	add	out1 = 16 + 8*16, sp+	;;+	.mem.offset 0, 0+	st8.spill [r16] = in2, 16+	.mem.offset 8, 0+	st8.spill [r17] = in3, 16+	add	out2 = 16, sp+	;;+	.mem.offset 0, 0+	st8.spill [r16] = in4, 16+	.mem.offset 8, 0+	st8.spill [r17] = in5, 16+	mov	out3 = r8+	;;+	.mem.offset 0, 0+	st8.spill [r16] = in6+	.mem.offset 8, 0+	st8.spill [r17] = in7++	/* Invoke ffi_closure_unix_inner for the hard work.  */+	br.call.sptk.many b0 = ffi_closure_unix_inner+	;;++	/* Dispatch to handle return value.  */+	mov	gp = loc3+	zxt1	r16 = r8+	;;+	addl	r18 = @ltoffx(.Lld_table), gp+	mov	ar.pfs = loc0+	;;+#ifdef __hpux+	ld8	r18 = [r18]+#else+	ld8.mov	r18 = [r18], .Lst_table+#endif+	mov	b0 = loc1+	;;+	shladd	r18 = r16, 3, r18+	mov	ar.unat = loc2+	;;+	ld8	r17 = [r18]+	shr	r8 = r8, 8+	;;+	add	r17 = r17, r18+	add	r16 = 16, sp+	;;+	mov	b6 = r17+	br	b6+	;;+	.label_state 1++.Lld_void:+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;+.Lld_int:+	.body+	.copy_state 1+	ld8	r8 = [r16]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;+.Lld_float:+	.body+	.copy_state 1+	ldfs	f8 = [r16]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;+.Lld_double:+	.body+	.copy_state 1+	ldfd	f8 = [r16]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;+.Lld_ldouble:+	.body+	.copy_state 1+	ldfe	f8 = [r16]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;++.Lld_small_struct:+	.body+	.copy_state 1+	add	r17 = 8, r16+	cmp.lt	p6, p0 = 8, r8+	cmp.lt	p7, p0 = 16, r8+	cmp.lt	p8, p0 = 24, r8+	;;+	ld8	r8 = [r16], 16+(p6)	ld8	r9 = [r17], 16+	;;+(p7)	ld8	r10 = [r16]+(p8)	ld8	r11 = [r17]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;++.Lld_hfa_float:+	.body+	.copy_state 1+	add	r17 = 4, r16+	cmp.lt	p6, p0 = 4, r8+	;;+	ldfs	f8 = [r16], 8+(p6)	ldfs	f9 = [r17], 8+	cmp.lt	p7, p0 = 8, r8+	cmp.lt	p8, p0 = 12, r8+	;;+(p7)	ldfs	f10 = [r16], 8+(p8)	ldfs	f11 = [r17], 8+	cmp.lt	p9, p0 = 16, r8+	cmp.lt	p10, p0 = 20, r8+	;;+(p9)	ldfs	f12 = [r16], 8+(p10)	ldfs	f13 = [r17], 8+	cmp.lt	p6, p0 = 24, r8+	cmp.lt	p7, p0 = 28, r8+	;;+(p6)	ldfs	f14 = [r16]+(p7)	ldfs	f15 = [r17]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;++.Lld_hfa_double:+	.body+	.copy_state 1+	add	r17 = 8, r16+	cmp.lt	p6, p0 = 8, r8+	;;+	ldfd	f8 = [r16], 16+(p6)	ldfd	f9 = [r17], 16+	cmp.lt	p7, p0 = 16, r8+	cmp.lt	p8, p0 = 24, r8+	;;+(p7)	ldfd	f10 = [r16], 16+(p8)	ldfd	f11 = [r17], 16+	cmp.lt	p9, p0 = 32, r8+	cmp.lt	p10, p0 = 40, r8+	;;+(p9)	ldfd	f12 = [r16], 16+(p10)	ldfd	f13 = [r17], 16+	cmp.lt	p6, p0 = 48, r8+	cmp.lt	p7, p0 = 56, r8+	;;+(p6)	ldfd	f14 = [r16]+(p7)	ldfd	f15 = [r17]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;++.Lld_hfa_ldouble:+	.body+	.copy_state 1+	add	r17 = 16, r16+	cmp.lt	p6, p0 = 16, r8+	;;+	ldfe	f8 = [r16], 32+(p6)	ldfe	f9 = [r17], 32+	cmp.lt	p7, p0 = 32, r8+	cmp.lt	p8, p0 = 48, r8+	;;+(p7)	ldfe	f10 = [r16], 32+(p8)	ldfe	f11 = [r17], 32+	cmp.lt	p9, p0 = 64, r8+	cmp.lt	p10, p0 = 80, r8+	;;+(p9)	ldfe	f12 = [r16], 32+(p10)	ldfe	f13 = [r17], 32+	cmp.lt	p6, p0 = 96, r8+	cmp.lt	p7, p0 = 112, r8+	;;+(p6)	ldfe	f14 = [r16]+(p7)	ldfe	f15 = [r17]+	.restore sp+	add	sp = FRAME_SIZE, sp+	br.ret.sptk.many b0+	;;++	.endp	ffi_closure_unix+#ifdef __hpux+	.rodata+#else+	.section .rodata+#endif+	.align	8+.Lst_table:+	data8	@pcrel(.Lst_void)		// FFI_TYPE_VOID+	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_INT+	data8	@pcrel(.Lst_float)		// FFI_TYPE_FLOAT+	data8	@pcrel(.Lst_double)		// FFI_TYPE_DOUBLE+	data8	@pcrel(.Lst_ldouble)		// FFI_TYPE_LONGDOUBLE+	data8	@pcrel(.Lst_uint8)		// FFI_TYPE_UINT8+	data8	@pcrel(.Lst_sint8)		// FFI_TYPE_SINT8+	data8	@pcrel(.Lst_uint16)		// FFI_TYPE_UINT16+	data8	@pcrel(.Lst_sint16)		// FFI_TYPE_SINT16+	data8	@pcrel(.Lst_uint32)		// FFI_TYPE_UINT32+	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_SINT32+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_UINT64+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_SINT64+	data8	@pcrel(.Lst_void)		// FFI_TYPE_STRUCT+	data8	@pcrel(.Lst_int64)		// FFI_TYPE_POINTER+	data8	@pcrel(.Lst_void)		// FFI_TYPE_COMPLEX (not implemented)+	data8 	@pcrel(.Lst_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT+	data8	@pcrel(.Lst_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT+	data8	@pcrel(.Lst_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE+	data8	@pcrel(.Lst_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE++.Lld_table:+	data8	@pcrel(.Lld_void)		// FFI_TYPE_VOID+	data8	@pcrel(.Lld_int)		// FFI_TYPE_INT+	data8	@pcrel(.Lld_float)		// FFI_TYPE_FLOAT+	data8	@pcrel(.Lld_double)		// FFI_TYPE_DOUBLE+	data8	@pcrel(.Lld_ldouble)		// FFI_TYPE_LONGDOUBLE+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT8+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT8+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT16+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT16+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT32+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT32+	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT64+	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT64+	data8	@pcrel(.Lld_void)		// FFI_TYPE_STRUCT+	data8	@pcrel(.Lld_int)		// FFI_TYPE_POINTER+	data8	@pcrel(.Lld_void)		// FFI_TYPE_COMPLEX (not implemented)+	data8 	@pcrel(.Lld_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT+	data8	@pcrel(.Lld_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT+	data8	@pcrel(.Lld_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE+	data8	@pcrel(.Lld_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/java_raw_api.c view
@@ -0,0 +1,374 @@+/* -----------------------------------------------------------------------+   java_raw_api.c - Copyright (c) 1999, 2007, 2008  Red Hat, Inc.++   Cloned from raw_api.c++   Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>+   Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>++   $Id $++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++/* This defines a Java- and 64-bit specific variant of the raw API.	*/+/* It assumes that "raw" argument blocks look like Java stacks on a	*/+/* 64-bit machine.  Arguments that can be stored in a single stack	*/+/* stack slots (longs, doubles) occupy 128 bits, but only the first	*/+/* 64 bits are actually used.						*/++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>++#if !defined(NO_JAVA_RAW_API)++size_t+ffi_java_raw_size (ffi_cif *cif)+{+  size_t result = 0;+  int i;++  ffi_type **at = cif->arg_types;++  for (i = cif->nargs-1; i >= 0; i--, at++)+    {+      switch((*at) -> type) {+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_DOUBLE:+	  result += 2 * FFI_SIZEOF_JAVA_RAW;+	  break;+	case FFI_TYPE_STRUCT:+	  /* No structure parameters in Java.	*/+	  abort();+	case FFI_TYPE_COMPLEX:+	  /* Not supported yet.  */+	  abort();+	default:+	  result += FFI_SIZEOF_JAVA_RAW;+      }+    }++  return result;+}+++void+ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)+{+  unsigned i;+  ffi_type **tp = cif->arg_types;++#if WORDS_BIGENDIAN++  for (i = 0; i < cif->nargs; i++, tp++, args++)+    {+      switch ((*tp)->type)+	{+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	  *args = (void*) ((char*)(raw++) + 3);+	  break;++	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	  *args = (void*) ((char*)(raw++) + 2);+	  break;++#if FFI_SIZEOF_JAVA_RAW == 8+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_DOUBLE:+	  *args = (void *)raw;+	  raw += 2;+	  break;+#endif++	case FFI_TYPE_POINTER:+	  *args = (void*) &(raw++)->ptr;+	  break;++	case FFI_TYPE_COMPLEX:+	  /* Not supported yet.  */+	  abort();++	default:+	  *args = raw;+	  raw +=+	    FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);+	}+    }++#else /* WORDS_BIGENDIAN */++#if !PDP++  /* then assume little endian */+  for (i = 0; i < cif->nargs; i++, tp++, args++)+    {+#if FFI_SIZEOF_JAVA_RAW == 8+      switch((*tp)->type) {+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_DOUBLE:+	  *args = (void*) raw;+	  raw += 2;+	  break;+	case FFI_TYPE_COMPLEX:+	  /* Not supported yet.  */+	  abort();+	default:+	  *args = (void*) raw++;+      }+#else /* FFI_SIZEOF_JAVA_RAW != 8 */+	*args = (void*) raw;+	raw +=+	  FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);+#endif /* FFI_SIZEOF_JAVA_RAW == 8 */+    }++#else+#error "pdp endian not supported"+#endif /* ! PDP */++#endif /* WORDS_BIGENDIAN */+}++void+ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)+{+  unsigned i;+  ffi_type **tp = cif->arg_types;++  for (i = 0; i < cif->nargs; i++, tp++, args++)+    {+      switch ((*tp)->type)+	{+	case FFI_TYPE_UINT8:+#if WORDS_BIGENDIAN+	  *(UINT32*)(raw++) = *(UINT8*) (*args);+#else+	  (raw++)->uint = *(UINT8*) (*args);+#endif+	  break;++	case FFI_TYPE_SINT8:+#if WORDS_BIGENDIAN+	  *(SINT32*)(raw++) = *(SINT8*) (*args);+#else+	  (raw++)->sint = *(SINT8*) (*args);+#endif+	  break;++	case FFI_TYPE_UINT16:+#if WORDS_BIGENDIAN+	  *(UINT32*)(raw++) = *(UINT16*) (*args);+#else+	  (raw++)->uint = *(UINT16*) (*args);+#endif+	  break;++	case FFI_TYPE_SINT16:+#if WORDS_BIGENDIAN+	  *(SINT32*)(raw++) = *(SINT16*) (*args);+#else+	  (raw++)->sint = *(SINT16*) (*args);+#endif+	  break;++	case FFI_TYPE_UINT32:+#if WORDS_BIGENDIAN+	  *(UINT32*)(raw++) = *(UINT32*) (*args);+#else+	  (raw++)->uint = *(UINT32*) (*args);+#endif+	  break;++	case FFI_TYPE_SINT32:+#if WORDS_BIGENDIAN+	  *(SINT32*)(raw++) = *(SINT32*) (*args);+#else+	  (raw++)->sint = *(SINT32*) (*args);+#endif+	  break;++	case FFI_TYPE_FLOAT:+	  (raw++)->flt = *(FLOAT32*) (*args);+	  break;++#if FFI_SIZEOF_JAVA_RAW == 8+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_DOUBLE:+	  raw->uint = *(UINT64*) (*args);+	  raw += 2;+	  break;+#endif++	case FFI_TYPE_POINTER:+	  (raw++)->ptr = **(void***) args;+	  break;++	default:+#if FFI_SIZEOF_JAVA_RAW == 8+	  FFI_ASSERT(0);	/* Should have covered all cases */+#else+	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);+	  raw +=+	    FFI_ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);+#endif+	}+    }+}++#if !FFI_NATIVE_RAW_API++static void+ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)+{+#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8+  switch (cif->rtype->type)+    {+    case FFI_TYPE_UINT8:+    case FFI_TYPE_UINT16:+    case FFI_TYPE_UINT32:+      *(UINT64 *)rvalue <<= 32;+      break;++    case FFI_TYPE_SINT8:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_INT:+#if FFI_SIZEOF_JAVA_RAW == 4+    case FFI_TYPE_POINTER:+#endif+      *(SINT64 *)rvalue <<= 32;+      break;++    case FFI_TYPE_COMPLEX:+      /* Not supported yet.  */+      abort();++    default:+      break;+    }+#endif+}++static void+ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)+{+#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8+  switch (cif->rtype->type)+    {+    case FFI_TYPE_UINT8:+    case FFI_TYPE_UINT16:+    case FFI_TYPE_UINT32:+      *(UINT64 *)rvalue >>= 32;+      break;++    case FFI_TYPE_SINT8:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_INT:+      *(SINT64 *)rvalue >>= 32;+      break;++    case FFI_TYPE_COMPLEX:+      /* Not supported yet.  */+      abort();++    default:+      break;+    }+#endif+}++/* This is a generic definition of ffi_raw_call, to be used if the+ * native system does not provide a machine-specific implementation.+ * Having this, allows code to be written for the raw API, without+ * the need for system-specific code to handle input in that format;+ * these following couple of functions will handle the translation forth+ * and back automatically. */++void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,+			ffi_java_raw *raw)+{+  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));+  ffi_java_raw_to_ptrarray (cif, raw, avalue);+  ffi_call (cif, fn, rvalue, avalue);+  ffi_java_rvalue_to_raw (cif, rvalue);+}++#if FFI_CLOSURES		/* base system provides closures */++static void+ffi_java_translate_args (ffi_cif *cif, void *rvalue,+		    void **avalue, void *user_data)+{+  ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));+  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;++  ffi_java_ptrarray_to_raw (cif, avalue, raw);+  (*cl->fun) (cif, rvalue, (ffi_raw*)raw, cl->user_data);+  ffi_java_raw_to_rvalue (cif, rvalue);+}++ffi_status+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,+			       ffi_cif *cif,+			       void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),+			       void *user_data,+			       void *codeloc)+{+  ffi_status status;++  status = ffi_prep_closure_loc ((ffi_closure*) cl,+				 cif,+				 &ffi_java_translate_args,+				 codeloc,+				 codeloc);+  if (status == FFI_OK)+    {+      cl->fun       = fun;+      cl->user_data = user_data;+    }++  return status;+}++/* Again, here is the generic version of ffi_prep_raw_closure, which+ * will install an intermediate "hub" for translation of arguments from+ * the pointer-array format, to the raw format */++ffi_status+ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,+			   ffi_cif *cif,+			   void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),+			   void *user_data)+{+  return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);+}++#endif /* FFI_CLOSURES */+#endif /* !FFI_NATIVE_RAW_API */+#endif /* !NO_JAVA_RAW_API */
+ src/kvx/asm.h view
@@ -0,0 +1,5 @@+/* args are passed on registers from r0 up to r11 => 12*8 bytes */+#define REG_ARGS_SIZE (12*8)+#define KVX_REGISTER_SIZE (8)+#define KVX_ABI_SLOT_SIZE (KVX_REGISTER_SIZE)+#define KVX_ABI_MAX_AGGREGATE_IN_REG_SIZE (4*KVX_ABI_SLOT_SIZE)
+ src/kvx/ffi.c view
@@ -0,0 +1,273 @@+/* Copyright (c) 2020 Kalray++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#if defined(__kvx__)+#include <stdio.h>+#include <stdlib.h>+#include <stdint.h>+#include <fficonfig.h>+#include <ffi.h>+#include "ffi_common.h"+#include "asm.h"++#define ALIGN(x, a) ALIGN_MASK(x, (typeof(x))(a) - 1)+#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))+#define KVX_ABI_STACK_ALIGNMENT (32)+#define KVX_ABI_STACK_ARG_ALIGNMENT (8)+#define max(a,b) ((a) > (b) ? (a) : (b))++#ifdef FFI_DEBUG+#define DEBUG_PRINT(...) do{ fprintf( stderr, __VA_ARGS__ ); } while(0)+#else+#define DEBUG_PRINT(...)+#endif++struct ret_value {+	unsigned long int r0;+	unsigned long int r1;+	unsigned long int r2;+	unsigned long int r3;+};++extern struct ret_value ffi_call_SYSV(unsigned total_size,+                                      unsigned size,+                                      extended_cif *ecif,+                                      unsigned *rvalue_addr,+                                      void *fn,+                                      unsigned int_ext_method);++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+  cif->flags = cif->rtype->size;+  return FFI_OK;+}++/* 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, unsigned int arg_slots_size, extended_cif *ecif)+{+  char *stacktemp = stack;+  char *current_arg_passed_by_value = stack + arg_slots_size;+  int i, s;+  ffi_type **arg;+  int count = 0;+  ffi_cif *cif = ecif->cif;+  void **argv = ecif->avalue;++  arg = cif->arg_types;++  DEBUG_PRINT("stack: %p\n", stack);+  DEBUG_PRINT("arg_slots_size: %u\n", arg_slots_size);+  DEBUG_PRINT("current_arg_passed_by_value: %p\n", current_arg_passed_by_value);+  DEBUG_PRINT("ecif: %p\n", ecif);+  DEBUG_PRINT("ecif->avalue: %p\n", ecif->avalue);++  for (i = 0; i < cif->nargs; i++) {++    s = KVX_ABI_SLOT_SIZE;+    switch((*arg)->type) {+      case FFI_TYPE_SINT8:+      case FFI_TYPE_UINT8:+      case FFI_TYPE_SINT16:+      case FFI_TYPE_UINT16:+      case FFI_TYPE_SINT32:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_FLOAT:+      case FFI_TYPE_DOUBLE:+      case FFI_TYPE_UINT64:+      case FFI_TYPE_SINT64:+      case FFI_TYPE_POINTER:+        DEBUG_PRINT("INT64/32/16/8/FLOAT/DOUBLE or POINTER @%p\n", stack);+        *(uint64_t *) stack = *(uint64_t *)(* argv);+        break;++      case FFI_TYPE_COMPLEX:+        if ((*arg)->size == 8)+          *(_Complex float *) stack = *(_Complex float *)(* argv);+        else if ((*arg)->size == 16) {+          *(_Complex double *) stack = *(_Complex double *)(* argv);+          s = 16;+        } else+          abort();+        break;+      case FFI_TYPE_STRUCT: {+        char *value;+        unsigned int written_size = 0;+        DEBUG_PRINT("struct by value @%p\n", stack);+        if ((*arg)->size > KVX_ABI_MAX_AGGREGATE_IN_REG_SIZE) {+          DEBUG_PRINT("big struct\n");+          *(uint64_t *) stack = (uintptr_t)current_arg_passed_by_value;+          value = current_arg_passed_by_value;+          current_arg_passed_by_value += (*arg)->size;+          written_size = KVX_ABI_SLOT_SIZE;+        } else {+          value = stack;+          written_size = (*arg)->size;+        }+        memcpy(value, *argv, (*arg)->size);+        s = ALIGN(written_size, KVX_ABI_STACK_ARG_ALIGNMENT);+        break;+      }+      default:+        printf("Error: unsupported arg type %d\n", (*arg)->type);+        abort();+        break;++    }+    stack += s;+    count += s;+    argv++;+    arg++;+  }+#ifdef FFI_DEBUG+  FFI_ASSERT(((intptr_t)(stacktemp + REG_ARGS_SIZE) & (KVX_ABI_STACK_ALIGNMENT-1)) == 0);+#endif+  return stacktemp + REG_ARGS_SIZE;+}++/* Perform machine dependent cif processing when we have a variadic function */++ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,+                                    unsigned int ntotalargs)+{+  cif->flags = cif->rtype->size;+  return FFI_OK;+}++static unsigned long handle_small_int_ext(kvx_intext_method *int_ext_method,+                                          const ffi_type *rtype)+{+  switch (rtype->type) {+    case FFI_TYPE_SINT8:+      *int_ext_method = KVX_RET_SXBD;+      return KVX_REGISTER_SIZE;++    case FFI_TYPE_SINT16:+      *int_ext_method = KVX_RET_SXHD;+      return KVX_REGISTER_SIZE;++    case FFI_TYPE_SINT32:+      *int_ext_method = KVX_RET_SXWD;+      return KVX_REGISTER_SIZE;++    case FFI_TYPE_UINT8:+      *int_ext_method = KVX_RET_ZXBD;+      return KVX_REGISTER_SIZE;++    case FFI_TYPE_UINT16:+      *int_ext_method = KVX_RET_ZXHD;+      return KVX_REGISTER_SIZE;++    case FFI_TYPE_UINT32:+      *int_ext_method = KVX_RET_ZXWD;+      return KVX_REGISTER_SIZE;++    default:+      *int_ext_method = KVX_RET_NONE;+      return rtype->size;+  }+}++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  int i;+  unsigned long int slot_fitting_args_size = 0;+  unsigned long int total_size = 0;+  unsigned long int big_struct_size = 0;+  kvx_intext_method int_extension_method;+  ffi_type **arg;+  struct ret_value local_rvalue = {0};+  size_t wb_size;+++  /* Calculate size to allocate on stack */+  for (i = 0, arg = cif->arg_types; i < cif->nargs; i++, arg++) {+    DEBUG_PRINT("argument %d, type %d, size %lu\n", i, (*arg)->type, (*arg)->size);+    if (((*arg)->type == FFI_TYPE_STRUCT) || ((*arg)->type == FFI_TYPE_COMPLEX)) {+      if ((*arg)->size <= KVX_ABI_MAX_AGGREGATE_IN_REG_SIZE) {+        slot_fitting_args_size += ALIGN((*arg)->size, KVX_ABI_SLOT_SIZE);+      } else {+        slot_fitting_args_size += KVX_ABI_SLOT_SIZE; /* aggregate passed by reference */+        big_struct_size += ALIGN((*arg)->size, KVX_ABI_SLOT_SIZE);+      }+    } else if ((*arg)->size <= KVX_ABI_SLOT_SIZE) {+      slot_fitting_args_size += KVX_ABI_SLOT_SIZE;+    } else {+      printf("Error: unsupported arg size %ld arg type %d\n", (*arg)->size, (*arg)->type);+      abort(); /* should never happen? */+    }+  }++  extended_cif ecif;+  ecif.cif = cif;+  ecif.avalue = avalue;+  ecif.rvalue = rvalue;++  /* This implementation allocates anyway for all register based args */+  slot_fitting_args_size = max(slot_fitting_args_size, REG_ARGS_SIZE);+  total_size = slot_fitting_args_size + big_struct_size;+  total_size = ALIGN(total_size, KVX_ABI_STACK_ALIGNMENT);++  /* wb_size: write back size, the size we will need to write back to user+   * provided buffer. In theory it should always be cif->flags which is+   * cif->rtype->size. But libffi API mandates that for integral types+   * of size <= system register size, then we *MUST* write back+   * the size of system register size.+   * in our case, if size <= 8 bytes we must write back 8 bytes.+   * floats, complex and structs are not affected, only integrals.+   */+  wb_size = handle_small_int_ext(&int_extension_method, cif->rtype);++  switch (cif->abi) {+    case FFI_SYSV:+      DEBUG_PRINT("total_size: %lu\n", total_size);+      DEBUG_PRINT("slot fitting args size: %lu\n", slot_fitting_args_size);+      DEBUG_PRINT("rvalue: %p\n", rvalue);+      DEBUG_PRINT("fn: %p\n", fn);+      DEBUG_PRINT("rsize: %u\n", cif->flags);+      DEBUG_PRINT("wb_size: %u\n", wb_size);+      DEBUG_PRINT("int_extension_method: %u\n", int_extension_method);+      local_rvalue = ffi_call_SYSV(total_size, slot_fitting_args_size,+                                   &ecif, rvalue, fn, int_extension_method);+      if ((cif->flags <= KVX_ABI_MAX_AGGREGATE_IN_REG_SIZE)+          && (cif->rtype->type != FFI_TYPE_VOID))+        memcpy(rvalue, &local_rvalue, wb_size);+      break;+    default:+      abort();+      break;+  }+}++/* Closures not supported yet */+ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+                      ffi_cif* cif,+                      void (*fun)(ffi_cif*,void*,void**,void*),+                      void *user_data,+                      void *codeloc)+{+  return FFI_BAD_ABI;+}++#endif /* (__kvx__) */
+ src/kvx/ffitarget.h view
@@ -0,0 +1,75 @@+/* -----------------------------------------------------------------------+   ffitarget.h - Copyright (c) 2020 Kalray++   KVX Target configuration macros++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;++/* Those values are set depending on return type+ * they are used in the assembly code in sysv.S+ */+typedef enum kvx_intext_method {+  KVX_RET_NONE = 0,+  KVX_RET_SXBD = 1,+  KVX_RET_SXHD = 2,+  KVX_RET_SXWD = 3,+  KVX_RET_ZXBD = 4,+  KVX_RET_ZXHD = 5,+  KVX_RET_ZXWD = 6+} kvx_intext_method;++#endif++/* ---- Definitions for closures ----------------------------------------- */++/* This is only to allow Python to compile+ * but closures are not supported yet+ */+#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 0++#define FFI_NATIVE_RAW_API 0+#define FFI_TARGET_SPECIFIC_VARIADIC 1+#define FFI_TARGET_HAS_COMPLEX_TYPE++#endif+
+ src/kvx/sysv.S view
@@ -0,0 +1,127 @@+/* Copyright (c) 2020 Kalray++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+``Software''), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */++#if defined(__kvx__)+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include <kvx/asm.h>++.text+.global ffi_call_SYSV+.type ffi_call_SYSV, @function+.type ffi_prep_args, @function+.align 8++/* ffi_call_SYSV++  r0: total size to allocate on stack+  r1: size of arg slots+  r2: extended cif structure, DO NOT REMOVE: it is used by ffi_prep_args()+  r3: return value address+  r4: function to call+  r5: integer sign extension method to be used+*/+ffi_call_SYSV:+	addd $r12 = $r12, -64+	so (-32)[$r12] = $r20r21r22r23+	;;+	sd (0)[$r12] = $r24+	;;+	get $r23 = $ra+	copyd $r20 = $r12+	sbfd $r12 = $r0, $r12+	;;+	copyd $r0 = $r12+	copyd $r21 = $r3+	copyd $r22 = $r4+	copyd $r24 = $r5+	call ffi_prep_args+	;;+	lo $r8r9r10r11 = (64)[$r12]+	;;+	lo $r4r5r6r7 = (32)[$r12]+	;;+	lo $r0r1r2r3 = (0)[$r12]+	copyd $r12 = $r0+	/* $r15 is the register used by the ABI to return big (>32 bytes)+	 * structs by value.+	 * It is also referred to as the "struct register" in the ABI.+	 */+	copyd $r15 = $r21+	icall $r22+	;;+	pcrel $r4 = @pcrel(.Ltable)+	cb.deqz $r24 ? .Lend+	;;+	addx8d $r24 = $r24, $r4+	;;+	igoto $r24+	;;+.Ltable:+0: /* we should never arrive here */+	goto .Lerror+	nop+	;;+1: /* Sign extend byte to double */+	sxbd $r0 = $r0+	goto .Lend+	;;+2: /* Sign extend half to double */+	sxhd $r0 = $r0+	goto .Lend+	;;+3: /* Sign extend word to double */+	sxwd $r0 = $r0+	goto .Lend+	;;+4: /* Zero extend byte to double */+	zxbd $r0 = $r0+	goto .Lend+	;;+5: /* Zero extend half to double */+	zxhd $r0 = $r0+	goto .Lend+	;;+6: /* Zero extend word to double */+	zxwd $r0 = $r0+	/* Fallthrough to .Lend */+	;;+.Lend:+	ld $r24 = (0)[$r12]+	;;+	set $ra = $r23+	lo $r20r21r22r23 = (32)[$r20]+	addd $r12 = $r20, 64+	;;+	ret+	;;+.Lerror:+	errop+	;;++#endif /* __kvx__ */++#if defined __ELF__ && defined __linux__+	.section .note.GNU-stack,"",%progbits+#endif+
+ src/loongarch64/ffi.c view
@@ -0,0 +1,624 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>+                         2022 Cheng Lulu <chenglulu@loongson.cn>+   Based on RISC-V port++   LoongArch 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 <tramp.h>++#include <stdlib.h>+#include <stdint.h>++#if defined(__loongarch_soft_float)+# define ABI_FRLEN 0+#elif defined(__loongarch_single_float)+# define ABI_FRLEN 32+# define ABI_FLOAT float+#elif defined(__loongarch_double_float)+# define ABI_FRLEN 64+# define ABI_FLOAT double+#else+#error unsupported LoongArch floating-point ABI+#endif++#define NARGREG 8+#define STKALIGN 16+#define MAXCOPYARG (2 * sizeof (double))++/* call_context registers+   - 8 floating point parameter/result registers.+   - 8 integer parameter/result registers.+   - 2 registers used by the assembly code to in-place construct its own+     stack frame+     - frame register+     - return register+*/+typedef struct call_context+{+#if !defined(__loongarch_soft_float)+  ABI_FLOAT fa[8];+#endif+  size_t a[10];+} call_context;++typedef struct call_builder+{+  call_context *aregs;+  int used_integer;+  int used_float;+  size_t *used_stack;+  size_t *stack;+  size_t next_struct_area;+} call_builder;++/* Integer (not pointer) less than ABI GRLEN.  */+/* FFI_TYPE_INT does not appear to be used.  */+#if __SIZEOF_POINTER__ == 8+# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)+#else+# define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)+#endif++#if ABI_FRLEN+typedef struct float_struct_info+{+  char as_elements;+  char type1;+  char offset2;+  char type2;+} float_struct_info;++#if ABI_FRLEN >= 64+# define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE)+#else+# define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT)+#endif++static ffi_type **+flatten_struct (ffi_type *in, ffi_type **out, ffi_type **out_end)+{+  int i;++  if (out == out_end)+    return out;+  if (in->type != FFI_TYPE_STRUCT)+    *(out++) = in;+  else+    for (i = 0; in->elements[i]; i++)+      out = flatten_struct (in->elements[i], out, out_end);+  return out;+}++/* Structs with at most two fields after flattening, one of which is of+   floating point type, are passed in multiple registers if sufficient+   registers are available.  */+static float_struct_info+struct_passed_as_elements (call_builder *cb, ffi_type *top)+{+  float_struct_info ret = {0, 0, 0, 0};+  ffi_type *fields[3];+  int num_floats, num_ints;+  int num_fields = flatten_struct (top, fields, fields + 3) - fields;++  if (num_fields == 1)+    {+      if (IS_FLOAT (fields[0]->type))+	{+	  ret.as_elements = 1;+	  ret.type1 = fields[0]->type;+	}+    }+  else if (num_fields == 2)+    {+      num_floats = IS_FLOAT (fields[0]->type) + IS_FLOAT (fields[1]->type);+      num_ints = IS_INT (fields[0]->type) + IS_INT (fields[1]->type);+      if (num_floats == 0 || num_floats + num_ints != 2)+	return ret;+      if (cb->used_float + num_floats > NARGREG+	  || cb->used_integer + (2 - num_floats) > NARGREG)+	return ret;+      if (!IS_FLOAT (fields[0]->type) && !IS_FLOAT (fields[1]->type))+	return ret;++      ret.type1 = fields[0]->type;+      ret.type2 = fields[1]->type;+      ret.offset2 = FFI_ALIGN (fields[0]->size, fields[1]->alignment);+      ret.as_elements = 1;+    }+  return ret;+}+#endif++/* Allocates a single register, float register, or GRLEN-sized stack slot to a+   datum.  */+static void+marshal_atom (call_builder *cb, int type, void *data)+{+  size_t value = 0;+  switch (type)+    {+    case FFI_TYPE_UINT8:+      value = *(uint8_t *) data;+      break;+    case FFI_TYPE_SINT8:+      value = *(int8_t *) data;+      break;+    case FFI_TYPE_UINT16:+      value = *(uint16_t *) data;+      break;+    case FFI_TYPE_SINT16:+      value = *(int16_t *) data;+      break;+    /* 32-bit quantities are always sign-extended in the ABI.  */+    case FFI_TYPE_UINT32:+      value = *(int32_t *) data;+      break;+    case FFI_TYPE_SINT32:+      value = *(int32_t *) data;+      break;+#if __SIZEOF_POINTER__ == 8+    case FFI_TYPE_UINT64:+      value = *(uint64_t *) data;+      break;+    case FFI_TYPE_SINT64:+      value = *(int64_t *) data;+      break;+#endif+    case FFI_TYPE_POINTER:+      value = *(size_t *) data;+      break;++#if ABI_FRLEN >= 32+    case FFI_TYPE_FLOAT:+      *(float *)(cb->aregs->fa + cb->used_float++) = *(float *) data;+      return;+#endif+#if ABI_FRLEN >= 64+    case FFI_TYPE_DOUBLE:+      (cb->aregs->fa[cb->used_float++]) = *(double *) data;+      return;+#endif+    default:+      FFI_ASSERT (0);+      break;+    }++  if (cb->used_integer == NARGREG)+    *cb->used_stack++ = value;+  else+    cb->aregs->a[cb->used_integer++] = value;+}++static void+unmarshal_atom (call_builder *cb, int type, void *data)+{+  size_t value;+  switch (type)+    {+#if ABI_FRLEN >= 32+    case FFI_TYPE_FLOAT:+      *(float *) data = *(float *)(cb->aregs->fa + cb->used_float++);+      return;+#endif+#if ABI_FRLEN >= 64+    case FFI_TYPE_DOUBLE:+      *(double *) data = cb->aregs->fa[cb->used_float++];+      return;+#endif+    }++  if (cb->used_integer == NARGREG)+    value = *cb->used_stack++;+  else+    value = cb->aregs->a[cb->used_integer++];++  switch (type)+    {+    case FFI_TYPE_UINT8:+    case FFI_TYPE_SINT8:+    case FFI_TYPE_UINT16:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_SINT32:+#if __SIZEOF_POINTER__ == 8+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+#endif+    case FFI_TYPE_POINTER:+      *(ffi_arg *)data = value;+      break;+    default:+      FFI_ASSERT (0);+      break;+    }+}++/* Allocate and copy a structure that is passed by value on the stack and+   return a pointer to it.  */+static void *+allocate_and_copy_struct_to_stack (call_builder *cb, void *data,+				   ffi_type *type)+{+  size_t dest = cb->next_struct_area - type->size;++  dest = FFI_ALIGN_DOWN (dest, type->alignment);+  cb->next_struct_area = dest;++  return memcpy ((char *)cb->stack + dest, data, type->size);+}++/* Adds an argument to a call, or a not by reference return value.  */+static void+marshal (call_builder *cb, ffi_type *type, int var, void *data)+{+  size_t realign[2];++#if ABI_FRLEN+  if (!var && type->type == FFI_TYPE_STRUCT)+    {+      float_struct_info fsi = struct_passed_as_elements (cb, type);+      if (fsi.as_elements)+	{+	  marshal_atom (cb, fsi.type1, data);+	  if (fsi.offset2)+	    marshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2);+	  return;+	}+    }++  if (!var && cb->used_float < NARGREG+      && IS_FLOAT (type->type))+    {+      marshal_atom (cb, type->type, data);+      return;+    }++  double promoted;+  if (var && type->type == FFI_TYPE_FLOAT)+    {+      /* C standard requires promoting float -> double for variable arg.  */+      promoted = *(float *) data;+      type = &ffi_type_double;+      data = &promoted;+    }+#endif++  if (type->size > 2 * __SIZEOF_POINTER__)+    /* Pass by reference.  */+    {+      allocate_and_copy_struct_to_stack (cb, data, type);+      data = (char *)cb->stack + cb->next_struct_area;+      marshal_atom (cb, FFI_TYPE_POINTER, &data);+    }+  else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER)+    marshal_atom (cb, type->type, data);+  else+    {+      /* Overlong integers, soft-float floats, and structs without special+	 float handling are treated identically from this point on.  */++      /* Variadics are aligned even in registers.  */+      if (type->alignment > __SIZEOF_POINTER__)+	{+	  if (var)+	    cb->used_integer = FFI_ALIGN (cb->used_integer, 2);+	  cb->used_stack+	    = (size_t *) FFI_ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__);+	}++      memcpy (realign, data, type->size);+      if (type->size > 0)+	marshal_atom (cb, FFI_TYPE_POINTER, realign);+      if (type->size > __SIZEOF_POINTER__)+	marshal_atom (cb, FFI_TYPE_POINTER, realign + 1);+    }+}++/* For arguments passed by reference returns the pointer, otherwise the arg+   is copied (up to MAXCOPYARG bytes).  */+static void *+unmarshal (call_builder *cb, ffi_type *type, int var, void *data)+{+  size_t realign[2];+  void *pointer;++#if ABI_FRLEN+  if (!var && type->type == FFI_TYPE_STRUCT)+    {+      float_struct_info fsi = struct_passed_as_elements (cb, type);+      if (fsi.as_elements)+	{+	  unmarshal_atom (cb, fsi.type1, data);+	  if (fsi.offset2)+	    unmarshal_atom (cb, fsi.type2, ((char *) data) + fsi.offset2);+	  return data;+	}+    }++  if (!var && cb->used_float < NARGREG+      && IS_FLOAT (type->type))+    {+      unmarshal_atom (cb, type->type, data);+      return data;+    }++  if (var && type->type == FFI_TYPE_FLOAT)+    {+      int m = cb->used_integer;+      void *promoted+	= m < NARGREG ? cb->aregs->a + m : cb->used_stack + m - NARGREG + 1;+      *(float *) promoted = *(double *) promoted;+    }+#endif++  if (type->size > 2 * __SIZEOF_POINTER__)+    {+      /* Pass by reference.  */+      unmarshal_atom (cb, FFI_TYPE_POINTER, (char *) &pointer);+      return pointer;+    }+  else if (IS_INT (type->type) || type->type == FFI_TYPE_POINTER)+    {+      unmarshal_atom (cb, type->type, data);+      return data;+    }+  else+    {+      /* Overlong integers, soft-float floats, and structs without special+	 float handling are treated identically from this point on.  */++      /* Variadics are aligned even in registers.  */+      if (type->alignment > __SIZEOF_POINTER__)+	{+	  if (var)+	    cb->used_integer = FFI_ALIGN (cb->used_integer, 2);+	  cb->used_stack+	    = (size_t *) FFI_ALIGN (cb->used_stack, 2 * __SIZEOF_POINTER__);+	}++      if (type->size > 0)+	unmarshal_atom (cb, FFI_TYPE_POINTER, realign);+      if (type->size > __SIZEOF_POINTER__)+	unmarshal_atom (cb, FFI_TYPE_POINTER, realign + 1);+      memcpy (data, realign, type->size);+      return data;+    }+}++static int+passed_by_ref (call_builder *cb, ffi_type *type, int var)+{+#if ABI_FRLEN+  if (!var && type->type == FFI_TYPE_STRUCT)+    {+      float_struct_info fsi = struct_passed_as_elements (cb, type);+      if (fsi.as_elements)+	return 0;+    }+#endif++  return type->size > 2 * __SIZEOF_POINTER__;+}++/* Perform machine dependent cif processing.  */+ffi_status+ffi_prep_cif_machdep (ffi_cif *cif)+{+  cif->loongarch_nfixedargs = cif->nargs;+  return FFI_OK;+}++/* Perform machine dependent cif processing when we have a variadic+   function.  */+ffi_status+ffi_prep_cif_machdep_var (ffi_cif *cif, unsigned int nfixedargs,+			  unsigned int ntotalargs)+{+  cif->loongarch_nfixedargs = nfixedargs;+  return FFI_OK;+}++/* Low level routine for calling functions.  */+extern void ffi_call_asm (void *stack, struct call_context *regs,+			  void (*fn) (void), void *closure) FFI_HIDDEN;++static void+ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,+	      void *closure)+{+  /* This is a conservative estimate, assuming a complex return value and+     that all remaining arguments are long long / __int128 */+  size_t arg_bytes = cif->bytes;+  size_t rval_bytes = 0;+  if (rvalue == NULL && cif->rtype->size > 2 * __SIZEOF_POINTER__)+    rval_bytes = FFI_ALIGN (cif->rtype->size, STKALIGN);+  size_t alloc_size = arg_bytes + rval_bytes + sizeof (call_context);++  /* The assembly code will deallocate all stack data at lower addresses+     than the argument region, so we need to allocate the frame and the+     return value after the arguments in a single allocation.  */+  size_t alloc_base;+  /* Argument region must be 16-byte aligned in LP64 ABIs.  */+  if (_Alignof(max_align_t) >= STKALIGN)+    /* Since sizeof long double is normally 16, the compiler will+       guarantee alloca alignment to at least that much.  */+    alloc_base = (size_t) alloca (alloc_size);+  else+    alloc_base = FFI_ALIGN (alloca (alloc_size + STKALIGN - 1), STKALIGN);++  if (rval_bytes)+    rvalue = (void *) (alloc_base + arg_bytes);++  call_builder cb;+  cb.used_float = cb.used_integer = 0;+  cb.aregs = (call_context *) (alloc_base + arg_bytes + rval_bytes);+  cb.used_stack = (void *) alloc_base;+  cb.stack = (void *) alloc_base;+  cb.next_struct_area = arg_bytes;++  int return_by_ref = passed_by_ref (&cb, cif->rtype, 0);+  if (return_by_ref)+    cb.aregs->a[cb.used_integer++] = (size_t)rvalue;++  int i;+  for (i = 0; i < cif->nargs; i++)+    marshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs,+	     avalue[i]);++  ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure);++  cb.used_float = cb.used_integer = 0;+  if (!return_by_ref && rvalue)+    unmarshal (&cb, cif->rtype, 0, rvalue);+}++void+ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,+	     void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}++extern void ffi_closure_asm (void) FFI_HIDDEN;++ffi_status+ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,+		      void (*fun) (ffi_cif *, void *, void **, void *),+		      void *user_data, void *codeloc)+{+  uint32_t *tramp = (uint32_t *) &closure->tramp[0];+  uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;++  if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)+    return FFI_BAD_ABI;++#if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      ffi_tramp_set_parms (closure->ftramp, ffi_closure_asm, closure);+      goto out;+    }+#endif++  /* Fill the dynamic trampoline.  We will call ffi_closure_inner with codeloc,+     not closure, but as long as the memory is readable it should work.  */+  tramp[0] = 0x1800000c; /* pcaddi $t0, 0 (i.e. $t0 <- tramp) */+  tramp[1] = 0x28c0418d; /* ld.d   $t1, $t0, 16 */+  tramp[2] = 0x4c0001a0; /* jirl   $zero, $t1, 0 */+  tramp[3] = 0x03400000; /* nop */+  tramp[4] = fn;+  tramp[5] = fn >> 32;++  __builtin___clear_cache (codeloc, codeloc + FFI_TRAMPOLINE_SIZE);++#if defined(FFI_EXEC_STATIC_TRAMP)+out:+#endif+  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++extern void ffi_go_closure_asm (void) FFI_HIDDEN;++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,+		     void (*fun) (ffi_cif *, void *, void **, void *))+{+  if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)+    return FFI_BAD_ABI;++  closure->tramp = (void *) ffi_go_closure_asm;+  closure->cif = cif;+  closure->fun = fun;+  return FFI_OK;+}++/* Called by the assembly code with aregs pointing to saved argument registers+   and stack pointing to the stacked arguments.  Return values passed in+   registers will be reloaded from aregs.  */+void FFI_HIDDEN+ffi_closure_inner (ffi_cif *cif,+		   void (*fun) (ffi_cif *, void *, void **, void *),+		   void *user_data, size_t *stack, call_context *aregs)+{+  void **avalue = alloca (cif->nargs * sizeof (void *));+  /* Storage for arguments which will be copied by unmarshal().  We could+     theoretically avoid the copies in many cases and use at most 128 bytes+     of memory, but allocating disjoint storage for each argument is+     simpler.  */+  char *astorage = alloca (cif->nargs * MAXCOPYARG);+  void *rvalue;+  call_builder cb;+  int return_by_ref;+  int i;++  cb.aregs = aregs;+  cb.used_integer = cb.used_float = 0;+  cb.used_stack = stack;++  return_by_ref = passed_by_ref (&cb, cif->rtype, 0);+  if (return_by_ref)+    unmarshal (&cb, &ffi_type_pointer, 0, &rvalue);+  else+    rvalue = alloca (cif->rtype->size);++  for (i = 0; i < cif->nargs; i++)+    avalue[i]+      = unmarshal (&cb, cif->arg_types[i], i >= cif->loongarch_nfixedargs,+		   astorage + i * MAXCOPYARG);++  fun (cif, rvalue, avalue, user_data);++  if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID)+    {+      cb.used_integer = cb.used_float = 0;+      marshal (&cb, cif->rtype, 0, rvalue);+    }+}++#if defined(FFI_EXEC_STATIC_TRAMP)+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;++  *tramp_size = 16;+  /* A mapping size of 64K is chosen to cover the page sizes of 4K, 16K, and+     64K.  */+  *map_size = 1 << 16;+  return &trampoline_code_table;+}+#endif
+ src/loongarch64/ffitarget.h view
@@ -0,0 +1,82 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>+                               2022 Cheng Lulu <chenglulu@loongson.cn>++   Target configuration macros for LoongArch.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error \+  "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef __loongarch__+#error \+  "libffi was configured for a LoongArch target but this does not appear to be a LoongArch compiler."+#endif++#ifndef LIBFFI_ASM++typedef unsigned long ffi_arg;+typedef signed long ffi_sarg;++typedef enum ffi_abi+{+  FFI_FIRST_ABI = 0,+  FFI_LP64S,+  FFI_LP64F,+  FFI_LP64D,+  FFI_LAST_ABI,++#if defined(__loongarch64)+#if defined(__loongarch_soft_float)+  FFI_DEFAULT_ABI = FFI_LP64S+#elif defined(__loongarch_single_float)+  FFI_DEFAULT_ABI = FFI_LP64F+#elif defined(__loongarch_double_float)+  FFI_DEFAULT_ABI = FFI_LP64D+#else+#error unsupported LoongArch floating-point ABI+#endif+#else+#error unsupported LoongArch base architecture+#endif+} ffi_abi;++#endif /* LIBFFI_ASM */++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 24+#define FFI_NATIVE_RAW_API 0+#define FFI_EXTRA_CIF_FIELDS \+  unsigned loongarch_nfixedargs; \+  unsigned loongarch_unused;+#define FFI_TARGET_SPECIFIC_VARIADIC+#endif
+ src/loongarch64/sysv.S view
@@ -0,0 +1,327 @@+/* -----------------------------------------------------------------------+  sysv.S  - Copyright (c) 2022 Xu Chenghua <xuchenghua@loongson.cn>+                          2022 Cheng Lulu <chenglulu@loongson.cn>++   LoongArch Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++/* Define aliases so that we can handle all ABIs uniformly.  */++#if __SIZEOF_POINTER__ == 8+# define PTRS 8+# define LARG ld.d+# define SARG st.d+#else+# define PTRS 4+# define LARG ld.w+# define SARG st.w+#endif++#if defined(__loongarch_single_float)+# define FLTS 4+# define FLD fld.w+# define FST fst.w+#elif defined(__loongarch_double_float)+# define FLTS 8+# define FLARG fld.d+# define FSARG fst.d+#elif defined(__loongarch_soft_float)+# define FLTS 0+#else+#error unsupported LoongArch floating-point ABI+#endif++    .text+    .globl  ffi_call_asm+    .type   ffi_call_asm, @function+    .hidden ffi_call_asm+/* struct call_context+   {+     ABI_FLOAT fa[8];+     size_t a[10];+   }++   - 8 floating point parameter/result registers (fa[0] - fa[7])+   - 8 integer parameter/result registers (a[0] - a[7])+   - 2 registers used by the assembly code to in-place construct its own stack+     frame.+    - frame pointer (a[8])+    - return address (a[9])++   void ffi_call_asm (size_t *stackargs, struct call_context *regargs,+		      void (*fn)(void), void *closure); */++#define FRAME_LEN (8 * FLTS + 10 * PTRS)++ffi_call_asm:+	.cfi_startproc++	/* We are NOT going to set up an ordinary stack frame.  In order to pass+	   the stacked args to the called function, we adjust our stack pointer+	   to a0, which is in the _caller's_ alloca area.  We establish our own+	   stack frame at the end of the call_context.++	   Anything below the arguments will be freed at this point, although+	   we preserve the call_context so that it can be read back in the+	   caller.  */++	.cfi_def_cfa	5, FRAME_LEN # Interim CFA based on a1.+	SARG	$fp, $a1, FRAME_LEN - 2*PTRS+	.cfi_offset	22, -2*PTRS+	SARG	$ra, $a1, FRAME_LEN - 1*PTRS+	.cfi_offset	1, -1*PTRS++	addi.d	$fp, $a1, FRAME_LEN+	move	$sp, $a0+	.cfi_def_cfa	22, 0 # Our frame is fully set up.++	# Load arguments.+	move	$t1, $a2+	move	$t2, $a3++#if FLTS+	FLARG	$fa0, $fp, -FRAME_LEN+0*FLTS+	FLARG	$fa1, $fp, -FRAME_LEN+1*FLTS+	FLARG	$fa2, $fp, -FRAME_LEN+2*FLTS+	FLARG	$fa3, $fp, -FRAME_LEN+3*FLTS+	FLARG	$fa4, $fp, -FRAME_LEN+4*FLTS+	FLARG	$fa5, $fp, -FRAME_LEN+5*FLTS+	FLARG	$fa6, $fp, -FRAME_LEN+6*FLTS+	FLARG	$fa7, $fp, -FRAME_LEN+7*FLTS+#endif++	LARG	$a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS+	LARG	$a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS+	LARG	$a2, $fp, -FRAME_LEN+8*FLTS+2*PTRS+	LARG	$a3, $fp, -FRAME_LEN+8*FLTS+3*PTRS+	LARG	$a4, $fp, -FRAME_LEN+8*FLTS+4*PTRS+	LARG	$a5, $fp, -FRAME_LEN+8*FLTS+5*PTRS+	LARG	$a6, $fp, -FRAME_LEN+8*FLTS+6*PTRS+	LARG	$a7, $fp, -FRAME_LEN+8*FLTS+7*PTRS++	/* Call */+	jirl	$ra, $t1, 0++#if FLTS+	/* Save return values - only a0/a1 (fa0/fa1) are used.  */+	FSARG	$fa0, $fp, -FRAME_LEN+0*FLTS+	FSARG	$fa1, $fp, -FRAME_LEN+1*FLTS+#endif++	SARG	$a0, $fp, -FRAME_LEN+8*FLTS+0*PTRS+	SARG	$a1, $fp, -FRAME_LEN+8*FLTS+1*PTRS++	/* Restore and return.  */+	addi.d	$sp, $fp, -FRAME_LEN+	.cfi_def_cfa	3, FRAME_LEN+	LARG	$ra, $fp, -1*PTRS+	.cfi_restore	1+	LARG	$fp, $fp, -2*PTRS+	.cfi_restore	22+	jr	$ra+	.cfi_endproc+	.size	ffi_call_asm, .-ffi_call_asm+++/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t0.+   void ffi_closure_inner (ffi_cif *cif,+			   void (*fun)(ffi_cif *, void *, void **, void *),+			   void *user_data,+			   size_t *stackargs, struct call_context *regargs) */++	.globl	ffi_closure_asm+	.hidden	ffi_closure_asm+	.type	ffi_closure_asm, @function++ffi_closure_asm:+	.cfi_startproc+	addi.d	$sp, $sp, -FRAME_LEN+	.cfi_def_cfa_offset FRAME_LEN++	/* Make a frame.  */+	SARG	$fp, $sp, FRAME_LEN - 2*PTRS+	.cfi_offset	22, -2*PTRS+	SARG	$ra, $sp, FRAME_LEN - 1*PTRS+	.cfi_offset	1, -1*PTRS+	addi.d	$fp, $sp, FRAME_LEN++	/* Save arguments.  */+#if FLTS+	FSARG	$fa0, $sp, 0*FLTS+	FSARG	$fa1, $sp, 1*FLTS+	FSARG	$fa2, $sp, 2*FLTS+	FSARG	$fa3, $sp, 3*FLTS+	FSARG	$fa4, $sp, 4*FLTS+	FSARG	$fa5, $sp, 5*FLTS+	FSARG	$fa6, $sp, 6*FLTS+	FSARG	$fa7, $sp, 7*FLTS+#endif++	SARG	$a0, $sp, 8*FLTS+0*PTRS+	SARG	$a1, $sp, 8*FLTS+1*PTRS+	SARG	$a2, $sp, 8*FLTS+2*PTRS+	SARG	$a3, $sp, 8*FLTS+3*PTRS+	SARG	$a4, $sp, 8*FLTS+4*PTRS+	SARG	$a5, $sp, 8*FLTS+5*PTRS+	SARG	$a6, $sp, 8*FLTS+6*PTRS+	SARG	$a7, $sp, 8*FLTS+7*PTRS++	/* Enter C */+	LARG	$a0, $t0, FFI_TRAMPOLINE_SIZE+0*PTRS+	LARG	$a1, $t0, FFI_TRAMPOLINE_SIZE+1*PTRS+	LARG	$a2, $t0, FFI_TRAMPOLINE_SIZE+2*PTRS+	addi.d	$a3, $sp, FRAME_LEN+	move	$a4, $sp++	bl	ffi_closure_inner++	/* Return values.  */+#if FLTS+	FLARG	$fa0, $sp, 0*FLTS+	FLARG	$fa1, $sp, 1*FLTS+#endif++	LARG	$a0, $sp, 8*FLTS+0*PTRS+	LARG	$a1, $sp, 8*FLTS+1*PTRS++	/* Restore and return.  */+	LARG	$ra, $sp, FRAME_LEN-1*PTRS+	.cfi_restore	1+	LARG	$fp, $sp, FRAME_LEN-2*PTRS+	.cfi_restore	22+	addi.d	$sp, $sp, FRAME_LEN+	.cfi_def_cfa_offset 0+	jr	$ra+	.cfi_endproc+	.size	ffi_closure_asm, .-ffi_closure_asm++/* Static trampoline code table, in which each element is a trampoline.++   The trampoline clobbers t0 and t1, but we don't save them on the stack+   because our psABI explicitly says they are scratch registers, at least for+   ELF.  Our dynamic trampoline is already clobbering them anyway.++   The trampoline has two parameters - target code to jump to and data for+   the target code. The trampoline extracts the parameters from its parameter+   block (see tramp_table_map()).  The trampoline saves the data address in+   t0 and jumps to the target code.  As ffi_closure_asm() already expects the+   data address to be in t0, we don't need a "ffi_closure_asm_alt".  */++#if defined(FFI_EXEC_STATIC_TRAMP)+	.align	16+	.globl	trampoline_code_table+	.hidden	trampoline_code_table+	.type	trampoline_code_table, @function++trampoline_code_table:++	.rept	65536 / 16+	pcaddu12i	$t1, 16 # 65536 >> 12+	ld.d	$t0, $t1, 0+	ld.d	$t1, $t1, 8+	jirl	$zero, $t1, 0+	.endr+	.size	trampoline_code_table, .-trampoline_code_table++	.align	2+#endif++/* ffi_go_closure_asm.  Expects address of the passed-in ffi_go_closure in t2.+   void ffi_closure_inner (ffi_cif *cif,+			   void (*fun)(ffi_cif *, void *, void **, void *),+			   void *user_data,+			   size_t *stackargs, struct call_context *regargs) */++	.globl	ffi_go_closure_asm+	.hidden	ffi_go_closure_asm+	.type	ffi_go_closure_asm, @function++ffi_go_closure_asm:+	.cfi_startproc+	addi.d	$sp, $sp, -FRAME_LEN+	.cfi_def_cfa_offset FRAME_LEN++	/* Make a frame.  */+	SARG	$fp, $sp, FRAME_LEN - 2*PTRS+	.cfi_offset	22, -2*PTRS+	SARG	$ra, $sp, FRAME_LEN - 1*PTRS+	.cfi_offset	1, -1*PTRS+	addi.d	$fp, $sp, FRAME_LEN++	/* Save arguments.  */+#if FLTS+	FSARG	$fa0, $sp, 0*FLTS+	FSARG	$fa1, $sp, 1*FLTS+	FSARG	$fa2, $sp, 2*FLTS+	FSARG	$fa3, $sp, 3*FLTS+	FSARG	$fa4, $sp, 4*FLTS+	FSARG	$fa5, $sp, 5*FLTS+	FSARG	$fa6, $sp, 6*FLTS+	FSARG	$fa7, $sp, 7*FLTS+#endif++	SARG	$a0, $sp, 8*FLTS+0*PTRS+	SARG	$a1, $sp, 8*FLTS+1*PTRS+	SARG	$a2, $sp, 8*FLTS+2*PTRS+	SARG	$a3, $sp, 8*FLTS+3*PTRS+	SARG	$a4, $sp, 8*FLTS+4*PTRS+	SARG	$a5, $sp, 8*FLTS+5*PTRS+	SARG	$a6, $sp, 8*FLTS+6*PTRS+	SARG	$a7, $sp, 8*FLTS+7*PTRS++	/* Enter C */+	LARG	$a0, $t2, 1*PTRS+	LARG	$a1, $t2, 2*PTRS+	move	$a2, $t2+	addi.d	$a3, $sp, FRAME_LEN+	move	$a4, $sp++	bl	ffi_closure_inner++	/* Return values.  */+#if FLTS+	FLARG	$fa0, $sp, 0*FLTS+	FLARG	$fa1, $sp, 1*FLTS+#endif++	LARG	$a0, $sp, 8*FLTS+0*PTRS+	LARG	$a1, $sp, 8*FLTS+1*PTRS++	/* Restore and return.  */+	LARG	$ra, $sp, FRAME_LEN-1*PTRS+	.cfi_restore	1+	LARG	$fp, $sp, FRAME_LEN-2*PTRS+	.cfi_restore	22+	addi.d	$sp, $sp, FRAME_LEN+	.cfi_def_cfa_offset 0+	jr	$ra+	.cfi_endproc+	.size	ffi_go_closure_asm, .-ffi_go_closure_asm++#if defined __ELF__ && defined __linux__+	.section .note.GNU-stack,"",%progbits+#endif
+ src/m32r/ffi.c view
@@ -0,0 +1,249 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2004  Renesas Technology+           Copyright (c) 2008  Red Hat, Inc.+           Copyright (c) 2022  Anthony Green++   M32R 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 RENESAS TECHNOLOGY 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)+{+  unsigned int i;+  int tmp;+  unsigned int avn;+  void **p_argv;+  char *argp;+  ffi_type **p_arg;++  tmp = 0;+  argp = stack;++  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 8)+    {+      *(void **) argp = ecif->rvalue;+      argp += 4;+    }++  avn = ecif->cif->nargs;+  p_argv = ecif->avalue;++  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+       (i != 0) && (avn != 0);+       i--, p_arg++)+    {+      size_t z;++      /* Align if necessary.  */+      if (((*p_arg)->alignment - 1) & (unsigned) argp)+	argp = (char *) FFI_ALIGN (argp, (*p_arg)->alignment);++      if (avn != 0)+	{+	  avn--;+	  z = (*p_arg)->size;+	  if (z < sizeof (int))+	    {+	      z = sizeof (int);++	      switch ((*p_arg)->type)+		{+		case FFI_TYPE_SINT8:+		  *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);+		  break;++		case FFI_TYPE_UINT8:+		  *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);+		  break;++		case FFI_TYPE_SINT16:+		  *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);+		  break;++		case FFI_TYPE_UINT16:+		  *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);+		  break;++		case FFI_TYPE_STRUCT:+	  	  z = (*p_arg)->size;+	  	  if ((*p_arg)->alignment != 1)+		    memcpy (argp, *p_argv, z);+		  else+		    memcpy (argp + 4 - z, *p_argv, z);+	  	  z = sizeof (int);+		  break;++		default:+		  FFI_ASSERT(0);+		}+	    }+	  else if (z == sizeof (int))+	    {+	       *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+	    }+	  else+	    {+	      if ((*p_arg)->type == FFI_TYPE_STRUCT)+	        {+		  if (z > 8)+		    {+		      *(unsigned int *) argp = (unsigned int)(void *)(* p_argv);+		      z = sizeof(void *);+		    }+		  else+		    {+	              memcpy(argp, *p_argv, z);+		      z = 8;+		    }+	        }+	      else+	        {+		  /* Double or long long 64bit.  */+	          memcpy (argp, *p_argv, z);+	        }+	    }+	  p_argv++;+	  argp += z;+	}+    }++  return;+}++/* Perform machine dependent cif processing.  */+ffi_status+ffi_prep_cif_machdep(ffi_cif *cif)+{+  /* Set the return type flag.  */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      cif->flags = (unsigned) cif->rtype->type;+      break;++    case FFI_TYPE_STRUCT:+      if (cif->rtype->size <= 4)+	cif->flags = FFI_TYPE_INT;++      else if (cif->rtype->size <= 8)+	cif->flags = FFI_TYPE_DOUBLE;++      else+	cif->flags = (unsigned) cif->rtype->type;+      break;++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_DOUBLE:+      cif->flags = FFI_TYPE_DOUBLE;+      break;++    case FFI_TYPE_FLOAT:+    default:+      cif->flags = FFI_TYPE_INT;+      break;+    }++  return FFI_OK;+}++extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,+			  unsigned, unsigned, unsigned *, void (*fn)(void));++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  extended_cif ecif;+  ffi_type **arg_types = cif->arg_types;+  int i, nargs = cif->nargs;++  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;++  /* If we have any large structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT && size > 4)+        {+          char *argcopy = alloca (size);+          memcpy (argcopy, avalue[i], size);+          avalue[i] = argcopy;+        }+    }++  switch (cif->abi)+    {+    case FFI_SYSV:+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,+		    cif->flags, ecif.rvalue, fn);+      if (cif->rtype->type == FFI_TYPE_STRUCT)+	{+	  int size = cif->rtype->size;+	  int align = cif->rtype->alignment;++	  if (size < 4)+	    {+	      if (align == 1)+	        *(unsigned long *)(ecif.rvalue) <<= (4 - size) * 8;+	    }+	  else if (4 < size && size < 8)+	    {+	      if (align == 1)+		{+		  memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);+		}+	      else if (align == 2)+		{+		  if (size & 1)+		    size += 1;++		  if (size != 8)+		    memcpy (ecif.rvalue, ecif.rvalue + 8-size, size);+		}+	    }+	}+      break;++    default:+      FFI_ASSERT(0);+      break;+    }+}
+ src/m32r/ffitarget.h view
@@ -0,0 +1,53 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 2004  Renesas Technology.+   Target configuration macros for M32R.++   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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- Generic type definitions ----------------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi+  {+    FFI_FIRST_ABI = 0,+    FFI_SYSV,+    FFI_LAST_ABI,+    FFI_DEFAULT_ABI = FFI_SYSV+  } ffi_abi;+#endif++#define FFI_CLOSURES 		0+#define FFI_TRAMPOLINE_SIZE	24+#define FFI_NATIVE_RAW_API 	0++#endif
+ src/m32r/sysv.S view
@@ -0,0 +1,121 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2004 Renesas Technology+   +   M32R 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 RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+   OTHER DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#ifdef HAVE_MACHINE_ASM_H+#include <machine/asm.h>+#else+/* XXX these lose for some platforms, I'm sure.  */+#define CNAME(x) x+#define ENTRY(x) .globl CNAME(x)! .type CNAME(x),%function! CNAME(x):+#endif++.text++	/* R0:   ffi_prep_args */+	/* R1:   &ecif */+	/* R2:   cif->bytes */+	/* R3:   fig->flags */+	/* sp+0: ecif.rvalue */+	/* sp+4: fn */++	/* This assumes we are using gas.  */+ENTRY(ffi_call_SYSV)+	/* Save registers.  */+	push	fp+	push	lr+	push	r3+	push	r2+	push	r1+	push	r0+	mv	fp, sp++	/* Make room for all of the new args.  */+	sub	sp, r2++	/* Place all of the ffi_prep_args in position.  */+	mv	lr, r0	+	mv	r0, sp+	/* R1 already set.  */++	/* And call.  */+	jl	lr++	/* Move first 4 parameters in registers...  */+	ld	r0, @(0,sp)+	ld	r1, @(4,sp)+	ld	r2, @(8,sp)+        ld	r3, @(12,sp)++	/* ...and adjust the stack.  */+	ld	lr, @(8,fp)+        cmpi	lr, #16+	bc	adjust_stack+	ldi	lr, #16+adjust_stack:+        add	sp, lr++	/* Call the function.  */+	ld	lr, @(28,fp)+	jl	lr	++	/* Remove the space we pushed for the args.  */+	mv	sp, fp	++	/* Load R2 with the pointer to storage for the return value.  */+	ld	r2, @(24,sp)++	/* Load R3 with the return type code.  */+	ld	r3, @(12,sp)++	/* If the return value pointer is NULL, assume no return value.  */+	beqz	r2, epilogue++	/* Return INT.  */+	ldi	r4, #FFI_TYPE_INT+	bne	r3, r4, return_double+	st	r0, @r2	+	bra	epilogue++return_double:+	/* Return DOUBLE or LONGDOUBLE.  */+	ldi	r4, #FFI_TYPE_DOUBLE+	bne	r3, r4, epilogue+	st	r0, @r2	+	st	r1, @(4,r2)++epilogue:+	pop	r0+	pop	r1+	pop	r2+	pop	r3+	pop	lr+	pop	fp+        jmp lr++.ffi_call_SYSV_end:+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+ src/m68k/ffi.c view
@@ -0,0 +1,362 @@+/* -----------------------------------------------------------------------+   ffi.c++   m68k Foreign Function Interface+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <unistd.h>+#ifdef __rtems__+void rtems_cache_flush_multiple_data_lines( const void *, size_t );+#else+#include <sys/syscall.h>+#ifdef __MINT__+#include <mint/mintbind.h>+#include <mint/ssystem.h>+#else+#include <asm/cachectl.h>+#endif+#endif++void ffi_call_SYSV (extended_cif *,+		    unsigned, unsigned,+		    void *, void (*fn) ());+void *ffi_prep_args (void *stack, extended_cif *ecif);+void ffi_closure_SYSV (ffi_closure *);+void ffi_closure_struct_SYSV (ffi_closure *);+unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,+				     void *resp, void *args);++/* ffi_prep_args is called by the assembly routine once stack space has+   been allocated for the function's arguments.  */++void *+ffi_prep_args (void *stack, extended_cif *ecif)+{+  unsigned int i;+  void **p_argv;+  char *argp;+  ffi_type **p_arg;+  void *struct_value_ptr;++  argp = stack;++  if (+#ifdef __MINT__+      (ecif->cif->rtype->type == FFI_TYPE_LONGDOUBLE) ||+#endif+      (((ecif->cif->rtype->type == FFI_TYPE_STRUCT)+        && !ecif->cif->flags)))+    struct_value_ptr = ecif->rvalue;+  else+    struct_value_ptr = NULL;++  p_argv = ecif->avalue;++  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+       i != 0;+       i--, p_arg++)+    {+      size_t z = (*p_arg)->size;+      int type = (*p_arg)->type;++      if (z < sizeof (int))+	{+	  switch (type)+	    {+	    case FFI_TYPE_SINT8:+	      *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;+	      break;++	    case FFI_TYPE_UINT8:+	      *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;+	      break;++	    case FFI_TYPE_SINT16:+	      *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;+	      break;++	    case FFI_TYPE_UINT16:+	      *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;+	      break;++	    case FFI_TYPE_STRUCT:+#ifdef __MINT__+	      if (z == 1 || z == 2)+		memcpy (argp + 2, *p_argv, z);+              else+		memcpy (argp, *p_argv, z);+#else+	      memcpy (argp + sizeof (int) - z, *p_argv, z);+#endif+	      break;++	    default:+	      FFI_ASSERT (0);+	    }+	  z = sizeof (int);+	}+      else+	{+	  memcpy (argp, *p_argv, z);++	  /* Align if necessary.  */+	  if ((sizeof(int) - 1) & z)+	    z = FFI_ALIGN(z, sizeof(int));+	}++      p_argv++;+      argp += z;+    }++  return struct_value_ptr;+}++#define CIF_FLAGS_INT		1+#define CIF_FLAGS_DINT		2+#define CIF_FLAGS_FLOAT		4+#define CIF_FLAGS_DOUBLE	8+#define CIF_FLAGS_LDOUBLE	16+#define CIF_FLAGS_POINTER	32+#define CIF_FLAGS_STRUCT1	64+#define CIF_FLAGS_STRUCT2	128+#define CIF_FLAGS_SINT8		256+#define CIF_FLAGS_SINT16	512++/* Perform machine dependent cif processing */+ffi_status+ffi_prep_cif_machdep (ffi_cif *cif)+{+  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      cif->flags = 0;+      break;++    case FFI_TYPE_STRUCT:+      if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT &&+          cif->rtype->elements[1])+        {+          cif->flags = 0;+          break;+        }++      switch (cif->rtype->size)+	{+	case 1:+#ifdef __MINT__+	  cif->flags = CIF_FLAGS_STRUCT2;+#else+	  cif->flags = CIF_FLAGS_STRUCT1;+#endif+	  break;+	case 2:+	  cif->flags = CIF_FLAGS_STRUCT2;+	  break;+#ifdef __MINT__+	case 3:+#endif+	case 4:+	  cif->flags = CIF_FLAGS_INT;+	  break;+#ifdef __MINT__+	case 7:+#endif+	case 8:+	  cif->flags = CIF_FLAGS_DINT;+	  break;+	default:+	  cif->flags = 0;+	  break;+	}+      break;++    case FFI_TYPE_FLOAT:+      cif->flags = CIF_FLAGS_FLOAT;+      break;++    case FFI_TYPE_DOUBLE:+      cif->flags = CIF_FLAGS_DOUBLE;+      break;++#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)+    case FFI_TYPE_LONGDOUBLE:+#ifdef __MINT__+      cif->flags = 0;+#else+      cif->flags = CIF_FLAGS_LDOUBLE;+#endif+      break;+#endif++    case FFI_TYPE_POINTER:+      cif->flags = CIF_FLAGS_POINTER;+      break;++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      cif->flags = CIF_FLAGS_DINT;+      break;++    case FFI_TYPE_SINT16:+      cif->flags = CIF_FLAGS_SINT16;+      break;++    case FFI_TYPE_SINT8:+      cif->flags = CIF_FLAGS_SINT8;+      break;++    default:+      cif->flags = CIF_FLAGS_INT;+      break;+    }++  return FFI_OK;+}++void+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)+{+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;++  /* If the return value is a struct and we don't have a return value+     address then we need to make one.  */++  if (rvalue == NULL+      && cif->rtype->type == FFI_TYPE_STRUCT+      && cif->rtype->size > 8)+    ecif.rvalue = alloca (cif->rtype->size);+  else+    ecif.rvalue = rvalue;++  switch (cif->abi)+    {+    case FFI_SYSV:+      ffi_call_SYSV (&ecif, cif->bytes, cif->flags,+		     ecif.rvalue, fn);+      break;++    default:+      FFI_ASSERT (0);+      break;+    }+}++static void+ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)+{+  unsigned int i;+  void **p_argv;+  char *argp;+  ffi_type **p_arg;++  argp = stack;+  p_argv = avalue;++  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)+    {+      size_t z;++      z = (*p_arg)->size;+#ifdef __MINT__+      if (cif->flags &&+          cif->rtype->type == FFI_TYPE_STRUCT &&+          (z == 1 || z == 2))+ 	{+	  *p_argv = (void *) (argp + 2);++	  z = 4;+	}+      else+      if (cif->flags &&+          cif->rtype->type == FFI_TYPE_STRUCT &&+          (z == 3 || z == 4))+ 	{+	  *p_argv = (void *) (argp);++	  z = 4;+	}+      else+#endif+      if (z <= 4)+	{+	  *p_argv = (void *) (argp + 4 - z);++	  z = 4;+	}+      else+	{+	  *p_argv = (void *) argp;++	  /* Align if necessary */+	  if ((sizeof(int) - 1) & z)+	    z = FFI_ALIGN(z, sizeof(int));+	}++      p_argv++;+      argp += z;+    }+}++unsigned int+ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)+{+  ffi_cif *cif;+  void **arg_area;++  cif = closure->cif;+  arg_area = (void**) alloca (cif->nargs * sizeof (void *));++  ffi_prep_incoming_args_SYSV(args, arg_area, cif);++  (closure->fun) (cif, resp, arg_area, closure->user_data);++  return cif->flags;+}++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif*,void*,void**,void*),+		      void *user_data,+		      void *codeloc)+{+  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  *(unsigned short *)closure->tramp = 0x207c;+  *(void **)(closure->tramp + 2) = codeloc;+  *(unsigned short *)(closure->tramp + 6) = 0x4ef9;++  if (+#ifdef __MINT__+      (cif->rtype->type == FFI_TYPE_LONGDOUBLE) ||+#endif+      (((cif->rtype->type == FFI_TYPE_STRUCT)+         && !cif->flags)))+    *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;+  else+    *(void **)(closure->tramp + 8) = ffi_closure_SYSV;++#ifdef __rtems__+  rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );+#elif defined(__MINT__)+  Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE);+#else+  syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,+	  FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);+#endif++  closure->cif  = cif;+  closure->user_data = user_data;+  closure->fun  = fun;++  return FFI_OK;+}
+ src/m68k/ffitarget.h view
@@ -0,0 +1,54 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for Motorola 68K.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 16+#define FFI_NATIVE_RAW_API 0++#endif+
+ src/m68k/sysv.S view
@@ -0,0 +1,357 @@+/* -----------------------------------------------------------------------+	+   sysv.S - Copyright (c) 2012 Alan Hourihane+	    Copyright (c) 1998, 2012 Andreas Schwab+	    Copyright (c) 2008 Red Hat, Inc.+	    Copyright (c) 2012, 2016 Thorsten Glaser++   m68k Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>++#ifdef HAVE_AS_CFI_PSEUDO_OP+#define CFI_STARTPROC()		.cfi_startproc+#define CFI_OFFSET(reg,off)	.cfi_offset	reg,off+#define CFI_DEF_CFA(reg,off)	.cfi_def_cfa	reg,off+#define CFI_ENDPROC()		.cfi_endproc+#else+#define CFI_STARTPROC()+#define CFI_OFFSET(reg,off)+#define CFI_DEF_CFA(reg,off)+#define CFI_ENDPROC()+#endif++#ifdef __MINT__+#define CALLFUNC(funcname) _ ## funcname+#else+#define CALLFUNC(funcname) funcname+#endif++	.text++	.globl	CALLFUNC(ffi_call_SYSV)+	.type	CALLFUNC(ffi_call_SYSV),@function+	.align	4++CALLFUNC(ffi_call_SYSV):+	CFI_STARTPROC()+	link	%fp,#0+	CFI_OFFSET(14,-8)+	CFI_DEF_CFA(14,8)+	move.l	%d2,-(%sp)+	CFI_OFFSET(2,-12)++	| Make room for all of the new args.+	sub.l	12(%fp),%sp++	| Call ffi_prep_args+	move.l	8(%fp),-(%sp)+	pea	4(%sp)+#if !defined __PIC__+	jsr	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+	addq.l	#8,%sp	++	| Pass pointer to struct value, if any+#ifdef __MINT__+	move.l	%d0,%a1+#else+	move.l	%a0,%a1+#endif++	| Call the function+	move.l	24(%fp),%a0+	jsr	(%a0)++	| Remove the space we pushed for the args+	add.l	12(%fp),%sp++	| Load the pointer to storage for the return value+	move.l	20(%fp),%a1++	| Load the return type code +	move.l	16(%fp),%d2++	| If the return value pointer is NULL, assume no return value.+	| NOTE: On the mc68000, tst on an address register is not supported.+#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)+	cmp.w	#0, %a1+#else+	tst.l	%a1+#endif+	jbeq	noretval++	btst	#0,%d2+	jbeq	retlongint+	move.l	%d0,(%a1)+	jbra	epilogue++retlongint:+	btst	#1,%d2+	jbeq	retfloat+	move.l	%d0,(%a1)+	move.l	%d1,4(%a1)+	jbra	epilogue++retfloat:+	btst	#2,%d2+	jbeq	retdouble+#if defined(__MC68881__) || defined(__HAVE_68881__)+	fmove.s	%fp0,(%a1)+#else+	move.l	%d0,(%a1)+#endif+	jbra	epilogue++retdouble:+	btst	#3,%d2+	jbeq	retlongdouble+#if defined(__MC68881__) || defined(__HAVE_68881__)+	fmove.d	%fp0,(%a1)+#else+	move.l	%d0,(%a1)++	move.l	%d1,(%a1)+#endif+	jbra	epilogue++retlongdouble:+	btst	#4,%d2+	jbeq	retpointer+#if defined(__MC68881__) || defined(__HAVE_68881__)+	fmove.x	%fp0,(%a1)+#else+	move.l	%d0,(%a1)++	move.l	%d1,(%a1)++	move.l	%d2,(%a1)+#endif+	jbra	epilogue++retpointer:+	btst	#5,%d2+	jbeq	retstruct1+#ifdef __MINT__+	move.l	%d0,(%a1)+#else+	move.l	%a0,(%a1)+#endif+	jbra	epilogue++retstruct1:+	btst	#6,%d2+	jbeq	retstruct2+	move.b	%d0,(%a1)+	jbra	epilogue++retstruct2:+	btst	#7,%d2+	jbeq	retsint8+	move.w	%d0,(%a1)+	jbra	epilogue++retsint8:+	btst	#8,%d2+	jbeq	retsint16+	| NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.+#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)+	ext.w	%d0+	ext.l	%d0+#else+	extb.l	%d0+#endif+	move.l	%d0,(%a1)+	jbra	epilogue++retsint16:+	btst	#9,%d2+	jbeq	noretval+	ext.l	%d0+	move.l	%d0,(%a1)++noretval:+epilogue:+	move.l	(%sp)+,%d2+	unlk	%fp+	rts+	CFI_ENDPROC()+	.size	CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)++	.globl	CALLFUNC(ffi_closure_SYSV)+	.type	CALLFUNC(ffi_closure_SYSV), @function+	.align	4++CALLFUNC(ffi_closure_SYSV):+	CFI_STARTPROC()+	link	%fp,#-12+	CFI_OFFSET(14,-8)+	CFI_DEF_CFA(14,8)+	move.l	%sp,-12(%fp)+	pea	8(%fp)+	pea	-12(%fp)+	move.l	%a0,-(%sp)+#if !defined __PIC__+	jsr	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++	lsr.l	#1,%d0+	jne	1f+	jcc	.Lcls_epilogue+	| CIF_FLAGS_INT+	move.l	-12(%fp),%d0+.Lcls_epilogue:+	| no CIF_FLAGS_*+	unlk	%fp+	rts+1:+	lea	-12(%fp),%a0+	lsr.l	#2,%d0+	jne	1f+	jcs	.Lcls_ret_float+	| CIF_FLAGS_DINT+	move.l	(%a0)+,%d0+	move.l	(%a0),%d1+	jra	.Lcls_epilogue+.Lcls_ret_float:+#if defined(__MC68881__) || defined(__HAVE_68881__)+	fmove.s	(%a0),%fp0+#else+	move.l	(%a0),%d0+#endif+	jra	.Lcls_epilogue+1:+	lsr.l	#2,%d0+	jne	1f+	jcs	.Lcls_ret_ldouble+	| CIF_FLAGS_DOUBLE+#if defined(__MC68881__) || defined(__HAVE_68881__)+	fmove.d	(%a0),%fp0+#else+	move.l	(%a0)+,%d0+	move.l	(%a0),%d1+#endif+	jra	.Lcls_epilogue+.Lcls_ret_ldouble:+#if defined(__MC68881__) || defined(__HAVE_68881__)+	fmove.x	(%a0),%fp0+#else+	move.l	(%a0)+,%d0+	move.l	(%a0)+,%d1+	move.l	(%a0),%d2+#endif+	jra	.Lcls_epilogue+1:+	lsr.l	#2,%d0+	jne	1f+	jcs	.Lcls_ret_struct1+	| CIF_FLAGS_POINTER+	move.l	(%a0),%a0+	move.l	%a0,%d0+	jra	.Lcls_epilogue+.Lcls_ret_struct1:+	move.b	(%a0),%d0+	jra	.Lcls_epilogue+1:+	lsr.l	#2,%d0+	jne	1f+	jcs	.Lcls_ret_sint8+	| CIF_FLAGS_STRUCT2+	move.w	(%a0),%d0+	jra	.Lcls_epilogue+.Lcls_ret_sint8:+	move.l	(%a0),%d0+	| NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.+#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)+	ext.w	%d0+	ext.l	%d0+#else+	extb.l	%d0+#endif+	jra	.Lcls_epilogue+1:+	| CIF_FLAGS_SINT16+	move.l	(%a0),%d0+	ext.l	%d0+	jra	.Lcls_epilogue+	CFI_ENDPROC()++	.size	CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)++	.globl	CALLFUNC(ffi_closure_struct_SYSV)+	.type	CALLFUNC(ffi_closure_struct_SYSV), @function+	.align	4++CALLFUNC(ffi_closure_struct_SYSV):+	CFI_STARTPROC()+	link	%fp,#0+	CFI_OFFSET(14,-8)+	CFI_DEF_CFA(14,8)+	move.l	%sp,-12(%fp)+	pea	8(%fp)+	move.l	%a1,-(%sp)+	move.l	%a0,-(%sp)+#if !defined __PIC__+	jsr	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+	unlk	%fp+	rts+	CFI_ENDPROC()+	.size	CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV)++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/m88k/ffi.c view
@@ -0,0 +1,400 @@+/*+ * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>+ *+ * Permission is hereby granted, free of charge, to any person obtaining+ * a copy of this software and associated documentation files (the+ * ``Software''), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ * + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++/*+ * m88k Foreign Function Interface+ *+ * This file attempts to provide all the FFI entry points which can reliably+ * be implemented in C.+ *+ * Only OpenBSD/m88k is currently supported; other platforms (such as+ * Motorola's SysV/m88k) could be supported with the following tweaks:+ *+ * - non-OpenBSD systems use an `outgoing parameter area' as part of the+ *   88BCS calling convention, which is not supported under OpenBSD from+ *   release 3.6 onwards.  Supporting it should be as easy as taking it+ *   into account when adjusting the stack, in the assembly code.+ *+ * - the logic deciding whether a function argument gets passed through+ *   registers, or on the stack, has changed several times in OpenBSD in+ *   edge cases (especially for structs larger than 32 bytes being passed+ *   by value). The code below attemps to match the logic used by the+ *   system compiler of OpenBSD 5.3, i.e. gcc 3.3.6 with many m88k backend+ *   fixes.+ */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <unistd.h>++void ffi_call_OBSD (unsigned int, extended_cif *, unsigned int, void *,+		    void (*fn) ());+void *ffi_prep_args (void *, extended_cif *);+void ffi_closure_OBSD (ffi_closure *);+void ffi_closure_struct_OBSD (ffi_closure *);+unsigned int ffi_closure_OBSD_inner (ffi_closure *, void *, unsigned int *,+				     char *);+void ffi_cacheflush_OBSD (unsigned int, unsigned int);++#define CIF_FLAGS_INT		(1 << 0)+#define CIF_FLAGS_DINT		(1 << 1)++/*+ * Foreign Function Interface API+ */++/* ffi_prep_args is called by the assembly routine once stack space has+   been allocated for the function's arguments.  */++void *+ffi_prep_args (void *stack, extended_cif *ecif)+{+  unsigned int i;+  void **p_argv;+  char *argp, *stackp;+  unsigned int *regp;+  unsigned int regused;+  ffi_type **p_arg;+  void *struct_value_ptr;++  regp = (unsigned int *)stack;+  stackp = (char *)(regp + 8);+  regused = 0;++  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT+      && !ecif->cif->flags)+    struct_value_ptr = ecif->rvalue;+  else+    struct_value_ptr = NULL;++  p_argv = ecif->avalue;++  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++)+    {+      size_t z;+      unsigned short t, a;++      z = (*p_arg)->size;+      t = (*p_arg)->type;+      a = (*p_arg)->alignment;++      /*+       * Figure out whether the argument can be passed through registers+       * or on the stack.+       * The rule is that registers can only receive simple types not larger+       * than 64 bits, or structs the exact size of a register and aligned to+       * the size of a register.+       */+      if (t == FFI_TYPE_STRUCT)+	{+	  if (z == sizeof (int) && a == sizeof (int) && regused < 8)+	    argp = (char *)regp;+	  else+	    argp = stackp;+	}+      else+	{+	  if (z > sizeof (int) && regused < 8 - 1)+	    {+	      /* align to an even register pair */+	      if (regused & 1)+		{+		  regp++;+		  regused++;+		}+	    }+	  if (regused < 8)+	    argp = (char *)regp;+	  else+	    argp = stackp;+	}++      /* Enforce proper stack alignment of 64-bit types */+      if (argp == stackp && a > sizeof (int))+	{+	  stackp = (char *) FFI_ALIGN(stackp, a);+	  argp = stackp;+	}++      switch (t)+	{+	case FFI_TYPE_SINT8:+	  *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;+	  break;++	case FFI_TYPE_UINT8:+	  *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;+	  break;++	case FFI_TYPE_SINT16:+	  *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;+	  break;++	case FFI_TYPE_UINT16:+	  *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;+	  break;++	case FFI_TYPE_INT:+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_POINTER:+	  *(unsigned int *) argp = *(unsigned int *) *p_argv;+	  break;++	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_STRUCT:+	  memcpy (argp, *p_argv, z);+	  break;++	default:+	  FFI_ASSERT (0);+	}++      /* Align if necessary.  */+      if ((sizeof (int) - 1) & z)+	z = FFI_ALIGN(z, sizeof (int));++      p_argv++;++      /* Be careful, once all registers are filled, and about to continue+         on stack, regp == stackp.  Therefore the check for regused as well. */+      if (argp == (char *)regp && regused < 8)+	{+	  regp += z / sizeof (int);+	  regused += z / sizeof (int);+	}+      else+	stackp += z;+    }++  return struct_value_ptr;+}++/* Perform machine dependent cif processing */+ffi_status+ffi_prep_cif_machdep (ffi_cif *cif)+{+  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      cif->flags = 0;+      break;++    case FFI_TYPE_STRUCT:+      if (cif->rtype->size == sizeof (int) &&+	  cif->rtype->alignment == sizeof (int))+	cif->flags = CIF_FLAGS_INT;+      else+	cif->flags = 0;+      break;++    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      cif->flags = CIF_FLAGS_DINT;+      break;++    default:+      cif->flags = CIF_FLAGS_INT;+      break;+    }++  return FFI_OK;+}++void+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)+{+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;++  /* If the return value is a struct and we don't have a return value+     address then we need to make one.  */++  if (rvalue == NULL+      && cif->rtype->type == FFI_TYPE_STRUCT+      && (cif->rtype->size != sizeof (int)+	  || cif->rtype->alignment != sizeof (int)))+    ecif.rvalue = alloca (cif->rtype->size);+  else+    ecif.rvalue = rvalue;++  switch (cif->abi)+    {+    case FFI_OBSD:+      ffi_call_OBSD (cif->bytes, &ecif, cif->flags, ecif.rvalue, fn);+      break;++    default:+      FFI_ASSERT (0);+      break;+    }+}++/*+ * Closure API+ */++static void+ffi_prep_closure_args_OBSD (ffi_cif *cif, void **avalue, unsigned int *regp,+			    char *stackp)+{+  unsigned int i;+  void **p_argv;+  char *argp;+  unsigned int regused;+  ffi_type **p_arg;++  regused = 0;++  p_argv = avalue;++  for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)+    {+      size_t z;+      unsigned short t, a;++      z = (*p_arg)->size;+      t = (*p_arg)->type;+      a = (*p_arg)->alignment;++      /*+       * Figure out whether the argument has been passed through registers+       * or on the stack.+       * The rule is that registers can only receive simple types not larger+       * than 64 bits, or structs the exact size of a register and aligned to+       * the size of a register.+       */+      if (t == FFI_TYPE_STRUCT)+	{+	  if (z == sizeof (int) && a == sizeof (int) && regused < 8)+	    argp = (char *)regp;+	  else+	    argp = stackp;+	}+      else+	{+	  if (z > sizeof (int) && regused < 8 - 1)+	    {+	      /* align to an even register pair */+	      if (regused & 1)+		{+		  regp++;+		  regused++;+		}+	    }+	  if (regused < 8)+	    argp = (char *)regp;+	  else+	    argp = stackp;+	}++      /* Enforce proper stack alignment of 64-bit types */+      if (argp == stackp && a > sizeof (int))+	{+	  stackp = (char *) FFI_ALIGN(stackp, a);+	  argp = stackp;+	}++      if (z < sizeof (int) && t != FFI_TYPE_STRUCT)+	*p_argv = (void *) (argp + sizeof (int) - z);+      else+	*p_argv = (void *) argp;++      /* Align if necessary */+      if ((sizeof (int) - 1) & z)+	z = FFI_ALIGN(z, sizeof (int));++      p_argv++;++      /* Be careful, once all registers are exhausted, and about to fetch from+	 stack, regp == stackp.  Therefore the check for regused as well. */+      if (argp == (char *)regp && regused < 8)+	{+	  regp += z / sizeof (int);+	  regused += z / sizeof (int);+	}+      else+	stackp += z;+    }+}++unsigned int+ffi_closure_OBSD_inner (ffi_closure *closure, void *resp, unsigned int *regp,+			char *stackp)+{+  ffi_cif *cif;+  void **arg_area;++  cif = closure->cif;+  arg_area = (void**) alloca (cif->nargs * sizeof (void *));++  ffi_prep_closure_args_OBSD(cif, arg_area, regp, stackp);++  (closure->fun) (cif, resp, arg_area, closure->user_data);++  return cif->flags;+}++ffi_status+ffi_prep_closure_loc (ffi_closure* closure, ffi_cif* cif,+		      void (*fun)(ffi_cif*,void*,void**,void*),+		      void *user_data, void *codeloc)+{+  unsigned int *tramp = (unsigned int *) codeloc;+  void *fn;++  FFI_ASSERT (cif->abi == FFI_OBSD);++  if (cif->rtype->type == FFI_TYPE_STRUCT && !cif->flags)+    fn = &ffi_closure_struct_OBSD;+  else+    fn = &ffi_closure_OBSD;++  /* or.u %r10, %r0, %hi16(fn) */+  tramp[0] = 0x5d400000 | (((unsigned int)fn) >> 16);+  /* or.u %r13, %r0, %hi16(closure) */+  tramp[1] = 0x5da00000 | ((unsigned int)closure >> 16);+  /* or %r10, %r10, %lo16(fn) */+  tramp[2] = 0x594a0000 | (((unsigned int)fn) & 0xffff);+  /* jmp.n %r10 */+  tramp[3] = 0xf400c40a;+  /* or %r13, %r13, %lo16(closure) */+  tramp[4] = 0x59ad0000 | ((unsigned int)closure & 0xffff);++  ffi_cacheflush_OBSD((unsigned int)codeloc, FFI_TRAMPOLINE_SIZE);++  closure->cif  = cif;+  closure->user_data = user_data;+  closure->fun  = fun;++  return FFI_OK;+}
+ src/m88k/ffitarget.h view
@@ -0,0 +1,49 @@+/*+ * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>+ *+ * Permission is hereby granted, free of charge, to any person obtaining+ * a copy of this software and associated documentation files (the+ * ``Software''), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ * + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++/*+ * m88k Foreign Function Interface+ */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_ASM+typedef unsigned long ffi_arg;+typedef signed long ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_OBSD,+  FFI_DEFAULT_ABI = FFI_OBSD,+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 0x14+#define FFI_NATIVE_RAW_API 0++#endif
+ src/m88k/obsd.S view
@@ -0,0 +1,209 @@+/*+ * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>+ *+ * Permission is hereby granted, free of charge, to any person obtaining+ * a copy of this software and associated documentation files (the+ * ``Software''), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ * + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++/*+ * m88k Foreign Function Interface+ */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>++	.text++/*+ * ffi_cacheflush_OBSD(unsigned int addr,	%r2+ *		       unsigned int size);	%r3+ */+	.align	4+	.globl	ffi_cacheflush_OBSD+	.type	ffi_cacheflush_OBSD,@function+ffi_cacheflush_OBSD:+	tb0	0,   %r0, 451+	or	%r0, %r0, %r0+	jmp	%r1+	.size	ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD++/*+ * ffi_call_OBSD(unsigned bytes,		%r2+ *		 extended_cif *ecif,		%r3+ *		 unsigned flags,		%r4+ *		 void *rvalue,			%r5+ *		 void (*fn)());			%r6+ */+	.align	4+	.globl	ffi_call_OBSD+	.type	ffi_call_OBSD,@function+ffi_call_OBSD:+	subu	%r31, %r31, 32+	st	%r30, %r31, 4+	st	%r1,  %r31, 0+	addu	%r30, %r31, 32++	| Save the few arguments we'll need after ffi_prep_args()+	st.d	%r4, %r31, 8+	st	%r6, %r31, 16++	| Allocate room for the image of r2-r9, and the stack space for+	| the args (rounded to a 16-byte boundary)+	addu	%r2,  %r2,  (8 * 4) + 15+	clr	%r2,  %r2,  4<0>+	subu	%r31, %r31, %r2++	| Fill register and stack image+	or	%r2, %r31, %r0+#ifdef PIC+	bsr	ffi_prep_args#plt+#else+	bsr	ffi_prep_args+#endif++	| Save pointer to return struct address, if any+	or	%r12, %r2, %r0++	| Get function pointer+	subu	%r4,  %r30, 32+	ld	%r1,  %r4,  16++	| Fetch the register arguments+	ld.d	%r2, %r31, (0 * 4)+	ld.d	%r4, %r31, (2 * 4)+	ld.d	%r6, %r31, (4 * 4)+	ld.d	%r8, %r31, (6 * 4)+	addu	%r31, %r31, (8 * 4)++	| Invoke the function+	jsr	%r1++	| Restore stack now that we don't need the args anymore+	subu	%r31, %r30, 32++	| Figure out what to return as the function's return value+	ld	%r5, %r31, 12		| rvalue+	ld	%r4, %r31, 8		| flags++	bcnd	eq0, %r5, 9f++	bb0	0, %r4, 1f		| CIF_FLAGS_INT+	st	%r2, %r5, 0+	br	9f++1:+	bb0	1, %r4, 1f		| CIF_FLAGS_DINT+	st.d	%r2, %r5, 0+	br	9f++1:+9:+	ld	%r1,  %r31, 0+	ld	%r30, %r31, 4+	jmp.n	%r1+	 addu	%r31, %r31, 32+	.size	ffi_call_OBSD, . - ffi_call_OBSD++/*+ * ffi_closure_OBSD(ffi_closure *closure);	%r13+ */+	.align	4+	.globl	ffi_closure_OBSD+	.type	ffi_closure_OBSD, @function+ffi_closure_OBSD:+	subu	%r31, %r31, 16+	st	%r30, %r31, 4+	st	%r1,  %r31, 0+	addu	%r30, %r31, 16++	| Make room on the stack for saved register arguments and return+	| value+	subu	%r31, %r31, (8 * 4) + (2 * 4)+	st.d	%r2,  %r31, (0 * 4)+	st.d	%r4,  %r31, (2 * 4)+	st.d	%r6,  %r31, (4 * 4)+	st.d	%r8,  %r31, (6 * 4)++	| Invoke the closure function+	or	%r5,  %r30, 0			| calling stack+	addu	%r4,  %r31, 0			| saved registers+	addu	%r3,  %r31, (8 * 4)		| return value+	or	%r2,  %r13, %r0			| closure+#ifdef PIC+	bsr	ffi_closure_OBSD_inner#plt+#else+	bsr	ffi_closure_OBSD_inner+#endif++	| Figure out what to return as the function's return value+	bb0	0, %r2, 1f		| CIF_FLAGS_INT+	ld	%r2, %r31, (8 * 4)+	br	9f++1:+	bb0	1, %r2, 1f		| CIF_FLAGS_DINT+	ld.d	%r2, %r31, (8 * 4)+	br	9f++1:+9:+	subu	%r31, %r30, 16+	ld	%r1,  %r31, 0+	ld	%r30, %r31, 4+	jmp.n	%r1+	 addu	%r31, %r31, 16+	.size	ffi_closure_OBSD,.-ffi_closure_OBSD++/*+ * ffi_closure_struct_OBSD(ffi_closure *closure);	%r13+ */+	.align	4+	.globl	ffi_closure_struct_OBSD+	.type	ffi_closure_struct_OBSD, @function+ffi_closure_struct_OBSD:+	subu	%r31, %r31, 16+	st	%r30, %r31, 4+	st	%r1,  %r31, 0+	addu	%r30, %r31, 16++	| Make room on the stack for saved register arguments+	subu	%r31, %r31, (8 * 4)+	st.d	%r2,  %r31, (0 * 4)+	st.d	%r4,  %r31, (2 * 4)+	st.d	%r6,  %r31, (4 * 4)+	st.d	%r8,  %r31, (6 * 4)++	| Invoke the closure function+	or	%r5,  %r30, 0			| calling stack+	addu	%r4,  %r31, 0			| saved registers+	or	%r3,  %r12, 0			| return value+	or	%r2,  %r13, %r0			| closure+#ifdef PIC+	bsr	ffi_closure_OBSD_inner#plt+#else+	bsr	ffi_closure_OBSD_inner+#endif++	subu	%r31, %r30, 16+	ld	%r1,  %r31, 0+	ld	%r30, %r31, 4+	jmp.n	%r1+	 addu	%r31, %r31, 16+	.size	ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD
+ src/metag/ffi.c view
@@ -0,0 +1,330 @@+/* ----------------------------------------------------------------------+  ffi.c - Copyright (c) 2013 Imagination Technologies++  Meta Foreign Function Interface+  Permission is hereby granted, free of charge, to any person obtaining+  a copy of this software and associated documentation files (the+  `Software''), to deal in the Software without restriction, including+  without limitation the rights to use, copy, modify, merge, publish,+  distribute, sublicense, and/or sell copies of the Software, and to+  permit persons to whom the Software is furnished to do so, subject to+  the following conditions:++  The above copyright notice and this permission notice shall be included+  in all copies or substantial portions of the Software.++  THE SOFTWARE IS PROVIDED `AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS+  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+  IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR+  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+  OTHER DEALINGS IN THE SOFTWARE.+----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>++#define MIN(a,b) (((a) < (b)) ? (a) : (b))++/*+ * ffi_prep_args is called by the assembly routine once stack space has been+ * allocated for the function's arguments+ */++unsigned int ffi_prep_args(char *stack, extended_cif *ecif)+{+	register unsigned int i;+	register void **p_argv;+	register char *argp;+	register ffi_type **p_arg;++	argp = stack;++	/* Store return value */+	if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {+		argp -= 4;+		*(void **) argp = ecif->rvalue;+	}++	p_argv = ecif->avalue;++	/* point to next location */+	for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); i--, p_arg++, p_argv++)+	{+		size_t z;++		/* Move argp to address of argument */+		z = (*p_arg)->size;+		argp -= z;++		/* Align if necessary */+		argp = (char *) FFI_ALIGN_DOWN(FFI_ALIGN_DOWN(argp, (*p_arg)->alignment), 4);++		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);+			case FFI_TYPE_STRUCT:+				memcpy(argp, *p_argv, (*p_arg)->size);+				break;+			default:+				FFI_ASSERT(0);+			}+		} else if ( z == sizeof(int)) {+			*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+		} else {+			memcpy(argp, *p_argv, z);+		}+	}++	/* return the size of the arguments to be passed in registers,+	   padded to an 8 byte boundary to preserve stack alignment */+	return FFI_ALIGN(MIN(stack - argp, 6*4), 8);+}++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+	ffi_type **ptr;+	unsigned i, bytes = 0;++	for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) {+		if ((*ptr)->size == 0)+			return FFI_BAD_TYPEDEF;++		/* Perform a sanity check on the argument type, do this+		   check after the initialization.  */+		FFI_ASSERT_VALID_TYPE(*ptr);++		/* Add any padding if necessary */+		if (((*ptr)->alignment - 1) & bytes)+			bytes = FFI_ALIGN(bytes, (*ptr)->alignment);++		bytes += FFI_ALIGN((*ptr)->size, 4);+	}++	/* Ensure arg space is aligned to an 8-byte boundary */+	bytes = FFI_ALIGN(bytes, 8);++	/* Make space for the return structure pointer */+	if (cif->rtype->type == FFI_TYPE_STRUCT) {+		bytes += sizeof(void*);++		/* Ensure stack is aligned to an 8-byte boundary */+		bytes = FFI_ALIGN(bytes, 8);+	}++	cif->bytes = bytes;++	/* Set the return type flag */+	switch (cif->rtype->type) {+	case FFI_TYPE_VOID:+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+		cif->flags = (unsigned) cif->rtype->type;+		break;+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+		cif->flags = (unsigned) FFI_TYPE_SINT64;+		break;+	case FFI_TYPE_STRUCT:+		/* Meta can store return values which are <= 64 bits */+		if (cif->rtype->size <= 4)+			/* Returned to D0Re0 as 32-bit value */+			cif->flags = (unsigned)FFI_TYPE_INT;+		else if ((cif->rtype->size > 4) && (cif->rtype->size <= 8))+			/* Returned valued is stored to D1Re0|R0Re0 */+			cif->flags = (unsigned)FFI_TYPE_DOUBLE;+		else+			/* value stored in memory */+			cif->flags = (unsigned)FFI_TYPE_STRUCT;+		break;+	default:+		cif->flags = (unsigned)FFI_TYPE_INT;+		break;+	}+	return FFI_OK;+}++extern void ffi_call_SYSV(void (*fn)(void), extended_cif *, unsigned, unsigned, double *);++/*+ * Exported in API. Entry point+ * cif -> ffi_cif object+ * fn -> function pointer+ * rvalue -> pointer to return value+ * avalue -> vector of void * pointers pointing to memory locations holding the+ * arguments+ */+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+	extended_cif ecif;++	int small_struct = (((cif->flags == FFI_TYPE_INT) || (cif->flags == FFI_TYPE_DOUBLE)) && (cif->rtype->type == FFI_TYPE_STRUCT));+	ecif.cif = cif;+	ecif.avalue = avalue;++	double temp;++	/*+	 * If the return value is a struct and we don't have a return value address+	 * then we need to make one+	 */++	if ((rvalue == NULL ) && (cif->flags == FFI_TYPE_STRUCT))+		ecif.rvalue = alloca(cif->rtype->size);+	else if (small_struct)+		ecif.rvalue = &temp;+	else+		ecif.rvalue = rvalue;++	switch (cif->abi) {+	case FFI_SYSV:+		ffi_call_SYSV(fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);+		break;+	default:+		FFI_ASSERT(0);+		break;+	}++	if (small_struct)+		memcpy (rvalue, &temp, cif->rtype->size);+}++/* private members */++static void ffi_prep_incoming_args_SYSV (char *, void **, void **,+	ffi_cif*, float *);++void ffi_closure_SYSV (ffi_closure *);++/* Do NOT change that without changing the FFI_TRAMPOLINE_SIZE */+extern unsigned int ffi_metag_trampoline[10]; /* 10 instructions */++/* end of private members */++/*+ * __tramp: trampoline memory location+ * __fun: assembly routine+ * __ctx: memory location for wrapper+ *+ * At this point, tramp[0] == __ctx !+ */+void ffi_init_trampoline(unsigned char *__tramp, unsigned int __fun, unsigned int __ctx) {+	memcpy (__tramp, ffi_metag_trampoline, sizeof(ffi_metag_trampoline));+	*(unsigned int*) &__tramp[40] = __ctx;+	*(unsigned int*) &__tramp[44] = __fun;+	/* This will flush the instruction cache */+	__builtin_meta2_cachewd(&__tramp[0], 1);+	__builtin_meta2_cachewd(&__tramp[47], 1);+}++++/* the cif must already be prepared */++ffi_status+ffi_prep_closure_loc (ffi_closure *closure,+	ffi_cif* cif,+	void (*fun)(ffi_cif*,void*,void**,void*),+	void *user_data,+	void *codeloc)+{+	void (*closure_func)(ffi_closure*) = NULL;++	if (cif->abi == FFI_SYSV)+		closure_func = &ffi_closure_SYSV;+	else+		return FFI_BAD_ABI;++	ffi_init_trampoline(+		(unsigned char*)&closure->tramp[0],+		(unsigned int)closure_func,+		(unsigned int)codeloc);++	closure->cif = cif;+	closure->user_data = user_data;+	closure->fun = fun;++	return FFI_OK;+}+++/* This function is jumped to by the trampoline */+unsigned int ffi_closure_SYSV_inner (closure, respp, args, vfp_args)+	ffi_closure *closure;+	void **respp;+	void *args;+	void *vfp_args;+{+	ffi_cif *cif;+	void **arg_area;++	cif = closure->cif;+	arg_area = (void**) alloca (cif->nargs * sizeof (void*));++	/*+	 * This call will initialize ARG_AREA, such that each+	 * element in that array points to the corresponding+	 * value on the stack; and if the function returns+	 * a structure, it will re-set RESP to point to the+	 * structure return address.+	 */+	ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args);++	(closure->fun) ( cif, *respp, arg_area, closure->user_data);++	return cif->flags;+}++static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,+	void **avalue, ffi_cif *cif,+	float *vfp_stack)+{+	register unsigned int i;+	register void **p_argv;+	register char *argp;+	register ffi_type **p_arg;++	/* stack points to original arguments */+	argp = stack;++	/* Store return value */+	if ( cif->flags == FFI_TYPE_STRUCT ) {+		argp -= 4;+		*rvalue = *(void **) argp;+	}++	p_argv = avalue;++	for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) {+		size_t z;+		size_t alignment;++		alignment = (*p_arg)->alignment;+		if (alignment < 4)+			alignment = 4;+		if ((alignment - 1) & (unsigned)argp)+			argp = (char *) FFI_ALIGN(argp, alignment);++		z = (*p_arg)->size;+		*p_argv = (void*) argp;+		p_argv++;+		argp -= z;+	}+	return;+}
+ src/metag/ffitarget.h view
@@ -0,0 +1,53 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2013 Imagination Technologies Ltd.+   Target configuration macros for Meta++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_DEFAULT_ABI = FFI_SYSV,+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1,+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 48+#define FFI_NATIVE_RAW_API 0++#endif+
+ src/metag/sysv.S view
@@ -0,0 +1,311 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2013 Imagination Technologies Ltd.++   Meta Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.+++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#ifdef HAVE_MACHINE_ASM_H+#include <machine/asm.h>+#else+#ifdef __USER_LABEL_PREFIX__+#define CONCAT1(a, b) CONCAT2(a, b)+#define CONCAT2(a, b) a ## b++/* Use the right prefix for global labels. */+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)+#else+#define CNAME(x) x+#endif+#define ENTRY(x) .globl CNAME(x); .type CNAME(x), %function; CNAME(x):+#endif++#ifdef __ELF__+#define LSYM(x) .x+#else+#define LSYM(x) x+#endif++.macro call_reg x=+	.text+	.balign 4+	mov D1RtP, \x+	swap D1RtP, PC+.endm++! Save register arguments+.macro SAVE_ARGS+	.text+	.balign 4+	setl	[A0StP++], D0Ar6, D1Ar5+	setl	[A0StP++], D0Ar4, D1Ar3+	setl	[A0StP++], D0Ar2, D1Ar1+.endm++! Save retrun, frame pointer and other regs+.macro SAVE_REGS regs=+	.text+	.balign 4+	setl	[A0StP++], D0FrT, D1RtP+	! Needs to be a pair of regs+	.ifnc "\regs",""+	setl	[A0StP++], \regs+	.endif+.endm++! Declare a global function+.macro METAG_FUNC_START name+	.text+	.balign 4+	ENTRY(\name)+.endm++! Return registers from the stack. Reverse SAVE_REGS operation+.macro RET_REGS regs=, cond=+	.ifnc "\regs", ""+	getl	\regs, [--A0StP]+	.endif+	getl	D0FrT, D1RtP, [--A0StP]+.endm++! Return arguments+.macro RET_ARGS+	getl	D0Ar2, D1Ar1, [--A0StP]+	getl	D0Ar4, D1Ar3, [--A0StP]+	getl	D0Ar6, D1Ar5, [--A0StP]+.endm+++	! D1Ar1:	fn+	! D0Ar2:	&ecif+	! D1Ar3:	cif->bytes+	! D0Ar4:	fig->flags+	! D1Ar5:	ecif.rvalue++	! This assumes we are using GNU as+METAG_FUNC_START ffi_call_SYSV+	! Save argument registers++	SAVE_ARGS++	! new frame+	mov	D0FrT, A0FrP+	add     A0FrP, A0StP, #0++	! Preserve the old frame pointer+	SAVE_REGS "D1.5, D0.5"++	! Make room for new args. cifs->bytes is the total space for input+	! and return arguments++	add	A0StP, A0StP, D1Ar3++	! Preserve cifs->bytes & fn+	mov	D0.5, D1Ar3+	mov	D1.5, D1Ar1++	! Place all of the ffi_prep_args in position+	mov	D1Ar1, A0StP++	! Call ffi_prep_args(stack, &ecif)+#ifdef __PIC__+	callr  D1RtP, CNAME(ffi_prep_args@PLT)+#else+	callr  D1RtP, CNAME(ffi_prep_args)+#endif++	! Restore fn pointer++	! The foreign stack should look like this+	! XXXXX XXXXXX <--- stack pointer+	! FnArgN rvalue+	! FnArgN+2 FnArgN+1+	! FnArgN+4 FnArgN+3+	! ....+	!++	! A0StP now points to the first (or return) argument + 4++	! Preserve cif->bytes+	getl	D0Ar2, D1Ar1, [--A0StP]+	getl	D0Ar4, D1Ar3, [--A0StP]+	getl	D0Ar6, D1Ar5, [--A0StP]++	! Place A0StP to the first argument again+	add	A0StP, A0StP, #24 ! That's because we loaded 6 regs x 4 byte each++	! A0FrP points to the initial stack without the reserved space for the+	! cifs->bytes, whilst A0StP points to the stack after the space allocation++	! fn was the first argument of ffi_call_SYSV.+	! The stack at this point looks like this:+	!+	! A0StP(on entry to _SYSV) ->	Arg6	Arg5     | low+	!				Arg4	Arg3     |+	! 				Arg2	Arg1     |+	! A0FrP ---->			D0FrtP	D1RtP    |+	!				D1.5	D0.5	 |+	! A0StP(bf prep_args) ->	FnArgn	FnArgn-1 |+	!				FnArgn-2FnArgn-3 |+	!				................ | <= cifs->bytes+	!				FnArg4  FnArg3	 |+	! A0StP (prv_A0StP+cifs->bytes) FnArg2  FnArg1   | high+	!+	! fn was in Arg1 so it's located in in A0FrP+#-0xC+	!++	! D0Re0 contains the size of arguments stored in registers+	sub	A0StP, A0StP, D0Re0++	! Arg1 is the function pointer for the foreign call. This has been+	! preserved in D1.5++	! Time to call (fn). Arguments should be like this:+	! Arg1-Arg6 are loaded to regs+	! The rest of the arguments are stored in stack pointed by A0StP++	call_reg D1.5++	! Reset stack.++	mov	A0StP, A0FrP++	! Load Arg1 with the pointer to storage for the return type+	! This was stored in Arg5++	getd	D1Ar1, [A0FrP+#-20]++	! Load D0Ar2 with the return type code. This was stored in Arg4 (flags)++	getd	D0Ar2, [A0FrP+#-16]++	! We are ready to start processing the return value+	! D0Re0 (and D1Re0) hold the return value++	! If the return value is NULL, assume no return value+	cmp	D1Ar1, #0+	beq	LSYM(Lepilogue)++	! return INT+	cmp		D0Ar2, #FFI_TYPE_INT+	! Sadly, there is no setd{cc} instruction so we need to workaround that+	bne	.INT64+	setd	[D1Ar1], D0Re0+	b	LSYM(Lepilogue)++	! return INT64+.INT64:+	cmp	D0Ar2, #FFI_TYPE_SINT64+	setleq	[D1Ar1], D0Re0, D1Re0++	! return DOUBLE+	cmp	D0Ar2, #FFI_TYPE_DOUBLE+	setl	[D1AR1++], D0Re0, D1Re0++LSYM(Lepilogue):+	! At this point, the stack pointer points right after the argument+	! saved area. We need to restore 4 regs, therefore we need to move+	! 16 bytes ahead.+	add     A0StP, A0StP, #16+	RET_REGS "D1.5, D0.5"+	RET_ARGS+	getd	D0Re0, [A0StP]+	mov     A0FrP, D0FrT+	swap	D1RtP, PC++.ffi_call_SYSV_end:+       .size   CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)+++/*+	(called by ffi_metag_trampoline)+	void ffi_closure_SYSV (ffi_closure*)++	(called by ffi_closure_SYSV)+	unsigned int FFI_HIDDEN+	ffi_closure_SYSV_inner (closure,respp, args)+		ffi_closure *closure;+		void **respp;+		void *args;+*/++METAG_FUNC_START ffi_closure_SYSV+	! We assume that D1Ar1 holds the address of the+	! ffi_closure struct. We will use that to fetch the+	! arguments. The stack pointer points to an empty space+	! and it is ready to store more data.++	! D1Ar1 is ready+	! Allocate stack space for return value+	add A0StP, A0StP, #8+	! Store it to D0Ar2+	sub D0Ar2, A0StP, #8++	sub D1Ar3, A0FrP, #4++	! D1Ar3 contains the address of the original D1Ar1 argument+	! We need to subtract #4 later on++	! Preverve D0Ar2+	mov D0.5, D0Ar2++#ifdef __PIC__+	callr D1RtP, CNAME(ffi_closure_SYSV_inner@PLT)+#else+	callr D1RtP, CNAME(ffi_closure_SYSV_inner)+#endif++	! Check the return value and store it to D0.5+	cmp D0Re0, #FFI_TYPE_INT+	beq .Lretint+	cmp D0Re0, #FFI_TYPE_DOUBLE+	beq .Lretdouble+.Lclosure_epilogue:+	sub A0StP, A0StP, #8+	RET_REGS "D1.5, D0.5"+	RET_ARGS+	swap	D1RtP, PC++.Lretint:+	setd [D0.5], D0Re0+	b .Lclosure_epilogue+.Lretdouble:+	setl [D0.5++], D0Re0, D1Re0+	b .Lclosure_epilogue+.ffi_closure_SYSV_end:+.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)+++ENTRY(ffi_metag_trampoline)+	SAVE_ARGS+	! New frame+	mov A0FrP, A0StP+	SAVE_REGS "D1.5, D0.5"+	mov D0.5, PC+	! Load D1Ar1 the value of ffi_metag_trampoline+	getd D1Ar1, [D0.5 + #8]+	! Jump to ffi_closure_SYSV+	getd PC, [D0.5 + #12]
+ src/microblaze/ffi.c view
@@ -0,0 +1,321 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2012, 2013 Xilinx, Inc++   MicroBlaze 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>++extern void ffi_call_SYSV(void (*)(void*, extended_cif*), extended_cif*,+		unsigned int, unsigned int, unsigned int*, void (*fn)(void),+		unsigned int, unsigned int);++extern void ffi_closure_SYSV(void);++#define WORD_SIZE			sizeof(unsigned int)+#define ARGS_REGISTER_SIZE	(WORD_SIZE * 6)+#define WORD_FFI_ALIGN(x)		FFI_ALIGN(x, WORD_SIZE)++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments */+void ffi_prep_args(void* stack, extended_cif* ecif)+{+	unsigned int i;+	ffi_type** p_arg;+	void** p_argv;+	void* stack_args_p = stack;++	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))+	{+		/* if return type is a struct which is referenced on the stack/reg5,+		 * by a pointer. Stored the return value pointer in r5.+		 */+		char* addr = stack_args_p;+		memcpy(addr, &(ecif->rvalue), WORD_SIZE);+		stack_args_p += WORD_SIZE;+	}++	if (ecif->avalue == NULL) {+		return; /* no arguments to prepare */+	}++	for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;+			i++, p_arg++)+	{+		size_t size = (*p_arg)->size;+		int type = (*p_arg)->type;+		void* value = p_argv[i];+		char* addr = stack_args_p;+		int aligned_size = WORD_FFI_ALIGN(size);++		/* force word alignment on the stack */+		stack_args_p += aligned_size;+		+		switch (type)+		{+			case FFI_TYPE_UINT8:+				*(unsigned int *)addr = (unsigned int)*(UINT8*)(value);+				break;+			case FFI_TYPE_SINT8:+				*(signed int *)addr = (signed int)*(SINT8*)(value);+				break;+			case FFI_TYPE_UINT16:+				*(unsigned int *)addr = (unsigned int)*(UINT16*)(value);+				break;+			case FFI_TYPE_SINT16:+				*(signed int *)addr = (signed int)*(SINT16*)(value);+				break;+			case FFI_TYPE_STRUCT:+#if __BIG_ENDIAN__+				/*+				 * MicroBlaze toolchain appears to emit:+				 * bsrli r5, r5, 8 (caller)+				 * ...+				 * <branch to callee>+				 * ...+				 * bslli r5, r5, 8 (callee)+				 * +				 * For structs like "struct a { uint8_t a[3]; };", when passed+				 * by value.+				 *+				 * Structs like "struct b { uint16_t a; };" are also expected+				 * to be packed strangely in registers.+				 *+				 * This appears to be because the microblaze toolchain expects+				 * "struct b == uint16_t", which is only any issue for big+				 * endian.+				 *+				 * The following is a work around for big-endian only, for the+				 * above mentioned case, it will re-align the contents of a+				 * <= 3-byte struct value.+				 */+				if (size < WORD_SIZE)+				{+				  memcpy (addr + (WORD_SIZE - size), value, size);+				  break;+				}+#endif+			case FFI_TYPE_SINT32:+			case FFI_TYPE_UINT32:+			case FFI_TYPE_FLOAT:+			case FFI_TYPE_SINT64:+			case FFI_TYPE_UINT64:+			case FFI_TYPE_DOUBLE:+			default:+				memcpy(addr, value, aligned_size);+		}+	}+}++ffi_status ffi_prep_cif_machdep(ffi_cif* cif)+{+	/* check ABI */+	switch (cif->abi)+	{+		case FFI_SYSV:+			break;+		default:+			return FFI_BAD_ABI;+	}+	return FFI_OK;+}++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_SYSV:+		ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags,+				ecif.rvalue, fn, cif->rtype->type, cif->rtype->size);+		break;+	default:+		FFI_ASSERT(0);+		break;+	}+}++void ffi_closure_call_SYSV(void* register_args, void* stack_args,+			ffi_closure* closure, void* rvalue,+			unsigned int* rtype, unsigned int* rsize)+{+	/* prepare arguments for closure call */+	ffi_cif* cif = closure->cif;+	ffi_type** arg_types = cif->arg_types;++	/* re-allocate data for the args. This needs to be done in order to keep+	 * multi-word objects (e.g. structs) in contiguous memory. Callers are not+	 * required to store the value of args in the lower 6 words in the stack+	 * (although they are allocated in the stack).+	 */+	char* stackclone = alloca(cif->bytes);+	void** avalue = alloca(cif->nargs * sizeof(void*));+	void* struct_rvalue = NULL;+	char* ptr = stackclone;+	int i;++	/* copy registers into stack clone */+	int registers_used = cif->bytes;+	if (registers_used > ARGS_REGISTER_SIZE) {+		registers_used = ARGS_REGISTER_SIZE;+	}+	memcpy(stackclone, register_args, registers_used);++	/* copy stack allocated args into stack clone */+	if (cif->bytes > ARGS_REGISTER_SIZE) {+		int stack_used = cif->bytes - ARGS_REGISTER_SIZE;+		memcpy(stackclone + ARGS_REGISTER_SIZE, stack_args, stack_used);+	}++	/* preserve struct type return pointer passing */+	if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) {+		struct_rvalue = *((void**)ptr);+		ptr += WORD_SIZE;+	}++	/* populate arg pointer list */+	for (i = 0; i < cif->nargs; i++)+	{+		switch (arg_types[i]->type)+		{+			case FFI_TYPE_SINT8:+			case FFI_TYPE_UINT8:+#ifdef __BIG_ENDIAN__+				avalue[i] = ptr + 3;+#else+				avalue[i] = ptr;+#endif+				break;+			case FFI_TYPE_SINT16:+			case FFI_TYPE_UINT16:+#ifdef __BIG_ENDIAN__+				avalue[i] = ptr + 2;+#else+				avalue[i] = ptr;+#endif+				break;+			case FFI_TYPE_STRUCT:+#if __BIG_ENDIAN__+				/*+				 * Work around strange ABI behaviour.+				 * (see info in ffi_prep_args)+				 */+				if (arg_types[i]->size < WORD_SIZE)+				{+				  memcpy (ptr, ptr + (WORD_SIZE - arg_types[i]->size), arg_types[i]->size);+				}+#endif+				avalue[i] = (void*)ptr;+				break;+			case FFI_TYPE_UINT64:+			case FFI_TYPE_SINT64:+			case FFI_TYPE_DOUBLE:+				avalue[i] = ptr;+				break;+			case FFI_TYPE_SINT32:+			case FFI_TYPE_UINT32:+			case FFI_TYPE_FLOAT:+			default:+				/* default 4-byte argument */+				avalue[i] = ptr;+				break;+		}+		ptr += WORD_FFI_ALIGN(arg_types[i]->size);+	}++	/* set the return type info passed back to the wrapper */+	*rsize = cif->rtype->size;+	*rtype = cif->rtype->type;+	if (struct_rvalue != NULL) {+		closure->fun(cif, struct_rvalue, avalue, closure->user_data);+		/* copy struct return pointer value into function return value */+		*((void**)rvalue) = struct_rvalue;+	} else {+		closure->fun(cif, rvalue, avalue, closure->user_data);+	}+}++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 long* tramp = (unsigned long*)&(closure->tramp[0]);+	unsigned long cls = (unsigned long)codeloc;+	unsigned long fn = 0;+	unsigned long fn_closure_call_sysv = (unsigned long)ffi_closure_call_SYSV;++	closure->cif = cif;+	closure->fun = fun;+	closure->user_data = user_data;++	switch (cif->abi)+	{+	case FFI_SYSV:+		fn = (unsigned long)ffi_closure_SYSV;++		/* load r11 (temp) with fn */+		/* imm fn(upper) */+		tramp[0] = 0xb0000000 | ((fn >> 16) & 0xffff);+		/* addik r11, r0, fn(lower) */+		tramp[1] = 0x31600000 | (fn & 0xffff);++		/* load r12 (temp) with cls */+		/* imm cls(upper) */+		tramp[2] = 0xb0000000 | ((cls >> 16) & 0xffff);+		/* addik r12, r0, cls(lower) */+		tramp[3] = 0x31800000 | (cls & 0xffff);++		/* load r3 (temp) with ffi_closure_call_SYSV */+		/* imm fn_closure_call_sysv(upper) */+		tramp[4] = 0xb0000000 | ((fn_closure_call_sysv >> 16) & 0xffff);+		/* addik r3, r0, fn_closure_call_sysv(lower) */+		tramp[5] = 0x30600000 | (fn_closure_call_sysv & 0xffff);+		/* branch/jump to address stored in r11 (fn) */+		tramp[6] = 0x98085800; /* bra r11 */++		break;+	default:+		return FFI_BAD_ABI;+	}+	return FFI_OK;+}
+ src/microblaze/ffitarget.h view
@@ -0,0 +1,53 @@+/* -----------------------------------------------------------------------+   ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc++   Target configuration macros for MicroBlaze.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long			ffi_arg;+typedef signed long			ffi_sarg;++typedef enum ffi_abi {+	FFI_FIRST_ABI = 0,+	FFI_SYSV,+	FFI_LAST_ABI,+	FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++/* Definitions for closures */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++#define FFI_TRAMPOLINE_SIZE (4*8)++#endif
+ src/microblaze/sysv.S view
@@ -0,0 +1,302 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2012, 2013 Xilinx, Inc++   MicroBlaze Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++	/*+	 * arg[0] (r5)  = ffi_prep_args,+	 * arg[1] (r6)  = &ecif,+	 * arg[2] (r7)  = cif->bytes,+	 * arg[3] (r8)  = cif->flags,+	 * arg[4] (r9)  = ecif.rvalue,+	 * arg[5] (r10) = fn+	 * arg[6] (sp[0]) = cif->rtype->type+	 * arg[7] (sp[4]) = cif->rtype->size+	 */+	.text+	.globl ffi_call_SYSV+	.type ffi_call_SYSV, @function+ffi_call_SYSV:+	/* push callee saves */+	addik r1, r1, -20+	swi r19, r1, 0 /* Frame Pointer */+	swi r20, r1, 4 /* PIC register */+	swi r21, r1, 8 /* PIC register */+	swi r22, r1, 12 /* save for locals */+	swi r23, r1, 16 /* save for locals */+	+	/* save the r5-r10 registers in the stack */+	addik r1, r1, -24 /* increment sp to store 6x 32-bit words */+	swi r5, r1, 0+	swi r6, r1, 4+	swi r7, r1, 8+	swi r8, r1, 12+	swi r9, r1, 16+	swi r10, r1, 20++	/* save function pointer */+	addik r3, r5, 0 /* copy ffi_prep_args into r3 */+	addik r22, r1, 0 /* save sp for unallocated args into r22 (callee-saved) */+	addik r23, r10, 0 /* save function address into r23 (callee-saved) */++	/* prepare stack with allocation for n (bytes = r7) args */+	rsub r1, r7, r1 /* subtract bytes from sp */++	/* prep args for ffi_prep_args call */+	addik r5, r1, 0 /* store stack pointer into arg[0] */+	/* r6 still holds ecif for arg[1] */++	/* Call ffi_prep_args(stack, &ecif). */+	addik r1, r1, -4+	swi r15, r1, 0 /* store the link register in the frame */+	brald r15, r3+	nop /* branch has delay slot */+	lwi r15, r1, 0+	addik r1, r1, 4 /* restore the link register from the frame */+	/* returns calling stack pointer location */++	/* prepare args for fn call, prep_args populates them onto the stack */+	lwi r5, r1, 0 /* arg[0] */+	lwi r6, r1, 4 /* arg[1] */+	lwi r7, r1, 8 /* arg[2] */+	lwi r8, r1, 12 /* arg[3] */+	lwi r9, r1, 16 /* arg[4] */+	lwi r10, r1, 20 /* arg[5] */++	/* call (fn) (...). */+	addik r1, r1, -4+	swi r15, r1, 0 /* store the link register in the frame */+	brald r15, r23+	nop /* branch has delay slot */+	lwi r15, r1, 0+	addik r1, r1, 4 /* restore the link register from the frame */++	/* Remove the space we pushed for the args. */+	addik r1, r22, 0 /* restore old SP */++	/* restore this functions parameters */+	lwi r5, r1, 0 /* arg[0] */+	lwi r6, r1, 4 /* arg[1] */+	lwi r7, r1, 8 /* arg[2] */+	lwi r8, r1, 12 /* arg[3] */+	lwi r9, r1, 16 /* arg[4] */+	lwi r10, r1, 20 /* arg[5] */+	addik r1, r1, 24 /* decrement sp to de-allocate 6x 32-bit words */++	/* If the return value pointer is NULL, assume no return value. */+	beqi r9, ffi_call_SYSV_end++	lwi r22, r1, 48 /* get return type (20 for locals + 28 for arg[6]) */+	lwi r23, r1, 52 /* get return size (20 for locals + 32 for arg[7])  */+	+	/* Check if return type is actually a struct, do nothing */+	rsubi r11, r22, FFI_TYPE_STRUCT+	beqi r11, ffi_call_SYSV_end++	/* Return 8bit */+	rsubi r11, r23, 1+	beqi r11, ffi_call_SYSV_store8++	/* Return 16bit */+	rsubi r11, r23, 2+	beqi r11, ffi_call_SYSV_store16++	/* Return 32bit */+	rsubi r11, r23, 4+	beqi r11, ffi_call_SYSV_store32++	/* Return 64bit */+	rsubi r11, r23, 8+	beqi r11, ffi_call_SYSV_store64++	/* Didn't match anything */+	bri ffi_call_SYSV_end++ffi_call_SYSV_store64:+	swi r3, r9, 0 /* store word r3 into return value */+	swi r4, r9, 4 /* store word r4 into return value */+	bri ffi_call_SYSV_end++ffi_call_SYSV_store32:+	swi r3, r9, 0 /* store word r3 into return value */+	bri ffi_call_SYSV_end++ffi_call_SYSV_store16:+#ifdef __BIG_ENDIAN__+	shi r3, r9, 2 /* store half-word r3 into return value */+#else+	shi r3, r9, 0 /* store half-word r3 into return value */+#endif+	bri ffi_call_SYSV_end++ffi_call_SYSV_store8:+#ifdef __BIG_ENDIAN__+	sbi r3, r9, 3 /* store byte r3 into return value */+#else+	sbi r3, r9, 0 /* store byte r3 into return value */+#endif+	bri ffi_call_SYSV_end++ffi_call_SYSV_end:+	/* callee restores */+	lwi r19, r1, 0 /* frame pointer */+	lwi r20, r1, 4 /* PIC register */+	lwi r21, r1, 8 /* PIC register */+	lwi r22, r1, 12+	lwi r23, r1, 16+	addik r1, r1, 20++	/* return from sub-routine (with delay slot) */+	rtsd r15, 8+	nop++	.size ffi_call_SYSV, . - ffi_call_SYSV++/* ------------------------------------------------------------------------- */++	/*+	 * args passed into this function, are passed down to the callee.+	 * this function is the target of the closure trampoline, as such r12 is +	 * a pointer to the closure object.+	 */+	.text+	.globl ffi_closure_SYSV+	.type ffi_closure_SYSV, @function+ffi_closure_SYSV:+	/* push callee saves */+	addik r11, r1, 28 /* save stack args start location (excluding regs/link) */+	addik r1, r1, -12+	swi r19, r1, 0 /* Frame Pointer */+	swi r20, r1, 4 /* PIC register */+	swi r21, r1, 8 /* PIC register */++	/* store register args on stack */+	addik r1, r1, -24+	swi r5, r1, 0+	swi r6, r1, 4+	swi r7, r1, 8+	swi r8, r1, 12+	swi r9, r1, 16+	swi r10, r1, 20++	/* setup args */+	addik r5, r1, 0 /* register_args */+	addik r6, r11, 0 /* stack_args */+	addik r7, r12, 0 /* closure object */+	addik r1, r1, -8 /* allocate return value */+	addik r8, r1, 0 /* void* rvalue */+	addik r1, r1, -8 /* allocate for return type/size values */+	addik r9, r1, 0 /* void* rtype */+	addik r10, r1, 4 /* void* rsize */++	/* call the wrap_call function */+	addik r1, r1, -28 /* allocate args + link reg */+	swi r15, r1, 0 /* store the link register in the frame */+	brald r15, r3+	nop /* branch has delay slot */+	lwi r15, r1, 0+	addik r1, r1, 28 /* restore the link register from the frame */++ffi_closure_SYSV_prepare_return:+	lwi r9, r1, 0 /* rtype */+	lwi r10, r1, 4 /* rsize */+	addik r1, r1, 8 /* de-allocate return info values */++	/* Check if return type is actually a struct, store 4 bytes */+	rsubi r11, r9, FFI_TYPE_STRUCT+	beqi r11, ffi_closure_SYSV_store32++	/* Return 8bit */+	rsubi r11, r10, 1+	beqi r11, ffi_closure_SYSV_store8++	/* Return 16bit */+	rsubi r11, r10, 2+	beqi r11, ffi_closure_SYSV_store16++	/* Return 32bit */+	rsubi r11, r10, 4+	beqi r11, ffi_closure_SYSV_store32++	/* Return 64bit */+	rsubi r11, r10, 8+	beqi r11, ffi_closure_SYSV_store64++	/* Didn't match anything */+	bri ffi_closure_SYSV_end++ffi_closure_SYSV_store64:+	lwi r3, r1, 0 /* store word r3 into return value */+	lwi r4, r1, 4 /* store word r4 into return value */+	/* 64 bits == 2 words, no sign extend occurs */+	bri ffi_closure_SYSV_end++ffi_closure_SYSV_store32:+	lwi r3, r1, 0 /* store word r3 into return value */+	/* 32 bits == 1 word, no sign extend occurs */+	bri ffi_closure_SYSV_end++ffi_closure_SYSV_store16:+#ifdef __BIG_ENDIAN__+	lhui r3, r1, 2 /* store half-word r3 into return value */+#else+	lhui r3, r1, 0 /* store half-word r3 into return value */+#endif+	rsubi r11, r9, FFI_TYPE_SINT16+	bnei r11, ffi_closure_SYSV_end+	sext16 r3, r3 /* fix sign extend of sint8 */+	bri ffi_closure_SYSV_end++ffi_closure_SYSV_store8:+#ifdef __BIG_ENDIAN__+	lbui r3, r1, 3 /* store byte r3 into return value */+#else+	lbui r3, r1, 0 /* store byte r3 into return value */+#endif+	rsubi r11, r9, FFI_TYPE_SINT8+	bnei r11, ffi_closure_SYSV_end+	sext8 r3, r3 /* fix sign extend of sint8 */+	bri ffi_closure_SYSV_end++ffi_closure_SYSV_end:+	addik r1, r1, 8 /* de-allocate return value */++	/* de-allocate stored args */+	addik r1, r1, 24++	/* callee restores */+	lwi r19, r1, 0 /* frame pointer */+	lwi r20, r1, 4 /* PIC register */+	lwi r21, r1, 8 /* PIC register */+	addik r1, r1, 12++	/* return from sub-routine (with delay slot) */+	rtsd r15, 8+	nop++	.size ffi_closure_SYSV, . - ffi_closure_SYSV
+ src/mips/ffi.c view
@@ -0,0 +1,1317 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2011  Anthony Green+           Copyright (c) 2008  David Daney+           Copyright (c) 1996, 2007, 2008, 2011  Red Hat, Inc.+   +   MIPS 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 <stdint.h>+#include <stdlib.h>+#include <stdio.h>++#ifdef __GNUC__+#  if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))+#    define USE__BUILTIN___CLEAR_CACHE 1+#  endif+#endif++#ifndef USE__BUILTIN___CLEAR_CACHE+#  if defined(__FreeBSD__)+#    include <machine/sysarch.h>+#  elif defined(__OpenBSD__)+#    include <mips64/sysarch.h>+#  else+#    include <sys/cachectl.h>+#  endif+#endif++#ifdef FFI_DEBUG+# define FFI_MIPS_STOP_HERE() ffi_stop_here()+#else+# define FFI_MIPS_STOP_HERE() do {} while(0)+#endif++#ifdef FFI_MIPS_N32+#define FIX_ARGP \+FFI_ASSERT(argp <= &stack[bytes]); \+if (argp == &stack[bytes]) \+{ \+  argp = stack; \+  FFI_MIPS_STOP_HERE(); \+}+#else+#define FIX_ARGP +#endif+++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments */++static void ffi_prep_args(char *stack, +			  extended_cif *ecif,+			  int bytes,+			  int flags)+{+  int i;+  void **p_argv;+  char *argp, *argp_f;+  ffi_type **p_arg;++  memset(stack, 0, bytes);++#ifdef FFI_MIPS_N32+  int soft_float = (ecif->cif->abi == FFI_N32_SOFT_FLOAT+		    || ecif->cif->abi == FFI_N64_SOFT_FLOAT);+  /* If more than 8 double words are used, the remainder go+     on the stack. We reorder stuff on the stack here to +     support this easily. */+  /* if ret is _Complex long double, args reg shift2, and a0 should holds pointer to rvalue */+  if (ecif->cif->rtype->type == FFI_TYPE_COMPLEX && ecif->cif->rtype->elements[0]->type == FFI_TYPE_LONGDOUBLE)+    {+      if (bytes + 16 > 8 * sizeof(ffi_arg))+        argp = &stack[bytes - (8 * sizeof(ffi_arg))];+      else+        argp = stack;+      * (unsigned long *) argp = (unsigned long) ecif->rvalue;+      argp += 16;+    }+  else+    {+      if (bytes > 8 * sizeof(ffi_arg))+        argp = &stack[bytes - (8 * sizeof(ffi_arg))];+      else+        argp = stack;+    }+#else+  argp = stack;+#endif++  argp_f = argp;++#ifdef FFI_MIPS_N32+  if ( ecif->cif->rstruct_flag != 0 )+#else+  if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )+#endif  +    {+      *(ffi_arg *) argp = (ffi_arg) ecif->rvalue;+      argp += sizeof(ffi_arg);+      FIX_ARGP;+    }++  p_argv = ecif->avalue;++  for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)+    {+      size_t z;+      unsigned int a;++      /* Align if necessary.  */+      a = (*p_arg)->alignment;+      if (a < sizeof(ffi_arg))+        a = sizeof(ffi_arg);+      +      if ((a - 1) & (unsigned long) argp)+	{+	  argp = (char *) FFI_ALIGN(argp, a);+	  FIX_ARGP;+	}++      z = (*p_arg)->size;+      if (z <= sizeof(ffi_arg))+	{+          int type = (*p_arg)->type;+	  z = sizeof(ffi_arg);++          /* The size of a pointer depends on the ABI */+          if (type == FFI_TYPE_POINTER)+            type = (ecif->cif->abi == FFI_N64+		    || ecif->cif->abi == FFI_N64_SOFT_FLOAT)+	      ? FFI_TYPE_SINT64 : FFI_TYPE_UINT32;++	if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT+		      || ecif->cif->abi == FFI_N64_SOFT_FLOAT))+	  {+	    switch (type)+	      {+	      case FFI_TYPE_FLOAT:+		type = FFI_TYPE_UINT32;+		break;+	      case FFI_TYPE_DOUBLE:+		type = FFI_TYPE_UINT64;+		break;+	      default:+		break;+	      }+	  }+	  switch (type)+	    {+	      case FFI_TYPE_SINT8:+		*(ffi_arg *)argp = *(SINT8 *)(* p_argv);+		break;++	      case FFI_TYPE_UINT8:+		*(ffi_arg *)argp = *(UINT8 *)(* p_argv);+		break;+		  +	      case FFI_TYPE_SINT16:+		*(ffi_arg *)argp = *(SINT16 *)(* p_argv);+		break;+		  +	      case FFI_TYPE_UINT16:+		*(ffi_arg *)argp = *(UINT16 *)(* p_argv);+		break;+		  +	      case FFI_TYPE_SINT32:+		*(ffi_arg *)argp = *(SINT32 *)(* p_argv);+		break;+		  +	      case FFI_TYPE_UINT32:+#ifdef FFI_MIPS_N32+		/* The N32 ABI requires that 32-bit integers+		   be sign-extended to 64-bits, regardless of+		   whether they are signed or unsigned. */+		*(ffi_arg *)argp = *(SINT32 *)(* p_argv);+#else+		*(ffi_arg *)argp = *(UINT32 *)(* p_argv);+#endif+		break;++#ifdef FFI_MIPS_N32+	      case FFI_TYPE_COMPLEX:+		/* expand from 4+4 to 8+8 if pass with fpr reg */+		/* argp will wind back to stack when we process all of reg args */+		/* all var_args passed with gpr, should be expand */+	        if(!soft_float+		    && (*p_arg)->elements[0]->type == FFI_TYPE_FLOAT+		    && argp>=argp_f+		    && i < ecif->cif->mips_nfixedargs)+		  {+		    *(float *) argp = *(float *)(* p_argv);+		    argp += z;+		    char *tmp = (void *) (*p_argv);+		    *(float *) argp = *(float *)(tmp+4);+		  }+		else+		  memcpy(argp, *p_argv, (*p_arg)->size);+		break;+#endif+	      /* This can only happen with 64bit slots.  */+	      case FFI_TYPE_FLOAT:+		*(float *) argp = *(float *)(* p_argv);+		break;++	      /* Handle structures.  */+	      default:+		memcpy(argp, *p_argv, (*p_arg)->size);+		break;+	    }+	}+      else+	{+#ifdef FFI_MIPS_O32+	  memcpy(argp, *p_argv, z);+#else+	  {+	    unsigned long end = (unsigned long) argp + z;+	    unsigned long cap = (unsigned long) stack + bytes;++	    /* Check if the data will fit within the register space.+	       Handle it if it doesn't.  */++	    if (end <= cap)+	      memcpy(argp, *p_argv, z);+	    else+	      {+		unsigned long portion = cap - (unsigned long)argp;++		memcpy(argp, *p_argv, portion);+		argp = stack;+                z -= portion;+		memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),+                       z);+	      }+	  }+#endif+      }+      p_argv++;+      argp += z;+      FIX_ARGP;+    }+}++#ifdef FFI_MIPS_N32++/* The n32 spec says that if "a chunk consists solely of a double +   float field (but not a double, which is part of a union), it+   is passed in a floating point register. Any other chunk is+   passed in an integer register". This code traverses structure+   definitions and generates the appropriate flags. */++static int+calc_n32_struct_flags_element(unsigned *flags, ffi_type *e,+			      unsigned *loc, unsigned *arg_reg)+{+  /* Align this object.  */+  *loc = FFI_ALIGN(*loc, e->alignment);+  if (e->type == FFI_TYPE_DOUBLE)+    {+      /* Already aligned to FFI_SIZEOF_ARG.  */+      *arg_reg = *loc / FFI_SIZEOF_ARG;+      if (*arg_reg > 7)+	return 1;+      *flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));+    }+  *loc += e->size;+  return 0;+}++static unsigned+calc_n32_struct_flags(int soft_float, ffi_type *arg,+		      unsigned *loc, unsigned *arg_reg)+{+  unsigned flags = 0;+  unsigned index = 0;++  ffi_type *e;++  if (soft_float)+    return 0;++  while ((e = arg->elements[index]))+    {+      if (e->type == FFI_TYPE_COMPLEX)+	{+	  if (calc_n32_struct_flags_element(&flags, e->elements[0], loc, arg_reg))+	    break;+	  if (calc_n32_struct_flags_element(&flags, e->elements[0], loc, arg_reg))+	    break;+	}+      else+	if (calc_n32_struct_flags_element(&flags, e, loc, arg_reg))+	  break;+      index++;+    }+  /* Next Argument register at alignment of FFI_SIZEOF_ARG.  */+  *arg_reg = FFI_ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;++  return flags;+}++static unsigned+calc_n32_return_struct_flags(int soft_float, ffi_type *arg)+{+  unsigned flags;+  unsigned small = FFI_TYPE_SMALLSTRUCT;+  ffi_type *e;++  /* Returning structures under n32 is a tricky thing.+     A struct with only one or two floating point fields +     is returned in $f0 (and $f2 if necessary). Any other+     struct results at most 128 bits are returned in $2+     (the first 64 bits) and $3 (remainder, if necessary).+     Larger structs are handled normally. */+  +  if (arg->size > 16)+    return 0;++  if (arg->size > 8)+    small = FFI_TYPE_SMALLSTRUCT2;++  e = arg->elements[0];++  if (e->type == FFI_TYPE_COMPLEX)+    {+      int type = e->elements[0]->type;++      if (type != FFI_TYPE_DOUBLE && type != FFI_TYPE_FLOAT)+	return small;++      if (arg->elements[1])+	{+	  /* Two floating point fields with more fields!+	     This must be passed the old way. */+	  return small;+	}++      flags = (type << FFI_FLAG_BITS) + type;+    }+  else+    {+      if (e->type != FFI_TYPE_DOUBLE && e->type != FFI_TYPE_FLOAT)+	return small;++      flags = e->type;++      if (arg->elements[1])+	{+	  e = arg->elements[1];+	  if (e->type != FFI_TYPE_DOUBLE && e->type != FFI_TYPE_FLOAT)+	    return small;++	  if (arg->elements[2])+	    {+	      /* There are three arguments and the first two are+		 floats! This must be passed the old way. */+	      return small;+	    }++	  flags += e->type << FFI_FLAG_BITS;+	}+    }++  if (soft_float)+    flags += FFI_TYPE_STRUCT_SOFT;+  return flags;+}++#endif++/* Perform machine dependent cif processing */+static ffi_status ffi_prep_cif_machdep_int(ffi_cif *cif, unsigned nfixedargs)+{+  cif->flags = 0;+  cif->mips_nfixedargs = nfixedargs;++#ifdef FFI_MIPS_O32+  /* Set the flags necessary for O32 processing.  FFI_O32_SOFT_FLOAT+   * does not have special handling for floating point args.+   */++  if (cif->rtype->type != FFI_TYPE_STRUCT && cif->rtype->type != FFI_TYPE_COMPLEX && cif->abi == FFI_O32)+    {+      if (cif->nargs > 0 && cif->nargs == nfixedargs)+	{+	  switch ((cif->arg_types)[0]->type)+	    {+	    case FFI_TYPE_FLOAT:+	    case FFI_TYPE_DOUBLE:+	      cif->flags += (cif->arg_types)[0]->type;+	      break;+	      +	    default:+	      break;+	    }++	  if (cif->nargs > 1)+	    {+	      /* Only handle the second argument if the first+		 is a float or double. */+	      if (cif->flags)+		{+		  switch ((cif->arg_types)[1]->type)+		    {+		    case FFI_TYPE_FLOAT:+		    case FFI_TYPE_DOUBLE:+		      cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;+		      break;+		      +		    default:+		      break;+		    }+		}+	    }+	}+    }+      +  /* Set the return type flag */++  if (cif->abi == FFI_O32_SOFT_FLOAT)+    {+      switch (cif->rtype->type)+        {+        case FFI_TYPE_VOID:+        case FFI_TYPE_STRUCT:+          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);+          break;++        case FFI_TYPE_SINT64:+        case FFI_TYPE_UINT64:+        case FFI_TYPE_DOUBLE:+          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);+          break;+      +        case FFI_TYPE_FLOAT:+        default:+          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);+          break;+        }+    }+  else+    {+      /* FFI_O32 */      +      switch (cif->rtype->type)+        {+        case FFI_TYPE_VOID:+        case FFI_TYPE_STRUCT:+        case FFI_TYPE_FLOAT:+        case FFI_TYPE_DOUBLE:+        case FFI_TYPE_COMPLEX:+          cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);+	  if (cif->rtype->type == FFI_TYPE_COMPLEX)+            cif->flags +=  ((*cif->rtype->elements[0]).type) << (FFI_FLAG_BITS * 4);+          break;++        case FFI_TYPE_SINT64:+        case FFI_TYPE_UINT64:+          cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 2);+          break;+      +        default:+          cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);+          break;+        }+    }+#endif++#ifdef FFI_MIPS_N32+  /* Set the flags necessary for N32 processing */+  {+    unsigned arg_reg = 0;+    unsigned loc = 0;+    unsigned count = (cif->nargs < 8) ? cif->nargs : 8;+    unsigned index = 0;++    unsigned struct_flags = 0;+    int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT+		      || cif->abi == FFI_N64_SOFT_FLOAT);++    if (cif->rtype->type == FFI_TYPE_STRUCT)+      {+	struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);++	if (struct_flags == 0)+	  {+	    /* This means that the structure is being passed as+	       a hidden argument */++	    arg_reg = 1;+	    count = (cif->nargs < 7) ? cif->nargs : 7;++	    cif->rstruct_flag = !0;+	  }+	else+	    cif->rstruct_flag = 0;+      }+    else+      cif->rstruct_flag = 0;++    while (count-- > 0 && arg_reg < 8)+      {+	ffi_type *t = cif->arg_types[index];++	switch (t->type)+	  {+	  case FFI_TYPE_FLOAT:+	  case FFI_TYPE_DOUBLE:+	    if (!soft_float && index < nfixedargs)+              cif->flags += t->type << (arg_reg * FFI_FLAG_BITS);+	    arg_reg++;+	    break;+          case FFI_TYPE_LONGDOUBLE:+            /* Align it.  */+            arg_reg = FFI_ALIGN(arg_reg, 2);+            /* Treat it as two adjacent doubles.  */+	    if (soft_float || index >= nfixedargs)+	      {+		arg_reg += 2;+	      }+	    else+	      {+		cif->flags +=+		  (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));+		arg_reg++;+		if (arg_reg >= 8)+		  continue;+		cif->flags +=+		  (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));+		arg_reg++;+	      }+            break;++	  case FFI_TYPE_COMPLEX:+	    switch (t->elements[0]->type)+	      {+	      case FFI_TYPE_LONGDOUBLE:+		arg_reg = FFI_ALIGN(arg_reg, 2);+		if (soft_float || index >= nfixedargs)+		  {+		    arg_reg += 2;+		  }+		else+		  {+		    cif->flags +=+		      (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));+		    arg_reg++;+		    if (arg_reg >= 8)+		        continue;+		    cif->flags +=+		      (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));+		    arg_reg++;+		    if (arg_reg >= 8)+		        continue;+		  }+		/* passthrough */+	      case FFI_TYPE_FLOAT:+		// one fpr can only holds one arg even it is single+		cif->bytes += 16;+		/* passthrough */+	      case FFI_TYPE_SINT32:+	      case FFI_TYPE_UINT32:+	      case FFI_TYPE_DOUBLE:+		if (soft_float || index >= nfixedargs)+		  {+		    arg_reg += 2;+		  }+		else+		  {+		    uint32_t type = t->elements[0]->type != FFI_TYPE_LONGDOUBLE? t->elements[0]->type: FFI_TYPE_DOUBLE;+		    cif->flags +=+		      (type << (arg_reg * FFI_FLAG_BITS));+		    arg_reg++;+		    if (arg_reg >= 8)+		        continue;+		    cif->flags +=+		      (type << (arg_reg * FFI_FLAG_BITS));+		    arg_reg++;+		  }+		break;+	      default:+		arg_reg += 2;+		break;+	      }+	    break;++	  case FFI_TYPE_STRUCT:+            loc = arg_reg * FFI_SIZEOF_ARG;+	    cif->flags += calc_n32_struct_flags(soft_float || index >= nfixedargs,+						t, &loc, &arg_reg);+	    break;++	  default:+	    arg_reg++;+            break;+	  }++	index++;+      }++  /* Set the return type flag */+    switch (cif->rtype->type)+      {+      case FFI_TYPE_STRUCT:+	{+	  if (struct_flags == 0)+	    {+	      /* The structure is returned through a hidden+		 first argument. Do nothing, 'cause FFI_TYPE_VOID +		 is 0 */+	    }+	  else+	    {+	      /* The structure is returned via some tricky+		 mechanism */+	      cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);+	      cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));+	    }+	  break;+	}+      +      case FFI_TYPE_VOID:+	/* Do nothing, 'cause FFI_TYPE_VOID is 0 */+	break;++      case FFI_TYPE_POINTER:+	if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)+	  cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);+	else+	  cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8);+	break;++      case FFI_TYPE_FLOAT:+	if (soft_float)+	  {+	    cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);+	    break;+	  }+	/* else fall through */+      case FFI_TYPE_DOUBLE:+	if (soft_float)+	  cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8);+	else+	  cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);+	break;++      case FFI_TYPE_LONGDOUBLE:+	/* Long double is returned as if it were a struct containing+	   two doubles.  */+	if (soft_float)+	  {+	    /* if ret is long double, the ret is given by v0 and a0, no idea why+	     * Let's us VOID | VOID | LONGDOUBLE for it*/+	    cif->flags += FFI_TYPE_LONGDOUBLE << (FFI_FLAG_BITS * 8);+ 	  }+	else+	  {+	    cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);+	    cif->flags += (FFI_TYPE_DOUBLE+			   + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))+					      << (4 + (FFI_FLAG_BITS * 8));+	  }+	break;+      case FFI_TYPE_COMPLEX:+	{+	  int type = cif->rtype->elements[0]->type;++	  cif->flags += (FFI_TYPE_COMPLEX << (FFI_FLAG_BITS * 8));+	  if (soft_float || (type != FFI_TYPE_FLOAT && type != FFI_TYPE_DOUBLE && type != FFI_TYPE_LONGDOUBLE))+	    {+	      switch (type)+		{+		case FFI_TYPE_DOUBLE:+		case FFI_TYPE_SINT64:+		case FFI_TYPE_UINT64:+		case FFI_TYPE_INT:+		  type = FFI_TYPE_SMALLSTRUCT2;+		  break;+		case FFI_TYPE_LONGDOUBLE:+		  type = FFI_TYPE_LONGDOUBLE;+		  break;+		case FFI_TYPE_FLOAT:+		default:+		  type = FFI_TYPE_SMALLSTRUCT;+		}+	      cif->flags += type << (4 + (FFI_FLAG_BITS * 8));+	    }+	  else+	    {+	      //cif->flags += (type + (type << FFI_FLAG_BITS))+		//	    << (4 + (FFI_FLAG_BITS * 8));+	      cif->flags += type << (4 + (FFI_FLAG_BITS * 8));+	    }+	  break;+	}+      case FFI_TYPE_UINT32:+	/* In the N32 or N64 ABI unsigned 32-bit integer should be+	   *sign*-extended.  */+	cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);+	break;+      case FFI_TYPE_SINT64:+	cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8);+	break;+      default:+	cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);+	break;+      }+  }+#endif+  return FFI_OK;+}++ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+    return ffi_prep_cif_machdep_int(cif, cif->nargs);+}++ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,+                                    unsigned nfixedargs,+                                    unsigned ntotalargs MAYBE_UNUSED)+{+    return ffi_prep_cif_machdep_int(cif, nfixedargs);+}++/* Low level routine for calling O32 functions */+extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), +			extended_cif *, unsigned, +			unsigned, unsigned *, void (*)(void), void *closure);++/* Low level routine for calling N32 functions */+extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), +			extended_cif *, unsigned, +			unsigned, void *, void (*)(void), void *closure);++void ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue, +	      void **avalue, void *closure)+{+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;+  +  /* If the return value is a struct and we don't have a return	*/+  /* value address then we need to make one		        */+  +  if ((rvalue == NULL) && +      (cif->rtype->type == FFI_TYPE_STRUCT || cif->rtype->type == FFI_TYPE_COMPLEX))+    ecif.rvalue = alloca(cif->rtype->size);+  else+    ecif.rvalue = rvalue;+    +  switch (cif->abi) +    {+#ifdef FFI_MIPS_O32+    case FFI_O32:+    case FFI_O32_SOFT_FLOAT:+      ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, +		   cif->flags, ecif.rvalue, fn, closure);+      break;+#endif++#ifdef FFI_MIPS_N32+    case FFI_N32:+    case FFI_N32_SOFT_FLOAT:+    case FFI_N64:+    case FFI_N64_SOFT_FLOAT:+      {+        int copy_rvalue = 0;+	int copy_offset = 0;+        char *rvalue_copy = ecif.rvalue;+        if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)+          {+            /* For structures smaller than 16 bytes we clobber memory+               in 8 byte increments.  Make a copy so we don't clobber+               the callers memory outside of the struct bounds.  */+            rvalue_copy = alloca(16);+            copy_rvalue = 1;+          }+	else if (cif->rtype->type == FFI_TYPE_FLOAT+		 && (cif->abi == FFI_N64_SOFT_FLOAT+		     || cif->abi == FFI_N32_SOFT_FLOAT))+	  {+	    rvalue_copy = alloca (8);+	    copy_rvalue = 1;+#if defined(__MIPSEB__) || defined(_MIPSEB)+	    copy_offset = 4;+#endif+	  }+        ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,+                     cif->flags, rvalue_copy, fn, closure);+        if (copy_rvalue)+          memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);+      }+      break;+#endif++    default:+      FFI_ASSERT(0);+      break;+    }+}++void+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}+++#if FFI_CLOSURES+#if defined(FFI_MIPS_O32)+extern void ffi_closure_O32(void);+extern void ffi_go_closure_O32(void);+#else+extern void ffi_closure_N32(void);+extern void ffi_go_closure_N32(void);+#endif /* FFI_MIPS_O32 */++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];+  void * fn;+  char *clear_location = (char *) codeloc;++#if defined(FFI_MIPS_O32)+  if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)+    return FFI_BAD_ABI;+  fn = ffi_closure_O32;+#else+#if _MIPS_SIM ==_ABIN32+  if (cif->abi != FFI_N32+      && cif->abi != FFI_N32_SOFT_FLOAT)+    return FFI_BAD_ABI;+#else+  if (cif->abi != FFI_N64+      && cif->abi != FFI_N64_SOFT_FLOAT)+    return FFI_BAD_ABI;+#endif+  fn = ffi_closure_N32;+#endif /* FFI_MIPS_O32 */++#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)+  /* lui  $25,high(fn) */+  tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);+  /* ori  $25,low(fn)  */+  tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);+  /* lui  $12,high(codeloc) */+  tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);+  /* jr   $25          */+#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)+  tramp[3] = 0x03200008;+#else+  tramp[3] = 0x03200009;+#endif+  /* ori  $12,low(codeloc)  */+  tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);+#else+  /* N64 has a somewhat larger trampoline.  */+  /* lui  $25,high(fn) */+  tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);+  /* lui  $12,high(codeloc) */+  tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);+  /* ori  $25,mid-high(fn)  */+  tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);+  /* ori  $12,mid-high(codeloc)  */+  tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);+  /* dsll $25,$25,16 */+  tramp[4] = 0x0019cc38;+  /* dsll $12,$12,16 */+  tramp[5] = 0x000c6438;+  /* ori  $25,mid-low(fn)  */+  tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);+  /* ori  $12,mid-low(codeloc)  */+  tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);+  /* dsll $25,$25,16 */+  tramp[8] = 0x0019cc38;+  /* dsll $12,$12,16 */+  tramp[9] = 0x000c6438;+  /* ori  $25,low(fn)  */+  tramp[10] = 0x37390000 | ((unsigned long)fn  & 0xffff);+  /* jr   $25          */+#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)+  tramp[11] = 0x03200008;+#else+  tramp[11] = 0x03200009;+#endif+  /* ori  $12,low(codeloc)  */+  tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);++#endif++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++#if !defined(__FreeBSD__)+#ifdef USE__BUILTIN___CLEAR_CACHE+  __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);+#else+  cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);+#endif+#endif /* ! __FreeBSD__ */+  return FFI_OK;+}++/*+ * Decodes the arguments to a function, which will be stored on the+ * stack. AR is the pointer to the beginning of the integer arguments+ * (and, depending upon the arguments, some floating-point arguments+ * as well). FPR is a pointer to the area where floating point+ * registers have been saved, if any.+ *+ * RVALUE is the location where the function return value will be+ * stored. CLOSURE is the prepared closure to invoke.+ *+ * This function should only be called from assembly, which is in+ * turn called from a trampoline.+ *+ * Returns the function return type.+ *+ * Based on the similar routine for sparc.+ */+int+ffi_closure_mips_inner_O32 (ffi_cif *cif,+                            void (*fun)(ffi_cif*, void*, void**, void*),+			    void *user_data,+			    void *rvalue, ffi_arg *ar,+			    double *fpr)+{+  void **avaluep;+  ffi_arg *avalue;+  ffi_type **arg_types;+  int i, avn, argn, seen_int;++  avalue = alloca (cif->nargs * sizeof (ffi_arg));+  avaluep = alloca (cif->nargs * sizeof (ffi_arg));++  seen_int = (cif->abi == FFI_O32_SOFT_FLOAT) || (cif->mips_nfixedargs != cif->nargs);+  argn = 0;++  if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)+    {+      rvalue = (void *)(uintptr_t)ar[0];+      argn = 1;+      seen_int = 1;+    }+  if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_COMPLEX)+    {+      rvalue = fpr;+      argn = 1;+    }++  i = 0;+  avn = cif->nargs;+  arg_types = cif->arg_types;++  while (i < avn)+    {+      if (arg_types[i]->alignment == 8 && (argn & 0x1))+        argn++;+      if (i < 2 && !seen_int &&+	  (arg_types[i]->type == FFI_TYPE_FLOAT ||+	   arg_types[i]->type == FFI_TYPE_DOUBLE ||+	   arg_types[i]->type == FFI_TYPE_LONGDOUBLE))+	{+#if defined(__MIPSEB__) || defined(_MIPSEB)+	  if (arg_types[i]->type == FFI_TYPE_FLOAT)+	    avaluep[i] = ((char *) &fpr[i]) + sizeof (float);+	  else+#endif+	    avaluep[i] = (char *) &fpr[i];+	}+      else+	{+	  switch (arg_types[i]->type)+	    {+	      case FFI_TYPE_SINT8:+		avaluep[i] = &avalue[i];+		*(SINT8 *) &avalue[i] = (SINT8) ar[argn];+		break;++	      case FFI_TYPE_UINT8:+		avaluep[i] = &avalue[i];+		*(UINT8 *) &avalue[i] = (UINT8) ar[argn];+		break;+		  +	      case FFI_TYPE_SINT16:+		avaluep[i] = &avalue[i];+		*(SINT16 *) &avalue[i] = (SINT16) ar[argn];+		break;+		  +	      case FFI_TYPE_UINT16:+		avaluep[i] = &avalue[i];+		*(UINT16 *) &avalue[i] = (UINT16) ar[argn];+		break;++	      default:+		avaluep[i] = (char *) &ar[argn];+		break;+	    }+	  seen_int = 1;+	}+      argn += FFI_ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;+      i++;+    }++  /* Invoke the closure. */+  fun(cif, rvalue, avaluep, user_data);++  if (cif->abi == FFI_O32_SOFT_FLOAT)+    {+      switch (cif->rtype->type)+        {+        case FFI_TYPE_FLOAT:+          return FFI_TYPE_INT;+        case FFI_TYPE_DOUBLE:+          return FFI_TYPE_UINT64;+        default:+          return cif->rtype->type;+        }+    }+  else+    {+      if (cif->rtype->type == FFI_TYPE_COMPLEX) {+          __asm__ volatile ("move $v1, %0" : : "r"(cif->rtype->size));+      }+      return cif->rtype->type;+    }+}++#if defined(FFI_MIPS_N32)++static void+copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,+                int argn, unsigned arg_offset, ffi_arg *ar,+                ffi_arg *fpr, int soft_float)+{+  ffi_type **elt_typep = type->elements;+  while(*elt_typep)+    {+      ffi_type *elt_type = *elt_typep;+      unsigned o;+      char *tp;+      char *argp;+      char *fpp;++      o = FFI_ALIGN(offset, elt_type->alignment);+      arg_offset += o - offset;+      offset = o;+      argn += arg_offset / sizeof(ffi_arg);+      arg_offset = arg_offset % sizeof(ffi_arg);++      argp = (char *)(ar + argn);+      fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);++      tp = target + offset;++      if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)+        *(double *)tp = *(double *)fpp;+      else+        memcpy(tp, argp + arg_offset, elt_type->size);++      offset += elt_type->size;+      arg_offset += elt_type->size;+      elt_typep++;+      argn += arg_offset / sizeof(ffi_arg);+      arg_offset = arg_offset % sizeof(ffi_arg);+    }+}++/*+ * Decodes the arguments to a function, which will be stored on the+ * stack. AR is the pointer to the beginning of the integer+ * arguments. FPR is a pointer to the area where floating point+ * registers have been saved.+ *+ * RVALUE is the location where the function return value will be+ * stored. CLOSURE is the prepared closure to invoke.+ *+ * This function should only be called from assembly, which is in+ * turn called from a trampoline.+ *+ * Returns the function return flags.+ *+ */+int+ffi_closure_mips_inner_N32 (ffi_cif *cif, +			    void (*fun)(ffi_cif*, void*, void**, void*),+                            void *user_data,+			    void *rvalue, ffi_arg *ar,+			    ffi_arg *fpr)+{+  void **avaluep;+  ffi_arg *avalue;+  ffi_type **arg_types;+  int i, avn, argn;+  int soft_float;+  ffi_arg *argp;++  soft_float = cif->abi == FFI_N64_SOFT_FLOAT+    || cif->abi == FFI_N32_SOFT_FLOAT;+  avalue = alloca (cif->nargs * sizeof (ffi_arg));+  avaluep = alloca (cif->nargs * sizeof (ffi_arg));++  argn = 0;++  if (cif->rstruct_flag)+    {+#if _MIPS_SIM==_ABIN32+      rvalue = (void *)(UINT32)ar[0];+#else /* N64 */+      rvalue = (void *)ar[0];+#endif+      argn = 1;+    }+  if (cif->rtype->type == FFI_TYPE_COMPLEX && cif->rtype->elements[0]->type == FFI_TYPE_LONGDOUBLE)+    argn = 2;++  i = 0;+  avn = cif->nargs;+  arg_types = cif->arg_types;++  while (i < avn)+    {+      if (arg_types[i]->type == FFI_TYPE_FLOAT+	  || arg_types[i]->type == FFI_TYPE_DOUBLE+	  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)+        {+          argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;+          if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((uintptr_t)argp & (arg_types[i]->alignment-1)))+            {+              argp=(ffi_arg*)FFI_ALIGN(argp,arg_types[i]->alignment);+              argn++;+            }+#if defined(__MIPSEB__) || defined(_MIPSEB)+          if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)+            avaluep[i] = ((char *) argp) + sizeof (float);+          else+#endif+            avaluep[i] = (char *) argp;+        }+      else if (arg_types[i]->type == FFI_TYPE_COMPLEX && arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)+        {+          argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;+          avaluep[i] = (char *) argp;+        }+      else if (arg_types[i]->type == FFI_TYPE_COMPLEX && arg_types[i]->elements[0]->type == FFI_TYPE_LONGDOUBLE)+        {+	  /* align long double */+	  argn += ((argn & 0x1)? 1 : 0);+          argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;+          avaluep[i] = (char *) argp;+        }+      else if (arg_types[i]->type == FFI_TYPE_COMPLEX && arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT)+        {+          if (argn >= 8 || i >= cif->mips_nfixedargs || soft_float)+	     argp = ar + argn;+	  else+	    {+	      argp = fpr + argn;+	      /* the normal args for function holds 8bytes, while here we convert it to ptr */+	      uint32_t *tmp = (uint32_t *)argp;+	      tmp[1] = tmp[2];+	    }+          avaluep[i] = (char *) argp;+        }+      else+        {+          unsigned type = arg_types[i]->type;++          if (arg_types[i]->alignment > sizeof(ffi_arg))+            argn = FFI_ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));++          argp = ar + argn;++          /* The size of a pointer depends on the ABI */+          if (type == FFI_TYPE_POINTER)+            type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)+	      ? FFI_TYPE_SINT64 : FFI_TYPE_UINT32;++	  if (soft_float && type ==  FFI_TYPE_FLOAT)+	    type = FFI_TYPE_SINT32;++          switch (type)+            {+            case FFI_TYPE_SINT8:+              avaluep[i] = &avalue[i];+              *(SINT8 *) &avalue[i] = (SINT8) *argp;+              break;++            case FFI_TYPE_UINT8:+              avaluep[i] = &avalue[i];+              *(UINT8 *) &avalue[i] = (UINT8) *argp;+              break;++            case FFI_TYPE_SINT16:+              avaluep[i] = &avalue[i];+              *(SINT16 *) &avalue[i] = (SINT16) *argp;+              break;++            case FFI_TYPE_UINT16:+              avaluep[i] = &avalue[i];+              *(UINT16 *) &avalue[i] = (UINT16) *argp;+              break;++            case FFI_TYPE_SINT32:+              avaluep[i] = &avalue[i];+              *(SINT32 *) &avalue[i] = (SINT32) *argp;+              break;++            case FFI_TYPE_UINT32:+              avaluep[i] = &avalue[i];+              *(UINT32 *) &avalue[i] = (UINT32) *argp;+              break;++            case FFI_TYPE_STRUCT:+              if (argn < 8)+                {+                  /* Allocate space for the struct as at least part of+                     it was passed in registers.  */+                  avaluep[i] = alloca(arg_types[i]->size);+                  copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],+                                  argn, 0, ar, fpr, i >= cif->mips_nfixedargs || soft_float);++                  break;+                }+              /* Else fall through.  */+            default:+              avaluep[i] = (char *) argp;+              break;+            }+        }+      argn += FFI_ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);+      i++;+    }++  /* Invoke the closure. */+  fun (cif, rvalue, avaluep, user_data);++  return cif->flags >> (FFI_FLAG_BITS * 8);+}++#endif /* FFI_MIPS_N32 */++#if defined(FFI_MIPS_O32)+extern void ffi_closure_O32(void);+extern void ffi_go_closure_O32(void);+#else+extern void ffi_closure_N32(void);+extern void ffi_go_closure_N32(void);+#endif /* FFI_MIPS_O32 */++ffi_status+ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,+		     void (*fun)(ffi_cif*,void*,void**,void*))+{+  void * fn;++#if defined(FFI_MIPS_O32)+  if (cif->abi != FFI_O32 && cif->abi != FFI_O32_SOFT_FLOAT)+    return FFI_BAD_ABI;+  fn = ffi_go_closure_O32;+#else+#if _MIPS_SIM ==_ABIN32+  if (cif->abi != FFI_N32+      && cif->abi != FFI_N32_SOFT_FLOAT)+    return FFI_BAD_ABI;+#else+  if (cif->abi != FFI_N64+      && cif->abi != FFI_N64_SOFT_FLOAT)+    return FFI_BAD_ABI;+#endif+  fn = ffi_go_closure_N32;+#endif /* FFI_MIPS_O32 */++  closure->tramp = (void *)fn;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++#endif /* FFI_CLOSURES */
+ src/mips/ffitarget.h view
@@ -0,0 +1,249 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for MIPS.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifdef __rtems__+/*+ * Subprogram calling convention - copied from sgidefs.h+ */+#define _MIPS_SIM_ABI32		1+#define _MIPS_SIM_NABI32	2+#define _MIPS_SIM_ABI64		3+#elif !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__linux__)+# include <sgidefs.h>+#endif++#  ifndef _ABIN32+#    define _ABIN32 _MIPS_SIM_NABI32+#  endif+#  ifndef _ABI64+#    define _ABI64 _MIPS_SIM_ABI64+#  endif+#  ifndef _ABIO32+#    define _ABIO32 _MIPS_SIM_ABI32+#  endif++#if !defined(_MIPS_SIM)+# error -- something is very wrong --+#else+#  if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))+#    define FFI_MIPS_N32+#  else+#    if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))+#      define FFI_MIPS_O32+#    else+#     error -- this is an unsupported platform --+#    endif+#  endif+#endif++#ifdef FFI_MIPS_O32+/* O32 stack frames have 32bit integer args */+#  define FFI_SIZEOF_ARG    4+#else+/* N32 and N64 frames have 64bit integer args */+#  define FFI_SIZEOF_ARG    8+#  if _MIPS_SIM == _ABIN32+#    define FFI_SIZEOF_JAVA_RAW  4+#  endif+#endif++#define FFI_TARGET_HAS_COMPLEX_TYPE 1+#define FFI_FLAG_BITS 2++/* SGI's strange assembler requires that we multiply by 4 rather +   than shift left by FFI_FLAG_BITS */++#define FFI_ARGS_D   FFI_TYPE_DOUBLE+#define FFI_ARGS_F   FFI_TYPE_FLOAT+#define FFI_ARGS_DD  FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE+#define FFI_ARGS_FF  FFI_TYPE_FLOAT * 4 +  FFI_TYPE_FLOAT+#define FFI_ARGS_FD  FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT+#define FFI_ARGS_DF  FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE++/* Needed for N32 structure returns */+#define FFI_TYPE_SMALLSTRUCT  FFI_TYPE_UINT8+#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8++#if 0+/* The SGI assembler can't handle this.. */+#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT+/* (and so on) */+#else+/* ...so we calculate these by hand! */+#define FFI_TYPE_STRUCT_D      61+#define FFI_TYPE_STRUCT_F      45+#define FFI_TYPE_STRUCT_DD     253+#define FFI_TYPE_STRUCT_FF     173+#define FFI_TYPE_STRUCT_FD     237+#define FFI_TYPE_STRUCT_DF     189+#define FFI_TYPE_STRUCT_SMALL  93+#define FFI_TYPE_STRUCT_SMALL2 109++#define FFI_TYPE_COMPLEX_SMALL    95+#define FFI_TYPE_COMPLEX_SMALL2   111+#define FFI_TYPE_COMPLEX_FF       47+#define FFI_TYPE_COMPLEX_DD       63+#define FFI_TYPE_COMPLEX_LDLD     79++/* and for n32 soft float, add 16 * 2^4 */+#define FFI_TYPE_STRUCT_D_SOFT      317+#define FFI_TYPE_STRUCT_F_SOFT      301+#define FFI_TYPE_STRUCT_DD_SOFT     509+#define FFI_TYPE_STRUCT_FF_SOFT     429+#define FFI_TYPE_STRUCT_FD_SOFT     493+#define FFI_TYPE_STRUCT_DF_SOFT     445+#define FFI_TYPE_STRUCT_SOFT        16+#endif++#ifdef LIBFFI_ASM+#define v0 $2+#define v1 $3+#define a0 $4+#define a1 $5+#define a2 $6+#define a3 $7+#define a4 $8		+#define a5 $9		+#define a6 $10		+#define a7 $11		+#define t0 $8+#define t1 $9+#define t2 $10+#define t3 $11+#define t4 $12		+#define t5 $13+#define t6 $14	+#define t7 $15+#define t8 $24+#define t9 $25+#define ra $31		++#ifdef FFI_MIPS_O32+# define REG_L	lw+# define REG_S	sw+# define SUBU	subu+# define ADDU	addu+# define SRL	srl+# define LI	li+#else /* !FFI_MIPS_O32 */+# define REG_L	ld+# define REG_S	sd+# define SUBU	dsubu+# define ADDU	daddu+# define SRL	dsrl+# define LI 	dli+# if (_MIPS_SIM==_ABI64)+#  define LA dla+#  define EH_FRAME_ALIGN 3+#  define FDE_ADDR_BYTES .8byte+# else+#  define LA la+#  define EH_FRAME_ALIGN 2+#  define FDE_ADDR_BYTES .4byte+# endif /* _MIPS_SIM==_ABI64 */+#endif /* !FFI_MIPS_O32 */+#else /* !LIBFFI_ASM */+# ifdef __GNUC__+#  ifdef FFI_MIPS_O32+/* O32 stack frames have 32bit integer args */+typedef unsigned int     ffi_arg __attribute__((__mode__(__SI__)));+typedef signed   int     ffi_sarg __attribute__((__mode__(__SI__)));+#else+/* N32 and N64 frames have 64bit integer args */+typedef unsigned int     ffi_arg __attribute__((__mode__(__DI__)));+typedef signed   int     ffi_sarg __attribute__((__mode__(__DI__)));+#  endif+# else+#  ifdef FFI_MIPS_O32+/* O32 stack frames have 32bit integer args */+typedef __uint32_t ffi_arg;+typedef __int32_t ffi_sarg;+#  else+/* N32 and N64 frames have 64bit integer args */+typedef __uint64_t ffi_arg;+typedef __int64_t ffi_sarg;+#  endif+# endif /* __GNUC__ */++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_O32,+  FFI_N32,+  FFI_N64,+  FFI_O32_SOFT_FLOAT,+  FFI_N32_SOFT_FLOAT,+  FFI_N64_SOFT_FLOAT,+  FFI_LAST_ABI,++#ifdef FFI_MIPS_O32+#ifdef __mips_soft_float+  FFI_DEFAULT_ABI = FFI_O32_SOFT_FLOAT+#else+  FFI_DEFAULT_ABI = FFI_O32+#endif+#else+# if _MIPS_SIM==_ABI64+#  ifdef __mips_soft_float+  FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT+#  else+  FFI_DEFAULT_ABI = FFI_N64+#  endif+# else+#  ifdef __mips_soft_float+  FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT+#  else+  FFI_DEFAULT_ABI = FFI_N32+#  endif+# endif+#endif+} ffi_abi;++#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag; unsigned mips_nfixedargs+#define FFI_TARGET_SPECIFIC_VARIADIC+#endif /* !LIBFFI_ASM */++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++#if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)+# define FFI_TRAMPOLINE_SIZE 20+#else+# define FFI_TRAMPOLINE_SIZE 56+#endif++#endif+
+ src/mips/n32.S view
@@ -0,0 +1,827 @@+/* -----------------------------------------------------------------------+   n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010  Red Hat, Inc.+   +   MIPS Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>++/* Only build this code if we are compiling for n32 */	++#if defined(FFI_MIPS_N32)++#define callback a0+#define bytes	 a2+#define flags	 a3+#define raddr    a4+#define fn       a5+#define closure  a6++/* Note: to keep stack 16 byte aligned we need even number slots +   used 9 slots here+*/+#define SIZEOF_FRAME	( 10 * FFI_SIZEOF_ARG )++#ifdef __GNUC__+	.abicalls+#endif+#if !defined(__mips_isa_rev) || (__mips_isa_rev<6)+	.set mips4+#endif+	.text+	.align	2+	.globl	ffi_call_N32+	.ent	ffi_call_N32+ffi_call_N32:	+.LFB0:+	.frame	$fp, SIZEOF_FRAME, ra+	.mask	0xc0000000,-FFI_SIZEOF_ARG+	.fmask	0x00000000,0++	# Prologue+	SUBU	$sp, SIZEOF_FRAME			# Frame size+.LCFI00:+	REG_S	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp)	# Save frame pointer+	REG_S	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)	# Save return address+.LCFI01:+	move	$fp, $sp+.LCFI02:+	move	t9, callback	# callback function pointer+	REG_S	bytes, 2*FFI_SIZEOF_ARG($fp) # bytes+	REG_S	flags, 3*FFI_SIZEOF_ARG($fp) # flags+	REG_S	raddr, 4*FFI_SIZEOF_ARG($fp) # raddr+	REG_S	fn,    5*FFI_SIZEOF_ARG($fp) # fn+	REG_S	closure, 6*FFI_SIZEOF_ARG($fp) # closure++	# Allocate at least 4 words in the argstack+	move	v0, bytes+	bge	bytes, 4 * FFI_SIZEOF_ARG, bigger	+	LI	v0, 4 * FFI_SIZEOF_ARG+	b	sixteen++	bigger:	+	ADDU	t4, v0, 2 * FFI_SIZEOF_ARG -1	# make sure it is aligned +	and	v0, t4, -2 * FFI_SIZEOF_ARG		# to a proper boundry.++sixteen:+	SUBU	$sp, $sp, v0	# move the stack pointer to reflect the+				# arg space++	move	a0, $sp         # 4 * FFI_SIZEOF_ARG+	ADDU	a3, $fp, 3 * FFI_SIZEOF_ARG++	# Call ffi_prep_args+	jal	t9+	+	# Copy the stack pointer to t9+	move	t9, $sp+	+	# Fix the stack if there are more than 8 64bit slots worth+	# of arguments.++	# Load the number of bytes+	REG_L	t6, 2*FFI_SIZEOF_ARG($fp)++	# Is it bigger than 8 * FFI_SIZEOF_ARG?+	daddiu	t8, t6, -(8 * FFI_SIZEOF_ARG)+	bltz	t8, loadregs++	ADDU	t9, t9, t8+	+loadregs:	++	REG_L	t6, 3*FFI_SIZEOF_ARG($fp)  # load the flags word into t6.++	# when retval is _Complex long double, $f12/$a0, $f13/$a1 will be skipped+	# no idea why, but gcc does it.+	SRL	t4, t6, 8*FFI_FLAG_BITS+	move	t8, t6+	bne	t4, FFI_TYPE_COMPLEX_LDLD, loadregs1++	SLL	t8, t6, 2*FFI_FLAG_BITS+++loadregs1:+#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, t8, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a0, 0*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg1_next+	bne	t4, FFI_TYPE_FLOAT, arg1_doublep+	l.s	$f12, 0*FFI_SIZEOF_ARG(t9)+	b	arg1_next+arg1_doublep:	+	l.d	$f12, 0*FFI_SIZEOF_ARG(t9)+arg1_next:	+	+	SRL	t4, t8, 1*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a1, 1*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg2_next+	bne	t4, FFI_TYPE_FLOAT, arg2_doublep+	l.s	$f13, 1*FFI_SIZEOF_ARG(t9)	+	b	arg2_next+arg2_doublep:	+	l.d	$f13, 1*FFI_SIZEOF_ARG(t9)	+arg2_next:	+	+	SRL	t4, t8, 2*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a2, 2*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg3_next+	bne	t4, FFI_TYPE_FLOAT, arg3_doublep+	l.s	$f14, 2*FFI_SIZEOF_ARG(t9)	+	b	arg3_next+arg3_doublep:	+	l.d	$f14, 2*FFI_SIZEOF_ARG(t9)	+arg3_next:	+	+	SRL	t4, t8, 3*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a3, 3*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg4_next+	bne	t4, FFI_TYPE_FLOAT, arg4_doublep+	l.s	$f15, 3*FFI_SIZEOF_ARG(t9)	+	b	arg4_next+arg4_doublep:	+	l.d	$f15, 3*FFI_SIZEOF_ARG(t9)	+arg4_next:	+	+	SRL	t4, t8, 4*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a4, 4*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg5_next+	bne	t4, FFI_TYPE_FLOAT, arg5_doublep+	l.s	$f16, 4*FFI_SIZEOF_ARG(t9)	+	b	arg5_next+arg5_doublep:	+	l.d	$f16, 4*FFI_SIZEOF_ARG(t9)	+arg5_next:	+	+	SRL	t4, t8, 5*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a5, 5*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg6_next+	bne	t4, FFI_TYPE_FLOAT, arg6_doublep+	l.s	$f17, 5*FFI_SIZEOF_ARG(t9)	+	b	arg6_next+arg6_doublep:	+	l.d	$f17, 5*FFI_SIZEOF_ARG(t9)	+arg6_next:	+	+	SRL	t4, t8, 6*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a6, 6*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg7_next+	bne	t4, FFI_TYPE_FLOAT, arg7_doublep+	l.s	$f18, 6*FFI_SIZEOF_ARG(t9)	+	b	arg7_next+arg7_doublep:	+	l.d	$f18, 6*FFI_SIZEOF_ARG(t9)	+arg7_next:	+	+	SRL	t4, t8, 7*FFI_FLAG_BITS+	and	t4, ((1<<FFI_FLAG_BITS)-1)+	REG_L	a7, 7*FFI_SIZEOF_ARG(t9)+	beqz	t4, arg8_next+	bne	t4, FFI_TYPE_FLOAT, arg8_doublep+ 	l.s	$f19, 7*FFI_SIZEOF_ARG(t9)	+	b	arg8_next+arg8_doublep:	+ 	l.d	$f19, 7*FFI_SIZEOF_ARG(t9)	+arg8_next:	+#endif++callit:+	# Load the function pointer+	REG_L	t9, 5*FFI_SIZEOF_ARG($fp)++	# install the static chain(t7=$15)+	REG_L	t7, 6*FFI_SIZEOF_ARG($fp)++	# If the return value pointer is NULL, assume no return value.+	REG_L	t5, 4*FFI_SIZEOF_ARG($fp)+	beqz	t5, noretval++	# Shift the return type flag over+	SRL	t6, 8*FFI_FLAG_BITS++	bne     t6, FFI_TYPE_UINT64, retsint32++retuint64:+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sd	v0, 0(t4)+	b	epilogue++retsint32:+	bne	t6, FFI_TYPE_SINT32, retuint16+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sll	v0, v0, 0+	sd	v0, 0(t4)+	b	epilogue++retuint16:+	bne	t6, FFI_TYPE_UINT16, retsint16+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	andi	v0, v0, 0xffff+	sd	v0, 0(t4)+	b	epilogue++retsint16:+	bne	t6, FFI_TYPE_SINT16, retuint8+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	dsll	v0, v0, 48+	dsra	v0, v0, 48+	sd	v0, 0(t4)+	b	epilogue++retuint8:+	bne	t6, FFI_TYPE_UINT8, retsint8+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	andi	v0, v0, 0xff+	sd	v0, 0(t4)+	b	epilogue++retsint8:+	bne	t6, FFI_TYPE_SINT8, retfloat+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sd	v0, 0(t4)+	dsll	v0, v0, 56+	dsra	v0, v0, 56+	b	epilogue++retfloat:+#ifndef __mips_soft_float+	bne     t6, FFI_TYPE_FLOAT, retdouble+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.s	$f0, 0(t4)+	b	epilogue++retdouble:	+	bne	t6, FFI_TYPE_DOUBLE, retstruct_d+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.d	$f0, 0(t4)+	b	epilogue++retstruct_d:+	bne	t6, FFI_TYPE_STRUCT_D, retstruct_f+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.d	$f0, 0(t4)+	b	epilogue+	+retstruct_f:	+	bne	t6, FFI_TYPE_STRUCT_F, retstruct_d_d+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.s	$f0, 0(t4)+	b	epilogue+	+retstruct_d_d:+	bne	t6, FFI_TYPE_STRUCT_DD, retcomplex_d_d+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.d	$f0, 0(t4)+	s.d	$f2, 8(t4)+	b	epilogue++retcomplex_d_d:+	bne	t6, FFI_TYPE_COMPLEX_DD, retcomplex_ld_ld+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.d	$f0, 0(t4)+	s.d	$f2, 8(t4)+	b	epilogue++retcomplex_ld_ld:+	bne	t6, FFI_TYPE_COMPLEX_LDLD, retstruct_f_f+	jal	t9+	b	epilogue+	+retstruct_f_f:+	bne	t6, FFI_TYPE_STRUCT_FF, retcomplex_f_f+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.s	$f0, 0(t4)+	s.s	$f2, 4(t4)+	b	epilogue++retcomplex_f_f:+	bne	t6, FFI_TYPE_COMPLEX_FF, retstruct_d_f+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.s	$f0, 0(t4)+	s.s	$f2, 4(t4)+	b	epilogue+	+retstruct_d_f:	+	bne	t6, FFI_TYPE_STRUCT_DF, retstruct_f_d+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	s.d	$f0, 0(t4)+	s.s	$f2, 8(t4)+	b	epilogue+	+retstruct_f_d:	+	bne	t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	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+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sd	v0, 0(t4)+	b	epilogue+	+retstruct_f_soft:	+	bne	t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sw	v0, 0(t4)+	b	epilogue+	+retstruct_d_d_soft:	+	bne	t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sd	v0, 0(t4)+	sd	a0, 8(t4) # not typo, it is a0, I have no idea, gcc does do it+	b	epilogue+	+retstruct_f_f_soft:	+	bne	t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sw	v0, 0(t4)+	sw	v1, 4(t4)+	b	epilogue+	+retstruct_d_f_soft:	+	bne	t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sd	v0, 0(t4)+	sw	v1, 8(t4)+	b	epilogue+	+retstruct_f_d_soft:	+	bne	t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	sw	v0, 0(t4)+	sd	a0, 8(t4) # not typo, it is a0, I have no idea, gcc does do it+	b	epilogue+	+retstruct_small:	+	bne	t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	REG_S	v0, 0(t4)+	b	epilogue+	+retstruct_small2:	+	bne	t6, FFI_TYPE_STRUCT_SMALL2, retlongdouble_soft+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	REG_S	v0, 0(t4)+	REG_S	v1, 8(t4)+	b	epilogue+	+retlongdouble_soft:+	bne	t6, FFI_TYPE_LONGDOUBLE, retcomplex_small+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	REG_S	v0, 0(t4)+	REG_S	a0, 8(t4) # not typo, it is a0, I have no idea, gcc does do it+	b	epilogue++retcomplex_small:+	bne	t6, FFI_TYPE_COMPLEX_SMALL, retcomplex_small2+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	REG_S	v0, 0(t4)+	b	epilogue++retcomplex_small2:+	bne	t6, FFI_TYPE_COMPLEX_SMALL2, retstruct+	jal	t9+	REG_L	t4, 4*FFI_SIZEOF_ARG($fp)+	REG_S	v0, 0(t4)+	REG_S	v1, 8(t4)+	b	epilogue++retstruct:+noretval:	+	jal	t9+	+	# Epilogue+epilogue:	+	move	$sp, $fp	+	REG_L	$fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer+	REG_L	ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp)  # Restore return address+	ADDU	$sp, SIZEOF_FRAME		      # Fix stack pointer+	j	ra++.LFE0:+	.end	ffi_call_N32++/* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0+   ($12). Stores any arguments passed in registers onto the stack,+   then calls ffi_closure_mips_inner_N32, which then decodes+   them.+	+	Stack layout:++	20 - Start of parameters, original sp+	19 - Called function a7 save+	18 - Called function a6 save+	17 - Called function a5 save+	16 - Called function a4 save+	15 - Called function a3 save+	14 - Called function a2 save+	13 - Called function a1 save+	12 - Called function a0 save+	11 - Called function f19+	10 - Called function f18+	 9 - Called function f17+	 8 - Called function f16+	 7 - Called function f15+         6 - Called function f14+         5 - Called function f13+         4 - Called function f12+	 3 - return value high (v1 or $f2)+	 2 - return value low (v0 or $f0)+	 1 - ra save+	 0 - gp save our sp  points here+	 */++#define SIZEOF_FRAME2	(20 * FFI_SIZEOF_ARG)++#define A7_OFF2		(19 * FFI_SIZEOF_ARG)+#define A6_OFF2		(18 * FFI_SIZEOF_ARG)+#define A5_OFF2		(17 * FFI_SIZEOF_ARG)+#define A4_OFF2		(16 * FFI_SIZEOF_ARG)+#define A3_OFF2		(15 * FFI_SIZEOF_ARG)+#define A2_OFF2		(14 * FFI_SIZEOF_ARG)+#define A1_OFF2		(13 * FFI_SIZEOF_ARG)+#define A0_OFF2		(12 * FFI_SIZEOF_ARG)	++#define F19_OFF2	(11 * FFI_SIZEOF_ARG)+#define F18_OFF2	(10 * FFI_SIZEOF_ARG)+#define F17_OFF2	(9  * FFI_SIZEOF_ARG)+#define F16_OFF2	(8  * FFI_SIZEOF_ARG)+#define F15_OFF2	(7  * FFI_SIZEOF_ARG)+#define F14_OFF2	(6  * FFI_SIZEOF_ARG)+#define F13_OFF2	(5  * FFI_SIZEOF_ARG)+#define F12_OFF2	(4  * FFI_SIZEOF_ARG)++#define V1_OFF2		(3  * FFI_SIZEOF_ARG)+#define V0_OFF2		(2  * FFI_SIZEOF_ARG)++#define RA_OFF2		(1  * FFI_SIZEOF_ARG)+#define GP_OFF2		(0  * FFI_SIZEOF_ARG)++	.align	2+	.globl	ffi_go_closure_N32+	.ent	ffi_go_closure_N32+ffi_go_closure_N32:+.LFB1:+	.frame	$sp, SIZEOF_FRAME2, ra+	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)+	.fmask	0x00000000,0+	SUBU	$sp, SIZEOF_FRAME2+.LCFI10:+	.cpsetup t9, GP_OFF2, ffi_go_closure_N32+	REG_S	ra, RA_OFF2($sp)	# Save return address+.LCFI11:++	REG_S	a0, A0_OFF2($sp)+	REG_S	a1, A1_OFF2($sp)+	REG_S	a2, A2_OFF2($sp)+	REG_S	a3, A3_OFF2($sp)+	REG_S	a4, A4_OFF2($sp)+	REG_S	a5, A5_OFF2($sp)++	# Call ffi_closure_mips_inner_N32 to do the real work.+	LA	t9, ffi_closure_mips_inner_N32+#if _MIPS_SIM==_ABIN32+	lw	a0, 4($15)   # cif+	lw	a1, 8($15) # fun+#else+	REG_L	a0, 8($15)   # cif+	REG_L	a1, 16($15) # fun+#endif+	move	a2, t7                     # userdata=closure+	ADDU	a3, $sp, V0_OFF2           # rvalue+	ADDU	a4, $sp, A0_OFF2           # ar+	ADDU	a5, $sp, F12_OFF2          # fpr++	b	$do_closure++.LFE1:	+	.end	ffi_go_closure_N32++	.align	2+	.globl	ffi_closure_N32+	.ent	ffi_closure_N32+ffi_closure_N32:+.LFB2:+	.frame	$sp, SIZEOF_FRAME2, ra+	.mask	0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)+	.fmask	0x00000000,0+	SUBU	$sp, SIZEOF_FRAME2+.LCFI20:+	.cpsetup t9, GP_OFF2, ffi_closure_N32+	REG_S	ra, RA_OFF2($sp)	# Save return address+.LCFI21:+	REG_S	a0, A0_OFF2($sp)+	REG_S	a1, A1_OFF2($sp)+	REG_S	a2, A2_OFF2($sp)+	REG_S	a3, A3_OFF2($sp)+	REG_S	a4, A4_OFF2($sp)+	REG_S	a5, A5_OFF2($sp)++	# Call ffi_closure_mips_inner_N32 to do the real work.+	LA	t9, ffi_closure_mips_inner_N32+#if _MIPS_SIM==_ABIN32+	lw	a0, 20($12)   # cif+	lw	a1, 24($12)   # fun+	lw	a2, 28($12) # user_data+#else+	REG_L	a0, 56($12)   # cif+	REG_L	a1, 64($12)   # fun+	REG_L	a2, 72($12) # user_data+#endif+	ADDU	a3, $sp, V0_OFF2+	# FIXME: a4 does work, while if ret is _Complex long double, it will overwrite Fn_OFF2+	ADDU	a4, $sp, A0_OFF2+	ADDU	a5, $sp, F12_OFF2++$do_closure:+	# Store all possible argument registers. If there are more than+	# fit in registers, then they were stored on the stack.+	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)+	s.d	$f14, F14_OFF2($sp)+	s.d	$f15, F15_OFF2($sp)+	s.d	$f16, F16_OFF2($sp)+	s.d	$f17, F17_OFF2($sp)+	s.d	$f18, F18_OFF2($sp)+	s.d	$f19, F19_OFF2($sp)+#endif++	jalr	t9++cls_retuint64:+	# Return flags are in v0+	bne     v0, FFI_TYPE_UINT64, cls_retsint32+	ld	v0, V0_OFF2($sp)+	b	cls_epilogue++cls_retsint32:+	bne     v0, FFI_TYPE_SINT32, cls_retsint16+	lw	v0, V0_OFF2($sp)+	b	cls_epilogue++cls_retsint16:+	bne     v0, FFI_TYPE_SINT16, cls_retuint16+	lh	v0, V0_OFF2($sp)+	b	cls_epilogue++cls_retuint16:+	bne     v0, FFI_TYPE_UINT16, cls_retsint8+	lhu	v0, V0_OFF2($sp)+	b	cls_epilogue++cls_retsint8:+	bne     v0, FFI_TYPE_SINT8, cls_retuint8+	lb	v0, V0_OFF2($sp)+	b	cls_epilogue++cls_retuint8:+	bne     v0, FFI_TYPE_UINT8, cls_retfloat+	lbu	v0, V0_OFF2($sp)+	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++cls_retdouble:	+	bne	v0, FFI_TYPE_DOUBLE, cls_retstruct_d+	l.d	$f0, V0_OFF2($sp)+	b	cls_epilogue++cls_retstruct_d:	+	bne	v0, FFI_TYPE_STRUCT_D, cls_retstruct_f+	l.d	$f0, V0_OFF2($sp)+	b	cls_epilogue+	+cls_retstruct_f:	+	bne	v0, FFI_TYPE_STRUCT_F, cls_retstruct_d_d+	l.s	$f0, V0_OFF2($sp)+	b	cls_epilogue+	+cls_retstruct_d_d:	+	bne	v0, FFI_TYPE_STRUCT_DD, cls_retcomplex_d_d+	l.d	$f0, V0_OFF2($sp)+	l.d	$f2, V1_OFF2($sp)+	b	cls_epilogue++cls_retcomplex_d_d:+	bne	v0, FFI_TYPE_COMPLEX_DD, cls_retcomplex_f_f+	l.d	$f0, V0_OFF2($sp)+	l.d	$f2, V1_OFF2($sp)+	b	cls_epilogue+	+cls_retstruct_f_f:+	bne	v0, FFI_TYPE_STRUCT_FF, cls_retcomplex_f_f+	l.s	$f0, V0_OFF2($sp)+	l.s	$f2, V1_OFF2($sp)+	b	cls_epilogue+	+cls_retcomplex_f_f:+	bne	v0, FFI_TYPE_COMPLEX_FF, cls_retstruct_d_f+	l.s	$f0, V0_OFF2($sp)+	l.s	$f2, (V0_OFF2+4)($sp)+	b	cls_epilogue++cls_retstruct_d_f:	+	bne	v0, FFI_TYPE_STRUCT_DF, cls_retstruct_f_d+	l.d	$f0, V0_OFF2($sp)+	l.s	$f2, V1_OFF2($sp)+	b	cls_epilogue+	+cls_retstruct_f_d:	+	bne	v0, FFI_TYPE_STRUCT_FD, cls_retcomplex_ld_ld+	l.s	$f0, V0_OFF2($sp)+	l.d	$f2, V1_OFF2($sp)+	b	cls_epilogue+#else+cls_longdouble_soft:+	bne	v0, FFI_TYPE_LONGDOUBLE, cls_retcomplex_ld_ld+	REG_L	v0, V0_OFF2($sp)+	REG_L	a0, V1_OFF2($sp) # not typo, it is a0, I have no idea, gcc does do it+	b	cls_epilogue+#endif++cls_retcomplex_ld_ld:+	bne	v0, FFI_TYPE_COMPLEX_LDLD, cls_retstruct_small2+	REG_L	t8, A0_OFF2($sp)+	REG_L	t9, 16($sp)+	REG_S	t9, 0(t8)+	REG_L	t9, 24($sp)+	REG_S	t9, 8(t8)+	REG_L	t9, 32($sp)+	REG_S	t9, 16(t8)+	REG_L	t9, 40($sp)+	REG_S	t9, 24(t8)+	b	cls_epilogue++cls_retstruct_small2:	+	REG_L	v0, V0_OFF2($sp)+	REG_L	v1, V1_OFF2($sp)+	+	# Epilogue+cls_epilogue:	+	REG_L	ra,  RA_OFF2($sp)	 # Restore return address+	.cpreturn+	ADDU	$sp, SIZEOF_FRAME2+	j	ra+.LFE2:	+	.end	ffi_closure_N32++#ifdef __GNUC__+        .section        .eh_frame,EH_FRAME_FLAGS,@progbits+.Lframe1:+        .4byte  .LECIE1-.LSCIE1		# length+.LSCIE1:+        .4byte  0x0			# CIE+        .byte   0x1			# Version 1+        .ascii  "\000"			# Augmentation+        .uleb128 0x1			# Code alignment 1+        .sleb128 -4			# Data alignment -4+        .byte   0x1f			# Return Address $31+        .byte   0xc			# DW_CFA_def_cfa+        .uleb128 0x1d			# in $sp+        .uleb128 0x0			# offset 0+        .align  EH_FRAME_ALIGN+.LECIE1:++.LSFDE0:+        .4byte  .LEFDE0-.LASFDE0	# length.+.LASFDE0:+        .4byte  .LASFDE0-.Lframe1	# CIE_pointer.+        FDE_ADDR_BYTES  .LFB0		# initial_location.+        FDE_ADDR_BYTES  .LFE0-.LFB0	# address_range.+        .byte   0x4			# DW_CFA_advance_loc4+        .4byte  .LCFI00-.LFB0		# to .LCFI00+        .byte   0xe			# DW_CFA_def_cfa_offset+        .uleb128 SIZEOF_FRAME		# adjust stack.by SIZEOF_FRAME+        .byte   0x4			# DW_CFA_advance_loc4+        .4byte  .LCFI01-.LCFI00		# to .LCFI01+        .byte   0x9e			# DW_CFA_offset of $fp+        .uleb128 2*FFI_SIZEOF_ARG/4	# +        .byte   0x9f			# DW_CFA_offset of ra+        .uleb128 1*FFI_SIZEOF_ARG/4	# +        .byte   0x4			# DW_CFA_advance_loc4+        .4byte  .LCFI02-.LCFI01		# to .LCFI02+        .byte   0xd			# DW_CFA_def_cfa_register+        .uleb128 0x1e			# in $fp+        .align  EH_FRAME_ALIGN+.LEFDE0:++.LSFDE1:+	.4byte	.LEFDE1-.LASFDE1	# length+.LASFDE1:+	.4byte	.LASFDE1-.Lframe1	# CIE_pointer.+	FDE_ADDR_BYTES	.LFB1		# initial_location.+	FDE_ADDR_BYTES	.LFE1-.LFB1	# address_range.+	.byte	0x4			# DW_CFA_advance_loc4+	.4byte	.LCFI10-.LFB1		# to .LCFI10+	.byte	0xe			# DW_CFA_def_cfa_offset+	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME+	.byte	0x4			# DW_CFA_advance_loc4+	.4byte	.LCFI11-.LCFI10		# to .LCFI11+	.byte	0x9c			# DW_CFA_offset of $gp ($28)+	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4+	.byte	0x9f			# DW_CFA_offset of ra ($31)+	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4+	.align	EH_FRAME_ALIGN+.LEFDE1:++.LSFDE2:+	.4byte	.LEFDE2-.LASFDE2	# length+.LASFDE2:+	.4byte	.LASFDE2-.Lframe1	# CIE_pointer.+	FDE_ADDR_BYTES	.LFB2		# initial_location.+	FDE_ADDR_BYTES	.LFE2-.LFB2	# address_range.+	.byte	0x4			# DW_CFA_advance_loc4+	.4byte	.LCFI20-.LFB2		# to .LCFI20+	.byte	0xe			# DW_CFA_def_cfa_offset+	.uleb128 SIZEOF_FRAME2		# adjust stack.by SIZEOF_FRAME+	.byte	0x4			# DW_CFA_advance_loc4+	.4byte	.LCFI21-.LCFI20		# to .LCFI21+	.byte	0x9c			# DW_CFA_offset of $gp ($28)+	.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4+	.byte	0x9f			# DW_CFA_offset of ra ($31)+	.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4+	.align	EH_FRAME_ALIGN+.LEFDE2:+#endif /* __GNUC__ */	+	+#endif++#if defined __ELF__ && defined __linux__+	.section .note.GNU-stack,"",%progbits+#endif
+ src/mips/o32.S view
@@ -0,0 +1,565 @@+/* -----------------------------------------------------------------------+   o32.S - Copyright (c) 1996, 1998, 2005  Red Hat, Inc.+   +   MIPS Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>++/* Only build this code if we are compiling for o32 */	++#if defined(FFI_MIPS_O32)+	+#define callback a0+#define bytes	 a2+#define flags	 a3+		+#define SIZEOF_FRAME	(4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG)+#define A3_OFF		(SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG)+#define FP_OFF		(SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG)+#define RA_OFF		(SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG)++	.abicalls+	.text+	.align	2+	.globl	ffi_call_O32+	.ent	ffi_call_O32+ffi_call_O32:	+$LFB0:+	# Prologue+	SUBU	$sp, SIZEOF_FRAME	# Frame size+$LCFI00:+	REG_S	$fp, FP_OFF($sp)	# Save frame pointer+$LCFI01:+	REG_S	ra, RA_OFF($sp)		# Save return address+$LCFI02:+	move	$fp, $sp++$LCFI03:+	move	t9, callback		# callback function pointer+	REG_S	flags, A3_OFF($fp)	# flags++	# Allocate at least 4 words in the argstack+	LI	v0, 4 * FFI_SIZEOF_ARG+	blt	bytes, v0, sixteen++	ADDU	v0, bytes, 7	# make sure it is aligned +	and	v0, -8		# to an 8 byte boundry++sixteen:+	SUBU	$sp, v0		# move the stack pointer to reflect the+				# arg space++	ADDU	a0, $sp, 4 * FFI_SIZEOF_ARG++	jalr	t9+	+	REG_L	t0, A3_OFF($fp)		# load the flags word+	SRL	t2, t0, 4		# shift our arg info+	and     t0, ((1<<4)-1)          # mask out the return type+		+	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+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)	# passing a double+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)+	b	call_it++pass_f:	+	bne	t0, FFI_ARGS_F, pass_d_d+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args+	REG_L	a1,   1*FFI_SIZEOF_ARG($sp)	# passing a float+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)+	b	call_it		++pass_d_d:		+	bne	t0, FFI_ARGS_DD, pass_f_f+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args+	l.d	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing two doubles+	b	call_it++pass_f_f:	+	bne	t0, FFI_ARGS_FF, pass_d_f+	l.s	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args+	l.s	$f14, 1*FFI_SIZEOF_ARG($sp)	# passing two floats+	REG_L	a2,   2*FFI_SIZEOF_ARG($sp)+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)+	b	call_it++pass_d_f:		+	bne	t0, FFI_ARGS_DF, pass_f_d+	l.d	$f12, 0*FFI_SIZEOF_ARG($sp)	# load $fp regs from args+	l.s	$f14, 2*FFI_SIZEOF_ARG($sp)	# passing double and float+	REG_L	a3,   3*FFI_SIZEOF_ARG($sp)+	b	call_it++pass_f_d:		+ # assume that the only other combination must be float then double+ #	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+	REG_L	t7, SIZEOF_FRAME + 6*FFI_SIZEOF_ARG($fp)++	# Load the function pointer+	REG_L	t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp)++	# If the return value pointer is NULL, assume no return value.+	REG_L	t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)+	beqz	t1, noretval++	and     t1, t2, ((1<<4)-1)+	bne     t1, FFI_TYPE_INT, retlonglong+	jalr	t9+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)+	REG_S	v0, 0(t0)+	b	epilogue++retlonglong:+	# Really any 64-bit int, signed or not.+	bne	t1, FFI_TYPE_UINT64, retfloat+	jalr	t9+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)+	REG_S	v1, 4(t0)+	REG_S	v0, 0(t0)+	b	epilogue++retfloat:+	bne     t1, 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	t1, FFI_TYPE_DOUBLE, retcomplex+	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+	+retcomplex:+	# mask out the complex elements type.+	# the struct of flags (bits):+	# 0-1: arg0+	# 2-3: arg1+	# 4-7: return type+	# 8-11: rtype elements type: for complex+	# Note here: t2 is flags>>4+	bne	t1, FFI_TYPE_COMPLEX, noretval+	jalr	t9+	REG_L	t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)+	REG_L	t1, A3_OFF($fp)		# load the flags word+	SRL	t1, t1, 8+	li	t3, 3+	beq	t1, t3, 3f # double+	li	t3, 2+	beq	t1, t3, 2f # float+	# FIXME: long double+	slti	t3, t1, 5+	beqz	t3, 5f     # (u)int8/16/32/64+2:+#ifndef __mips_soft_float+	s.s	$f0, 0(t0)+	s.s	$f2, 4(t0)+#else+	# FIXME: do nothing can pass all of the testsuite+#endif+	b	epilogue+3:+#ifndef __mips_soft_float+	s.d	$f0, 0(t0)+	s.d	$f2, 8(t0)+#else+	# FIXME: do nothing can pass all of the testsuite+#endif+	b	epilogue++5:+	REG_S	v1, 4(t0)+	REG_S	v0, 0(t0)+	b	epilogue++noretval:	+	jalr	t9+	+	# Epilogue+epilogue:	+	move	$sp, $fp	+	REG_L	$fp, FP_OFF($sp)	# Restore frame pointer+	REG_L	ra, RA_OFF($sp)		# Restore return address+	ADDU	$sp, SIZEOF_FRAME	# Fix stack pointer+	j	ra++$LFE0:+	.end	ffi_call_O32+++/* ffi_closure_O32. Expects address of the passed-in ffi_closure+	in t4 ($12). Stores any arguments passed in registers onto the+	stack, then calls ffi_closure_mips_inner_O32, which+	then decodes them.+	+	Stack layout:++	 3 - a3 save+	 2 - a2 save+	 1 - a1 save+	 0 - a0 save, original sp+	-1 - ra save+	-2 - fp save+	-3 - $16 (s0) save+	-4 - cprestore+	-5 - return value high (v1)+	-6 - return value low (v0)+	-7 - f14 (le high, be low)+	-8 - f14 (le low, be high)+	-9 - f12 (le high, be low)+       -10 - f12 (le low, be high)+       -11 - Called function a5 save+       -12 - Called function a4 save+       -13 - Called function a3 save+       -14 - Called function a2 save+       -15 - Called function a1 save+       -16 - Called function a0 save, our sp and fp point here+	 */+	+#define SIZEOF_FRAME2	(16 * FFI_SIZEOF_ARG)+#define A3_OFF2		(SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)+#define A2_OFF2		(SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)+#define A1_OFF2		(SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)+#define A0_OFF2		(SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG)+#define RA_OFF2		(SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG)+#define FP_OFF2		(SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG)+#define S0_OFF2		(SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG)+#define GP_OFF2		(SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG)+#define V1_OFF2		(SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG)+#define V0_OFF2		(SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG)+#define FA_1_1_OFF2	(SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG)+#define FA_1_0_OFF2	(SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)+#define FA_0_1_OFF2	(SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)+#define FA_0_0_OFF2	(SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)+#define CALLED_A5_OFF2  (SIZEOF_FRAME2 - 11 * FFI_SIZEOF_ARG)+#define CALLED_A4_OFF2  (SIZEOF_FRAME2 - 12 * FFI_SIZEOF_ARG)++	.text++	.align	2+	.globl	ffi_go_closure_O32+	.ent	ffi_go_closure_O32+ffi_go_closure_O32:+$LFB1:+	# Prologue+	.frame	$fp, SIZEOF_FRAME2, ra+	.set	noreorder+	.cpload	t9+	.set	reorder+	SUBU	$sp, SIZEOF_FRAME2+	.cprestore GP_OFF2+$LCFI10:++	REG_S	$16, S0_OFF2($sp)	 # Save s0+	REG_S	$fp, FP_OFF2($sp)	 # Save frame pointer+	REG_S	ra, RA_OFF2($sp)	 # Save return address+$LCFI11:++	move	$fp, $sp+$LCFI12:++	REG_S	a0, A0_OFF2($fp)+	REG_S	a1, A1_OFF2($fp)+	REG_S	a2, A2_OFF2($fp)+	REG_S	a3, A3_OFF2($fp)++	# Load ABI enum to s0+	REG_L	$16, 4($15)	# cif +	REG_L	$16, 0($16)	# abi is first member.++	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, 4($15)	 # cif +	REG_L	a1, 8($15)	 # fun+	move	a2, $15		 # user_data = go closure+	addu	a3, $fp, V0_OFF2 # rvalue++	addu	t9, $fp, A0_OFF2 # ar+	REG_S   t9, CALLED_A4_OFF2($fp)++	addu	t9, $fp, FA_0_0_OFF2 #fpr+	REG_S   t9, CALLED_A5_OFF2($fp)++	b $do_closure++$LFE1:+	.end ffi_go_closure_O32++	.align	2+	.globl	ffi_closure_O32+	.ent	ffi_closure_O32+ffi_closure_O32:+$LFB2:+	# Prologue+	.frame	$fp, SIZEOF_FRAME2, ra+	.set	noreorder+	.cpload	t9+	.set	reorder+	SUBU	$sp, SIZEOF_FRAME2+	.cprestore GP_OFF2+$LCFI20:+	REG_S	$16, S0_OFF2($sp)	 # Save s0+	REG_S	$fp, FP_OFF2($sp)	 # Save frame pointer+	REG_S	ra, RA_OFF2($sp)	 # Save return address+$LCFI21:+	move	$fp, $sp++$LCFI22:+	# Store all possible argument registers. If there are more than+	# four arguments, then they are stored above where we put a3.+	REG_S	a0, A0_OFF2($fp)+	REG_S	a1, A1_OFF2($fp)+	REG_S	a2, A2_OFF2($fp)+	REG_S	a3, A3_OFF2($fp)++	# Load ABI enum to s0+	REG_L	$16, 20($12)	# cif pointer follows tramp.+	REG_L	$16, 0($16)	# abi is first member.++	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.+	REG_L	a1, 24($12)	 # fun+	REG_L	a2, 28($12)	 # user_data+	addu	a3, $fp, V0_OFF2 # rvalue++	addu	t9, $fp, A0_OFF2 # ar+	REG_S   t9, CALLED_A4_OFF2($fp)++	addu	t9, $fp, FA_0_0_OFF2 #fpr+	REG_S   t9, CALLED_A5_OFF2($fp)++$do_closure:+	la	t9, ffi_closure_mips_inner_O32+	# Call ffi_closure_mips_inner_O32 to do the work.+	jalr	t9++	# Load the return value into the appropriate register.+	move	$8, $2+	li	$9, FFI_TYPE_VOID+	beq	$8, $9, closure_done++	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++	li	$9, FFI_TYPE_DOUBLE+	l.d	$f0, V0_OFF2($fp)+	beq	$8, $9, closure_done++	li      $9, FFI_TYPE_COMPLEX+	bne     $8, $9, 1f++	li      $9, 8+	l.s	$f0, V0_OFF2($fp)+	l.s	$f2, V1_OFF2($fp)+	beq     $3, $9, closure_done++	li      $9, 16+	l.d	$f0, V0_OFF2($fp)+	l.d	$f2, (V0_OFF2+8)($fp)+	beq     $3, $9, closure_done+#endif+1:	+	REG_L	$3, V1_OFF2($fp)+	REG_L	$2, V0_OFF2($fp)++closure_done:+	# Epilogue+	move	$sp, $fp+	REG_L	$16, S0_OFF2($sp)	 # Restore s0+	REG_L	$fp, FP_OFF2($sp)	 # Restore frame pointer+	REG_L	ra,  RA_OFF2($sp)	 # Restore return address+	ADDU	$sp, SIZEOF_FRAME2+	j	ra+$LFE2:+	.end	ffi_closure_O32++/* DWARF-2 unwind info. */++	.section	.eh_frame,"a",@progbits+$Lframe0:+	.4byte	$LECIE0-$LSCIE0	 # Length of Common Information Entry+$LSCIE0:+	.4byte	0x0	 # CIE Identifier Tag+	.byte	0x1	 # CIE Version+	.ascii "zR\0"	 # CIE Augmentation+	.uleb128 0x1	 # CIE Code Alignment Factor+	.sleb128 4	 # CIE Data Alignment Factor+	.byte	0x1f	 # CIE RA Column+	.uleb128 0x1	 # Augmentation size+	.byte	0x00	 # FDE Encoding (absptr)+	.byte	0xc	 # DW_CFA_def_cfa+	.uleb128 0x1d+	.uleb128 0x0+	.align	2+$LECIE0:++$LSFDE0:+	.4byte	$LEFDE0-$LASFDE0	 # FDE Length+$LASFDE0:+	.4byte	$LASFDE0-$Lframe0	 # FDE CIE offset+	.4byte	$LFB0	 # FDE initial location+	.4byte	$LFE0-$LFB0	 # FDE address range+	.uleb128 0x0	 # Augmentation size+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI00-$LFB0+	.byte	0xe	 # DW_CFA_def_cfa_offset+	.uleb128 0x18+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI01-$LCFI00+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x1e	 # $fp+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x1f	 # $ra+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI02-$LCFI01+	.byte	0xc	 # DW_CFA_def_cfa+	.uleb128 0x1e+	.uleb128 0x18+	.align	2+$LEFDE0:++$LSFDE1:+	.4byte	$LEFDE1-$LASFDE1	 # FDE Length+$LASFDE1:+	.4byte	$LASFDE1-$Lframe0	 # FDE CIE offset+	.4byte	$LFB1	 # FDE initial location+	.4byte	$LFE1-$LFB1	 # FDE address range+	.uleb128 0x0	 # Augmentation size+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI10-$LFB1+	.byte	0xe	 # DW_CFA_def_cfa_offset+	.uleb128 SIZEOF_FRAME2+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI11-$LCFI10+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x10	 # $16+	.sleb128 -3	 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x1e	 # $fp+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x1f	 # $ra+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI12-$LCFI11+	.byte	0xc	 # DW_CFA_def_cfa+	.uleb128 0x1e+	.uleb128 SIZEOF_FRAME2+	.align	2+$LEFDE1:++$LSFDE2:+	.4byte	$LEFDE2-$LASFDE2	 # FDE Length+$LASFDE2:+	.4byte	$LASFDE2-$Lframe0	 # FDE CIE offset+	.4byte	$LFB2	 # FDE initial location+	.4byte	$LFE2-$LFB2	 # FDE address range+	.uleb128 0x0	 # Augmentation size+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI20-$LFB2+	.byte	0xe	 # DW_CFA_def_cfa_offset+	.uleb128 SIZEOF_FRAME2+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI21-$LCFI20+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x10	 # $16+	.sleb128 -3	 # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x1e	 # $fp+	.sleb128 -2	 # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)+	.byte	0x11	 # DW_CFA_offset_extended_sf+	.uleb128 0x1f	 # $ra+	.sleb128 -1	 # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)+	.byte	0x4	 # DW_CFA_advance_loc4+	.4byte	$LCFI22-$LCFI21+	.byte	0xc	 # DW_CFA_def_cfa+	.uleb128 0x1e+	.uleb128 SIZEOF_FRAME2+	.align	2+$LEFDE2:++#endif++#if defined __ELF__ && defined __linux__+	.section .note.GNU-stack,"",%progbits+#endif
+ src/moxie/eabi.S view
@@ -0,0 +1,101 @@+/* -----------------------------------------------------------------------+   eabi.S - Copyright (c) 2012, 2013  Anthony Green+   +   Moxie 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++	# $r0 :   ffi_prep_args+	# $r1 :   &ecif+	# $r2 :   cif->bytes+	# $r3 :   fig->flags+	# $r4 :   ecif.rvalue+	# $r5 :   fn+	+ffi_call_EABI:+	push	$sp, $r6+	push	$sp, $r7+	push	$sp, $r8+	dec	$sp, 24++	/* Store incoming args on stack.  */+	sto.l	0($sp), $r0 /* ffi_prep_args */+	sto.l	4($sp), $r1 /* ecif */+	sto.l	8($sp), $r2 /* bytes */+	sto.l	12($sp), $r3 /* flags */+	sto.l	16($sp), $r4 /* &rvalue */+	sto.l	20($sp), $r5 /* fn */+	+	/* Call ffi_prep_args.  */+	mov 	$r6, $r4 /* Save result buffer */+	mov	$r7, $r5 /* Save the target fn */+	mov	$r8, $r3 /* Save the flags */+	sub	$sp, $r2 /* Allocate stack space */+	mov	$r0, $sp /* We can stomp over $r0 */+	/* $r1 is already set up */+	jsra 	ffi_prep_args++	/* Load register arguments.  */+	ldo.l	$r0, 0($sp)+	ldo.l	$r1, 4($sp)+	ldo.l	$r2, 8($sp)+	ldo.l	$r3, 12($sp)+	ldo.l	$r4, 16($sp)+	ldo.l	$r5, 20($sp)+	+	/* Call the target function.  */+	jsr	$r7++	ldi.l	$r7, 0xffffffff+	cmp	$r8, $r7+	beq	retstruct++	ldi.l	$r7, 4+	cmp	$r8, $r7+	bgt	ret2reg++	st.l	($r6), $r0+	jmpa	retdone++ret2reg:	+	st.l	($r6), $r0+	sto.l	4($r6), $r1++retstruct:+retdone:	+	/* Return.  */+	ldo.l	$r6, -4($fp)+	ldo.l	$r7, -8($fp)+	ldo.l	$r8, -12($fp)+	ret+	.size ffi_call_EABI, .-ffi_call_EABI+	
+ src/moxie/ffi.c view
@@ -0,0 +1,310 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (C) 2012, 2013, 2018, 2021, 2022  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;++  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)+    {+      *(void **) argp = ecif->rvalue;+      argp += 4;+    }++  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;+	}+      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 : FFI_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 = FFI_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;+  ffi_type **arg_types = cif->arg_types;+  int i, nargs = cif->nargs;++  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;++  /* If we have any large structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT) /*  && size > 4) All struct args?? */+        {+          char *argcopy = alloca (size);+          memcpy (argcopy, avalue[i], size);+          avalue[i] = argcopy;+        }+    }++  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 $r12.  We must save this+     pointer in a place that will persist while we do our work.  */+  register ffi_closure *creg __asm__ ("$r12");+  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");++  /* Pointer to a struct return value.  */+  void *struct_rvalue = (void *) arg1;++  /* 6 words reserved for register args + 3 words from jsr */+  char *stack_args = frame_pointer + 9*4;++  /* Lay the register arguments down in a continuous chunk of memory.  */+  unsigned register_args[6] =+    { arg1, arg2, arg3, arg4, arg5, arg6 };+  char *register_args_ptr = (char *) register_args;++  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;++  /* preserve struct type return pointer passing */+  if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) {+    ptr += 4;+    register_args_ptr = (char *)&register_args[1];+  }++  /* 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:+	case FFI_TYPE_POINTER:+	  avalue[i] = ptr;+	  break;+	case FFI_TYPE_STRUCT:+          {+            if (arg_types[i]->size > 4)+              {+                void *copy = alloca(arg_types[i]->size);+                memcpy(copy, *(void**)ptr, arg_types[i]->size);+                avalue[i] = copy;+              }+            else+              avalue[i] = *(void**)ptr;+          }+	  break;+	default:+	  /* This is an 8-byte value.  */+	  if (ptr == (char *) &register_args[5])+	    {+	      /* The value is split across two locations */+	      unsigned *ip = alloca(8);+	      avalue[i] = ip;+	      ip[0] = *(unsigned *) ptr;+	      ip[1] = *(unsigned *) stack_args;+	    }+	  else+	    {+	      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])+	ptr = stack_args;+      else if (ptr == (char *) &register_args[7])+	ptr = stack_args + 4;+    }++  /* Invoke the closure.  */+  if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT))+    {+      (closure->fun) (cif, struct_rvalue, 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);+      asm ("mov $r12, %0\n ld.l $r0, ($r12)\n ldo.l $r1, 4($r12)" : : "r" (&rvalue));+    }+}++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 short *tramp = (unsigned short *) &closure->tramp[0];+  unsigned long fn = (long) ffi_closure_eabi;+  unsigned long cls = (long) codeloc;++  if (cif->abi != FFI_EABI)+    return FFI_BAD_ABI;++  fn = (unsigned long) ffi_closure_eabi;++  tramp[0] = 0x01e0; /* ldi.l $r12, .... */+  tramp[1] = cls >> 16;+  tramp[2] = cls & 0xffff;+  tramp[3] = 0x1a00; /* jmpa .... */+  tramp[4] = fn >> 16;+  tramp[5] = fn & 0xffff;++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}
+ src/moxie/ffitarget.h view
@@ -0,0 +1,52 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012, 2013  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,+  FFI_EABI,+  FFI_DEFAULT_ABI = FFI_EABI,+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++/* Trampolines are 12-bytes long.  See ffi_prep_closure_loc.  */+#define FFI_TRAMPOLINE_SIZE (12)++#endif
+ src/or1k/ffi.c view
@@ -0,0 +1,341 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2014 Sebastian Macke <sebastian@macke.de>++   OpenRISC 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"++/* 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)+{+  char *stacktemp = stack;+  int i, s;+  ffi_type **arg;+  int count = 0;+  int nfixedargs;++  nfixedargs = ecif->cif->nfixedargs;+  arg = ecif->cif->arg_types;+  void **argv = ecif->avalue;++  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)+    {+      *(void **) stack = ecif->rvalue;+      stack += 4;+      count = 4;+    }+  for(i=0; i<ecif->cif->nargs; i++)+  {++    /* variadic args are saved on stack */+    if ((nfixedargs == 0) && (count < 24))+      {+        count = 24;+        stack = stacktemp + 24;+      }+    nfixedargs--;++    s = 4;+    switch((*arg)->type)+      {+      case FFI_TYPE_STRUCT:+        *(void **)stack = *argv;+        break;++      case FFI_TYPE_SINT8:+        *(signed int *) stack = (signed int)*(SINT8 *)(* argv);+        break;++      case FFI_TYPE_UINT8:+        *(unsigned int *) stack = (unsigned int)*(UINT8 *)(* argv);+        break;++      case FFI_TYPE_SINT16:+        *(signed int *) stack = (signed int)*(SINT16 *)(* argv);+        break;++      case FFI_TYPE_UINT16:+        *(unsigned int *) stack = (unsigned int)*(UINT16 *)(* argv);+        break;++      case FFI_TYPE_SINT32:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_FLOAT:+      case FFI_TYPE_POINTER:+        *(int *)stack = *(int*)(*argv);+        break;++      default: /* 8 byte types */+        if (count == 20) /* never split arguments */+          {+            stack += 4;+            count += 4;+          }+        s = (*arg)->size;+        memcpy(stack, *argv, s);+        break;+      }++    stack += s;+    count += s;+    argv++;+    arg++;+  }+  return stacktemp + ((count>24)?24:0);+}++extern void ffi_call_SYSV(unsigned,+                          extended_cif *,+                          void *(*)(char *, extended_cif *),+                          unsigned *,+                          void (*fn)(void),+                          unsigned);+++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  int i;+  int size;+  ffi_type **arg;++  /* Calculate size to allocate on stack */++  for(i = 0, arg = cif->arg_types, size=0; i < cif->nargs; i++, arg++)+    {+      if ((*arg)->type == FFI_TYPE_STRUCT)+        size += 4;+      else+      if ((*arg)->size <= 4)+        size += 4;+      else+        size += 8;++      /* If we have any large structure arguments, make a copy so we are passing+         by value.  */+      {+        ffi_type *at = cif->arg_types[i];+        int size = at->size;+        if (at->type == FFI_TYPE_STRUCT) /* && size > 4) All struct args? */+          {+            char *argcopy = alloca (size);+            memcpy (argcopy, avalue[i], size);+            avalue[i] = argcopy;+          }+      }+    }++  /* for variadic functions more space is needed on the stack */+  if (cif->nargs != cif->nfixedargs)+    size += 24;++  if (cif->rtype->type == FFI_TYPE_STRUCT)+    size += 4;+++  extended_cif ecif;+  ecif.cif = cif;+  ecif.avalue = avalue;+  ecif.rvalue = rvalue;++  switch (cif->abi)+  {+    case FFI_SYSV:+      ffi_call_SYSV(size, &ecif, ffi_prep_args, rvalue, fn, cif->flags);+      break;+    default:+      FFI_ASSERT(0);+      break;+  }+}+++void ffi_closure_SYSV(unsigned long r3, unsigned long r4, unsigned long r5,+                      unsigned long r6, unsigned long r7, unsigned long r8)+{+  register int *sp __asm__ ("r17");+  register int *r13 __asm__ ("r13");++  ffi_closure* closure = (ffi_closure*) r13;+  char *stack_args = (char*) sp;++  /* Lay the register arguments down in a continuous chunk of memory.  */+  unsigned register_args[6] =+    { r3, r4, r5, r6, r7, r8 };++  /* Pointer to a struct return value.  */+  void *struct_rvalue = (void *) r3;++  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 count = 0;+  int nfixedargs = cif->nfixedargs;+  int i;++  /* preserve struct type return pointer passing */++  if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))+  {+    ptr += 4;+    count = 4;+  }++  /* Find the address of each argument.  */+  for (i = 0; i < cif->nargs; i++)+    {++      /* variadic args are saved on stack */+      if ((nfixedargs == 0) && (count < 24))+        {+          ptr = stack_args;+          count = 24;+        }+      nfixedargs--;++      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:+        case FFI_TYPE_POINTER:+          avalue[i] = ptr;+          break;++        case FFI_TYPE_STRUCT:+          avalue[i] = *(void**)ptr;+          break;++        default:+          /* 8-byte values  */++          /* arguments are never splitted */+          if (ptr == &register_args[5])+            ptr = stack_args;+          avalue[i] = ptr;+          ptr += 4;+          count += 4;+          break;+        }+      ptr += 4;+      count += 4;++      /* If we've handled more arguments than fit in registers,+         start looking at the those passed on the stack.  */++      if (count == 24)+        ptr = stack_args;+    }++  if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT))+    {+      (closure->fun) (cif, struct_rvalue, avalue, closure->user_data);+    } else+    {+      long long rvalue;+      (closure->fun) (cif, &rvalue, avalue, closure->user_data);+      if (cif->rtype)+        asm ("l.ori r12, %0, 0x0\n l.lwz r11, 0(r12)\n l.lwz r12, 4(r12)" : : "r" (&rvalue));+    }+}+++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 short *tramp = (unsigned short *) closure->tramp;+  unsigned long fn = (unsigned long) ffi_closure_SYSV;+  unsigned long cls = (unsigned long) codeloc;++  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  closure->cif = cif;+  closure->user_data = user_data;+  closure->fun = fun;++  /* write pointers to temporary registers */+  tramp[0] = (0x6 << 10) | (13 << 5); /* l.movhi r13, ... */+  tramp[1] = cls >> 16;+  tramp[2] = (0x2a << 10) | (13 << 5) | 13; /* l.ori r13, r13, ... */+  tramp[3] = cls & 0xFFFF;++  tramp[4] = (0x6 << 10) | (15 << 5); /* l.movhi r15, ... */+  tramp[5] = fn >> 16;+  tramp[6] = (0x2a << 10) | (15 << 5) | 15; /* l.ori r15, r15 ... */+  tramp[7] = fn & 0xFFFF;++  tramp[8] = (0x11 << 10); /* l.jr r15 */+  tramp[9] = 15 << 11;++  tramp[10] = (0x2a << 10) | (17 << 5) | 1; /* l.ori r17, r1, ... */+  tramp[11] = 0x0;++  return FFI_OK;+}+++ffi_status ffi_prep_cif_machdep (ffi_cif *cif)+{+  cif->flags = 0;++  /* structures are returned as pointers */+  if (cif->rtype->type == FFI_TYPE_STRUCT)+    cif->flags = FFI_TYPE_STRUCT;+  else+  if (cif->rtype->size > 4)+    cif->flags = FFI_TYPE_UINT64;++  cif->nfixedargs = cif->nargs;++  return FFI_OK;+}+++ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,+         unsigned int nfixedargs, unsigned int ntotalargs)+{+  ffi_status status;++  status = ffi_prep_cif_machdep (cif);+  cif->nfixedargs = nfixedargs;+  return status;+}
+ src/or1k/ffitarget.h view
@@ -0,0 +1,58 @@+/* -----------------------------------------------------------------------+   ffitarget.h - Copyright (c) 2014 Sebastian Macke <sebastian@macke.de>++   OpenRISC Target configuration macros++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0+#define FFI_TRAMPOLINE_SIZE (24)++#define FFI_TARGET_SPECIFIC_VARIADIC 1+#define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs;++#endif+
+ src/or1k/sysv.S view
@@ -0,0 +1,107 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2014 Sebastian Macke <sebastian@macke.de>++   OpenRISC Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++.text+	.globl ffi_call_SYSV+	.type ffi_call_SYSV, @function+/*+  r3: size to allocate on stack+  r4: extended cif structure+  r5: function pointer ffi_prep_args+  r6: ret address+  r7: function to call+  r8: flag for return type+*/++ffi_call_SYSV:+	/* Store registers used on stack */+	l.sw -4(r1), r9 /* return address */+	l.sw -8(r1), r1 /* stack address */+	l.sw -12(r1), r14 /* callee saved registers */+	l.sw -16(r1), r16+	l.sw -20(r1), r18 +	l.sw -24(r1), r20++	l.ori r14, r1, 0x0 /* save stack pointer */+	l.addi r1, r1, -24++	l.ori r16, r7, 0x0 /* save function address */+	l.ori r18, r6, 0x0 /* save ret address */+	l.ori r20, r8, 0x0 /* save flag */++	l.sub r1, r1, r3 /* reserve space on stack */++	/* Call ffi_prep_args */+	l.ori r3, r1, 0x0  /* first argument stack address, second already ecif */+	l.jalr r5+	l.nop++	/* Load register arguments and call*/++	l.lwz r3, 0(r1)+	l.lwz r4, 4(r1)+	l.lwz r5, 8(r1)+	l.lwz r6, 12(r1)+	l.lwz r7, 16(r1)+	l.lwz r8, 20(r1)+	l.ori r1, r11, 0x0 /* new stack pointer */+	l.jalr r16+	l.nop+	+	/* handle return values */++	l.sfeqi r20, FFI_TYPE_STRUCT+	l.bf ret  /* structs don't return an rvalue */+	l.nop++	/* copy ret address */++	l.sfeqi r20, FFI_TYPE_UINT64+	l.bnf four_byte_ret  /* 8 byte value is returned */+	l.nop++	l.sw 4(r18), r12++four_byte_ret:+	l.sw 0(r18), r11++ret:+	/* return */+	l.ori r1, r14, 0x0 /* reset stack pointer */+	l.lwz r9, -4(r1)+	l.lwz r1, -8(r1)+	l.lwz r14, -12(r1)+	l.lwz r16, -16(r1)+	l.lwz r18, -20(r1)+	l.lwz r20, -24(r1)+	l.jr r9+	l.nop++.size ffi_call_SYSV, .-ffi_call_SYSV
+ src/pa/ffi.c view
@@ -0,0 +1,673 @@+/* -----------------------------------------------------------------------+   ffi.c - (c) 2011 Anthony Green+           (c) 2008 Red Hat, Inc.+	   (c) 2006 Free Software Foundation, Inc.+           (c) 2003-2004 Randolph Chung <tausq@debian.org>+           +   HPPA Foreign Function Interface+   HP-UX PA ABI support ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdio.h>++#define ROUND_UP(v, a)  (((size_t)(v) + (a) - 1) & ~((a) - 1))++#define MIN_STACK_SIZE  64+#define FIRST_ARG_SLOT  9+#define DEBUG_LEVEL   0++#define fldw(addr, fpreg) \+  __asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)+#define fstw(fpreg, addr) \+  __asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))+#define fldd(addr, fpreg) \+  __asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)+#define fstd(fpreg, addr) \+  __asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))++#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)++static inline int ffi_struct_type(ffi_type *t)+{+  size_t sz = t->size;++  /* Small structure results are passed in registers,+     larger ones are passed by pointer.  Note that small+     structures differ from the corresponding integer+     types in that they have different alignment requirements.  */++  if (sz <= 8)+    return -sz;+  else+    return FFI_TYPE_STRUCT; /* else, we pass it by pointer.  */+}++/* PA has a downward growing stack, which looks like this:++   Offset+	[ Variable args ]+   SP = (4*(n+9))       arg word N+   ...+   SP-52                arg word 4+	[ Fixed args ]+   SP-48                arg word 3+   SP-44                arg word 2+   SP-40                arg word 1+   SP-36                arg word 0+	[ Frame marker ]+   ...+   SP-20                RP+   SP-4                 previous SP++   The first four argument words on the stack are reserved for use by+   the callee.  Instead, the general and floating registers replace+   the first four argument slots.  Non FP arguments are passed solely+   in the general registers.  FP arguments are passed in both general+   and floating registers when using libffi.++   Non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23.+   Non-FP 64-bit args are passed in register pairs, starting+   on an odd numbered register (i.e. r25+r26 and r23+r24).+   FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L.+   FP 64-bit arguments are passed in fr5 and fr7.++   The registers are allocated in the same manner as stack slots.+   This allows the callee to save its arguments on the stack if+   necessary:++   arg word 3 -> gr23 or fr7L+   arg word 2 -> gr24 or fr6L or fr7R+   arg word 1 -> gr25 or fr5L+   arg word 0 -> gr26 or fr4L or fr5R++   Note that fr4R and fr6R are never used for arguments (i.e.,+   doubles are not passed in fr4 or fr6).++   The rest of the arguments are passed on the stack starting at SP-52,+   but 64-bit arguments need to be aligned to an 8-byte boundary++   This means we can have holes either in the register allocation,+   or in the stack.  */++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments++   The following code will put everything into the stack frame+   (which was allocated by the asm routine), and on return+   the asm routine will load the arguments that should be+   passed by register into the appropriate registers++   NOTE: We load floating point args in this function... that means we+   assume gcc will not mess with fp regs in here.  */++void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes)+{+  register unsigned int i;+  register ffi_type **p_arg;+  register void **p_argv;+  unsigned int slot = FIRST_ARG_SLOT;+  char *dest_cpy;+  size_t len;++  debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack,+	ecif, bytes);++  p_arg = ecif->cif->arg_types;+  p_argv = ecif->avalue;++  for (i = 0; i < ecif->cif->nargs; i++)+    {+      int type = (*p_arg)->type;++      switch (type)+	{+	case FFI_TYPE_SINT8:+	  *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);+	  break;++	case FFI_TYPE_UINT8:+	  *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);+	  break;++	case FFI_TYPE_SINT16:+	  *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);+	  break;++	case FFI_TYPE_UINT16:+	  *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);+	  break;++	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_POINTER:+	  debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv),+		slot);+	  *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);+	  break;++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	  /* Align slot for 64-bit type.  */+	  slot += (slot & 1) ? 1 : 2;+	  *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);+	  break;++	case FFI_TYPE_FLOAT:+	  /* First 4 args go in fr4L - fr7L.  */+	  debug(3, "Storing UINT32(float) in slot %u\n", slot);+	  *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);+	  switch (slot - FIRST_ARG_SLOT)+	    {+	    /* First 4 args go in fr4L - fr7L.  */+	    case 0: fldw(stack - slot, fr4); break;+	    case 1: fldw(stack - slot, fr5); break;+	    case 2: fldw(stack - slot, fr6); break;+	    case 3: fldw(stack - slot, fr7); break;+	    }+	  break;++	case FFI_TYPE_DOUBLE:+	  /* Align slot for 64-bit type.  */+	  slot += (slot & 1) ? 1 : 2;+	  debug(3, "Storing UINT64(double) at slot %u\n", slot);+	  *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);+	  switch (slot - FIRST_ARG_SLOT)+	    {+	      /* First 2 args go in fr5, fr7.  */+	      case 1: fldd(stack - slot, fr5); break;+	      case 3: fldd(stack - slot, fr7); break;+	    }+	  break;++#ifdef PA_HPUX+	case FFI_TYPE_LONGDOUBLE:+	  /* Long doubles are passed in the same manner as structures+	     larger than 8 bytes.  */+	  *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);+	  break;+#endif++	case FFI_TYPE_STRUCT:++	  /* Structs smaller or equal than 4 bytes are passed in one+	     register. Structs smaller or equal 8 bytes are passed in two+	     registers. Larger structures are passed by pointer.  */++	  len = (*p_arg)->size;+	  if (len <= 4)+	    {+	      dest_cpy = (char *)(stack - slot) + 4 - len;+	      memcpy(dest_cpy, (char *)*p_argv, len);+	    }+	  else if (len <= 8)+	    {+	      slot += (slot & 1) ? 1 : 2;+	      dest_cpy = (char *)(stack - slot) + 8 - len;+	      memcpy(dest_cpy, (char *)*p_argv, len);+	    }+	  else+	    *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);+	  break;++	default:+	  FFI_ASSERT(0);+	}++      slot++;+      p_arg++;+      p_argv++;+    }++  /* Make sure we didn't mess up and scribble on the stack.  */+  {+    unsigned int n;++    debug(5, "Stack setup:\n");+    for (n = 0; n < (bytes + 3) / 4; n++)+      {+	if ((n%4) == 0) { debug(5, "\n%08x: ", (unsigned int)(stack - n)); }+	debug(5, "%08x ", *(stack - n));+      }+    debug(5, "\n");+  }++  FFI_ASSERT(slot * 4 <= bytes);++  return;+}++static void ffi_size_stack_pa32(ffi_cif *cif)+{+  ffi_type **ptr;+  int i;+  int z = 0; /* # stack slots */++  for (ptr = cif->arg_types, i = 0; i < cif->nargs; ptr++, i++)+    {+      int type = (*ptr)->type;++      switch (type)+	{+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	  z += 2 + (z & 1); /* must start on even regs, so we may waste one */+	  break;++#ifdef PA_HPUX+	case FFI_TYPE_LONGDOUBLE:+#endif+	case FFI_TYPE_STRUCT:+	  z += 1; /* pass by ptr, callee will copy */+	  break;++	default: /* <= 32-bit values */+	  z++;+	}+    }++  /* We can fit up to 6 args in the default 64-byte stack frame,+     if we need more, we need more stack.  */+  if (z <= 6)+    cif->bytes = MIN_STACK_SIZE; /* min stack size */+  else+    cif->bytes = 64 + ROUND_UP((z - 6) * sizeof(UINT32), MIN_STACK_SIZE);++  debug(3, "Calculated stack size is %u bytes\n", cif->bytes);+}++/* Perform machine dependent cif processing.  */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+      cif->flags = (unsigned) cif->rtype->type;+      break;++#ifdef PA_HPUX+    case FFI_TYPE_LONGDOUBLE:+      /* Long doubles are treated like a structure.  */+      cif->flags = FFI_TYPE_STRUCT;+      break;+#endif++    case FFI_TYPE_STRUCT:+      /* For the return type we have to check the size of the structures.+	 If the size is smaller or equal 4 bytes, the result is given back+	 in one register. If the size is smaller or equal 8 bytes than we+	 return the result in two registers. But if the size is bigger than+	 8 bytes, we work with pointers.  */+      cif->flags = ffi_struct_type(cif->rtype);+      break;++    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      cif->flags = FFI_TYPE_UINT64;+      break;++    default:+      cif->flags = FFI_TYPE_INT;+      break;+    }++  /* Lucky us, because of the unique PA ABI we get to do our+     own stack sizing.  */+  switch (cif->abi)+    {+    case FFI_PA32:+      ffi_size_stack_pa32(cif);+      break;++    default:+      FFI_ASSERT(0);+      break;+    }++  return FFI_OK;+}++extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),+			  extended_cif *, unsigned, unsigned, unsigned *,+			  void (*fn)(void));++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  extended_cif ecif;+  size_t i, nargs = cif->nargs;+  ffi_type **arg_types = cif->arg_types;++  ecif.cif = cif;+  ecif.avalue = avalue;++  /* If we have any large structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT && size > 8)+	{+	  char *argcopy = alloca (size);+	  memcpy (argcopy, avalue[i], size);+	  avalue[i] = argcopy;+	}+    }++  /* 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+#ifdef PA_HPUX+      && (cif->rtype->type == FFI_TYPE_STRUCT+	  || cif->rtype->type == FFI_TYPE_LONGDOUBLE))+#else+      && cif->rtype->type == FFI_TYPE_STRUCT)+#endif+    {+      ecif.rvalue = alloca(cif->rtype->size);+    }+  else+    ecif.rvalue = rvalue;+++  switch (cif->abi)+    {+    case FFI_PA32:+      debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);+      ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes,+		     cif->flags, ecif.rvalue, fn);+      break;++    default:+      FFI_ASSERT(0);+      break;+    }+}++#if FFI_CLOSURES+/* This is more-or-less an inverse of ffi_call -- we have arguments on+   the stack, and we need to fill them into a cif structure and invoke+   the user function. This really ought to be in asm to make sure+   the compiler doesn't do things we don't expect.  */+ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)+{+  ffi_cif *cif;+  void **avalue;+  void *rvalue;+  /* Functions can return up to 64-bits in registers.  Return address+     must be double word aligned.  */+  union { double rd; UINT32 ret[2]; } u;+  ffi_type **p_arg;+  char *tmp;+  int i, avn;+  unsigned int slot = FIRST_ARG_SLOT;+  register UINT32 r28 asm("r28");++  cif = closure->cif;++  /* If returning via structure, callee will write to our pointer.  */+  if (cif->flags == FFI_TYPE_STRUCT)+    rvalue = (void *)r28;+  else+    rvalue = &u;++  avalue = (void **)alloca(cif->nargs * FFI_SIZEOF_ARG);+  avn = cif->nargs;+  p_arg = cif->arg_types;++  for (i = 0; i < avn; i++)+    {+      int type = (*p_arg)->type;++      switch (type)+	{+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_POINTER:+	  avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size;+	  break;++	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	  slot += (slot & 1) ? 1 : 2;+	  avalue[i] = (void *)(stack - slot);+	  break;++	case FFI_TYPE_FLOAT:+#ifdef PA_LINUX+	  /* The closure call is indirect.  In Linux, floating point+	     arguments in indirect calls with a prototype are passed+	     in the floating point registers instead of the general+	     registers.  So, we need to replace what was previously+	     stored in the current slot with the value in the+	     corresponding floating point register.  */+	  switch (slot - FIRST_ARG_SLOT)+	    {+	    case 0: fstw(fr4, (void *)(stack - slot)); break;+	    case 1: fstw(fr5, (void *)(stack - slot)); break;+	    case 2: fstw(fr6, (void *)(stack - slot)); break;+	    case 3: fstw(fr7, (void *)(stack - slot)); break;+	    }+#endif+	  avalue[i] = (void *)(stack - slot);+	  break;++	case FFI_TYPE_DOUBLE:+	  slot += (slot & 1) ? 1 : 2;+#ifdef PA_LINUX+	  /* See previous comment for FFI_TYPE_FLOAT.  */+	  switch (slot - FIRST_ARG_SLOT)+	    {+	    case 1: fstd(fr5, (void *)(stack - slot)); break;+	    case 3: fstd(fr7, (void *)(stack - slot)); break;+	    }+#endif+	  avalue[i] = (void *)(stack - slot);+	  break;++#ifdef PA_HPUX+	case FFI_TYPE_LONGDOUBLE:+	  /* Long doubles are treated like a big structure.  */+	  avalue[i] = (void *) *(stack - slot);+	  break;+#endif++	case FFI_TYPE_STRUCT:+	  /* Structs smaller or equal than 4 bytes are passed in one+	     register. Structs smaller or equal 8 bytes are passed in two+	     registers. Larger structures are passed by pointer.  */+	  if((*p_arg)->size <= 4)+	    {+	      avalue[i] = (void *)(stack - slot) + sizeof(UINT32) -+		(*p_arg)->size;+	    }+	  else if ((*p_arg)->size <= 8)+	    {+	      slot += (slot & 1) ? 1 : 2;+	      avalue[i] = (void *)(stack - slot) + sizeof(UINT64) -+		(*p_arg)->size;+	    }+	  else+	    avalue[i] = (void *) *(stack - slot);+	  break;++	default:+	  FFI_ASSERT(0);+	}++      slot++;+      p_arg++;+    }++  /* Invoke the closure.  */+  (closure->fun) (cif, rvalue, avalue, closure->user_data);++  debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", u.ret[0],+	u.ret[1]);++  /* Store the result using the lower 2 bytes of the flags.  */+  switch (cif->flags)+    {+    case FFI_TYPE_UINT8:+      *(stack - FIRST_ARG_SLOT) = (UINT8)u.ret[0];+      break;+    case FFI_TYPE_SINT8:+      *(stack - FIRST_ARG_SLOT) = (SINT8)u.ret[0];+      break;+    case FFI_TYPE_UINT16:+      *(stack - FIRST_ARG_SLOT) = (UINT16)u.ret[0];+      break;+    case FFI_TYPE_SINT16:+      *(stack - FIRST_ARG_SLOT) = (SINT16)u.ret[0];+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+      *(stack - FIRST_ARG_SLOT) = u.ret[0];+      break;+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      *(stack - FIRST_ARG_SLOT) = u.ret[0];+      *(stack - FIRST_ARG_SLOT - 1) = u.ret[1];+      break;++    case FFI_TYPE_DOUBLE:+      fldd(rvalue, fr4);+      break;++    case FFI_TYPE_FLOAT:+      fldw(rvalue, fr4);+      break;++    case FFI_TYPE_STRUCT:+      /* Don't need a return value, done by caller.  */+      break;++    case FFI_TYPE_SMALL_STRUCT1:+    case FFI_TYPE_SMALL_STRUCT2:+    case FFI_TYPE_SMALL_STRUCT3:+    case FFI_TYPE_SMALL_STRUCT4:+      tmp = (void*)(stack -  FIRST_ARG_SLOT);+      tmp += 4 - cif->rtype->size;+      memcpy((void*)tmp, &u, cif->rtype->size);+      break;++    case FFI_TYPE_SMALL_STRUCT5:+    case FFI_TYPE_SMALL_STRUCT6:+    case FFI_TYPE_SMALL_STRUCT7:+    case FFI_TYPE_SMALL_STRUCT8:+      {+	unsigned int ret2[2];+	int off;++	/* Right justify ret[0] and ret[1] */+	switch (cif->flags)+	  {+	    case FFI_TYPE_SMALL_STRUCT5: off = 3; break;+	    case FFI_TYPE_SMALL_STRUCT6: off = 2; break;+	    case FFI_TYPE_SMALL_STRUCT7: off = 1; break;+	    default: off = 0; break;+	  }++	memset (ret2, 0, sizeof (ret2));+	memcpy ((char *)ret2 + off, &u, 8 - off);++	*(stack - FIRST_ARG_SLOT) = ret2[0];+	*(stack - FIRST_ARG_SLOT - 1) = ret2[1];+      }+      break;++    case FFI_TYPE_POINTER:+    case FFI_TYPE_VOID:+      break;++    default:+      debug(0, "assert with cif->flags: %d\n",cif->flags);+      FFI_ASSERT(0);+      break;+    }+  return FFI_OK;+}++/* Fill in a closure to refer to the specified fun and user_data.+   cif specifies the argument and result types for fun.+   The cif must already be prep'ed.  */++extern void ffi_closure_pa32(void);++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif*,void*,void**,void*),+		      void *user_data,+		      void *codeloc)+{+  /* The layout of a function descriptor.  A function pointer with the PLABEL+     bit set points to a function descriptor.  */+  struct pa32_fd+  {+    UINT32 code_pointer;+    UINT32 gp;+  };++  struct ffi_pa32_trampoline_struct+  {+     UINT32 code_pointer;        /* Pointer to ffi_closure_unix.  */+     UINT32 fake_gp;             /* Pointer to closure, installed as gp.  */+     UINT32 real_gp;             /* Real gp value.  */+  };++  struct ffi_pa32_trampoline_struct *tramp;+  struct pa32_fd *fd;++  if (cif->abi != FFI_PA32)+    return FFI_BAD_ABI;++  /* Get function descriptor address for ffi_closure_pa32.  */+  fd = (struct pa32_fd *)((UINT32)ffi_closure_pa32 & ~3);++  /* Setup trampoline.  */+  tramp = (struct ffi_pa32_trampoline_struct *)closure->tramp;+  tramp->code_pointer = fd->code_pointer;+  tramp->fake_gp = (UINT32)codeloc & ~3;+  tramp->real_gp = fd->gp;++  closure->cif  = cif;+  closure->user_data = user_data;+  closure->fun  = fun;++  return FFI_OK;+}+#endif
+ src/pa/ffitarget.h view
@@ -0,0 +1,94 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for hppa.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,++#ifdef PA_LINUX+  FFI_PA32,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_PA32+#endif++#ifdef PA_HPUX+  FFI_PA32,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_PA32+#endif++#ifdef PA64_HPUX+  FFI_PA64,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_PA64+#endif+} ffi_abi;+#endif++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0+#if defined(PA64_HPUX)+#define FFI_TRAMPOLINE_SIZE 32+#else+#define FFI_TRAMPOLINE_SIZE 12+#endif++#define FFI_TYPE_SMALL_STRUCT1 -1+#define FFI_TYPE_SMALL_STRUCT2 -2+#define FFI_TYPE_SMALL_STRUCT3 -3+#define FFI_TYPE_SMALL_STRUCT4 -4+#define FFI_TYPE_SMALL_STRUCT5 -5+#define FFI_TYPE_SMALL_STRUCT6 -6+#define FFI_TYPE_SMALL_STRUCT7 -7+#define FFI_TYPE_SMALL_STRUCT8 -8++/* linux.S and hpux32.S expect FFI_TYPE_COMPLEX is the last generic type.  */+#define FFI_PA_TYPE_LAST FFI_TYPE_COMPLEX++/* If new generic types are added, the jump tables in linux.S and hpux32.S+   likely need updating.  */+#if FFI_TYPE_LAST != FFI_PA_TYPE_LAST+# error "You likely have broken jump tables"+#endif++#endif
+ src/pa/hpux32.S view
@@ -0,0 +1,417 @@+/* -----------------------------------------------------------------------+   hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.+	                (c) 2008 Red Hat, Inc.+   based on src/pa/linux.S++   HP-UX PA 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 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>++	.LEVEL 1.1+	.SPACE	$PRIVATE$+	.IMPORT	$global$,DATA+	.IMPORT	$$dyncall,MILLICODE+	.SUBSPA	$DATA$+	.align	4++	/* void ffi_call_pa32(void (*)(char *, extended_cif *),+			       extended_cif *ecif,+			       unsigned bytes,+			       unsigned flags,+			       unsigned *rvalue,+			       void (*fn)(void));+	 */++	.export	ffi_call_pa32,ENTRY,PRIV_LEV=3+	.import	ffi_prep_args_pa32,CODE++	.SPACE	$TEXT$+	.SUBSPA $CODE$+	.align	4++L$FB1+ffi_call_pa32+	.proc+	.callinfo	FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4+	.entry+	stw	%rp, -20(%sp)+	copy	%r3, %r1+L$CFI11+	copy	%sp, %r3+L$CFI12++	/* Setup the stack for calling prep_args...+	   We want the stack to look like this:++	   [ Previous stack                            ] <- %r3++	   [ 64-bytes register save area               ] <- %r4++	   [ Stack space for actual call, passed as    ] <- %arg0+	   [     arg0 to ffi_prep_args_pa32           ]++	   [ Stack for calling prep_args               ] <- %sp+	 */++	stwm	%r1, 64(%sp)+	stw	%r4, 12(%r3)+L$CFI13+	copy	%sp, %r4++	addl	%arg2, %r4, %arg0	; arg stack+	stw	%arg3, -48(%r3)		; save flags we need it later++	/* Call prep_args:+	   %arg0(stack) -- set up above+	   %arg1(ecif)  -- same as incoming param+	   %arg2(bytes) -- same as incoming param */+	bl	ffi_prep_args_pa32,%r2+	ldo	64(%arg0), %sp+	ldo	-64(%sp), %sp++	/* now %sp should point where %arg0 was pointing.  */++	/* Load the arguments that should be passed in registers+	   The fp args are loaded by the prep_args function.  */+	ldw	-36(%sp), %arg0+	ldw	-40(%sp), %arg1+	ldw	-44(%sp), %arg2+	ldw	-48(%sp), %arg3++	/* in case the function is going to return a structure+	   we need to give it a place to put the result.  */+	ldw	-52(%r3), %ret0		; %ret0 <- rvalue+	ldw	-56(%r3), %r22		; %r22 <- function to call+	bl	$$dyncall, %r31		; Call the user function+	copy	%r31, %rp++	/* Prepare to store the result; we need to recover flags and rvalue.  */+	ldw	-48(%r3), %r21		; r21 <- flags++	/* Adjust flags range from [-8, 15] to  [0, 23].  */+	addi	8, %r21, %r21++	blr	%r21, %r0+	ldw	-52(%r3), %r20		; r20 <- rvalue++	/* Giant jump table */+	/* 8-byte small struct */+	b,n	L$smst8+	nop+	/* 7-byte small struct */+	b,n	L$smst7+	nop+	/* 6-byte small struct */+	b,n	L$smst6+	nop+	/* 5-byte small struct */+	b,n	L$smst5+	nop+	/* 4-byte small struct */+	b,n	L$smst4+	nop+	/* 3-byte small struct */+	b,n	L$smst3+	nop+	/* 2-byte small struct */+	b,n	L$smst2+	nop+	/* 1-byte small struct */+	b	L$done+	stb	%ret0, 0(%r20)+	/* void */+	b,n	L$done+	nop+	/* int */+	b	L$done+	stw	%ret0, 0(%r20)+	/* float */+	b	L$done+	fstw	%fr4L,0(%r20)+	/* double */+	b	L$done+	fstd	%fr4,0(%r20)+	/* long double */+	b,n	L$done+	nop+	/* unsigned int8 */+	b	L$done+	stw	%ret0, 0(%r20)+	/* signed int8 */+	b	L$done+	stw	%ret0, 0(%r20)+	/* unsigned int16 */+	b	L$done+	stw	%ret0, 0(%r20)+	/* signed int16 */+	b	L$done+	stw	%ret0, 0(%r20)+	/* unsigned int32 */+	b	L$done+	stw	%ret0, 0(%r20)+	/* signed int32 */+	b	L$done+	stw	%ret0, 0(%r20)+	/* unsigned int64 */+	b,n	L$uint64+	nop+	/* signed int64 */+	b,n	L$sint64+	nop+	/* large struct */+	b,n	L$done+	nop+	/* pointer */+	b	L$done+	stw	%ret0, 0(%r20)+	/* complex */+	b,n	L$done+	nop++	/* Store the result according to the return type.  The most+	   likely types should come first.  */++L$uint64+L$sint64+	stw	%ret0, 0(%r20)+	b	L$done+	stw	%ret1, 4(%r20)++L$smst2+	/* 2-byte structs are returned in ret0 as ????xxyy.  */+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret0, 0(%r20)++L$smst3+	/* 3-byte structs are returned in ret0 as ??xxyyzz.  */+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret0, 0(%r20)++L$smst4+	/* 4-byte structs are returned in ret0 as wwxxyyzz.  */+	extru	%ret0, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret0, 0(%r20)++L$smst5+	/* 5 byte values are returned right justified:+	      ret0     ret1+	   5: ??????aa bbccddee */+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret1, 0(%r20)++L$smst6+	/* 6 byte values are returned right justified:+	      ret0     ret1+	   6: ????aabb ccddeeff */+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret1, 0(%r20)++L$smst7+	/* 7 byte values are returned right justified:+	      ret0     ret1+	   7: ??aabbcc ddeeffgg */+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret1, 0(%r20)++L$smst8+	/* 8 byte values are returned right justified:+	      ret0     ret1+	   8: aabbccdd eeffgghh */+	extru	%ret0, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stb	%ret1, 0(%r20)++L$done+	/* all done, return */+	copy	%r4, %sp	; pop arg stack+	ldw	12(%r3), %r4+	ldwm	-64(%sp), %r3	; .. and pop stack+	ldw	-20(%sp), %rp+	bv	%r0(%rp)+	nop+	.exit+	.procend+L$FE1++	/* void ffi_closure_pa32(void);+	   Called with closure argument in %r19 */++	.SPACE $TEXT$+	.SUBSPA $CODE$+	.export ffi_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR+	.import ffi_closure_inner_pa32,CODE+	.align 4+L$FB2+ffi_closure_pa32+	.proc+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3+	.entry++	stw	%rp, -20(%sp)+	copy	%r3, %r1+L$CFI21+	copy	%sp, %r3+L$CFI22+	stwm	%r1, 64(%sp)++	/* Put arguments onto the stack and call ffi_closure_inner.  */+	stw	%arg0, -36(%r3)+	stw	%arg1, -40(%r3)+	stw	%arg2, -44(%r3)+	stw	%arg3, -48(%r3)++	/* Retrieve closure pointer and real gp.  */+	copy	%r19, %arg0+	ldw	8(%r19), %r19+	bl	ffi_closure_inner_pa32, %r2+	copy    %r3, %arg1+	ldwm	-64(%sp), %r3+	ldw	-20(%sp), %rp+	ldw	-36(%sp), %ret0+	bv	%r0(%rp)+	ldw	-40(%sp), %ret1+	.exit+	.procend+L$FE2:++	.SPACE $PRIVATE$+	.SUBSPA $DATA$++	.align 4+	.EXPORT _GLOBAL__F_ffi_call_pa32,DATA+_GLOBAL__F_ffi_call_pa32+L$frame1:+	.word   L$ECIE1-L$SCIE1 ;# Length of Common Information Entry+L$SCIE1:+	.word   0x0     ;# CIE Identifier Tag+	.byte   0x1     ;# CIE Version+	.ascii "\0"     ;# CIE Augmentation+	.uleb128 0x1    ;# CIE Code Alignment Factor+	.sleb128 4      ;# CIE Data Alignment Factor+	.byte   0x2     ;# CIE RA Column+	.byte   0xc     ;# DW_CFA_def_cfa+	.uleb128 0x1e+	.uleb128 0x0+	.align 4+L$ECIE1:+L$SFDE1:+	.word   L$EFDE1-L$ASFDE1        ;# FDE Length+L$ASFDE1:+	.word   L$ASFDE1-L$frame1       ;# FDE CIE offset+	.word   L$FB1   ;# FDE initial location+	.word   L$FE1-L$FB1     ;# FDE address range++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI11-L$FB1+	.byte	0x83	;# DW_CFA_offset, column 0x3+	.uleb128 0x0+	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]+	.uleb128 0x2+	.sleb128 -5++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI12-L$CFI11+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3+	.uleb128 0x3++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI13-L$CFI12+	.byte	0x84	;# DW_CFA_offset, column 0x4+	.uleb128 0x3++	.align 4+L$EFDE1:++L$SFDE2:+	.word   L$EFDE2-L$ASFDE2        ;# FDE Length+L$ASFDE2:+	.word   L$ASFDE2-L$frame1       ;# FDE CIE offset+	.word   L$FB2   ;# FDE initial location+	.word   L$FE2-L$FB2     ;# FDE address range+	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI21-L$FB2+	.byte   0x83    ;# DW_CFA_offset, column 0x3+	.uleb128 0x0+	.byte   0x11    ;# DW_CFA_offset_extended_sf+	.uleb128 0x2+	.sleb128 -5++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI22-L$CFI21+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3+	.uleb128 0x3++	.align 4+L$EFDE2:
+ src/pa/hpux64.S view
@@ -0,0 +1,681 @@+/* -----------------------------------------------------------------------+   hpux64.S - (c) 2005-2022 John David Anglin <dave.anglin@bell.net>++   HPUX PA 64-Bit 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 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>++	.LEVEL 2.0w+	.text+	.align	4++	/* void ffi_call_pa64(void (*)(char *, extended_cif *),+			       extended_cif *ecif,+			       unsigned bytes,+			       unsigned flags,+			       unsigned *rvalue,+			       void (*fn)());+	 */++	.export	ffi_call_pa64,code+	.import	ffi_prep_args_pa64,code++	.align	4++L$FB1+ffi_call_pa64+	.proc+	.callinfo	FRAME=48,CALLS,SAVE_RP,ENTRY_GR=4+	.entry+	std	%rp, -16(%sp)+	copy	%r3, %r1+L$CFI11+	copy	%sp, %r3+L$CFI12+	std,ma	%r1, 48(%sp)++	/* Setup the stack for calling prep_args...+	   We want the stack to look like this:++	   [ Previous stack                            ] <- %r3++	   [ 48-byte register save area                ]++	   [ Stack space for call arguments            ] <- %r4++	   [ 16-byte rame marker                       ]++	   [ 128-byte stack for calling prep_args      ] <- %sp+	 */++	std	%r4, 8(%r3)		; save r4+L$CFI13+	std	%r23, 16(%r3)		; save flags we need it later+	std	%r22, 24(%r3)		; save rvalue+	std	%r21, 32(%r3)		; save fn pointer++	copy	%sp, %r4+	copy	%r4, %r26		; argument stack pointer+	addl	%r24, %sp, %sp		; allocate argument space++	ldo	112(%sp), %r29		; arg pointer for prep args++	/* Call prep_args:+	   %arg0(stack) -- set up above to point to call arguments+	   %arg1(ecif) -- same as incoming param+	   %arg2(bytes) -- same as incoming param */+	bl	ffi_prep_args_pa64,%r2+	ldo	128(%sp), %sp+	ldo	-128(%sp), %sp++	/* Load the arguments that should be passed in registers+	   The fp args were loaded by the prep_args function.  */+	ldd	0(%r4), %r26+	ldd	8(%r4), %r25+	ldd	16(%r4), %r24+	ldd	24(%r4), %r23+	ldd     32(%r4), %r22+	ldd     40(%r4), %r21+	ldd     48(%r4), %r20+	ldd     56(%r4), %r19++	ldd	24(%r3), %ret0		; %ret0 <- rvalue++	ldd	32(%r3), %r1		; %r1 <- function pointer+	ldd	16(%r1), %rp		; fn address+	ldd	24(%r1), %dp		; New gp+	bve,l	(%rp), %r2		; Call the user function+	ldo	64(%r4), %r29		; Argument pointer++	/* Prepare to store the result; recover flags and rvalue.  */+	ldd	16(%r3), %r21		; r21 <- flags+	extrd,s	%r21, 63, 32, %r21	; sign extend flags for blr++	/* Adjust flags range from [-16, 15] to  [0, 31].  */+	addi	16, %r21, %r21++	blr	%r21, %r0+	ldd	24(%r3), %r20		; r20 <- rvalue++	/* Giant jump table */+	/* 16-byte small struct */+	b,n	L$smst16+	nop+	/* 15-byte small struct */+	b,n	L$smst15+	nop+	/* 14-byte small struct */+	b,n	L$smst14+	nop+	/* 13-byte small struct */+	b,n	L$smst13+	nop+	/* 12-byte small struct */+	b,n	L$smst12+	nop+	/* 11-byte small struct */+	b,n	L$smst11+	nop+	/* 10-byte small struct */+	b,n	L$smst10+	nop+	/* 9-byte small struct */+	b,n	L$smst9+	nop+	/* 8-byte small struct */+	b,n	L$smst8+	nop+	/* 7-byte small struct */+	b,n	L$smst7+	nop+	/* 6-byte small struct */+	b,n	L$smst6+	nop+	/* 5-byte small struct */+	b,n	L$smst5+	nop+	/* 4-byte small struct */+	b,n	L$smst4+	nop+	/* 3-byte small struct */+	b,n	L$smst3+	nop+	/* 2-byte small struct */+	b,n	L$smst2+	nop+	/* 1-byte small struct */+	b,n	L$smst1+	nop+	/* void */+	b,n	L$done+	nop+	/* int */+	b	L$done+	std	%ret0, 0(%r20)+	/* float */+	b	L$done+	fstw	%fr4R, 0(%r20)+	/* double */+	b	L$done+	fstd	%fr4, 0(%r20)+	/* long double */+	b,n	L$longdouble+	nop+	/* unsigned int8 */+	b	L$done+	std	%ret0, 0(%r20)+	/* signed int8 */+	b	L$done+	std	%ret0, 0(%r20)+	/* unsigned int16 */+	b	L$done+	std	%ret0, 0(%r20)+	/* signed int16 */+	b	L$done+	std	%ret0, 0(%r20)+	/* unsigned int32 */+	b	L$done+	std	%ret0, 0(%r20)+	/* signed int32 */+	b	L$done+	std	%ret0, 0(%r20)+	/* unsigned int64 */+	b	L$done+	std	%ret0, 0(%r20)+	/* signed int64 */+	b	L$done+	std	%ret0, 0(%r20)+	/* large struct */+	b,n	L$done+	nop+	/* pointer */+	b	L$done+	std	%ret0, 0(%r20)+	/* complex */+	b,n	L$done+	nop++L$longdouble+	std	%ret0, 0(%r20)+	b	L$done+	std	%ret1, 8(%r20)++	/* We need to copy byte-by-byte the exact number bytes+	   in the struct to avoid clobbering other data.  */+L$smst1+	extrd,u	%ret0, 7, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst2+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst3+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst4+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst5+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst6+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst7+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst8+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	b	L$done+	stb	%ret0, 0(%r20)++L$smst9+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst10+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst11+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 23, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst12+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 31, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst13+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 39, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst14+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 47, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst15+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 55, 8, %r22+	b	L$done+	stb	%r22, 0(%r20)++L$smst16+	extrd,u	%ret0, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret0, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb,ma	%ret0, 1(%r20)+	extrd,u	%ret1, 7, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 15, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 23, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 31, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 39, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 47, 8, %r22+	stb,ma	%r22, 1(%r20)+	extrd,u	%ret1, 55, 8, %r22+	stb,ma	%r22, 1(%r20)+	stb	%ret1, 0(%r20)++L$done+	/* all done, restore registers and return */+	copy	%r4, %sp+	ldd	8(%r3), %r4+	ldd	-16(%r3), %rp+	bve	(%rp)+	ldd,mb	-48(%sp), %r3+	.exit+	.procend+L$FE1+	.size	ffi_call_pa64, .-ffi_call_pa64++	/* void ffi_closure_pa64(void);+	   Called with closure argument in %r21 */++	.export ffi_closure_pa64,code+	.import ffi_closure_inner_pa64,code+	.align 4+L$FB2+ffi_closure_pa64+	.proc+	.callinfo FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3+	.entry++	std	%rp, -16(%sp)+	copy	%r3, %r1+L$CFI21+	copy	%sp, %r3+L$CFI22+	std,ma	%r1, 128(%sp)+L$CFI23++	/* Put arguments onto the stack and call ffi_closure_inner.  */+	std	%r26, -64(%r29)+	std	%r25, -56(%r29)+	std	%r24, -48(%r29)+	std	%r23, -40(%r29)+	std	%r22, -32(%r29)+	std	%r21, -24(%r29)+	std	%r20, -16(%r29)+	std	%r19, -8(%r29)++	/* Load and save start of argument stack.  */+	ldo	-64(%r29), %r25+	std	%r25, 8(%r3)++	/* Setup arg pointer.  */+	ldo	-16(%sp), %ret1++	/* Retrieve closure pointer and real gp.  */+	copy	%dp, %r26+	bl	ffi_closure_inner_pa64, %r2+	ldd	0(%dp), %dp++	/* Retrieve start of argument stack.  */+	ldd	8(%r3), %r1++	/* Restore r3 and op stack.  */+	ldd,mb	-128(%sp), %r3++	/* Load return address.  */+	ldd	-16(%sp), %rp++	/* Load return values from first and second stack slots.  */+	ldd	0(%r1), %ret0+	bve	(%rp)+	ldd	8(%r1), %ret1++	.exit+	.procend+	.end+L$FE2:+	.size	ffi_closure_pa64, .-ffi_closure_pa64++	.section	.eh_frame,"aw",@progbits+L$frame1:+	.word   L$ECIE1-L$SCIE1 ;# Length of Common Information Entry+L$SCIE1:+	.word   0x0     ;# CIE Identifier Tag+	.byte   0x3     ;# CIE Version+	.stringz ""     ;# CIE Augmentation+	.uleb128 0x1    ;# CIE Code Alignment Factor+	.sleb128 8      ;# CIE Data Alignment Factor+	.byte   0x2     ;# CIE RA Column+	.byte   0xc     ;# DW_CFA_def_cfa+	.uleb128 0x1e+	.uleb128 0x0+	.align 8+L$ECIE1:+L$SFDE1:+	.word   L$EFDE1-L$ASFDE1        ;# FDE Length+L$ASFDE1:+	.word   L$ASFDE1-L$frame1       ;# FDE CIE offset+	.dword  L$FB1	;# FDE initial location+	.dword  L$FE1-L$FB1	;# FDE address range++	.byte   0x4	;# DW_CFA_advance_loc4+	.word   L$CFI11-L$FB1+	.byte	0x9	;# DW_CFA_register: r3 in r1+	.uleb128 0x3+	.uleb128 0x1+	.byte   0x11    ;# DW_CFA_offset_extended_sf: r2 at cfa-16+	.uleb128 0x2+	.sleb128 -2+	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI12-L$CFI11+	.byte   0xd     ;# DW_CFA_def_cfa_register: r3+	.uleb128 0x3++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI13-L$CFI12+	.byte	0x83	;# DW_CFA_offset: r3 at cfa+0+	.uleb128 0+	.byte	0x84	;# DW_CFA_offset: r4 at cfa+8+	.uleb128 1++	.align 8+L$EFDE1:++L$SFDE2:+	.word   L$EFDE2-L$ASFDE2        ;# FDE Length+L$ASFDE2:+	.word   L$ASFDE2-L$frame1       ;# FDE CIE offset+	.dword   L$FB2	;# FDE initial location+	.dword   L$FE2-L$FB2     ;# FDE address range+	.byte   0x4	;# DW_CFA_advance_loc4+	.word   L$CFI21-L$FB2+	.byte   0x9	;# DW_CFA_register: r3 in r1+	.uleb128 0x3+	.uleb128 0x1+	.byte   0x11    ;# DW_CFA_offset_extended_sf: r2 at cfa-16+	.uleb128 0x2+	.sleb128 -2++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI22-L$CFI21+	.byte   0xd     ;# DW_CFA_def_cfa_register: r3+	.uleb128 0x3++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   L$CFI23-L$CFI22+	.byte	0x83	;# DW_CFA_offset: r3 at cfa+0+	.uleb128 0++	.align 8+L$EFDE2:
+ src/pa/linux.S view
@@ -0,0 +1,431 @@+/* -----------------------------------------------------------------------+   linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>+	     (c) 2008 Red Hat, Inc.++   HPPA 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 RENESAS TECHNOLOGY 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>++	.text+	.level 1.1+	.align 4++	/* void ffi_call_pa32(void (*)(char *, extended_cif *),+			       extended_cif *ecif,+			       unsigned bytes,+			       unsigned flags,+			       unsigned *rvalue,+			       void (*fn)(void));+	 */++	.export ffi_call_pa32,code+	.import ffi_prep_args_pa32,code++	.type ffi_call_pa32, @function+.LFB1:+ffi_call_pa32:+	.proc+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4+	.entry+	stw %rp, -20(%sp)+	copy %r3, %r1+.LCFI11:++	copy %sp, %r3+.LCFI12:++	/* Setup the stack for calling prep_args...+	   We want the stack to look like this:++	   [ Previous stack                            ] <- %r3++	   [ 64-bytes register save area               ] <- %r4++	   [ Stack space for actual call, passed as    ] <- %arg0+	   [     arg0 to ffi_prep_args_pa32           ]++	   [ Stack for calling prep_args               ] <- %sp+	 */++	stwm %r1, 64(%sp)+	stw %r4, 12(%r3)+.LCFI13:+	copy %sp, %r4++	addl %arg2, %r4, %arg0      /* arg stack */+	stw %arg3, -48(%r3)         /* save flags; we need it later */++	/* Call prep_args:+	   %arg0(stack) -- set up above+	   %arg1(ecif) -- same as incoming param+	   %arg2(bytes) -- same as incoming param */+	bl ffi_prep_args_pa32,%r2+	ldo 64(%arg0), %sp+	ldo -64(%sp), %sp++	/* now %sp should point where %arg0 was pointing.  */++	/* Load the arguments that should be passed in registers+	   The fp args were loaded by the prep_args function.  */+	ldw -36(%sp), %arg0+	ldw -40(%sp), %arg1+	ldw -44(%sp), %arg2+	ldw -48(%sp), %arg3++	/* in case the function is going to return a structure+	   we need to give it a place to put the result.  */+	ldw -52(%r3), %ret0                     /* %ret0 <- rvalue */+	ldw -56(%r3), %r22                      /* %r22 <- function to call */+	bl $$dyncall, %r31                      /* Call the user function */+	copy %r31, %rp++	/* Prepare to store the result; we need to recover flags and rvalue.  */+	ldw -48(%r3), %r21                      /* r21 <- flags */++	/* Adjust flags range from [-8, 15] to  [0, 23].  */+	addi 8, %r21, %r21++	blr %r21, %r0+	ldw -52(%r3), %r20                      /* r20 <- rvalue */++	/* Giant jump table */+	/* 8-byte small struct */+	b,n	.Lsmst8+	nop+	/* 7-byte small struct */+	b,n	.Lsmst7+	nop+	/* 6-byte small struct */+	b,n	.Lsmst6+	nop+	/* 5-byte small struct */+	b,n	.Lsmst5+	nop+	/* 4-byte small struct */+	b,n	.Lsmst4+	nop+	/* 3-byte small struct */+	b,n	.Lsmst3+	nop+	/* 2-byte small struct */+	b,n	.Lsmst2+	nop+	/* 1-byte small struct */+	b	.Ldone+	stb	%ret0, 0(%r20)+	/* void */+	b,n	.Ldone+	nop+	/* int */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* float */+	b	.Ldone+	fstw	%fr4L,0(%r20)+	/* double */+	b	.Ldone+	fstd	%fr4,0(%r20)+	/* long double */+	b	.Ldone+	fstd	%fr4,0(%r20)+	/* unsigned int8 */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* sint8 */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* unsigned int16 */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* sint16 */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* unsigned int32 */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* sint32 */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* unsigned int64 */+	b,n	.Luint64+	nop+	/* signed int64 */+	b,n	.Lsint64+	nop+	/* large struct */+	b,n	.Ldone+	nop+	/* pointer */+	b	.Ldone+	stw	%ret0, 0(%r20)+	/* complex */+	b,n	.Ldone+	nop++	/* Store the result according to the return type.  */++.Luint64:+.Lsint64:+	stw	%ret0, 0(%r20)+	b	.Ldone+	stw	%ret1, 4(%r20)++.Lsmst2:+	/* 2-byte structs are returned in ret0 as ????xxyy.  */+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	.Ldone+	stb	%ret0, 0(%r20)++.Lsmst3:+	/* 3-byte structs are returned in ret0 as ??xxyyzz.  */+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	.Ldone+	stb	%ret0, 0(%r20)++.Lsmst4:+	/* 4-byte structs are returned in ret0 as wwxxyyzz.  */+	extru	%ret0, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	.Ldone+	stb	%ret0, 0(%r20)++.Lsmst5:+	/* 5 byte values are returned right justified:+	      ret0     ret1+	   5: ??????aa bbccddee */+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	.Ldone+	stb	%ret1, 0(%r20)++.Lsmst6:+	/* 6 byte values are returned right justified:+	      ret0     ret1+	   6: ????aabb ccddeeff */+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	.Ldone+	stb	%ret1, 0(%r20)++.Lsmst7:+	/* 7 byte values are returned right justified:+	      ret0     ret1+	   7: ??aabbcc ddeeffgg */+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	b	.Ldone+	stb	%ret1, 0(%r20)++.Lsmst8:+	/* 8 byte values are returned right justified:+	      ret0     ret1+	   8: aabbccdd eeffgghh */+	extru	%ret0, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret0, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stbs,ma	%ret0, 1(%r20)+	extru	%ret1, 7, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 15, 8, %r22+	stbs,ma	%r22, 1(%r20)+	extru	%ret1, 23, 8, %r22+	stbs,ma	%r22, 1(%r20)+	stb	%ret1, 0(%r20)++.Ldone:+	/* all done, return */+	copy %r4, %sp                           /* pop arg stack */+	ldw 12(%r3), %r4+	ldwm -64(%sp), %r3                      /* .. and pop stack */+	ldw -20(%sp), %rp+	bv %r0(%rp)+	nop+	.exit+	.procend+.LFE1:++	/* void ffi_closure_pa32(void);+	   Called with closure argument in %r19 */+	.export ffi_closure_pa32,code+	.import ffi_closure_inner_pa32,code++	.type ffi_closure_pa32, @function+.LFB2:+ffi_closure_pa32:+	.proc+	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3+	.entry++	stw %rp, -20(%sp)+.LCFI20:+	copy %r3, %r1+.LCFI21:+	copy %sp, %r3+.LCFI22:+	stwm %r1, 64(%sp)++	/* Put arguments onto the stack and call ffi_closure_inner.  */+	stw %arg0, -36(%r3)+	stw %arg1, -40(%r3)+	stw %arg2, -44(%r3)+	stw %arg3, -48(%r3)++	/* Retrieve closure pointer and real gp.  */+	copy    %r19, %arg0+	ldw     8(%r19), %r19+	bl ffi_closure_inner_pa32, %r2+	copy %r3, %arg1++	ldwm -64(%sp), %r3+	ldw -20(%sp), %rp+	ldw -36(%sp), %ret0+	bv %r0(%r2)+	ldw -40(%sp), %ret1++	.exit+	.procend+.LFE2:++	.section        ".eh_frame",EH_FRAME_FLAGS,@progbits+.Lframe1:+	.word   .LECIE1-.LSCIE1 ;# Length of Common Information Entry+.LSCIE1:+	.word   0x0     ;# CIE Identifier Tag+	.byte   0x1     ;# CIE Version+#ifdef __PIC__+	.ascii  "zR\0"  ;# CIE Augmentation: 'z' - data, 'R' - DW_EH_PE_... data+#else+	.ascii "\0"     ;# CIE Augmentation+#endif+	.uleb128 0x1    ;# CIE Code Alignment Factor+	.sleb128 4      ;# CIE Data Alignment Factor+	.byte   0x2     ;# CIE RA Column+#ifdef __PIC__+	.uleb128 0x1    ;# Augmentation size+	.byte	0x1b    ;# FDE Encoding (DW_EH_PE_pcrel|DW_EH_PE_sdata4)+#endif+	.byte   0xc     ;# DW_CFA_def_cfa+	.uleb128 0x1e+	.uleb128 0x0+	.align 4+.LECIE1:+.LSFDE1:+	.word   .LEFDE1-.LASFDE1        ;# FDE Length+.LASFDE1:+	.word   .LASFDE1-.Lframe1       ;# FDE CIE offset+#ifdef __PIC__+	.word	.LFB1-. ;# FDE initial location+#else+	.word	.LFB1   ;# FDE initial location+#endif+	.word   .LFE1-.LFB1     ;# FDE address range+#ifdef __PIC__+	.uleb128 0x0	;# Augmentation size: no data+#endif+	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   .LCFI11-.LFB1+	.byte	0x83	;# DW_CFA_offset, column 0x3+	.uleb128 0x0+	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]+	.uleb128 0x2+	.sleb128 -5++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   .LCFI12-.LCFI11+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3+	.uleb128 0x3++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   .LCFI13-.LCFI12+	.byte	0x84	;# DW_CFA_offset, column 0x4+	.uleb128 0x3++	.align 4+.LEFDE1:++.LSFDE2:+	.word   .LEFDE2-.LASFDE2        ;# FDE Length+.LASFDE2:+	.word   .LASFDE2-.Lframe1       ;# FDE CIE offset+#ifdef __PIC__+	.word   .LFB2-. ;# FDE initial location+#else+	.word   .LFB2   ;# FDE initial location+#endif+	.word   .LFE2-.LFB2     ;# FDE address range+#ifdef __PIC__+	.uleb128 0x0	;# Augmentation size: no data+#endif+	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   .LCFI21-.LFB2+	.byte   0x83    ;# DW_CFA_offset, column 0x3+	.uleb128 0x0+	.byte   0x11    ;# DW_CFA_offset_extended_sf+	.uleb128 0x2+	.sleb128 -5++	.byte   0x4     ;# DW_CFA_advance_loc4+	.word   .LCFI22-.LCFI21+	.byte   0xd     ;# DW_CFA_def_cfa_register = r3+	.uleb128 0x3++	.align 4+.LEFDE2:++#if defined(__ELF__) && defined(__linux__)+.section .note.GNU-stack,"",%progbits+#endif
+ src/powerpc/aix.S view
@@ -0,0 +1,566 @@+/* -----------------------------------------------------------------------+   aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.+   based on darwin.S by John Hornkvist++   PowerPC 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.+   ----------------------------------------------------------------------- */++	.set r0,0+	.set r1,1+	.set r2,2+	.set r3,3+	.set r4,4+	.set r5,5+	.set r6,6+	.set r7,7+	.set r8,8+	.set r9,9+	.set r10,10+	.set r11,11+	.set r12,12+	.set r13,13+	.set r14,14+	.set r15,15+	.set r16,16+	.set r17,17+	.set r18,18+	.set r19,19+	.set r20,20+	.set r21,21+	.set r22,22+	.set r23,23+	.set r24,24+	.set r25,25+	.set r26,26+	.set r27,27+	.set r28,28+	.set r29,29+	.set r30,30+	.set r31,31+	.set f0,0+	.set f1,1+	.set f2,2+	.set f3,3+	.set f4,4+	.set f5,5+	.set f6,6+	.set f7,7+	.set f8,8+	.set f9,9+	.set f10,10+	.set f11,11+	.set f12,12+	.set f13,13+	.set f14,14+	.set f15,15+	.set f16,16+	.set f17,17+	.set f18,18+	.set f19,19+	.set f20,20+	.set f21,21++	.extern .ffi_prep_args++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#define JUMPTARGET(name) name+#define L(x) x+	.file "aix.S"+	.toc++	/* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,+	 *		     unsigned int flags, unsigned int *rvalue,+	 *		     void (*fn)(),+	 *		     void (*prep_args)(extended_cif*, unsigned *const));+	 * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args+	 */++.csect .text[PR]+	.align 2+	.globl ffi_call_AIX+	.globl .ffi_call_AIX+.csect ffi_call_AIX[DS]+ffi_call_AIX:+#ifdef __64BIT__+	.llong .ffi_call_AIX, TOC[tc0], 0+	.csect .text[PR]+.ffi_call_AIX:+	.function .ffi_call_AIX,.ffi_call_AIX,16,044,LFE..0-LFB..0+	.bf __LINE__+	.line 1+LFB..0:+	/* Save registers we use.  */+	mflr	r0++	std	r28,-32(r1)+	std	r29,-24(r1)+	std	r30,-16(r1)+	std	r31, -8(r1)++	std	r0, 16(r1)+LCFI..0:+	mr	r28, r1		/* our AP.  */+	stdux	r1, r1, r4+LCFI..1:++	/* Save arguments over call...  */+	mr	r31, r5	/* flags, */+	mr	r30, r6	/* rvalue, */+	mr	r29, r7	/* function address.  */+	std	r2, 40(r1)++	/* Call ffi_prep_args.  */+	mr	r4, r1+	bl	.ffi_prep_args+	nop++	/* Now do the call.  */+	ld	r0, 0(r29)+	ld	r2, 8(r29)+	ld	r11, 16(r29)+	/* Set up cr1 with bits 4-7 of the flags.  */+	mtcrf	0x40, r31+	mtctr	r0+	/* Load all those argument registers.  */+	/* We have set up a nice stack frame, just load it into registers. */+	ld	r3, 40+(1*8)(r1)+	ld	r4, 40+(2*8)(r1)+	ld	r5, 40+(3*8)(r1)+	ld	r6, 40+(4*8)(r1)+	nop+	ld	r7, 40+(5*8)(r1)+	ld	r8, 40+(6*8)(r1)+	ld	r9, 40+(7*8)(r1)+	ld	r10,40+(8*8)(r1)++L1:+	/* Load all the FP registers.  */+	bf	6,L2 /* 2f + 0x18 */+	lfd	f1,-32-(13*8)(r28)+	lfd	f2,-32-(12*8)(r28)+	lfd	f3,-32-(11*8)(r28)+	lfd	f4,-32-(10*8)(r28)+	nop+	lfd	f5,-32-(9*8)(r28)+	lfd	f6,-32-(8*8)(r28)+	lfd	f7,-32-(7*8)(r28)+	lfd	f8,-32-(6*8)(r28)+	nop+	lfd	f9,-32-(5*8)(r28)+	lfd	f10,-32-(4*8)(r28)+	lfd	f11,-32-(3*8)(r28)+	lfd	f12,-32-(2*8)(r28)+	nop+	lfd	f13,-32-(1*8)(r28)++L2:+	/* Make the call.  */+	bctrl+	ld	r2, 40(r1)++	/* Now, deal with the return value.  */+	mtcrf	0x01, r31++	bt	30, L(done_return_value)+	bt	29, L(fp_return_value)+	std	r3, 0(r30)++	/* Fall through...  */++L(done_return_value):+	/* Restore the registers we used and return.  */+	mr	r1, r28+	ld	r0, 16(r28)+	ld	r28, -32(r1)+	mtlr	r0+	ld	r29, -24(r1)+	ld	r30, -16(r1)+	ld	r31, -8(r1)+	blr++L(fp_return_value):+	bf	28, L(float_return_value)+	stfd	f1, 0(r30)+	bf	31, L(done_return_value)+	stfd	f2, 8(r30)+	b	L(done_return_value)+L(float_return_value):+	stfs	f1, 0(r30)+	b	L(done_return_value)+LFE..0:+#else /* ! __64BIT__ */+	+	.long .ffi_call_AIX, TOC[tc0], 0+	.csect .text[PR]+.ffi_call_AIX:+	.function .ffi_call_AIX,.ffi_call_AIX,16,044,LFE..0-LFB..0+	.bf __LINE__+	.line 1+LFB..0:+	/* Save registers we use.  */+	mflr	r0++	stw	r28,-16(r1)+	stw	r29,-12(r1)+	stw	r30, -8(r1)+	stw	r31, -4(r1)++	stw	r0, 8(r1)+LCFI..0:+	mr	r28, r1		/* out AP.  */+	stwux	r1, r1, r4+LCFI..1:++	/* Save arguments over call...  */+	mr	r31, r5	/* flags, */+	mr	r30, r6	/* rvalue, */+	mr	r29, r7	/* function address, */+	stw	r2, 20(r1)++	/* Call ffi_prep_args.  */+	mr	r4, r1+	bl	.ffi_prep_args+	nop++	/* Now do the call.  */+	lwz	r0, 0(r29)+	lwz	r2, 4(r29)+	lwz	r11, 8(r29)+	/* Set up cr1 with bits 4-7 of the flags.  */+	mtcrf	0x40, r31+	mtctr	r0+	/* Load all those argument registers.  */+	/* We have set up a nice stack frame, just load it into registers. */+	lwz	r3, 20+(1*4)(r1)+	lwz	r4, 20+(2*4)(r1)+	lwz	r5, 20+(3*4)(r1)+	lwz	r6, 20+(4*4)(r1)+	nop+	lwz	r7, 20+(5*4)(r1)+	lwz	r8, 20+(6*4)(r1)+	lwz	r9, 20+(7*4)(r1)+	lwz	r10,20+(8*4)(r1)++L1:+	/* Load all the FP registers.  */+	bf	6,L2 /* 2f + 0x18 */+	lfd	f1,-16-(13*8)(r28)+	lfd	f2,-16-(12*8)(r28)+	lfd	f3,-16-(11*8)(r28)+	lfd	f4,-16-(10*8)(r28)+	nop+	lfd	f5,-16-(9*8)(r28)+	lfd	f6,-16-(8*8)(r28)+	lfd	f7,-16-(7*8)(r28)+	lfd	f8,-16-(6*8)(r28)+	nop+	lfd	f9,-16-(5*8)(r28)+	lfd	f10,-16-(4*8)(r28)+	lfd	f11,-16-(3*8)(r28)+	lfd	f12,-16-(2*8)(r28)+	nop+	lfd	f13,-16-(1*8)(r28)++L2:+	/* Make the call.  */+	bctrl+	lwz	r2, 20(r1)++	/* Now, deal with the return value.  */+	mtcrf	0x01, r31++	bt	30, L(done_return_value)+	bt	29, L(fp_return_value)+	stw	r3, 0(r30)+	bf	28, L(done_return_value)+	stw	r4, 4(r30)++	/* Fall through...  */++L(done_return_value):+	/* Restore the registers we used and return.  */+	mr	r1, r28+	lwz	r0, 8(r28)+	lwz	r28,-16(r1)+	mtlr	r0+	lwz	r29,-12(r1)+	lwz	r30, -8(r1)+	lwz	r31, -4(r1)+	blr++L(fp_return_value):+	bf	28, L(float_return_value)+	stfd	f1, 0(r30)+	b	L(done_return_value)+L(float_return_value):+	stfs	f1, 0(r30)+	b	L(done_return_value)+LFE..0:+#endif+	.ef __LINE__+	.long 0+	.byte 0,0,0,1,128,4,0,0+/* END(ffi_call_AIX) */++	/* void ffi_call_go_AIX(extended_cif *ecif, unsigned long bytes,+	 *		        unsigned int flags, unsigned int *rvalue,+	 *		        void (*fn)(),+	 *		        void (*prep_args)(extended_cif*, unsigned *const),+	 *                      void *closure);+	 * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args, r9=closure+	 */++.csect .text[PR]+	.align 2+	.globl ffi_call_go_AIX+	.globl .ffi_call_go_AIX+.csect ffi_call_go_AIX[DS]+ffi_call_go_AIX:+#ifdef __64BIT__+	.llong .ffi_call_go_AIX, TOC[tc0], 0+	.csect .text[PR]+.ffi_call_go_AIX:+	.function .ffi_call_go_AIX,.ffi_call_go_AIX,16,044,LFE..1-LFB..1+	.bf __LINE__+	.line 1+LFB..1:+	/* Save registers we use.  */+	mflr	r0++	std	r28,-32(r1)+	std	r29,-24(r1)+	std	r30,-16(r1)+	std	r31, -8(r1)++	std	r9, 8(r1)	/* closure, saved in cr field. */+	std	r0, 16(r1)+LCFI..2:+	mr	r28, r1		/* our AP.  */+	stdux	r1, r1, r4+LCFI..3:++	/* Save arguments over call...  */+	mr	r31, r5	/* flags, */+	mr	r30, r6	/* rvalue, */+	mr	r29, r7	/* function address,  */+	std	r2, 40(r1)++	/* Call ffi_prep_args.  */+	mr	r4, r1+	bl	.ffi_prep_args+	nop++	/* Now do the call.  */+	ld	r0, 0(r29)+	ld	r2, 8(r29)+	ld      r11, 8(r28)	/* closure */+	/* Set up cr1 with bits 4-7 of the flags.  */+	mtcrf	0x40, r31+	mtctr	r0+	/* Load all those argument registers.  */+	/* We have set up a nice stack frame, just load it into registers. */+	ld	r3, 40+(1*8)(r1)+	ld	r4, 40+(2*8)(r1)+	ld	r5, 40+(3*8)(r1)+	ld	r6, 40+(4*8)(r1)+	nop+	ld	r7, 40+(5*8)(r1)+	ld	r8, 40+(6*8)(r1)+	ld	r9, 40+(7*8)(r1)+	ld	r10,40+(8*8)(r1)++	b	L1+LFE..1:+#else /* ! __64BIT__ */+	+	.long .ffi_call_go_AIX, TOC[tc0], 0+	.csect .text[PR]+.ffi_call_go_AIX:+	.function .ffi_call_go_AIX,.ffi_call_go_AIX,16,044,LFE..1-LFB..1+	.bf __LINE__+	.line 1+	/* Save registers we use.  */+LFB..1:+	mflr	r0++	stw	r28,-16(r1)+	stw	r29,-12(r1)+	stw	r30, -8(r1)+	stw	r31, -4(r1)++	stw	r9, 4(r1)	/* closure, saved in cr field.  */+	stw	r0, 8(r1)+LCFI..2:+	mr	r28, r1		/* out AP.  */+	stwux	r1, r1, r4+LCFI..3:++	/* Save arguments over call...  */+	mr	r31, r5	/* flags, */+	mr	r30, r6	/* rvalue, */+	mr	r29, r7	/* function address, */+	stw	r2, 20(r1)++	/* Call ffi_prep_args.  */+	mr	r4, r1+	bl	.ffi_prep_args+	nop++	/* Now do the call.  */+	lwz	r0, 0(r29)+	lwz	r2, 4(r29)+	lwz	r11, 4(r28)	/* closure */+	/* Set up cr1 with bits 4-7 of the flags.  */+	mtcrf	0x40, r31+	mtctr	r0+	/* Load all those argument registers.  */+	/* We have set up a nice stack frame, just load it into registers. */+	lwz	r3, 20+(1*4)(r1)+	lwz	r4, 20+(2*4)(r1)+	lwz	r5, 20+(3*4)(r1)+	lwz	r6, 20+(4*4)(r1)+	nop+	lwz	r7, 20+(5*4)(r1)+	lwz	r8, 20+(6*4)(r1)+	lwz	r9, 20+(7*4)(r1)+	lwz	r10,20+(8*4)(r1)++	b	L1+LFE..1:+#endif+	.ef __LINE__+	.long 0+	.byte 0,0,0,1,128,4,0,0+/* END(ffi_call_go_AIX) */++.csect .text[PR]+	.align 2+	.globl ffi_call_DARWIN+	.globl .ffi_call_DARWIN+.csect ffi_call_DARWIN[DS]+ffi_call_DARWIN:+#ifdef __64BIT__+	.llong .ffi_call_DARWIN, TOC[tc0], 0+#else+	.long .ffi_call_DARWIN, TOC[tc0], 0+#endif+	.csect .text[PR]+.ffi_call_DARWIN:+	blr+	.long 0+	.byte 0,0,0,0,0,0,0,0+/* END(ffi_call_DARWIN) */++/* EH frame stuff.  */++#define LR_REGNO		0x41		/* Link Register (65), see rs6000.md */+#ifdef __64BIT__+#define PTRSIZE			8+#define LOG2_PTRSIZE		3+#define FDE_ENCODING		0x1c		/* DW_EH_PE_pcrel|DW_EH_PE_sdata8 */+#define EH_DATA_ALIGN_FACT	0x78		/* LEB128 -8 */+#else+#define PTRSIZE			4+#define LOG2_PTRSIZE		2+#define FDE_ENCODING		0x1b		/* DW_EH_PE_pcrel|DW_EH_PE_sdata4 */+#define EH_DATA_ALIGN_FACT	0x7c		/* LEB128 -4 */+#endif+	.csect	_unwind.ro_[RO],4+	.align	LOG2_PTRSIZE+	.globl	_GLOBAL__F_libffi_src_powerpc_aix+_GLOBAL__F_libffi_src_powerpc_aix:+Lframe..1:+	.vbyte	4,LECIE..1-LSCIE..1	/* CIE Length */+LSCIE..1:+	.vbyte	4,0			/* CIE Identifier Tag */+	.byte	0x3			/* CIE Version */+	.byte	"zR"			/* CIE Augmentation */+	.byte	0+	.byte	0x1			/* uleb128 0x1; CIE Code Alignment Factor */+	.byte	EH_DATA_ALIGN_FACT	/* leb128 -4/-8; CIE Data Alignment Factor */+	.byte	0x41			/* CIE RA Column */+	.byte	0x1			/* uleb128 0x1; Augmentation size */+	.byte	FDE_ENCODING		/* FDE Encoding (pcrel|sdata4/8) */+	.byte	0xc			/* DW_CFA_def_cfa */+	.byte	0x1			/*     uleb128 0x1; Register r1 */+	.byte	0			/*     uleb128 0x0; Offset 0 */+	.align	LOG2_PTRSIZE+LECIE..1:+LSFDE..1:+	.vbyte	4,LEFDE..1-LASFDE..1	/* FDE Length */+LASFDE..1:+	.vbyte	4,LASFDE..1-Lframe..1	/* FDE CIE offset */+	.vbyte	PTRSIZE,LFB..0-$	/* FDE initial location */+	.vbyte	PTRSIZE,LFE..0-LFB..0	/* FDE address range */+	.byte   0			/* uleb128 0x0; Augmentation size */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..0-LFB..0+	.byte	0x11			/* DW_CFA_def_offset_extended_sf */+	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */+	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */+	.byte	0x9f			/* DW_CFA_offset Register r31 */+	.byte	0x1			/*     uleb128 0x1; Offset 1 (-4/-8) */+	.byte	0x9e			/* DW_CFA_offset Register r30 */+	.byte	0x2			/*     uleb128 0x2; Offset 2 (-8/-16) */+	.byte	0x9d			/* DW_CFA_offset Register r29 */+	.byte	0x3			/*     uleb128 0x3; Offset 3 (-12/-24) */+	.byte	0x9c			/* DW_CFA_offset Register r28 */+	.byte	0x4			/*     uleb128 0x4; Offset 4 (-16/-32) */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..1-LCFI..0+	.byte	0xd			/* DW_CFA_def_cfa_register */+	.byte	0x1c			/*     uleb128 28; Register r28 */+	.align	LOG2_PTRSIZE+LEFDE..1:+LSFDE..2:+	.vbyte	4,LEFDE..2-LASFDE..2	/* FDE Length */+LASFDE..2:+	.vbyte	4,LASFDE..2-Lframe..1	/* FDE CIE offset */+	.vbyte	PTRSIZE,LFB..1-$	/* FDE initial location */+	.vbyte	PTRSIZE,LFE..1-LFB..1	/* FDE address range */+	.byte   0			/* uleb128 0x0; Augmentation size */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..2-LFB..1+	.byte	0x11			/* DW_CFA_def_offset_extended_sf */+	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */+	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */+	.byte	0x9f			/* DW_CFA_offset Register r31 */+	.byte	0x1			/*     uleb128 0x1; Offset 1 (-4/-8) */+	.byte	0x9e			/* DW_CFA_offset Register r30 */+	.byte	0x2			/*     uleb128 0x2; Offset 2 (-8/-16) */+	.byte	0x9d			/* DW_CFA_offset Register r29 */+	.byte	0x3			/*     uleb128 0x3; Offset 3 (-12/-24) */+	.byte	0x9c			/* DW_CFA_offset Register r28 */+	.byte	0x4			/*     uleb128 0x4; Offset 4 (-16/-32) */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..3-LCFI..2+	.byte	0xd			/* DW_CFA_def_cfa_register */+	.byte	0x1c			/*     uleb128 28; Register r28 */+	.align	LOG2_PTRSIZE+LEFDE..2:+	.vbyte	4,0			/* End of FDEs */++	.csect	.text[PR]+	.ref	_GLOBAL__F_libffi_src_powerpc_aix	/* Prevents garbage collection by AIX linker */+
+ src/powerpc/aix_closure.S view
@@ -0,0 +1,694 @@+/* -----------------------------------------------------------------------+   aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.+   based on darwin_closure.S++   PowerPC 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.+   ----------------------------------------------------------------------- */++	.set r0,0+	.set r1,1+	.set r2,2+	.set r3,3+	.set r4,4+	.set r5,5+	.set r6,6+	.set r7,7+	.set r8,8+	.set r9,9+	.set r10,10+	.set r11,11+	.set r12,12+	.set r13,13+	.set r14,14+	.set r15,15+	.set r16,16+	.set r17,17+	.set r18,18+	.set r19,19+	.set r20,20+	.set r21,21+	.set r22,22+	.set r23,23+	.set r24,24+	.set r25,25+	.set r26,26+	.set r27,27+	.set r28,28+	.set r29,29+	.set r30,30+	.set r31,31+	.set f0,0+	.set f1,1+	.set f2,2+	.set f3,3+	.set f4,4+	.set f5,5+	.set f6,6+	.set f7,7+	.set f8,8+	.set f9,9+	.set f10,10+	.set f11,11+	.set f12,12+	.set f13,13+	.set f14,14+	.set f15,15+	.set f16,16+	.set f17,17+	.set f18,18+	.set f19,19+	.set f20,20+	.set f21,21++	.extern .ffi_closure_helper_DARWIN+	.extern .ffi_go_closure_helper_DARWIN++#define LIBFFI_ASM+#define JUMPTARGET(name) name+#define L(x) x+	.file "aix_closure.S"+	.toc+LC..60:+	.tc L..60[TC],L..60+	.csect .text[PR]+	.align 2++.csect .text[PR]+	.align 2+	.globl ffi_closure_ASM+	.globl .ffi_closure_ASM+.csect ffi_closure_ASM[DS]+ffi_closure_ASM:+#ifdef __64BIT__+	.llong .ffi_closure_ASM, TOC[tc0], 0+	.csect .text[PR]+.ffi_closure_ASM:+	.function .ffi_closure_ASM,.ffi_closure_ASM,16,044,LFE..0-LFB..0+	.bf __LINE__+	.line 1+LFB..0:+/* we want to build up an area for the parameters passed */+/* in registers (both floating point and integer) */++	/* we store gpr 3 to gpr 10 (aligned to 4)+	in the parents outgoing area  */+	std   r3, 48+(0*8)(r1)+	std   r4, 48+(1*8)(r1)+	std   r5, 48+(2*8)(r1)+	std   r6, 48+(3*8)(r1)+	mflr  r0++	std   r7, 48+(4*8)(r1)+	std   r8, 48+(5*8)(r1)+	std   r9, 48+(6*8)(r1)+	std   r10, 48+(7*8)(r1)+	std   r0, 16(r1)	/* save the return address */+LCFI..0:+	/* 48  Bytes (Linkage Area) */+	/* 64  Bytes (params) */+	/* 16  Bytes (result) */+	/* 104 Bytes (13*8 from FPR) */+	/* 8   Bytes (alignment) */+	/* 240 Bytes */++	stdu  r1, -240(r1)	/* skip over caller save area+				   keep stack aligned to 16  */+LCFI..1:++	/* next save fpr 1 to fpr 13 (aligned to 8) */+	stfd  f1, 128+(0*8)(r1)+	stfd  f2, 128+(1*8)(r1)+	stfd  f3, 128+(2*8)(r1)+	stfd  f4, 128+(3*8)(r1)+	stfd  f5, 128+(4*8)(r1)+	stfd  f6, 128+(5*8)(r1)+	stfd  f7, 128+(6*8)(r1)+	stfd  f8, 128+(7*8)(r1)+	stfd  f9, 128+(8*8)(r1)+	stfd  f10, 128+(9*8)(r1)+	stfd  f11, 128+(10*8)(r1)+	stfd  f12, 128+(11*8)(r1)+	stfd  f13, 128+(12*8)(r1)++	/* set up registers for the routine that actually does the work */+	/* get the context pointer from the trampoline */+	mr r3, r11++	/* now load up the pointer to the result storage */+	addi r4, r1, 112++	/* now load up the pointer to the saved gpr registers */+	addi r5, r1, 288++	/* now load up the pointer to the saved fpr registers */+	addi r6, r1, 128++	/* make the call */+	bl .ffi_closure_helper_DARWIN+	nop++.Ldoneclosure:++	/* now r3 contains the return type */+	/* so use it to look up in a table */+	/* so we know how to deal with each type */++	/* look up the proper starting point in table  */+	/* by using return type as offset */+	lhz	r3, 10(r3)	/* load type from return type */+	ld	r4, LC..60(2)	/* get address of jump table */+	sldi	r3, r3, 4	/* now multiply return type by 16 */+	ld	r0, 240+16(r1)	/* load return address */+	add	r3, r3, r4	/* add contents of table to table address */+	mtctr	r3+	bctr			/* jump to it */++/* Each fragment must be exactly 16 bytes long (4 instructions).+   Align to 16 byte boundary for cache and dispatch efficiency.  */+	.align 4++L..60:+/* case FFI_TYPE_VOID */+	mtlr r0+	addi r1, r1, 240+	blr+	nop++/* case FFI_TYPE_INT */+	lwa r3, 112+4(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_FLOAT */+	lfs f1, 112+0(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_DOUBLE */+	lfd f1, 112+0(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_LONGDOUBLE */+	lfd f1, 112+0(r1)+	mtlr r0+	lfd f2, 112+8(r1)+	b L..finish++/* case FFI_TYPE_UINT8 */+	lbz r3, 112+7(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_SINT8 */+	lbz r3, 112+7(r1)+	mtlr r0+	extsb r3, r3+	b L..finish++/* case FFI_TYPE_UINT16 */+	lhz r3, 112+6(r1)+	mtlr r0+L..finish:+	addi r1, r1, 240+	blr++/* case FFI_TYPE_SINT16 */+	lha r3, 112+6(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_UINT32 */+	lwz r3, 112+4(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_SINT32 */+	lwa r3, 112+4(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_UINT64 */+	ld r3, 112+0(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_SINT64 */+	ld r3, 112+0(r1)+	mtlr r0+	addi r1, r1, 240+	blr++/* case FFI_TYPE_STRUCT */+	mtlr r0+	addi r1, r1, 240+	blr+	nop++/* case FFI_TYPE_POINTER */+	ld r3, 112+0(r1)+	mtlr r0+	addi r1, r1, 240+	blr+LFE..0:++#else /* ! __64BIT__ */+	+	.long .ffi_closure_ASM, TOC[tc0], 0+	.csect .text[PR]+.ffi_closure_ASM:+	.function .ffi_closure_ASM,.ffi_closure_ASM,16,044,LFE..0-LFB..0+	.bf __LINE__+	.line 1+LFB..0:+/* we want to build up an area for the parameters passed */+/* in registers (both floating point and integer) */++	/* we store gpr 3 to gpr 10 (aligned to 4)+	in the parents outgoing area  */+	stw   r3, 24+(0*4)(r1)+	stw   r4, 24+(1*4)(r1)+	stw   r5, 24+(2*4)(r1)+	stw   r6, 24+(3*4)(r1)+	mflr  r0++	stw   r7, 24+(4*4)(r1)+	stw   r8, 24+(5*4)(r1)+	stw   r9, 24+(6*4)(r1)+	stw   r10, 24+(7*4)(r1)+	stw   r0, 8(r1)+LCFI..0:+	/* 24 Bytes (Linkage Area) */+	/* 32 Bytes (params) */+	/* 16  Bytes (result) */+	/* 104 Bytes (13*8 from FPR) */+	/* 176 Bytes */++	stwu  r1, -176(r1)	/* skip over caller save area+				   keep stack aligned to 16  */+LCFI..1:++	/* next save fpr 1 to fpr 13 (aligned to 8) */+	stfd  f1, 72+(0*8)(r1)+	stfd  f2, 72+(1*8)(r1)+	stfd  f3, 72+(2*8)(r1)+	stfd  f4, 72+(3*8)(r1)+	stfd  f5, 72+(4*8)(r1)+	stfd  f6, 72+(5*8)(r1)+	stfd  f7, 72+(6*8)(r1)+	stfd  f8, 72+(7*8)(r1)+	stfd  f9, 72+(8*8)(r1)+	stfd  f10, 72+(9*8)(r1)+	stfd  f11, 72+(10*8)(r1)+	stfd  f12, 72+(11*8)(r1)+	stfd  f13, 72+(12*8)(r1)++	/* set up registers for the routine that actually does the work */+	/* get the context pointer from the trampoline */+	mr r3, r11++	/* now load up the pointer to the result storage */+	addi r4, r1, 56++	/* now load up the pointer to the saved gpr registers */+	addi r5, r1, 200++	/* now load up the pointer to the saved fpr registers */+	addi r6, r1, 72++	/* make the call */+	bl .ffi_closure_helper_DARWIN+	nop++.Ldoneclosure:++	/* now r3 contains the return type */+	/* so use it to look up in a table */+	/* so we know how to deal with each type */++	/* look up the proper starting point in table  */+	/* by using return type as offset */+	lhz	r3, 6(r3)	/* load type from return type */+	lwz	r4, LC..60(2)	/* get address of jump table */+	slwi	r3, r3, 4	/* now multiply return type by 16 */+	lwz	r0, 176+8(r1)	/* load return address */+	add	r3, r3, r4	/* add contents of table to table address */+	mtctr	r3+	bctr			/* jump to it */++/* Each fragment must be exactly 16 bytes long (4 instructions).+   Align to 16 byte boundary for cache and dispatch efficiency.  */+	.align 4++L..60:+/* case FFI_TYPE_VOID */+	mtlr r0+	addi r1, r1, 176+	blr+	nop++/* case FFI_TYPE_INT */+	lwz r3, 56+0(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_FLOAT */+	lfs f1, 56+0(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_DOUBLE */+	lfd f1, 56+0(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_LONGDOUBLE */+	lfd f1, 56+0(r1)+	mtlr r0+	lfd f2, 56+8(r1)+	b L..finish++/* case FFI_TYPE_UINT8 */+	lbz r3, 56+3(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_SINT8 */+	lbz r3, 56+3(r1)+	mtlr r0+	extsb r3, r3+	b L..finish++/* case FFI_TYPE_UINT16 */+	lhz r3, 56+2(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_SINT16 */+	lha r3, 56+2(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_UINT32 */+	lwz r3, 56+0(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_SINT32 */+	lwz r3, 56+0(r1)+	mtlr r0+	addi r1, r1, 176+	blr++/* case FFI_TYPE_UINT64 */+	lwz r3, 56+0(r1)+	mtlr r0+	lwz r4, 56+4(r1)+	b L..finish++/* case FFI_TYPE_SINT64 */+	lwz r3, 56+0(r1)+	mtlr r0+	lwz r4, 56+4(r1)+	b L..finish++/* case FFI_TYPE_STRUCT */+	mtlr r0+	addi r1, r1, 176+	blr+	nop++/* case FFI_TYPE_POINTER */+	lwz r3, 56+0(r1)+	mtlr r0+L..finish:+	addi r1, r1, 176+	blr+LFE..0:+#endif+	.ef __LINE__+/* END(ffi_closure_ASM) */+++.csect .text[PR]+	.align 2+	.globl ffi_go_closure_ASM+	.globl .ffi_go_closure_ASM+.csect ffi_go_closure_ASM[DS]+ffi_go_closure_ASM:+#ifdef __64BIT__+	.llong .ffi_go_closure_ASM, TOC[tc0], 0+	.csect .text[PR]+.ffi_go_closure_ASM:+	.function .ffi_go_closure_ASM,.ffi_go_closure_ASM,16,044,LFE..1-LFB..1+	.bf __LINE__+	.line 1+LFB..1:+/* we want to build up an area for the parameters passed */+/* in registers (both floating point and integer) */++	/* we store gpr 3 to gpr 10 (aligned to 4)+	in the parents outgoing area  */+	std   r3, 48+(0*8)(r1)+	std   r4, 48+(1*8)(r1)+	std   r5, 48+(2*8)(r1)+	std   r6, 48+(3*8)(r1)+	mflr  r0++	std   r7, 48+(4*8)(r1)+	std   r8, 48+(5*8)(r1)+	std   r9, 48+(6*8)(r1)+	std   r10, 48+(7*8)(r1)+	std   r0, 16(r1)	/* save the return address */+LCFI..2:+	/* 48  Bytes (Linkage Area) */+	/* 64  Bytes (params) */+	/* 16  Bytes (result) */+	/* 104 Bytes (13*8 from FPR) */+	/* 8   Bytes (alignment) */+	/* 240 Bytes */++	stdu  r1, -240(r1)	/* skip over caller save area+				   keep stack aligned to 16  */+LCFI..3:++	/* next save fpr 1 to fpr 13 (aligned to 8) */+	stfd  f1, 128+(0*8)(r1)+	stfd  f2, 128+(1*8)(r1)+	stfd  f3, 128+(2*8)(r1)+	stfd  f4, 128+(3*8)(r1)+	stfd  f5, 128+(4*8)(r1)+	stfd  f6, 128+(5*8)(r1)+	stfd  f7, 128+(6*8)(r1)+	stfd  f8, 128+(7*8)(r1)+	stfd  f9, 128+(8*8)(r1)+	stfd  f10, 128+(9*8)(r1)+	stfd  f11, 128+(10*8)(r1)+	stfd  f12, 128+(11*8)(r1)+	stfd  f13, 128+(12*8)(r1)++	/* set up registers for the routine that actually does the work */+	mr r3, r11	/* go closure */++	/* now load up the pointer to the result storage */+	addi r4, r1, 112++	/* now load up the pointer to the saved gpr registers */+	addi r5, r1, 288++	/* now load up the pointer to the saved fpr registers */+	addi r6, r1, 128++	/* make the call */+	bl .ffi_go_closure_helper_DARWIN+	nop++	b .Ldoneclosure+LFE..1:++#else /* ! __64BIT__ */+	+	.long .ffi_go_closure_ASM, TOC[tc0], 0+	.csect .text[PR]+.ffi_go_closure_ASM:+	.function .ffi_go_closure_ASM,.ffi_go_closure_ASM,16,044,LFE..1-LFB..1+	.bf __LINE__+	.line 1+LFB..1:+/* we want to build up an area for the parameters passed */+/* in registers (both floating point and integer) */++	/* we store gpr 3 to gpr 10 (aligned to 4)+	in the parents outgoing area  */+	stw   r3, 24+(0*4)(r1)+	stw   r4, 24+(1*4)(r1)+	stw   r5, 24+(2*4)(r1)+	stw   r6, 24+(3*4)(r1)+	mflr  r0++	stw   r7, 24+(4*4)(r1)+	stw   r8, 24+(5*4)(r1)+	stw   r9, 24+(6*4)(r1)+	stw   r10, 24+(7*4)(r1)+	stw   r0, 8(r1)+LCFI..2:+	/* 24 Bytes (Linkage Area) */+	/* 32 Bytes (params) */+	/* 16  Bytes (result) */+	/* 104 Bytes (13*8 from FPR) */+	/* 176 Bytes */++	stwu  r1, -176(r1)	/* skip over caller save area+				   keep stack aligned to 16  */+LCFI..3:++	/* next save fpr 1 to fpr 13 (aligned to 8) */+	stfd  f1, 72+(0*8)(r1)+	stfd  f2, 72+(1*8)(r1)+	stfd  f3, 72+(2*8)(r1)+	stfd  f4, 72+(3*8)(r1)+	stfd  f5, 72+(4*8)(r1)+	stfd  f6, 72+(5*8)(r1)+	stfd  f7, 72+(6*8)(r1)+	stfd  f8, 72+(7*8)(r1)+	stfd  f9, 72+(8*8)(r1)+	stfd  f10, 72+(9*8)(r1)+	stfd  f11, 72+(10*8)(r1)+	stfd  f12, 72+(11*8)(r1)+	stfd  f13, 72+(12*8)(r1)++	/* set up registers for the routine that actually does the work */+	mr   r3, 11	/* go closure */++	/* now load up the pointer to the result storage */+	addi r4, r1, 56++	/* now load up the pointer to the saved gpr registers */+	addi r5, r1, 200++	/* now load up the pointer to the saved fpr registers */+	addi r6, r1, 72++	/* make the call */+	bl .ffi_go_closure_helper_DARWIN+	nop++	b    .Ldoneclosure+LFE..1:+#endif+	.ef __LINE__+/* END(ffi_go_closure_ASM) */++/* EH frame stuff.  */++#define LR_REGNO		0x41		/* Link Register (65), see rs6000.md */+#ifdef __64BIT__+#define PTRSIZE			8+#define LOG2_PTRSIZE		3+#define CFA_OFFSET		0xf0,0x01	/* LEB128 240 */+#define FDE_ENCODING		0x1c		/* DW_EH_PE_pcrel|DW_EH_PE_sdata8 */+#define EH_DATA_ALIGN_FACT	0x78		/* LEB128 -8 */+#else+#define PTRSIZE			4+#define LOG2_PTRSIZE		2+#define CFA_OFFSET		0xb0,0x01	/* LEB128 176 */+#define FDE_ENCODING		0x1b		/* DW_EH_PE_pcrel|DW_EH_PE_sdata4 */+#define EH_DATA_ALIGN_FACT	0x7c		/* LEB128 -4 */+#endif++	.csect	_unwind.ro_[RO],4+	.align	LOG2_PTRSIZE+	.globl	_GLOBAL__F_libffi_src_powerpc_aix_closure+_GLOBAL__F_libffi_src_powerpc_aix_closure:+Lframe..1:+	.vbyte	4,LECIE..1-LSCIE..1	/* CIE Length */+LSCIE..1:+	.vbyte	4,0			/* CIE Identifier Tag */+	.byte	0x3			/* CIE Version */+	.byte	"zR"			/* CIE Augmentation */+	.byte	0+	.byte	0x1			/* uleb128 0x1; CIE Code Alignment Factor */+	.byte	EH_DATA_ALIGN_FACT	/* leb128 -4/-8; CIE Data Alignment Factor */+	.byte	LR_REGNO		/* CIE RA Column */+	.byte	0x1			/* uleb128 0x1; Augmentation size */+	.byte	FDE_ENCODING		/* FDE Encoding (pcrel|sdata4/8) */+	.byte	0xc			/* DW_CFA_def_cfa */+	.byte	0x1			/*     uleb128 0x1; Register r1 */+	.byte	0			/*     uleb128 0x0; Offset 0 */+	.align	LOG2_PTRSIZE+LECIE..1:+LSFDE..1:+	.vbyte	4,LEFDE..1-LASFDE..1	/* FDE Length */+LASFDE..1:+	.vbyte	4,LASFDE..1-Lframe..1	/* FDE CIE offset */+	.vbyte	PTRSIZE,LFB..0-$	/* FDE initial location */+	.vbyte	PTRSIZE,LFE..0-LFB..0	/* FDE address range */+	.byte	0			/* uleb128 0x0; Augmentation size */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..1-LCFI..0+	.byte	0xe			/* DW_CFA_def_cfa_offset */+	.byte	CFA_OFFSET		/*     uleb128 176/240 */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..0-LFB..0+	.byte	0x11			/* DW_CFA_offset_extended_sf */+	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */+	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */+	.align	LOG2_PTRSIZE+LEFDE..1:+LSFDE..2:+	.vbyte	4,LEFDE..2-LASFDE..2	/* FDE Length */+LASFDE..2:+	.vbyte	4,LASFDE..2-Lframe..1	/* FDE CIE offset */+	.vbyte	PTRSIZE,LFB..1-$	/* FDE initial location */+	.vbyte	PTRSIZE,LFE..1-LFB..1	/* FDE address range */+	.byte	0			/* uleb128 0x0; Augmentation size */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..3-LCFI..2+	.byte	0xe			/* DW_CFA_def_cfa_offset */+	.byte	CFA_OFFSET		/*     uleb128 176/240 */+	.byte	0x4			/* DW_CFA_advance_loc4 */+	.vbyte	4,LCFI..2-LFB..1+	.byte	0x11			/* DW_CFA_offset_extended_sf */+	.byte	LR_REGNO		/*     uleb128 LR_REGNO; Register LR */+	.byte	0x7e			/*     leb128 -2; Offset -2 (8/16) */+	.align	LOG2_PTRSIZE+LEFDE..2:+	.vbyte	4,0			/* End of FDEs */++	.csect	.text[PR]+	.ref	_GLOBAL__F_libffi_src_powerpc_aix_closure	/* Prevents garbage collection by AIX linker */+
+ src/powerpc/asm.h view
@@ -0,0 +1,125 @@+/* -----------------------------------------------------------------------+   asm.h - Copyright (c) 1998 Geoffrey Keating++   PowerPC 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 ASM_GLOBAL_DIRECTIVE .globl+++#define C_SYMBOL_NAME(name) name+/* Macro for a label.  */+#ifdef	__STDC__+#define C_LABEL(name)		name##:+#else+#define C_LABEL(name)		name/**/:+#endif++/* This seems to always be the case on PPC.  */+#define ALIGNARG(log2) log2+/* For ELF we need the `.type' directive to make shared libs work right.  */+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name++/* If compiled for profiling, call `_mcount' at the start of each function.  */+#ifdef	PROF+/* The mcount code relies on the return address being on the stack+   to locate our caller and so it can restore it; so store one just+   for its benefit.  */+#ifdef PIC+#define CALL_MCOUNT							      \+  .pushsection;								      \+  .section ".data";							      \+  .align ALIGNARG(2);							      \+0:.long 0;								      \+  .previous;								      \+  mflr  %r0;								      \+  stw   %r0,4(%r1);							      \+  bl    _GLOBAL_OFFSET_TABLE_@local-4;					      \+  mflr  %r11;								      \+  lwz   %r0,0b@got(%r11);						      \+  bl    JUMPTARGET(_mcount);+#else  /* PIC */+#define CALL_MCOUNT							      \+  .section ".data";							      \+  .align ALIGNARG(2);							      \+0:.long 0;								      \+  .previous;								      \+  mflr  %r0;								      \+  lis   %r11,0b@ha;							      \+  stw   %r0,4(%r1);							      \+  addi  %r0,%r11,0b@l;							      \+  bl    JUMPTARGET(_mcount);+#endif /* PIC */+#else  /* PROF */+#define CALL_MCOUNT		/* Do nothing.  */+#endif /* PROF */++#define	ENTRY(name)							      \+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \+  .align ALIGNARG(2);							      \+  C_LABEL(name)								      \+  CALL_MCOUNT++#define EALIGN_W_0  /* No words to insert.  */+#define EALIGN_W_1  nop+#define EALIGN_W_2  nop;nop+#define EALIGN_W_3  nop;nop;nop+#define EALIGN_W_4  EALIGN_W_3;nop+#define EALIGN_W_5  EALIGN_W_4;nop+#define EALIGN_W_6  EALIGN_W_5;nop+#define EALIGN_W_7  EALIGN_W_6;nop++/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes+   past a 2^align boundary.  */+#ifdef PROF+#define EFFI_ALIGN(name, alignt, words)					      \+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \+  .align ALIGNARG(2);							      \+  C_LABEL(name)								      \+  CALL_MCOUNT								      \+  b 0f;									      \+  .align ALIGNARG(alignt);						      \+  EALIGN_W_##words;							      \+  0:+#else /* PROF */+#define EFFI_ALIGN(name, alignt, words)					      \+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \+  .align ALIGNARG(alignt);						      \+  EALIGN_W_##words;							      \+  C_LABEL(name)+#endif++#define END(name)							      \+  ASM_SIZE_DIRECTIVE(name)++#ifdef PIC+#define JUMPTARGET(name) name##@plt+#else+#define JUMPTARGET(name) name+#endif++/* Local labels stripped out by the linker.  */+#define L(x) .L##x
+ src/powerpc/darwin.S view
@@ -0,0 +1,378 @@+/* -----------------------------------------------------------------------+   darwin.S - Copyright (c) 2000 John Hornkvist+	      Copyright (c) 2004, 2010 Free Software Foundation, Inc.++   PowerPC 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+#if defined(__ppc64__)+#define MODE_CHOICE(x, y) y+#else+#define MODE_CHOICE(x, y) x+#endif++#define machine_choice	MODE_CHOICE(ppc7400,ppc64)++; Define some pseudo-opcodes for size-independent load & store of GPRs ...+#define lgu		MODE_CHOICE(lwzu, ldu)+#define lg		MODE_CHOICE(lwz,ld)+#define sg		MODE_CHOICE(stw,std)+#define sgu		MODE_CHOICE(stwu,stdu)+#define sgux		MODE_CHOICE(stwux,stdux)++; ... and the size of GPRs and their storage indicator.+#define GPR_BYTES	MODE_CHOICE(4,8)+#define LOG2_GPR_BYTES	MODE_CHOICE(2,3)	/* log2(GPR_BYTES) */+#define g_long		MODE_CHOICE(long, quad)	/* usage is ".g_long" */++; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.+#define LINKAGE_SIZE	MODE_CHOICE(24,48)+#define PARAM_AREA	MODE_CHOICE(32,64)+#define SAVED_LR_OFFSET	MODE_CHOICE(8,16)	/* save position for lr */++/* If there is any FP stuff we make space for all of the regs.  */+#define SAVED_FPR_COUNT 13+#define FPR_SIZE	8+#define RESULT_BYTES	16++/* This should be kept in step with the same value in ffi_darwin.c.  */+#define ASM_NEEDS_REGISTERS 4+#define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES)++#include <fficonfig.h>+#include <ffi.h>++#define JUMPTARGET(name) name+#define L(x) x++	.text+	.align 2+	.globl _ffi_prep_args++	.align 2+	.globl _ffi_call_DARWIN++	/* We arrive here with:+	   r3 = ptr to extended cif.+	   r4 = -bytes.+	   r5 = cif flags.+	   r6 = ptr to return value.+	   r7 = fn pointer (user func).+	   r8 = fn pointer (ffi_prep_args).+	   r9 = ffi_type* for the ret val.  */++_ffi_call_DARWIN:+Lstartcode:+	mr   	r12,r8	/* We only need r12 until the call,+			   so it does not have to be saved.  */+LFB1:+	/* Save the old stack pointer as AP.  */+	mr	r8,r1+LCFI0:+	+	/* Save the retval type in parents frame.  */+	sg	r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8)++	/* Allocate the stack space we need.  */+	sgux	r1,r1,r4++	/* Save registers we use.  */+	mflr	r9+	sg	r9,SAVED_LR_OFFSET(r8)++	sg	r28,-(4 * GPR_BYTES)(r8)	+	sg	r29,-(3 * GPR_BYTES)(r8)+	sg	r30,-(2 * GPR_BYTES)(r8)+	sg	r31,-(    GPR_BYTES)(r8)++#if !defined(POWERPC_DARWIN)+	/* The TOC slot is reserved in the Darwin ABI and r2 is volatile.  */+	sg	r2,(5 * GPR_BYTES)(r1)+#endif++LCFI1:++	/* Save arguments over call.  */+	mr	r31,r5	/* flags,  */+	mr	r30,r6	/* rvalue,  */+	mr	r29,r7	/* function address,  */+	mr	r28,r8	/* our AP.  */+LCFI2:+	/* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy.  */+	mr	r4,r1+	li	r9,0++	mtctr	r12 /* r12 holds address of _ffi_prep_args.  */+	bctrl++#if !defined(POWERPC_DARWIN)+	/* The TOC slot is reserved in the Darwin ABI and r2 is volatile.  */+	lg     r2,(5 * GPR_BYTES)(r1)+#endif+	/* Now do the call.+	   Set up cr1 with bits 4-7 of the flags.  */+	mtcrf	0x40,r31+	/* Get the address to call into CTR.  */+	mtctr	r29+	/* Load all those argument registers.+	   We have set up a nice stack frame, just load it into registers.  */+	lg     r3, (LINKAGE_SIZE                )(r1)+	lg     r4, (LINKAGE_SIZE +     GPR_BYTES)(r1)+	lg     r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1)+	lg     r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1)+	nop+	lg     r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1)+	lg     r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1)+	lg     r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1)+	lg     r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1)++L1:+	/* ... Load all the FP registers.  */+	bf	6,L2	/* No floats to load.  */+	lfd	f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)+	lfd	f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)+	lfd	f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)+	lfd	f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)+	nop+	lfd	f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)+	lfd	f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)+	lfd	f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)+	lfd	f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)+	nop+	lfd     f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)+	lfd     f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)+	lfd     f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)+	lfd     f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)+	nop+	lfd     f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)++L2:+	mr	r12,r29	/* Put the target address in r12 as specified.  */+	mtctr  	r12+	nop+	nop++	/* Make the call.  */+	bctrl++	/* Now, deal with the return value.  */++	/* m64 structure returns can occupy the same set of registers as+	   would be used to pass such a structure as arg0 - so take care +	   not to step on any possibly hot regs.  */++	/* Get the flags.. */+	mtcrf	0x03,r31 ; we need c6 & cr7 now.+	; FLAG_RETURNS_NOTHING also covers struct ret-by-ref.+	bt	30,L(done_return_value)	  ; FLAG_RETURNS_NOTHING+	bf	27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT+	+	/* OK, so we have a struct.  */+#if defined(__ppc64__)+	bt	31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case ++	/* OK, we have to map the return back to a mem struct.+	   We are about to trample the parents param area, so recover the+	   return type.  r29 is free, since the call is done.  */+	lg	r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28)++	sg	r3, (LINKAGE_SIZE                )(r28)+	sg	r4, (LINKAGE_SIZE +     GPR_BYTES)(r28)+	sg	r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28)+	sg	r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28)+	nop+	sg	r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28)+	sg	r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28)+	sg	r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28)+	sg	r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)+	/* OK, so do the block move - we trust that memcpy will not trample+	   the fprs...  */+	mr 	r3,r30 ; dest+	addi	r4,r28,LINKAGE_SIZE ; source+	/* The size is a size_t, should be long.  */+	lg	r5,0(r29)+	/* Figure out small structs */+	cmpi	0,r5,4+	bgt	L3	; 1, 2 and 4 bytes have special rules.+	cmpi	0,r5,3+	beq	L3	; not 3+	addi	r4,r4,8+	subf	r4,r5,r4+L3:+	bl	_memcpy+	+	/* ... do we need the FP registers? - recover the flags.. */+	mtcrf	0x03,r31 ; we need c6 & cr7 now.+	bf	29,L(done_return_value)	/* No floats in the struct.  */+	stfd	f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)+	stfd	f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)+	stfd	f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)+	stfd	f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)+	nop+	stfd	f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)+	stfd	f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)+	stfd	f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)+	stfd	f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)+	nop+	stfd	f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)+	stfd	f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)+	stfd	f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)+	stfd	f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)+	nop+	stfd	f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)++	mr	r3,r29	; ffi_type *+	mr	r4,r30	; dest+	addi	r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs+	xor	r6,r6,r6+	sg	r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)+	addi	r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter.+	bl 	_darwin64_struct_floats_to_mem++	b L(done_return_value)+#else+	stw	r3,0(r30) ; m32 the only struct return in reg is 4 bytes.+#endif+	b L(done_return_value)++L(fp_return_value):+	/* Do we have long double to store?  */+	bf	31,L(fd_return_value) ; FLAG_RETURNS_128BITS+	stfd	f1,0(r30)+	stfd	f2,FPR_SIZE(r30)+	b	L(done_return_value)++L(fd_return_value):+	/* Do we have double to store?  */+	bf	28,L(float_return_value)+	stfd	f1,0(r30)+	b	L(done_return_value)++L(float_return_value):+	/* We only have a float to store.  */+	stfs	f1,0(r30)+	b	L(done_return_value)++L(scalar_return_value):+	bt	29,L(fp_return_value)	; FLAG_RETURNS_FP+	; ffi_arg is defined as unsigned long. +	sg	r3,0(r30)		; Save the reg.+	bf	28,L(done_return_value) ; not FLAG_RETURNS_64BITS ++#if defined(__ppc64__)+L(maybe_return_128):+	std	r3,0(r30)+	bf	31,L(done_return_value) ; not FLAG_RETURNS_128BITS +	std	r4,8(r30)+#else+	stw	r4,4(r30)+#endif++	/* Fall through.  */+	/* We want this at the end to simplify eh epilog computation.  */++L(done_return_value):+	/* Restore the registers we used and return.  */+	lg	r29,SAVED_LR_OFFSET(r28)+	; epilog+	lg	r31,-(1 * GPR_BYTES)(r28)+	mtlr	r29+	lg	r30,-(2 * GPR_BYTES)(r28)+	lg	r29,-(3 * GPR_BYTES)(r28)+	lg	r28,-(4 * GPR_BYTES)(r28)+	lg	r1,0(r1)+	blr+LFE1:+	.align	1+/* END(_ffi_call_DARWIN)  */++/* Provide a null definition of _ffi_call_AIX.  */+	.text+	.globl _ffi_call_AIX+	.align 2+_ffi_call_AIX:+	blr+/* END(_ffi_call_AIX)  */++/* EH stuff.  */++#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)++	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support+EH_frame1:+	.set	L$set$0,LECIE1-LSCIE1+	.long	L$set$0	; Length of Common Information Entry+LSCIE1:+	.long	0x0	; CIE Identifier Tag+	.byte	0x1	; CIE Version+	.ascii	"zR\0"	; CIE Augmentation+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor+	.byte	EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor+	.byte	0x41	; CIE RA Column+	.byte	0x1	; uleb128 0x1; Augmentation size+	.byte	0x10	; FDE Encoding (pcrel)+	.byte	0xc	; DW_CFA_def_cfa+	.byte	0x1	; uleb128 0x1+	.byte	0x0	; uleb128 0x0+	.align	LOG2_GPR_BYTES+LECIE1:++	.globl _ffi_call_DARWIN.eh+_ffi_call_DARWIN.eh:+LSFDE1:+	.set	L$set$1,LEFDE1-LASFDE1+	.long	L$set$1	; FDE Length+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+	.byte   0x0     ; uleb128 0x0; Augmentation size+	.byte	0x4	; DW_CFA_advance_loc4+	.set	L$set$4,LCFI0-Lstartcode+	.long	L$set$4+	.byte	0xd	; DW_CFA_def_cfa_register+	.byte	0x08	; uleb128 0x08+	.byte	0x4	; DW_CFA_advance_loc4+	.set	L$set$5,LCFI1-LCFI0+	.long	L$set$5+	.byte   0x11    ; DW_CFA_offset_extended_sf+	.byte	0x41	; uleb128 0x41+	.byte   0x7e    ; sleb128 -2+	.byte	0x9f	; DW_CFA_offset, column 0x1f+	.byte	0x1	; uleb128 0x1+	.byte	0x9e	; DW_CFA_offset, column 0x1e+	.byte	0x2	; uleb128 0x2+	.byte	0x9d	; DW_CFA_offset, column 0x1d+	.byte	0x3	; uleb128 0x3+	.byte	0x9c	; DW_CFA_offset, column 0x1c+	.byte	0x4	; uleb128 0x4+	.byte	0x4	; DW_CFA_advance_loc4+	.set	L$set$6,LCFI2-LCFI1+	.long	L$set$6+	.byte	0xd	; DW_CFA_def_cfa_register+	.byte	0x1c	; uleb128 0x1c+	.align LOG2_GPR_BYTES+LEFDE1:+	.align 1+
+ src/powerpc/darwin_closure.S view
@@ -0,0 +1,571 @@+/* -----------------------------------------------------------------------+   darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010, +   Free Software Foundation, Inc. +   based on ppc_closure.S++   PowerPC 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+#define L(x) x++#if defined(__ppc64__)+#define MODE_CHOICE(x, y) y+#else+#define MODE_CHOICE(x, y) x+#endif++#define machine_choice	MODE_CHOICE(ppc7400,ppc64)++; Define some pseudo-opcodes for size-independent load & store of GPRs ...+#define lgu		MODE_CHOICE(lwzu, ldu)+#define lg		MODE_CHOICE(lwz,ld)+#define sg		MODE_CHOICE(stw,std)+#define sgu		MODE_CHOICE(stwu,stdu)++; ... and the size of GPRs and their storage indicator.+#define GPR_BYTES	MODE_CHOICE(4,8)+#define LOG2_GPR_BYTES	MODE_CHOICE(2,3)	/* log2(GPR_BYTES) */+#define g_long		MODE_CHOICE(long, quad)	/* usage is ".g_long" */++; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.+#define LINKAGE_SIZE	MODE_CHOICE(24,48)+#define PARAM_AREA	MODE_CHOICE(32,64)++#define SAVED_CR_OFFSET	MODE_CHOICE(4,8)	/* save position for CR */+#define SAVED_LR_OFFSET	MODE_CHOICE(8,16)	/* save position for lr */++/* WARNING: if ffi_type is changed... here be monsters.  +   Offsets of items within the result type.  */+#define FFI_TYPE_TYPE	MODE_CHOICE(6,10)+#define FFI_TYPE_ELEM	MODE_CHOICE(8,16)++#define SAVED_FPR_COUNT 13+#define FPR_SIZE	8+/* biggest m64 struct ret is 8GPRS + 13FPRS = 168 bytes - rounded to 16bytes = 176. */+#define RESULT_BYTES	MODE_CHOICE(16,176)++; The whole stack frame **MUST** be 16byte-aligned.+#define SAVE_SIZE (((LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)+15) & -16LL)+#define PAD_SIZE (SAVE_SIZE-(LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES))++#define PARENT_PARM_BASE (SAVE_SIZE+LINKAGE_SIZE)+#define FP_SAVE_BASE (LINKAGE_SIZE+PARAM_AREA)++#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050+; We no longer need the pic symbol stub for Darwin >= 9.+#define BLCLS_HELP _ffi_closure_helper_DARWIN+#define STRUCT_RETVALUE_P _darwin64_struct_ret_by_value_p+#define PASS_STR_FLOATS _darwin64_pass_struct_floats+#undef WANT_STUB+#else+#define BLCLS_HELP L_ffi_closure_helper_DARWIN$stub+#define STRUCT_RETVALUE_P L_darwin64_struct_ret_by_value_p$stub+#define PASS_STR_FLOATS L_darwin64_pass_struct_floats$stub+#define WANT_STUB+#endif++/* m32/m64++   The stack layout looks like this:++   |   Additional params...			| |     Higher address+   ~						~ ~+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS+   |--------------------------------------------| |+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |+   |--------------------------------------------| |+   |   Reserved                       2*4/8	| |+   |--------------------------------------------| |+   |   Space for callee`s LR		4/8	| |+   |--------------------------------------------| |+   |   Saved CR [low word for m64]      4/8	| |+   |--------------------------------------------| |+   |   Current backchain pointer	4/8	|-/ Parent`s frame.+   |--------------------------------------------| <+ <<< on entry to+   |   Result Bytes		       16/176	| |+   |--------------------------------------------| |+   ~   padding to 16-byte alignment		~ ~+   |--------------------------------------------| |+   |   NUM_FPR_ARG_REGISTERS slots		| |+   |   here fp13 .. fp1		       13*8	| |+   |--------------------------------------------| |+   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS+   |--------------------------------------------| |+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |+   |--------------------------------------------| |	stack	|+   |   Reserved [compiler,binder]     2*4/8	| |	grows	|+   |--------------------------------------------| |	down	V+   |   Space for callees LR		4/8	| |+   |--------------------------------------------| |	lower addresses+   |   Saved CR [low word for m64]      4/8	| |+   |--------------------------------------------| |     stack pointer here+   |   Current backchain pointer	4/8	|-/	during+   |--------------------------------------------|   <<<	call.++*/++	.file	"darwin_closure.S"++	.machine machine_choice++	.text+	.globl _ffi_closure_ASM+	.align LOG2_GPR_BYTES+_ffi_closure_ASM:+LFB1:+Lstartcode:+	mflr	r0			/* extract return address  */+	sg	r0,SAVED_LR_OFFSET(r1)	/* save the return address  */+LCFI0:+	sgu	r1,-SAVE_SIZE(r1)	/* skip over caller save area+					keep stack aligned to 16.  */+LCFI1:+	/* We want to build up an area for the parameters passed+	   in registers. (both floating point and integer)  */++	/* Put gpr 3 to gpr 10 in the parents outgoing area...+	   ... the remainder of any params that overflowed the regs will+	   follow here.  */+	sg	r3, (PARENT_PARM_BASE                )(r1)+	sg	r4, (PARENT_PARM_BASE + GPR_BYTES    )(r1)+	sg	r5, (PARENT_PARM_BASE + GPR_BYTES * 2)(r1)+	sg	r6, (PARENT_PARM_BASE + GPR_BYTES * 3)(r1)+	sg	r7, (PARENT_PARM_BASE + GPR_BYTES * 4)(r1)+	sg	r8, (PARENT_PARM_BASE + GPR_BYTES * 5)(r1)+	sg	r9, (PARENT_PARM_BASE + GPR_BYTES * 6)(r1)+	sg	r10,(PARENT_PARM_BASE + GPR_BYTES * 7)(r1)++	/* We save fpr 1 to fpr 14 in our own save frame.  */+	stfd	f1, (FP_SAVE_BASE                 )(r1)+	stfd	f2, (FP_SAVE_BASE +  FPR_SIZE     )(r1)+	stfd	f3, (FP_SAVE_BASE +  FPR_SIZE * 2 )(r1)+	stfd	f4, (FP_SAVE_BASE +  FPR_SIZE * 3 )(r1)+	stfd	f5, (FP_SAVE_BASE +  FPR_SIZE * 4 )(r1)+	stfd	f6, (FP_SAVE_BASE +  FPR_SIZE * 5 )(r1)+	stfd	f7, (FP_SAVE_BASE +  FPR_SIZE * 6 )(r1)+	stfd	f8, (FP_SAVE_BASE +  FPR_SIZE * 7 )(r1)+	stfd	f9, (FP_SAVE_BASE +  FPR_SIZE * 8 )(r1)+	stfd	f10,(FP_SAVE_BASE +  FPR_SIZE * 9 )(r1)+	stfd	f11,(FP_SAVE_BASE +  FPR_SIZE * 10)(r1)+	stfd	f12,(FP_SAVE_BASE +  FPR_SIZE * 11)(r1)+	stfd	f13,(FP_SAVE_BASE +  FPR_SIZE * 12)(r1)++	/* Set up registers for the routine that actually does the work+	   get the context pointer from the trampoline.  */+	mr	r3,r11++	/* Now load up the pointer to the result storage.  */+	addi	r4,r1,(SAVE_SIZE-RESULT_BYTES)++	/* Now load up the pointer to the saved gpr registers.  */+	addi	r5,r1,PARENT_PARM_BASE++	/* Now load up the pointer to the saved fpr registers.  */+	addi	r6,r1,FP_SAVE_BASE++	/* Make the call.  */+	bl	BLCLS_HELP++	/* r3 contains the rtype pointer... save it since we will need+	   it later.  */+	sg	r3,LINKAGE_SIZE(r1)	; ffi_type * result_type+	lg	r0,0(r3)		; size => r0+	lhz	r3,FFI_TYPE_TYPE(r3)	; type => r3++	/* The helper will have intercepted structure returns and inserted+	   the caller`s destination address for structs returned by ref.  */++	/* r3 contains the return type  so use it to look up in a table+	   so we know how to deal with each type.  */++	addi	r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here.  */+	bl	Lget_ret_type0_addr	/* Get pointer to Lret_type0 into LR.  */+	mflr	r4			/* Move to r4.  */+	slwi	r3,r3,4			/* Now multiply return type by 16.  */+	add	r3,r3,r4		/* Add contents of table to table address.  */+	mtctr	r3+	bctr			 	 /* Jump to it.  */+LFE1:+/* Each of the ret_typeX code fragments has to be exactly 16 bytes long+   (4 instructions). For cache effectiveness we align to a 16 byte boundary+   first.  */++	.align 4++	nop+	nop+	nop+Lget_ret_type0_addr:+	blrl++/* case FFI_TYPE_VOID  */+Lret_type0:+	b	Lfinish+	nop+	nop+	nop++/* case FFI_TYPE_INT  */+Lret_type1:+	lg	r3,0(r5)+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_FLOAT  */+Lret_type2:+	lfs	f1,0(r5)+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_DOUBLE  */+Lret_type3:+	lfd	f1,0(r5)+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_LONGDOUBLE  */+Lret_type4:+	lfd	f1,0(r5)+	lfd	f2,8(r5)+	b	Lfinish+	nop++/* case FFI_TYPE_UINT8  */+Lret_type5:+#if defined(__ppc64__)+	lbz	r3,7(r5)+#else+	lbz	r3,3(r5)+#endif+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_SINT8  */+Lret_type6:+#if defined(__ppc64__)+	lbz	r3,7(r5)+#else+	lbz	r3,3(r5)+#endif+	extsb	r3,r3+	b	Lfinish+	nop++/* case FFI_TYPE_UINT16  */+Lret_type7:+#if defined(__ppc64__)+	lhz	r3,6(r5)+#else+	lhz	r3,2(r5)+#endif+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_SINT16  */+Lret_type8:+#if defined(__ppc64__)+	lha	r3,6(r5)+#else+	lha	r3,2(r5)+#endif+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_UINT32  */+Lret_type9:+#if defined(__ppc64__)+	lwz	r3,4(r5)+#else+	lwz	r3,0(r5)+#endif+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_SINT32  */+Lret_type10:+#if defined(__ppc64__)+	lwz	r3,4(r5)+#else+	lwz	r3,0(r5)+#endif+	b	Lfinish+	nop+	nop++/* case FFI_TYPE_UINT64  */+Lret_type11:+#if defined(__ppc64__)+	lg	r3,0(r5)+	b	Lfinish+	nop+#else+	lwz	r3,0(r5)+	lwz	r4,4(r5)+	b	Lfinish+#endif+	nop++/* case FFI_TYPE_SINT64  */+Lret_type12:+#if defined(__ppc64__)+	lg	r3,0(r5)+	b	Lfinish+	nop+#else+	lwz	r3,0(r5)+	lwz	r4,4(r5)+	b	Lfinish+#endif+	nop++/* case FFI_TYPE_STRUCT  */+Lret_type13:+#if defined(__ppc64__)+	lg	r3,0(r5)		; we need at least this...+	cmpi	0,r0,4+	bgt	Lstructend		; not a special small case+	b	Lsmallstruct		; see if we need more.+#else+	cmpwi	0,r0,4+	bgt	Lfinish		; not by value+	lg	r3,0(r5)+	b	Lfinish+#endif+/* case FFI_TYPE_POINTER  */+Lret_type14:+	lg	r3,0(r5)+	b	Lfinish+	nop+	nop++#if defined(__ppc64__)+Lsmallstruct:+	beq	Lfour			; continuation of Lret13.+	cmpi	0,r0,3+	beq	Lfinish			; don`t adjust this - can`t be any floats here...+	srdi	r3,r3,48+	cmpi	0,r0,2+	beq	Lfinish			; .. or here ..+	srdi	r3,r3,8+	b 	Lfinish			; .. or here.++Lfour:+	lg	r6,LINKAGE_SIZE(r1)	; get the result type+	lg	r6,FFI_TYPE_ELEM(r6)	; elements array pointer+	lg	r6,0(r6)		; first element+	lhz	r0,FFI_TYPE_TYPE(r6)	; OK go the type+	cmpi	0,r0,2			; FFI_TYPE_FLOAT+	bne	Lfourint+	lfs	f1,0(r5)		; just one float in the struct.+	b 	Lfinish++Lfourint:+	srdi	r3,r3,32		; four bytes.+	b 	Lfinish++Lstructend:+	lg	r3,LINKAGE_SIZE(r1)	; get the result type+	bl	STRUCT_RETVALUE_P+	cmpi	0,r3,0+	beq	Lfinish			; nope.+	/* Recover a pointer to the results.  */+	addi	r11,r1,(SAVE_SIZE-RESULT_BYTES)+	lg	r3,0(r11)		; we need at least this...+	lg	r4,8(r11)+	cmpi	0,r0,16+	beq	Lfinish		; special case 16 bytes we don't consider floats.++	/* OK, frustratingly, the process of saving the struct to mem might have+	   messed with the FPRs, so we have to re-load them :(.+	   We`ll use our FPRs space again - calling: +	   void darwin64_pass_struct_floats (ffi_type *s, char *src, +					     unsigned *nfpr, double **fprs) +	   We`ll temporarily pinch the first two slots of the param area for local+	   vars used by the routine.  */+	xor	r6,r6,r6+	addi	r5,r1,PARENT_PARM_BASE		; some space+	sg	r6,0(r5)			; *nfpr zeroed.+	addi	r6,r5,8				; **fprs+	addi	r3,r1,FP_SAVE_BASE		; pointer to FPRs space+	sg	r3,0(r6)+	mr	r4,r11				; the struct is here...+	lg	r3,LINKAGE_SIZE(r1)		; ffi_type * result_type.+	bl	PASS_STR_FLOATS			; get struct floats into FPR save space.+	/* See if we used any floats  */+	lwz	r0,(SAVE_SIZE-RESULT_BYTES)(r1)	+	cmpi	0,r0,0+	beq	Lstructints			; nope.+	/* OK load `em up... */+	lfd	f1, (FP_SAVE_BASE                 )(r1)+	lfd	f2, (FP_SAVE_BASE +  FPR_SIZE     )(r1)+	lfd	f3, (FP_SAVE_BASE +  FPR_SIZE * 2 )(r1)+	lfd	f4, (FP_SAVE_BASE +  FPR_SIZE * 3 )(r1)+	lfd	f5, (FP_SAVE_BASE +  FPR_SIZE * 4 )(r1)+	lfd	f6, (FP_SAVE_BASE +  FPR_SIZE * 5 )(r1)+	lfd	f7, (FP_SAVE_BASE +  FPR_SIZE * 6 )(r1)+	lfd	f8, (FP_SAVE_BASE +  FPR_SIZE * 7 )(r1)+	lfd	f9, (FP_SAVE_BASE +  FPR_SIZE * 8 )(r1)+	lfd	f10,(FP_SAVE_BASE +  FPR_SIZE * 9 )(r1)+	lfd	f11,(FP_SAVE_BASE +  FPR_SIZE * 10)(r1)+	lfd	f12,(FP_SAVE_BASE +  FPR_SIZE * 11)(r1)+	lfd	f13,(FP_SAVE_BASE +  FPR_SIZE * 12)(r1)++	/* point back at our saved struct.  */+Lstructints:+	addi	r11,r1,(SAVE_SIZE-RESULT_BYTES)+	lg	r3,0(r11)			; we end up picking the+	lg	r4,8(r11)			; first two again.+	lg	r5,16(r11)+	lg	r6,24(r11)+	lg	r7,32(r11)+	lg	r8,40(r11)+	lg	r9,48(r11)+	lg	r10,56(r11)+#endif++/* case done  */+Lfinish:+	addi	r1,r1,SAVE_SIZE		/* Restore stack pointer.  */+	lg	r0,SAVED_LR_OFFSET(r1)	/* Get return address.  */+	mtlr	r0			/* Reset link register.  */+	blr+Lendcode:+	.align 1+	+/* END(ffi_closure_ASM)  */++/* EH frame stuff.  */+#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)+/* 176, 400 */+#define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90)+#define EH_FRAME_OFFSETB MODE_CHOICE(1,3)++	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support+EH_frame1:+	.set	L$set$0,LECIE1-LSCIE1+	.long	L$set$0	; Length of Common Information Entry+LSCIE1:+	.long	0x0	; CIE Identifier Tag+	.byte	0x1	; CIE Version+	.ascii	"zR\0"	; CIE Augmentation+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor+	.byte	EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor+	.byte	0x41	; CIE RA Column+	.byte	0x1	; uleb128 0x1; Augmentation size+	.byte	0x10	; FDE Encoding (pcrel)+	.byte	0xc	; DW_CFA_def_cfa+	.byte	0x1	; uleb128 0x1+	.byte	0x0	; uleb128 0x0+	.align	LOG2_GPR_BYTES+LECIE1:+	.globl _ffi_closure_ASM.eh+_ffi_closure_ASM.eh:+LSFDE1:+	.set	L$set$1,LEFDE1-LASFDE1+	.long	L$set$1	; FDE Length++LASFDE1:+	.long	LASFDE1-EH_frame1	; FDE CIE offset+	.g_long	Lstartcode-.	; FDE initial location+	.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+	.long	L$set$3+	.byte	0xe	; DW_CFA_def_cfa_offset+	.byte	EH_FRAME_OFFSETA,EH_FRAME_OFFSETB	; uleb128 176,1/190,3+	.byte	0x4	; DW_CFA_advance_loc4+	.set	L$set$4,LCFI0-Lstartcode+	.long	L$set$4+	.byte   0x11    ; DW_CFA_offset_extended_sf+	.byte	0x41	; uleb128 0x41+	.byte   0x7e    ; sleb128 -2+	.align	LOG2_GPR_BYTES+LEFDE1:+	.align 	1++#ifdef WANT_STUB+	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32+	.align 5+L_ffi_closure_helper_DARWIN$stub:+	.indirect_symbol _ffi_closure_helper_DARWIN+	mflr r0+	bcl 20,31,"L1$spb"+"L1$spb":+	mflr r11+	addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")+	mtlr r0+	lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11)+	mtctr r12+	bctr+	.lazy_symbol_pointer+L_ffi_closure_helper_DARWIN$lazy_ptr:+	.indirect_symbol _ffi_closure_helper_DARWIN+	.g_long	dyld_stub_binding_helper++#if defined(__ppc64__)+	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32+	.align 5+L_darwin64_struct_ret_by_value_p$stub:+	.indirect_symbol _darwin64_struct_ret_by_value_p+	mflr r0+	bcl 20,31,"L2$spb"+"L2$spb":+	mflr r11+	addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")+	mtlr r0+	lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11)+	mtctr r12+	bctr+	.lazy_symbol_pointer+L_darwin64_struct_ret_by_value_p$lazy_ptr:+	.indirect_symbol _darwin64_struct_ret_by_value_p+	.g_long	dyld_stub_binding_helper++	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32+	.align 5+L_darwin64_pass_struct_floats$stub:+	.indirect_symbol _darwin64_pass_struct_floats+	mflr r0+	bcl 20,31,"L3$spb"+"L3$spb":+	mflr r11+	addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")+	mtlr r0+	lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11)+	mtctr r12+	bctr+	.lazy_symbol_pointer+L_darwin64_pass_struct_floats$lazy_ptr:+	.indirect_symbol _darwin64_pass_struct_floats+	.g_long	dyld_stub_binding_helper+#  endif+#endif
+ src/powerpc/ffi.c view
@@ -0,0 +1,194 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (C) 2013 IBM+           Copyright (C) 2011 Anthony Green+           Copyright (C) 2011 Kyle Moffett+           Copyright (C) 2008 Red Hat, Inc+           Copyright (C) 2007, 2008 Free Software Foundation, Inc+	   Copyright (c) 1998 Geoffrey Keating++   PowerPC 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 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.+   ----------------------------------------------------------------------- */++#include "ffi.h"+#include "ffi_common.h"+#include "ffi_powerpc.h"+#include "internal.h"+#include <tramp.h>++#if HAVE_LONG_DOUBLE_VARIANT+/* Adjust ffi_type_longdouble.  */+void FFI_HIDDEN+ffi_prep_types (ffi_abi abi)+{+# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+#  ifdef POWERPC64+  ffi_prep_types_linux64 (abi);+#  else+  ffi_prep_types_sysv (abi);+#  endif+# endif+}+#endif++/* Perform machine dependent cif processing */+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep (ffi_cif *cif)+{+#ifdef POWERPC64+  return ffi_prep_cif_linux64 (cif);+#else+  return ffi_prep_cif_sysv (cif);+#endif+}++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep_var (ffi_cif *cif,+			  unsigned int nfixedargs MAYBE_UNUSED,+			  unsigned int ntotalargs MAYBE_UNUSED)+{+#ifdef POWERPC64+  return ffi_prep_cif_linux64_var (cif, nfixedargs, ntotalargs);+#else+  return ffi_prep_cif_sysv (cif);+#endif+}++static void+ffi_call_int (ffi_cif *cif,+	      void (*fn) (void),+	      void *rvalue,+	      void **avalue,+	      void *closure)+{+  /* The final SYSV ABI says that structures smaller or equal 8 bytes+     are returned in r3/r4.  A draft ABI used by linux instead returns+     them in memory.++     We bounce-buffer SYSV small struct return values so that sysv.S+     can write r3 and r4 to memory without worrying about struct size.+   +     For ELFv2 ABI, use a bounce buffer for homogeneous structs too,+     for similar reasons. This bounce buffer must be aligned to 16+     bytes for use with homogeneous structs of vectors (float128).  */+  float128 smst_buffer[8];+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;++  ecif.rvalue = rvalue;+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)+    ecif.rvalue = smst_buffer;+  /* Ensure that we have a valid struct return value.+     FIXME: Isn't this just papering over a user problem?  */+  else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)+    ecif.rvalue = alloca (cif->rtype->size);++#ifdef POWERPC64+  ffi_call_LINUX64 (&ecif, fn, ecif.rvalue, cif->flags, closure,+		    -(long) cif->bytes);+#else+  ffi_call_SYSV (&ecif, fn, ecif.rvalue, cif->flags, closure, -cif->bytes);+#endif++  /* Check for a bounce-buffered return value */+  if (rvalue && ecif.rvalue == smst_buffer)+    {+      unsigned int rsize = cif->rtype->size;+#ifndef __LITTLE_ENDIAN__+      /* The SYSV ABI returns a structure of up to 4 bytes in size+	 left-padded in r3.  */+# ifndef POWERPC64+      if (rsize <= 4)+	memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);+      else+# endif+	/* The SYSV ABI returns a structure of up to 8 bytes in size+	   left-padded in r3/r4, and the ELFv2 ABI similarly returns a+	   structure of up to 8 bytes in size left-padded in r3. But+	   note that a structure of a single float is not paddded.  */+	if (rsize <= 8 && (cif->flags & FLAG_RETURNS_FP) == 0)+	  memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);+	else+#endif+	  memcpy (rvalue, smst_buffer, rsize);+    }+}++void+ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,+	     void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}++ffi_status+ffi_prep_closure_loc (ffi_closure *closure,+		      ffi_cif *cif,+		      void (*fun) (ffi_cif *, void *, void **, void *),+		      void *user_data,+		      void *codeloc)+{+#ifdef POWERPC64+  return ffi_prep_closure_loc_linux64 (closure, cif, fun, user_data, codeloc);+#else+  return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc);+#endif+}++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure,+		     ffi_cif *cif,+		     void (*fun) (ffi_cif *, void *, void **, void *))+{+#ifdef POWERPC64+  closure->tramp = ffi_go_closure_linux64;+#else+  closure->tramp = ffi_go_closure_sysv;+#endif+  closure->cif = cif;+  closure->fun = fun;+  return FFI_OK;+}++#ifdef FFI_EXEC_STATIC_TRAMP+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;+  *tramp_size = PPC_TRAMP_SIZE;+  *map_size = PPC_TRAMP_MAP_SIZE;+#if defined (_CALL_AIX) || _CALL_ELF == 1+  /* The caller wants the entry point address of the trampoline code,+     not the address of the function descriptor.  */+  return *(void **)trampoline_code_table;+#else+  return &trampoline_code_table;+#endif+}+#endif
+ src/powerpc/ffi_darwin.c view
@@ -0,0 +1,1464 @@+/* -----------------------------------------------------------------------+   ffi_darwin.c++   Copyright (C) 1998 Geoffrey Keating+   Copyright (C) 2001 John Hornkvist+   Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.++   FFI support for Darwin and AIX.+   +   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.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>++extern void ffi_closure_ASM (void);++#if defined (FFI_GO_CLOSURES)+extern void ffi_go_closure_ASM (void);+#endif++enum {+  /* The assembly depends on these exact flags.  +     For Darwin64 (when FLAG_RETURNS_STRUCT is set):+       FLAG_RETURNS_FP indicates that the structure embeds FP data.+       FLAG_RETURNS_128BITS signals a special struct size that is not+       expanded for float content.  */+  FLAG_RETURNS_128BITS	= 1 << (31-31), /* These go in cr7  */+  FLAG_RETURNS_NOTHING	= 1 << (31-30),+  FLAG_RETURNS_FP	= 1 << (31-29),+  FLAG_RETURNS_64BITS	= 1 << (31-28),++  FLAG_RETURNS_STRUCT	= 1 << (31-27), /* This goes in cr6  */++  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),+  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */+  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),+  FLAG_RETVAL_REFERENCE = 1 << (31- 4)+};++/* About the DARWIN ABI.  */+enum {+  NUM_GPR_ARG_REGISTERS = 8,+  NUM_FPR_ARG_REGISTERS = 13,+  LINKAGE_AREA_GPRS = 6+};++enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments.+   +   m32/m64++   The stack layout we want looks like this:++   |   Return address from ffi_call_DARWIN      |	higher addresses+   |--------------------------------------------|+   |   Previous backchain pointer	4/8	|	stack pointer here+   |--------------------------------------------|<+ <<<	on entry to+   |   ASM_NEEDS_REGISTERS=r28-r31   4*(4/8)	| |	ffi_call_DARWIN+   |--------------------------------------------| |+   |   When we have any FP activity... the	| |+   |   FPRs occupy NUM_FPR_ARG_REGISTERS slots	| |+   |   here fp13 .. fp1 from high to low addr.	| |+   ~						~ ~+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS+   |--------------------------------------------| |+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |+   |--------------------------------------------| |	stack	|+   |   Reserved                       2*4/8	| |	grows	|+   |--------------------------------------------| |	down	V+   |   Space for callee's LR		4/8	| |+   |--------------------------------------------| |	lower addresses+   |   Saved CR [low word for m64]      4/8	| |+   |--------------------------------------------| |     stack pointer here+   |   Current backchain pointer	4/8	|-/	during+   |--------------------------------------------|   <<<	ffi_call_DARWIN++   */++#if defined(POWERPC_DARWIN64)+static void+darwin64_pass_struct_by_value +  (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);+#endif++/* This depends on GPR_SIZE = sizeof (unsigned long) */++void+ffi_prep_args (extended_cif *ecif, unsigned long *const stack)+{+  const unsigned bytes = ecif->cif->bytes;+  const unsigned flags = ecif->cif->flags;+  const unsigned nargs = ecif->cif->nargs;+#if !defined(POWERPC_DARWIN64) +  const ffi_abi abi = ecif->cif->abi;+#endif++  /* 'stacktop' points at the previous backchain pointer.  */+  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));++  /* 'fpr_base' points at the space for fpr1, and grows upwards as+     we use FPR registers.  */+  double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;+  int gp_count = 0, fparg_count = 0;++  /* 'next_arg' grows up as we put parameters in it.  */+  unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions.  */++  int i;+  double double_tmp;+  void **p_argv = ecif->avalue;+  unsigned long gprvalue;+  ffi_type** ptr = ecif->cif->arg_types;+#if !defined(POWERPC_DARWIN64) +  char *dest_cpy;+#endif+  unsigned size_al = 0;++  /* Check that everything starts aligned properly.  */+  FFI_ASSERT(((unsigned) (char *) stack & 0xF) == 0);+  FFI_ASSERT(((unsigned) (char *) stacktop & 0xF) == 0);+  FFI_ASSERT((bytes & 0xF) == 0);++  /* Deal with return values that are actually pass-by-reference.+     Rule:+     Return values are referenced by r3, so r4 is the first parameter.  */++  if (flags & FLAG_RETVAL_REFERENCE)+    *next_arg++ = (unsigned long) (char *) ecif->rvalue;++  /* Now for the arguments.  */+  for (i = nargs; i > 0; i--, ptr++, p_argv++)+    {+      switch ((*ptr)->type)+	{+	/* If a floating-point parameter appears before all of the general-+	   purpose registers are filled, the corresponding GPRs that match+	   the size of the floating-point parameter are skipped.  */+	case FFI_TYPE_FLOAT:+	  double_tmp = *(float *) *p_argv;+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)+	    *fpr_base++ = double_tmp;+#if defined(POWERPC_DARWIN)+	  *(float *)next_arg = *(float *) *p_argv;+#else+	  *(double *)next_arg = double_tmp;+#endif+	  next_arg++;+	  gp_count++;+	  fparg_count++;+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);+	  break;++	case FFI_TYPE_DOUBLE:+	  double_tmp = *(double *) *p_argv;+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)+	    *fpr_base++ = double_tmp;+	  *(double *)next_arg = double_tmp;+#ifdef POWERPC64+	  next_arg++;+	  gp_count++;+#else+	  next_arg += 2;+	  gp_count += 2;+#endif+	  fparg_count++;+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);+	  break;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE++	case FFI_TYPE_LONGDOUBLE:+#  if defined(POWERPC64) && !defined(POWERPC_DARWIN64)+	  /* ??? This will exceed the regs count when the value starts at fp13+	     and it will not put the extra bit on the stack.  */+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)+	    *(long double *) fpr_base++ = *(long double *) *p_argv;+	  else+	    *(long double *) next_arg = *(long double *) *p_argv;+	  next_arg += 2;+	  fparg_count += 2;+#  else+	  double_tmp = ((double *) *p_argv)[0];+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)+	    *fpr_base++ = double_tmp;+	  *(double *) next_arg = double_tmp;+#    if defined(POWERPC_DARWIN64)+	  next_arg++;+	  gp_count++;+#    else+	  next_arg += 2;+	  gp_count += 2;+#    endif+	  fparg_count++;+	  double_tmp = ((double *) *p_argv)[1];+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)+	    *fpr_base++ = double_tmp;+	  *(double *) next_arg = double_tmp;+#    if defined(POWERPC_DARWIN64)+	  next_arg++;+	  gp_count++;+#    else+	  next_arg += 2;+	  gp_count += 2;+#    endif+	  fparg_count++;+#  endif+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);+	  break;+#endif+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+#ifdef POWERPC64+	  gprvalue = *(long long *) *p_argv;+	  goto putgpr;+#else+	  *(long long *) next_arg = *(long long *) *p_argv;+	  next_arg += 2;+	  gp_count += 2;+#endif+	  break;+	case FFI_TYPE_POINTER:+	  gprvalue = *(unsigned long *) *p_argv;+	  goto putgpr;+	case FFI_TYPE_UINT8:+	  gprvalue = *(unsigned char *) *p_argv;+	  goto putgpr;+	case FFI_TYPE_SINT8:+	  gprvalue = *(signed char *) *p_argv;+	  goto putgpr;+	case FFI_TYPE_UINT16:+	  gprvalue = *(unsigned short *) *p_argv;+	  goto putgpr;+	case FFI_TYPE_SINT16:+	  gprvalue = *(signed short *) *p_argv;+	  goto putgpr;++	case FFI_TYPE_STRUCT:+	  size_al = (*ptr)->size;+#if defined(POWERPC_DARWIN64)+	  next_arg = (unsigned long *)FFI_ALIGN((char *)next_arg, (*ptr)->alignment);+	  darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, +					 (unsigned) size_al,+					 (unsigned int *) &fparg_count,+					 &fpr_base, &next_arg);+#else+	  dest_cpy = (char *) next_arg;++	  /* If the first member of the struct is a double, then include enough+	     padding in the struct size to align it to double-word.  */+	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)+	    size_al = FFI_ALIGN((*ptr)->size, 8);++#  if defined(POWERPC64) +	  FFI_ASSERT (abi != FFI_DARWIN);+	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);+	  next_arg += (size_al + 7) / 8;+#  else+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,+	     SI 4 bytes) are aligned as if they were those modes.+	     Structures with 3 byte in size are padded upwards.  */+	  if (size_al < 3 && abi == FFI_DARWIN)+	    dest_cpy += 4 - size_al;++	  memcpy((char *) dest_cpy, (char *) *p_argv, size_al);+	  next_arg += (size_al + 3) / 4;+#  endif+#endif+	  break;++	case FFI_TYPE_INT:+	case FFI_TYPE_SINT32:+	  gprvalue = *(signed int *) *p_argv;+	  goto putgpr;++	case FFI_TYPE_UINT32:+	  gprvalue = *(unsigned int *) *p_argv;+	putgpr:+	  *next_arg++ = gprvalue;+	  gp_count++;+	  break;+	default:+	  break;+	}+    }++  /* Check that we didn't overrun the stack...  */+  /* FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);+     FFI_ASSERT((unsigned *)fpr_base+     	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);+     FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);  */+}++#if defined(POWERPC_DARWIN64)++/* See if we can put some of the struct into fprs.+   This should not be called for structures of size 16 bytes, since these are not+   broken out this way.  */+static void+darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)+{+  int i;++  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)++  for (i = 0; s->elements[i] != NULL; i++)+    {+      ffi_type *p = s->elements[i];+      switch (p->type)+	{+	  case FFI_TYPE_STRUCT:+	    darwin64_scan_struct_for_floats (p, nfpr);+	    break;+	  case FFI_TYPE_LONGDOUBLE:+	    (*nfpr) += 2;+	    break;+	  case FFI_TYPE_DOUBLE:+	  case FFI_TYPE_FLOAT:+	    (*nfpr) += 1;+	    break;+	  default:+	    break;    +	}+    }+}++static int+darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)+{+  unsigned struct_offset=0, i;++  for (i = 0; s->elements[i] != NULL; i++)+    {+      char *item_base;+      ffi_type *p = s->elements[i];+      /* Find the start of this item (0 for the first one).  */+      if (i > 0)+        struct_offset = FFI_ALIGN(struct_offset, p->alignment);++      item_base = src + struct_offset;++      switch (p->type)+	{+	  case FFI_TYPE_STRUCT:+	    if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))+	      return 1;+	    break;+	  case FFI_TYPE_LONGDOUBLE:+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)+	      return 1;+	    (*nfpr) += 1;+	    item_base += 8;+	  /* FALL THROUGH */+	  case FFI_TYPE_DOUBLE:+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)+	      return 1;+	    (*nfpr) += 1;+	    break;+	  case FFI_TYPE_FLOAT:+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)+	      return 1;+	    (*nfpr) += 1;+	    break;+	  default:+	    /* If we try and place any item, that is non-float, once we've+	       exceeded the 8 GPR mark, then we can't fit the struct.  */+	    if ((unsigned long)item_base >= 8*8) +	      return 1;+	    break;    +	}+      /* now count the size of what we just used.  */+      struct_offset += p->size;+    }+  return 0;+}++/* Can this struct be returned by value?  */+int +darwin64_struct_ret_by_value_p (ffi_type *s)+{+  unsigned nfp = 0;++  FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);+  +  /* The largest structure we can return is 8long + 13 doubles.  */+  if (s->size > 168)+    return 0;+  +  /* We can't pass more than 13 floats.  */+  darwin64_scan_struct_for_floats (s, &nfp);+  if (nfp > 13)+    return 0;+  +  /* If there are not too many floats, and the struct is+     small enough to accommodate in the GPRs, then it must be OK.  */+  if (s->size <= 64)+    return 1;+  +  /* Well, we have to look harder.  */+  nfp = 0;+  if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))+    return 0;+  +  return 1;+}++void+darwin64_pass_struct_floats (ffi_type *s, char *src, +			     unsigned *nfpr, double **fprs)+{+  int i;+  double *fpr_base = *fprs;+  unsigned struct_offset = 0;++  /* We don't assume anything about the alignment of the source.  */+  for (i = 0; s->elements[i] != NULL; i++)+    {+      char *item_base;+      ffi_type *p = s->elements[i];+      /* Find the start of this item (0 for the first one).  */+      if (i > 0)+        struct_offset = FFI_ALIGN(struct_offset, p->alignment);+      item_base = src + struct_offset;++      switch (p->type)+	{+	  case FFI_TYPE_STRUCT:+	    darwin64_pass_struct_floats (p, item_base, nfpr,+					   &fpr_base);+	    break;+	  case FFI_TYPE_LONGDOUBLE:+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)+	      *fpr_base++ = *(double *)item_base;+	    (*nfpr) += 1;+	    item_base += 8;+	  /* FALL THROUGH */+	  case FFI_TYPE_DOUBLE:+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)+	      *fpr_base++ = *(double *)item_base;+	    (*nfpr) += 1;+	    break;+	  case FFI_TYPE_FLOAT:+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)+	      *fpr_base++ = (double) *(float *)item_base;+	    (*nfpr) += 1;+	    break;+	  default:+	    break;    +	}+      /* now count the size of what we just used.  */+      struct_offset += p->size;+    }+  /* Update the scores.  */+  *fprs = fpr_base;+}++/* Darwin64 special rules.+   Break out a struct into params and float registers.  */+static void+darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,+			       unsigned *nfpr, double **fprs, unsigned long **arg)+{+  unsigned long *next_arg = *arg;+  char *dest_cpy = (char *)next_arg;++  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)++  if (!size)+    return;++  /* First... special cases.  */+  if (size < 3+      || (size == 4 +	  && s->elements[0] +	  && s->elements[0]->type != FFI_TYPE_FLOAT))+    {+      /* Must be at least one GPR, padding is unspecified in value, +	 let's make it zero.  */+      *next_arg = 0UL; +      dest_cpy += 8 - size;+      memcpy ((char *) dest_cpy, src, size);+      next_arg++;+    }+  else if (size == 16)+    {+      memcpy ((char *) dest_cpy, src, size);+      next_arg += 2;+    }+  else+    {+      /* now the general case, we consider embedded floats.  */+      memcpy ((char *) dest_cpy, src, size);+      darwin64_pass_struct_floats (s, src, nfpr, fprs);+      next_arg += (size+7)/8;+    }+    +  *arg = next_arg;+}++double *+darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)+{+  int i;+  unsigned struct_offset = 0;++  /* We don't assume anything about the alignment of the source.  */+  for (i = 0; s->elements[i] != NULL; i++)+    {+      char *item_base;+      ffi_type *p = s->elements[i];+      /* Find the start of this item (0 for the first one).  */+      if (i > 0)+        struct_offset = FFI_ALIGN(struct_offset, p->alignment);+      item_base = dest + struct_offset;++      switch (p->type)+	{+	  case FFI_TYPE_STRUCT:+	    fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);+	    break;+	  case FFI_TYPE_LONGDOUBLE:+	    if (*nf < NUM_FPR_ARG_REGISTERS)+	      {+		*(double *)item_base = *fprs++ ;+		(*nf) += 1;+	      }+	    item_base += 8;+	  /* FALL THROUGH */+	  case FFI_TYPE_DOUBLE:+	    if (*nf < NUM_FPR_ARG_REGISTERS)+	      {+		*(double *)item_base = *fprs++ ;+		(*nf) += 1;+	      }+	    break;+	  case FFI_TYPE_FLOAT:+	    if (*nf < NUM_FPR_ARG_REGISTERS)+	      {+		*(float *)item_base = (float) *fprs++ ;+		(*nf) += 1;+	      }+	    break;+	  default:+	    break;    +	}+      /* now count the size of what we just used.  */+      struct_offset += p->size;+    }+  return fprs;+}++#endif++/* Adjust the size of S to be correct for Darwin.+   On Darwin m32, the first field of a structure has natural alignment.  +   On Darwin m64, all fields have natural alignment.  */++static void+darwin_adjust_aggregate_sizes (ffi_type *s)+{+  int i;++  if (s->type != FFI_TYPE_STRUCT)+    return;++  s->size = 0;+  for (i = 0; s->elements[i] != NULL; i++)+    {+      ffi_type *p;+      int align;+      +      p = s->elements[i];+      if (p->type == FFI_TYPE_STRUCT)+	darwin_adjust_aggregate_sizes (p);+#if defined(POWERPC_DARWIN64)+      /* Natural alignment for all items.  */+      align = p->alignment;+#else+      /* Natural alignment for the first item... */+      if (i == 0)+	align = p->alignment;+      else if (p->alignment == 16 || p->alignment < 4)+	/* .. subsequent items with vector or align < 4 have natural align.  */+	align = p->alignment;+      else+	/* .. or align is 4.  */+	align = 4;+#endif+      /* Pad, if necessary, before adding the current item.  */+      s->size = FFI_ALIGN(s->size, align) + p->size;+    }+  +  s->size = FFI_ALIGN(s->size, s->alignment);+  +  /* This should not be necessary on m64, but harmless.  */+  if (s->elements[0]->type == FFI_TYPE_UINT64+      || s->elements[0]->type == FFI_TYPE_SINT64+      || s->elements[0]->type == FFI_TYPE_DOUBLE+      || s->elements[0]->alignment == 8)+    s->alignment = s->alignment > 8 ? s->alignment : 8;+  /* Do not add additional tail padding.  */+}++/* Adjust the size of S to be correct for AIX.+   Word-align double unless it is the first member of a structure recursively.+   Return non-zero if we found a recursive first member aggregate of interest. */++static int+aix_adjust_aggregate_sizes (ffi_type *s, int outer_most_type_or_first_member)+{+  int i, nested_first_member=0, final_align, rc=0;++  if (s->type != FFI_TYPE_STRUCT)+    return 0;++  s->size = 0;+  for (i = 0; s->elements[i] != NULL; i++)+    {+      ffi_type p;+      int align;++      /* nested aggregates layout differently on AIX, so take a copy of the type */+      p = *(s->elements[i]);+      if (i == 0)+        nested_first_member = aix_adjust_aggregate_sizes(&p, outer_most_type_or_first_member);+      else+        aix_adjust_aggregate_sizes(&p, 0);+      align = p.alignment;+      if (i != 0 && p.type == FFI_TYPE_DOUBLE)+        align = 4;+      s->size = FFI_ALIGN(s->size, align) + p.size;+    }++  final_align=s->alignment;+  if ((s->elements[0]->type == FFI_TYPE_UINT64+          || s->elements[0]->type == FFI_TYPE_SINT64+          || s->elements[0]->type == FFI_TYPE_DOUBLE+          || s->elements[0]->alignment == 8 || nested_first_member)) {+      final_align = s->alignment > 8 ? s->alignment : 8;+      rc=1;+      /* still use the adjusted alignment to calculate tail padding, but don't adjust the types alignment if+         we aren't in the recursive first position */+      if (outer_most_type_or_first_member)+        s->alignment=final_align;+  }++  s->size = FFI_ALIGN(s->size, final_align);+  return rc;+}++/* Perform machine dependent cif processing.  */+ffi_status+ffi_prep_cif_machdep (ffi_cif *cif)+{+  /* All this is for the DARWIN ABI.  */+  unsigned i;+  ffi_type **ptr;+  unsigned bytes;+  unsigned fparg_count = 0, intarg_count = 0;+  unsigned flags = 0;+  unsigned size_al = 0;++  /* All the machine-independent calculation of cif->bytes will be wrong.+     All the calculation of structure sizes will also be wrong.+     Redo the calculation for DARWIN.  */++  if (cif->abi == FFI_DARWIN)+    {+      darwin_adjust_aggregate_sizes (cif->rtype);+      for (i = 0; i < cif->nargs; i++)+	darwin_adjust_aggregate_sizes (cif->arg_types[i]);+    }++  if (cif->abi == FFI_AIX)+    {+      aix_adjust_aggregate_sizes (cif->rtype, 1);+      for (i = 0; i < cif->nargs; i++)+	aix_adjust_aggregate_sizes (cif->arg_types[i], 1);+    }++  /* Space for the frame pointer, callee's LR, CR, etc, and for+     the asm's temp regs.  */++  bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);++  /* Return value handling.  +    The rules m32 are as follows:+     - 32-bit (or less) integer values are returned in gpr3;+     - structures of size <= 4 bytes also returned in gpr3;+     - 64-bit integer values [??? and structures between 5 and 8 bytes] are+       returned in gpr3 and gpr4;+     - Single/double FP values are returned in fpr1;+     - Long double FP (if not equivalent to double) values are returned in+       fpr1 and fpr2;+     m64:+     - 64-bit or smaller integral values are returned in GPR3+     - Single/double FP values are returned in fpr1;+     - Long double FP values are returned in fpr1 and fpr2;+     m64 Structures:+     - If the structure could be accommodated in registers were it to be the+       first argument to a routine, then it is returned in those registers.+     m32/m64 structures otherwise:+     - Larger structures values are allocated space and a pointer is passed+       as the first argument.  */+  switch (cif->rtype->type)+    {++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+    case FFI_TYPE_LONGDOUBLE:+      flags |= FLAG_RETURNS_128BITS;+      flags |= FLAG_RETURNS_FP;+      break;+#endif++    case FFI_TYPE_DOUBLE:+      flags |= FLAG_RETURNS_64BITS;+      /* Fall through.  */+    case FFI_TYPE_FLOAT:+      flags |= FLAG_RETURNS_FP;+      break;++    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+#ifdef POWERPC64+    case FFI_TYPE_POINTER:+#endif+      flags |= FLAG_RETURNS_64BITS;+      break;++    case FFI_TYPE_STRUCT:+#if defined(POWERPC_DARWIN64)+      {+	/* Can we fit the struct into regs?  */+	if (darwin64_struct_ret_by_value_p (cif->rtype))+	  {+	    unsigned nfpr = 0;+	    flags |= FLAG_RETURNS_STRUCT;+	    if (cif->rtype->size != 16)+	      darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;+	    else+	      flags |= FLAG_RETURNS_128BITS;+	    /* Will be 0 for 16byte struct.  */+	    if (nfpr)+	      flags |= FLAG_RETURNS_FP;+	  }+	else /* By ref. */+	  {+	    flags |= FLAG_RETVAL_REFERENCE;+	    flags |= FLAG_RETURNS_NOTHING;+	    intarg_count++;+	  }+      }+#elif defined(DARWIN_PPC)+      if (cif->rtype->size <= 4)+	flags |= FLAG_RETURNS_STRUCT;+      else /* else by reference.  */+	{+	  flags |= FLAG_RETVAL_REFERENCE;+	  flags |= FLAG_RETURNS_NOTHING;+	  intarg_count++;+	}+#else /* assume we pass by ref.  */+      flags |= FLAG_RETVAL_REFERENCE;+      flags |= FLAG_RETURNS_NOTHING;+      intarg_count++;+#endif+      break;+    case FFI_TYPE_VOID:+      flags |= FLAG_RETURNS_NOTHING;+      break;++    default:+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */+      break;+    }++  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the+     first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest+     goes on the stack.  +     ??? Structures are passed as a pointer to a copy of the structure. +     Stuff on the stack needs to keep proper alignment.  +     For m64 the count is effectively of half-GPRs.  */+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)+    {+      unsigned align_words;+      switch ((*ptr)->type)+	{+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	  fparg_count++;+#if !defined(POWERPC_DARWIN64)+	  /* If this FP arg is going on the stack, it must be+	     8-byte-aligned.  */+	  if (fparg_count > NUM_FPR_ARG_REGISTERS+	      && (intarg_count & 0x01) != 0)+	    intarg_count++;+#endif+	  break;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+	  fparg_count += 2;+	  /* If this FP arg is going on the stack, it must be+	     16-byte-aligned.  */+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)+#if defined (POWERPC64)+	    intarg_count = FFI_ALIGN(intarg_count, 2);+#else+	    intarg_count = FFI_ALIGN(intarg_count, 4);+#endif+	  break;+#endif++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+#if defined(POWERPC64)+	  intarg_count++;+#else+	  /* 'long long' arguments are passed as two words, but+	     either both words must fit in registers or both go+	     on the stack.  If they go on the stack, they must+	     be 8-byte-aligned.  */+	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1+	      || (intarg_count >= NUM_GPR_ARG_REGISTERS +	          && (intarg_count & 0x01) != 0))+	    intarg_count++;+	  intarg_count += 2;+#endif+	  break;++	case FFI_TYPE_STRUCT:+	  size_al = (*ptr)->size;+#if defined(POWERPC_DARWIN64)+	  align_words = (*ptr)->alignment >> 3;+	  if (align_words)+	    intarg_count = FFI_ALIGN(intarg_count, align_words);+	  /* Base size of the struct.  */+	  intarg_count += (size_al + 7) / 8;+	  /* If 16 bytes then don't worry about floats.  */+	  if (size_al != 16)+	    /* Scan through for floats to be placed in regs.  */+	    darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;+#else+	  align_words = (*ptr)->alignment >> 2;+	  if (align_words)+	    intarg_count = FFI_ALIGN(intarg_count, align_words);+	  /* If the first member of the struct is a double, then align+	     the struct to double-word. +	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)+	    size_al = FFI_ALIGN((*ptr)->size, 8); */+#  ifdef POWERPC64+	  intarg_count += (size_al + 7) / 8;+#  else+	  intarg_count += (size_al + 3) / 4;+#  endif+#endif+	  break;++	default:+	  /* Everything else is passed as a 4-byte word in a GPR, either+	     the object itself or a pointer to it.  */+	  intarg_count++;+	  break;+	}+    }++  if (fparg_count != 0)+    flags |= FLAG_FP_ARGUMENTS;++#if defined(POWERPC_DARWIN64)+  /* Space to image the FPR registers, if needed - which includes when they might be+     used in a struct return.  */+  if (fparg_count != 0 +      || ((flags & FLAG_RETURNS_STRUCT)+	   && (flags & FLAG_RETURNS_FP)))+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);+#else+  /* Space for the FPR registers, if needed.  */+  if (fparg_count != 0)+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);+#endif++  /* Stack space.  */+#ifdef POWERPC64+  if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)+    bytes += (intarg_count + fparg_count) * sizeof(long);+#else+  if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)+    bytes += (intarg_count + 2 * fparg_count) * sizeof(long);+#endif+  else+    bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);++  /* The stack space allocated needs to be a multiple of 16 bytes.  */+  bytes = FFI_ALIGN(bytes, 16) ;++  cif->flags = flags;+  cif->bytes = bytes;++  return FFI_OK;+}++extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,+			 void (*fn)(void), void (*fn2)(void));++#if defined (FFI_GO_CLOSURES)+extern void ffi_call_go_AIX(extended_cif *, long, unsigned, unsigned *,+			    void (*fn)(void), void (*fn2)(void), void *closure);+#endif++extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,+			    void (*fn)(void), void (*fn2)(void), ffi_type*);++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_AIX:+      ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,+		   FFI_FN(ffi_prep_args));+      break;+    case FFI_DARWIN:+      ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,+		      FFI_FN(ffi_prep_args), cif->rtype);+      break;+    default:+      FFI_ASSERT(0);+      break;+    }+}++#if defined (FFI_GO_CLOSURES)+void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,+	     void *closure)+{+  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_AIX:+      ffi_call_go_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,+		      FFI_FN(ffi_prep_args), closure);+      break;+    default:+      FFI_ASSERT(0);+      break;+    }+}+#endif++static void flush_icache(char *);+static void flush_range(char *, int);++/* The layout of a function descriptor.  A C function pointer really+   points to one of these.  */++typedef struct aix_fd_struct {+  void *code_pointer;+  void *toc;+} aix_fd;++/* here I'd like to add the stack frame layout we use in darwin_closure.S+   and aix_closure.S++   m32/m64++   The stack layout looks like this:++   |   Additional params...			| |     Higher address+   ~						~ ~+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS+   |--------------------------------------------| |+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |+   |--------------------------------------------| |+   |   Reserved                       2*4/8	| |+   |--------------------------------------------| |+   |   Space for callee's LR		4/8	| |+   |--------------------------------------------| |+   |   Saved CR [low word for m64]      4/8	| |+   |--------------------------------------------| |+   |   Current backchain pointer	4/8	|-/ Parent's frame.+   |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM+   |   Result Bytes			16	| |+   |--------------------------------------------| |+   ~   padding to 16-byte alignment		~ ~+   |--------------------------------------------| |+   |   NUM_FPR_ARG_REGISTERS slots		| |+   |   here fp13 .. fp1		       13*8	| |+   |--------------------------------------------| |+   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS+   |--------------------------------------------| |+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |+   |--------------------------------------------| |	stack	|+   |   Reserved [compiler,binder]     2*4/8	| |	grows	|+   |--------------------------------------------| |	down	V+   |   Space for callee's LR		4/8	| |+   |--------------------------------------------| |	lower addresses+   |   Saved CR [low word for m64]      4/8	| |+   |--------------------------------------------| |     stack pointer here+   |   Current backchain pointer	4/8	|-/	during+   |--------------------------------------------|   <<<	ffi_closure_ASM.++*/++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;+  struct ffi_aix_trampoline_struct *tramp_aix;+  aix_fd *fd;++  switch (cif->abi)+    {+      case FFI_DARWIN:++	FFI_ASSERT (cif->abi == FFI_DARWIN);++	tramp = (unsigned int *) &closure->tramp[0];+#if defined(POWERPC_DARWIN64)+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */+	tramp[1] = 0x429f0015;  /*   bcl-    20,4*cr7+so,  +0x18 (L1)  */+	/* We put the addresses here.  */+	tramp[6] = 0x7d6802a6;  /*L1:   mflr    r11  */+	tramp[7] = 0xe98b0000;  /*   ld     r12,0(r11) function address  */+	tramp[8] = 0x7c0803a6;  /*   mtlr    r0   */+	tramp[9] = 0x7d8903a6;  /*   mtctr   r12  */+	tramp[10] = 0xe96b0008;  /*   lwz     r11,8(r11) static chain  */+	tramp[11] = 0x4e800420;  /*   bctr  */++	*((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function  */+	*((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context  */+#else+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */+	tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */+	tramp[4] = 0x7d6802a6;  /*   mflr    r11  */+	tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */+	tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */+	tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */+	tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */+	tramp[9] = 0x4e800420;  /*   bctr  */+	tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */+	tramp[3] = (unsigned long) codeloc; /* context  */+#endif+	closure->cif = cif;+	closure->fun = fun;+	closure->user_data = user_data;++	/* Flush the icache. Only necessary on Darwin.  */+	flush_range(codeloc, FFI_TRAMPOLINE_SIZE);++	break;++    case FFI_AIX:++      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);+      fd = (aix_fd *)(void *)ffi_closure_ASM;++      FFI_ASSERT (cif->abi == FFI_AIX);++      tramp_aix->code_pointer = fd->code_pointer;+      tramp_aix->toc = fd->toc;+      tramp_aix->static_chain = codeloc;+      closure->cif = cif;+      closure->fun = fun;+      closure->user_data = user_data;+      break;++    default:+      return FFI_BAD_ABI;+      break;+    }+  return FFI_OK;+}++#if defined (FFI_GO_CLOSURES)+ffi_status+ffi_prep_go_closure (ffi_go_closure* closure,+		     ffi_cif* cif,+		     void (*fun)(ffi_cif*, void*, void**, void*))+{+  switch (cif->abi)+    {+      case FFI_AIX:++        FFI_ASSERT (cif->abi == FFI_AIX);++        closure->tramp = (void *)ffi_go_closure_ASM;+        closure->cif = cif;+        closure->fun = fun;+        return FFI_OK;+      +      // For now, ffi_prep_go_closure is only implemented for AIX, not for Darwin+      default:+        return FFI_BAD_ABI;+        break;+    }+  return FFI_OK;+}+#endif++static void+flush_icache(char *addr)+{+#ifndef _AIX+  __asm__ volatile (+		"dcbf 0,%0\n"+		"\tsync\n"+		"\ticbi 0,%0\n"+		"\tsync\n"+		"\tisync"+		: : "r"(addr) : "memory");+#endif+}++static void+flush_range(char * addr1, int size)+{+#define MIN_LINE_SIZE 32+  int i;+  for (i = 0; i < size; i += MIN_LINE_SIZE)+    flush_icache(addr1+i);+  flush_icache(addr1+size-1);+}++typedef union+{+  float f;+  double d;+} ffi_dblfl;++ffi_type *+ffi_closure_helper_DARWIN (ffi_closure *, void *,+			   unsigned long *, ffi_dblfl *);++#if defined (FFI_GO_CLOSURES)+ffi_type *+ffi_go_closure_helper_DARWIN (ffi_go_closure*, void *,+			      unsigned long *, ffi_dblfl *);+#endif++/* Basically the trampoline invokes ffi_closure_ASM, and on+   entry, r11 holds the address of the closure.+   After storing the registers that could possibly contain+   parameters to be passed into the stack frame and setting+   up space for a return value, ffi_closure_ASM invokes the+   following helper function to do most of the work.  */++static ffi_type *+ffi_closure_helper_common (ffi_cif* cif,+			   void (*fun)(ffi_cif*, void*, void**, void*),+			   void *user_data, void *rvalue,+			   unsigned long *pgr, ffi_dblfl *pfr)+{+  /* rvalue is the pointer to space for return value in closure assembly+     pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM+     pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */++  typedef double ldbits[2];++  union ldu+  {+    ldbits lb;+    long double ld;+  };++  void **          avalue;+  ffi_type **      arg_types;+  long             i, avn;+  ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;+  unsigned         size_al;+#if defined(POWERPC_DARWIN64)+  unsigned 	   fpsused = 0;+#endif++  avalue = alloca (cif->nargs * sizeof(void *));++  if (cif->rtype->type == FFI_TYPE_STRUCT)+    {+#if defined(POWERPC_DARWIN64)+      if (!darwin64_struct_ret_by_value_p (cif->rtype))+	{+    	  /* Won't fit into the regs - return by ref.  */+	  rvalue = (void *) *pgr;+	  pgr++;+	}+#elif defined(DARWIN_PPC)+      if (cif->rtype->size > 4)+	{+	  rvalue = (void *) *pgr;+	  pgr++;+	}+#else /* assume we return by ref.  */+      rvalue = (void *) *pgr;+      pgr++;+#endif+    }++  i = 0;+  avn = cif->nargs;+  arg_types = cif->arg_types;++  /* Grab the addresses of the arguments from the stack frame.  */+  while (i < avn)+    {+      switch (arg_types[i]->type)+	{+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+#if  defined(POWERPC64)+	  avalue[i] = (char *) pgr + 7;+#else+	  avalue[i] = (char *) pgr + 3;+#endif+	  pgr++;+	  break;++	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+#if  defined(POWERPC64)+	  avalue[i] = (char *) pgr + 6;+#else+	  avalue[i] = (char *) pgr + 2;+#endif+	  pgr++;+	  break;++	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+#if  defined(POWERPC64)+	  avalue[i] = (char *) pgr + 4;+#else+	case FFI_TYPE_POINTER:+	  avalue[i] = pgr;+#endif+	  pgr++;+	  break;++	case FFI_TYPE_STRUCT:+	  size_al = arg_types[i]->size;+#if defined(POWERPC_DARWIN64)+	  pgr = (unsigned long *)FFI_ALIGN((char *)pgr, arg_types[i]->alignment);+	  if (size_al < 3 || size_al == 4)+	    {+	      avalue[i] = ((char *)pgr)+8-size_al;+	      if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT+		  && fpsused < NUM_FPR_ARG_REGISTERS)+		{+		  *(float *)pgr = (float) *(double *)pfr;+		  pfr++;+		  fpsused++;+		}+	    }+	  else +	    {+	      if (size_al != 16)+		pfr = (ffi_dblfl *) +		    darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,+						   (double *)pfr, &fpsused);+	      avalue[i] = pgr;+	    }+	  pgr += (size_al + 7) / 8;+#else+	  /* If the first member of the struct is a double, then align+	     the struct to double-word.  */+	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)+	    size_al = FFI_ALIGN(arg_types[i]->size, 8);+#  if defined(POWERPC64)+	  FFI_ASSERT (cif->abi != FFI_DARWIN);+	  avalue[i] = pgr;+	  pgr += (size_al + 7) / 8;+#  else+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,+	     SI 4 bytes) are aligned as if they were those modes.  */+	  if (size_al < 3 && cif->abi == FFI_DARWIN)+	    avalue[i] = (char*) pgr + 4 - size_al;+	  else+	    avalue[i] = pgr;+	  pgr += (size_al + 3) / 4;+#  endif+#endif+	  break;++	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+#if  defined(POWERPC64)+	case FFI_TYPE_POINTER:+	  avalue[i] = pgr;+	  pgr++;+	  break;+#else+	  /* Long long ints are passed in two gpr's.  */+	  avalue[i] = pgr;+	  pgr += 2;+	  break;+#endif++	case FFI_TYPE_FLOAT:+	  /* A float value consumes a GPR.+	     There are 13 64bit floating point registers.  */+	  if (pfr < end_pfr)+	    {+	      double temp = pfr->d;+	      pfr->f = (float) temp;+	      avalue[i] = pfr;+	      pfr++;+	    }+	  else+	    {+	      avalue[i] = pgr;+	    }+	  pgr++;+	  break;++	case FFI_TYPE_DOUBLE:+	  /* A double value consumes two GPRs.+	     There are 13 64bit floating point registers.  */+	  if (pfr < end_pfr)+	    {+	      avalue[i] = pfr;+	      pfr++;+	    }+	  else+	    {+	      avalue[i] = pgr;+	    }+#ifdef POWERPC64+	  pgr++;+#else+	  pgr += 2;+#endif+	  break;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE++	case FFI_TYPE_LONGDOUBLE:+#ifdef POWERPC64+	  if (pfr + 1 < end_pfr)+	    {+	      avalue[i] = pfr;+	      pfr += 2;+	    }+	  else+	    {+	      if (pfr < end_pfr)+		{+		  *pgr = *(unsigned long *) pfr;+		  pfr++;+		}+	      avalue[i] = pgr;+	    }+	  pgr += 2;+#else  /* POWERPC64 */+	  /* A long double value consumes four GPRs and two FPRs.+	     There are 13 64bit floating point registers.  */+	  if (pfr + 1 < end_pfr)+	    {+	      avalue[i] = pfr;+	      pfr += 2;+	    }+	  /* Here we have the situation where one part of the long double+	     is stored in fpr13 and the other part is already on the stack.+	     We use a union to pass the long double to avalue[i].  */+	  else if (pfr + 1 == end_pfr)+	    {+	      union ldu temp_ld;+	      memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));+	      memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));+	      avalue[i] = &temp_ld.ld;+	      pfr++;+	    }+	  else+	    {+	      avalue[i] = pgr;+	    }+	  pgr += 4;+#endif  /* POWERPC64 */+	  break;+#endif+	default:+	  FFI_ASSERT(0);+	}+      i++;+    }++  (fun) (cif, rvalue, avalue, user_data);++  /* Tell ffi_closure_ASM to perform return type promotions.  */+  return cif->rtype;+}++ffi_type *+ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,+			   unsigned long *pgr, ffi_dblfl *pfr)+{+  return ffi_closure_helper_common (closure->cif, closure->fun,+				    closure->user_data, rvalue, pgr, pfr);+}++#if defined (FFI_GO_CLOSURES)+ffi_type *+ffi_go_closure_helper_DARWIN (ffi_go_closure *closure, void *rvalue,+			      unsigned long *pgr, ffi_dblfl *pfr)+{+  return ffi_closure_helper_common (closure->cif, closure->fun,+				    closure, rvalue, pgr, pfr);+}+#endif
+ src/powerpc/ffi_linux64.c view
@@ -0,0 +1,1160 @@+/* -----------------------------------------------------------------------+   ffi_linux64.c - Copyright (C) 2013 IBM+                   Copyright (C) 2011 Anthony Green+                   Copyright (C) 2011 Kyle Moffett+                   Copyright (C) 2008 Red Hat, Inc+                   Copyright (C) 2007, 2008 Free Software Foundation, Inc+                   Copyright (c) 1998 Geoffrey Keating++   PowerPC 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 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.+   ----------------------------------------------------------------------- */++#include "ffi.h"+#include <tramp.h>++#ifdef POWERPC64+#include "ffi_common.h"+#include "ffi_powerpc.h"+++/* About the LINUX64 ABI.  */+enum {+  NUM_GPR_ARG_REGISTERS64 = 8,+  NUM_FPR_ARG_REGISTERS64 = 13,+  NUM_VEC_ARG_REGISTERS64 = 12,+};+enum { ASM_NEEDS_REGISTERS64 = 4 };+++#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+/* Adjust size of ffi_type_longdouble.  */+void FFI_HIDDEN+ffi_prep_types_linux64 (ffi_abi abi)+{+  if ((abi & (FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128)) == FFI_LINUX)+    {+      ffi_type_longdouble.size = 8;+      ffi_type_longdouble.alignment = 8;+    }+  else+    {+      ffi_type_longdouble.size = 16;+      ffi_type_longdouble.alignment = 16;+    }+}+#endif+++static unsigned int+discover_homogeneous_aggregate (ffi_abi abi,+                                const ffi_type *t,+                                unsigned int *elnum)+{+  switch (t->type)+    {+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+    case FFI_TYPE_LONGDOUBLE:+      /* 64-bit long doubles are equivalent to doubles. */+      if ((abi & FFI_LINUX_LONG_DOUBLE_128) == 0)+        {+          *elnum = 1;+          return FFI_TYPE_DOUBLE;+        }+      /* IBM extended precision values use unaligned pairs+         of FPRs, but according to the ABI must be considered+         distinct from doubles. They are also limited to a+         maximum of four members in a homogeneous aggregate. */+      else if ((abi & FFI_LINUX_LONG_DOUBLE_IEEE128) == 0)+        {+          *elnum = 2;+          return FFI_TYPE_LONGDOUBLE;+        }+      /* Fall through. */+#endif+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+      *elnum = 1;+      return (int) t->type;++    case FFI_TYPE_STRUCT:;+      {+	unsigned int base_elt = 0, total_elnum = 0;+	ffi_type **el = t->elements;+	while (*el)+	  {+	    unsigned int el_elt, el_elnum = 0;+	    el_elt = discover_homogeneous_aggregate (abi, *el, &el_elnum);+	    if (el_elt == 0+		|| (base_elt && base_elt != el_elt))+	      return 0;+	    base_elt = el_elt;+	    total_elnum += el_elnum;+#if _CALL_ELF == 2+	    if (total_elnum > 8)+	      return 0;+#else+	    if (total_elnum > 1)+	      return 0;+#endif+	    el++;+	  }+	*elnum = total_elnum;+	return base_elt;+      }++    default:+      return 0;+    }+}+++/* Perform machine dependent cif processing */+static ffi_status+ffi_prep_cif_linux64_core (ffi_cif *cif)+{+  ffi_type **ptr;+  unsigned bytes;+  unsigned i, fparg_count = 0, intarg_count = 0, vecarg_count = 0;+  unsigned flags = cif->flags;+  unsigned elt, elnum, rtype;++#if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE+  /* If compiled without long double support... */+  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0 ||+      (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+    return FFI_BAD_ABI;+#elif !defined(__VEC__)+  /* If compiled without vector register support (used by assembly)... */+  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+    return FFI_BAD_ABI;+#else+  /* If the IEEE128 flag is set, but long double is only 64 bits wide... */+  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) == 0 &&+      (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+    return FFI_BAD_ABI;+#endif++  /* The machine-independent calculation of cif->bytes doesn't work+     for us.  Redo the calculation.  */+#if _CALL_ELF == 2+  /* Space for backchain, CR, LR, TOC and the asm's temp regs.  */+  bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long);++  /* Space for the general registers.  */+  bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long);+#else+  /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp+     regs.  */+  bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);++  /* Space for the mandatory parm save area and general registers.  */+  bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);+#endif++  /* Return value handling.  */+  rtype = cif->rtype->type;+#if _CALL_ELF == 2+homogeneous:+#endif+  switch (rtype)+    {+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+    case FFI_TYPE_LONGDOUBLE:+      if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+        {+          flags |= FLAG_RETURNS_VEC;+          break;+        }+      if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)+	flags |= FLAG_RETURNS_128BITS;+      /* Fall through.  */+#endif+    case FFI_TYPE_DOUBLE:+      flags |= FLAG_RETURNS_64BITS;+      /* Fall through.  */+    case FFI_TYPE_FLOAT:+      flags |= FLAG_RETURNS_FP;+      break;++    case FFI_TYPE_UINT128:+      flags |= FLAG_RETURNS_128BITS;+      /* Fall through.  */+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_POINTER:+      flags |= FLAG_RETURNS_64BITS;+      break;++    case FFI_TYPE_STRUCT:+#if _CALL_ELF == 2+      elt = discover_homogeneous_aggregate (cif->abi, cif->rtype, &elnum);+      if (elt)+        {+          flags |= FLAG_RETURNS_SMST;+          rtype = elt;+          goto homogeneous;+        }+      if (cif->rtype->size <= 16)+        {+          flags |= FLAG_RETURNS_SMST;+          break;+        }+#endif+      intarg_count++;+      flags |= FLAG_RETVAL_REFERENCE;+      /* Fall through.  */+    case FFI_TYPE_VOID:+      flags |= FLAG_RETURNS_NOTHING;+      break;++    default:+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */+      break;+    }++  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)+    {+      unsigned int align;++      switch ((*ptr)->type)+	{+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+          if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+            {+              vecarg_count++;+              /* Align to 16 bytes, plus the 16-byte argument. */+              intarg_count = (intarg_count + 3) & ~0x1;+              if (vecarg_count > NUM_VEC_ARG_REGISTERS64)+                flags |= FLAG_ARG_NEEDS_PSAVE;+              break;+            }+	  if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)+	    {+	      fparg_count++;+	      intarg_count++;+	    }+	  /* Fall through.  */+#endif+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_FLOAT:+	  fparg_count++;+	  intarg_count++;+	  if (fparg_count > NUM_FPR_ARG_REGISTERS64)+	    flags |= FLAG_ARG_NEEDS_PSAVE;+	  break;++	case FFI_TYPE_STRUCT:+	  if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0)+	    {+	      align = (*ptr)->alignment;+	      if (align > 16)+		align = 16;+	      align = align / 8;+	      if (align > 1)+		intarg_count = FFI_ALIGN (intarg_count, align);+	    }+	  intarg_count += ((*ptr)->size + 7) / 8;+	  elt = discover_homogeneous_aggregate (cif->abi, *ptr, &elnum);+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+          if (elt == FFI_TYPE_LONGDOUBLE &&+              (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+            {+              vecarg_count += elnum;+              if (vecarg_count > NUM_VEC_ARG_REGISTERS64)+                flags |= FLAG_ARG_NEEDS_PSAVE;+              break;+            }+	  else+#endif+	  if (elt)+	    {+	      fparg_count += elnum;+	      if (fparg_count > NUM_FPR_ARG_REGISTERS64)+		flags |= FLAG_ARG_NEEDS_PSAVE;+	    }+	  else+	    {+	      if (intarg_count > NUM_GPR_ARG_REGISTERS64)+		flags |= FLAG_ARG_NEEDS_PSAVE;+	    }+	  break;++	case FFI_TYPE_POINTER:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_INT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	  /* Everything else is passed as a 8-byte word in a GPR, either+	     the object itself or a pointer to it.  */+	  intarg_count++;+	  if (intarg_count > NUM_GPR_ARG_REGISTERS64)+	    flags |= FLAG_ARG_NEEDS_PSAVE;+	  break;+	default:+	  FFI_ASSERT (0);+	}+    }++  if (fparg_count != 0)+    flags |= FLAG_FP_ARGUMENTS;+  if (intarg_count > 4)+    flags |= FLAG_4_GPR_ARGUMENTS;+  if (vecarg_count != 0)+    flags |= FLAG_VEC_ARGUMENTS;++  /* Space for the FPR registers, if needed.  */+  if (fparg_count != 0)+    bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);+  /* Space for the vector registers, if needed, aligned to 16 bytes. */+  if (vecarg_count != 0) {+    bytes = (bytes + 15) & ~0xF;+    bytes += NUM_VEC_ARG_REGISTERS64 * sizeof (float128);+  }++  /* Stack space.  */+#if _CALL_ELF == 2+  if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0)+    bytes += intarg_count * sizeof (long);+#else+  if (intarg_count > NUM_GPR_ARG_REGISTERS64)+    bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);+#endif++  /* The stack space allocated needs to be a multiple of 16 bytes.  */+  bytes = (bytes + 15) & ~0xF;++  cif->flags = flags;+  cif->bytes = bytes;++  return FFI_OK;+}++ffi_status FFI_HIDDEN+ffi_prep_cif_linux64 (ffi_cif *cif)+{+  if ((cif->abi & FFI_LINUX) != 0)+    cif->nfixedargs = cif->nargs;+#if _CALL_ELF != 2+  else if (cif->abi == FFI_COMPAT_LINUX64)+    {+      /* This call is from old code.  Don't touch cif->nfixedargs+	 since old code will be using a smaller cif.  */+      cif->flags |= FLAG_COMPAT;+      /* Translate to new abi value.  */+      cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128;+    }+#endif+  else+    return FFI_BAD_ABI;+  return ffi_prep_cif_linux64_core (cif);+}++ffi_status FFI_HIDDEN+ffi_prep_cif_linux64_var (ffi_cif *cif,+			  unsigned int nfixedargs,+			  unsigned int ntotalargs MAYBE_UNUSED)+{+  if ((cif->abi & FFI_LINUX) != 0)+    cif->nfixedargs = nfixedargs;+#if _CALL_ELF != 2+  else if (cif->abi == FFI_COMPAT_LINUX64)+    {+      /* This call is from old code.  Don't touch cif->nfixedargs+	 since old code will be using a smaller cif.  */+      cif->flags |= FLAG_COMPAT;+      /* Translate to new abi value.  */+      cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128;+    }+#endif+  else+    return FFI_BAD_ABI;+#if _CALL_ELF == 2+  cif->flags |= FLAG_ARG_NEEDS_PSAVE;+#endif+  return ffi_prep_cif_linux64_core (cif);+}+++/* ffi_prep_args64 is called by the assembly routine once stack space+   has been allocated for the function's arguments.++   The stack layout we want looks like this:++   |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses+   |--------------------------------------------|+   |   CR save area			8bytes	|+   |--------------------------------------------|+   |   Previous backchain pointer	8	|	stack pointer here+   |--------------------------------------------|<+ <<<	on entry to+   |   Saved r28-r31			4*8	| |	ffi_call_LINUX64+   |--------------------------------------------| |+   |   GPR registers r3-r10		8*8	| |+   |--------------------------------------------| |+   |   FPR registers f1-f13 (optional)	13*8	| |+   |--------------------------------------------| |+   |   VEC registers v2-v13 (optional)  12*16   | |+   |--------------------------------------------| |+   |   Parameter save area		        | |+   |--------------------------------------------| |+   |   TOC save area			8	| |+   |--------------------------------------------| |	stack	|+   |   Linker doubleword		8	| |	grows	|+   |--------------------------------------------| |	down	V+   |   Compiler doubleword		8	| |+   |--------------------------------------------| |	lower addresses+   |   Space for callee's LR		8	| |+   |--------------------------------------------| |+   |   CR save area			8	| |+   |--------------------------------------------| |	stack pointer here+   |   Current backchain pointer	8	|-/	during+   |--------------------------------------------|   <<<	ffi_call_LINUX64++*/++void FFI_HIDDEN+ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)+{+  const unsigned long bytes = ecif->cif->bytes;+  const unsigned long flags = ecif->cif->flags;++  typedef union+  {+    char *c;+    unsigned long *ul;+    float *f;+    double *d;+    float128 *f128;+    size_t p;+  } valp;++  /* 'stacktop' points at the previous backchain pointer.  */+  valp stacktop;++  /* 'next_arg' points at the space for gpr3, and grows upwards as+     we use GPR registers, then continues at rest.  */+  valp gpr_base;+  valp gpr_end;+  valp rest;+  valp next_arg;++  /* 'fpr_base' points at the space for f1, and grows upwards as+     we use FPR registers.  */+  valp fpr_base;+  unsigned int fparg_count;++  /* 'vec_base' points at the space for v2, and grows upwards as+     we use vector registers.  */+  valp vec_base;+  unsigned int vecarg_count;++  unsigned int i, words, nargs, nfixedargs;+  ffi_type **ptr;+  double double_tmp;+  union+  {+    void **v;+    char **c;+    signed char **sc;+    unsigned char **uc;+    signed short **ss;+    unsigned short **us;+    signed int **si;+    unsigned int **ui;+    unsigned long **ul;+    float **f;+    double **d;+    float128 **f128;+  } p_argv;+  unsigned long gprvalue;+  unsigned long align;++  stacktop.c = (char *) stack + bytes;+  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;+  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;+#if _CALL_ELF == 2+  rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64;+#else+  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;+#endif+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;+  fparg_count = 0;+  /* Place the vector args below the FPRs, if used, else the GPRs. */+  if (ecif->cif->flags & FLAG_FP_ARGUMENTS)+    vec_base.p = fpr_base.p & ~0xF;+  else+    vec_base.p = gpr_base.p;+  vec_base.f128 -= NUM_VEC_ARG_REGISTERS64;+  vecarg_count = 0;+  next_arg.ul = gpr_base.ul;++  /* Check that everything starts aligned properly.  */+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);+  FFI_ASSERT (((unsigned long) gpr_base.c & 0xF) == 0);+  FFI_ASSERT (((unsigned long) gpr_end.c  & 0xF) == 0);+  FFI_ASSERT (((unsigned long) vec_base.c & 0xF) == 0);+  FFI_ASSERT ((bytes & 0xF) == 0);++  /* Deal with return values that are actually pass-by-reference.  */+  if (flags & FLAG_RETVAL_REFERENCE)+    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;++  /* Now for the arguments.  */+  p_argv.v = ecif->avalue;+  nargs = ecif->cif->nargs;+#if _CALL_ELF != 2+  nfixedargs = (unsigned) -1;+  if ((flags & FLAG_COMPAT) == 0)+#endif+    nfixedargs = ecif->cif->nfixedargs;+  for (ptr = ecif->cif->arg_types, i = 0;+       i < nargs;+       i++, ptr++, p_argv.v++)+    {+      unsigned int elt, elnum;++      switch ((*ptr)->type)+	{+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+          if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+            {+              next_arg.p = FFI_ALIGN (next_arg.p, 16);+              if (next_arg.ul == gpr_end.ul)+                next_arg.ul = rest.ul;+              if (vecarg_count < NUM_VEC_ARG_REGISTERS64 && i < nfixedargs)+		memcpy (vec_base.f128++, *p_argv.f128, sizeof (float128));+              else+		memcpy (next_arg.f128, *p_argv.f128, sizeof (float128));+              if (++next_arg.f128 == gpr_end.f128)+                next_arg.f128 = rest.f128;+              vecarg_count++;+              FFI_ASSERT (__LDBL_MANT_DIG__ == 113);+              FFI_ASSERT (flags & FLAG_VEC_ARGUMENTS);+              break;+            }+	  if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)+	    {+	      double_tmp = (*p_argv.d)[0];+	      if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)+		{+		  *fpr_base.d++ = double_tmp;+# if _CALL_ELF != 2+		  if ((flags & FLAG_COMPAT) != 0)+		    *next_arg.d = double_tmp;+# endif+		}+	      else+		*next_arg.d = double_tmp;+	      if (++next_arg.ul == gpr_end.ul)+		next_arg.ul = rest.ul;+	      fparg_count++;+	      double_tmp = (*p_argv.d)[1];+	      if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)+		{+		  *fpr_base.d++ = double_tmp;+# if _CALL_ELF != 2+		  if ((flags & FLAG_COMPAT) != 0)+		    *next_arg.d = double_tmp;+# endif+		}+	      else+		*next_arg.d = double_tmp;+	      if (++next_arg.ul == gpr_end.ul)+		next_arg.ul = rest.ul;+	      fparg_count++;+	      FFI_ASSERT (__LDBL_MANT_DIG__ == 106);+	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);+	      break;+	    }+	  /* Fall through.  */+#endif+	case FFI_TYPE_DOUBLE:+#if _CALL_ELF != 2+	do_double:+#endif+	  double_tmp = **p_argv.d;+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)+	    {+	      *fpr_base.d++ = double_tmp;+#if _CALL_ELF != 2+	      if ((flags & FLAG_COMPAT) != 0)+		*next_arg.d = double_tmp;+#endif+	    }+	  else+	    *next_arg.d = double_tmp;+	  if (++next_arg.ul == gpr_end.ul)+	    next_arg.ul = rest.ul;+	  fparg_count++;+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);+	  break;++	case FFI_TYPE_FLOAT:+#if _CALL_ELF != 2+	do_float:+#endif+	  double_tmp = **p_argv.f;+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)+	    {+	      *fpr_base.d++ = double_tmp;+#if _CALL_ELF != 2+	      if ((flags & FLAG_COMPAT) != 0)+		{+# ifndef __LITTLE_ENDIAN__+		  next_arg.f[1] = (float) double_tmp;+# else+		  next_arg.f[0] = (float) double_tmp;+# endif+		}+#endif+	    }+	  else+	    {+# ifndef __LITTLE_ENDIAN__+	      next_arg.f[1] = (float) double_tmp;+# else+	      next_arg.f[0] = (float) double_tmp;+# endif+	    }+	  if (++next_arg.ul == gpr_end.ul)+	    next_arg.ul = rest.ul;+	  fparg_count++;+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);+	  break;++	case FFI_TYPE_STRUCT:+	  if ((ecif->cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0)+	    {+	      align = (*ptr)->alignment;+	      if (align > 16)+		align = 16;+	      if (align > 1)+                {+                  next_arg.p = FFI_ALIGN (next_arg.p, align);+                  if (next_arg.ul == gpr_end.ul)+                    next_arg.ul = rest.ul;+                }+	    }+	  elt = discover_homogeneous_aggregate (ecif->cif->abi, *ptr, &elnum);+	  if (elt)+	    {+#if _CALL_ELF == 2+	      union {+		void *v;+		float *f;+		double *d;+		float128 *f128;+	      } arg;++	      arg.v = *p_argv.v;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+              if (elt == FFI_TYPE_LONGDOUBLE &&+                  (ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+                {+                  do+                    {+                      if (vecarg_count < NUM_VEC_ARG_REGISTERS64+                          && i < nfixedargs)+		        memcpy (vec_base.f128++, arg.f128++, sizeof (float128));+                      else+		        memcpy (next_arg.f128, arg.f128++, sizeof (float128));+                      if (++next_arg.f128 == gpr_end.f128)+                        next_arg.f128 = rest.f128;+                      vecarg_count++;+                    }+                  while (--elnum != 0);+                }+              else+#endif+	      if (elt == FFI_TYPE_FLOAT)+		{+		  do+		    {+		      double_tmp = *arg.f++;+		      if (fparg_count < NUM_FPR_ARG_REGISTERS64+			  && i < nfixedargs)+			*fpr_base.d++ = double_tmp;+		      else+			*next_arg.f = (float) double_tmp;+		      if (++next_arg.f == gpr_end.f)+			next_arg.f = rest.f;+		      fparg_count++;+		    }+		  while (--elnum != 0);+		  if ((next_arg.p & 7) != 0)+                    if (++next_arg.f == gpr_end.f)+                      next_arg.f = rest.f;+		}+	      else+		do+		  {+		    double_tmp = *arg.d++;+		    if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)+		      *fpr_base.d++ = double_tmp;+		    else+		      *next_arg.d = double_tmp;+		    if (++next_arg.d == gpr_end.d)+		      next_arg.d = rest.d;+		    fparg_count++;+		  }+		while (--elnum != 0);+#else+	      if (elt == FFI_TYPE_FLOAT)+		goto do_float;+	      else+		goto do_double;+#endif+	    }+	  else+	    {+	      words = ((*ptr)->size + 7) / 8;+	      if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)+		{+		  size_t first = gpr_end.c - next_arg.c;+		  memcpy (next_arg.c, *p_argv.c, first);+		  memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);+		  next_arg.c = rest.c + words * 8 - first;+		}+	      else+		{+		  char *where = next_arg.c;++#ifndef __LITTLE_ENDIAN__+		  /* Structures with size less than eight bytes are passed+		     left-padded.  */+		  if ((*ptr)->size < 8)+		    where += 8 - (*ptr)->size;+#endif+		  memcpy (where, *p_argv.c, (*ptr)->size);+		  next_arg.ul += words;+		  if (next_arg.ul == gpr_end.ul)+		    next_arg.ul = rest.ul;+		}+	    }+	  break;++	case FFI_TYPE_UINT8:+	  gprvalue = **p_argv.uc;+	  goto putgpr;+	case FFI_TYPE_SINT8:+	  gprvalue = **p_argv.sc;+	  goto putgpr;+	case FFI_TYPE_UINT16:+	  gprvalue = **p_argv.us;+	  goto putgpr;+	case FFI_TYPE_SINT16:+	  gprvalue = **p_argv.ss;+	  goto putgpr;+	case FFI_TYPE_UINT32:+	  gprvalue = **p_argv.ui;+	  goto putgpr;+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT32:+	  gprvalue = **p_argv.si;+	  goto putgpr;++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_POINTER:+	  gprvalue = **p_argv.ul;+	putgpr:+	  *next_arg.ul++ = gprvalue;+	  if (next_arg.ul == gpr_end.ul)+	    next_arg.ul = rest.ul;+	  break;+	}+    }++  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS+	      || (next_arg.ul >= gpr_base.ul+		  && next_arg.ul <= gpr_base.ul + 4));+}+++#if _CALL_ELF == 2+#define MIN_CACHE_LINE_SIZE 8++static void+flush_icache (char *wraddr, char *xaddr, int size)+{+  int i;+  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)+    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"+		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");+  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"+		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)+		    : "memory");+}+#endif+++ffi_status FFI_HIDDEN+ffi_prep_closure_loc_linux64 (ffi_closure *closure,+			      ffi_cif *cif,+			      void (*fun) (ffi_cif *, void *, void **, void *),+			      void *user_data,+			      void *codeloc)+{+  if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI)+    return FFI_BAD_ABI;++#ifdef FFI_EXEC_STATIC_TRAMP+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      void (*dest)(void) = ffi_closure_LINUX64;+      ffi_tramp_set_parms (closure->ftramp, dest, closure);+    }+  else+#endif+    {+#if _CALL_ELF == 2+      unsigned int *tramp = (unsigned int *) &closure->tramp[0];+      tramp[0] = 0xe96c0018;	/* 0:	ld	11,2f-0b(12)	*/+      tramp[1] = 0xe98c0010;	/*	ld	12,1f-0b(12)	*/+      tramp[2] = 0x7d8903a6;	/*	mtctr	12		*/+      tramp[3] = 0x4e800420;	/*	bctr			*/+				/* 1:	.quad	function_addr	*/+				/* 2:	.quad	context		*/+      *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;+      *(void **) &tramp[6] = codeloc;+      flush_icache ((char *) tramp, (char *) codeloc, 4 * 4);+#else+      /* Copy function address and TOC from ffi_closure_LINUX64 OPD.  */+      void **tramp = (void **) &closure->tramp[0];+      memcpy (&tramp[0], (void **) ffi_closure_LINUX64, sizeof (void *));+      tramp[1] = codeloc;+      memcpy (&tramp[2], (void **) ffi_closure_LINUX64 + 1, sizeof (void *));+#endif+    }++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}+++int FFI_HIDDEN+ffi_closure_helper_LINUX64 (ffi_cif *cif,+			    void (*fun) (ffi_cif *, void *, void **, void *),+			    void *user_data,+			    void *rvalue,+			    unsigned long *pst,+                            ffi_dblfl *pfr,+                            float128 *pvec)+{+  /* rvalue is the pointer to space for return value in closure assembly */+  /* pst is the pointer to parameter save area+     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */+  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */+  /* pvec is the pointer to where v2-v13 are stored in ffi_closure_LINUX64 */++  void **avalue;+  ffi_type **arg_types;+  unsigned long i, avn, nfixedargs;+  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;+  float128 *end_pvec = pvec + NUM_VEC_ARG_REGISTERS64;+  unsigned long align;++  avalue = alloca (cif->nargs * sizeof (void *));++  /* Copy the caller's structure return value address so that the+     closure returns the data directly to the caller.  */+  if (cif->rtype->type == FFI_TYPE_STRUCT+      && (cif->flags & FLAG_RETURNS_SMST) == 0)+    {+      rvalue = (void *) *pst;+      pst++;+    }++  i = 0;+  avn = cif->nargs;+#if _CALL_ELF != 2+  nfixedargs = (unsigned) -1;+  if ((cif->flags & FLAG_COMPAT) == 0)+#endif+    nfixedargs = cif->nfixedargs;+  arg_types = cif->arg_types;++  /* Grab the addresses of the arguments from the stack frame.  */+  while (i < avn)+    {+      unsigned int elt, elnum;++      switch (arg_types[i]->type)+	{+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+#ifndef __LITTLE_ENDIAN__+	  avalue[i] = (char *) pst + 7;+	  pst++;+	  break;+#endif++	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+#ifndef __LITTLE_ENDIAN__+	  avalue[i] = (char *) pst + 6;+	  pst++;+	  break;+#endif++	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+#ifndef __LITTLE_ENDIAN__+	  avalue[i] = (char *) pst + 4;+	  pst++;+	  break;+#endif++	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_POINTER:+	  avalue[i] = pst;+	  pst++;+	  break;++	case FFI_TYPE_STRUCT:+	  if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0)+	    {+	      align = arg_types[i]->alignment;+	      if (align > 16)+		align = 16;+	      if (align > 1)+		pst = (unsigned long *) FFI_ALIGN ((size_t) pst, align);+	    }+	  elt = discover_homogeneous_aggregate (cif->abi, arg_types[i], &elnum);+	  if (elt)+	    {+#if _CALL_ELF == 2+	      union {+		void *v;+		unsigned long *ul;+		float *f;+		double *d;+		float128 *f128;+		size_t p;+	      } to, from;++	      /* Repackage the aggregate from its parts.  The+		 aggregate size is not greater than the space taken by+		 the registers so store back to the register/parameter+		 save arrays.  */+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+              if (elt == FFI_TYPE_LONGDOUBLE &&+                  (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+                {+                  if (pvec + elnum <= end_pvec)+                    to.v = pvec;+                  else+                    to.v = pst;+                }+              else+#endif+	      if (pfr + elnum <= end_pfr)+		to.v = pfr;+	      else+		to.v = pst;++	      avalue[i] = to.v;+	      from.ul = pst;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+              if (elt == FFI_TYPE_LONGDOUBLE &&+                  (cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+                {+                  do+                    {+                      if (pvec < end_pvec && i < nfixedargs)+		        memcpy (to.f128, pvec++, sizeof (float128));+                      else+		        memcpy (to.f128, from.f128, sizeof (float128));+                      to.f128++;+                      from.f128++;+                    }+                  while (--elnum != 0);+                }+              else+#endif+	      if (elt == FFI_TYPE_FLOAT)+		{+		  do+		    {+		      if (pfr < end_pfr && i < nfixedargs)+			{+			  *to.f = (float) pfr->d;+			  pfr++;+			}+		      else+			*to.f = *from.f;+		      to.f++;+		      from.f++;+		    }+		  while (--elnum != 0);+		}+	      else+		{+		  do+		    {+		      if (pfr < end_pfr && i < nfixedargs)+			{+			  *to.d = pfr->d;+			  pfr++;+			}+		      else+			*to.d = *from.d;+		      to.d++;+		      from.d++;+		    }+		  while (--elnum != 0);+		}+#else+	      if (elt == FFI_TYPE_FLOAT)+		goto do_float;+	      else+		goto do_double;+#endif+	    }+	  else+	    {+#ifndef __LITTLE_ENDIAN__+	      /* Structures with size less than eight bytes are passed+		 left-padded.  */+	      if (arg_types[i]->size < 8)+		avalue[i] = (char *) pst + 8 - arg_types[i]->size;+	      else+#endif+		avalue[i] = pst;+	    }+	  pst += (arg_types[i]->size + 7) / 8;+	  break;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+          if ((cif->abi & FFI_LINUX_LONG_DOUBLE_IEEE128) != 0)+            {+              if (((unsigned long) pst & 0xF) != 0)+                ++pst;+              if (pvec < end_pvec && i < nfixedargs)+                avalue[i] = pvec++;+              else+                avalue[i] = pst;+              pst += 2;+              break;+            }+          else if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0)+	    {+	      if (pfr + 1 < end_pfr && i + 1 < nfixedargs)+		{+		  avalue[i] = pfr;+		  pfr += 2;+		}+	      else+		{+		  if (pfr < end_pfr && i < nfixedargs)+		    {+		      /* Passed partly in f13 and partly on the stack.+			 Move it all to the stack.  */+		      *pst = *(unsigned long *) pfr;+		      pfr++;+		    }+		  avalue[i] = pst;+		}+	      pst += 2;+	      break;+	    }+	  /* Fall through.  */+#endif+	case FFI_TYPE_DOUBLE:+#if _CALL_ELF != 2+	do_double:+#endif+	  /* On the outgoing stack all values are aligned to 8 */+	  /* there are 13 64bit floating point registers */++	  if (pfr < end_pfr && i < nfixedargs)+	    {+	      avalue[i] = pfr;+	      pfr++;+	    }+	  else+	    avalue[i] = pst;+	  pst++;+	  break;++	case FFI_TYPE_FLOAT:+#if _CALL_ELF != 2+	do_float:+#endif+	  if (pfr < end_pfr && i < nfixedargs)+	    {+	      /* Float values are stored as doubles in the+		 ffi_closure_LINUX64 code.  Fix them here.  */+	      pfr->f = (float) pfr->d;+	      avalue[i] = pfr;+	      pfr++;+	    }+	  else+	    {+#ifndef __LITTLE_ENDIAN__+	      avalue[i] = (char *) pst + 4;+#else+	      avalue[i] = pst;+#endif+	    }+	  pst++;+	  break;++	default:+	  FFI_ASSERT (0);+	}++      i++;+    }++  (*fun) (cif, rvalue, avalue, user_data);++  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)+    {+      if ((cif->flags & (FLAG_RETURNS_FP | FLAG_RETURNS_VEC)) == 0)+	return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1;+      else if ((cif->flags & FLAG_RETURNS_VEC) != 0)+        return FFI_V2_TYPE_VECTOR_HOMOG;+      else if ((cif->flags & FLAG_RETURNS_64BITS) != 0)+	return FFI_V2_TYPE_DOUBLE_HOMOG;+      else+	return FFI_V2_TYPE_FLOAT_HOMOG;+    }+  if ((cif->flags & FLAG_RETURNS_VEC) != 0)+    return FFI_V2_TYPE_VECTOR;+  return cif->rtype->type;+}+#endif
+ src/powerpc/ffi_powerpc.h view
@@ -0,0 +1,105 @@+/* -----------------------------------------------------------------------+   ffi_powerpc.h - Copyright (C) 2013 IBM+                   Copyright (C) 2011 Anthony Green+                   Copyright (C) 2011 Kyle Moffett+                   Copyright (C) 2008 Red Hat, Inc+                   Copyright (C) 2007, 2008 Free Software Foundation, Inc+                   Copyright (c) 1998 Geoffrey Keating++   PowerPC 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 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.+   ----------------------------------------------------------------------- */++enum {+  /* The assembly depends on these exact flags.  */+  /* These go in cr7 */+  FLAG_RETURNS_SMST     = 1 << (31-31), /* Used for FFI_SYSV small structs.  */+  FLAG_RETURNS_NOTHING  = 1 << (31-30),+  FLAG_RETURNS_FP       = 1 << (31-29),+  FLAG_RETURNS_VEC      = 1 << (31-28),++  /* These go in cr6 */+  FLAG_RETURNS_64BITS   = 1 << (31-27),+  FLAG_RETURNS_128BITS  = 1 << (31-26),++  FLAG_COMPAT           = 1 << (31- 8), /* Not used by assembly */++  /* These go in cr1 */+  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7), /* Used by sysv code */+  FLAG_ARG_NEEDS_PSAVE  = FLAG_ARG_NEEDS_COPY, /* Used by linux64 code */+  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */+  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),+  FLAG_RETVAL_REFERENCE = 1 << (31- 4),+  FLAG_VEC_ARGUMENTS    = 1 << (31- 3),+};++typedef union+{+  float f;+  double d;+} ffi_dblfl;++#if defined(__FLOAT128_TYPE__) && defined(__HAVE_FLOAT128)+typedef _Float128 float128;+#elif defined(__FLOAT128__)+typedef __float128 float128;+#else+typedef char float128[16] __attribute__((aligned(16)));+#endif++void FFI_HIDDEN ffi_closure_SYSV (void);+void FFI_HIDDEN ffi_go_closure_sysv (void);+void FFI_HIDDEN ffi_call_SYSV(extended_cif *, void (*)(void), void *,+			      unsigned, void *, int);++void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi);+ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *);+ffi_status FFI_HIDDEN ffi_prep_closure_loc_sysv (ffi_closure *,+						 ffi_cif *,+						 void (*) (ffi_cif *, void *,+							   void **, void *),+						 void *, void *);+int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_cif *,+					void (*) (ffi_cif *, void *,+						  void **, void *),+					void *, void *, unsigned long *,+					ffi_dblfl *, unsigned long *);++void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, void (*) (void), void *,+				 unsigned long, void *, long);+void FFI_HIDDEN ffi_closure_LINUX64 (void);+void FFI_HIDDEN ffi_go_closure_linux64 (void);++void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi);+ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *);+ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int,+						unsigned int);+void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const);+ffi_status FFI_HIDDEN ffi_prep_closure_loc_linux64 (ffi_closure *, ffi_cif *,+						    void (*) (ffi_cif *, void *,+							      void **, void *),+						    void *, void *);+int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_cif *,+					   void (*) (ffi_cif *, void *,+						     void **, void *),+					   void *, void *,+					   unsigned long *, ffi_dblfl *,+					   float128 *);
+ src/powerpc/ffi_sysv.c view
@@ -0,0 +1,933 @@+/* -----------------------------------------------------------------------+   ffi_sysv.c - Copyright (C) 2013 IBM+                Copyright (C) 2011 Anthony Green+                Copyright (C) 2011 Kyle Moffett+                Copyright (C) 2008 Red Hat, Inc+                Copyright (C) 2007, 2008 Free Software Foundation, Inc+                Copyright (c) 1998 Geoffrey Keating++   PowerPC 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 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.+   ----------------------------------------------------------------------- */++#include "ffi.h"+#include <tramp.h>++#ifndef POWERPC64+#include "ffi_common.h"+#include "ffi_powerpc.h"+++/* About the SYSV ABI.  */+#define ASM_NEEDS_REGISTERS 6+#define NUM_GPR_ARG_REGISTERS 8+#define NUM_FPR_ARG_REGISTERS 8+++#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+/* Adjust size of ffi_type_longdouble.  */+void FFI_HIDDEN+ffi_prep_types_sysv (ffi_abi abi)+{+  if ((abi & (FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128)) == FFI_SYSV)+    {+      ffi_type_longdouble.size = 8;+      ffi_type_longdouble.alignment = 8;+    }+  else+    {+      ffi_type_longdouble.size = 16;+      ffi_type_longdouble.alignment = 16;+    }+}+#endif++/* Transform long double, double and float to other types as per abi.  */+static int+translate_float (int abi, int type)+{+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+  if (type == FFI_TYPE_LONGDOUBLE+      && (abi & FFI_SYSV_LONG_DOUBLE_128) == 0)+    type = FFI_TYPE_DOUBLE;+#endif+  if ((abi & FFI_SYSV_SOFT_FLOAT) != 0)+    {+      if (type == FFI_TYPE_FLOAT)+	type = FFI_TYPE_UINT32;+      else if (type == FFI_TYPE_DOUBLE)+	type = FFI_TYPE_UINT64;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+      else if (type == FFI_TYPE_LONGDOUBLE)+	type = FFI_TYPE_UINT128;+    }+  else if ((abi & FFI_SYSV_IBM_LONG_DOUBLE) == 0)+    {+      if (type == FFI_TYPE_LONGDOUBLE)+	type = FFI_TYPE_STRUCT;+#endif+    }+  return type;+}++/* Perform machine dependent cif processing */+static ffi_status+ffi_prep_cif_sysv_core (ffi_cif *cif)+{+  ffi_type **ptr;+  unsigned bytes;+  unsigned i, fpr_count = 0, gpr_count = 0, stack_count = 0;+  unsigned flags = cif->flags;+  unsigned struct_copy_size = 0;+  unsigned type = cif->rtype->type;+  unsigned size = cif->rtype->size;++  /* The machine-independent calculation of cif->bytes doesn't work+     for us.  Redo the calculation.  */++  /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */+  bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);++  /* Space for the GPR registers.  */+  bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);++  /* Return value handling.  The rules for SYSV are as follows:+     - 32-bit (or less) integer values are returned in gpr3;+     - Structures of size <= 4 bytes also returned in gpr3;+     - 64-bit integer values and structures between 5 and 8 bytes are returned+     in gpr3 and gpr4;+     - Larger structures are allocated space and a pointer is passed as+     the first argument.+     - Single/double FP values are returned in fpr1;+     - long doubles (if not equivalent to double) are returned in+     fpr1,fpr2 for Linux and as for large structs for SysV.  */++  type = translate_float (cif->abi, type);++  switch (type)+    {+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+    case FFI_TYPE_LONGDOUBLE:+      flags |= FLAG_RETURNS_128BITS;+      /* Fall through.  */+#endif+    case FFI_TYPE_DOUBLE:+      flags |= FLAG_RETURNS_64BITS;+      /* Fall through.  */+    case FFI_TYPE_FLOAT:+      flags |= FLAG_RETURNS_FP;+#ifdef __NO_FPRS__+      return FFI_BAD_ABI;+#endif+      break;++    case FFI_TYPE_UINT128:+      flags |= FLAG_RETURNS_128BITS;+      /* Fall through.  */+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      flags |= FLAG_RETURNS_64BITS;+      break;++    case FFI_TYPE_STRUCT:+      /* The final SYSV ABI says that structures smaller or equal 8 bytes+	 are returned in r3/r4.  A draft ABI used by linux instead+	 returns them in memory.  */+      if ((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)+	{+	  flags |= FLAG_RETURNS_SMST;+	  break;+	}+      gpr_count++;+      flags |= FLAG_RETVAL_REFERENCE;+      /* Fall through.  */+    case FFI_TYPE_VOID:+      flags |= FLAG_RETURNS_NOTHING;+      break;++    default:+      /* Returns 32-bit integer, or similar.  Nothing to do here.  */+      break;+    }++  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the+     first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest+     goes on the stack.  Structures and long doubles (if not equivalent+     to double) are passed as a pointer to a copy of the structure.+     Stuff on the stack needs to keep proper alignment.  */+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)+    {+      unsigned short typenum = (*ptr)->type;++      typenum = translate_float (cif->abi, typenum);++      switch (typenum)+	{+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+	  if (fpr_count >= NUM_FPR_ARG_REGISTERS - 1)+	    {+	      fpr_count = NUM_FPR_ARG_REGISTERS;+	      /* 8-byte align long doubles.  */+	      stack_count += stack_count & 1;+	      stack_count += 4;+	    }+	  else+	    fpr_count += 2;+#ifdef __NO_FPRS__+	  return FFI_BAD_ABI;+#endif+	  break;+#endif++	case FFI_TYPE_DOUBLE:+	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)+	    {+	      /* 8-byte align doubles.  */+	      stack_count += stack_count & 1;+	      stack_count += 2;+	    }+	  else+	    fpr_count += 1;+#ifdef __NO_FPRS__+	  return FFI_BAD_ABI;+#endif+	  break;++	case FFI_TYPE_FLOAT:+	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)+	    /* Yes, we don't follow the ABI, but neither does gcc.  */+	    stack_count += 1;+	  else+	    fpr_count += 1;+#ifdef __NO_FPRS__+	  return FFI_BAD_ABI;+#endif+	  break;++	case FFI_TYPE_UINT128:+	  /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set+	     of four consecutive gprs. If we do not have enough, we+	     have to adjust the gpr_count value.  */+	  if (gpr_count >= NUM_GPR_ARG_REGISTERS - 3)+	    gpr_count = NUM_GPR_ARG_REGISTERS;+	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)+	    stack_count += 4;+	  else+	    gpr_count += 4;+	  break;++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	  /* 'long long' arguments are passed as two words, but+	     either both words must fit in registers or both go+	     on the stack.  If they go on the stack, they must+	     be 8-byte-aligned.++	     Also, only certain register pairs can be used for+	     passing long long int -- specifically (r3,r4), (r5,r6),+	     (r7,r8), (r9,r10).  */+	  gpr_count += gpr_count & 1;+	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)+	    {+	      stack_count += stack_count & 1;+	      stack_count += 2;+	    }+	  else+	    gpr_count += 2;+	  break;++	case FFI_TYPE_STRUCT:+	  /* We must allocate space for a copy of these to enforce+	     pass-by-value.  Pad the space up to a multiple of 16+	     bytes (the maximum alignment required for anything under+	     the SYSV ABI).  */+	  struct_copy_size += ((*ptr)->size + 15) & ~0xF;+	  /* Fall through (allocate space for the pointer).  */++	case FFI_TYPE_POINTER:+	case FFI_TYPE_INT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	  /* Everything else is passed as a 4-byte word in a GPR, either+	     the object itself or a pointer to it.  */+	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)+	    stack_count += 1;+	  else+	    gpr_count += 1;+	  break;++	default:+	  FFI_ASSERT (0);+	}+    }++  if (fpr_count != 0)+    flags |= FLAG_FP_ARGUMENTS;+  if (gpr_count > 4)+    flags |= FLAG_4_GPR_ARGUMENTS;+  if (struct_copy_size != 0)+    flags |= FLAG_ARG_NEEDS_COPY;++  /* Space for the FPR registers, if needed.  */+  if (fpr_count != 0)+    bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);++  /* Stack space.  */+  bytes += stack_count * sizeof (int);++  /* The stack space allocated needs to be a multiple of 16 bytes.  */+  bytes = (bytes + 15) & ~0xF;++  /* Add in the space for the copied structures.  */+  bytes += struct_copy_size;++  cif->flags = flags;+  cif->bytes = bytes;++  return FFI_OK;+}++ffi_status FFI_HIDDEN+ffi_prep_cif_sysv (ffi_cif *cif)+{+  if ((cif->abi & FFI_SYSV) == 0)+    {+      /* This call is from old code.  Translate to new ABI values.  */+      cif->flags |= FLAG_COMPAT;+      switch (cif->abi)+	{+	default:+	  return FFI_BAD_ABI;++	case FFI_COMPAT_SYSV:+	  cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128;+	  break;++	case FFI_COMPAT_GCC_SYSV:+	  cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128;+	  break;++	case FFI_COMPAT_LINUX:+	  cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE+		      | FFI_SYSV_LONG_DOUBLE_128);+	  break;++	case FFI_COMPAT_LINUX_SOFT_FLOAT:+	  cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE+		      | FFI_SYSV_LONG_DOUBLE_128);+	  break;+	}+    }+  return ffi_prep_cif_sysv_core (cif);+}++/* ffi_prep_args_SYSV is called by the assembly routine once stack space+   has been allocated for the function's arguments.++   The stack layout we want looks like this:++   |   Return address from ffi_call_SYSV 4bytes	|	higher addresses+   |--------------------------------------------|+   |   Previous backchain pointer	4	|       stack pointer here+   |--------------------------------------------|<+ <<<	on entry to+   |   Saved r28-r31			4*4	| |	ffi_call_SYSV+   |--------------------------------------------| |+   |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV+   |--------------------------------------------| |+   |   FPR registers f1-f8 (optional)	8*8	| |+   |--------------------------------------------| |	stack	|+   |   Space for copied structures		| |	grows	|+   |--------------------------------------------| |	down    V+   |   Parameters that didn't fit in registers  | |+   |--------------------------------------------| |	lower addresses+   |   Space for callee's LR		4	| |+   |--------------------------------------------| |	stack pointer here+   |   Current backchain pointer	4	|-/	during+   |--------------------------------------------|   <<<	ffi_call_SYSV++*/++void FFI_HIDDEN+ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)+{+  const unsigned bytes = ecif->cif->bytes;+  const unsigned flags = ecif->cif->flags;++  typedef union+  {+    char *c;+    unsigned *u;+    long long *ll;+    float *f;+    double *d;+  } valp;++  /* 'stacktop' points at the previous backchain pointer.  */+  valp stacktop;++  /* 'gpr_base' points at the space for gpr3, and grows upwards as+     we use GPR registers.  */+  valp gpr_base;+  valp gpr_end;++#ifndef __NO_FPRS__+  /* 'fpr_base' points at the space for fpr1, and grows upwards as+     we use FPR registers.  */+  valp fpr_base;+  valp fpr_end;+#endif++  /* 'copy_space' grows down as we put structures in it.  It should+     stay 16-byte aligned.  */+  valp copy_space;++  /* 'next_arg' grows up as we put parameters in it.  */+  valp next_arg;++  int i;+  ffi_type **ptr;+#ifndef __NO_FPRS__+  double double_tmp;+#endif+  union+  {+    void **v;+    char **c;+    signed char **sc;+    unsigned char **uc;+    signed short **ss;+    unsigned short **us;+    unsigned int **ui;+    long long **ll;+    float **f;+    double **d;+  } p_argv;+  size_t struct_copy_size;+  unsigned gprvalue;++  stacktop.c = (char *) stack + bytes;+  gpr_end.u = stacktop.u - ASM_NEEDS_REGISTERS;+  gpr_base.u = gpr_end.u - NUM_GPR_ARG_REGISTERS;+#ifndef __NO_FPRS__+  fpr_end.d = gpr_base.d;+  fpr_base.d = fpr_end.d - NUM_FPR_ARG_REGISTERS;+  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);+#else+  copy_space.c = gpr_base.c;+#endif+  next_arg.u = stack + 2;++  /* Check that everything starts aligned properly.  */+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);+  FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);+  FFI_ASSERT ((bytes & 0xF) == 0);+  FFI_ASSERT (copy_space.c >= next_arg.c);++  /* Deal with return values that are actually pass-by-reference.  */+  if (flags & FLAG_RETVAL_REFERENCE)+    *gpr_base.u++ = (unsigned) (char *) ecif->rvalue;++  /* Now for the arguments.  */+  p_argv.v = ecif->avalue;+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;+       i > 0;+       i--, ptr++, p_argv.v++)+    {+      unsigned int typenum = (*ptr)->type;++      typenum = translate_float (ecif->cif->abi, typenum);++      /* Now test the translated value */+      switch (typenum)+	{+#ifndef __NO_FPRS__+# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+	  double_tmp = (*p_argv.d)[0];++	  if (fpr_base.d >= fpr_end.d - 1)+	    {+	      fpr_base.d = fpr_end.d;+	      if (((next_arg.u - stack) & 1) != 0)+		next_arg.u += 1;+	      *next_arg.d = double_tmp;+	      next_arg.u += 2;+	      double_tmp = (*p_argv.d)[1];+	      *next_arg.d = double_tmp;+	      next_arg.u += 2;+	    }+	  else+	    {+	      *fpr_base.d++ = double_tmp;+	      double_tmp = (*p_argv.d)[1];+	      *fpr_base.d++ = double_tmp;+	    }+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);+	  break;+# endif+	case FFI_TYPE_DOUBLE:+	  double_tmp = **p_argv.d;++	  if (fpr_base.d >= fpr_end.d)+	    {+	      if (((next_arg.u - stack) & 1) != 0)+		next_arg.u += 1;+	      *next_arg.d = double_tmp;+	      next_arg.u += 2;+	    }+	  else+	    *fpr_base.d++ = double_tmp;+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);+	  break;++	case FFI_TYPE_FLOAT:+	  double_tmp = **p_argv.f;+	  if (fpr_base.d >= fpr_end.d)+	    {+	      *next_arg.f = (float) double_tmp;+	      next_arg.u += 1;+	    }+	  else+	    *fpr_base.d++ = double_tmp;+	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);+	  break;+#endif /* have FPRs */++	case FFI_TYPE_UINT128:+	  /* The soft float ABI for long doubles works like this, a long double+	     is passed in four consecutive GPRs if available.  A maximum of 2+	     long doubles can be passed in gprs.  If we do not have 4 GPRs+	     left, the long double is passed on the stack, 4-byte aligned.  */+	  if (gpr_base.u >= gpr_end.u - 3)+	    {+	      unsigned int ii;+	      gpr_base.u = gpr_end.u;+	      for (ii = 0; ii < 4; ii++)+		{+		  unsigned int int_tmp = (*p_argv.ui)[ii];+		  *next_arg.u++ = int_tmp;+		}+	    }+	  else+	    {+	      unsigned int ii;+	      for (ii = 0; ii < 4; ii++)+		{+		  unsigned int int_tmp = (*p_argv.ui)[ii];+		  *gpr_base.u++ = int_tmp;+		}+	    }+	  break;++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	  if (gpr_base.u >= gpr_end.u - 1)+	    {+	      gpr_base.u = gpr_end.u;+	      if (((next_arg.u - stack) & 1) != 0)+		next_arg.u++;+	      *next_arg.ll = **p_argv.ll;+	      next_arg.u += 2;+	    }+	  else+	    {+	      /* The abi states only certain register pairs can be+		 used for passing long long int specifically (r3,r4),+		 (r5,r6), (r7,r8), (r9,r10).  If next arg is long long+		 but not correct starting register of pair then skip+		 until the proper starting register.  */+	      if (((gpr_end.u - gpr_base.u) & 1) != 0)+		gpr_base.u++;+	      *gpr_base.ll++ = **p_argv.ll;+	    }+	  break;++	case FFI_TYPE_STRUCT:+	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;+	  copy_space.c -= struct_copy_size;+	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);++	  gprvalue = (unsigned long) copy_space.c;++	  FFI_ASSERT (copy_space.c > next_arg.c);+	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);+	  goto putgpr;++	case FFI_TYPE_UINT8:+	  gprvalue = **p_argv.uc;+	  goto putgpr;+	case FFI_TYPE_SINT8:+	  gprvalue = **p_argv.sc;+	  goto putgpr;+	case FFI_TYPE_UINT16:+	  gprvalue = **p_argv.us;+	  goto putgpr;+	case FFI_TYPE_SINT16:+	  gprvalue = **p_argv.ss;+	  goto putgpr;++	case FFI_TYPE_INT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_POINTER:++	  gprvalue = **p_argv.ui;++	putgpr:+	  if (gpr_base.u >= gpr_end.u)+	    *next_arg.u++ = gprvalue;+	  else+	    *gpr_base.u++ = gprvalue;+	  break;+	}+    }++  /* Check that we didn't overrun the stack...  */+  FFI_ASSERT (copy_space.c >= next_arg.c);+  FFI_ASSERT (gpr_base.u <= gpr_end.u);+#ifndef __NO_FPRS__+  FFI_ASSERT (fpr_base.u <= fpr_end.u);+#endif+  FFI_ASSERT (((flags & FLAG_4_GPR_ARGUMENTS) != 0)+	      == (gpr_end.u - gpr_base.u < 4));+}++#define MIN_CACHE_LINE_SIZE 8++static void+flush_icache (char *wraddr, char *xaddr, int size)+{+  int i;+  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)+    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"+		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");+  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"+		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)+		    : "memory");+}++ffi_status FFI_HIDDEN+ffi_prep_closure_loc_sysv (ffi_closure *closure,+			   ffi_cif *cif,+			   void (*fun) (ffi_cif *, void *, void **, void *),+			   void *user_data,+			   void *codeloc)+{+  if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI)+    return FFI_BAD_ABI;++#ifdef FFI_EXEC_STATIC_TRAMP+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      void (*dest)(void) = ffi_closure_SYSV;+      ffi_tramp_set_parms (closure->ftramp, dest, closure);+    }+  else+#endif+    {+      unsigned int *tramp = (unsigned int *) &closure->tramp[0];+      tramp[0] = 0x7c0802a6;  /*   mflr    r0 */+      tramp[1] = 0x429f0005;  /*   bcl     20,31,.+4 */+      tramp[2] = 0x7d6802a6;  /*   mflr    r11 */+      tramp[3] = 0x7c0803a6;  /*   mtlr    r0 */+      tramp[4] = 0x800b0018;  /*   lwz     r0,24(r11) */+      tramp[5] = 0x816b001c;  /*   lwz     r11,28(r11) */+      tramp[6] = 0x7c0903a6;  /*   mtctr   r0 */+      tramp[7] = 0x4e800420;  /*   bctr */+      *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */+      *(void **) &tramp[9] = codeloc;			/* context */++      /* Flush the icache.  */+      flush_icache ((char *)tramp, (char *)codeloc, 8 * 4);+    }++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++/* Basically the trampoline invokes ffi_closure_SYSV, and on+   entry, r11 holds the address of the closure.+   After storing the registers that could possibly contain+   parameters to be passed into the stack frame and setting+   up space for a return value, ffi_closure_SYSV invokes the+   following helper function to do most of the work.  */++int+ffi_closure_helper_SYSV (ffi_cif *cif,+			 void (*fun) (ffi_cif *, void *, void **, void *),+			 void *user_data,+			 void *rvalue,+			 unsigned long *pgr,+			 ffi_dblfl *pfr,+			 unsigned long *pst)+{+  /* rvalue is the pointer to space for return value in closure assembly */+  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */+  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */+  /* pst is the pointer to outgoing parameter stack in original caller */++  void **          avalue;+  ffi_type **      arg_types;+  long             i, avn;+#ifndef __NO_FPRS__+  long             nf = 0;   /* number of floating registers already used */+#endif+  long             ng = 0;   /* number of general registers already used */++  unsigned       size     = cif->rtype->size;+  unsigned short rtypenum = cif->rtype->type;++  avalue = alloca (cif->nargs * sizeof (void *));++  /* First translate for softfloat/nonlinux */+  rtypenum = translate_float (cif->abi, rtypenum);++  /* Copy the caller's structure return value address so that the closure+     returns the data directly to the caller.+     For FFI_SYSV the result is passed in r3/r4 if the struct size is less+     or equal 8 bytes.  */+  if (rtypenum == FFI_TYPE_STRUCT+      && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8))+    {+      rvalue = (void *) *pgr;+      ng++;+      pgr++;+    }++  i = 0;+  avn = cif->nargs;+  arg_types = cif->arg_types;++  /* Grab the addresses of the arguments from the stack frame.  */+  while (i < avn) {+    unsigned short typenum = arg_types[i]->type;++    /* We may need to handle some values depending on ABI.  */+    typenum = translate_float (cif->abi, typenum);++    switch (typenum)+      {+#ifndef __NO_FPRS__+      case FFI_TYPE_FLOAT:+	/* Unfortunately float values are stored as doubles+	   in the ffi_closure_SYSV code (since we don't check+	   the type in that routine).  */+	if (nf < NUM_FPR_ARG_REGISTERS)+	  {+	    /* FIXME? here we are really changing the values+	       stored in the original calling routines outgoing+	       parameter stack.  This is probably a really+	       naughty thing to do but...  */+	    double temp = pfr->d;+	    pfr->f = (float) temp;+	    avalue[i] = pfr;+	    nf++;+	    pfr++;+	  }+	else+	  {+	    avalue[i] = pst;+	    pst += 1;+	  }+	break;++      case FFI_TYPE_DOUBLE:+	if (nf < NUM_FPR_ARG_REGISTERS)+	  {+	    avalue[i] = pfr;+	    nf++;+	    pfr++;+	  }+	else+	  {+	    if (((long) pst) & 4)+	      pst++;+	    avalue[i] = pst;+	    pst += 2;+	  }+	break;++# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+      case FFI_TYPE_LONGDOUBLE:+	if (nf < NUM_FPR_ARG_REGISTERS - 1)+	  {+	    avalue[i] = pfr;+	    pfr += 2;+	    nf += 2;+	  }+	else+	  {+	    if (((long) pst) & 4)+	      pst++;+	    avalue[i] = pst;+	    pst += 4;+	    nf = 8;+	  }+	break;+# endif+#endif++      case FFI_TYPE_UINT128:+	/* Test if for the whole long double, 4 gprs are available.+	   otherwise the stuff ends up on the stack.  */+	if (ng < NUM_GPR_ARG_REGISTERS - 3)+	  {+	    avalue[i] = pgr;+	    pgr += 4;+	    ng += 4;+	  }+	else+	  {+	    avalue[i] = pst;+	    pst += 4;+	    ng = 8+4;+	  }+	break;++      case FFI_TYPE_SINT8:+      case FFI_TYPE_UINT8:+#ifndef __LITTLE_ENDIAN__+	if (ng < NUM_GPR_ARG_REGISTERS)+	  {+	    avalue[i] = (char *) pgr + 3;+	    ng++;+	    pgr++;+	  }+	else+	  {+	    avalue[i] = (char *) pst + 3;+	    pst++;+	  }+	break;+#endif++      case FFI_TYPE_SINT16:+      case FFI_TYPE_UINT16:+#ifndef __LITTLE_ENDIAN__+	if (ng < NUM_GPR_ARG_REGISTERS)+	  {+	    avalue[i] = (char *) pgr + 2;+	    ng++;+	    pgr++;+	  }+	else+	  {+	    avalue[i] = (char *) pst + 2;+	    pst++;+	  }+	break;+#endif++      case FFI_TYPE_SINT32:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_POINTER:+	if (ng < NUM_GPR_ARG_REGISTERS)+	  {+	    avalue[i] = pgr;+	    ng++;+	    pgr++;+	  }+	else+	  {+	    avalue[i] = pst;+	    pst++;+	  }+	break;++      case FFI_TYPE_STRUCT:+	/* Structs are passed by reference. The address will appear in a+	   gpr if it is one of the first 8 arguments.  */+	if (ng < NUM_GPR_ARG_REGISTERS)+	  {+	    avalue[i] = (void *) *pgr;+	    ng++;+	    pgr++;+	  }+	else+	  {+	    avalue[i] = (void *) *pst;+	    pst++;+	  }+	break;++      case FFI_TYPE_SINT64:+      case FFI_TYPE_UINT64:+	/* Passing long long ints are complex, they must+	   be passed in suitable register pairs such as+	   (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)+	   and if the entire pair aren't available then the outgoing+	   parameter stack is used for both but an alignment of 8+	   must will be kept.  So we must either look in pgr+	   or pst to find the correct address for this type+	   of parameter.  */+	if (ng < NUM_GPR_ARG_REGISTERS - 1)+	  {+	    if (ng & 1)+	      {+		/* skip r4, r6, r8 as starting points */+		ng++;+		pgr++;+	      }+	    avalue[i] = pgr;+	    ng += 2;+	    pgr += 2;+	  }+	else+	  {+	    if (((long) pst) & 4)+	      pst++;+	    avalue[i] = pst;+	    pst += 2;+	    ng = NUM_GPR_ARG_REGISTERS;+	  }+	break;++      default:+	FFI_ASSERT (0);+      }++    i++;+  }++  (*fun) (cif, rvalue, avalue, user_data);++  /* Tell ffi_closure_SYSV how to perform return type promotions.+     Because the FFI_SYSV ABI returns the structures <= 8 bytes in+     r3/r4 we have to tell ffi_closure_SYSV how to treat them.  We+     combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of+     the struct less one.  We never have a struct with size zero.+     See the comment in ffitarget.h about ordering.  */+  if (rtypenum == FFI_TYPE_STRUCT+      && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)+    return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size;+  return rtypenum;+}+#endif
+ src/powerpc/ffitarget.h view
@@ -0,0 +1,204 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc+                 Copyright (c) 1996-2003  Red Hat, Inc.++   Target configuration macros for PowerPC.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++#if defined (POWERPC) && defined (__powerpc64__)	/* linux64 */+#ifndef POWERPC64+#define POWERPC64+#endif+#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin64 */+#ifndef POWERPC64+#define POWERPC64+#endif+#ifndef POWERPC_DARWIN64+#define POWERPC_DARWIN64+#endif+#elif defined (POWERPC_AIX) && defined (__64BIT__)	/* AIX64 */+#ifndef POWERPC64+#define POWERPC64+#endif+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,++#if defined (POWERPC_AIX)+  FFI_AIX,+  FFI_DARWIN,+  FFI_DEFAULT_ABI = FFI_AIX,+  FFI_LAST_ABI++#elif defined (POWERPC_DARWIN)+  FFI_AIX,+  FFI_DARWIN,+  FFI_DEFAULT_ABI = FFI_DARWIN,+  FFI_LAST_ABI++#else+  /* The FFI_COMPAT values are used by old code.  Since libffi may be+     a shared library we have to support old values for backwards+     compatibility.  */+  FFI_COMPAT_SYSV,+  FFI_COMPAT_GCC_SYSV,+  FFI_COMPAT_LINUX64,+  FFI_COMPAT_LINUX,+  FFI_COMPAT_LINUX_SOFT_FLOAT,++# if defined (POWERPC64)+  /* This bit, always set in new code, must not be set in any of the+     old FFI_COMPAT values that might be used for 64-bit linux.  We+     only need worry about FFI_COMPAT_LINUX64, but to be safe avoid+     all old values.  */+  FFI_LINUX = 8,+  /* This and following bits can reuse FFI_COMPAT values.  */+  FFI_LINUX_STRUCT_ALIGN = 1,+  FFI_LINUX_LONG_DOUBLE_128 = 2,+  FFI_LINUX_LONG_DOUBLE_IEEE128 = 4,+  FFI_DEFAULT_ABI = (FFI_LINUX+#  ifdef __STRUCT_PARM_ALIGN__+		     | FFI_LINUX_STRUCT_ALIGN+#  endif+#  ifdef __LONG_DOUBLE_128__+		     | FFI_LINUX_LONG_DOUBLE_128+#   ifdef __LONG_DOUBLE_IEEE128__+		     | FFI_LINUX_LONG_DOUBLE_IEEE128+#   endif+#  endif+		     ),+  FFI_LAST_ABI = 16++# else+  /* This bit, always set in new code, must not be set in any of the+     old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd.  */+  FFI_SYSV = 8,+  /* This and following bits can reuse FFI_COMPAT values.  */+  FFI_SYSV_SOFT_FLOAT = 1,+  FFI_SYSV_STRUCT_RET = 2,+  FFI_SYSV_IBM_LONG_DOUBLE = 4,+  FFI_SYSV_LONG_DOUBLE_128 = 16,++  FFI_DEFAULT_ABI = (FFI_SYSV+#  ifdef __NO_FPRS__+		     | FFI_SYSV_SOFT_FLOAT+#  endif+#  if (defined (__SVR4_STRUCT_RETURN)					\+       || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN))+		     | FFI_SYSV_STRUCT_RET+#  endif+#  if __LDBL_MANT_DIG__ == 106+		     | FFI_SYSV_IBM_LONG_DOUBLE+#  endif+#  ifdef __LONG_DOUBLE_128__+		     | FFI_SYSV_LONG_DOUBLE_128+#  endif+		     ),+  FFI_LAST_ABI = 32+# endif+#endif++} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0+#if defined (POWERPC) || defined (POWERPC_FREEBSD)+# define FFI_GO_CLOSURES 1+# define FFI_TARGET_SPECIFIC_VARIADIC 1+# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs+#endif+#if defined (POWERPC_AIX)+# define FFI_GO_CLOSURES 1+#endif++/* ppc_closure.S and linux64_closure.S expect this.  */+#define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER++/* We define additional types below.  If generic types are added that+   must be supported by powerpc libffi then it is likely that+   FFI_PPC_TYPE_LAST needs increasing *and* the jump tables in+   ppc_closure.S and linux64_closure.S be extended.  */++#if !(FFI_TYPE_LAST == FFI_PPC_TYPE_LAST		\+      || (FFI_TYPE_LAST == FFI_TYPE_COMPLEX		\+	  && !defined FFI_TARGET_HAS_COMPLEX_TYPE))+# error "You likely have a broken powerpc libffi"+#endif++/* Needed for soft-float long-double-128 support.  */+#define FFI_TYPE_UINT128 (FFI_PPC_TYPE_LAST + 1)++/* Needed for FFI_SYSV small structure returns.  */+#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_PPC_TYPE_LAST + 2)++/* Used by ELFv2 for homogenous structure returns.  */+#define FFI_V2_TYPE_VECTOR		(FFI_PPC_TYPE_LAST + 1)+#define FFI_V2_TYPE_VECTOR_HOMOG	(FFI_PPC_TYPE_LAST + 2)+#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_PPC_TYPE_LAST + 3)+#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_PPC_TYPE_LAST + 4)+#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_PPC_TYPE_LAST + 5)++#if _CALL_ELF == 2+# define FFI_TRAMPOLINE_SIZE 32+#else+# if defined(POWERPC64) || defined(POWERPC_AIX)+#  if defined(POWERPC_DARWIN64)+#    define FFI_TRAMPOLINE_SIZE 48+#  else+#    define FFI_TRAMPOLINE_SIZE 24+#  endif+# else /* POWERPC || POWERPC_AIX */+#  define FFI_TRAMPOLINE_SIZE 40+# endif+#endif++#ifndef LIBFFI_ASM+#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)+struct ffi_aix_trampoline_struct {+    void * code_pointer;	/* Pointer to ffi_closure_ASM */+    void * toc;			/* TOC */+    void * static_chain;	/* Pointer to closure */+};+#endif+#endif++#endif
+ src/powerpc/internal.h view
@@ -0,0 +1,10 @@+#ifdef FFI_EXEC_STATIC_TRAMP+/* For the trampoline code table mapping, a mapping size of 64K is chosen.  */+#define PPC_TRAMP_MAP_SHIFT	16+#define PPC_TRAMP_MAP_SIZE	(1 << PPC_TRAMP_MAP_SHIFT)+# ifdef __PCREL__+#  define PPC_TRAMP_SIZE	24+# else+#  define PPC_TRAMP_SIZE	40+# endif /* __PCREL__ */+#endif /* FFI_EXEC_STATIC_TRAMP */
+ src/powerpc/linux64.S view
@@ -0,0 +1,293 @@+/* -----------------------------------------------------------------------+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>+	    Copyright (c) 2008 Red Hat, Inc.++   PowerPC64 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 AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++	.machine altivec++#ifdef POWERPC64+	.hidden	ffi_call_LINUX64+	.globl	ffi_call_LINUX64+	.text+	.cfi_startproc+# if _CALL_ELF == 2+ffi_call_LINUX64:+#  ifndef __PCREL__+	addis	%r2, %r12, .TOC.-ffi_call_LINUX64@ha+	addi	%r2, %r2, .TOC.-ffi_call_LINUX64@l+#  endif+	.localentry ffi_call_LINUX64, . - ffi_call_LINUX64+# else+	.section	".opd","aw"+	.align	3+ffi_call_LINUX64:+#  ifdef _CALL_LINUX+	.quad	.L.ffi_call_LINUX64,.TOC.@tocbase,0+	.type	ffi_call_LINUX64,@function+	.text+.L.ffi_call_LINUX64:+#  else+	.hidden	.ffi_call_LINUX64+	.globl	.ffi_call_LINUX64+	.quad	.ffi_call_LINUX64,.TOC.@tocbase,0+	.size	ffi_call_LINUX64,24+	.type	.ffi_call_LINUX64,@function+	.text+.ffi_call_LINUX64:+#  endif+# endif+	mflr	%r0+	std	%r28, -32(%r1)+	std	%r29, -24(%r1)+	std	%r30, -16(%r1)+	std	%r31, -8(%r1)+	std	%r7, 8(%r1)	/* closure, saved in cr field.  */+	std	%r0, 16(%r1)++	mr	%r28, %r1	/* our AP.  */+	.cfi_def_cfa_register 28+	.cfi_offset 65, 16+	.cfi_offset 31, -8+	.cfi_offset 30, -16+	.cfi_offset 29, -24+	.cfi_offset 28, -32++	stdux	%r1, %r1, %r8+	mr	%r31, %r6	/* flags, */+	mr	%r30, %r5	/* rvalue, */+	mr	%r29, %r4	/* function address.  */+/* Save toc pointer, not for the ffi_prep_args64 call, but for the later+   bctrl function call.  */+# if _CALL_ELF == 2+	std	%r2, 24(%r1)+# else+	std	%r2, 40(%r1)+# endif++	/* Call ffi_prep_args64.  */+	mr	%r4, %r1+# if defined _CALL_LINUX || _CALL_ELF == 2+#  ifdef __PCREL__+	bl	ffi_prep_args64@notoc+#  else+	bl	ffi_prep_args64+	nop+#  endif+# else+	bl	.ffi_prep_args64+	nop+# endif++# if _CALL_ELF == 2+	mr	%r12, %r29+# else+	ld	%r12, 0(%r29)+	ld	%r2, 8(%r29)+# endif+	/* Now do the call.  */+	/* Set up cr1 with bits 3-7 of the flags.  */+	mtcrf	0xc0, %r31++	/* Get the address to call into CTR.  */+	mtctr	%r12+	/* Load all those argument registers.  */+	addi	%r29, %r28, -32-(8*8)+	ld	%r3,  (0*8)(%r29)+	ld	%r4,  (1*8)(%r29)+	ld	%r5,  (2*8)(%r29)+	ld	%r6,  (3*8)(%r29)+	bf-	5, 1f+	ld	%r7,  (4*8)(%r29)+	ld	%r8,  (5*8)(%r29)+	ld	%r9,  (6*8)(%r29)+	ld	%r10, (7*8)(%r29)+1:++	/* Load all the FP registers.  */+	bf-	6, 2f+	addi	%r29, %r29, -(14*8)+	lfd	%f1,  ( 1*8)(%r29)+	lfd	%f2,  ( 2*8)(%r29)+	lfd	%f3,  ( 3*8)(%r29)+	lfd	%f4,  ( 4*8)(%r29)+	lfd	%f5,  ( 5*8)(%r29)+	lfd	%f6,  ( 6*8)(%r29)+	lfd	%f7,  ( 7*8)(%r29)+	lfd	%f8,  ( 8*8)(%r29)+	lfd	%f9,  ( 9*8)(%r29)+	lfd	%f10, (10*8)(%r29)+	lfd	%f11, (11*8)(%r29)+	lfd	%f12, (12*8)(%r29)+	lfd	%f13, (13*8)(%r29)+2:++	/* Load all the vector registers.  */+	bf-	3, 3f+	addi	%r29, %r29, -16+	lvx	%v13, 0, %r29+	addi	%r29, %r29, -16+	lvx	%v12, 0, %r29+	addi	%r29, %r29, -16+	lvx	%v11, 0, %r29+	addi	%r29, %r29, -16+	lvx	%v10, 0, %r29+	addi	%r29, %r29, -16+	lvx	%v9,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v8,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v7,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v6,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v5,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v4,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v3,  0, %r29+	addi	%r29, %r29, -16+	lvx	%v2,  0, %r29+3:++	/* Make the call.  */+	ld	%r11, 8(%r28)+	bctrl++	/* This must follow the call immediately, the unwinder+	   uses this to find out if r2 has been saved or not.  */+# if _CALL_ELF == 2+	ld	%r2, 24(%r1)+# else+	ld	%r2, 40(%r1)+# endif++	/* Now, deal with the return value.  */+	mtcrf	0x01, %r31+	bt	31, .Lstruct_return_value+	bt	30, .Ldone_return_value+	bt	29, .Lfp_return_value+	bt	28, .Lvec_return_value+	std	%r3, 0(%r30)+	/* Fall through...  */++.Ldone_return_value:+	/* Restore the registers we used and return.  */+	mr	%r1, %r28+	.cfi_def_cfa_register 1+	ld	%r0, 16(%r28)+	ld	%r28, -32(%r28)+	mtlr	%r0+	ld	%r29, -24(%r1)+	ld	%r30, -16(%r1)+	ld	%r31, -8(%r1)+	blr++.Lvec_return_value:+	stvx	%v2, 0, %r30+	b	.Ldone_return_value++.Lfp_return_value:+	.cfi_def_cfa_register 28+	mtcrf	0x02, %r31 /* cr6  */+	bf	27, .Lfloat_return_value+	stfd	%f1, 0(%r30)+	bf	26, .Ldone_return_value+	stfd	%f2, 8(%r30)+	b	.Ldone_return_value+.Lfloat_return_value:+	stfs	%f1, 0(%r30)+	b	.Ldone_return_value++.Lstruct_return_value:+	bf	29, .Lvec_homog_or_small_struct+	mtcrf	0x02, %r31 /* cr6  */+	bf	27, .Lfloat_homog_return_value+	stfd	%f1, 0(%r30)+	stfd	%f2, 8(%r30)+	stfd	%f3, 16(%r30)+	stfd	%f4, 24(%r30)+	stfd	%f5, 32(%r30)+	stfd	%f6, 40(%r30)+	stfd	%f7, 48(%r30)+	stfd	%f8, 56(%r30)+	b	.Ldone_return_value++.Lfloat_homog_return_value:+	stfs	%f1, 0(%r30)+	stfs	%f2, 4(%r30)+	stfs	%f3, 8(%r30)+	stfs	%f4, 12(%r30)+	stfs	%f5, 16(%r30)+	stfs	%f6, 20(%r30)+	stfs	%f7, 24(%r30)+	stfs	%f8, 28(%r30)+	b	.Ldone_return_value++.Lvec_homog_or_small_struct:+	bf	28, .Lsmall_struct+	stvx	%v2, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v3, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v4, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v5, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v6, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v7, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v8, 0, %r30+	addi	%r30, %r30, 16+	stvx	%v9, 0, %r30+	b	.Ldone_return_value++.Lsmall_struct:+	std	%r3, 0(%r30)+	std	%r4, 8(%r30)+	b	.Ldone_return_value++	.cfi_endproc+# if _CALL_ELF == 2+	.size	ffi_call_LINUX64,.-ffi_call_LINUX64+# else+#  ifdef _CALL_LINUX+	.size	ffi_call_LINUX64,.-.L.ffi_call_LINUX64+#  else+	.long	0+	.byte	0,12,0,1,128,4,0,0+	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64+#  endif+# endif++#endif++#if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/powerpc/linux64_closure.S view
@@ -0,0 +1,613 @@+/* -----------------------------------------------------------------------+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>+	    Copyright (c) 2008 Red Hat, Inc.++   PowerPC64 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 AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include "internal.h"++	.file	"linux64_closure.S"++	.machine altivec++#ifdef POWERPC64+	FFI_HIDDEN (ffi_closure_LINUX64)+	.globl  ffi_closure_LINUX64+	.text+	.cfi_startproc+# if _CALL_ELF == 2+ffi_closure_LINUX64:+#  ifndef __PCREL__+	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha+	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l+#  endif+	.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64+# else+	.section        ".opd","aw"+	.align  3+ffi_closure_LINUX64:+#  ifdef _CALL_LINUX+	.quad   .L.ffi_closure_LINUX64,.TOC.@tocbase,0+	.type   ffi_closure_LINUX64,@function+	.text+.L.ffi_closure_LINUX64:+#  else+	FFI_HIDDEN (.ffi_closure_LINUX64)+	.globl  .ffi_closure_LINUX64+	.quad   .ffi_closure_LINUX64,.TOC.@tocbase,0+	.size   ffi_closure_LINUX64,24+	.type   .ffi_closure_LINUX64,@function+	.text+.ffi_closure_LINUX64:+#  endif+# endif++# if _CALL_ELF == 2+#  ifdef __VEC__+#   32 byte special reg save area + 64 byte parm save area+#   + 128 byte retval area + 13*8 fpr save area + 12*16 vec save area + round to 16+#   define STACKFRAME 528+#  else+#   32 byte special reg save area + 64 byte parm save area+#   + 64 byte retval area + 13*8 fpr save area + round to 16+#   define STACKFRAME 272+#  endif+#  define PARMSAVE 32+#  define RETVAL PARMSAVE+64+# else+#  48 bytes special reg save area + 64 bytes parm save area+#  + 16 bytes retval area + 13*8 bytes fpr save area + round to 16+#  define STACKFRAME 240+#  define PARMSAVE 48+#  define RETVAL PARMSAVE+64+# endif++# if _CALL_ELF == 2+	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif+	mflr	%r0+	lwz	%r12, 28(%r12)				# cif->flags+	mtcrf	0x40, %r12+	addi	%r12, %r1, PARMSAVE+	bt	7, 0f+	# Our caller has not allocated a parameter save area.+	# We need to allocate one here and use it to pass gprs to+	# ffi_closure_helper_LINUX64.+	addi	%r12, %r1, -STACKFRAME+PARMSAVE+0:+	# Save general regs into parm save area+	std	%r3, 0(%r12)+	std	%r4, 8(%r12)+	std	%r5, 16(%r12)+	std	%r6, 24(%r12)+	std	%r7, 32(%r12)+	std	%r8, 40(%r12)+	std	%r9, 48(%r12)+	std	%r10, 56(%r12)++	# load up the pointer to the parm save area+	mr	%r7, %r12+# else+	# copy r2 to r11 and load TOC into r2+	mr	%r11, %r2+	ld	%r2, 16(%r2)++	mflr	%r0+	# Save general regs into parm save area+	# This is the parameter save area set up by our caller.+	std	%r3, PARMSAVE+0(%r1)+	std	%r4, PARMSAVE+8(%r1)+	std	%r5, PARMSAVE+16(%r1)+	std	%r6, PARMSAVE+24(%r1)+	std	%r7, PARMSAVE+32(%r1)+	std	%r8, PARMSAVE+40(%r1)+	std	%r9, PARMSAVE+48(%r1)+	std	%r10, PARMSAVE+56(%r1)++	# load up the pointer to the parm save area+	addi	%r7, %r1, PARMSAVE+# endif+	std	%r0, 16(%r1)++	# closure->cif+	ld	%r3, FFI_TRAMPOLINE_SIZE(%r11)+	# closure->fun+	ld	%r4, FFI_TRAMPOLINE_SIZE+8(%r11)+	# closure->user_data+	ld	%r5, FFI_TRAMPOLINE_SIZE+16(%r11)++.Ldoclosure:+	# next save fpr 1 to fpr 13+	stfd	%f1, -104+(0*8)(%r1)+	stfd	%f2, -104+(1*8)(%r1)+	stfd	%f3, -104+(2*8)(%r1)+	stfd	%f4, -104+(3*8)(%r1)+	stfd	%f5, -104+(4*8)(%r1)+	stfd	%f6, -104+(5*8)(%r1)+	stfd	%f7, -104+(6*8)(%r1)+	stfd	%f8, -104+(7*8)(%r1)+	stfd	%f9, -104+(8*8)(%r1)+	stfd	%f10, -104+(9*8)(%r1)+	stfd	%f11, -104+(10*8)(%r1)+	stfd	%f12, -104+(11*8)(%r1)+	stfd	%f13, -104+(12*8)(%r1)++	# load up the pointer to the saved fpr registers+	addi	%r8, %r1, -104++# ifdef __VEC__+	# load up the pointer to the saved vector registers+	# 8 bytes padding for 16-byte alignment at -112(%r1)+	addi	%r9, %r8, -24+	stvx	%v13, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v12, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v11, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v10, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v9, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v8, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v7, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v6, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v5, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v4, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v3, 0, %r9+	addi	%r9, %r9, -16+	stvx	%v2, 0, %r9+# endif++	# load up the pointer to the result storage+	addi	%r6, %r1, -STACKFRAME+RETVAL++	stdu	%r1, -STACKFRAME(%r1)+	.cfi_def_cfa_offset STACKFRAME+	.cfi_offset 65, 16++	# make the call+# if defined _CALL_LINUX || _CALL_ELF == 2+#  ifdef __PCREL__+	bl ffi_closure_helper_LINUX64@notoc+.Lret:+#  else+	bl ffi_closure_helper_LINUX64+.Lret:+	nop+#  endif+# else+	bl .ffi_closure_helper_LINUX64+.Lret:+	nop+# endif++	# now r3 contains the return type+	# so use it to look up in a table+	# so we know how to deal with each type++	# look up the proper starting point in table+	# by using return type as offset+	ld %r0, STACKFRAME+16(%r1)+	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT+	bge .Lsmall+	mflr %r4		# move address of .Lret to r4+	sldi %r3, %r3, 4	# now multiply return type by 16+	addi %r4, %r4, .Lret_type0 - .Lret+	add %r3, %r3, %r4	# add contents of table to table address+	mtctr %r3+	bctr			# jump to it++# Each of the ret_typeX code fragments has to be exactly 16 bytes long+# (4 instructions). For cache effectiveness we align to a 16 byte boundary+# first.+	.align 4++.Lret_type0:+# case FFI_TYPE_VOID+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+	nop+# case FFI_TYPE_INT+# ifdef __LITTLE_ENDIAN__+	lwa %r3, RETVAL+0(%r1)+# else+	lwa %r3, RETVAL+4(%r1)+# endif+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_FLOAT+	lfs %f1, RETVAL+0(%r1)+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_DOUBLE+	lfd %f1, RETVAL+0(%r1)+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_LONGDOUBLE+	lfd %f1, RETVAL+0(%r1)+	mtlr %r0+	lfd %f2, RETVAL+8(%r1)+	b .Lfinish+# case FFI_TYPE_UINT8+# ifdef __LITTLE_ENDIAN__+	lbz %r3, RETVAL+0(%r1)+# else+	lbz %r3, RETVAL+7(%r1)+# endif+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_SINT8+# ifdef __LITTLE_ENDIAN__+	lbz %r3, RETVAL+0(%r1)+# else+	lbz %r3, RETVAL+7(%r1)+# endif+	extsb %r3,%r3+	mtlr %r0+	b .Lfinish+# case FFI_TYPE_UINT16+# ifdef __LITTLE_ENDIAN__+	lhz %r3, RETVAL+0(%r1)+# else+	lhz %r3, RETVAL+6(%r1)+# endif+	mtlr %r0+.Lfinish:+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_SINT16+# ifdef __LITTLE_ENDIAN__+	lha %r3, RETVAL+0(%r1)+# else+	lha %r3, RETVAL+6(%r1)+# endif+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_UINT32+# ifdef __LITTLE_ENDIAN__+	lwz %r3, RETVAL+0(%r1)+# else+	lwz %r3, RETVAL+4(%r1)+# endif+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_SINT32+# ifdef __LITTLE_ENDIAN__+	lwa %r3, RETVAL+0(%r1)+# else+	lwa %r3, RETVAL+4(%r1)+# endif+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_UINT64+	ld %r3, RETVAL+0(%r1)+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_SINT64+	ld %r3, RETVAL+0(%r1)+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_TYPE_STRUCT+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+	nop+# case FFI_TYPE_POINTER+	ld %r3, RETVAL+0(%r1)+	mtlr %r0+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+# case FFI_V2_TYPE_VECTOR+	addi %r3, %r1, RETVAL+	lvx %v2, 0, %r3+	mtlr %r0+	b .Lfinish+# case FFI_V2_TYPE_VECTOR_HOMOG+	addi %r3, %r1, RETVAL+	lvx %v2, 0, %r3+	addi %r3, %r3, 16+	b .Lmorevector+# case FFI_V2_TYPE_FLOAT_HOMOG+	lfs %f1, RETVAL+0(%r1)+	lfs %f2, RETVAL+4(%r1)+	lfs %f3, RETVAL+8(%r1)+	b .Lmorefloat+# case FFI_V2_TYPE_DOUBLE_HOMOG+	lfd %f1, RETVAL+0(%r1)+	lfd %f2, RETVAL+8(%r1)+	lfd %f3, RETVAL+16(%r1)+	lfd %f4, RETVAL+24(%r1)+	mtlr %r0+	lfd %f5, RETVAL+32(%r1)+	lfd %f6, RETVAL+40(%r1)+	lfd %f7, RETVAL+48(%r1)+	lfd %f8, RETVAL+56(%r1)+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+.Lmorevector:+	lvx %v3, 0, %r3+	addi %r3, %r3, 16+	lvx %v4, 0, %r3+	addi %r3, %r3, 16+	lvx %v5, 0, %r3+	mtlr %r0+	addi %r3, %r3, 16+	lvx %v6, 0, %r3+	addi %r3, %r3, 16+	lvx %v7, 0, %r3+	addi %r3, %r3, 16+	lvx %v8, 0, %r3+	addi %r3, %r3, 16+	lvx %v9, 0, %r3+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+.Lmorefloat:+	lfs %f4, RETVAL+12(%r1)+	mtlr %r0+	lfs %f5, RETVAL+16(%r1)+	lfs %f6, RETVAL+20(%r1)+	lfs %f7, RETVAL+24(%r1)+	lfs %f8, RETVAL+28(%r1)+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+.Lsmall:+# ifdef __LITTLE_ENDIAN__+	ld %r3,RETVAL+0(%r1)+	mtlr %r0+	ld %r4,RETVAL+8(%r1)+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+# else+	# A struct smaller than a dword is returned in the low bits of r3+	# ie. right justified.  Larger structs are passed left justified+	# in r3 and r4.  The return value area on the stack will have+	# the structs as they are usually stored in memory.+	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?+	neg %r5, %r3+	ld %r3,RETVAL+0(%r1)+	blt .Lsmalldown+	mtlr %r0+	ld %r4,RETVAL+8(%r1)+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset STACKFRAME+.Lsmalldown:+	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7+	mtlr %r0+	sldi %r5, %r5, 3+	addi %r1, %r1, STACKFRAME+	.cfi_def_cfa_offset 0+	srd %r3, %r3, %r5+	blr+# endif++	.cfi_endproc+# if _CALL_ELF == 2+	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64+# else+#  ifdef _CALL_LINUX+	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64+#  else+	.long	0+	.byte	0,12,0,1,128,0,0,0+	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64+#  endif+# endif+++	FFI_HIDDEN (ffi_go_closure_linux64)+	.globl  ffi_go_closure_linux64+	.text+	.cfi_startproc+# if _CALL_ELF == 2+ffi_go_closure_linux64:+#  ifndef __PCREL__+	addis	%r2, %r12, .TOC.-ffi_go_closure_linux64@ha+	addi	%r2, %r2, .TOC.-ffi_go_closure_linux64@l+#  endif+	.localentry ffi_go_closure_linux64, . - ffi_go_closure_linux64+# else+	.section        ".opd","aw"+	.align  3+ffi_go_closure_linux64:+#  ifdef _CALL_LINUX+	.quad   .L.ffi_go_closure_linux64,.TOC.@tocbase,0+	.type   ffi_go_closure_linux64,@function+	.text+.L.ffi_go_closure_linux64:+#  else+	FFI_HIDDEN (.ffi_go_closure_linux64)+	.globl  .ffi_go_closure_linux64+	.quad   .ffi_go_closure_linux64,.TOC.@tocbase,0+	.size   ffi_go_closure_linux64,24+	.type   .ffi_go_closure_linux64,@function+	.text+.ffi_go_closure_linux64:+#  endif+# endif++# if _CALL_ELF == 2+	ld	%r12, 8(%r11)				# closure->cif+	mflr	%r0+	lwz	%r12, 28(%r12)				# cif->flags+	mtcrf	0x40, %r12+	addi	%r12, %r1, PARMSAVE+	bt	7, 0f+	# Our caller has not allocated a parameter save area.+	# We need to allocate one here and use it to pass gprs to+	# ffi_closure_helper_LINUX64.+	addi	%r12, %r1, -STACKFRAME+PARMSAVE+0:+	# Save general regs into parm save area+	std	%r3, 0(%r12)+	std	%r4, 8(%r12)+	std	%r5, 16(%r12)+	std	%r6, 24(%r12)+	std	%r7, 32(%r12)+	std	%r8, 40(%r12)+	std	%r9, 48(%r12)+	std	%r10, 56(%r12)++	# load up the pointer to the parm save area+	mr	%r7, %r12+# else+	mflr	%r0+	# Save general regs into parm save area+	# This is the parameter save area set up by our caller.+	std	%r3, PARMSAVE+0(%r1)+	std	%r4, PARMSAVE+8(%r1)+	std	%r5, PARMSAVE+16(%r1)+	std	%r6, PARMSAVE+24(%r1)+	std	%r7, PARMSAVE+32(%r1)+	std	%r8, PARMSAVE+40(%r1)+	std	%r9, PARMSAVE+48(%r1)+	std	%r10, PARMSAVE+56(%r1)++	# load up the pointer to the parm save area+	addi	%r7, %r1, PARMSAVE+# endif+	std	%r0, 16(%r1)++	# closure->cif+	ld	%r3, 8(%r11)+	# closure->fun+	ld	%r4, 16(%r11)+	# user_data+	mr	%r5, %r11+	b	.Ldoclosure++	.cfi_endproc+# if _CALL_ELF == 2+	.size	ffi_go_closure_linux64,.-ffi_go_closure_linux64+# else+#  ifdef _CALL_LINUX+	.size	ffi_go_closure_linux64,.-.L.ffi_go_closure_linux64+#  else+	.long	0+	.byte	0,12,0,1,128,0,0,0+	.size	.ffi_go_closure_linux64,.-.ffi_go_closure_linux64+#  endif+# endif++#ifdef FFI_EXEC_STATIC_TRAMP+	.text+	.align PPC_TRAMP_MAP_SHIFT+	FFI_HIDDEN (trampoline_code_table)+	.globl  trampoline_code_table+# if _CALL_ELF == 2+	.type   trampoline_code_table,@function+trampoline_code_table:+	.localentry trampoline_code_table,.-trampoline_code_table+# else+	.section	".opd","aw"+	.align  3+trampoline_code_table:+	.quad   .L.trampoline_code_table,.TOC.@tocbase,0+	.type   trampoline_code_table,@function+	.text+.L.trampoline_code_table:+# endif+	.rept	PPC_TRAMP_MAP_SIZE / PPC_TRAMP_SIZE+#ifdef __PCREL__+	pla	%r2,PPC_TRAMP_MAP_SIZE+	ld	%r11,0(%r2)+	ld	%r12,8(%r2)+	mtctr	%r12+	bctr+#else+	mflr	%r0+	bcl	20,31,$+4+	mflr	%r11+	addis	%r11,%r11,PPC_TRAMP_MAP_SIZE@ha+	mtlr	%r0+	ld	%r12,(PPC_TRAMP_MAP_SIZE+0)@l(%r11)+	mtctr	%r12+	ld	%r11,(PPC_TRAMP_MAP_SIZE-8)@l(%r11)+	bctr+	nop+#endif+	.endr+	.align PPC_TRAMP_MAP_SHIFT+#if _CALL_ELF == 2+	.size	trampoline_code_table,.-trampoline_code_table+#else+	.size	trampoline_code_table,.-.L.trampoline_code_table+#endif+#endif /* FFI_EXEC_STATIC_TRAMP */+#endif /* POWERPC64 */++#if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/powerpc/ppc_closure.S view
@@ -0,0 +1,421 @@+/* -----------------------------------------------------------------------+   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>+	    Copyright (c) 2008 Red Hat, Inc.++   PowerPC 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 AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include "internal.h"+#include <powerpc/asm.h>++	.file   "ppc_closure.S"++#ifndef POWERPC64++FFI_HIDDEN(ffi_closure_SYSV)+ENTRY(ffi_closure_SYSV)+	.cfi_startproc+	stwu %r1,-144(%r1)+	.cfi_def_cfa_offset 144+	mflr %r0+	stw %r0,148(%r1)+	.cfi_offset 65, 4++# we want to build up an areas for the parameters passed+# in registers (both floating point and integer)++	# so first save gpr 3 to gpr 10 (aligned to 4)+	stw   %r3, 16(%r1)+	stw   %r4, 20(%r1)+	stw   %r5, 24(%r1)++	# set up registers for the routine that does the work++	# closure->cif+	lwz %r3,FFI_TRAMPOLINE_SIZE(%r11)+	# closure->fun+	lwz %r4,FFI_TRAMPOLINE_SIZE+4(%r11)+	# closure->user_data+	lwz %r5,FFI_TRAMPOLINE_SIZE+8(%r11)++.Ldoclosure:+	stw   %r6, 28(%r1)+	stw   %r7, 32(%r1)+	stw   %r8, 36(%r1)+	stw   %r9, 40(%r1)+	stw   %r10,44(%r1)++#ifndef __NO_FPRS__+	# next save fpr 1 to fpr 8 (aligned to 8)+	stfd  %f1, 48(%r1)+	stfd  %f2, 56(%r1)+	stfd  %f3, 64(%r1)+	stfd  %f4, 72(%r1)+	stfd  %f5, 80(%r1)+	stfd  %f6, 88(%r1)+	stfd  %f7, 96(%r1)+	stfd  %f8, 104(%r1)+#endif++	# pointer to the result storage+	addi %r6,%r1,112++	# pointer to the saved gpr registers+	addi %r7,%r1,16++	# pointer to the saved fpr registers+	addi %r8,%r1,48++	# pointer to the outgoing parameter save area in the previous frame+	# i.e. the previous frame pointer + 8+	addi %r9,%r1,152++	# make the call+	bl ffi_closure_helper_SYSV@local+.Lret:+	# now r3 contains the return type+	# so use it to look up in a table+	# so we know how to deal with each type++	# look up the proper starting point in table+	# by using return type as offset++	mflr %r4		# move address of .Lret to r4+	slwi %r3,%r3,4		# now multiply return type by 16+	addi %r4, %r4, .Lret_type0 - .Lret+	lwz %r0,148(%r1)+	add %r3,%r3,%r4		# add contents of table to table address+	mtctr %r3+	bctr			# jump to it++# Each of the ret_typeX code fragments has to be exactly 16 bytes long+# (4 instructions). For cache effectiveness we align to a 16 byte boundary+# first.+	.align 4+# case FFI_TYPE_VOID+.Lret_type0:+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144+	nop++# case FFI_TYPE_INT+	lwz %r3,112+0(%r1)+	mtlr %r0+.Lfinish:+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_FLOAT+#ifndef __NO_FPRS__+	lfs %f1,112+0(%r1)+#else+	nop+#endif+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_DOUBLE+#ifndef __NO_FPRS__+	lfd %f1,112+0(%r1)+#else+	nop+#endif+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_LONGDOUBLE+#ifndef __NO_FPRS__+	lfd %f1,112+0(%r1)+	lfd %f2,112+8(%r1)+	mtlr %r0+	b .Lfinish+#else+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144+	nop+#endif++# case FFI_TYPE_UINT8+#ifdef __LITTLE_ENDIAN__+	lbz %r3,112+0(%r1)+#else+	lbz %r3,112+3(%r1)+#endif+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_SINT8+#ifdef __LITTLE_ENDIAN__+	lbz %r3,112+0(%r1)+#else+	lbz %r3,112+3(%r1)+#endif+	extsb %r3,%r3+	mtlr %r0+	b .Lfinish++# case FFI_TYPE_UINT16+#ifdef __LITTLE_ENDIAN__+	lhz %r3,112+0(%r1)+#else+	lhz %r3,112+2(%r1)+#endif+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_SINT16+#ifdef __LITTLE_ENDIAN__+	lha %r3,112+0(%r1)+#else+	lha %r3,112+2(%r1)+#endif+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_UINT32+	lwz %r3,112+0(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_SINT32+	lwz %r3,112+0(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_UINT64+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+	mtlr %r0+	b .Lfinish++# case FFI_TYPE_SINT64+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+	mtlr %r0+	b .Lfinish++# case FFI_TYPE_STRUCT+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144+	nop++# case FFI_TYPE_POINTER+	lwz %r3,112+0(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_TYPE_UINT128+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+	lwz %r5,112+8(%r1)+	b .Luint128++# The return types below are only used when the ABI type is FFI_SYSV.+# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.+	lbz %r3,112+0(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.+	lhz %r3,112+0(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.+	lwz %r3,112+0(%r1)+#ifdef __LITTLE_ENDIAN__+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144+#else+	srwi %r3,%r3,8+	mtlr %r0+	b .Lfinish+#endif++# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.+	lwz %r3,112+0(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144++# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+#ifdef __LITTLE_ENDIAN__+	mtlr %r0+	b .Lfinish+#else+	li %r5,24+	b .Lstruct567+#endif++# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+#ifdef __LITTLE_ENDIAN__+	mtlr %r0+	b .Lfinish+#else+	li %r5,16+	b .Lstruct567+#endif++# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+#ifdef __LITTLE_ENDIAN__+	mtlr %r0+	b .Lfinish+#else+	li %r5,8+	b .Lstruct567+#endif++# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.+	lwz %r3,112+0(%r1)+	lwz %r4,112+4(%r1)+	mtlr %r0+	b .Lfinish++#ifndef __LITTLE_ENDIAN__+.Lstruct567:+	subfic %r6,%r5,32+	srw %r4,%r4,%r5+	slw %r6,%r3,%r6+	srw %r3,%r3,%r5+	or %r4,%r6,%r4+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_def_cfa_offset 144+#endif++.Luint128:+	lwz %r6,112+12(%r1)+	mtlr %r0+	addi %r1,%r1,144+	.cfi_def_cfa_offset 0+	blr+	.cfi_endproc+END(ffi_closure_SYSV)+++FFI_HIDDEN(ffi_go_closure_sysv)+ENTRY(ffi_go_closure_sysv)+	.cfi_startproc+	stwu %r1,-144(%r1)+	.cfi_def_cfa_offset 144+	mflr %r0+	stw %r0,148(%r1)+	.cfi_offset 65, 4++	stw   %r3, 16(%r1)+	stw   %r4, 20(%r1)+	stw   %r5, 24(%r1)++	# closure->cif+	lwz %r3,4(%r11)+	# closure->fun+	lwz %r4,8(%r11)+	# user_data+	mr %r5,%r11+	b .Ldoclosure+	.cfi_endproc+END(ffi_go_closure_sysv)++#ifdef FFI_EXEC_STATIC_TRAMP+	.text+	.align PPC_TRAMP_MAP_SHIFT+	FFI_HIDDEN (trampoline_code_table)+	.globl  trampoline_code_table+	.type   trampoline_code_table,@function+trampoline_code_table:+	.rept   PPC_TRAMP_MAP_SIZE / PPC_TRAMP_SIZE+	mflr    %r0+	bcl     20,31,$+4+	mflr    %r11+	addis   %r11,%r11,PPC_TRAMP_MAP_SIZE@ha+	mtlr    %r0+	lwz     %r0,(PPC_TRAMP_MAP_SIZE-4)@l(%r11)+	mtctr   %r0+	lwz     %r11,(PPC_TRAMP_MAP_SIZE-8)@l(%r11)+	bctr+	nop+	.endr+	.size   trampoline_code_table,.-trampoline_code_table+	.align PPC_TRAMP_MAP_SHIFT+#endif /* FFI_EXEC_STATIC_TRAMP */++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif+#endif
+ src/powerpc/sysv.S view
@@ -0,0 +1,173 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 1998 Geoffrey Keating+   Copyright (C) 2007 Free Software Foundation, Inc++   PowerPC 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 AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <powerpc/asm.h>++#ifndef POWERPC64+FFI_HIDDEN(ffi_call_SYSV)+ENTRY(ffi_call_SYSV)+	.cfi_startproc+	/* Save the old stack pointer as AP.  */+	mr	%r10,%r1+	.cfi_def_cfa_register 10++	/* Allocate the stack space we need.  */+	stwux	%r1,%r1,%r8+	/* Save registers we use.  */+	mflr	%r9+	stw	%r28,-16(%r10)+	stw	%r29,-12(%r10)+	stw	%r30, -8(%r10)+	stw	%r31, -4(%r10)+	stw	%r9,   4(%r10)+	.cfi_offset 65, 4+	.cfi_offset 31, -4+	.cfi_offset 30, -8+	.cfi_offset 29, -12+	.cfi_offset 28, -16++	/* Save arguments over call...  */+	stw	%r7,   -20(%r10)	/* closure, */+	mr	%r31,%r6		/* flags, */+	mr	%r30,%r5		/* rvalue, */+	mr	%r29,%r4		/* function address, */+	mr	%r28,%r10		/* our AP. */+	.cfi_def_cfa_register 28++	/* Call ffi_prep_args_SYSV.  */+	mr	%r4,%r1+	bl	ffi_prep_args_SYSV@local++	/* Now do the call.  */+	/* Set up cr1 with bits 4-7 of the flags.  */+	mtcrf	0x40,%r31+	/* Get the address to call into CTR.  */+	mtctr	%r29+	/* Load all those argument registers.  */+	lwz	%r3,-24-(8*4)(%r28)+	lwz	%r4,-24-(7*4)(%r28)+	lwz	%r5,-24-(6*4)(%r28)+	lwz	%r6,-24-(5*4)(%r28)+	bf-	5,1f+	nop+	lwz	%r7,-24-(4*4)(%r28)+	lwz	%r8,-24-(3*4)(%r28)+	lwz	%r9,-24-(2*4)(%r28)+	lwz	%r10,-24-(1*4)(%r28)+	nop+1:++#ifndef __NO_FPRS__+	/* Load all the FP registers.  */+	bf-	6,2f+	lfd	%f1,-24-(8*4)-(8*8)(%r28)+	lfd	%f2,-24-(8*4)-(7*8)(%r28)+	lfd	%f3,-24-(8*4)-(6*8)(%r28)+	lfd	%f4,-24-(8*4)-(5*8)(%r28)+	nop+	lfd	%f5,-24-(8*4)-(4*8)(%r28)+	lfd	%f6,-24-(8*4)-(3*8)(%r28)+	lfd	%f7,-24-(8*4)-(2*8)(%r28)+	lfd	%f8,-24-(8*4)-(1*8)(%r28)+#endif+2:++	/* Make the call.  */+	lwz	%r11, -20(%r28)+	bctrl++	/* Now, deal with the return value.  */+	mtcrf	0x03,%r31 /* cr6-cr7  */+	bt-	31,L(small_struct_return_value)+	bt-	30,L(done_return_value)+#ifndef __NO_FPRS__+	bt-	29,L(fp_return_value)+#endif+	stw	%r3,0(%r30)+	bf+	27,L(done_return_value)+	stw	%r4,4(%r30)+	bf	26,L(done_return_value)+	stw     %r5,8(%r30)+	stw	%r6,12(%r30)+	/* Fall through...  */++L(done_return_value):+	/* Restore the registers we used and return.  */+	lwz	%r9,   4(%r28)+	lwz	%r31, -4(%r28)+	mtlr	%r9+	lwz	%r30, -8(%r28)+	lwz	%r29,-12(%r28)+	lwz	%r28,-16(%r28)+	.cfi_remember_state+	/* At this point we don't have a cfa register.  Say all our+	   saved regs have been restored.  */+	.cfi_same_value 65+	.cfi_same_value 31+	.cfi_same_value 30+	.cfi_same_value 29+	.cfi_same_value 28+	/* Hopefully this works..  */+	.cfi_def_cfa_register 1+	.cfi_offset 1, 0+	lwz	%r1,0(%r1)+	.cfi_same_value 1+	blr++#ifndef __NO_FPRS__+L(fp_return_value):+	.cfi_restore_state+	bf	27,L(float_return_value)+	stfd	%f1,0(%r30)+	bf	26,L(done_return_value)+	stfd	%f2,8(%r30)+	b	L(done_return_value)+L(float_return_value):+	stfs	%f1,0(%r30)+	b	L(done_return_value)+#endif++L(small_struct_return_value):+	/*+	 * The C code always allocates a properly-aligned 8-byte bounce+	 * buffer to make this assembly code very simple.  Just write out+	 * r3 and r4 to the buffer to allow the C code to handle the rest.+	 */+	stw %r3, 0(%r30)+	stw %r4, 4(%r30)+	b L(done_return_value)+	.cfi_endproc++END(ffi_call_SYSV)++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif+#endif
+ src/prep_cif.c view
@@ -0,0 +1,280 @@+/* -----------------------------------------------------------------------+   prep_cif.c - Copyright (c) 2011, 2012, 2021, 2025  Anthony Green+                Copyright (c) 1996, 1998, 2007  Red Hat, Inc.+                Copyright (c) 2022 Oracle and/or its affiliates.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>++/* Round up to FFI_SIZEOF_ARG. */++#define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)++/* Perform machine independent initialization of aggregate type+   specifications. */++static ffi_status initialize_aggregate(ffi_type *arg, size_t *offsets)+{+  ffi_type **ptr;++  if (UNLIKELY(arg == NULL || arg->elements == NULL))+    return FFI_BAD_TYPEDEF;++  arg->size = 0;+  arg->alignment = 0;++  ptr = &(arg->elements[0]);++  if (UNLIKELY(ptr == 0))+    return FFI_BAD_TYPEDEF;++  while ((*ptr) != NULL)+    {+      if (UNLIKELY(((*ptr)->size == 0)+		    && (initialize_aggregate((*ptr), NULL) != FFI_OK)))+	return FFI_BAD_TYPEDEF;++      /* Perform a sanity check on the argument type */+      FFI_ASSERT_VALID_TYPE(*ptr);++      arg->size = FFI_ALIGN(arg->size, (*ptr)->alignment);+      if (offsets)+	*offsets++ = arg->size;+      arg->size += (*ptr)->size;++      arg->alignment = (arg->alignment > (*ptr)->alignment) ?+	arg->alignment : (*ptr)->alignment;++      ptr++;+    }++  /* Structure size includes tail padding.  This is important for+     structures that fit in one register on ABIs like the PowerPC64+     Linux ABI that right justify small structs in a register.+     It's also needed for nested structure layout, for example+     struct A { long a; char b; }; struct B { struct A x; char y; };+     should find y at an offset of 2*sizeof(long) and result in a+     total size of 3*sizeof(long).  */+  arg->size = FFI_ALIGN (arg->size, arg->alignment);++  /* On some targets, the ABI defines that structures have an additional+     alignment beyond the "natural" one based on their elements.  */+#ifdef FFI_AGGREGATE_ALIGNMENT+  if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)+    arg->alignment = FFI_AGGREGATE_ALIGNMENT;+#endif++  if (arg->size == 0)+    return FFI_BAD_TYPEDEF;+  else+    return FFI_OK;+}++#ifndef __CRIS__+/* The CRIS ABI specifies structure elements to have byte+   alignment only, so it completely overrides this functions,+   which assumes "natural" alignment and padding.  */++/* Perform machine independent ffi_cif preparation, then call+   machine dependent routine. */++/* For non variadic functions isvariadic should be 0 and+   nfixedargs==ntotalargs.++   For variadic calls, isvariadic should be 1 and nfixedargs+   and ntotalargs set as appropriate. nfixedargs must always be >=1 */+++ffi_status FFI_HIDDEN 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)+{+  unsigned bytes = 0;+  unsigned int i;+  ffi_type **ptr;++  FFI_ASSERT(cif != NULL);+  FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));+  FFI_ASSERT(nfixedargs <= ntotalargs);++  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))+    return FFI_BAD_ABI;++  cif->abi = abi;+  cif->arg_types = atypes;+  cif->nargs = ntotalargs;+  cif->rtype = rtype;++  cif->flags = 0;+#if (defined(_M_ARM64) || defined(__aarch64__)) && defined(_WIN32)+  cif->is_variadic = isvariadic;+#endif+#if HAVE_LONG_DOUBLE_VARIANT+  ffi_prep_types (abi);+#endif++  /* Initialize the return type if necessary */+  if ((cif->rtype->size == 0)+      && (initialize_aggregate(cif->rtype, NULL) != FFI_OK))+    return FFI_BAD_TYPEDEF;++#ifndef FFI_TARGET_HAS_COMPLEX_TYPE+  if (rtype->type == FFI_TYPE_COMPLEX)+    abort();+#endif+  /* Perform a sanity check on the return type */+  FFI_ASSERT_VALID_TYPE(cif->rtype);++  /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */+#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION+  /* Make space for the return structure pointer */+  if (cif->rtype->type == FFI_TYPE_STRUCT+#ifdef TILE+      && (cif->rtype->size > 10 * FFI_SIZEOF_ARG)+#endif+#ifdef XTENSA+      && (cif->rtype->size > 16)+#endif+     )+    bytes = STACK_ARG_SIZE(sizeof(void*));+#endif++  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)+    {++      /* Initialize any uninitialized aggregate type definitions */+      if (((*ptr)->size == 0)+	  && (initialize_aggregate((*ptr), NULL) != FFI_OK))+	return FFI_BAD_TYPEDEF;++#ifndef FFI_TARGET_HAS_COMPLEX_TYPE+      if ((*ptr)->type == FFI_TYPE_COMPLEX)+	abort();+#endif+      /* Perform a sanity check on the argument type, do this+	 check after the initialization.  */+      FFI_ASSERT_VALID_TYPE(*ptr);++#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION+	{+	  /* Add any padding if necessary */+	  if (((*ptr)->alignment - 1) & bytes)+	    bytes = (unsigned)FFI_ALIGN(bytes, (*ptr)->alignment);++#ifdef TILE+	  if (bytes < 10 * FFI_SIZEOF_ARG &&+	      bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG)+	    {+	      /* An argument is never split between the 10 parameter+		 registers and the stack.  */+	      bytes = 10 * FFI_SIZEOF_ARG;+	    }+#endif+#ifdef XTENSA+	  if (bytes <= 6*4 && bytes + STACK_ARG_SIZE((*ptr)->size) > 6*4)+	    bytes = 6*4;+#endif++	  bytes += (unsigned int)STACK_ARG_SIZE((*ptr)->size);+	}+#endif+    }++  cif->bytes = bytes;++  /* Perform machine dependent cif processing */+#ifdef FFI_TARGET_SPECIFIC_VARIADIC+  if (isvariadic)+	return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);+#endif++  return ffi_prep_cif_machdep(cif);+}+#endif /* not __CRIS__ */++ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,+			     ffi_type *rtype, ffi_type **atypes)+{+  return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);+}++ffi_status ffi_prep_cif_var(ffi_cif *cif,+                            ffi_abi abi,+                            unsigned int nfixedargs,+                            unsigned int ntotalargs,+                            ffi_type *rtype,+                            ffi_type **atypes)+{+  ffi_status rc;+  size_t int_size = ffi_type_sint.size;+  unsigned int i;++  rc = ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);++  if (rc != FFI_OK)+    return rc;++  for (i = nfixedargs; i < ntotalargs; i++)+    {+      ffi_type *arg_type = atypes[i];+      if (arg_type == &ffi_type_float+          || ((arg_type->type != FFI_TYPE_STRUCT+               && arg_type->type != FFI_TYPE_COMPLEX)+              && arg_type->size < int_size))+        return FFI_BAD_ARGTYPE;+    }++  return FFI_OK;+}++#if FFI_CLOSURES++ffi_status+ffi_prep_closure (ffi_closure* closure,+		  ffi_cif* cif,+		  void (*fun)(ffi_cif*,void*,void**,void*),+		  void *user_data)+{+  return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);+}++#endif++ffi_status+ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)+{+  if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))+    return FFI_BAD_ABI;+  if (struct_type->type != FFI_TYPE_STRUCT)+    return FFI_BAD_TYPEDEF;++#if HAVE_LONG_DOUBLE_VARIANT+  ffi_prep_types (abi);+#endif++  return initialize_aggregate(struct_type, offsets);+}
+ src/raw_api.c view
@@ -0,0 +1,267 @@+/* -----------------------------------------------------------------------+   raw_api.c - Copyright (c) 1999, 2008  Red Hat, Inc.++   Author: Kresten Krab Thorup <krab@gnu.org>++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++/* This file defines generic functions for use with the raw api. */++#include <ffi.h>+#include <ffi_common.h>++#if !FFI_NO_RAW_API++size_t+ffi_raw_size (ffi_cif *cif)+{+  size_t result = 0;+  int i;++  ffi_type **at = cif->arg_types;++  for (i = cif->nargs-1; i >= 0; i--, at++)+    {+#if !FFI_NO_STRUCTS+      if ((*at)->type == FFI_TYPE_STRUCT)+	result += FFI_ALIGN (sizeof (void*), FFI_SIZEOF_ARG);+      else+#endif+	result += FFI_ALIGN ((*at)->size, FFI_SIZEOF_ARG);+    }++  return result;+}+++void+ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)+{+  unsigned i;+  ffi_type **tp = cif->arg_types;++#if WORDS_BIGENDIAN++  for (i = 0; i < cif->nargs; i++, tp++, args++)+    {	  +      switch ((*tp)->type)+	{+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	  *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 1);+	  break;+	  +	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	  *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 2);+	  break;++#if FFI_SIZEOF_ARG >= 4	  +	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	  *args = (void*) ((char*)(raw++) + FFI_SIZEOF_ARG - 4);+	  break;+#endif+	+#if !FFI_NO_STRUCTS  +	case FFI_TYPE_STRUCT:+	  *args = (raw++)->ptr;+	  break;+#endif++	case FFI_TYPE_COMPLEX:+	  *args = (raw++)->ptr;+	  break;++	case FFI_TYPE_POINTER:+	  *args = (void*) &(raw++)->ptr;+	  break;+	  +	default:+	  *args = raw;+	  raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;+	}+    }++#else /* WORDS_BIGENDIAN */++#if !PDP++  /* then assume little endian */+  for (i = 0; i < cif->nargs; i++, tp++, args++)+    {	  +#if !FFI_NO_STRUCTS+      if ((*tp)->type == FFI_TYPE_STRUCT)+	{+	  *args = (raw++)->ptr;+	}+      else+#endif+      if ((*tp)->type == FFI_TYPE_COMPLEX)+	{+	  *args = (raw++)->ptr;+	}+      else+	{+	  *args = (void*) raw;+	  raw += FFI_ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);+	}+    }++#else+#error "pdp endian not supported"+#endif /* ! PDP */++#endif /* WORDS_BIGENDIAN */+}++void+ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)+{+  unsigned i;+  ffi_type **tp = cif->arg_types;++  for (i = 0; i < cif->nargs; i++, tp++, args++)+    {	  +      switch ((*tp)->type)+	{+	case FFI_TYPE_UINT8:+	  (raw++)->uint = *(UINT8*) (*args);+	  break;++	case FFI_TYPE_SINT8:+	  (raw++)->sint = *(SINT8*) (*args);+	  break;++	case FFI_TYPE_UINT16:+	  (raw++)->uint = *(UINT16*) (*args);+	  break;++	case FFI_TYPE_SINT16:+	  (raw++)->sint = *(SINT16*) (*args);+	  break;++#if FFI_SIZEOF_ARG >= 4+	case FFI_TYPE_UINT32:+	  (raw++)->uint = *(UINT32*) (*args);+	  break;++	case FFI_TYPE_SINT32:+	  (raw++)->sint = *(SINT32*) (*args);+	  break;+#endif++#if !FFI_NO_STRUCTS+	case FFI_TYPE_STRUCT:+	  (raw++)->ptr = *args;+	  break;+#endif++	case FFI_TYPE_COMPLEX:+	  (raw++)->ptr = *args;+	  break;++	case FFI_TYPE_POINTER:+	  (raw++)->ptr = **(void***) args;+	  break;++	default:+	  memcpy ((void*) raw->data, (void*)*args, (*tp)->size);+	  raw += FFI_ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;+	}+    }+}++#if !FFI_NATIVE_RAW_API+++/* This is a generic definition of ffi_raw_call, to be used if the+ * native system does not provide a machine-specific implementation.+ * Having this, allows code to be written for the raw API, without+ * the need for system-specific code to handle input in that format;+ * these following couple of functions will handle the translation forth+ * and back automatically. */++void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)+{+  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));+  ffi_raw_to_ptrarray (cif, raw, avalue);+  ffi_call (cif, fn, rvalue, avalue);+}++#if FFI_CLOSURES		/* base system provides closures */++static void+ffi_translate_args (ffi_cif *cif, void *rvalue,+		    void **avalue, void *user_data)+{+  ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));+  ffi_raw_closure *cl = (ffi_raw_closure*)user_data;++  ffi_ptrarray_to_raw (cif, avalue, raw);+  (*cl->fun) (cif, rvalue, raw, cl->user_data);+}++ffi_status+ffi_prep_raw_closure_loc (ffi_raw_closure* cl,+			  ffi_cif *cif,+			  void (*fun)(ffi_cif*,void*,ffi_raw*,void*),+			  void *user_data,+			  void *codeloc)+{+  ffi_status status;++  status = ffi_prep_closure_loc ((ffi_closure*) cl,+				 cif,+				 &ffi_translate_args,+				 codeloc,+				 codeloc);+  if (status == FFI_OK)+    {+      cl->fun       = fun;+      cl->user_data = user_data;+    }++  return status;+}++#endif /* FFI_CLOSURES */+#endif /* !FFI_NATIVE_RAW_API */++#if FFI_CLOSURES++/* Again, here is the generic version of ffi_prep_raw_closure, which+ * will install an intermediate "hub" for translation of arguments from+ * the pointer-array format, to the raw format */++ffi_status+ffi_prep_raw_closure (ffi_raw_closure* cl,+		      ffi_cif *cif,+		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),+		      void *user_data)+{+  return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);+}++#endif /* FFI_CLOSURES */++#endif /* !FFI_NO_RAW_API */
+ src/riscv/ffi.c view
@@ -0,0 +1,514 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>+                         2015 Andrew Waterman <waterman@cs.berkeley.edu>+                         2018 Stef O'Rear <sorear2@gmail.com>+   Based on MIPS N32/64 port++   RISC-V Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdint.h>++#if __riscv_float_abi_double+#define ABI_FLEN 64+#define ABI_FLOAT double+#elif __riscv_float_abi_single+#define ABI_FLEN 32+#define ABI_FLOAT float+#endif++#define NARGREG 8+#define STKALIGN 16+#define MAXCOPYARG (2 * sizeof(double))++typedef struct call_context+{+#if ABI_FLEN+    ABI_FLOAT fa[8];+#endif+    size_t a[8];+    /* used by the assembly code to in-place construct its own stack frame */+    char frame[16];+} call_context;++typedef struct call_builder+{+    call_context *aregs;+    int used_integer;+    int used_float;+    size_t *used_stack;+    void *struct_stack;+} call_builder;++/* integer (not pointer) less than ABI XLEN */+/* FFI_TYPE_INT does not appear to be used */+#if __SIZEOF_POINTER__ == 8+#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT64)+#else+#define IS_INT(type) ((type) >= FFI_TYPE_UINT8 && (type) <= FFI_TYPE_SINT32)+#endif++#if ABI_FLEN+typedef struct {+    char as_elements, type1, offset2, type2;+} float_struct_info;++#if ABI_FLEN >= 64+#define IS_FLOAT(type) ((type) >= FFI_TYPE_FLOAT && (type) <= FFI_TYPE_DOUBLE)+#else+#define IS_FLOAT(type) ((type) == FFI_TYPE_FLOAT)+#endif++static ffi_type **flatten_struct(ffi_type *in, ffi_type **out, ffi_type **out_end) {+    int i;+    if (out == out_end) return out;+    if (in->type != FFI_TYPE_STRUCT) {+        *(out++) = in;+    } else {+        for (i = 0; in->elements[i]; i++)+            out = flatten_struct(in->elements[i], out, out_end);+    }+    return out;+}++/* Structs with at most two fields after flattening, one of which is of+   floating point type, are passed in multiple registers if sufficient+   registers are available. */+static float_struct_info struct_passed_as_elements(call_builder *cb, ffi_type *top) {+    float_struct_info ret = {0, 0, 0, 0};+    ffi_type *fields[3];+    int num_floats, num_ints;+    int num_fields = flatten_struct(top, fields, fields + 3) - fields;++    if (num_fields == 1) {+        if (IS_FLOAT(fields[0]->type)) {+            ret.as_elements = 1;+            ret.type1 = fields[0]->type;+        }+    } else if (num_fields == 2) {+        num_floats = IS_FLOAT(fields[0]->type) + IS_FLOAT(fields[1]->type);+        num_ints = IS_INT(fields[0]->type) + IS_INT(fields[1]->type);+        if (num_floats == 0 || num_floats + num_ints != 2)+            return ret;+        if (cb->used_float + num_floats > NARGREG || cb->used_integer + (2 - num_floats) > NARGREG)+            return ret;+        if (!IS_FLOAT(fields[0]->type) && !IS_FLOAT(fields[1]->type))+            return ret;++        ret.type1 = fields[0]->type;+        ret.type2 = fields[1]->type;+        ret.offset2 = FFI_ALIGN(fields[0]->size, fields[1]->alignment);+        ret.as_elements = 1;+    }++    return ret;+}+#endif++/* allocates a single register, float register, or XLEN-sized stack slot to a datum */+static void marshal_atom(call_builder *cb, int type, void *data) {+    size_t value = 0;+    switch (type) {+        case FFI_TYPE_UINT8: value = *(uint8_t *)data; break;+        case FFI_TYPE_SINT8: value = *(int8_t *)data; break;+        case FFI_TYPE_UINT16: value = *(uint16_t *)data; break;+        case FFI_TYPE_SINT16: value = *(int16_t *)data; break;+        /* 32-bit quantities are always sign-extended in the ABI */+        case FFI_TYPE_UINT32: value = *(int32_t *)data; break;+        case FFI_TYPE_SINT32: value = *(int32_t *)data; break;+#if __SIZEOF_POINTER__ == 8+        case FFI_TYPE_UINT64: value = *(uint64_t *)data; break;+        case FFI_TYPE_SINT64: value = *(int64_t *)data; break;+#endif+        case FFI_TYPE_POINTER: value = *(size_t *)data; break;++        /* float values may be recoded in an implementation-defined way+           by hardware conforming to 2.1 or earlier, so use asm to+           reinterpret floats as doubles */+#if ABI_FLEN >= 32+        case FFI_TYPE_FLOAT:+            asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(float *)data));+            return;+#endif+#if ABI_FLEN >= 64+        case FFI_TYPE_DOUBLE:+            asm("" : "=f"(cb->aregs->fa[cb->used_float++]) : "0"(*(double *)data));+            return;+#endif+        default: FFI_ASSERT(0); break;+    }++    if (cb->used_integer == NARGREG) {+        *cb->used_stack++ = value;+    } else {+        cb->aregs->a[cb->used_integer++] = value;+    }+}++static void unmarshal_atom(call_builder *cb, int type, void *data) {+    size_t value;+    switch (type) {+#if ABI_FLEN >= 32+        case FFI_TYPE_FLOAT:+            asm("" : "=f"(*(float *)data) : "0"(cb->aregs->fa[cb->used_float++]));+            return;+#endif+#if ABI_FLEN >= 64+        case FFI_TYPE_DOUBLE:+            asm("" : "=f"(*(double *)data) : "0"(cb->aregs->fa[cb->used_float++]));+            return;+#endif+    }++    if (cb->used_integer == NARGREG) {+        value = *cb->used_stack++;+    } else {+        value = cb->aregs->a[cb->used_integer++];+    }++    switch (type) {+        case FFI_TYPE_UINT8: *(uint8_t *)data = value; break;+        case FFI_TYPE_SINT8: *(uint8_t *)data = value; break;+        case FFI_TYPE_UINT16: *(uint16_t *)data = value; break;+        case FFI_TYPE_SINT16: *(uint16_t *)data = value; break;+        case FFI_TYPE_UINT32: *(uint32_t *)data = value; break;+        case FFI_TYPE_SINT32: *(uint32_t *)data = value; break;+#if __SIZEOF_POINTER__ == 8+        case FFI_TYPE_UINT64: *(uint64_t *)data = value; break;+        case FFI_TYPE_SINT64: *(uint64_t *)data = value; break;+#endif+        case FFI_TYPE_POINTER: *(size_t *)data = value; break;+        default: FFI_ASSERT(0); break;+    }+}++/* adds an argument to a call, or a not by reference return value */+static void marshal(call_builder *cb, ffi_type *type, int var, void *data) {+    size_t realign[2];++#if ABI_FLEN+    if (!var && type->type == FFI_TYPE_STRUCT) {+        float_struct_info fsi = struct_passed_as_elements(cb, type);+        if (fsi.as_elements) {+            marshal_atom(cb, fsi.type1, data);+            if (fsi.offset2)+                marshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2);+            return;+        }+    }++    if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) {+        marshal_atom(cb, type->type, data);+        return;+    }+#endif++    if (type->size > 2 * __SIZEOF_POINTER__) {+        /* copy to stack and pass by reference */+        data = memcpy (cb->struct_stack, data, type->size);+        cb->struct_stack = (size_t *) FFI_ALIGN ((char *) cb->struct_stack + type->size, __SIZEOF_POINTER__);+        marshal_atom(cb, FFI_TYPE_POINTER, &data);+    } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {+        marshal_atom(cb, type->type, data);+    } else {+        /* overlong integers, soft-float floats, and structs without special+           float handling are treated identically from this point on */++        /* variadics are aligned even in registers */+        if (type->alignment > __SIZEOF_POINTER__) {+            if (var)+                cb->used_integer = FFI_ALIGN(cb->used_integer, 2);+            cb->used_stack = (size_t *)FFI_ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__);+        }++        memcpy(realign, data, type->size);+        if (type->size > 0)+            marshal_atom(cb, FFI_TYPE_POINTER, realign);+        if (type->size > __SIZEOF_POINTER__)+            marshal_atom(cb, FFI_TYPE_POINTER, realign + 1);+    }+}++/* for arguments passed by reference returns the pointer, otherwise the arg is copied (up to MAXCOPYARG bytes) */+static void *unmarshal(call_builder *cb, ffi_type *type, int var, void *data) {+    size_t realign[2];+    void *pointer;++#if ABI_FLEN+    if (!var && type->type == FFI_TYPE_STRUCT) {+        float_struct_info fsi = struct_passed_as_elements(cb, type);+        if (fsi.as_elements) {+            unmarshal_atom(cb, fsi.type1, data);+            if (fsi.offset2)+                unmarshal_atom(cb, fsi.type2, ((char*)data) + fsi.offset2);+            return data;+        }+    }++    if (!var && cb->used_float < NARGREG && IS_FLOAT(type->type)) {+        unmarshal_atom(cb, type->type, data);+        return data;+    }+#endif++    if (type->size > 2 * __SIZEOF_POINTER__) {+        /* pass by reference */+        unmarshal_atom(cb, FFI_TYPE_POINTER, (char*)&pointer);+        return pointer;+    } else if (IS_INT(type->type) || type->type == FFI_TYPE_POINTER) {+        unmarshal_atom(cb, type->type, data);+        return data;+    } else {+        /* overlong integers, soft-float floats, and structs without special+           float handling are treated identically from this point on */++        /* variadics are aligned even in registers */+        if (type->alignment > __SIZEOF_POINTER__) {+            if (var)+                cb->used_integer = FFI_ALIGN(cb->used_integer, 2);+            cb->used_stack = (size_t *)FFI_ALIGN(cb->used_stack, 2*__SIZEOF_POINTER__);+        }++        if (type->size > 0)+            unmarshal_atom(cb, FFI_TYPE_POINTER, realign);+        if (type->size > __SIZEOF_POINTER__)+            unmarshal_atom(cb, FFI_TYPE_POINTER, realign + 1);+        memcpy(data, realign, type->size);+        return data;+    }+}++static int passed_by_ref(call_builder *cb, ffi_type *type, int var) {+#if ABI_FLEN+    if (!var && type->type == FFI_TYPE_STRUCT) {+        float_struct_info fsi = struct_passed_as_elements(cb, type);+        if (fsi.as_elements) return 0;+    }+#endif++    return type->size > 2 * __SIZEOF_POINTER__;+}++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif) {+    cif->riscv_nfixedargs = cif->nargs;+    return FFI_OK;+}++/* Perform machine dependent cif processing when we have a variadic function */++ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs, unsigned int ntotalargs) {+    cif->riscv_nfixedargs = nfixedargs;+    return FFI_OK;+}++/* Low level routine for calling functions */+extern void ffi_call_asm (void *stack, struct call_context *regs,+			  void (*fn) (void), void *closure) FFI_HIDDEN;++static void+ffi_call_int (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,+	      void *closure)+{+    /* this is a conservative estimate, assuming a complex return value and+       that all remaining arguments are long long / __int128 */+    size_t arg_bytes = cif->nargs <= 3 ? 0 :+        FFI_ALIGN(2 * sizeof(size_t) * (cif->nargs - 3), STKALIGN);+    /* Allocate space for copies of big structures.  */+    size_t struct_bytes = FFI_ALIGN (cif->bytes, STKALIGN);+    size_t rval_bytes = 0;+    if (rvalue == NULL && cif->rtype->size > 2*__SIZEOF_POINTER__)+        rval_bytes = FFI_ALIGN(cif->rtype->size, STKALIGN);+    size_t alloc_size = arg_bytes + rval_bytes + struct_bytes + sizeof(call_context);++    /* the assembly code will deallocate all stack data at lower addresses+       than the argument region, so we need to allocate the frame and the+       return value after the arguments in a single allocation */+    size_t alloc_base;+    /* Argument region must be 16-byte aligned */+    if (_Alignof(max_align_t) >= STKALIGN) {+        /* since sizeof long double is normally 16, the compiler will+           guarantee alloca alignment to at least that much */+        alloc_base = (size_t)alloca(alloc_size);+    } else {+        alloc_base = FFI_ALIGN(alloca(alloc_size + STKALIGN - 1), STKALIGN);+    }++    if (rval_bytes)+        rvalue = (void*)(alloc_base + arg_bytes);++    call_builder cb;+    cb.used_float = cb.used_integer = 0;+    cb.aregs = (call_context*)(alloc_base + arg_bytes + rval_bytes + struct_bytes);+    cb.used_stack = (void*)alloc_base;+    cb.struct_stack = (void *) (alloc_base + arg_bytes + rval_bytes);++    int return_by_ref = passed_by_ref(&cb, cif->rtype, 0);+    if (return_by_ref)+        marshal(&cb, &ffi_type_pointer, 0, &rvalue);++    int i;+    for (i = 0; i < cif->nargs; i++)+        marshal(&cb, cif->arg_types[i], i >= cif->riscv_nfixedargs, avalue[i]);++    ffi_call_asm ((void *) alloc_base, cb.aregs, fn, closure);++    cb.used_float = cb.used_integer = 0;+    if (!return_by_ref && rvalue)+      {+	if (IS_INT(cif->rtype->type)+	    && cif->rtype->size < sizeof (ffi_arg))+	  {+	    /* Integer types smaller than ffi_arg need to be extended.  */+	    switch (cif->rtype->type)+	      {+	      case FFI_TYPE_SINT8:+	      case FFI_TYPE_SINT16:+	      case FFI_TYPE_SINT32:+		unmarshal_atom (&cb, (sizeof (ffi_arg) > 4+				      ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32),+				rvalue);+		break;+	      case FFI_TYPE_UINT8:+	      case FFI_TYPE_UINT16:+	      case FFI_TYPE_UINT32:+		unmarshal_atom (&cb, (sizeof (ffi_arg) > 4+				      ? FFI_TYPE_UINT64 : FFI_TYPE_UINT32),+				rvalue);+		break;+	      }+	  }+	else+	  unmarshal(&cb, cif->rtype, 0, rvalue);+      }+}++void+ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)+{+  ffi_call_int(cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int(cif, fn, rvalue, avalue, closure);+}++extern void ffi_closure_asm(void) FFI_HIDDEN;++ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, void *codeloc)+{+    uint32_t *tramp = (uint32_t *) &closure->tramp[0];+    uint64_t fn = (uint64_t) (uintptr_t) ffi_closure_asm;++    if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)+        return FFI_BAD_ABI;++    /* we will call ffi_closure_inner with codeloc, not closure, but as long+       as the memory is readable it should work */++    tramp[0] = 0x00000317; /* auipc t1, 0 (i.e. t0 <- codeloc) */+#if __SIZEOF_POINTER__ == 8+    tramp[1] = 0x01033383; /* ld t2, 16(t1) */+#else+    tramp[1] = 0x01032383; /* lw t2, 16(t1) */+#endif+    tramp[2] = 0x00038067; /* jr t2 */+    tramp[3] = 0x00000013; /* nop */+    tramp[4] = fn;+    tramp[5] = fn >> 32;++    closure->cif = cif;+    closure->fun = fun;+    closure->user_data = user_data;++#if !defined(__FreeBSD__)+    __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE);+#endif++    return FFI_OK;+}++extern void ffi_go_closure_asm (void) FFI_HIDDEN;++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,+		     void (*fun) (ffi_cif *, void *, void **, void *))+{+  if (cif->abi <= FFI_FIRST_ABI || cif->abi >= FFI_LAST_ABI)+    return FFI_BAD_ABI;++  closure->tramp = (void *) ffi_go_closure_asm;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++/* Called by the assembly code with aregs pointing to saved argument registers+   and stack pointing to the stacked arguments.  Return values passed in+   registers will be reloaded from aregs. */+void FFI_HIDDEN+ffi_closure_inner (ffi_cif *cif,+		   void (*fun) (ffi_cif *, void *, void **, void *),+		   void *user_data,+		   size_t *stack, call_context *aregs)+{+    void **avalue = alloca(cif->nargs * sizeof(void*));+    /* storage for arguments which will be copied by unmarshal().  We could+       theoretically avoid the copies in many cases and use at most 128 bytes+       of memory, but allocating disjoint storage for each argument is+       simpler. */+    char *astorage = alloca(cif->nargs * MAXCOPYARG);+    void *rvalue;+    call_builder cb;+    int return_by_ref;+    int i;++    cb.aregs = aregs;+    cb.used_integer = cb.used_float = 0;+    cb.used_stack = stack;++    return_by_ref = passed_by_ref(&cb, cif->rtype, 0);+    if (return_by_ref)+        unmarshal(&cb, &ffi_type_pointer, 0, &rvalue);+    else+        rvalue = alloca(cif->rtype->size);++    for (i = 0; i < cif->nargs; i++)+        avalue[i] = unmarshal(&cb, cif->arg_types[i],+            i >= cif->riscv_nfixedargs, astorage + i*MAXCOPYARG);++    fun (cif, rvalue, avalue, user_data);++    if (!return_by_ref && cif->rtype->type != FFI_TYPE_VOID) {+        cb.used_integer = cb.used_float = 0;+        marshal(&cb, cif->rtype, 0, rvalue);+    }+}
+ src/riscv/ffitarget.h view
@@ -0,0 +1,69 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - 2014 Michael Knyszek++   Target configuration macros for RISC-V.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef __riscv+#error "libffi was configured for a RISC-V target but this does not appear to be a RISC-V compiler."+#endif++#ifndef LIBFFI_ASM++typedef unsigned long ffi_arg;+typedef   signed long ffi_sarg;++/* FFI_UNUSED_NN and riscv_unused are to maintain ABI compatibility with a+   distributed Berkeley patch from 2014, and can be removed at SONAME bump */+typedef enum ffi_abi {+    FFI_FIRST_ABI = 0,+    FFI_SYSV,+    FFI_UNUSED_1,+    FFI_UNUSED_2,+    FFI_UNUSED_3,+    FFI_LAST_ABI,++    FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;++#endif /* LIBFFI_ASM */++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 24+#define FFI_NATIVE_RAW_API 0+#define FFI_EXTRA_CIF_FIELDS unsigned riscv_nfixedargs; unsigned riscv_unused;+#define FFI_TARGET_SPECIFIC_VARIADIC++#endif+
+ src/riscv/sysv.S view
@@ -0,0 +1,293 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>+                         2015 Andrew Waterman <waterman@cs.berkeley.edu>+                         2018 Stef O'Rear <sorear2@gmail.com>++   RISC-V Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++/* Define aliases so that we can handle all ABIs uniformly */++#if __SIZEOF_POINTER__ == 8+#define PTRS 8+#define LARG ld+#define SARG sd+#else+#define PTRS 4+#define LARG lw+#define SARG sw+#endif++#if __riscv_float_abi_double+#define FLTS 8+#define FLARG fld+#define FSARG fsd+#elif __riscv_float_abi_single+#define FLTS 4+#define FLARG flw+#define FSARG fsw+#else+#define FLTS 0+#endif++#define fp s0++    .text+    .globl  ffi_call_asm+    .type   ffi_call_asm, @function+    .hidden ffi_call_asm+/*+  struct call_context {+      floatreg fa[8];+      intreg a[8];+      intreg pad[rv32 ? 2 : 0];+      intreg save_fp, save_ra;+  }+  void ffi_call_asm (size_t *stackargs, struct call_context *regargs,+                     void (*fn) (void), void *closure);+*/++#define FRAME_LEN (8 * FLTS + 8 * PTRS + 16)++ffi_call_asm:+    .cfi_startproc++    /*+      We are NOT going to set up an ordinary stack frame.  In order to pass+      the stacked args to the called function, we adjust our stack pointer to+      a0, which is in the _caller's_ alloca area.  We establish our own stack+      frame at the end of the call_context.++      Anything below the arguments will be freed at this point, although we+      preserve the call_context so that it can be read back in the caller.+    */++    .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1+    SARG    fp, FRAME_LEN - 2*PTRS(a1)+    .cfi_offset 8, -2*PTRS+    SARG    ra, FRAME_LEN - 1*PTRS(a1)+    .cfi_offset 1, -1*PTRS++    addi    fp, a1, FRAME_LEN+    mv      sp, a0+    .cfi_def_cfa 8, 0 # our frame is fully set up++    # Load arguments+    mv      t1, a2+    mv      t2, a3++#if FLTS+    FLARG   fa0, -FRAME_LEN+0*FLTS(fp)+    FLARG   fa1, -FRAME_LEN+1*FLTS(fp)+    FLARG   fa2, -FRAME_LEN+2*FLTS(fp)+    FLARG   fa3, -FRAME_LEN+3*FLTS(fp)+    FLARG   fa4, -FRAME_LEN+4*FLTS(fp)+    FLARG   fa5, -FRAME_LEN+5*FLTS(fp)+    FLARG   fa6, -FRAME_LEN+6*FLTS(fp)+    FLARG   fa7, -FRAME_LEN+7*FLTS(fp)+#endif++    LARG    a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)+    LARG    a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)+    LARG    a2, -FRAME_LEN+8*FLTS+2*PTRS(fp)+    LARG    a3, -FRAME_LEN+8*FLTS+3*PTRS(fp)+    LARG    a4, -FRAME_LEN+8*FLTS+4*PTRS(fp)+    LARG    a5, -FRAME_LEN+8*FLTS+5*PTRS(fp)+    LARG    a6, -FRAME_LEN+8*FLTS+6*PTRS(fp)+    LARG    a7, -FRAME_LEN+8*FLTS+7*PTRS(fp)++    /* Call */+    jalr    t1++    /* Save return values - only a0/a1 (fa0/fa1) are used */+#if FLTS+    FSARG   fa0, -FRAME_LEN+0*FLTS(fp)+    FSARG   fa1, -FRAME_LEN+1*FLTS(fp)+#endif++    SARG    a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)+    SARG    a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)++    /* Restore and return */+    addi    sp, fp, -FRAME_LEN+    .cfi_def_cfa 2, FRAME_LEN+    LARG    ra, -1*PTRS(fp)+    .cfi_restore 1+    LARG    fp, -2*PTRS(fp)+    .cfi_restore 8+    ret+    .cfi_endproc+    .size   ffi_call_asm, .-ffi_call_asm+++/*+  ffi_closure_asm. Expects address of the passed-in ffi_closure in t1.+  void ffi_closure_inner (ffi_cif *cif,+		          void (*fun) (ffi_cif *, void *, void **, void *),+		          void *user_data,+		          size_t *stackargs, struct call_context *regargs)+*/++    .globl ffi_closure_asm+    .hidden ffi_closure_asm+    .type ffi_closure_asm, @function+ffi_closure_asm:+    .cfi_startproc++    addi    sp,  sp, -FRAME_LEN+    .cfi_def_cfa_offset FRAME_LEN++    /* make a frame */+    SARG    fp, FRAME_LEN - 2*PTRS(sp)+    .cfi_offset 8, -2*PTRS+    SARG    ra, FRAME_LEN - 1*PTRS(sp)+    .cfi_offset 1, -1*PTRS+    addi    fp, sp, FRAME_LEN++    /* save arguments */+#if FLTS+    FSARG   fa0, 0*FLTS(sp)+    FSARG   fa1, 1*FLTS(sp)+    FSARG   fa2, 2*FLTS(sp)+    FSARG   fa3, 3*FLTS(sp)+    FSARG   fa4, 4*FLTS(sp)+    FSARG   fa5, 5*FLTS(sp)+    FSARG   fa6, 6*FLTS(sp)+    FSARG   fa7, 7*FLTS(sp)+#endif++    SARG    a0, 8*FLTS+0*PTRS(sp)+    SARG    a1, 8*FLTS+1*PTRS(sp)+    SARG    a2, 8*FLTS+2*PTRS(sp)+    SARG    a3, 8*FLTS+3*PTRS(sp)+    SARG    a4, 8*FLTS+4*PTRS(sp)+    SARG    a5, 8*FLTS+5*PTRS(sp)+    SARG    a6, 8*FLTS+6*PTRS(sp)+    SARG    a7, 8*FLTS+7*PTRS(sp)++    /* enter C */+    LARG    a0, FFI_TRAMPOLINE_SIZE+0*PTRS(t1)+    LARG    a1, FFI_TRAMPOLINE_SIZE+1*PTRS(t1)+    LARG    a2, FFI_TRAMPOLINE_SIZE+2*PTRS(t1)+    addi    a3, sp, FRAME_LEN+    mv      a4, sp++    call    ffi_closure_inner++    /* return values */+#if FLTS+    FLARG   fa0, 0*FLTS(sp)+    FLARG   fa1, 1*FLTS(sp)+#endif++    LARG    a0, 8*FLTS+0*PTRS(sp)+    LARG    a1, 8*FLTS+1*PTRS(sp)++    /* restore and return */+    LARG    ra, FRAME_LEN-1*PTRS(sp)+    .cfi_restore 1+    LARG    fp, FRAME_LEN-2*PTRS(sp)+    .cfi_restore 8+    addi    sp, sp, FRAME_LEN+    .cfi_def_cfa_offset 0+    ret+    .cfi_endproc+    .size ffi_closure_asm, .-ffi_closure_asm++/*+  ffi_go_closure_asm.  Expects address of the passed-in ffi_go_closure in t2.+  void ffi_closure_inner (ffi_cif *cif,+		          void (*fun) (ffi_cif *, void *, void **, void *),+		          void *user_data,+		          size_t *stackargs, struct call_context *regargs)+*/++    .globl ffi_go_closure_asm+    .hidden ffi_go_closure_asm+    .type ffi_go_closure_asm, @function+ffi_go_closure_asm:+    .cfi_startproc++    addi    sp,  sp, -FRAME_LEN+    .cfi_def_cfa_offset FRAME_LEN++    /* make a frame */+    SARG    fp, FRAME_LEN - 2*PTRS(sp)+    .cfi_offset 8, -2*PTRS+    SARG    ra, FRAME_LEN - 1*PTRS(sp)+    .cfi_offset 1, -1*PTRS+    addi    fp, sp, FRAME_LEN++    /* save arguments */+#if FLTS+    FSARG   fa0, 0*FLTS(sp)+    FSARG   fa1, 1*FLTS(sp)+    FSARG   fa2, 2*FLTS(sp)+    FSARG   fa3, 3*FLTS(sp)+    FSARG   fa4, 4*FLTS(sp)+    FSARG   fa5, 5*FLTS(sp)+    FSARG   fa6, 6*FLTS(sp)+    FSARG   fa7, 7*FLTS(sp)+#endif++    SARG    a0, 8*FLTS+0*PTRS(sp)+    SARG    a1, 8*FLTS+1*PTRS(sp)+    SARG    a2, 8*FLTS+2*PTRS(sp)+    SARG    a3, 8*FLTS+3*PTRS(sp)+    SARG    a4, 8*FLTS+4*PTRS(sp)+    SARG    a5, 8*FLTS+5*PTRS(sp)+    SARG    a6, 8*FLTS+6*PTRS(sp)+    SARG    a7, 8*FLTS+7*PTRS(sp)++    /* enter C */+    LARG    a0, 1*PTRS(t2)+    LARG    a1, 2*PTRS(t2)+    mv      a2, t2+    addi    a3, sp, FRAME_LEN+    mv      a4, sp++    call    ffi_closure_inner++    /* return values */+#if FLTS+    FLARG   fa0, 0*FLTS(sp)+    FLARG   fa1, 1*FLTS(sp)+#endif++    LARG    a0, 8*FLTS+0*PTRS(sp)+    LARG    a1, 8*FLTS+1*PTRS(sp)++    /* restore and return */+    LARG    ra, FRAME_LEN-1*PTRS(sp)+    .cfi_restore 1+    LARG    fp, FRAME_LEN-2*PTRS(sp)+    .cfi_restore 8+    addi    sp, sp, FRAME_LEN+    .cfi_def_cfa_offset 0+    ret+    .cfi_endproc+    .size ffi_go_closure_asm, .-ffi_go_closure_asm
+ src/s390/ffi.c view
@@ -0,0 +1,783 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2000, 2007 Software AG+           Copyright (c) 2008 Red Hat, Inc++   S390 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 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.+   ----------------------------------------------------------------------- */+/*====================================================================*/+/*                          Includes                                  */+/*                          --------                                  */+/*====================================================================*/++#include <ffi.h>+#include <ffi_common.h>+#include <stdint.h>+#include "internal.h"+#include <tramp.h>++/*====================== End of Includes =============================*/++/*====================================================================*/+/*                           Defines                                  */+/*                           -------                                  */+/*====================================================================*/++/* Maximum number of GPRs available for argument passing.  */+#define MAX_GPRARGS 5++/* Maximum number of FPRs available for argument passing.  */+#ifdef __s390x__+#define MAX_FPRARGS 4+#else+#define MAX_FPRARGS 2+#endif++/* Round to multiple of 16.  */+#define ROUND_SIZE(size) (((size) + 15) & ~15)++/*===================== End of Defines ===============================*/++/*====================================================================*/+/*                          Externals                                 */+/*                          ---------                                 */+/*====================================================================*/++struct call_frame+{+  void *back_chain;+  void *eos;+  unsigned long gpr_args[5];+  unsigned long gpr_save[9];+  unsigned long long fpr_args[4];+};++extern void FFI_HIDDEN ffi_call_SYSV(struct call_frame *, unsigned, void *,+			             void (*fn)(void), void *);++extern void ffi_closure_SYSV(void);+extern void ffi_go_closure_SYSV(void);++/*====================== End of Externals ============================*/++/*====================================================================*/+/*                                                                    */+/* Name     - ffi_check_struct_type.                                  */+/*                                                                    */+/* Function - Determine if a structure can be passed within a         */+/*            general purpose or floating point register.             */+/*                                                                    */+/*====================================================================*/++static int+ffi_check_struct_type (ffi_type *arg)+{+  size_t size = arg->size;++  /* If the struct has just one element, look at that element+     to find out whether to consider the struct as floating point.  */+  while (arg->type == FFI_TYPE_STRUCT+         && arg->elements[0] && !arg->elements[1])+    arg = arg->elements[0];++  /* Structs of size 1, 2, 4, and 8 are passed in registers,+     just like the corresponding int/float types.  */+  switch (size)+    {+      case 1:+        return FFI_TYPE_UINT8;++      case 2:+        return FFI_TYPE_UINT16;++      case 4:+	if (arg->type == FFI_TYPE_FLOAT)+          return FFI_TYPE_FLOAT;+	else+	  return FFI_TYPE_UINT32;++      case 8:+	if (arg->type == FFI_TYPE_DOUBLE)+          return FFI_TYPE_DOUBLE;+	else+	  return FFI_TYPE_UINT64;++      default:+	break;+    }++  /* Other structs are passed via a pointer to the data.  */+  return FFI_TYPE_POINTER;+}++/*======================== End of Routine ============================*/++/*====================================================================*/+/*                                                                    */+/* Name     - ffi_prep_cif_machdep.                                   */+/*                                                                    */+/* Function - Perform machine dependent CIF processing.               */+/*                                                                    */+/*====================================================================*/++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep(ffi_cif *cif)+{+  size_t struct_size = 0;+  int n_gpr = 0;+  int n_fpr = 0;+  int n_ov = 0;++  ffi_type **ptr;+  int i;++  /* Determine return value handling.  */++  switch (cif->rtype->type)+    {+      /* Void is easy.  */+      case FFI_TYPE_VOID:+	cif->flags = FFI390_RET_VOID;+	break;++      /* Structures and complex are returned via a hidden pointer.  */+      case FFI_TYPE_STRUCT:+      case FFI_TYPE_COMPLEX:+	cif->flags = FFI390_RET_STRUCT;+	n_gpr++;  /* We need one GPR to pass the pointer.  */+	break;++      /* Floating point values are returned in fpr 0.  */+      case FFI_TYPE_FLOAT:+	cif->flags = FFI390_RET_FLOAT;+	break;++      case FFI_TYPE_DOUBLE:+	cif->flags = FFI390_RET_DOUBLE;+	break;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+      case FFI_TYPE_LONGDOUBLE:+	cif->flags = FFI390_RET_STRUCT;+	n_gpr++;+	break;+#endif+      /* Integer values are returned in gpr 2 (and gpr 3+	 for 64-bit values on 31-bit machines).  */+      case FFI_TYPE_UINT64:+      case FFI_TYPE_SINT64:+	cif->flags = FFI390_RET_INT64;+	break;++      case FFI_TYPE_POINTER:+      case FFI_TYPE_INT:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_SINT32:+      case FFI_TYPE_UINT16:+      case FFI_TYPE_SINT16:+      case FFI_TYPE_UINT8:+      case FFI_TYPE_SINT8:+	/* These are to be extended to word size.  */+#ifdef __s390x__+	cif->flags = FFI390_RET_INT64;+#else+	cif->flags = FFI390_RET_INT32;+#endif+	break;++      default:+        FFI_ASSERT (0);+        break;+    }++  /* Now for the arguments.  */++  for (ptr = cif->arg_types, i = cif->nargs;+       i > 0;+       i--, ptr++)+    {+      int type = (*ptr)->type;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+      /* 16-byte long double is passed like a struct.  */+      if (type == FFI_TYPE_LONGDOUBLE)+	type = FFI_TYPE_STRUCT;+#endif++      /* Check how a structure type is passed.  */+      if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)+	{+	  if (type == FFI_TYPE_COMPLEX)+	    type = FFI_TYPE_POINTER;+	  else+	    type = ffi_check_struct_type (*ptr);++	  /* If we pass the struct via pointer, we must reserve space+	     to copy its data for proper call-by-value semantics.  */+	  if (type == FFI_TYPE_POINTER)+	    struct_size += ROUND_SIZE ((*ptr)->size);+	}++      /* Now handle all primitive int/float data types.  */+      switch (type)+	{+	  /* The first MAX_FPRARGS floating point arguments+	     go in FPRs, the rest overflow to the stack.  */++	  case FFI_TYPE_DOUBLE:+	    if (n_fpr < MAX_FPRARGS)+	      n_fpr++;+	    else+	      n_ov += sizeof (double) / sizeof (long);+	    break;++	  case FFI_TYPE_FLOAT:+	    if (n_fpr < MAX_FPRARGS)+	      n_fpr++;+	    else+	      n_ov++;+	    break;++	  /* On 31-bit machines, 64-bit integers are passed in GPR pairs,+	     if one is still available, or else on the stack.  If only one+	     register is free, skip the register (it won't be used for any+	     subsequent argument either).  */++#ifndef __s390x__+	  case FFI_TYPE_UINT64:+	  case FFI_TYPE_SINT64:+	    if (n_gpr == MAX_GPRARGS-1)+	      n_gpr = MAX_GPRARGS;+	    if (n_gpr < MAX_GPRARGS)+	      n_gpr += 2;+	    else+	      n_ov += 2;+	    break;+#endif++	  /* Everything else is passed in GPRs (until MAX_GPRARGS+	     have been used) or overflows to the stack.  */++	  default:+	    if (n_gpr < MAX_GPRARGS)+	      n_gpr++;+	    else+	      n_ov++;+	    break;+        }+    }++  /* Total stack space as required for overflow arguments+     and temporary structure copies.  */++  cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;++  return FFI_OK;+}++/*======================== End of Routine ============================*/++/*====================================================================*/+/*                                                                    */+/* Name     - ffi_call.                                               */+/*                                                                    */+/* Function - Call the FFI routine.                                   */+/*                                                                    */+/*====================================================================*/++static void+ffi_call_int(ffi_cif *cif,+	     void (*fn)(void),+	     void *rvalue,+	     void **avalue,+	     void *closure)+{+  int ret_type = cif->flags;+  size_t rsize = 0, bytes = cif->bytes;+  unsigned char *stack, *p_struct;+  struct call_frame *frame;+  unsigned long *p_ov, *p_gpr;+  unsigned long long *p_fpr;+  int n_fpr, n_gpr, n_ov, i, n;+  ffi_type **arg_types;++  FFI_ASSERT (cif->abi == FFI_SYSV);++  /* If we don't have a return value, we need to fake one.  */+  if (rvalue == NULL)+    {+      if (ret_type & FFI390_RET_IN_MEM)+	rsize = cif->rtype->size;+      else+	ret_type = FFI390_RET_VOID;+    }++  /* The stack space will be filled with those areas:++	dummy structure return		    (highest addresses)+	  FPR argument register save area+	  GPR argument register save area+	stack frame for ffi_call_SYSV+	temporary struct copies+	overflow argument area              (lowest addresses)++     We set up the following pointers:++        p_fpr: bottom of the FPR area (growing upwards)+	p_gpr: bottom of the GPR area (growing upwards)+	p_ov: bottom of the overflow area (growing upwards)+	p_struct: top of the struct copy area (growing downwards)++     All areas are kept aligned to twice the word size.++     Note that we're going to create the stack frame for both+     ffi_call_SYSV _and_ the target function right here.  This+     works because we don't make any function calls with more+     than 5 arguments (indeed only memcpy and ffi_call_SYSV),+     and thus we don't have any stacked outgoing parameters.  */++  stack = alloca (bytes + sizeof(struct call_frame) + rsize);+  frame = (struct call_frame *)(stack + bytes);+  if (rsize)+    rvalue = frame + 1;++  /* Link the new frame back to the one from this function.  */+  frame->back_chain = __builtin_frame_address (0);++  /* Fill in all of the argument stuff.  */+  p_ov = (unsigned long *)stack;+  p_struct = (unsigned char *)frame;+  p_gpr = frame->gpr_args;+  p_fpr = frame->fpr_args;+  n_fpr = n_gpr = n_ov = 0;++  /* If we returning a structure then we set the first parameter register+     to the address of where we are returning this structure.  */+  if (cif->flags & FFI390_RET_IN_MEM)+    p_gpr[n_gpr++] = (uintptr_t) rvalue;++  /* Now for the arguments.  */+  arg_types = cif->arg_types;+  for (i = 0, n = cif->nargs; i < n; ++i)+    {+      ffi_type *ty = arg_types[i];+      void *arg = avalue[i];+      int type = ty->type;+      ffi_arg val;++    restart:+      switch (type)+	{+	case FFI_TYPE_SINT8:+	  val = *(SINT8 *)arg;+	  goto do_int;+	case FFI_TYPE_UINT8:+	  val = *(UINT8 *)arg;+	  goto do_int;+	case FFI_TYPE_SINT16:+	  val = *(SINT16 *)arg;+	  goto do_int;+	case FFI_TYPE_UINT16:+	  val = *(UINT16 *)arg;+	  goto do_int;+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT32:+	  val = *(SINT32 *)arg;+	  goto do_int;+	case FFI_TYPE_UINT32:+	  val = *(UINT32 *)arg;+	  goto do_int;+	case FFI_TYPE_POINTER:+	  val = *(uintptr_t *)arg;+	do_int:+	  *(n_gpr < MAX_GPRARGS ? p_gpr + n_gpr++ : p_ov + n_ov++) = val;+	  break;++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+#ifdef __s390x__+	  val = *(UINT64 *)arg;+	  goto do_int;+#else+	  if (n_gpr == MAX_GPRARGS-1)+	    n_gpr = MAX_GPRARGS;+	  if (n_gpr < MAX_GPRARGS)+	    p_gpr[n_gpr++] = ((UINT32 *) arg)[0],+	    p_gpr[n_gpr++] = ((UINT32 *) arg)[1];+	  else+	    p_ov[n_ov++] = ((UINT32 *) arg)[0],+	    p_ov[n_ov++] = ((UINT32 *) arg)[1];+#endif+	  break;++	case FFI_TYPE_DOUBLE:+	  if (n_fpr < MAX_FPRARGS)+	    p_fpr[n_fpr++] = *(UINT64 *) arg;+	  else+	    {+#ifdef __s390x__+	      p_ov[n_ov++] = *(UINT64 *) arg;+#else+	      p_ov[n_ov++] = ((UINT32 *) arg)[0],+	      p_ov[n_ov++] = ((UINT32 *) arg)[1];+#endif+	    }+	  break;++	case FFI_TYPE_FLOAT:+	  val = *(UINT32 *)arg;+	  if (n_fpr < MAX_FPRARGS)+	    p_fpr[n_fpr++] = (UINT64)val << 32;+	  else+	    p_ov[n_ov++] = val;+	  break;++	case FFI_TYPE_STRUCT:+          /* Check how a structure type is passed.  */+	  type = ffi_check_struct_type (ty);+	  /* Some structures are passed via a type they contain.  */+	  if (type != FFI_TYPE_POINTER)+	    goto restart;+	  /* ... otherwise, passed by reference.  fallthru.  */++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+	  /* 16-byte long double is passed via reference.  */+#endif+	case FFI_TYPE_COMPLEX:+	  /* Complex types are passed via reference.  */+	  p_struct -= ROUND_SIZE (ty->size);+	  memcpy (p_struct, arg, ty->size);+	  val = (uintptr_t)p_struct;+	  goto do_int;++	default:+	  FFI_ASSERT (0);+	  break;+        }+    }++  ffi_call_SYSV (frame, ret_type & FFI360_RET_MASK, rvalue, fn, closure);+}++void+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int(cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int(cif, fn, rvalue, avalue, closure);+}++/*======================== End of Routine ============================*/++/*====================================================================*/+/*                                                                    */+/* Name     - ffi_closure_helper_SYSV.                                */+/*                                                                    */+/* Function - Call a FFI closure target function.                     */+/*                                                                    */+/*====================================================================*/++void FFI_HIDDEN+ffi_closure_helper_SYSV (ffi_cif *cif,+			 void (*fun)(ffi_cif*,void*,void**,void*),+			 void *user_data,+			 unsigned long *p_gpr,+			 unsigned long long *p_fpr,+			 unsigned long *p_ov)+{+  unsigned long long ret_buffer;++  void *rvalue = &ret_buffer;+  void **avalue;+  void **p_arg;++  int n_gpr = 0;+  int n_fpr = 0;+  int n_ov = 0;++  ffi_type **ptr;+  int i;++  /* Allocate buffer for argument list pointers.  */+  p_arg = avalue = alloca (cif->nargs * sizeof (void *));++  /* If we returning a structure, pass the structure address+     directly to the target function.  Otherwise, have the target+     function store the return value to the GPR save area.  */+  if (cif->flags & FFI390_RET_IN_MEM)+    rvalue = (void *) p_gpr[n_gpr++];++  /* Now for the arguments.  */+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)+    {+      int deref_struct_pointer = 0;+      int type = (*ptr)->type;++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+      /* 16-byte long double is passed like a struct.  */+      if (type == FFI_TYPE_LONGDOUBLE)+	type = FFI_TYPE_STRUCT;+#endif++      /* Check how a structure type is passed.  */+      if (type == FFI_TYPE_STRUCT || type == FFI_TYPE_COMPLEX)+	{+	  if (type == FFI_TYPE_COMPLEX)+	    type = FFI_TYPE_POINTER;+	  else+	    type = ffi_check_struct_type (*ptr);++	  /* If we pass the struct via pointer, remember to+	     retrieve the pointer later.  */+	  if (type == FFI_TYPE_POINTER)+	    deref_struct_pointer = 1;+	}++      /* Pointers are passed like UINTs of the same size.  */+      if (type == FFI_TYPE_POINTER)+	{+#ifdef __s390x__+	  type = FFI_TYPE_UINT64;+#else+	  type = FFI_TYPE_UINT32;+#endif+	}++      /* Now handle all primitive int/float data types.  */+      switch (type)+	{+	  case FFI_TYPE_DOUBLE:+	    if (n_fpr < MAX_FPRARGS)+	      *p_arg = &p_fpr[n_fpr++];+	    else+	      *p_arg = &p_ov[n_ov],+	      n_ov += sizeof (double) / sizeof (long);+	    break;++	  case FFI_TYPE_FLOAT:+	    if (n_fpr < MAX_FPRARGS)+	      *p_arg = &p_fpr[n_fpr++];+	    else+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;+	    break;++	  case FFI_TYPE_UINT64:+	  case FFI_TYPE_SINT64:+#ifdef __s390x__+	    if (n_gpr < MAX_GPRARGS)+	      *p_arg = &p_gpr[n_gpr++];+	    else+	      *p_arg = &p_ov[n_ov++];+#else+	    if (n_gpr == MAX_GPRARGS-1)+	      n_gpr = MAX_GPRARGS;+	    if (n_gpr < MAX_GPRARGS)+	      *p_arg = &p_gpr[n_gpr], n_gpr += 2;+	    else+	      *p_arg = &p_ov[n_ov], n_ov += 2;+#endif+	    break;++	  case FFI_TYPE_INT:+	  case FFI_TYPE_UINT32:+	  case FFI_TYPE_SINT32:+	    if (n_gpr < MAX_GPRARGS)+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;+	    else+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;+	    break;++	  case FFI_TYPE_UINT16:+	  case FFI_TYPE_SINT16:+	    if (n_gpr < MAX_GPRARGS)+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;+	    else+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;+	    break;++	  case FFI_TYPE_UINT8:+	  case FFI_TYPE_SINT8:+	    if (n_gpr < MAX_GPRARGS)+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;+	    else+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;+	    break;++	  default:+	    FFI_ASSERT (0);+	    break;+        }++      /* If this is a struct passed via pointer, we need to+	 actually retrieve that pointer.  */+      if (deref_struct_pointer)+	*p_arg = *(void **)*p_arg;+    }+++  /* Call the target function.  */+  (fun) (cif, rvalue, avalue, user_data);++  /* Convert the return value.  */+  switch (cif->rtype->type)+    {+      /* Void is easy, and so is struct.  */+      case FFI_TYPE_VOID:+      case FFI_TYPE_STRUCT:+      case FFI_TYPE_COMPLEX:+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+      case FFI_TYPE_LONGDOUBLE:+#endif+	break;++      /* Floating point values are returned in fpr 0.  */+      case FFI_TYPE_FLOAT:+	p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;+	break;++      case FFI_TYPE_DOUBLE:+	p_fpr[0] = *(unsigned long long *) rvalue;+	break;++      /* Integer values are returned in gpr 2 (and gpr 3+	 for 64-bit values on 31-bit machines).  */+      case FFI_TYPE_UINT64:+      case FFI_TYPE_SINT64:+#ifdef __s390x__+	p_gpr[0] = *(unsigned long *) rvalue;+#else+	p_gpr[0] = ((unsigned long *) rvalue)[0],+	p_gpr[1] = ((unsigned long *) rvalue)[1];+#endif+	break;++      case FFI_TYPE_POINTER:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_UINT16:+      case FFI_TYPE_UINT8:+	p_gpr[0] = *(unsigned long *) rvalue;+	break;++      case FFI_TYPE_INT:+      case FFI_TYPE_SINT32:+      case FFI_TYPE_SINT16:+      case FFI_TYPE_SINT8:+	p_gpr[0] = *(signed long *) rvalue;+	break;++      default:+        FFI_ASSERT (0);+        break;+    }+}++/*======================== End of Routine ============================*/++/*====================================================================*/+/*                                                                    */+/* Name     - ffi_prep_closure_loc.                                   */+/*                                                                    */+/* Function - Prepare a FFI closure.                                  */+/*                                                                    */+/*====================================================================*/++ffi_status+ffi_prep_closure_loc (ffi_closure *closure,+		      ffi_cif *cif,+		      void (*fun) (ffi_cif *, void *, void **, void *),+		      void *user_data,+		      void *codeloc)+{+  static unsigned short const template[] = {+    0x0d10,			/* basr %r1,0 */+#ifndef __s390x__+    0x9801, 0x1006,		/* lm %r0,%r1,6(%r1) */+#else+    0xeb01, 0x100e, 0x0004,	/* lmg %r0,%r1,14(%r1) */+#endif+    0x07f1			/* br %r1 */+  };+  void (*dest)(void);+  unsigned long *tramp = (unsigned long *)&closure->tramp;++  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;+++#if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      dest = ffi_closure_SYSV;+      ffi_tramp_set_parms (closure->ftramp, dest, closure);+      goto out;+    }+#endif++  memcpy (tramp, template, sizeof(template));+  tramp[2] = (unsigned long)codeloc;+  tramp[3] = (unsigned long)&ffi_closure_SYSV;++#if defined(FFI_EXEC_STATIC_TRAMP)+out:+#endif+  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++/*======================== End of Routine ============================*/++/* Build a Go language closure.  */++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,+		     void (*fun)(ffi_cif*,void*,void**,void*))+{+  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  closure->tramp = ffi_go_closure_SYSV;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++#if defined(FFI_EXEC_STATIC_TRAMP)+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;++  *tramp_size = FFI390_TRAMP_SIZE;+  *map_size = FFI390_TRAMP_MAP_SIZE;+  return &trampoline_code_table;+}+#endif
+ src/s390/ffitarget.h view
@@ -0,0 +1,70 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for S390.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#if defined (__s390x__)+#ifndef S390X+#define S390X+#endif+#endif++/* ---- System specific configurations ----------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION+#define FFI_TARGET_HAS_COMPLEX_TYPE++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#ifdef S390X+#define FFI_TRAMPOLINE_SIZE 32+#else+#define FFI_TRAMPOLINE_SIZE 16+#endif+#define FFI_NATIVE_RAW_API 0++#endif+
+ src/s390/internal.h view
@@ -0,0 +1,22 @@+/* If these values change, sysv.S must be adapted!  */+#define FFI390_RET_DOUBLE	0+#define FFI390_RET_FLOAT	1+#define FFI390_RET_INT64	2+#define FFI390_RET_INT32	3+#define FFI390_RET_VOID		4++#define FFI360_RET_MASK		7+#define FFI390_RET_IN_MEM	8++#define FFI390_RET_STRUCT	(FFI390_RET_VOID | FFI390_RET_IN_MEM)+++#if defined(FFI_EXEC_STATIC_TRAMP)+/*+ * For the trampoline code table mapping, a mapping size of 4K is chosen.+ */+#define FFI390_TRAMP_MAP_SHIFT	12+#define FFI390_TRAMP_MAP_SIZE	(1 << FFI390_TRAMP_MAP_SHIFT)+#define FFI390_TRAMP_SIZE	16++#endif
+ src/s390/sysv.S view
@@ -0,0 +1,363 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2000 Software AG+            Copyright (c) 2008 Red Hat, Inc.++   S390 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include "internal.h"++	.text++#ifndef __s390x__++	# r2:	frame+	# r3:	ret_type+	# r4:	ret_addr+	# r5:	fun+	# r6:	closure++	# This assumes we are using gas.+	.balign	8+	.globl	ffi_call_SYSV+	FFI_HIDDEN(ffi_call_SYSV)+	.type	ffi_call_SYSV,%function+ffi_call_SYSV:+	.cfi_startproc+	st	%r6,44(%r2)			# Save registers+	stm	%r12,%r14,48(%r2)+	lr	%r13,%r2			# Install frame pointer+	.cfi_rel_offset r6, 44+	.cfi_rel_offset r12, 48+	.cfi_rel_offset r13, 52+	.cfi_rel_offset r14, 56+	.cfi_def_cfa_register r13+	st	%r2,0(%r15)			# Set up back chain+	sla	%r3,3				# ret_type *= 8+	lr	%r12,%r4			# Save ret_addr+	lr	%r1,%r5				# Save fun+	lr	%r0,%r6				# Install static chain++	# Set return address, so that there is only one indirect jump.+#ifdef HAVE_AS_S390_ZARCH+	larl	%r14,.Ltable+	ar	%r14,%r3+#else+	basr	%r14,0+0:	la	%r14,.Ltable-0b(%r14,%r3)+#endif++	lm	%r2,%r6,8(%r13)			# Load arguments+	ld	%f0,64(%r13)+	ld	%f2,72(%r13)+	br	%r1				# ... and call function++	.balign	8+.Ltable:+# FFI390_RET_DOUBLE+	std	%f0,0(%r12)+	j	.Ldone++	.balign	8+# FFI390_RET_FLOAT+	ste	%f0,0(%r12)+	j	.Ldone++	.balign	8+# FFI390_RET_INT64+	st	%r3,4(%r12)+	nop+	# fallthru++	.balign	8+# FFI390_RET_INT32+	st	%r2,0(%r12)+	nop+	# fallthru++	.balign	8+# FFI390_RET_VOID+.Ldone:+	l	%r14,56(%r13)+	l	%r12,48(%r13)+	l	%r6,44(%r13)+	l	%r13,52(%r13)+	.cfi_restore 14+	.cfi_restore 13+	.cfi_restore 12+	.cfi_restore 6+	.cfi_def_cfa r15, 96+	br	%r14+	.cfi_endproc+	.size	 ffi_call_SYSV,.-ffi_call_SYSV+++	.balign	8+	.globl	ffi_go_closure_SYSV+	FFI_HIDDEN(ffi_go_closure_SYSV)+	.type	ffi_go_closure_SYSV,%function+ffi_go_closure_SYSV:+	.cfi_startproc+	stm	%r2,%r6,8(%r15)			# Save arguments+	lr	%r4,%r0				# Load closure -> user_data+	l	%r2,4(%r4)			#   ->cif+	l	%r3,8(%r4)			#   ->fun+	j	.Ldoclosure+	.cfi_endproc++	.balign	8+	.globl	ffi_closure_SYSV+	FFI_HIDDEN(ffi_closure_SYSV)+	.type	ffi_closure_SYSV,%function+ffi_closure_SYSV:+	.cfi_startproc+	stm	%r2,%r6,8(%r15)			# Save arguments+	lr	%r4,%r0				# Closure+	l	%r2,16(%r4)			#   ->cif+	l	%r3,20(%r4)			#   ->fun+	l	%r4,24(%r4)			#   ->user_data+.Ldoclosure:+	stm	%r12,%r15,48(%r15)		# Save registers+	lr	%r12,%r15+	.cfi_def_cfa_register r12+	.cfi_rel_offset r6, 24+	.cfi_rel_offset r12, 48+	.cfi_rel_offset r13, 52+	.cfi_rel_offset r14, 56+	.cfi_rel_offset r15, 60+#ifndef HAVE_AS_S390_ZARCH+	basr	%r13,0				# Set up base register+.Lcbase:+	l	%r1,.Lchelper-.Lcbase(%r13)	# Get helper function+#endif+	ahi	%r15,-96-8			# Set up stack frame+	st	%r12,0(%r15)			# Set up back chain++	std	%f0,64(%r12)			# Save fp arguments+	std	%f2,72(%r12)++	la	%r5,96(%r12)			# Overflow+	st	%r5,96(%r15)+	la	%r6,64(%r12)			# FPRs+	la	%r5,8(%r12)			# GPRs+#ifdef HAVE_AS_S390_ZARCH+	brasl	%r14,ffi_closure_helper_SYSV+#else+	bas	%r14,0(%r1,%r13)		# Call helper+#endif++	lr	%r15,%r12+	.cfi_def_cfa_register r15+	lm	%r12,%r14,48(%r12)		# Restore saved registers+	l	%r6,24(%r15)+	ld	%f0,64(%r15)			# Load return registers+	lm	%r2,%r3,8(%r15)+	br	%r14+	.cfi_endproc++#ifndef HAVE_AS_S390_ZARCH+	.align 4+.Lchelper:+	.long	ffi_closure_helper_SYSV-.Lcbase+#endif++	.size	 ffi_closure_SYSV,.-ffi_closure_SYSV++#else++	# r2:	frame+	# r3:	ret_type+	# r4:	ret_addr+	# r5:	fun+	# r6:	closure++	# This assumes we are using gas.+	.balign	8+	.globl	ffi_call_SYSV+	FFI_HIDDEN(ffi_call_SYSV)+	.type	ffi_call_SYSV,%function+ffi_call_SYSV:+	.cfi_startproc+	stg	%r6,88(%r2)			# Save registers+	stmg	%r12,%r14,96(%r2)+	lgr	%r13,%r2			# Install frame pointer+	.cfi_rel_offset r6, 88+	.cfi_rel_offset r12, 96+	.cfi_rel_offset r13, 104+	.cfi_rel_offset r14, 112+	.cfi_def_cfa_register r13+	stg	%r2,0(%r15)			# Set up back chain+	larl	%r14,.Ltable			# Set up return address+	slag	%r3,%r3,3			# ret_type *= 8+	lgr	%r12,%r4			# Save ret_addr+	lgr	%r1,%r5				# Save fun+	lgr	%r0,%r6				# Install static chain+	agr	%r14,%r3+	lmg	%r2,%r6,16(%r13)		# Load arguments+	ld	%f0,128(%r13)+	ld	%f2,136(%r13)+	ld	%f4,144(%r13)+	ld	%f6,152(%r13)+	br	%r1				# ... and call function++	.balign	8+.Ltable:+# FFI390_RET_DOUBLE+	std	%f0,0(%r12)+	j	.Ldone++	.balign	8+# FFI390_RET_DOUBLE+	ste	%f0,0(%r12)+	j	.Ldone++	.balign	8+# FFI390_RET_INT64+	stg	%r2,0(%r12)++	.balign	8+# FFI390_RET_INT32+	# Never used, as we always store type ffi_arg.+	# But the stg above is 6 bytes and we cannot+	# jump around this case, so fall through.+	nop+	nop++	.balign	8+# FFI390_RET_VOID+.Ldone:+	lg	%r14,112(%r13)+	lg	%r12,96(%r13)+	lg	%r6,88(%r13)+	lg	%r13,104(%r13)+	.cfi_restore r14+	.cfi_restore r13+	.cfi_restore r12+	.cfi_restore r6+	.cfi_def_cfa r15, 160+	br	%r14+	.cfi_endproc+	.size	 ffi_call_SYSV,.-ffi_call_SYSV+++	.balign	8+	.globl	ffi_go_closure_SYSV+	FFI_HIDDEN(ffi_go_closure_SYSV)+	.type	ffi_go_closure_SYSV,%function+ffi_go_closure_SYSV:+	.cfi_startproc+	stmg	%r2,%r6,16(%r15)		# Save arguments+	lgr	%r4,%r0				# Load closure -> user_data+	lg	%r2,8(%r4)			#   ->cif+	lg	%r3,16(%r4)			#   ->fun+	j	.Ldoclosure+	.cfi_endproc+	.size	 ffi_go_closure_SYSV,.-ffi_go_closure_SYSV+++	.balign	8+	.globl	ffi_closure_SYSV+	FFI_HIDDEN(ffi_closure_SYSV)+	.type	ffi_closure_SYSV,%function+ffi_closure_SYSV:+	.cfi_startproc+	stmg	%r2,%r6,16(%r15)		# Save arguments+	lgr	%r4,%r0				# Load closure+	lg	%r2,32(%r4)			#   ->cif+	lg	%r3,40(%r4)			#   ->fun+	lg	%r4,48(%r4)			#   ->user_data+.Ldoclosure:+	stmg	%r13,%r15,104(%r15)		# Save registers+	lgr	%r13,%r15+	.cfi_def_cfa_register r13+	.cfi_rel_offset r6, 48+	.cfi_rel_offset r13, 104+	.cfi_rel_offset r14, 112+	.cfi_rel_offset r15, 120+	aghi	%r15,-160-16			# Set up stack frame+	stg	%r13,0(%r15)			# Set up back chain++	std	%f0,128(%r13)			# Save fp arguments+	std	%f2,136(%r13)+	std	%f4,144(%r13)+	std	%f6,152(%r13)+	la	%r5,160(%r13)			# Overflow+	stg	%r5,160(%r15)+	la	%r6,128(%r13)			# FPRs+	la	%r5,16(%r13)			# GPRs+	brasl	%r14,ffi_closure_helper_SYSV	# Call helper++	lgr	%r15,%r13+	.cfi_def_cfa_register r15+	lmg	%r13,%r14,104(%r13)		# Restore saved registers+	lg	%r6,48(%r15)+	ld	%f0,128(%r15)			# Load return registers+	lg	%r2,16(%r15)+	br	%r14+	.cfi_endproc+	.size	 ffi_closure_SYSV,.-ffi_closure_SYSV+++#if defined(FFI_EXEC_STATIC_TRAMP)+/*+ * Below is the definition of the trampoline code table. Each element in+ * the code table is a trampoline.+ */+/*+ * The trampoline uses the volatile register r0 and r1. As the registers are+ * marked volatile in the ABI, the original values are not saved.+ *+ * The trampoline has two parameters - target code to jump to and data for+ * the target code. The trampoline extracts the parameters from its parameter+ * block (see tramp_table_map()). The trampoline saves the data address in r0.+ * Finally, it jumps to the target code.+ */++	.align	FFI390_TRAMP_MAP_SIZE+trampoline_code_table:+	.rept	FFI390_TRAMP_MAP_SIZE / FFI390_TRAMP_SIZE+	basr %r1,0              # load next instruction address to r1+	lmg %r0,%r1,4094(%r1)   # load parameter block+							# 		r0 -> data+							# 		r1 -> code+	br %r1                  # jump to r1/code+	.balign	8+	.endr++	.globl trampoline_code_table+	FFI_HIDDEN(trampoline_code_table)+#ifdef __ELF__+	.type	trampoline_code_table, @function+	.size	trampoline_code_table,.- trampoline_code_table+#endif+	.align	FFI390_TRAMP_MAP_SIZE+#endif /* FFI_EXEC_STATIC_TRAMP */++#endif /* !s390x */++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/sh/ffi.c view
@@ -0,0 +1,717 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2002-2008, 2012 Kaz Kojima+           Copyright (c) 2008 Red Hat, Inc.+   +   SuperH 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>++#define NGREGARG 4+#if defined(__SH4__)+#define NFREGARG 8+#endif++#if defined(__HITACHI__)+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1+#else+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0+#endif++/* If the structure has essentially an unique element, return its type.  */+static int+simple_type (ffi_type *arg)+{+  if (arg->type != FFI_TYPE_STRUCT)+    return arg->type;+  else if (arg->elements[1])+    return FFI_TYPE_STRUCT;++  return simple_type (arg->elements[0]);+}++static int+return_type (ffi_type *arg)+{+  unsigned short type;++  if (arg->type != FFI_TYPE_STRUCT)+    return arg->type;++  type = simple_type (arg->elements[0]);+  if (! arg->elements[1])+    {+      switch (type)+	{+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	  return FFI_TYPE_INT;++	default:+	  return type;+	}+    }++  /* gcc uses r0/r1 pair for some kind of structures.  */+  if (arg->size <= 2 * sizeof (int))+    {+      int i = 0;+      ffi_type *e;++      while ((e = arg->elements[i++]))+	{+	  type = simple_type (e);+	  switch (type)+	    {+	    case FFI_TYPE_SINT32:+	    case FFI_TYPE_UINT32:+	    case FFI_TYPE_INT:+	    case FFI_TYPE_FLOAT:+	      return FFI_TYPE_UINT64;++	    default:+	      break;+	    }+	}+    }++  return FFI_TYPE_STRUCT;+}++/* 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 int tmp;+  register unsigned int avn;+  register void **p_argv;+  register char *argp;+  register ffi_type **p_arg;+  int greg, ireg;+#if defined(__SH4__)+  int freg = 0;+#endif++  tmp = 0;+  argp = stack;++  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)+    {+      *(void **) argp = ecif->rvalue;+      argp += 4;+      ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;+    }+  else+    ireg = 0;++  /* Set arguments for registers.  */+  greg = ireg;+  avn = ecif->cif->nargs;+  p_argv = ecif->avalue;++  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)+    {+      size_t z;++      z = (*p_arg)->size;+      if (z < sizeof(int))+	{+	  if (greg++ >= NGREGARG)+	    continue;++	  z = sizeof(int);+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_UINT8:+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_SINT16:+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_UINT16:+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_STRUCT:+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+	      break;++	    default:+	      FFI_ASSERT(0);+	    }+	  argp += z;+	}+      else if (z == sizeof(int))+	{+#if defined(__SH4__)+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)+	    {+	      if (freg++ >= NFREGARG)+		continue;+	    }+	  else+#endif+	    {+	      if (greg++ >= NGREGARG)+		continue;+	    }+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+	  argp += z;+	}+#if defined(__SH4__)+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)+	{+	  if (freg + 1 >= NFREGARG)+	    continue;+	  freg = (freg + 1) & ~1;+	  freg += 2;+	  memcpy (argp, *p_argv, z);+	  argp += z;+	}+#endif+      else+	{+	  int n = (z + sizeof (int) - 1) / sizeof (int);+#if defined(__SH4__)+	  if (greg + n - 1 >= NGREGARG)+	    continue;+#else+	  if (greg >= NGREGARG)+	    continue;+#endif+	  greg += n;+	  memcpy (argp, *p_argv, z);+	  argp += n * sizeof (int);+	}+    }++  /* Set arguments on stack.  */+  greg = ireg;+#if defined(__SH4__)+  freg = 0;+#endif+  p_argv = ecif->avalue;++  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)+    {+      size_t z;++      z = (*p_arg)->size;+      if (z < sizeof(int))+	{+	  if (greg++ < NGREGARG)+	    continue;++	  z = sizeof(int);+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_UINT8:+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_SINT16:+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_UINT16:+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);+	      break;+  +	    case FFI_TYPE_STRUCT:+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+	      break;++	    default:+	      FFI_ASSERT(0);+	    }+	  argp += z;+	}+      else if (z == sizeof(int))+	{+#if defined(__SH4__)+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)+	    {+	      if (freg++ < NFREGARG)+		continue;+	    }+	  else+#endif+	    {+	      if (greg++ < NGREGARG)+		continue;+	    }+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);+	  argp += z;+	}+#if defined(__SH4__)+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)+	{+	  if (freg + 1 < NFREGARG)+	    {+	      freg = (freg + 1) & ~1;+	      freg += 2;+	      continue;+	    }+	  memcpy (argp, *p_argv, z);+	  argp += z;+	}+#endif+      else+	{+	  int n = (z + sizeof (int) - 1) / sizeof (int);+	  if (greg + n - 1 < NGREGARG)+	    {+	      greg += n;+	      continue;+	    }+#if (! defined(__SH4__))+	  else if (greg < NGREGARG)+	    {+	      greg = NGREGARG;+	      continue;+	    }+#endif+	  memcpy (argp, *p_argv, z);+	  argp += n * sizeof (int);+	}+    }++  return;+}++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+  int i, j;+  int size, type;+  int n, m;+  int greg;+#if defined(__SH4__)+  int freg = 0;+#endif++  cif->flags = 0;++  greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&+	  STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;++#if defined(__SH4__)+  for (i = j = 0; i < cif->nargs && j < 12; i++)+    {+      type = (cif->arg_types)[i]->type;+      switch (type)+	{+	case FFI_TYPE_FLOAT:+	  if (freg >= NFREGARG)+	    continue;+	  freg++;+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);+	  j++;+	  break;++	case FFI_TYPE_DOUBLE:+	  if ((freg + 1) >= NFREGARG)+	    continue;+	  freg = (freg + 1) & ~1;+	  freg += 2;+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);+	  j++;+	  break;+	      +	default:+	  size = (cif->arg_types)[i]->size;+	  n = (size + sizeof (int) - 1) / sizeof (int);+	  if (greg + n - 1 >= NGREGARG)+		continue;+	  greg += n;+	  for (m = 0; m < n; m++)+	    cif->flags += FFI_TYPE_INT << (2 * j++);+	  break;+	}+    }+#else+  for (i = j = 0; i < cif->nargs && j < 4; i++)+    {+      size = (cif->arg_types)[i]->size;+      n = (size + sizeof (int) - 1) / sizeof (int);+      if (greg >= NGREGARG)+	continue;+      else if (greg + n - 1 >= NGREGARG)+	n = NGREGARG - greg;+      greg += n;+      for (m = 0; m < n; m++)+        cif->flags += FFI_TYPE_INT << (2 * j++);+    }+#endif++  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_STRUCT:+      cif->flags += (unsigned) (return_type (cif->rtype)) << 24;+      break;++    case FFI_TYPE_VOID:+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      cif->flags += (unsigned) cif->rtype->type << 24;+      break;++    default:+      cif->flags += FFI_TYPE_INT << 24;+      break;+    }++  return FFI_OK;+}++extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,+			  unsigned, unsigned, unsigned *, void (*fn)(void));++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  extended_cif ecif;+  UINT64 trvalue;++  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 (cif->rtype->type == FFI_TYPE_STRUCT+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)+    ecif.rvalue = &trvalue;+  else if ((rvalue == NULL) && +      (cif->rtype->type == FFI_TYPE_STRUCT))+    {+      ecif.rvalue = alloca(cif->rtype->size);+    }+  else+    ecif.rvalue = rvalue;++  switch (cif->abi) +    {+    case FFI_SYSV:+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,+		    fn);+      break;+    default:+      FFI_ASSERT(0);+      break;+    }++  if (rvalue+      && cif->rtype->type == FFI_TYPE_STRUCT+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)+    memcpy (rvalue, &trvalue, cif->rtype->size);+}++extern void ffi_closure_SYSV (void);+#if defined(__SH4__)+extern void __ic_invalidate (void *line);+#endif++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 insn;++  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  tramp = (unsigned int *) &closure->tramp[0];+  /* Set T bit if the function returns a struct pointed with R2.  */+  insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT+	  ? 0x0018 /* sett */+	  : 0x0008 /* clrt */);++#ifdef __LITTLE_ENDIAN__+  tramp[0] = 0xd301d102;+  tramp[1] = 0x0000412b | (insn << 16);+#else+  tramp[0] = 0xd102d301;+  tramp[1] = 0x412b0000 | insn;+#endif+  *(void **) &tramp[2] = (void *)codeloc;          /* ctx */+  *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++#if defined(__SH4__)+  /* Flush the icache.  */+  __ic_invalidate(codeloc);+#endif++  return FFI_OK;+}++/* Basically the trampoline invokes ffi_closure_SYSV, and on + * entry, r3 holds the address of the closure.+ * After storing the registers that could possibly contain+ * parameters to be passed into the stack frame and setting+ * up space for a return value, ffi_closure_SYSV invokes the + * following helper function to do most of the work.+ */++#ifdef __LITTLE_ENDIAN__+#define OFS_INT8	0+#define OFS_INT16	0+#else+#define OFS_INT8	3+#define OFS_INT16	2+#endif++int+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, +			 unsigned long *pgr, unsigned long *pfr, +			 unsigned long *pst)+{+  void **avalue;+  ffi_type **p_arg;+  int i, avn;+  int ireg, greg = 0;+#if defined(__SH4__)+  int freg = 0;+#endif+  ffi_cif *cif; ++  cif = closure->cif;+  avalue = alloca(cif->nargs * sizeof(void *));++  /* Copy the caller's structure return value address so that the closure+     returns the data directly to the caller.  */+  if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)+    {+      rvalue = (void *) *pgr++;+      ireg = 1;+    }+  else+    ireg = 0;++  cif = closure->cif;+  greg = ireg;+  avn = cif->nargs;++  /* Grab the addresses of the arguments from the stack frame.  */+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)+    {+      size_t z;++      z = (*p_arg)->size;+      if (z < sizeof(int))+	{+	  if (greg++ >= NGREGARG)+	    continue;++	  z = sizeof(int);+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	    case FFI_TYPE_UINT8:+	      avalue[i] = (((char *)pgr) + OFS_INT8);+	      break;+  +	    case FFI_TYPE_SINT16:+	    case FFI_TYPE_UINT16:+	      avalue[i] = (((char *)pgr) + OFS_INT16);+	      break;+  +	    case FFI_TYPE_STRUCT:+	      avalue[i] = pgr;+	      break;++	    default:+	      FFI_ASSERT(0);+	    }+	  pgr++;+	}+      else if (z == sizeof(int))+	{+#if defined(__SH4__)+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)+	    {+	      if (freg++ >= NFREGARG)+		continue;+	      avalue[i] = pfr;+	      pfr++;+	    }+	  else+#endif+	    {+	      if (greg++ >= NGREGARG)+		continue;+	      avalue[i] = pgr;+	      pgr++;+	    }+	}+#if defined(__SH4__)+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)+	{+	  if (freg + 1 >= NFREGARG)+	    continue;+	  if (freg & 1)+	    pfr++;+	  freg = (freg + 1) & ~1;+	  freg += 2;+	  avalue[i] = pfr;+	  pfr += 2;+	}+#endif+      else+	{+	  int n = (z + sizeof (int) - 1) / sizeof (int);+#if defined(__SH4__)+	  if (greg + n - 1 >= NGREGARG)+	    continue;+#else+	  if (greg >= NGREGARG)+	    continue;+#endif+	  greg += n;+	  avalue[i] = pgr;+	  pgr += n;+	}+    }++  greg = ireg;+#if defined(__SH4__)+  freg = 0;+#endif++  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)+    {+      size_t z;++      z = (*p_arg)->size;+      if (z < sizeof(int))+	{+	  if (greg++ < NGREGARG)+	    continue;++	  z = sizeof(int);+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	    case FFI_TYPE_UINT8:+	      avalue[i] = (((char *)pst) + OFS_INT8);+	      break;+  +	    case FFI_TYPE_SINT16:+	    case FFI_TYPE_UINT16:+	      avalue[i] = (((char *)pst) + OFS_INT16);+	      break;+  +	    case FFI_TYPE_STRUCT:+	      avalue[i] = pst;+	      break;++	    default:+	      FFI_ASSERT(0);+	    }+	  pst++;+	}+      else if (z == sizeof(int))+	{+#if defined(__SH4__)+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)+	    {+	      if (freg++ < NFREGARG)+		continue;+	    }+	  else+#endif+	    {+	      if (greg++ < NGREGARG)+		continue;+	    }+	  avalue[i] = pst;+	  pst++;+	}+#if defined(__SH4__)+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)+	{+	  if (freg + 1 < NFREGARG)+	    {+	      freg = (freg + 1) & ~1;+	      freg += 2;+	      continue;+	    }+	  avalue[i] = pst;+	  pst += 2;+	}+#endif+      else+	{+	  int n = (z + sizeof (int) - 1) / sizeof (int);+	  if (greg + n - 1 < NGREGARG)+	    {+	      greg += n;+	      continue;+	    }+#if (! defined(__SH4__))+	  else if (greg < NGREGARG)+	    {+	      greg += n;+	      pst += greg - NGREGARG;+	      continue;+	    }+#endif+	  avalue[i] = pst;+	  pst += n;+	}+    }++  (closure->fun) (cif, rvalue, avalue, closure->user_data);++  /* Tell ffi_closure_SYSV how to perform return type promotions.  */+  return return_type (cif->rtype);+}
+ src/sh/ffitarget.h view
@@ -0,0 +1,54 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012 Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for SuperH.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- Generic type definitions ----------------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 16+#define FFI_NATIVE_RAW_API 0++#endif+
+ src/sh/sysv.S view
@@ -0,0 +1,850 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2002, 2003, 2004, 2006, 2008 Kaz Kojima+   +   SuperH Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>+#ifdef HAVE_MACHINE_ASM_H+#include <machine/asm.h>+#else+/* XXX these lose for some platforms, I'm sure. */+#define CNAME(x) x+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):+#endif++#if defined(__HITACHI__)+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1+#else+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0+#endif++.text++	# r4:	ffi_prep_args+	# r5:	&ecif+	# r6:	bytes+	# r7:	flags+	# sp+0: rvalue+	# sp+4: fn++	# This assumes we are using gas.+ENTRY(ffi_call_SYSV)+	# Save registers+.LFB1:+	mov.l	r8,@-r15+.LCFI0:+	mov.l	r9,@-r15+.LCFI1:+	mov.l	r10,@-r15+.LCFI2:+	mov.l	r12,@-r15+.LCFI3:+	mov.l	r14,@-r15+.LCFI4:+	sts.l	pr,@-r15+.LCFI5:+	mov	r15,r14+.LCFI6:+#if defined(__SH4__)+	mov	r6,r8+	mov	r7,r9++	sub	r6,r15+	add	#-16,r15+	mov	#~7,r0+	and	r0,r15++	mov	r4,r0+	jsr	@r0+	 mov	r15,r4++	mov	r9,r1+	shlr8	r9+	shlr8	r9+	shlr8	r9++	mov	#FFI_TYPE_STRUCT,r2+	cmp/eq	r2,r9+	bf	1f+#if STRUCT_VALUE_ADDRESS_WITH_ARG+ 	mov.l	@r15+,r4+	bra	2f+	 mov	#5,r2+#else+ 	mov.l	@r15+,r10+#endif+1:+	mov	#4,r2+2:+	mov	#4,r3++L_pass:+	cmp/pl	r8+	bf	L_call_it++	mov	r1,r0+	and	#3,r0++L_pass_d:+	cmp/eq	#FFI_TYPE_DOUBLE,r0+	bf	L_pass_f++	mov	r3,r0+	and	#1,r0+	tst	r0,r0+	bt	1f+	add	#1,r3+1:+	mov	#12,r0+	cmp/hs	r0,r3+	bt/s	3f+	 shlr2	r1+	bsr	L_pop_d+	 nop+3:+	add	#2,r3+	bra	L_pass+	 add	#-8,r8++L_pop_d:+	mov	r3,r0+	add	r0,r0+	add	r3,r0+	add	#-12,r0+	braf	r0+	 nop+#ifdef __LITTLE_ENDIAN__+	fmov.s	@r15+,fr5+	rts+	 fmov.s	@r15+,fr4+	fmov.s	@r15+,fr7+	rts+	 fmov.s	@r15+,fr6+	fmov.s	@r15+,fr9+	rts+	 fmov.s	@r15+,fr8+	fmov.s	@r15+,fr11+	rts+	 fmov.s	@r15+,fr10+#else+	fmov.s	@r15+,fr4+	rts+	 fmov.s	@r15+,fr5+	fmov.s	@r15+,fr6+	rts+	 fmov.s	@r15+,fr7+	fmov.s	@r15+,fr8+	rts+	 fmov.s	@r15+,fr9+	fmov.s	@r15+,fr10+	rts+	 fmov.s	@r15+,fr11+#endif++L_pass_f:+	cmp/eq	#FFI_TYPE_FLOAT,r0+	bf	L_pass_i++	mov	#12,r0+	cmp/hs	r0,r3+	bt/s	2f+	 shlr2	r1+	bsr	L_pop_f+	 nop+2:+	add	#1,r3+	bra	L_pass+	 add	#-4,r8++L_pop_f:+	mov	r3,r0+	shll2	r0+	add	#-16,r0+	braf	r0+	 nop+#ifdef __LITTLE_ENDIAN__+	rts+	 fmov.s	@r15+,fr5+	rts+	 fmov.s	@r15+,fr4+	rts+	 fmov.s	@r15+,fr7+	rts+	 fmov.s	@r15+,fr6+	rts+	 fmov.s	@r15+,fr9+	rts+	 fmov.s	@r15+,fr8+	rts+	 fmov.s	@r15+,fr11+	rts+	 fmov.s	@r15+,fr10+#else+	rts+	 fmov.s	@r15+,fr4+	rts+	 fmov.s	@r15+,fr5+	rts+	 fmov.s	@r15+,fr6+	rts+	 fmov.s	@r15+,fr7+	rts+	 fmov.s	@r15+,fr8+	rts+	 fmov.s	@r15+,fr9+	rts+	 fmov.s	@r15+,fr10+	rts+	 fmov.s	@r15+,fr11+#endif++L_pass_i:+	cmp/eq	#FFI_TYPE_INT,r0+	bf	L_call_it++	mov	#8,r0+	cmp/hs	r0,r2+	bt/s	2f+	 shlr2	r1+	bsr	L_pop_i+	 nop+2:+	add	#1,r2+	bra	L_pass+	 add	#-4,r8++L_pop_i:+	mov	r2,r0+	shll2	r0+	add	#-16,r0+	braf	r0+	 nop+	rts+	 mov.l	@r15+,r4+	rts+	 mov.l	@r15+,r5+	rts+	 mov.l	@r15+,r6+	rts+	 mov.l	@r15+,r7++L_call_it:+	# call function+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)+	mov	r10, r2+#endif+	mov.l  @(28,r14),r1+	jsr    @r1+	 nop++L_ret_d:+	mov	#FFI_TYPE_DOUBLE,r2+	cmp/eq	r2,r9+	bf	L_ret_ll++	mov.l	@(24,r14),r1+#ifdef __LITTLE_ENDIAN__+	fmov.s	fr1,@r1+	add	#4,r1+	bra	L_epilogue+	 fmov.s	fr0,@r1+#else+	fmov.s	fr0,@r1+	add	#4,r1+	bra	L_epilogue+	 fmov.s	fr1,@r1+#endif++L_ret_ll:+	mov	#FFI_TYPE_SINT64,r2+	cmp/eq	r2,r9+	bt/s	1f+	 mov	#FFI_TYPE_UINT64,r2+	cmp/eq	r2,r9+	bf	L_ret_f++1:+	mov.l	@(24,r14),r2+	mov.l	r0,@r2+	bra	L_epilogue+	 mov.l	r1,@(4,r2)++L_ret_f:+	mov	#FFI_TYPE_FLOAT,r2+	cmp/eq	r2,r9+	bf	L_ret_i++	mov.l	@(24,r14),r1+	bra	L_epilogue+	 fmov.s	fr0,@r1++L_ret_i:+	mov	#FFI_TYPE_INT,r2+	cmp/eq	r2,r9+	bf	L_epilogue++	mov.l	@(24,r14),r1+	bra	L_epilogue+	 mov.l	r0,@r1++L_epilogue:+	# Remove the space we pushed for the args+	mov   r14,r15++	lds.l  @r15+,pr+	mov.l  @r15+,r14+	mov.l  @r15+,r12+	mov.l  @r15+,r10+	mov.l  @r15+,r9+	rts+	 mov.l  @r15+,r8+#else+	mov	r6,r8+	mov	r7,r9++	sub	r6,r15+	add	#-16,r15+	mov	#~7,r0+	and	r0,r15++	mov	r4,r0+	jsr	@r0+	 mov	r15,r4++	mov	r9,r3+	shlr8	r9+	shlr8	r9+	shlr8	r9++	mov	#FFI_TYPE_STRUCT,r2+	cmp/eq	r2,r9+	bf	1f+#if STRUCT_VALUE_ADDRESS_WITH_ARG+	mov.l	@r15+,r4+	bra	2f+	 mov	#5,r2+#else+	mov.l	@r15+,r10+#endif+1:+	mov	#4,r2+2:++L_pass:+	cmp/pl	r8+	bf	L_call_it++	mov	r3,r0+	and	#3,r0++L_pass_d:+	cmp/eq	#FFI_TYPE_DOUBLE,r0+	bf	L_pass_i++	mov	r15,r0+	and	#7,r0+	tst	r0,r0+	bt	1f+	add	#4,r15+1:+	mov	#8,r0+	cmp/hs	r0,r2+	bt/s	2f+	 shlr2	r3+	bsr	L_pop_d+	 nop+2:+	add	#2,r2+	bra	L_pass+	 add	#-8,r8++L_pop_d:+	mov	r2,r0+	add	r0,r0+	add	r2,r0+	add	#-12,r0+	add	r0,r0+	braf	r0+	 nop+	mov.l	@r15+,r4+	rts+	 mov.l	@r15+,r5+	mov.l	@r15+,r5+	rts+	 mov.l	@r15+,r6+	mov.l	@r15+,r6+	rts+	 mov.l	@r15+,r7+	rts+	 mov.l	@r15+,r7++L_pass_i:+	cmp/eq	#FFI_TYPE_INT,r0+	bf	L_call_it++	mov	#8,r0+	cmp/hs	r0,r2+	bt/s	2f+	 shlr2	r3+	bsr	L_pop_i+	 nop+2:+	add	#1,r2+	bra	L_pass+	 add	#-4,r8++L_pop_i:+	mov	r2,r0+	shll2	r0+	add	#-16,r0+	braf	r0+	 nop+	rts+	 mov.l	@r15+,r4+	rts+	 mov.l	@r15+,r5+	rts+	 mov.l	@r15+,r6+	rts+	 mov.l	@r15+,r7++L_call_it:+	# call function+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)+	mov	r10, r2+#endif+	mov.l  @(28,r14),r1+	jsr    @r1+	 nop++L_ret_d:+	mov	#FFI_TYPE_DOUBLE,r2+	cmp/eq	r2,r9+	bf	L_ret_ll++	mov.l	@(24,r14),r2+	mov.l	r0,@r2+	bra	L_epilogue+	 mov.l	r1,@(4,r2)++L_ret_ll:+	mov	#FFI_TYPE_SINT64,r2+	cmp/eq	r2,r9+	bt/s	1f+	 mov	#FFI_TYPE_UINT64,r2+	cmp/eq	r2,r9+	bf	L_ret_i++1:+	mov.l	@(24,r14),r2+	mov.l	r0,@r2+	bra	L_epilogue+	 mov.l	r1,@(4,r2)++L_ret_i:+	mov	#FFI_TYPE_FLOAT,r2+	cmp/eq	r2,r9+	bt	1f+	mov	#FFI_TYPE_INT,r2+	cmp/eq	r2,r9+	bf	L_epilogue+1:+	mov.l	@(24,r14),r1+	bra	L_epilogue+	 mov.l	r0,@r1++L_epilogue:+	# Remove the space we pushed for the args+	mov   r14,r15++	lds.l  @r15+,pr+	mov.l  @r15+,r14+	mov.l  @r15+,r12+	mov.l  @r15+,r10+	mov.l  @r15+,r9+	rts+	 mov.l  @r15+,r8+#endif+.LFE1:+.ffi_call_SYSV_end:+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)++.globl	ffi_closure_helper_SYSV++ENTRY(ffi_closure_SYSV)+.LFB2:+	mov.l	r7,@-r15+.LCFI7:+	mov.l	r6,@-r15+.LCFI8:+	mov.l	r5,@-r15+.LCFI9:+	mov.l	r4,@-r15+.LCFIA:+	mov.l	r14,@-r15+.LCFIB:+	sts.l	pr,@-r15++	/* Stack layout:	+	   xx bytes (on stack parameters)+	   16 bytes (register parameters)+	    4 bytes (saved frame pointer)+	    4 bytes (saved return address)+	   32 bytes (floating register parameters, SH-4 only)+	    8 bytes (result)+	    4 bytes (pad)+	    4 bytes (5th arg)+	   <- new stack pointer+	*/+.LCFIC:+#if defined(__SH4__)+	add	#-48,r15+#else+	add	#-16,r15+#endif+.LCFID:+	mov	r15,r14+.LCFIE:++#if defined(__SH4__)+	mov	r14,r1+	add	#48,r1+#ifdef __LITTLE_ENDIAN__+	fmov.s	fr10,@-r1+	fmov.s	fr11,@-r1+	fmov.s	fr8,@-r1+	fmov.s	fr9,@-r1+	fmov.s	fr6,@-r1+	fmov.s	fr7,@-r1+	fmov.s	fr4,@-r1+	fmov.s	fr5,@-r1+#else+	fmov.s	fr11,@-r1+	fmov.s	fr10,@-r1+	fmov.s	fr9,@-r1+	fmov.s	fr8,@-r1+	fmov.s	fr7,@-r1+	fmov.s	fr6,@-r1+	fmov.s	fr5,@-r1+	fmov.s	fr4,@-r1+#endif+	mov	r1,r7+	mov	r14,r6+	add	#56,r6+#else+	mov	r14,r6+	add	#24,r6+#endif++	bt/s	10f+	 mov	r2, r5+	mov	r14,r1+	add	#8,r1+	mov	r1,r5+10:++	mov	r14,r1+#if defined(__SH4__)+	add	#72,r1+#else+	add	#40,r1+#endif+	mov.l	r1,@r14++#ifdef PIC+	mov.l	L_got,r1+	mova	L_got,r0+	add	r0,r1+	mov.l	L_helper,r0+	add	r1,r0+#else+	mov.l	L_helper,r0+#endif+	jsr	@r0+	 mov	r3,r4++	shll	r0+	mov	r0,r1+	mova	L_table,r0+	add	r1,r0+	mov.w	@r0,r0+	mov	r14,r2+	braf	r0+	 add	#8,r2+0:+	.align 2+#ifdef PIC+L_got:+	.long	_GLOBAL_OFFSET_TABLE_+L_helper:+	.long	ffi_closure_helper_SYSV@GOTOFF+#else+L_helper:+	.long	ffi_closure_helper_SYSV+#endif+L_table:+	.short L_case_v - 0b	/* FFI_TYPE_VOID */+	.short L_case_i - 0b	/* FFI_TYPE_INT */+#if defined(__SH4__)+	.short L_case_f - 0b	/* FFI_TYPE_FLOAT */+	.short L_case_d - 0b	/* FFI_TYPE_DOUBLE */+	.short L_case_d - 0b	/* FFI_TYPE_LONGDOUBLE */+#else+	.short L_case_i - 0b	/* FFI_TYPE_FLOAT */+	.short L_case_ll - 0b	/* FFI_TYPE_DOUBLE */+	.short L_case_ll - 0b	/* FFI_TYPE_LONGDOUBLE */+#endif+	.short L_case_uq - 0b	/* FFI_TYPE_UINT8 */+	.short L_case_q - 0b	/* FFI_TYPE_SINT8 */+	.short L_case_uh - 0b	/* FFI_TYPE_UINT16 */+	.short L_case_h - 0b	/* FFI_TYPE_SINT16 */+	.short L_case_i - 0b	/* FFI_TYPE_UINT32 */+	.short L_case_i - 0b	/* FFI_TYPE_SINT32 */+	.short L_case_ll - 0b	/* FFI_TYPE_UINT64 */+	.short L_case_ll - 0b	/* FFI_TYPE_SINT64 */+	.short L_case_v - 0b	/* FFI_TYPE_STRUCT */+	.short L_case_i - 0b	/* FFI_TYPE_POINTER */++#if defined(__SH4__)+L_case_d:+#ifdef __LITTLE_ENDIAN__+	fmov.s	@r2+,fr1+	bra	L_case_v+	 fmov.s	@r2,fr0+#else+	fmov.s	@r2+,fr0+	bra	L_case_v+	 fmov.s	@r2,fr1+#endif++L_case_f:+	bra	L_case_v+	 fmov.s	@r2,fr0+#endif+	+L_case_ll:+	mov.l	@r2+,r0+	bra	L_case_v+	 mov.l	@r2,r1+	+L_case_i:+	bra	L_case_v+	 mov.l	@r2,r0+	+L_case_q:+#ifdef __LITTLE_ENDIAN__+#else+	add	#3,r2+#endif+	bra	L_case_v+	 mov.b	@r2,r0++L_case_uq:+#ifdef __LITTLE_ENDIAN__+#else+	add	#3,r2+#endif+	mov.b	@r2,r0+	bra	L_case_v+	 extu.b r0,r0++L_case_h:+#ifdef __LITTLE_ENDIAN__+#else+	add	#2,r2+#endif+	bra	L_case_v+	 mov.w	@r2,r0++L_case_uh:+#ifdef __LITTLE_ENDIAN__+#else+	add	#2,r2+#endif+	mov.w	@r2,r0+	extu.w	r0,r0+	/* fall through */++L_case_v:+#if defined(__SH4__)+	add	#48,r15+#else+	add	#16,r15+#endif+	lds.l	@r15+,pr+	mov.l	@r15+,r14+	rts+	 add	#16,r15+.LFE2:+.ffi_closure_SYSV_end:+        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif++	.section	".eh_frame","aw",@progbits+__FRAME_BEGIN__:+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */+.LSCIE1:+	.4byte	0x0	/* CIE Identifier Tag */+	.byte	0x1	/* CIE Version */+#ifdef PIC+	.ascii "zR\0"	/* CIE Augmentation */+#else+	.byte	0x0	/* CIE Augmentation */+#endif+	.byte	0x1	/* uleb128 0x1; CIE Code Alignment Factor */+	.byte	0x7c	/* sleb128 -4; CIE Data Alignment Factor */+	.byte	0x11	/* CIE RA Column */+#ifdef PIC+	.uleb128 0x1	/* Augmentation size */+	.byte	0x10	/* FDE Encoding (pcrel) */+#endif+	.byte	0xc	/* DW_CFA_def_cfa */+	.byte	0xf	/* uleb128 0xf */+	.byte	0x0	/* uleb128 0x0 */+	.align	2+.LECIE1:+.LSFDE1:+	.4byte	.LEFDE1-.LASFDE1	/* FDE Length */+.LASFDE1:+	.4byte	.LASFDE1-__FRAME_BEGIN__	/* FDE CIE offset */+#ifdef PIC+	.4byte	.LFB1-.	/* FDE initial location */+#else+	.4byte	.LFB1	/* FDE initial location */+#endif+	.4byte	.LFE1-.LFB1	 /* FDE address range */+#ifdef PIC+	.uleb128 0x0	/* Augmentation size */+#endif+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI0-.LFB1+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x4	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI1-.LCFI0+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x8	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI2-.LCFI1+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0xc	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI3-.LCFI2+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x10	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI4-.LCFI3+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x14	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI5-.LCFI4+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x18	/* uleb128 0x4 */+	.byte	0x91	/* DW_CFA_offset, column 0x11 */+	.byte	0x6	/* uleb128 0x6 */+	.byte	0x8e	/* DW_CFA_offset, column 0xe */+	.byte	0x5	/* uleb128 0x5 */+	.byte	0x8c	/* DW_CFA_offset, column 0xc */+	.byte	0x4	/* uleb128 0x4 */+	.byte	0x8a	/* DW_CFA_offset, column 0xa */+	.byte	0x3	/* uleb128 0x3 */+	.byte	0x89	/* DW_CFA_offset, column 0x9 */+	.byte	0x2	/* uleb128 0x2 */+	.byte	0x88	/* DW_CFA_offset, column 0x8 */+	.byte	0x1	/* uleb128 0x1 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI6-.LCFI5+	.byte	0xd	/* DW_CFA_def_cfa_register */+	.byte	0xe	/* uleb128 0xe */+	.align	2+.LEFDE1:++.LSFDE3:+	.4byte	.LEFDE3-.LASFDE3	/* FDE Length */+.LASFDE3:+	.4byte	.LASFDE3-__FRAME_BEGIN__	/* FDE CIE offset */+#ifdef PIC+	.4byte	.LFB2-.	/* FDE initial location */+#else+	.4byte	.LFB2	/* FDE initial location */+#endif+	.4byte	.LFE2-.LFB2	 /* FDE address range */+#ifdef PIC+	.uleb128 0x0	/* Augmentation size */+#endif+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI7-.LFB2+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x4	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI8-.LCFI7+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x8	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFI9-.LCFI8+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0xc	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFIA-.LCFI9+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x10	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFIB-.LCFIA+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x14	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFIC-.LCFIB+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.byte	0x18	/* uleb128 0x4 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFID-.LCFIC+	.byte	0xe	/* DW_CFA_def_cfa_offset */+#if defined(__SH4__)+	.byte	24+48	/* uleb128 24+48 */+#else+	.byte	24+16	/* uleb128 24+16 */+#endif+	.byte	0x91	/* DW_CFA_offset, column 0x11 */+	.byte	0x6	/* uleb128 0x6 */+	.byte	0x8e	/* DW_CFA_offset, column 0xe */+	.byte	0x5	/* uleb128 0x5 */+	.byte	0x84	/* DW_CFA_offset, column 0x4 */+	.byte	0x4	/* uleb128 0x4 */+	.byte	0x85	/* DW_CFA_offset, column 0x5 */+	.byte	0x3	/* uleb128 0x3 */+	.byte	0x86	/* DW_CFA_offset, column 0x6 */+	.byte	0x2	/* uleb128 0x2 */+	.byte	0x87	/* DW_CFA_offset, column 0x7 */+	.byte	0x1	/* uleb128 0x1 */+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	.LCFIE-.LCFID+	.byte	0xd	/* DW_CFA_def_cfa_register */+	.byte	0xe	/* uleb128 0xe */+	.align	2+.LEFDE3:
+ src/sh64/ffi.c view
@@ -0,0 +1,469 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2003, 2004, 2006, 2007, 2012 Kaz Kojima+           Copyright (c) 2008 Anthony Green+   +   SuperH SHmedia 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>++#define NGREGARG 8+#define NFREGARG 12++static int+return_type (ffi_type *arg)+{++  if (arg->type != FFI_TYPE_STRUCT)+    return arg->type;++  /* gcc uses r2 if the result can be packed in on register.  */+  if (arg->size <= sizeof (UINT8))+    return FFI_TYPE_UINT8;+  else if (arg->size <= sizeof (UINT16))+    return FFI_TYPE_UINT16;+  else if (arg->size <= sizeof (UINT32))+    return FFI_TYPE_UINT32;+  else if (arg->size <= sizeof (UINT64))+    return FFI_TYPE_UINT64;++  return FFI_TYPE_STRUCT;+}++/* 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 unsigned int avn;+  register void **p_argv;+  register char *argp;+  register ffi_type **p_arg;++  argp = stack;++  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)+    {+      *(void **) argp = ecif->rvalue;+      argp += sizeof (UINT64);+    }++  avn = ecif->cif->nargs;+  p_argv = ecif->avalue;++  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)+    {+      size_t z;+      int align;++      z = (*p_arg)->size;+      align = (*p_arg)->alignment;+      if (z < sizeof (UINT32))+	{+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	      *(SINT64 *) argp = (SINT64) *(SINT8 *)(*p_argv);+	      break;+  +	    case FFI_TYPE_UINT8:+	      *(UINT64 *) argp = (UINT64) *(UINT8 *)(*p_argv);+	      break;+  +	    case FFI_TYPE_SINT16:+	      *(SINT64 *) argp = (SINT64) *(SINT16 *)(*p_argv);+	      break;+  +	    case FFI_TYPE_UINT16:+	      *(UINT64 *) argp = (UINT64) *(UINT16 *)(*p_argv);+	      break;+  +	    case FFI_TYPE_STRUCT:+	      memcpy (argp, *p_argv, z);+	      break;++	    default:+	      FFI_ASSERT(0);+	    }+	  argp += sizeof (UINT64);+	}+      else if (z == sizeof (UINT32) && align == sizeof (UINT32))+	{+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_INT:+	    case FFI_TYPE_SINT32:+	      *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);+	      break;++	    case FFI_TYPE_FLOAT:+	    case FFI_TYPE_POINTER:+	    case FFI_TYPE_UINT32:+	    case FFI_TYPE_STRUCT:+	      *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);+	      break;++	    default:+	      FFI_ASSERT(0);+	      break;+	    }+	  argp += sizeof (UINT64);+	}+      else if (z == sizeof (UINT64)+	       && align == sizeof (UINT64)+	       && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0)+	{+	  *(UINT64 *) argp = *(UINT64 *) (*p_argv);+	  argp += sizeof (UINT64);+	}+      else+	{+	  int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);++	  memcpy (argp, *p_argv, z);+	  argp += n * sizeof (UINT64);+	}+    }++  return;+}++/* Perform machine dependent cif processing */+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+  int i, j;+  int size, type;+  int n, m;+  int greg;+  int freg;+  int fpair = -1;++  greg = (return_type (cif->rtype) == FFI_TYPE_STRUCT ? 1 : 0);+  freg = 0;+  cif->flags2 = 0;++  for (i = j = 0; i < cif->nargs; i++)+    {+      type = (cif->arg_types)[i]->type;+      switch (type)+	{+	case FFI_TYPE_FLOAT:+	  greg++;+	  cif->bytes += sizeof (UINT64) - sizeof (float);+	  if (freg >= NFREGARG - 1)+	    continue;+	  if (fpair < 0)+	    {+	      fpair = freg;+	      freg += 2;+	    }+	  else+	    fpair = -1;+	  cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);+	  break;++	case FFI_TYPE_DOUBLE:+	  if (greg++ >= NGREGARG && (freg + 1) >= NFREGARG)+	    continue;+	  if ((freg + 1) < NFREGARG)+	    {+	      freg += 2;+	      cif->flags2 += ((cif->arg_types)[i]->type) << (2 * j++);+	    }+	  else+	    cif->flags2 += FFI_TYPE_INT << (2 * j++);+	  break;+	      +	default:+	  size = (cif->arg_types)[i]->size;+	  if (size < sizeof (UINT64))+	    cif->bytes += sizeof (UINT64) - size;+	  n = (size + sizeof (UINT64) - 1) / sizeof (UINT64);+	  if (greg >= NGREGARG)+	    continue;+	  else if (greg + n - 1 >= NGREGARG)+	    greg = NGREGARG;+	  else+	    greg += n;+	  for (m = 0; m < n; m++)+	    cif->flags2 += FFI_TYPE_INT << (2 * j++);+	  break;+	}+    }++  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_STRUCT:+      cif->flags = return_type (cif->rtype);+      break;++    case FFI_TYPE_VOID:+    case FFI_TYPE_FLOAT:+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      cif->flags = cif->rtype->type;+      break;++    default:+      cif->flags = FFI_TYPE_INT;+      break;+    }++  return FFI_OK;+}++/*@-declundef@*/+/*@-exportheader@*/+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), +			  /*@out@*/ extended_cif *, +			  unsigned, unsigned, long long,+			  /*@out@*/ unsigned *, +			  void (*fn)(void));+/*@=declundef@*/+/*@=exportheader@*/++void ffi_call(/*@dependent@*/ ffi_cif *cif, +	      void (*fn)(void), +	      /*@out@*/ void *rvalue, +	      /*@dependent@*/ void **avalue)+{+  extended_cif ecif;+  UINT64 trvalue;++  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 (cif->rtype->type == FFI_TYPE_STRUCT+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)+    ecif.rvalue = &trvalue;+  else if ((rvalue == NULL) && +      (cif->rtype->type == FFI_TYPE_STRUCT))+    {+      ecif.rvalue = alloca(cif->rtype->size);+    }+  else+    ecif.rvalue = rvalue;++  switch (cif->abi) +    {+    case FFI_SYSV:+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, cif->flags2,+		    ecif.rvalue, fn);+      break;+    default:+      FFI_ASSERT(0);+      break;+    }++  if (rvalue+      && cif->rtype->type == FFI_TYPE_STRUCT+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)+    memcpy (rvalue, &trvalue, cif->rtype->size);+}++extern void ffi_closure_SYSV (void);+extern void __ic_invalidate (void *line);++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;++  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  tramp = (unsigned int *) &closure->tramp[0];+  /* Since ffi_closure is an aligned object, the ffi trampoline is+     called as an SHcompact code.  Sigh.+     SHcompact part:+     mova @(1,pc),r0; add #1,r0; jmp @r0; nop;+     SHmedia part:+     movi fnaddr >> 16,r1; shori fnaddr,r1; ptabs/l r1,tr0+     movi cxt >> 16,r1; shori cxt,r1; blink tr0,r63  */+#ifdef __LITTLE_ENDIAN__+  tramp[0] = 0x7001c701;+  tramp[1] = 0x0009402b;+#else+  tramp[0] = 0xc7017001;+  tramp[1] = 0x402b0009;+#endif+  tramp[2] = 0xcc000010 | (((UINT32) ffi_closure_SYSV) >> 16) << 10;+  tramp[3] = 0xc8000010 | (((UINT32) ffi_closure_SYSV) & 0xffff) << 10;+  tramp[4] = 0x6bf10600;+  tramp[5] = 0xcc000010 | (((UINT32) codeloc) >> 16) << 10;+  tramp[6] = 0xc8000010 | (((UINT32) codeloc) & 0xffff) << 10;+  tramp[7] = 0x4401fff0;++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  /* Flush the icache.  */+  asm volatile ("ocbwb %0,0; synco; icbi %1,0; synci" : : "r" (tramp),+		"r"(codeloc));++  return FFI_OK;+}++/* Basically the trampoline invokes ffi_closure_SYSV, and on + * entry, r3 holds the address of the closure.+ * After storing the registers that could possibly contain+ * parameters to be passed into the stack frame and setting+ * up space for a return value, ffi_closure_SYSV invokes the + * following helper function to do most of the work.+ */++int+ffi_closure_helper_SYSV (ffi_closure *closure, UINT64 *rvalue, +			 UINT64 *pgr, UINT64 *pfr, UINT64 *pst)+{+  void **avalue;+  ffi_type **p_arg;+  int i, avn;+  int greg, freg;+  ffi_cif *cif;+  int fpair = -1;++  cif = closure->cif;+  avalue = alloca (cif->nargs * sizeof (void *));++  /* Copy the caller's structure return value address so that the closure+     returns the data directly to the caller.  */+  if (return_type (cif->rtype) == FFI_TYPE_STRUCT)+    {+      rvalue = (UINT64 *) *pgr;+      greg = 1;+    }+  else+    greg = 0;++  freg = 0;+  cif = closure->cif;+  avn = cif->nargs;++  /* Grab the addresses of the arguments from the stack frame.  */+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)+    {+      size_t z;+      void *p;++      z = (*p_arg)->size;+      if (z < sizeof (UINT32))+	{+	  p = pgr + greg++;++	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	    case FFI_TYPE_UINT8:+	    case FFI_TYPE_SINT16:+	    case FFI_TYPE_UINT16:+	    case FFI_TYPE_STRUCT:+#ifdef __LITTLE_ENDIAN__+	      avalue[i] = p;+#else+	      avalue[i] = ((char *) p) + sizeof (UINT32) - z;+#endif+	      break;++	    default:+	      FFI_ASSERT(0);+	    }+	}+      else if (z == sizeof (UINT32))+	{+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)+	    {+	      if (freg < NFREGARG - 1)+		{+		  if (fpair >= 0)+		    {+		      avalue[i] = (UINT32 *) pfr + fpair;+		      fpair = -1;+		    }+		  else+		    {+#ifdef __LITTLE_ENDIAN__+		      fpair = freg;+		      avalue[i] = (UINT32 *) pfr + (1 ^ freg);+#else+		      fpair = 1 ^ freg;+		      avalue[i] = (UINT32 *) pfr + freg;+#endif+		      freg += 2;+		    }+		}+	      else+#ifdef __LITTLE_ENDIAN__+		avalue[i] = pgr + greg;+#else+		avalue[i] = (UINT32 *) (pgr + greg) + 1;+#endif+	    }+	  else+#ifdef __LITTLE_ENDIAN__+	    avalue[i] = pgr + greg;+#else+	    avalue[i] = (UINT32 *) (pgr + greg) + 1;+#endif+	  greg++;+	}+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)+	{+	  if (freg + 1 >= NFREGARG)+	    avalue[i] = pgr + greg;+	  else+	    {+	      avalue[i] = pfr + (freg >> 1);+	      freg += 2;+	    }+	  greg++;+	}+      else+	{+	  int n = (z + sizeof (UINT64) - 1) / sizeof (UINT64);++	  avalue[i] = pgr + greg;+	  greg += n;+	}+    }++  (closure->fun) (cif, rvalue, avalue, closure->user_data);++  /* Tell ffi_closure_SYSV how to perform return type promotions.  */+  return return_type (cif->rtype);+}+
+ src/sh64/ffitarget.h view
@@ -0,0 +1,58 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for SuperH - SHmedia.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- Generic type definitions ----------------------------------------- */++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;++#define FFI_EXTRA_CIF_FIELDS long long flags2+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 32+#define FFI_NATIVE_RAW_API 0++#endif+
+ src/sh64/sysv.S view
@@ -0,0 +1,539 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2003, 2004, 2006, 2008 Kaz Kojima+   +   SuperH SHmedia Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++ +   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>+#ifdef HAVE_MACHINE_ASM_H+#include <machine/asm.h>+#else+/* XXX these lose for some platforms, I'm sure. */+#define CNAME(x) x+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):+#endif++#ifdef __LITTLE_ENDIAN__+#define OFS_FLT	0+#else+#define OFS_FLT	4+#endif++	.section	.text..SHmedia32,"ax"++	# r2:	ffi_prep_args+	# r3:	&ecif+	# r4:	bytes+	# r5:	flags+	# r6:	flags2+	# r7:	rvalue+	# r8:	fn++	# This assumes we are using gas.+	.align	5+ENTRY(ffi_call_SYSV)+	# Save registers+.LFB1:+	addi.l	r15, -48, r15+.LCFI0:+	st.q	r15, 40, r32+	st.q	r15, 32, r31+	st.q	r15, 24, r30+	st.q	r15, 16, r29+	st.q	r15, 8, r28+	st.l	r15, 4, r18+	st.l	r15, 0, r14+.LCFI1:+	add.l	r15, r63, r14+.LCFI2:+#	add	r4, r63, r28+	add	r5, r63, r29+	add	r6, r63, r30+	add	r7, r63, r31+	add	r8, r63, r32++	addi	r4, (64 + 7), r4+	andi	r4, ~7, r4+	sub.l	r15, r4, r15++	ptabs/l	r2, tr0+	add	r15, r63, r2+	blink	tr0, r18++	addi	r15, 64, r22+	movi	0, r0+	movi	0, r1+	movi	-1, r23++	pt/l	1f, tr1+	bnei/l	r29, FFI_TYPE_STRUCT, tr1+	ld.l	r15, 0, r19+	addi	r15, 8, r15+	addi	r0, 1, r0+1:++.L_pass:+	andi	r30, 3, r20+	shlri	r30, 2, r30++	pt/l	.L_call_it, tr0+	pt/l	.L_pass_i, tr1+	pt/l	.L_pass_f, tr2++	beqi/l	r20, FFI_TYPE_VOID, tr0+	beqi/l	r20, FFI_TYPE_INT, tr1+	beqi/l	r20, FFI_TYPE_FLOAT, tr2++.L_pass_d:+	addi	r0, 1, r0+	pt/l	3f, tr0+	movi	12, r20+	bge/l	r1, r20, tr0++	pt/l	.L_pop_d, tr1+	pt/l	2f, tr0+	blink	tr1, r63+2:+	addi.l	r15, 8, r15+3:+	pt/l	.L_pass, tr0+	addi	r1, 2, r1+	blink	tr0, r63++.L_pop_d:+	pt/l	.L_pop_d_tbl, tr1+	gettr	tr1, r20+	shlli	r1, 2, r21+	add	r20, r21, r20+	ptabs/l	r20, tr1+	blink	tr1, r63++.L_pop_d_tbl:+	fld.d	r15, 0, dr0+	blink	tr0, r63+	fld.d	r15, 0, dr2+	blink	tr0, r63+	fld.d	r15, 0, dr4+	blink	tr0, r63+	fld.d	r15, 0, dr6+	blink	tr0, r63+	fld.d	r15, 0, dr8+	blink	tr0, r63+	fld.d	r15, 0, dr10+	blink	tr0, r63++.L_pass_f:+	addi	r0, 1, r0+	pt/l	3f, tr0+	movi	12, r20+	bge/l	r1, r20, tr0++	pt/l	.L_pop_f, tr1+	pt/l	2f, tr0+	blink	tr1, r63+2:+	addi.l	r15, 8, r15+3:+	pt/l	.L_pass, tr0+	blink	tr0, r63++.L_pop_f:+	pt/l	.L_pop_f_tbl, tr1+	pt/l	5f, tr2+	gettr	tr1, r20+	bge/l	r23, r63, tr2+	add	r1, r63, r23 +	shlli	r1, 3, r21+	addi	r1, 2, r1+	add	r20, r21, r20+	ptabs/l	r20, tr1+	blink	tr1, r63+5:+	addi	r23, 1, r21+	movi	-1, r23+	shlli	r21, 3, r21+	add	r20, r21, r20+	ptabs/l	r20, tr1+	blink	tr1, r63++.L_pop_f_tbl:+	fld.s	r15, OFS_FLT, fr0+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr1+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr2+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr3+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr4+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr5+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr6+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr7+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr8+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr9+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr10+	blink	tr0, r63+	fld.s	r15, OFS_FLT, fr11+	blink	tr0, r63++.L_pass_i:+	pt/l	3f, tr0+	movi	8, r20+	bge/l	r0, r20, tr0++	pt/l	.L_pop_i, tr1+	pt/l	2f, tr0+	blink	tr1, r63+2:+	addi.l	r15, 8, r15+3:+	pt/l	.L_pass, tr0+	addi	r0, 1, r0+	blink	tr0, r63++.L_pop_i:+	pt/l	.L_pop_i_tbl, tr1+	gettr	tr1, r20+	shlli	r0, 3, r21+	add	r20, r21, r20+	ptabs/l	r20, tr1+	blink	tr1, r63++.L_pop_i_tbl:+	ld.q	r15, 0, r2+	blink	tr0, r63+	ld.q	r15, 0, r3+	blink	tr0, r63+	ld.q	r15, 0, r4+	blink	tr0, r63+	ld.q	r15, 0, r5+	blink	tr0, r63+	ld.q	r15, 0, r6+	blink	tr0, r63+	ld.q	r15, 0, r7+	blink	tr0, r63+	ld.q	r15, 0, r8+	blink	tr0, r63+	ld.q	r15, 0, r9+	blink	tr0, r63++.L_call_it:+	# call function+	pt/l	1f, tr1+	bnei/l	r29, FFI_TYPE_STRUCT, tr1+	add	r19, r63, r2+1:+	add	r22, r63, r15+	ptabs/l	r32, tr0+	blink	tr0, r18++	pt/l	.L_ret_i, tr0+	pt/l	.L_ret_ll, tr1+	pt/l	.L_ret_d, tr2+	pt/l	.L_ret_f, tr3+	pt/l	.L_epilogue, tr4++	beqi/l	r29, FFI_TYPE_INT, tr0+	beqi/l	r29, FFI_TYPE_UINT32, tr0+	beqi/l	r29, FFI_TYPE_SINT64, tr1+	beqi/l	r29, FFI_TYPE_UINT64, tr1+	beqi/l	r29, FFI_TYPE_DOUBLE, tr2+	beqi/l	r29, FFI_TYPE_FLOAT, tr3++	pt/l	.L_ret_q, tr0+	pt/l	.L_ret_h, tr1++	beqi/l	r29, FFI_TYPE_UINT8, tr0+	beqi/l	r29, FFI_TYPE_UINT16, tr1+	blink	tr4, r63++.L_ret_d:+	fst.d	r31, 0, dr0+	blink	tr4, r63++.L_ret_ll:+	st.q	r31, 0, r2+	blink	tr4, r63++.L_ret_f:+	fst.s	r31, OFS_FLT, fr0+	blink	tr4, r63++.L_ret_q:+	st.b	r31, 0, r2+	blink	tr4, r63++.L_ret_h:+	st.w	r31, 0, r2+	blink	tr4, r63++.L_ret_i:+	st.l	r31, 0, r2+	# Fall++.L_epilogue:+	# Remove the space we pushed for the args+	add	r14, r63, r15++	ld.l	r15, 0, r14+	ld.l	r15, 4, r18+	ld.q	r15, 8, r28+	ld.q	r15, 16, r29+	ld.q	r15, 24, r30+	ld.q	r15, 32, r31+	ld.q	r15, 40, r32+	addi.l	r15, 48, r15+	ptabs	r18, tr0+	blink	tr0, r63++.LFE1:+.ffi_call_SYSV_end:+	.size	 CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)++	.align	5+ENTRY(ffi_closure_SYSV)+.LFB2:+	addi.l	r15, -136, r15+.LCFI3:+	st.l	r15, 12, r18+	st.l	r15, 8, r14+	st.l	r15, 4, r12+.LCFI4:+	add	r15, r63, r14+.LCFI5:+	/* Stack layout:	+	   ...+	   64 bytes (register parameters)+	   48 bytes (floating register parameters)+	    8 bytes (result)+	    4 bytes (r18)+	    4 bytes (r14)+	    4 bytes (r12)+	    4 bytes (for align)+	   <- new stack pointer+	*/+	fst.d	r14, 24, dr0+	fst.d	r14, 32, dr2+	fst.d	r14, 40, dr4+	fst.d	r14, 48, dr6+	fst.d	r14, 56, dr8+	fst.d	r14, 64, dr10+	st.q	r14, 72, r2+	st.q	r14, 80, r3+	st.q	r14, 88, r4+	st.q	r14, 96, r5+	st.q	r14, 104, r6+	st.q	r14, 112, r7+	st.q	r14, 120, r8+	st.q	r14, 128, r9++	add	r1, r63, r2+	addi	r14, 16, r3+	addi	r14, 72, r4+	addi	r14, 24, r5+	addi	r14, 136, r6+#ifdef PIC+	movi	(((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12+        shori	((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12+.LPCS0:	ptrel/u r12, tr0+	movi	((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1+	gettr	tr0, r12+	ldx.l	r1, r12, r1+	ptabs	r1, tr0+#else+	pt/l	ffi_closure_helper_SYSV, tr0+#endif+	blink	tr0, r18++	shlli	r2, 1, r1+        movi    (((datalabel .L_table) >> 16) & 65535), r2+        shori   ((datalabel .L_table) & 65535), r2+        ldx.w   r2, r1, r1+        add     r1, r2, r1+	pt/l	.L_case_v, tr1+        ptabs   r1, tr0+        blink   tr0, r63++        .align 2+.L_table:+	.word	.L_case_v - datalabel .L_table	/* FFI_TYPE_VOID */+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_INT */+	.word	.L_case_f - datalabel .L_table	/* FFI_TYPE_FLOAT */+	.word	.L_case_d - datalabel .L_table	/* FFI_TYPE_DOUBLE */+	.word	.L_case_d - datalabel .L_table	/* FFI_TYPE_LONGDOUBLE */+	.word	.L_case_uq - datalabel .L_table	/* FFI_TYPE_UINT8 */+	.word	.L_case_q - datalabel .L_table	/* FFI_TYPE_SINT8 */+	.word	.L_case_uh - datalabel .L_table	/* FFI_TYPE_UINT16 */+	.word	.L_case_h - datalabel .L_table	/* FFI_TYPE_SINT16 */+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_UINT32 */+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_SINT32 */+	.word	.L_case_ll - datalabel .L_table	/* FFI_TYPE_UINT64 */+	.word	.L_case_ll - datalabel .L_table	/* FFI_TYPE_SINT64 */+	.word	.L_case_v - datalabel .L_table	/* FFI_TYPE_STRUCT */+	.word	.L_case_i - datalabel .L_table	/* FFI_TYPE_POINTER */++        .align 2+.L_case_d:+	fld.d	r14, 16, dr0+	blink	tr1, r63+.L_case_f:+	fld.s	r14, 16, fr0+	blink	tr1, r63+.L_case_ll:+	ld.q	r14, 16, r2+	blink	tr1, r63+.L_case_i:+	ld.l	r14, 16, r2+	blink	tr1, r63+.L_case_q:+	ld.b	r14, 16, r2+	blink	tr1, r63+.L_case_uq:+	ld.ub	r14, 16, r2+	blink	tr1, r63+.L_case_h:+	ld.w	r14, 16, r2+	blink	tr1, r63+.L_case_uh:+	ld.uw	r14, 16, r2+	blink	tr1, r63+.L_case_v:+	add.l	r14, r63, r15+	ld.l	r15, 4, r12+	ld.l	r15, 8, r14+	ld.l	r15, 12, r18+	addi.l	r15, 136, r15+	ptabs	r18, tr0+	blink	tr0, r63++.LFE2:+.ffi_closure_SYSV_end:+	.size	 CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif++	.section	".eh_frame","aw",@progbits+__FRAME_BEGIN__:+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */+.LSCIE1:+	.4byte	0x0	/* CIE Identifier Tag */+	.byte	0x1	/* CIE Version */+#ifdef PIC+	.ascii "zR\0"	/* CIE Augmentation */+#else+	.byte	0x0	/* CIE Augmentation */+#endif+	.uleb128 0x1	/* CIE Code Alignment Factor */+	.sleb128 -4	/* CIE Data Alignment Factor */+	.byte	0x12	/* CIE RA Column */+#ifdef PIC+	.uleb128 0x1	/* Augmentation size */+	.byte	0x10	/* FDE Encoding (pcrel) */+#endif+	.byte	0xc	/* DW_CFA_def_cfa */+	.uleb128 0xf+	.uleb128 0x0+	.align	2+.LECIE1:+.LSFDE1:+	.4byte	datalabel .LEFDE1-datalabel .LASFDE1	/* FDE Length */+.LASFDE1:+	.4byte	datalabel .LASFDE1-datalabel __FRAME_BEGIN__+#ifdef PIC+	.4byte	.LFB1-.	/* FDE initial location */+#else+	.4byte	.LFB1	/* FDE initial location */+#endif+	.4byte	datalabel .LFE1-datalabel .LFB1	/* FDE address range */+#ifdef PIC+	.uleb128 0x0	/* Augmentation size */+#endif+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	datalabel .LCFI0-datalabel .LFB1+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.uleb128 0x30+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	datalabel .LCFI1-datalabel .LCFI0+	.byte   0x8e	/* DW_CFA_offset, column 0xe */+	.uleb128 0xc+	.byte   0x92	/* DW_CFA_offset, column 0x12 */+	.uleb128 0xb+	.byte   0x9c	/* DW_CFA_offset, column 0x1c */+	.uleb128 0xa+	.byte   0x9d	/* DW_CFA_offset, column 0x1d */+	.uleb128 0x8+	.byte   0x9e	/* DW_CFA_offset, column 0x1e */+	.uleb128 0x6+	.byte   0x9f	/* DW_CFA_offset, column 0x1f */+	.uleb128 0x4+	.byte   0xa0	/* DW_CFA_offset, column 0x20 */+	.uleb128 0x2+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	datalabel .LCFI2-datalabel .LCFI1+	.byte	0xd	/* DW_CFA_def_cfa_register */+	.uleb128 0xe+	.align	2+.LEFDE1:++.LSFDE3:+	.4byte	datalabel .LEFDE3-datalabel .LASFDE3	/* FDE Length */+.LASFDE3:+	.4byte	datalabel .LASFDE3-datalabel __FRAME_BEGIN__+#ifdef PIC+	.4byte	.LFB2-.	/* FDE initial location */+#else+	.4byte	.LFB2	/* FDE initial location */+#endif+	.4byte	datalabel .LFE2-datalabel .LFB2	/* FDE address range */+#ifdef PIC+	.uleb128 0x0	/* Augmentation size */+#endif+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	datalabel .LCFI3-datalabel .LFB2+	.byte	0xe	/* DW_CFA_def_cfa_offset */+	.uleb128 0x88+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	datalabel .LCFI4-datalabel .LCFI3+	.byte   0x8c	/* DW_CFA_offset, column 0xc */+	.uleb128 0x21+	.byte   0x8e	/* DW_CFA_offset, column 0xe */+	.uleb128 0x20+	.byte   0x92	/* DW_CFA_offset, column 0x12 */+	.uleb128 0x1f+	.byte	0x4	/* DW_CFA_advance_loc4 */+	.4byte	datalabel .LCFI5-datalabel .LCFI4+	.byte	0xd	/* DW_CFA_def_cfa_register */+	.uleb128 0xe+	.align	2+.LEFDE3:
+ src/sparc/ffi.c view
@@ -0,0 +1,484 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2011, 2013 Anthony Green+           Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.+   +   SPARC Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>+#include "internal.h"++#ifndef SPARC64++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;+   all further uses in this file will refer to the 128-bit type.  */+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+# if FFI_TYPE_LONGDOUBLE != 4+#  error FFI_TYPE_LONGDOUBLE out of date+# endif+#else+# undef FFI_TYPE_LONGDOUBLE+# define FFI_TYPE_LONGDOUBLE 4+#endif++/* Perform machine dependent cif processing */+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep(ffi_cif *cif)+{+  ffi_type *rtype = cif->rtype;+  int rtt = rtype->type;+  size_t bytes;+  int i, n, flags;++  /* Set the return type flag */+  switch (rtt)+    {+    case FFI_TYPE_VOID:+      flags = SPARC_RET_VOID;+      break;+    case FFI_TYPE_FLOAT:+      flags = SPARC_RET_F_1;+      break;+    case FFI_TYPE_DOUBLE:+      flags = SPARC_RET_F_2;+      break;+    case FFI_TYPE_LONGDOUBLE:+    case FFI_TYPE_STRUCT:+      flags = (rtype->size & 0xfff) << SPARC_SIZEMASK_SHIFT;+      flags |= SPARC_RET_STRUCT;+      break;+    case FFI_TYPE_SINT8:+      flags = SPARC_RET_SINT8;+      break;+    case FFI_TYPE_UINT8:+      flags = SPARC_RET_UINT8;+      break;+    case FFI_TYPE_SINT16:+      flags = SPARC_RET_SINT16;+      break;+    case FFI_TYPE_UINT16:+      flags = SPARC_RET_UINT16;+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_POINTER:+      flags = SPARC_RET_UINT32;+      break;+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      flags = SPARC_RET_INT64;+      break;+    case FFI_TYPE_COMPLEX:+      rtt = rtype->elements[0]->type;+      switch (rtt)+	{+	case FFI_TYPE_FLOAT:+	  flags = SPARC_RET_F_2;+	  break;+	case FFI_TYPE_DOUBLE:+	  flags = SPARC_RET_F_4;+	  break;+	case FFI_TYPE_LONGDOUBLE:+	  flags = SPARC_RET_F_8;+	  break;+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	  flags = SPARC_RET_INT128;+	  break;+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	  flags = SPARC_RET_INT64;+	  break;+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	  flags = SP_V8_RET_CPLX16;+	  break;+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	  flags = SP_V8_RET_CPLX8;+	  break;+	default:+	  abort();+	}+      break;+    default:+      abort();+    }+  cif->flags = flags;++  bytes = 0;+  for (i = 0, n = cif->nargs; i < n; ++i)+    {+      ffi_type *ty = cif->arg_types[i];+      size_t z = ty->size;+      int tt = ty->type;++      switch (tt)+	{+	case FFI_TYPE_STRUCT:+	case FFI_TYPE_LONGDOUBLE:+	by_reference:+	  /* Passed by reference.  */+	  z = 4;+	  break;++	case FFI_TYPE_COMPLEX:+	  tt = ty->elements[0]->type;+	  if (tt == FFI_TYPE_FLOAT || z > 8)+	    goto by_reference;+	  /* FALLTHRU */++	default:+	  z = FFI_ALIGN(z, 4);+	}+      bytes += z;+    }++  /* Sparc call frames require that space is allocated for 6 args,+     even if they aren't used. Make that space if necessary.  */+  if (bytes < 6 * 4)+    bytes = 6 * 4;++  /* The ABI always requires space for the struct return pointer.  */+  bytes += 4;++  /* The stack must be 2 word aligned, so round bytes up appropriately. */+  bytes = FFI_ALIGN(bytes, 2 * 4);++  /* Include the call frame to prep_args.  */+  bytes += 4*16 + 4*8;+  cif->bytes = bytes;++  return FFI_OK;+}++extern void ffi_call_v8(ffi_cif *cif, void (*fn)(void), void *rvalue,+			void **avalue, size_t bytes, void *closure) FFI_HIDDEN;++int FFI_HIDDEN+ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)+{+  ffi_type **p_arg;+  int flags = cif->flags;+  int i, nargs;++  if (rvalue == NULL)+    {+      if ((flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)+	{+	  /* Since we pass the pointer to the callee, we need a value.+	     We allowed for this space in ffi_call, before ffi_call_v8+	     alloca'd the space.  */+	  rvalue = (char *)argp + cif->bytes;+	}+      else+	{+	  /* Otherwise, we can ignore the return value.  */+	  flags = SPARC_RET_VOID;+	}+    }++  /* This could only really be done when we are returning a structure.+     However, the space is reserved so we can do it unconditionally.  */+  *argp++ = (unsigned long)rvalue;++#ifdef USING_PURIFY+  /* Purify will probably complain in our assembly routine,+     unless we zero out this memory. */+  memset(argp, 0, 6*4);+#endif++  p_arg = cif->arg_types;+  for (i = 0, nargs = cif->nargs; i < nargs; i++)+    {+      ffi_type *ty = p_arg[i];+      void *a = avalue[i];+      int tt = ty->type;+      size_t z;++      switch (tt)+	{+	case FFI_TYPE_STRUCT:+	case FFI_TYPE_LONGDOUBLE:+	by_reference:+	  *argp++ = (unsigned long)a;+	  break;++	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	  memcpy(argp, a, 8);+	  argp += 2;+	  break;++	case FFI_TYPE_INT:+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_POINTER:+	  *argp++ = *(unsigned *)a;+	  break;++	case FFI_TYPE_UINT8:+	  *argp++ = *(UINT8 *)a;+	  break;+	case FFI_TYPE_SINT8:+	  *argp++ = *(SINT8 *)a;+	  break;+	case FFI_TYPE_UINT16:+	  *argp++ = *(UINT16 *)a;+	  break;+	case FFI_TYPE_SINT16:+	  *argp++ = *(SINT16 *)a;+	  break;++        case FFI_TYPE_COMPLEX:+	  tt = ty->elements[0]->type;+	  z = ty->size;+	  if (tt == FFI_TYPE_FLOAT || z > 8)+	    goto by_reference;+	  if (z < 4)+	    {+	      memcpy((char *)argp + 4 - z, a, z);+	      argp++;+	    }+	  else+	    {+	      memcpy(argp, a, z);+	      argp += z / 4;+	    }+	  break;++	default:+	  abort();+	}+    }++  return flags;+}++static void+ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,+	      void **avalue, void *closure)+{+  size_t bytes = cif->bytes;+  size_t i, nargs = cif->nargs;+  ffi_type **arg_types = cif->arg_types;++  FFI_ASSERT (cif->abi == FFI_V8);++  /* If we've not got a return value, we need to create one if we've+     got to pass the return value to the callee.  Otherwise ignore it.  */+  if (rvalue == NULL+      && (cif->flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)+    bytes += FFI_ALIGN (cif->rtype->size, 8);++  /* If we have any structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT)+        {+          char *argcopy = alloca (size);+          memcpy (argcopy, avalue[i], size);+          avalue[i] = argcopy;+        }+    }++  ffi_call_v8(cif, fn, rvalue, avalue, -bytes, closure);+}++void+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}++#ifdef __GNUC__+static inline void+ffi_flush_icache (void *p)+{+  /* SPARC v8 requires 5 instructions for flush to be visible */+  asm volatile ("iflush	%0; iflush %0+8; nop; nop; nop; nop; nop"+		: : "r" (p) : "memory");+}+#else+extern void ffi_flush_icache (void *) FFI_HIDDEN;+#endif++extern void ffi_closure_v8(void) FFI_HIDDEN;+extern void ffi_go_closure_v8(void) FFI_HIDDEN;++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 ctx = (unsigned long) closure;+  unsigned long fn = (unsigned long) ffi_closure_v8;++  if (cif->abi != FFI_V8)+    return FFI_BAD_ABI;++  tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/+  tramp[1] = 0x05000000 | ctx >> 10;	/* sethi %hi(ctx), %g2	*/+  tramp[2] = 0x81c06000 | (fn & 0x3ff);	/* jmp   %g1+%lo(fn)	*/+  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)	*/++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  ffi_flush_icache (closure);++  return FFI_OK;+}++ffi_status+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,+		     void (*fun)(ffi_cif*, void*, void**, void*))+{+  if (cif->abi != FFI_V8)+    return FFI_BAD_ABI;++  closure->tramp = ffi_go_closure_v8;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++int FFI_HIDDEN+ffi_closure_sparc_inner_v8(ffi_cif *cif, +			   void (*fun)(ffi_cif*, void*, void**, void*),+			   void *user_data, void *rvalue,+			   unsigned long *argp)+{+  ffi_type **arg_types;+  void **avalue;+  int i, nargs, flags;++  arg_types = cif->arg_types;+  nargs = cif->nargs;+  flags = cif->flags;+  avalue = alloca(nargs * sizeof(void *));++  /* Copy the caller's structure return address so that the closure+     returns the data directly to the caller.  Also install it so we+     can return the address in %o0.  */+  if ((flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)+    {+      void *new_rvalue = (void *)*argp;+      *(void **)rvalue = new_rvalue;+      rvalue = new_rvalue;+    }++  /* Always skip the structure return address.  */+  argp++;++  /* Grab the addresses of the arguments from the stack frame.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *ty = arg_types[i];+      int tt = ty->type;+      void *a = argp;+      size_t z;++      switch (tt)+	{+	case FFI_TYPE_STRUCT:+	case FFI_TYPE_LONGDOUBLE:+	by_reference:+	  /* Straight copy of invisible reference.  */+	  a = (void *)*argp;+	  break;++	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	  if ((unsigned long)a & 7)+	    {+	      /* Align on a 8-byte boundary.  */+	      UINT64 *tmp = alloca(8);+	      *tmp = ((UINT64)argp[0] << 32) | argp[1];+	      a = tmp;+	    }+	  argp++;+	  break;++	case FFI_TYPE_INT:+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_POINTER:+	  break;+        case FFI_TYPE_UINT16:+        case FFI_TYPE_SINT16:+	  a += 2;+	  break;+        case FFI_TYPE_UINT8:+        case FFI_TYPE_SINT8:+	  a += 3;+	  break;++        case FFI_TYPE_COMPLEX:+	  tt = ty->elements[0]->type;+	  z = ty->size;+	  if (tt == FFI_TYPE_FLOAT || z > 8)+	    goto by_reference;+	  if (z < 4)+	    a += 4 - z;+	  else if (z > 4)+	    argp++;+	  break;++	default:+	  abort();+	}+      argp++;+      avalue[i] = a;+    }++  /* Invoke the closure.  */+  fun (cif, rvalue, avalue, user_data);++  /* Tell ffi_closure_sparc how to perform return type promotions.  */+  return flags;+}+#endif /* !SPARC64 */
+ src/sparc/ffi64.c view
@@ -0,0 +1,630 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2011, 2013 Anthony Green+           Copyright (c) 1996, 2003-2004, 2007-2008 Red Hat, Inc.++   SPARC Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>+#include "internal.h"++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;+   all further uses in this file will refer to the 128-bit type.  */+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+# if FFI_TYPE_LONGDOUBLE != 4+#  error FFI_TYPE_LONGDOUBLE out of date+# endif+#else+# undef FFI_TYPE_LONGDOUBLE+# define FFI_TYPE_LONGDOUBLE 4+#endif++#ifdef SPARC64++/* Flatten the contents of a structure to the parts that are passed in+   floating point registers.  The return is a bit mask wherein bit N+   set means bytes [4*n, 4*n+3] are passed in %fN.++   We encode both the (running) size (maximum 32) and mask (maxumum 255)+   into one integer.  The size is placed in the low byte, so that align+   and addition work correctly.  The mask is placed in the second byte.  */++static int+ffi_struct_float_mask (ffi_type *outer_type, int size_mask)+{+  ffi_type **elts;+  ffi_type *t;++  if (outer_type->type == FFI_TYPE_COMPLEX)+    {+      int m = 0, tt = outer_type->elements[0]->type;+      size_t z = outer_type->size;++      if (tt == FFI_TYPE_FLOAT+	  || tt == FFI_TYPE_DOUBLE+	  || tt == FFI_TYPE_LONGDOUBLE)+        m = (1 << (z / 4)) - 1;+      return (m << 8) | z;+    }+  FFI_ASSERT (outer_type->type == FFI_TYPE_STRUCT);++  for (elts = outer_type->elements; (t = *elts) != NULL; elts++)+    {+      size_t z = t->size;+      int o, m, tt;++      size_mask = FFI_ALIGN(size_mask, t->alignment);+      switch (t->type)+	{+	case FFI_TYPE_STRUCT:+	  size_mask = ffi_struct_float_mask (t, size_mask);+	  continue;+	case FFI_TYPE_COMPLEX:+	  tt = t->elements[0]->type;+	  if (tt != FFI_TYPE_FLOAT+	      && tt != FFI_TYPE_DOUBLE+	      && tt != FFI_TYPE_LONGDOUBLE)+	    break;+	  /* FALLTHRU */+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	  m = (1 << (z / 4)) - 1;	/* compute mask for type */+	  o = (size_mask >> 2) & 0x3f;	/* extract word offset */+	  size_mask |= m << (o + 8);	/* insert mask into place */+	  break;+	}+      size_mask += z;+    }++  size_mask = FFI_ALIGN(size_mask, outer_type->alignment);+  FFI_ASSERT ((size_mask & 0xff) == outer_type->size);++  return size_mask;+}++/* Merge floating point data into integer data.  If the structure is+   entirely floating point, simply return a pointer to the fp data.  */++static void *+ffi_struct_float_merge (int size_mask, void *vi, void *vf)+{+  int size = size_mask & 0xff;+  int mask = size_mask >> 8;+  int n = size >> 2;++  if (mask == 0)+    return vi;+  else if (mask == (1 << n) - 1)+    return vf;+  else+    {+      unsigned int *wi = vi, *wf = vf;+      int i;++      for (i = 0; i < n; ++i)+	if ((mask >> i) & 1)+	  wi[i] = wf[i];++      return vi;+    }+}++/* Similar, but place the data into VD in the end.  */++void FFI_HIDDEN+ffi_struct_float_copy (int size_mask, void *vd, void *vi, void *vf)+{+  int size = size_mask & 0xff;+  int mask = size_mask >> 8;+  int n = size >> 2;++  if (mask == 0)+    ;+  else if (mask == (1 << n) - 1)+    vi = vf;+  else+    {+      unsigned int *wd = vd, *wi = vi, *wf = vf;+      int i;++      for (i = 0; i < n; ++i)+	wd[i] = ((mask >> i) & 1 ? wf : wi)[i];+      return;+    }+  memcpy (vd, vi, size);+}++/* Perform machine dependent cif processing */++static ffi_status+ffi_prep_cif_machdep_core(ffi_cif *cif)+{+  ffi_type *rtype = cif->rtype;+  int rtt = rtype->type;+  size_t bytes = 0;+  int i, n, flags;++  /* Set the return type flag */+  switch (rtt)+    {+    case FFI_TYPE_VOID:+      flags = SPARC_RET_VOID;+      break;+    case FFI_TYPE_FLOAT:+      flags = SPARC_RET_F_1;+      break;+    case FFI_TYPE_DOUBLE:+      flags = SPARC_RET_F_2;+      break;+    case FFI_TYPE_LONGDOUBLE:+      flags = SPARC_RET_F_4;+      break;++    case FFI_TYPE_COMPLEX:+    case FFI_TYPE_STRUCT:+      if (rtype->size > 32)+	{+	  flags = SPARC_RET_VOID | SPARC_FLAG_RET_IN_MEM;+	  bytes = 8;+	}+      else+	{+	  int size_mask = ffi_struct_float_mask (rtype, 0);+	  int word_size = (size_mask >> 2) & 0x3f;+	  int all_mask = (1 << word_size) - 1;+	  int fp_mask = size_mask >> 8;++	  flags = (size_mask << SPARC_SIZEMASK_SHIFT) | SPARC_RET_STRUCT;++	  /* For special cases of all-int or all-fp, we can return+	     the value directly without popping through a struct copy.  */+	  if (fp_mask == 0)+	    {+	      if (rtype->alignment >= 8)+		{+		  if (rtype->size == 8)+		    flags = SPARC_RET_INT64;+		  else if (rtype->size == 16)+		    flags = SPARC_RET_INT128;+		}+	    }+	  else if (fp_mask == all_mask)+	    switch (word_size)+	      {+	      case 1: flags = SPARC_RET_F_1; break;+	      case 2: flags = SPARC_RET_F_2; break;+	      case 3: flags = SP_V9_RET_F_3; break;+	      case 4: flags = SPARC_RET_F_4; break;+	      /* 5 word structures skipped; handled via RET_STRUCT.  */+	      case 6: flags = SPARC_RET_F_6; break;+	      /* 7 word structures skipped; handled via RET_STRUCT.  */+	      case 8: flags = SPARC_RET_F_8; break;+	      }+	}+      break;++    case FFI_TYPE_SINT8:+      flags = SPARC_RET_SINT8;+      break;+    case FFI_TYPE_UINT8:+      flags = SPARC_RET_UINT8;+      break;+    case FFI_TYPE_SINT16:+      flags = SPARC_RET_SINT16;+      break;+    case FFI_TYPE_UINT16:+      flags = SPARC_RET_UINT16;+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+      flags = SP_V9_RET_SINT32;+      break;+    case FFI_TYPE_UINT32:+      flags = SPARC_RET_UINT32;+      break;+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_POINTER:+      flags = SPARC_RET_INT64;+      break;++    default:+      abort();+    }++  bytes = 0;+  for (i = 0, n = cif->nargs; i < n; ++i)+    {+      ffi_type *ty = cif->arg_types[i];+      size_t z = ty->size;+      size_t a = ty->alignment;++      switch (ty->type)+	{+	case FFI_TYPE_COMPLEX:+	case FFI_TYPE_STRUCT:+	  /* Large structs passed by reference.  */+	  if (z > 16)+	    {+	      a = z = 8;+	      break;+	    }+	  /* Small structs may be passed in integer or fp regs or both.  */+	  if (bytes >= 16*8)+	    break;+	  if ((ffi_struct_float_mask (ty, 0) & 0xff00) == 0)+	    break;+	  /* FALLTHRU */+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	  flags |= SPARC_FLAG_FP_ARGS;+	  break;+	}+      bytes = FFI_ALIGN(bytes, a);+      bytes += FFI_ALIGN(z, 8);+    }++  /* Sparc call frames require that space is allocated for 6 args,+     even if they aren't used. Make that space if necessary. */+  if (bytes < 6 * 8)+    bytes = 6 * 8;++  /* The stack must be 2 word aligned, so round bytes up appropriately. */+  bytes = FFI_ALIGN(bytes, 16);++  /* Include the call frame to prep_args.  */+  bytes += 8*16 + 8*8;++  cif->bytes = bytes;+  cif->flags = flags;+  return FFI_OK;+}++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep(ffi_cif *cif)+{+  cif->nfixedargs = cif->nargs;+  return ffi_prep_cif_machdep_core(cif);+}++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs)+{+  cif->nfixedargs = nfixedargs;+  return ffi_prep_cif_machdep_core(cif);+}++extern void ffi_call_v9(ffi_cif *cif, void (*fn)(void), void *rvalue,+			void **avalue, size_t bytes, void *closure) FFI_HIDDEN;++/* ffi_prep_args is called by the assembly routine once stack space+   has been allocated for the function's arguments */++int FFI_HIDDEN+ffi_prep_args_v9(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)+{+  ffi_type **p_arg;+  int flags = cif->flags;+  int i, nargs;++  if (rvalue == NULL)+    {+      if (flags & SPARC_FLAG_RET_IN_MEM)+	{+	  /* Since we pass the pointer to the callee, we need a value.+	     We allowed for this space in ffi_call, before ffi_call_v8+	     alloca'd the space.  */+	  rvalue = (char *)argp + cif->bytes;+	}+      else+	{+	  /* Otherwise, we can ignore the return value.  */+	  flags = SPARC_RET_VOID;+	}+    }++#ifdef USING_PURIFY+  /* Purify will probably complain in our assembly routine,+     unless we zero out this memory. */+  memset(argp, 0, 6*8);+#endif++  if (flags & SPARC_FLAG_RET_IN_MEM)+    *argp++ = (unsigned long)rvalue;++  p_arg = cif->arg_types;+  for (i = 0, nargs = cif->nargs; i < nargs; i++)+    {+      ffi_type *ty = p_arg[i];+      void *a = avalue[i];+      size_t z;++      switch (ty->type)+	{+	case FFI_TYPE_SINT8:+	  *argp++ = *(SINT8 *)a;+	  break;+	case FFI_TYPE_UINT8:+	  *argp++ = *(UINT8 *)a;+	  break;+	case FFI_TYPE_SINT16:+	  *argp++ = *(SINT16 *)a;+	  break;+	case FFI_TYPE_UINT16:+	  *argp++ = *(UINT16 *)a;+	  break;+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT32:+	  *argp++ = *(SINT32 *)a;+	  break;+	case FFI_TYPE_UINT32:+	  *argp++ = *(UINT32 *)a;+	  break;+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_POINTER:+	  *argp++ = *(UINT64 *)a;+	  break;+	case FFI_TYPE_FLOAT:+	  flags |= SPARC_FLAG_FP_ARGS;+	  *argp++ = *(UINT32 *)a;+	  break;+	case FFI_TYPE_DOUBLE:+	  flags |= SPARC_FLAG_FP_ARGS;+	  *argp++ = *(UINT64 *)a;+	  break;++	case FFI_TYPE_LONGDOUBLE:+	case FFI_TYPE_COMPLEX:+	case FFI_TYPE_STRUCT:+	  z = ty->size;+	  if (z > 16)+	    {+	      /* For structures larger than 16 bytes we pass reference.  */+	      *argp++ = (unsigned long)a;+	      break;+	    }+	  if (((unsigned long)argp & 15) && ty->alignment > 8)+	    argp++;+	  memcpy(argp, a, z);+	  argp += FFI_ALIGN(z, 8) / 8;+	  break;++	default:+	  abort();+	}+    }++  return flags;+}++static void+ffi_call_int(ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  size_t bytes = cif->bytes;+  size_t i, nargs = cif->nargs;+  ffi_type **arg_types = cif->arg_types;++  FFI_ASSERT (cif->abi == FFI_V9);++  if (rvalue == NULL && (cif->flags & SPARC_FLAG_RET_IN_MEM))+    bytes += FFI_ALIGN (cif->rtype->size, 16);++  /* If we have any large structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT && size > 4)+        {+          char *argcopy = alloca (size);+          memcpy (argcopy, avalue[i], size);+          avalue[i] = argcopy;+        }+    }  +  +  ffi_call_v9(cif, fn, rvalue, avalue, -bytes, closure);+}++void+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int(cif, fn, rvalue, avalue, NULL);+}++void+ffi_call_go(ffi_cif *cif, void (*fn)(void), void *rvalue,+	    void **avalue, void *closure)+{+  ffi_call_int(cif, fn, rvalue, avalue, closure);+}++#ifdef __GNUC__+static inline void+ffi_flush_icache (void *p)+{+  asm volatile ("flush	%0; flush %0+8" : : "r" (p) : "memory");+}+#else+extern void ffi_flush_icache (void *) FFI_HIDDEN;+#endif++extern void ffi_closure_v9(void) FFI_HIDDEN;+extern void ffi_go_closure_v9(void) FFI_HIDDEN;++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;++  if (cif->abi != FFI_V9)+    return FFI_BAD_ABI;++  /* Trampoline address is equal to the closure address.  We take advantage+     of that to reduce the trampoline size by 8 bytes. */+  fn = (unsigned long) ffi_closure_v9;+  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/+  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/+  tramp[2] = 0x81c14000;	/* jmp	%g5		*/+  tramp[3] = 0x01000000;	/* nop			*/+  *((unsigned long *) &tramp[4]) = fn;++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  ffi_flush_icache (closure);++  return FFI_OK;+}++ffi_status+ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,+		     void (*fun)(ffi_cif*, void*, void**, void*))+{+  if (cif->abi != FFI_V9)+    return FFI_BAD_ABI;++  closure->tramp = ffi_go_closure_v9;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++int FFI_HIDDEN+ffi_closure_sparc_inner_v9(ffi_cif *cif,+			   void (*fun)(ffi_cif*, void*, void**, void*),+			   void *user_data, void *rvalue,+			   unsigned long *gpr, unsigned long *fpr)+{+  ffi_type **arg_types;+  void **avalue;+  int i, argn, argx, nargs, flags, nfixedargs;++  arg_types = cif->arg_types;+  nargs = cif->nargs;+  flags = cif->flags;+  nfixedargs = cif->nfixedargs;++  avalue = alloca(nargs * sizeof(void *));++  /* Copy the caller's structure return address so that the closure+     returns the data directly to the caller.  */+  if (flags & SPARC_FLAG_RET_IN_MEM)+    {+      rvalue = (void *) gpr[0];+      /* Skip the structure return address.  */+      argn = 1;+    }+  else+    argn = 0;++  /* Grab the addresses of the arguments from the stack frame.  */+  for (i = 0; i < nargs; i++, argn = argx)+    {+      int named = i < nfixedargs;+      ffi_type *ty = arg_types[i];+      void *a = &gpr[argn];+      size_t z;++      argx = argn + 1;+      switch (ty->type)+	{+	case FFI_TYPE_COMPLEX:+	case FFI_TYPE_STRUCT:+	  z = ty->size;+	  if (z > 16)+	    a = *(void **)a;+	  else+	    {+	      argx = argn + FFI_ALIGN (z, 8) / 8;+	      if (named && argn < 16)+		{+		  int size_mask = ffi_struct_float_mask (ty, 0);+		  int argn_mask = (0xffff00 >> argn) & 0xff00;++		  /* Eliminate fp registers off the end.  */+		  size_mask = (size_mask & 0xff) | (size_mask & argn_mask);+		  a = ffi_struct_float_merge (size_mask, gpr+argn, fpr+argn);+		}+	    }+	  break;++	case FFI_TYPE_LONGDOUBLE:+	  argn = FFI_ALIGN (argn, 2);+	  a = (named && argn < 16 ? fpr : gpr) + argn;+	  argx = argn + 2;+	  break;+	case FFI_TYPE_DOUBLE:+	  if (named && argn < 16)+	    a = fpr + argn;+	  break;+	case FFI_TYPE_FLOAT:+	  if (named && argn < 16)+	    a = fpr + argn;+	  a += 4;+	  break;++	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_POINTER:+	  break;+	case FFI_TYPE_INT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	  a += 4;+	  break;+        case FFI_TYPE_UINT16:+        case FFI_TYPE_SINT16:+	  a += 6;+	  break;+        case FFI_TYPE_UINT8:+        case FFI_TYPE_SINT8:+	  a += 7;+	  break;++	default:+	  abort();+	}+      avalue[i] = a;+    }++  /* Invoke the closure.  */+  fun (cif, rvalue, avalue, user_data);++  /* Tell ffi_closure_sparc how to perform return type promotions.  */+  return flags;+}+#endif /* SPARC64 */
+ src/sparc/ffitarget.h view
@@ -0,0 +1,81 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012  Anthony Green+                 Copyright (c) 1996-2003  Red Hat, Inc.+   Target configuration macros for SPARC.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++#if defined(__arch64__) || defined(__sparcv9)+#ifndef SPARC64+#define SPARC64+#endif+#endif++#ifndef LIBFFI_ASM+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+#ifdef SPARC64+  FFI_V9,+  FFI_DEFAULT_ABI = FFI_V9,+#else+  FFI_V8,+  FFI_DEFAULT_ABI = FFI_V8,+#endif+  FFI_LAST_ABI+} ffi_abi;+#endif++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 1+#define FFI_TARGET_HAS_COMPLEX_TYPE 1++#ifdef SPARC64+# define FFI_TARGET_SPECIFIC_VARIADIC 1+# define FFI_EXTRA_CIF_FIELDS  unsigned int nfixedargs+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1+#define FFI_NATIVE_RAW_API 0++#ifdef SPARC64+#define FFI_TRAMPOLINE_SIZE 24+#else+#define FFI_TRAMPOLINE_SIZE 16+#endif++#endif+
+ src/sparc/internal.h view
@@ -0,0 +1,26 @@+#define SPARC_RET_VOID		0+#define SPARC_RET_STRUCT	1+#define SPARC_RET_UINT8		2+#define SPARC_RET_SINT8		3+#define SPARC_RET_UINT16	4+#define SPARC_RET_SINT16	5+#define SPARC_RET_UINT32	6+#define SP_V9_RET_SINT32	7	/* v9 only */+#define SP_V8_RET_CPLX16	7	/* v8 only */+#define SPARC_RET_INT64		8+#define SPARC_RET_INT128	9++/* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT.  */+#define SPARC_RET_F_8		10+#define SPARC_RET_F_6		11+#define SPARC_RET_F_4		12+#define SPARC_RET_F_2		13+#define SP_V9_RET_F_3		14	/* v9 only */+#define SP_V8_RET_CPLX8		14	/* v8 only */+#define SPARC_RET_F_1		15++#define SPARC_FLAG_RET_MASK	15+#define SPARC_FLAG_RET_IN_MEM	32+#define SPARC_FLAG_FP_ARGS	64++#define SPARC_SIZEMASK_SHIFT	8
+ src/sparc/v8.S view
@@ -0,0 +1,443 @@+/* -----------------------------------------------------------------------+   v8.S - Copyright (c) 2013  The Written Word, Inc.+	  Copyright (c) 1996, 1997, 2003, 2004, 2008  Red Hat, Inc.++   SPARC Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include "internal.h"++#ifndef SPARC64++#define C2(X, Y)  X ## Y+#define C1(X, Y)  C2(X, Y)++#ifdef __USER_LABEL_PREFIX__+# define C(Y)	C1(__USER_LABEL_PREFIX__, Y)+#else+# define C(Y)	Y+#endif+#define L(Y)	C1(.L, Y)++	.text++#ifndef __GNUC__+        .align 8+	.globl	C(ffi_flush_icache)+	.type	C(ffi_flush_icache),#function+	FFI_HIDDEN(C(ffi_flush_icache))++C(ffi_flush_icache):+1:	iflush %o0+	iflush %o+8+	nop+	nop+	nop+	nop+	nop+	retl+	 nop+	.size	C(ffi_flush_icache), . - C(ffi_flush_icache)+#endif++#if defined(__sun__) && defined(__svr4__)+# define E(INDEX)	.align 16+#else+# define E(INDEX)	.align 16; .org 2b + INDEX * 16+#endif++        .align 8+	.globl	C(ffi_call_v8)+	.type	C(ffi_call_v8),#function+	FFI_HIDDEN(C(ffi_call_v8))++C(ffi_call_v8):+.LUW0:+	! Allocate a stack frame sized by ffi_call.+	save	%sp, %o4, %sp+.LUW1:+	mov	%i0, %o0		! copy cif+	add	%sp, 64+32, %o1		! load args area+	mov	%i2, %o2		! copy rvalue+	call	C(ffi_prep_args_v8)+	 mov	%i3, %o3		! copy avalue++	add	%sp, 32, %sp		! deallocate prep frame+	and	%o0, SPARC_FLAG_RET_MASK, %l0	! save return type+	srl	%o0, SPARC_SIZEMASK_SHIFT, %l1	! save return size+	ld	[%sp+64+4], %o0		! load all argument registers+	ld	[%sp+64+8], %o1+	ld	[%sp+64+12], %o2+	ld	[%sp+64+16], %o3+	cmp	%l0, SPARC_RET_STRUCT	! struct return needs an unimp 4+	ld	[%sp+64+20], %o4+	be	8f+	 ld	[%sp+64+24], %o5++	! Call foreign function+	call	%i1+	 mov	%i5, %g2		! load static chain++0:	call	1f		! load pc in %o7+	 sll	%l0, 4, %l0+1:	add	%o7, %l0, %o7	! o7 = 0b + ret_type*16+	jmp	%o7+(2f-0b)+	 nop++	! Note that each entry is 4 insns, enforced by the E macro.+	.align	16+2:+E(SPARC_RET_VOID)+	ret+	 restore+E(SPARC_RET_STRUCT)+	unimp+E(SPARC_RET_UINT8)+	and	%o0, 0xff, %o0+	st	%o0, [%i2]+	ret+	 restore+E(SPARC_RET_SINT8)+	sll	%o0, 24, %o0+	b	7f+	 sra	%o0, 24, %o0+E(SPARC_RET_UINT16)+	sll	%o0, 16, %o0+	b	7f+	 srl	%o0, 16, %o0+E(SPARC_RET_SINT16)+	sll	%o0, 16, %o0+	b	7f+	 sra	%o0, 16, %o0+E(SPARC_RET_UINT32)+7:	st	%o0, [%i2]+	ret+	 restore+E(SP_V8_RET_CPLX16)+	sth	%o0, [%i2+2]+	b	9f+	 srl	%o0, 16, %o0+E(SPARC_RET_INT64)+	st	%o0, [%i2]+	st	%o1, [%i2+4]+	ret+	 restore+E(SPARC_RET_INT128)+	std	%o0, [%i2]+	std	%o2, [%i2+8]+	ret+	 restore+E(SPARC_RET_F_8)+	st	%f7, [%i2+7*4]+	nop+	st	%f6, [%i2+6*4]+	nop+E(SPARC_RET_F_6)+	st	%f5, [%i2+5*4]+	nop+	st	%f4, [%i2+4*4]+	nop+E(SPARC_RET_F_4)+	st	%f3, [%i2+3*4]+	nop+	st	%f2, [%i2+2*4]+	nop+E(SPARC_RET_F_2)+	st	%f1, [%i2+4]+	st	%f0, [%i2]+	ret+	 restore+E(SP_V8_RET_CPLX8)+	stb	%o0, [%i2+1]+	b	0f+	 srl	%o0, 8, %o0+E(SPARC_RET_F_1)+	st	%f0, [%i2]+	ret+	 restore++	.align	8+9:	sth	%o0, [%i2]+	ret+	 restore+	.align	8+0:	stb	%o0, [%i2]+	ret+	 restore++	! Struct returning functions expect and skip the unimp here.+	! To make it worse, conforming callees examine the unimp and+	! make sure the low 12 bits of the unimp match the size of+	! the struct being returned.+	.align	8+8:	call	1f				! load pc in %o7+	 sll	%l1, 2, %l0			! size * 4+1:	sll	%l1, 4, %l1			! size * 16+	add	%l0, %l1, %l0			! size * 20+	add	%o7, %l0, %o7			! o7 = 8b + size*20+	jmp	%o7+(2f-8b)+	 mov	%i5, %g2			! load static chain+2:++/* The Sun assembler doesn't understand .rept 0x1000.  */+#define rept1			\+	call	%i1;		\+	 nop;			\+	unimp	(. - 2b) / 20;	\+	ret;			\+	 restore++#define rept16				\+	rept1; rept1; rept1; rept1;	\+	rept1; rept1; rept1; rept1;	\+	rept1; rept1; rept1; rept1;	\+	rept1; rept1; rept1; rept1++#define rept256				\+	rept16; rept16; rept16; rept16;	\+	rept16; rept16; rept16; rept16;	\+	rept16; rept16; rept16; rept16;	\+	rept16; rept16; rept16; rept16++	rept256; rept256; rept256; rept256+	rept256; rept256; rept256; rept256+	rept256; rept256; rept256; rept256+	rept256; rept256; rept256; rept256++.LUW2:+	.size	C(ffi_call_v8),. - C(ffi_call_v8)+++/* 16*4 register window + 1*4 struct return + 6*4 args backing store+   + 8*4 return storage + 1*4 alignment.  */+#define	STACKFRAME	(16*4 + 4 + 6*4 + 8*4 + 4)++/* ffi_closure_v8(...)++   Receives the closure argument in %g2.   */++#ifdef HAVE_AS_REGISTER_PSEUDO_OP+	.register	%g2, #scratch+#endif++	.align 8+	.globl	C(ffi_go_closure_v8)+	.type	C(ffi_go_closure_v8),#function+	FFI_HIDDEN(C(ffi_go_closure_v8))++C(ffi_go_closure_v8):+.LUW3:+	save	%sp, -STACKFRAME, %sp+.LUW4:+	ld	[%g2+4], %o0			! load cif+	ld	[%g2+8], %o1			! load fun+	b	0f+	 mov	%g2, %o2			! load user_data+.LUW5:+	.size	C(ffi_go_closure_v8), . - C(ffi_go_closure_v8)++	.align 8+	.globl	C(ffi_closure_v8)+	.type	C(ffi_closure_v8),#function+	FFI_HIDDEN(C(ffi_closure_v8))++C(ffi_closure_v8):+.LUW6:+	save	%sp, -STACKFRAME, %sp+.LUW7:+	ld	[%g2+FFI_TRAMPOLINE_SIZE], %o0		! load cif+	ld	[%g2+FFI_TRAMPOLINE_SIZE+4], %o1	! load fun+	ld	[%g2+FFI_TRAMPOLINE_SIZE+8], %o2	! load user_data+0:+	! Store all of the potential argument registers in va_list format.+	st	%i0, [%fp+68+0]+	st	%i1, [%fp+68+4]+	st	%i2, [%fp+68+8]+	st	%i3, [%fp+68+12]+	st	%i4, [%fp+68+16]+	st	%i5, [%fp+68+20]++	! Call ffi_closure_sparc_inner to do the bulk of the work.+	add	%fp, -8*4, %o3+	call	ffi_closure_sparc_inner_v8+	 add	%fp,  64, %o4++0:	call	1f+	 and	%o0, SPARC_FLAG_RET_MASK, %o0+1:	sll	%o0, 4, %o0	! o0 = o0 * 16+	add	%o7, %o0, %o7	! o7 = 0b + o0*16+	jmp	%o7+(2f-0b)+	 add	%fp, -8*4, %i2+	 +	! Note that each entry is 4 insns, enforced by the E macro.+	.align	16+2:+E(SPARC_RET_VOID)+	ret+	 restore+E(SPARC_RET_STRUCT)+	ld	[%i2], %i0+	jmp	%i7+12+	 restore+E(SPARC_RET_UINT8)+	ldub	[%i2+3], %i0+	ret+	 restore+E(SPARC_RET_SINT8)+	ldsb	[%i2+3], %i0+	ret+	 restore+E(SPARC_RET_UINT16)+	lduh	[%i2+2], %i0+	ret+	 restore+E(SPARC_RET_SINT16)+	ldsh	[%i2+2], %i0+	ret+	 restore+E(SPARC_RET_UINT32)+	ld	[%i2], %i0+	ret+	 restore+E(SP_V8_RET_CPLX16)+	ld	[%i2], %i0+	ret+	 restore+E(SPARC_RET_INT64)+	ldd	[%i2], %i0+	ret+	 restore+E(SPARC_RET_INT128)+	ldd	[%i2], %i0+	ldd	[%i2+8], %i2+	ret+	 restore+E(SPARC_RET_F_8)+	ld	[%i2+7*4], %f7+	nop+	ld	[%i2+6*4], %f6+	nop+E(SPARC_RET_F_6)+	ld	[%i2+5*4], %f5+	nop+	ld	[%i2+4*4], %f4+	nop+E(SPARC_RET_F_4)+	ld	[%i2+3*4], %f3+	nop+	ld	[%i2+2*4], %f2+	nop+E(SPARC_RET_F_2)+	ldd	[%i2], %f0+	ret+	 restore+E(SP_V8_RET_CPLX8)+	lduh	[%i2], %i0+	ret+	 restore+E(SPARC_RET_F_1)+	ld	[%i2], %f0+	ret+	 restore++.LUW8:+	.size	C(ffi_closure_v8), . - C(ffi_closure_v8)++#ifdef HAVE_RO_EH_FRAME+        .section        ".eh_frame",#alloc+#else+        .section        ".eh_frame",#alloc,#write+#endif++#ifdef HAVE_AS_SPARC_UA_PCREL+# define FDE_ADDR(X)	%r_disp32(X)+#else+# define FDE_ADDR(X)	X+#endif++	.align 4+.LCIE:+	.long	.LECIE - .LSCIE		! CIE Length+.LSCIE:+	.long	0			! CIE Identifier Tag+	.byte	1			! CIE Version+	.ascii	"zR\0"			! CIE Augmentation+	.byte	4			! CIE Code Alignment Factor+	.byte	0x7c			! CIE Data Alignment Factor+	.byte	15			! CIE RA Column+	.byte	1			! Augmentation size+#ifdef HAVE_AS_SPARC_UA_PCREL+	.byte	0x1b			! FDE Encoding (pcrel sdata4)+#else+	.byte	0x50			! FDE Encoding (aligned absolute)+#endif+	.byte	0xc, 14, 0		! DW_CFA_def_cfa, %o6, offset 0+	.align	4+.LECIE:++	.long	.LEFDE1 - .LSFDE1	! FDE Length+.LSFDE1:+	.long	.LSFDE1 - .LCIE		! FDE CIE offset+	.long	FDE_ADDR(.LUW0)		! Initial location+	.long	.LUW2 - .LUW0		! Address range+	.byte	0			! Augmentation size+	.byte	0x40+1			! DW_CFA_advance_loc 4+	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6+	.byte	0x2d			! DW_CFA_GNU_window_save+	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7+	.align	4+.LEFDE1:++	.long	.LEFDE2 - .LSFDE2	! FDE Length+.LSFDE2:+	.long	.LSFDE2 - .LCIE		! FDE CIE offset+	.long	FDE_ADDR(.LUW3)		! Initial location+	.long	.LUW5 - .LUW3		! Address range+	.byte	0			! Augmentation size+	.byte	0x40+1			! DW_CFA_advance_loc 4+	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6+	.byte	0x2d			! DW_CFA_GNU_window_save+	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7+	.align	4+.LEFDE2:++	.long	.LEFDE3 - .LSFDE3	! FDE Length+.LSFDE3:+	.long	.LSFDE3 - .LCIE		! FDE CIE offset+	.long	FDE_ADDR(.LUW6)		! Initial location+	.long	.LUW8 - .LUW6		! Address range+	.byte	0			! Augmentation size+	.byte	0x40+1			! DW_CFA_advance_loc 4+	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6+	.byte	0x2d			! DW_CFA_GNU_window_save+	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7+	.align	4+.LEFDE3:++#endif /* !SPARC64 */+#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/sparc/v9.S view
@@ -0,0 +1,440 @@+/* -----------------------------------------------------------------------+   v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.+   +   SPARC 64-bit Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>+#include "internal.h"++#ifdef SPARC64++#define C2(X, Y)  X ## Y+#define C1(X, Y)  C2(X, Y)++#ifdef __USER_LABEL_PREFIX__+# define C(Y)	C1(__USER_LABEL_PREFIX__, Y)+#else+# define C(Y)	Y+#endif+#define L(Y)	C1(.L, Y)++#if defined(__sun__) && defined(__svr4__)+# define E(INDEX)	.align 16+#else+# define E(INDEX)	.align 16; .org 2b + INDEX * 16+#endif++#define STACK_BIAS 2047++	.text+        .align 8+	.globl	C(ffi_call_v9)+	.type	C(ffi_call_v9),#function+	FFI_HIDDEN(C(ffi_call_v9))++C(ffi_call_v9):+.LUW0:+	save	%sp, %o4, %sp+.LUW1:+	mov	%i0, %o0			! copy cif+	add	%sp, STACK_BIAS+128+48, %o1	! load args area+	mov	%i2, %o2			! copy rvalue+	call	C(ffi_prep_args_v9)+	 mov	%i3, %o3			! copy avalue++	andcc	%o0, SPARC_FLAG_FP_ARGS, %g0	! need fp regs?+	add	%sp, 48, %sp			! deallocate prep frame+	be,pt	%xcc, 1f+	 mov	%o0, %l0			! save flags++	ldd	[%sp+STACK_BIAS+128], %f0	! load all fp arg regs+	ldd	[%sp+STACK_BIAS+128+8], %f2+	ldd	[%sp+STACK_BIAS+128+16], %f4+	ldd	[%sp+STACK_BIAS+128+24], %f6+	ldd	[%sp+STACK_BIAS+128+32], %f8+	ldd	[%sp+STACK_BIAS+128+40], %f10+	ldd	[%sp+STACK_BIAS+128+48], %f12+	ldd	[%sp+STACK_BIAS+128+56], %f14+	ldd	[%sp+STACK_BIAS+128+64], %f16+	ldd	[%sp+STACK_BIAS+128+72], %f18+	ldd	[%sp+STACK_BIAS+128+80], %f20+	ldd	[%sp+STACK_BIAS+128+88], %f22+	ldd	[%sp+STACK_BIAS+128+96], %f24+	ldd	[%sp+STACK_BIAS+128+104], %f26+	ldd	[%sp+STACK_BIAS+128+112], %f28+	ldd	[%sp+STACK_BIAS+128+120], %f30++1:	ldx	[%sp+STACK_BIAS+128], %o0	! load all int arg regs+	ldx	[%sp+STACK_BIAS+128+8], %o1+	ldx	[%sp+STACK_BIAS+128+16], %o2+	ldx	[%sp+STACK_BIAS+128+24], %o3+	ldx	[%sp+STACK_BIAS+128+32], %o4+	ldx	[%sp+STACK_BIAS+128+40], %o5+	call	%i1+	 mov	%i5, %g5			! load static chain++0:	call	1f		! load pc in %o7+	 and	%l0, SPARC_FLAG_RET_MASK, %l1+1:	sll	%l1, 4, %l1+	add	%o7, %l1, %o7	! o7 = 0b + ret_type*16+	jmp	%o7+(2f-0b)+	 nop++	.align	16+2:+E(SPARC_RET_VOID)+	return	%i7+8+	 nop+E(SPARC_RET_STRUCT)+	add	%sp, STACK_BIAS-64+128+48, %l2+	sub	%sp, 64, %sp+	b	8f+	 stx	%o0, [%l2]+E(SPARC_RET_UINT8)+	and	%o0, 0xff, %i0+	return	%i7+8+	  stx	%o0, [%o2]+E(SPARC_RET_SINT8)+	sll	%o0, 24, %o0+	sra	%o0, 24, %i0+	return	%i7+8+	 stx	%o0, [%o2]+E(SPARC_RET_UINT16)+	sll	%o0, 16, %o0+	srl	%o0, 16, %i0+	return	%i7+8+	 stx	%o0, [%o2]+E(SPARC_RET_SINT16)+	sll	%o0, 16, %o0+	sra	%o0, 16, %i0+	return	%i7+8+	 stx	%o0, [%o2]+E(SPARC_RET_UINT32)+	srl	%o0, 0, %i0+	return	%i7+8+	 stx	%o0, [%o2]+E(SP_V9_RET_SINT32)+	sra	%o0, 0, %i0+	return	%i7+8+	 stx	%o0, [%o2]+E(SPARC_RET_INT64)+	stx	%o0, [%i2]+	return	%i7+8+	 nop+E(SPARC_RET_INT128)+	stx	%o0, [%i2]+	stx	%o1, [%i2+8]+	return	%i7+8+	 nop+E(SPARC_RET_F_8)+	st	%f7, [%i2+7*4]+	nop+	st	%f6, [%i2+6*4]+	nop+E(SPARC_RET_F_6)+	st	%f5, [%i2+5*4]+	nop+	st	%f4, [%i2+4*4]+	nop+E(SPARC_RET_F_4)+	std	%f2, [%i2+2*4]+	return	%i7+8+	 std	%f0, [%o2]+E(SPARC_RET_F_2)+	return	%i7+8+	 std	%f0, [%o2]+E(SP_V9_RET_F_3)+	st	%f2, [%i2+2*4]+	nop+	st	%f1, [%i2+1*4]+	nop+E(SPARC_RET_F_1)+	return	%i7+8+	 st	%f0, [%o2]++	! Finish the SPARC_RET_STRUCT sequence.+	.align	8+8:	stx	%o1, [%l2+8]+	stx	%o2, [%l2+16]+	stx	%o3, [%l2+24]+	std	%f0, [%l2+32]+	std	%f2, [%l2+40]+	std	%f4, [%l2+48]+	std	%f6, [%l2+56]++	! Copy the structure into place.+	srl	%l0, SPARC_SIZEMASK_SHIFT, %o0	! load size_mask+	mov	%i2, %o1			! load dst+	mov	%l2, %o2			! load src_gp+	call	C(ffi_struct_float_copy)+	 add	%l2, 32, %o3			! load src_fp++	return	%i7+8+	 nop++.LUW2:+	.size	C(ffi_call_v9), . - C(ffi_call_v9)+++#undef STACKFRAME+#define	STACKFRAME	 336	/* 16*8 register window ++				   6*8 args backing store ++				   20*8 locals */+#define	FP		%fp+STACK_BIAS++/* ffi_closure_v9(...)++   Receives the closure argument in %g1.   */++	.align 8+	.globl	C(ffi_go_closure_v9)+	.type	C(ffi_go_closure_v9),#function+	FFI_HIDDEN(C(ffi_go_closure_v9))++C(ffi_go_closure_v9):+.LUW3:+	save	%sp, -STACKFRAME, %sp+.LUW4:+	ldx	[%g5+8], %o0+	ldx	[%g5+16], %o1+	b	0f+	 mov	%g5, %o2++.LUW5:+	.size	C(ffi_go_closure_v9), . - C(ffi_go_closure_v9)++	.align 8+	.globl	C(ffi_closure_v9)+	.type	C(ffi_closure_v9),#function+	FFI_HIDDEN(C(ffi_closure_v9))++C(ffi_closure_v9):+.LUW6:+	save	%sp, -STACKFRAME, %sp+.LUW7:+	ldx	[%g1+FFI_TRAMPOLINE_SIZE], %o0+	ldx	[%g1+FFI_TRAMPOLINE_SIZE+8], %o1+	ldx	[%g1+FFI_TRAMPOLINE_SIZE+16], %o2+0:+	! Store all of the potential argument registers in va_list format.+	stx	%i0, [FP+128+0]+	stx	%i1, [FP+128+8]+	stx	%i2, [FP+128+16]+	stx	%i3, [FP+128+24]+	stx	%i4, [FP+128+32]+	stx	%i5, [FP+128+40]++	! Store possible floating point argument registers too.+	std	%f0,  [FP-128]+	std	%f2,  [FP-120]+	std	%f4,  [FP-112]+	std	%f6,  [FP-104]+	std	%f8,  [FP-96]+	std	%f10, [FP-88]+	std     %f12, [FP-80]+	std     %f14, [FP-72]+	std     %f16, [FP-64]+	std     %f18, [FP-56]+	std     %f20, [FP-48]+	std     %f22, [FP-40]+	std     %f24, [FP-32]+	std     %f26, [FP-24]+	std     %f28, [FP-16]+	std     %f30, [FP-8]++	! Call ffi_closure_sparc_inner to do the bulk of the work.+	add	%fp, STACK_BIAS-160, %o3+	add	%fp, STACK_BIAS+128, %o4+	call	C(ffi_closure_sparc_inner_v9)+	 add	%fp, STACK_BIAS-128, %o5++0:	call	1f		! load pc in %o7+	 and	%o0, SPARC_FLAG_RET_MASK, %o0+1:	sll	%o0, 4, %o0	! o2 = i2 * 16+	add	%o7, %o0, %o7	! o7 = 0b + i2*16+	jmp	%o7+(2f-0b)+	 nop++	! Note that we cannot load the data in the delay slot of+	! the return insn because the data is in the stack frame+	! that is deallocated by the return.+	.align	16+2:+E(SPARC_RET_VOID)+	return	%i7+8+	 nop+E(SPARC_RET_STRUCT)+	ldx	[FP-160], %i0+	ldd	[FP-160], %f0+	b	8f+	 ldx	[FP-152], %i1+E(SPARC_RET_UINT8)+	ldub	[FP-160+7], %i0+	return	%i7+8+	 nop+E(SPARC_RET_SINT8)+	ldsb	[FP-160+7], %i0+	return	%i7+8+	 nop+E(SPARC_RET_UINT16)+	lduh	[FP-160+6], %i0+	return	%i7+8+	 nop+E(SPARC_RET_SINT16)+	ldsh	[FP-160+6], %i0+	return	%i7+8+	 nop+E(SPARC_RET_UINT32)+	lduw	[FP-160+4], %i0+	return	%i7+8+	 nop+E(SP_V9_RET_SINT32)+	ldsw	[FP-160+4], %i0+	return	%i7+8+	 nop+E(SPARC_RET_INT64)+	ldx	[FP-160], %i0+	return	%i7+8+	 nop+E(SPARC_RET_INT128)+	ldx	[FP-160], %i0+	ldx	[FP-160+8], %i1+	return	%i7+8+	 nop+E(SPARC_RET_F_8)+	ld	[FP-160+7*4], %f7+	nop+	ld	[FP-160+6*4], %f6+	nop+E(SPARC_RET_F_6)+	ld	[FP-160+5*4], %f5+	nop+	ld	[FP-160+4*4], %f4+	nop+E(SPARC_RET_F_4)+	ldd	[FP-160], %f0+	ldd	[FP-160+8], %f2+	return	%i7+8+	 nop+E(SPARC_RET_F_2)+	ldd	[FP-160], %f0+	return	%i7+8+	 nop+E(SP_V9_RET_F_3)+	ld	[FP-160+2*4], %f2+	nop+	ld	[FP-160+1*4], %f1+	nop+E(SPARC_RET_F_1)+	ld	[FP-160], %f0+	return	%i7+8+	 nop++	! Finish the SPARC_RET_STRUCT sequence.+	.align	8+8:	ldd	[FP-152], %f2+	ldx	[FP-144], %i2+	ldd	[FP-144], %f4+	ldx	[FP-136], %i3+	ldd	[FP-136], %f6+	return	%i7+8+	 nop++.LUW8:+	.size	C(ffi_closure_v9), . - C(ffi_closure_v9)++#ifdef HAVE_RO_EH_FRAME+        .section        ".eh_frame",#alloc+#else+        .section        ".eh_frame",#alloc,#write+#endif++#ifdef HAVE_AS_SPARC_UA_PCREL+# define FDE_RANGE(B, E)  .long %r_disp32(B), E - B+#else+# define FDE_RANGE(B, E)  .align 8; .xword B, E - B+#endif++	.align 8+.LCIE:+	.long	.LECIE - .LSCIE		! CIE Length+.LSCIE:+	.long	0			! CIE Identifier Tag+	.byte	1			! CIE Version+	.ascii	"zR\0"			! CIE Augmentation+	.byte	4			! CIE Code Alignment Factor+	.byte	0x78			! CIE Data Alignment Factor+	.byte	15			! CIE RA Column+	.byte	1			! Augmentation size+#ifdef HAVE_AS_SPARC_UA_PCREL+	.byte	0x1b			! FDE Encoding (pcrel sdata4)+#else+	.byte	0x50			! FDE Encoding (aligned absolute)+#endif+	.byte	0xc, 14, 0xff, 0xf	! DW_CFA_def_cfa, %o6, offset 0x7ff+	.align	8+.LECIE:++	.long	.LEFDE1 - .LSFDE1	! FDE Length+.LSFDE1:+	.long	.LSFDE1 - .LCIE		! FDE CIE offset+	FDE_RANGE(.LUW0, .LUW2)+	.byte	0			! Augmentation size+	.byte	0x40+1			! DW_CFA_advance_loc 4+	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6+	.byte	0x2d			! DW_CFA_GNU_window_save+	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7+	.align	8+.LEFDE1:++	.long	.LEFDE2 - .LSFDE2	! FDE Length+.LSFDE2:+	.long	.LSFDE2 - .LCIE		! FDE CIE offset+	FDE_RANGE(.LUW3, .LUW5)+	.byte	0			! Augmentation size+	.byte	0x40+1			! DW_CFA_advance_loc 4+	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6+	.byte	0x2d			! DW_CFA_GNU_window_save+	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7+	.align	8+.LEFDE2:++	.long	.LEFDE3 - .LSFDE3	! FDE Length+.LSFDE3:+	.long	.LSFDE3 - .LCIE		! FDE CIE offset+	FDE_RANGE(.LUW6, .LUW8)+	.byte	0			! Augmentation size+	.byte	0x40+1			! DW_CFA_advance_loc 4+	.byte	0xd, 30			! DW_CFA_def_cfa_register, %i6+	.byte	0x2d			! DW_CFA_GNU_window_save+	.byte	0x9, 15, 31		! DW_CFA_register, %o7, %i7+	.align	8+.LEFDE3:++#endif /* SPARC64 */+#ifdef __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/tile/ffi.c view
@@ -0,0 +1,355 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2012 Tilera Corp.++   TILE Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>+#include <stdint.h>+#include <unistd.h>+#include <arch/abi.h>+#include <arch/icache.h>+#include <arch/opcode.h>+++/* The first 10 registers are used to pass arguments and return values. */+#define NUM_ARG_REGS 10++/* Performs a raw function call with the given NUM_ARG_REGS register arguments+   and the specified additional stack arguments (if any). */+extern void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS],+                          const ffi_sarg *stack_args,+                          size_t stack_args_bytes,+                          void (*fnaddr)(void))+  FFI_HIDDEN;++/* This handles the raw call from the closure stub, cleaning up the+   parameters and delegating to ffi_closure_tile_inner. */+extern void ffi_closure_tile(void) FFI_HIDDEN;+++ffi_status+ffi_prep_cif_machdep(ffi_cif *cif)+{+  /* We always allocate room for all registers. Even if we don't+     use them as parameters, they get returned in the same array+     as struct return values so we need to make room. */+  if (cif->bytes < NUM_ARG_REGS * FFI_SIZEOF_ARG)+    cif->bytes = NUM_ARG_REGS * FFI_SIZEOF_ARG;++  if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG)+    cif->flags = FFI_TYPE_STRUCT;+  else+    cif->flags = FFI_TYPE_INT;++  /* Nothing to do. */+  return FFI_OK;+}+++static long+assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type,+                  int write_to_reg)+{+  switch (type->type)+    {+    case FFI_TYPE_SINT8:+      *out = *(SINT8 *)in;+      return 1;++    case FFI_TYPE_UINT8:+      *out = *(UINT8 *)in;+      return 1;++    case FFI_TYPE_SINT16:+      *out = *(SINT16 *)in;+      return 1;++    case FFI_TYPE_UINT16:+      *out = *(UINT16 *)in;+      return 1;++    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+#ifndef __LP64__+    case FFI_TYPE_POINTER:+#endif+      /* Note that even unsigned 32-bit quantities are sign extended+         on tilegx when stored in a register.  */+      *out = *(SINT32 *)in;+      return 1;++    case FFI_TYPE_FLOAT:+#ifdef __tilegx__+      if (write_to_reg)+        {+          /* Properly sign extend the value.  */+          union { float f; SINT32 s32; } val;+          val.f = *(float *)in;+          *out = val.s32;+        }+      else+#endif+        {+          *(float *)out = *(float *)in;+        }+      return 1;++    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_DOUBLE:+#ifdef __LP64__+    case FFI_TYPE_POINTER:+#endif+      *(UINT64 *)out = *(UINT64 *)in;+      return sizeof(UINT64) / FFI_SIZEOF_ARG;++    case FFI_TYPE_STRUCT:+      memcpy(out, in, type->size);+      return (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;++    case FFI_TYPE_VOID:+      /* Must be a return type. Nothing to do. */+      return 0;++    default:+      FFI_ASSERT(0);+      return -1;+    }+}+++void+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_sarg * const arg_mem = alloca(cif->bytes);+  ffi_sarg * const reg_args = arg_mem;+  ffi_sarg * const stack_args = &reg_args[NUM_ARG_REGS];+  ffi_sarg *argp = arg_mem;+  ffi_type ** const arg_types = cif->arg_types;+  const long num_args = cif->nargs;+  long i;++  if (cif->flags == FFI_TYPE_STRUCT)+    {+      /* Pass a hidden pointer to the return value. We make sure there+         is scratch space for the callee to store the return value even if+         our caller doesn't care about it. */+      *argp++ = (intptr_t)(rvalue ? rvalue : alloca(cif->rtype->size));++      /* No more work needed to return anything. */+      rvalue = NULL;+    }++  for (i = 0; i < num_args; i++)+    {+      ffi_type *type = arg_types[i];+      void * const arg_in = avalue[i];+      ptrdiff_t arg_word = argp - arg_mem;++#ifndef __tilegx__+      /* Doubleword-aligned values are always in an even-number register+         pair, or doubleword-aligned stack slot if out of registers. */+      long align = arg_word & (type->alignment > FFI_SIZEOF_ARG);+      argp += align;+      arg_word += align;+#endif++      if (type->type == FFI_TYPE_STRUCT)+        {+          const size_t arg_size_in_words =+            (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;++          if (arg_word < NUM_ARG_REGS &&+              arg_word + arg_size_in_words > NUM_ARG_REGS)+            {+              /* Args are not allowed to span registers and the stack. */+              argp = stack_args;+            }++          memcpy(argp, arg_in, type->size);+          argp += arg_size_in_words;+        }+      else+        {+          argp += assign_to_ffi_arg(argp, arg_in, arg_types[i], 1);+        }+    }++  /* Actually do the call. */+  ffi_call_tile(reg_args, stack_args,+                cif->bytes - (NUM_ARG_REGS * FFI_SIZEOF_ARG), fn);++  if (rvalue != NULL)+    assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0);+}+++/* Template code for closure. */+extern const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN;+++ffi_status+ffi_prep_closure_loc (ffi_closure *closure,+                      ffi_cif *cif,+                      void (*fun)(ffi_cif*, void*, void**, void*),+                      void *user_data,+                      void *codeloc)+{+#ifdef __tilegx__+  /* TILE-Gx */+  SINT64 c;+  SINT64 h;+  int s;+  UINT64 *out;++  if (cif->abi != FFI_UNIX)+    return FFI_BAD_ABI;++  out = (UINT64 *)closure->tramp;++  c = (intptr_t)closure;+  h = (intptr_t)ffi_closure_tile;+  s = 0;++  /* Find the smallest shift count that doesn't lose information+     (i.e. no need to explicitly insert high bits of the address that+     are just the sign extension of the low bits). */+  while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s))+    s += 16;++#define OPS(a, b, shift) \+  (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift)))++  /* Emit the moveli. */+  *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s);+  for (s -= 16; s >= 0; s -= 16)+    *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s);++#undef OPS++  *out++ = ffi_template_tramp_tile[2];++#else+  /* TILEPro */+  UINT64 *out;+  intptr_t delta;++  if (cif->abi != FFI_UNIX)+    return FFI_BAD_ABI;++  out = (UINT64 *)closure->tramp;+  delta = (intptr_t)ffi_closure_tile - (intptr_t)codeloc;++  *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3);+#endif++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  invalidate_icache(closure->tramp, (char *)out - closure->tramp,+                    getpagesize());++  return FFI_OK;+}+++/* This is called by the assembly wrapper for closures. This does+   all of the work. On entry reg_args[0] holds the values the registers+   had when the closure was invoked. On return reg_args[1] holds the register+   values to be returned to the caller (many of which may be garbage). */+void FFI_HIDDEN+ffi_closure_tile_inner(ffi_closure *closure,+                       ffi_sarg reg_args[2][NUM_ARG_REGS],+                       ffi_sarg *stack_args)+{+  ffi_cif * const cif = closure->cif;+  void ** const avalue = alloca(cif->nargs * sizeof(void *));+  void *rvalue;+  ffi_type ** const arg_types = cif->arg_types;+  ffi_sarg * const reg_args_in = reg_args[0];+  ffi_sarg * const reg_args_out = reg_args[1];+  ffi_sarg * argp;+  long i, arg_word, nargs = cif->nargs;+  /* Use a union to guarantee proper alignment for double. */+  union { ffi_sarg arg[NUM_ARG_REGS]; double d; UINT64 u64; } closure_ret;++  /* Start out reading register arguments. */+  argp = reg_args_in;++  /* Copy the caller's structure return address to that the closure+     returns the data directly to the caller.  */+  if (cif->flags == FFI_TYPE_STRUCT)+    {+      /* Return by reference via hidden pointer. */+      rvalue = (void *)(intptr_t)*argp++;+      arg_word = 1;+    }+  else+    {+      /* Return the value in registers. */+      rvalue = &closure_ret;+      arg_word = 0;+    }++  /* Grab the addresses of the arguments. */+  for (i = 0; i < nargs; i++)+    {+      ffi_type * const type = arg_types[i];+      const size_t arg_size_in_words =+        (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG;++#ifndef __tilegx__+      /* Doubleword-aligned values are always in an even-number register+         pair, or doubleword-aligned stack slot if out of registers. */+      long align = arg_word & (type->alignment > FFI_SIZEOF_ARG);+      argp += align;+      arg_word += align;+#endif++      if (arg_word == NUM_ARG_REGS ||+          (arg_word < NUM_ARG_REGS &&+           arg_word + arg_size_in_words > NUM_ARG_REGS))+        {+          /* Switch to reading arguments from the stack. */+          argp = stack_args;+          arg_word = NUM_ARG_REGS;+        }++      avalue[i] = argp;+      argp += arg_size_in_words;+      arg_word += arg_size_in_words;+    }++  /* Invoke the closure.  */+  closure->fun(cif, rvalue, avalue, closure->user_data);++  if (cif->flags != FFI_TYPE_STRUCT)+    {+      /* Canonicalize for register representation. */+      assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1);+    }+}
+ src/tile/ffitarget.h view
@@ -0,0 +1,65 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012 Tilera Corp.+   Target configuration macros for TILE.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM++#include <arch/abi.h>++typedef uint_reg_t ffi_arg;+typedef int_reg_t  ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_UNIX,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_UNIX+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */+#define FFI_CLOSURES 1++#ifdef __tilegx__+/* We always pass 8-byte values, even in -m32 mode. */+# define FFI_SIZEOF_ARG 8+# ifdef __LP64__+#  define FFI_TRAMPOLINE_SIZE (8 * 5)  /* 5 bundles */+# else+#  define FFI_TRAMPOLINE_SIZE (8 * 3)  /* 3 bundles */+# endif+#else+# define FFI_SIZEOF_ARG 4+# define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */+#endif+#define FFI_NATIVE_RAW_API 0++#endif
+ src/tile/tile.S view
@@ -0,0 +1,360 @@+/* -----------------------------------------------------------------------+   tile.S - Copyright (c) 2011 Tilera Corp.++   Tilera TILEPro and TILE-Gx Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++/* Number of bytes in a register. */+#define REG_SIZE FFI_SIZEOF_ARG++/* Number of bytes in stack linkage area for backtracing.++   A note about the ABI: on entry to a procedure, sp points to a stack+   slot where it must spill the return address if it's not a leaf.+   REG_SIZE bytes beyond that is a slot owned by the caller which+   contains the sp value that the caller had when it was originally+   entered (i.e. the caller's frame pointer). */+#define LINKAGE_SIZE (2 * REG_SIZE)++/* The first 10 registers are used to pass arguments and return values. */+#define NUM_ARG_REGS 10++#ifdef __tilegx__+#define SW st+#define LW ld+#define BGZT bgtzt+#else+#define SW sw+#define LW lw+#define BGZT bgzt+#endif+++/* void ffi_call_tile (int_reg_t reg_args[NUM_ARG_REGS],+                       const int_reg_t *stack_args,+                       unsigned long stack_args_bytes,+                       void (*fnaddr)(void));++        On entry, REG_ARGS contain the outgoing register values,+        and STACK_ARGS contains STACK_ARG_BYTES of additional values+        to be passed on the stack. If STACK_ARG_BYTES is zero, then+        STACK_ARGS is ignored.++        When the invoked function returns, the values of r0-r9 are+        blindly stored back into REG_ARGS for the caller to examine. */++        .section .text.ffi_call_tile, "ax", @progbits+        .align  8+        .globl  ffi_call_tile+        FFI_HIDDEN(ffi_call_tile)+ffi_call_tile:++/* Incoming arguments. */+#define REG_ARGS                r0+#define INCOMING_STACK_ARGS     r1+#define STACK_ARG_BYTES         r2+#define ORIG_FNADDR             r3++/* Temporary values. */+#define FRAME_SIZE              r10+#define TMP                     r11+#define TMP2                    r12+#define OUTGOING_STACK_ARGS     r13+#define REG_ADDR_PTR            r14+#define RETURN_REG_ADDR         r15+#define FNADDR                  r16++        .cfi_startproc+        {+         /* Save return address. */+         SW     sp, lr+         .cfi_offset lr, 0+         /* Prepare to spill incoming r52. */+         addi   TMP, sp, -REG_SIZE+         /* Increase frame size to have room to spill r52 and REG_ARGS.+            The +7 is to round up mod 8. */+         addi   FRAME_SIZE, STACK_ARG_BYTES, \+                REG_SIZE + REG_SIZE + LINKAGE_SIZE + 7+        }+        {+         /* Round stack frame size to a multiple of 8 to satisfy ABI. */+         andi   FRAME_SIZE, FRAME_SIZE, -8+         /* Compute where to spill REG_ARGS value. */+         addi   TMP2, sp, -(REG_SIZE * 2)+        }+        {+         /* Spill incoming r52. */+         SW     TMP, r52+         .cfi_offset r52, -REG_SIZE+         /* Set up our frame pointer. */+         move   r52, sp+         .cfi_def_cfa_register r52+         /* Push stack frame. */+         sub    sp, sp, FRAME_SIZE+        }+        {+         /* Prepare to set up stack linkage. */+         addi   TMP, sp, REG_SIZE+         /* Prepare to memcpy stack args. */+         addi   OUTGOING_STACK_ARGS, sp, LINKAGE_SIZE+         /* Save REG_ARGS which we will need after we call the subroutine. */+         SW     TMP2, REG_ARGS+        }+        {+         /* Set up linkage info to hold incoming stack pointer. */+         SW     TMP, r52+        }+        {+         /* Skip stack args memcpy if we don't have any stack args (common). */+         blezt  STACK_ARG_BYTES, .Ldone_stack_args_memcpy+        }++.Lmemcpy_stack_args:+        {+         /* Load incoming argument from stack_args. */+         LW     TMP, INCOMING_STACK_ARGS+         addi   INCOMING_STACK_ARGS, INCOMING_STACK_ARGS, REG_SIZE+        }+        {+         /* Store stack argument into outgoing stack argument area. */+         SW     OUTGOING_STACK_ARGS, TMP+         addi   OUTGOING_STACK_ARGS, OUTGOING_STACK_ARGS, REG_SIZE+         addi   STACK_ARG_BYTES, STACK_ARG_BYTES, -REG_SIZE+        }+        {+         BGZT   STACK_ARG_BYTES, .Lmemcpy_stack_args+        }+.Ldone_stack_args_memcpy:++        {+         /* Copy aside ORIG_FNADDR so we can overwrite its register. */+         move   FNADDR, ORIG_FNADDR+         /* Prepare to load argument registers. */+         addi   REG_ADDR_PTR, r0, REG_SIZE+         /* Load outgoing r0. */+         LW     r0, r0+        }++        /* Load up argument registers from the REG_ARGS array. */+#define LOAD_REG(REG, PTR) \+        { \+         LW     REG, PTR ; \+         addi   PTR, PTR, REG_SIZE \+        }++        LOAD_REG(r1, REG_ADDR_PTR)+        LOAD_REG(r2, REG_ADDR_PTR)+        LOAD_REG(r3, REG_ADDR_PTR)+        LOAD_REG(r4, REG_ADDR_PTR)+        LOAD_REG(r5, REG_ADDR_PTR)+        LOAD_REG(r6, REG_ADDR_PTR)+        LOAD_REG(r7, REG_ADDR_PTR)+        LOAD_REG(r8, REG_ADDR_PTR)+        LOAD_REG(r9, REG_ADDR_PTR)++        {+         /* Call the subroutine. */+         jalr   FNADDR+        }++        {+         /* Restore original lr. */+         LW     lr, r52+         /* Prepare to recover ARGS, which we spilled earlier. */+         addi   TMP, r52, -(2 * REG_SIZE)+        }+        {+         /* Restore ARGS, so we can fill it in with the return regs r0-r9. */+         LW     RETURN_REG_ADDR, TMP+         /* Prepare to restore original r52. */+         addi   TMP, r52, -REG_SIZE+        }++        {+         /* Pop stack frame. */+         move   sp, r52+         /* Restore original r52. */+         LW     r52, TMP+        }++#define STORE_REG(REG, PTR) \+        { \+         SW     PTR, REG ; \+         addi   PTR, PTR, REG_SIZE \+        }++        /* Return all register values by reference. */+        STORE_REG(r0, RETURN_REG_ADDR)+        STORE_REG(r1, RETURN_REG_ADDR)+        STORE_REG(r2, RETURN_REG_ADDR)+        STORE_REG(r3, RETURN_REG_ADDR)+        STORE_REG(r4, RETURN_REG_ADDR)+        STORE_REG(r5, RETURN_REG_ADDR)+        STORE_REG(r6, RETURN_REG_ADDR)+        STORE_REG(r7, RETURN_REG_ADDR)+        STORE_REG(r8, RETURN_REG_ADDR)+        STORE_REG(r9, RETURN_REG_ADDR)++        {+         jrp    lr+        }++        .cfi_endproc+        .size ffi_call_tile, .-ffi_call_tile++/* ffi_closure_tile(...)++   On entry, lr points to the closure plus 8 bytes, and r10+   contains the actual return address.++   This function simply dumps all register parameters into a stack array+   and passes the closure, the registers array, and the stack arguments+   to C code that does all of the actual closure processing. */++        .section .text.ffi_closure_tile, "ax", @progbits+        .align  8+        .globl  ffi_closure_tile+        FFI_HIDDEN(ffi_closure_tile)++        .cfi_startproc+/* Room to spill all NUM_ARG_REGS incoming registers, plus frame linkage. */+#define CLOSURE_FRAME_SIZE (((NUM_ARG_REGS * REG_SIZE * 2 + LINKAGE_SIZE) + 7) & -8)+ffi_closure_tile:+        {+#ifdef __tilegx__+         st     sp, lr+         .cfi_offset lr, 0+#else+         /* Save return address (in r10 due to closure stub wrapper). */+         SW     sp, r10+         .cfi_return_column r10+         .cfi_offset r10, 0+#endif+         /* Compute address for stack frame linkage. */+         addli   r10, sp, -(CLOSURE_FRAME_SIZE - REG_SIZE)+        }+        {+         /* Save incoming stack pointer in linkage area. */+         SW     r10, sp+         .cfi_offset sp, -(CLOSURE_FRAME_SIZE - REG_SIZE)+         /* Push a new stack frame. */+         addli   sp, sp, -CLOSURE_FRAME_SIZE+         .cfi_adjust_cfa_offset CLOSURE_FRAME_SIZE+        }++        {+         /* Create pointer to where to start spilling registers. */+         addi   r10, sp, LINKAGE_SIZE+        }++        /* Spill all the incoming registers. */+        STORE_REG(r0, r10)+        STORE_REG(r1, r10)+        STORE_REG(r2, r10)+        STORE_REG(r3, r10)+        STORE_REG(r4, r10)+        STORE_REG(r5, r10)+        STORE_REG(r6, r10)+        STORE_REG(r7, r10)+        STORE_REG(r8, r10)+        {+         /* Save r9. */+         SW     r10, r9+#ifdef __tilegx__+         /* Pointer to closure is passed in r11. */+         move  r0, r11+#else+         /* Compute pointer to the closure object. Because the closure+            starts with a "jal ffi_closure_tile", we can just take the+            value of lr (a phony return address pointing into the closure)+            and subtract 8. */+         addi   r0, lr, -8+#endif+         /* Compute a pointer to the register arguments we just spilled. */+         addi   r1, sp, LINKAGE_SIZE+        }+        {+         /* Compute a pointer to the extra stack arguments (if any). */+         addli   r2, sp, CLOSURE_FRAME_SIZE + LINKAGE_SIZE+         /* Call C code to deal with all of the grotty details. */+         jal    ffi_closure_tile_inner+        }+        {+         addli   r10, sp, CLOSURE_FRAME_SIZE+        }+        {+         /* Restore the return address. */+         LW     lr, r10+         /* Compute pointer to registers array. */+         addli   r10, sp, LINKAGE_SIZE + (NUM_ARG_REGS * REG_SIZE)+        }+        /* Return all the register values, which C code may have set. */+        LOAD_REG(r0, r10)+        LOAD_REG(r1, r10)+        LOAD_REG(r2, r10)+        LOAD_REG(r3, r10)+        LOAD_REG(r4, r10)+        LOAD_REG(r5, r10)+        LOAD_REG(r6, r10)+        LOAD_REG(r7, r10)+        LOAD_REG(r8, r10)+        LOAD_REG(r9, r10)+        {+         /* Pop the frame. */+         addli   sp, sp, CLOSURE_FRAME_SIZE+         jrp    lr+        }++        .cfi_endproc+        .size   ffi_closure_tile, . - ffi_closure_tile+++/* What follows are code template instructions that get copied to the+   closure trampoline by ffi_prep_closure_loc.  The zeroed operands+   get replaced by their proper values at runtime. */++        .section .text.ffi_template_tramp_tile, "ax", @progbits+        .align  8+        .globl  ffi_template_tramp_tile+        FFI_HIDDEN(ffi_template_tramp_tile)+ffi_template_tramp_tile:+#ifdef __tilegx__+        {+          moveli r11, 0 /* backpatched to address of containing closure. */+          moveli r10, 0 /* backpatched to ffi_closure_tile. */+        }+        /* Note: the following bundle gets generated multiple times+           depending on the pointer value (esp. useful for -m32 mode). */+        { shl16insli r11, r11, 0 ; shl16insli r10, r10, 0 }+        { info 2+8 /* for backtracer: -> pc in lr, frame size 0 */ ; jr r10 }+#else+        /* 'jal .' yields a PC-relative offset of zero so we can OR in the+           right offset at runtime. */+        { move r10, lr ; jal . /* ffi_closure_tile */ }+#endif++        .size   ffi_template_tramp_tile, . - ffi_template_tramp_tile
+ src/tramp.c view
@@ -0,0 +1,721 @@+/* -----------------------------------------------------------------------+   tramp.c - Copyright (c) 2020 Madhavan T. Venkataraman+             Copyright (c) 2022 Anthony Green++   API and support functions for managing statically defined closure+   trampolines.++   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 <fficonfig.h>++#ifdef FFI_EXEC_STATIC_TRAMP++/* -------------------------- Headers and Definitions ---------------------*/+/*+ * Add support for other OSes later. For now, it is just Linux and Cygwin.+ */++#if defined (__linux__) || defined (__CYGWIN__)+#ifdef __linux__+#define _GNU_SOURCE 1+#endif++#include <ffi.h>+#include <ffi_common.h>++#include <stdio.h>+#include <unistd.h>+#include <stdlib.h>+#include <stdint.h>+#include <fcntl.h>+#include <pthread.h>+#include <sys/mman.h>+#include <tramp.h>+#ifdef __linux__+#include <linux/limits.h>+#include <linux/types.h>+#endif+#ifdef __CYGWIN__+#include <limits.h>+#endif+#endif++/*+ * Each architecture defines static code for a trampoline code table. The+ * trampoline code table is mapped into the address space of a process.+ *+ * The following architecture specific function returns:+ *+ *	- the address of the trampoline code table in the text segment+ *	- the size of each trampoline in the trampoline code table+ *	- the size of the mapping for the whole trampoline code table+ */+void __attribute__((weak)) *ffi_tramp_arch (size_t *tramp_size,+  size_t *map_size);++/* ------------------------- Trampoline Data Structures --------------------*/++struct tramp;++/*+ * Trampoline table. Manages one trampoline code table and one trampoline+ * parameter table.+ *+ * prev, next	Links in the global trampoline table list.+ * code_table	Trampoline code table mapping.+ * parm_table	Trampoline parameter table mapping.+ * array	Array of trampolines malloced.+ * free		List of free trampolines.+ * nfree	Number of free trampolines.+ */+struct tramp_table+{+  struct tramp_table *prev;+  struct tramp_table *next;+  void *code_table;+  void *parm_table;+  struct tramp *array;+  struct tramp *free;+  int nfree;+};++/*+ * Parameters for each trampoline.+ *+ * data+ *	Data for the target code that the trampoline jumps to.+ * target+ *	Target code that the trampoline jumps to.+ */+struct tramp_parm+{+  void *data;+  void *target;+};++/*+ * Trampoline structure for each trampoline.+ *+ * prev, next	Links in the trampoline free list of a trampoline table.+ * table	Trampoline table to which this trampoline belongs.+ * code		Address of this trampoline in the code table mapping.+ * parm		Address of this trampoline's parameters in the parameter+ *		table mapping.+ */+struct tramp+{+  struct tramp *prev;+  struct tramp *next;+  struct tramp_table *table;+  void *code;+  struct tramp_parm *parm;+};++enum tramp_globals_status {+	TRAMP_GLOBALS_UNINITIALIZED = 0,+	TRAMP_GLOBALS_PASSED,+	TRAMP_GLOBALS_FAILED,+};++/*+ * Trampoline globals.+ *+ * fd+ *	File descriptor of binary file that contains the trampoline code table.+ * offset+ *	Offset of the trampoline code table in that file.+ * text+ *	Address of the trampoline code table in the text segment.+ * map_size+ *	Size of the trampoline code table mapping.+ * size+ *	Size of one trampoline in the trampoline code table.+ * ntramp+ *	Total number of trampolines in the trampoline code table.+ * free_tables+ *	List of trampoline tables that contain free trampolines.+ * nfree_tables+ *	Number of trampoline tables that contain free trampolines.+ * status+ *	Initialization status.+ */+struct tramp_globals+{+  int fd;+  off_t offset;+  void *text;+  size_t map_size;+  size_t size;+  int ntramp;+  struct tramp_table *free_tables;+  int nfree_tables;+  enum tramp_globals_status status;+};++static struct tramp_globals tramp_globals;++/* --------------------- Trampoline File Initialization --------------------*/++/*+ * The trampoline file is the file used to map the trampoline code table into+ * the address space of a process. There are two ways to get this file:+ *+ * - From the OS. E.g., on Linux, /proc/<pid>/maps lists all the memory+ *   mappings for <pid>. For file-backed mappings, maps supplies the file name+ *   and the file offset. Using this, we can locate the mapping that maps+ *   libffi and get the path to the libffi binary. And, we can compute the+ *   offset of the trampoline code table within that binary.+ *+ * - Else, if we can create a temporary file, we can write the trampoline code+ *   table from the text segment into the temporary file.+ *+ * The first method is the preferred one. If the OS security subsystem+ * disallows mapping unsigned files with PROT_EXEC, then the second method+ * will fail.+ *+ * If an OS allows the trampoline code table in the text segment to be+ * directly remapped (e.g., MACH vm_remap ()), then we don't need the+ * trampoline file.+ */+static int tramp_table_alloc (void);++#if defined (__linux__) || defined (__CYGWIN__)++static int+ffi_tramp_get_libffi (void)+{+  FILE *fp;+  char file[PATH_MAX], line[PATH_MAX+100], perm[10], dev[10];+  unsigned long start, end, offset, inode;+  uintptr_t addr = (uintptr_t) tramp_globals.text;+  int nfields, found;+  int open_flags = O_RDONLY;++#ifdef O_CLOEXEC+  open_flags |= O_CLOEXEC;+#endif++  snprintf (file, PATH_MAX, "/proc/%d/maps", getpid());+  fp = fopen (file, "r");+  if (fp == NULL)+    return 0;++  found = 0;+  while (feof (fp) == 0) {+    if (fgets (line, sizeof (line), fp) == 0)+      break;++    nfields = sscanf (line, "%lx-%lx %9s %lx %9s %ld %s",+      &start, &end, perm, &offset, dev, &inode, file);+    if (nfields != 7)+      continue;++    if (addr >= start && addr < end) {+      tramp_globals.offset = offset + (addr - start);+      found = 1;+      break;+    }+  }+  fclose (fp);++  if (!found)+    return 0;++  tramp_globals.fd = open (file, open_flags);+  if (tramp_globals.fd == -1)+    return 0;++  /*+   * Allocate a trampoline table just to make sure that the trampoline code+   * table can be mapped.+   */+  if (!tramp_table_alloc ())+    {+      close (tramp_globals.fd);+      tramp_globals.fd = -1;+      return 0;+    }+  return 1;+}++#endif /* defined (__linux__) || defined (__CYGWIN__) */++#if defined (__linux__) || defined (__CYGWIN__)++static int+ffi_tramp_get_temp_file (void)+{+  ssize_t count;++  tramp_globals.offset = 0;+  tramp_globals.fd = open_temp_exec_file ();++  /*+   * Write the trampoline code table into the temporary file and allocate a+   * trampoline table to make sure that the temporary file can be mapped.+   */+  count = write(tramp_globals.fd, tramp_globals.text, tramp_globals.map_size);+  if (count >=0 && (size_t)count == tramp_globals.map_size && tramp_table_alloc ())+    return 1;++  close (tramp_globals.fd);+  tramp_globals.fd = -1;+  return 0;+}++#endif /* defined (__linux__) || defined (__CYGWIN__) */++/* ------------------------ OS-specific Initialization ----------------------*/++#if defined (__linux__) || defined (__CYGWIN__)++static int+ffi_tramp_init_os (void)+{+  if (ffi_tramp_get_libffi ())+    return 1;+  return ffi_tramp_get_temp_file ();+}++#endif /* defined (__linux__) || defined (__CYGWIN__) */++/* --------------------------- OS-specific Locking -------------------------*/++#if defined (__linux__) || defined (__CYGWIN__)++static pthread_mutex_t tramp_globals_mutex = PTHREAD_MUTEX_INITIALIZER;++static void+ffi_tramp_lock(void)+{+  pthread_mutex_lock (&tramp_globals_mutex);+}++static void+ffi_tramp_unlock(void)+{+  pthread_mutex_unlock (&tramp_globals_mutex);+}++#endif /* defined (__linux__) || defined (__CYGWIN__) */++/* ------------------------ OS-specific Memory Mapping ----------------------*/++/*+ * Create a trampoline code table mapping and a trampoline parameter table+ * mapping. The two mappings must be adjacent to each other for PC-relative+ * access.+ *+ * For each trampoline in the code table, there is a corresponding parameter+ * block in the parameter table. The size of the parameter block is the same+ * as the size of the trampoline. This means that the parameter block is at+ * a fixed offset from its trampoline making it easy for a trampoline to find+ * its parameters using PC-relative access.+ *+ * The parameter block will contain a struct tramp_parm. This means that+ * sizeof (struct tramp_parm) cannot exceed the size of a parameter block.+ */++#if defined (__linux__) || defined (__CYGWIN__)++static int+tramp_table_map (struct tramp_table *table)+{+  char *addr;++  /*+   * Create an anonymous mapping twice the map size. The top half will be used+   * for the code table. The bottom half will be used for the parameter table.+   */+  addr = mmap (NULL, tramp_globals.map_size * 2, PROT_READ | PROT_WRITE,+    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);+  if (addr == MAP_FAILED)+    return 0;++  /*+   * Replace the top half of the anonymous mapping with the code table mapping.+   */+  table->code_table = mmap (addr, tramp_globals.map_size, PROT_READ | PROT_EXEC,+    MAP_PRIVATE | MAP_FIXED, tramp_globals.fd, tramp_globals.offset);+  if (table->code_table == MAP_FAILED)+    {+      (void) munmap (addr, tramp_globals.map_size * 2);+      return 0;+    }+  table->parm_table = table->code_table + tramp_globals.map_size;+  return 1;+}++static void+tramp_table_unmap (struct tramp_table *table)+{+  (void) munmap (table->code_table, tramp_globals.map_size);+  (void) munmap (table->parm_table, tramp_globals.map_size);+}++#endif /* defined (__linux__) || defined (__CYGWIN__) */++/* ------------------------ Trampoline Initialization ----------------------*/++/*+ * Initialize the static trampoline feature.+ */+static int+ffi_tramp_init (void)+{+  long page_size;++  if (tramp_globals.status == TRAMP_GLOBALS_PASSED)+    return 1;++  if (tramp_globals.status == TRAMP_GLOBALS_FAILED)+    return 0;++  if (ffi_tramp_arch == NULL)+    {+      tramp_globals.status = TRAMP_GLOBALS_FAILED;+      return 0;+    }++  tramp_globals.free_tables = NULL;+  tramp_globals.nfree_tables = 0;++  /*+   * Get trampoline code table information from the architecture.+   */+  tramp_globals.text = ffi_tramp_arch (&tramp_globals.size,+    &tramp_globals.map_size);+  tramp_globals.ntramp = tramp_globals.map_size / tramp_globals.size;++  page_size = sysconf (_SC_PAGESIZE);+  if (page_size >= 0 && (size_t)page_size > tramp_globals.map_size)+    return 0;++  if (ffi_tramp_init_os ())+    {+      tramp_globals.status = TRAMP_GLOBALS_PASSED;+      return 1;+    }++  tramp_globals.status = TRAMP_GLOBALS_FAILED;+  return 0;+}++/* ---------------------- Trampoline Table functions ---------------------- */++/* This code assumes that malloc () is available on all OSes. */++static void tramp_add (struct tramp *tramp);++/*+ * Allocate and initialize a trampoline table.+ */+static int+tramp_table_alloc (void)+{+  struct tramp_table *table;+  struct tramp *tramp_array, *tramp;+  size_t size;+  char *code, *parm;+  int i;++  /*+   * If we already have tables with free trampolines, there is no need to+   * allocate a new table.+   */+  if (tramp_globals.nfree_tables > 0)+    return 1;++  /*+   * Allocate a new trampoline table structure.+   */+  table = malloc (sizeof (*table));+  if (table == NULL)+    return 0;++  /*+   * Allocate new trampoline structures.+   */+  tramp_array = malloc (sizeof (*tramp) * tramp_globals.ntramp);+  if (tramp_array == NULL)+    goto free_table;++  /*+   * Map a code table and a parameter table into the caller's address space.+   */+  if (!tramp_table_map (table))+    {+      /*+       * Failed to map the code and parameter tables.+       */+      goto free_tramp_array;+    }++  /*+   * Initialize the trampoline table.+   */+  table->array = tramp_array;+  table->free = NULL;+  table->nfree = 0;++  /*+   * Populate the trampoline table free list. This will also add the trampoline+   * table to the global list of trampoline tables.+   */+  size = tramp_globals.size;+  code = table->code_table;+  parm = table->parm_table;+  for (i = 0; i < tramp_globals.ntramp; i++)+    {+      tramp = &tramp_array[i];+      tramp->table = table;+      tramp->code = code;+      tramp->parm = (struct tramp_parm *) parm;+      tramp_add (tramp);++      code += size;+      parm += size;+    }+  /* Success */+  return 1;++/* Failure */+free_tramp_array:+  free (tramp_array);+free_table:+  free (table);+  return 0;+}++/*+ * Free a trampoline table.+ */+static void+tramp_table_free (struct tramp_table *table)+{+  tramp_table_unmap (table);+  free (table->array);+  free (table);+}++/*+ * Add a new trampoline table to the global table list.+ */+static void+tramp_table_add (struct tramp_table *table)+{+  table->next = tramp_globals.free_tables;+  table->prev = NULL;+  if (tramp_globals.free_tables != NULL)+    tramp_globals.free_tables->prev = table;+  tramp_globals.free_tables = table;+  tramp_globals.nfree_tables++;+}++/*+ * Delete a trampoline table from the global table list.+ */+static void+tramp_table_del (struct tramp_table *table)+{+  tramp_globals.nfree_tables--;+  if (table->prev != NULL)+    table->prev->next = table->next;+  if (table->next != NULL)+    table->next->prev = table->prev;+  if (tramp_globals.free_tables == table)+    tramp_globals.free_tables = table->next;+}++/* ------------------------- Trampoline functions ------------------------- */++/*+ * Add a trampoline to its trampoline table.+ */+static void+tramp_add (struct tramp *tramp)+{+  struct tramp_table *table = tramp->table;++  tramp->next = table->free;+  tramp->prev = NULL;+  if (table->free != NULL)+    table->free->prev = tramp;+  table->free = tramp;+  table->nfree++;++  if (table->nfree == 1)+    tramp_table_add (table);++  /*+   * We don't want to keep too many free trampoline tables lying around.+   */+  if (table->nfree == tramp_globals.ntramp &&+    tramp_globals.nfree_tables > 1)+    {+      tramp_table_del (table);+      tramp_table_free (table);+    }+}++/*+ * Remove a trampoline from its trampoline table.+ */+static void+tramp_del (struct tramp *tramp)+{+  struct tramp_table *table = tramp->table;++  table->nfree--;+  if (tramp->prev != NULL)+    tramp->prev->next = tramp->next;+  if (tramp->next != NULL)+    tramp->next->prev = tramp->prev;+  if (table->free == tramp)+    table->free = tramp->next;++  if (table->nfree == 0)+    tramp_table_del (table);+}++/* ------------------------ Trampoline API functions ------------------------ */++int+ffi_tramp_is_supported(void)+{+  int ret;++  ffi_tramp_lock();+  ret = ffi_tramp_init ();+  ffi_tramp_unlock();+  return ret;+}++/*+ * Allocate a trampoline and return its opaque address.+ */+void *+ffi_tramp_alloc (int flags)+{+  struct tramp *tramp;++  ffi_tramp_lock();++  if (!ffi_tramp_init () || flags != 0)+    {+      ffi_tramp_unlock();+      return NULL;+    }++  if (!tramp_table_alloc ())+    {+      ffi_tramp_unlock();+      return NULL;+    }++  tramp = tramp_globals.free_tables->free;+  tramp_del (tramp);++  ffi_tramp_unlock();++  return tramp;+}++/*+ * Set the parameters for a trampoline.+ */+void+ffi_tramp_set_parms (void *arg, void *target, void *data)+{+  struct tramp *tramp = arg;++  ffi_tramp_lock();+  tramp->parm->target = target;+  tramp->parm->data = data;+  ffi_tramp_unlock();+}++/*+ * Get the invocation address of a trampoline.+ */+void *+ffi_tramp_get_addr (void *arg)+{+  struct tramp *tramp = arg;+  void *addr;++  ffi_tramp_lock();+  addr = tramp->code;+  ffi_tramp_unlock();++  return addr;+}++/*+ * Free a trampoline.+ */+void+ffi_tramp_free (void *arg)+{+  struct tramp *tramp = arg;++  ffi_tramp_lock();+  tramp_add (tramp);+  ffi_tramp_unlock();+}++/* ------------------------------------------------------------------------- */++#else /* !FFI_EXEC_STATIC_TRAMP */++#include <stddef.h>++int+ffi_tramp_is_supported(void)+{+  return 0;+}++void *+ffi_tramp_alloc (int flags)+{+  return NULL;+}++void+ffi_tramp_set_parms (void *arg, void *target, void *data)+{+}++void *+ffi_tramp_get_addr (void *arg)+{+  return NULL;+}++void+ffi_tramp_free (void *arg)+{+}++#endif /* FFI_EXEC_STATIC_TRAMP */
+ src/types.c view
@@ -0,0 +1,128 @@+/* -----------------------------------------------------------------------+   types.c - Copyright (c) 1996, 1998, 2024, 2025  Red Hat, Inc.++   Predefined ffi_types needed by libffi.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++/* Hide the basic type definitions from the header file, so that we+   can redefine them here as "const".  */+#define LIBFFI_HIDE_BASIC_TYPES++#include <ffi.h>+#include <ffi_common.h>++/* Return a version string. */+const char *ffi_get_version (void)+{+  return FFI_VERSION_STRING;+}++/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */+unsigned long ffi_get_version_number (void)+{+  return FFI_VERSION_NUMBER;+}++unsigned int ffi_get_default_abi (void)+{+  return FFI_DEFAULT_ABI;+}++size_t ffi_get_closure_size (void)+{+  return sizeof(ffi_closure);+}++/* Type definitions */++#define FFI_TYPEDEF(name, type, id, maybe_const)\+struct struct_align_##name {			\+  char c;					\+  type x;					\+};						\+FFI_EXTERN					\+maybe_const ffi_type ffi_type_##name = {	\+  sizeof(type),					\+  offsetof(struct struct_align_##name, x),	\+  id, NULL					\+}++#define FFI_COMPLEX_TYPEDEF(name, type, maybe_const)	\+static ffi_type *ffi_elements_complex_##name [2] = {	\+	(ffi_type *)(&ffi_type_##name), NULL		\+};							\+struct struct_align_complex_##name {			\+  char c;						\+  _Complex type x;					\+};							\+FFI_EXTERN						\+maybe_const ffi_type ffi_type_complex_##name = {	\+  sizeof(_Complex type),				\+  offsetof(struct struct_align_complex_##name, x),	\+  FFI_TYPE_COMPLEX,					\+  (ffi_type **)ffi_elements_complex_##name		\+}++/* Size and alignment are fake here. They must not be 0. */+FFI_EXTERN const ffi_type ffi_type_void = {+  1, 1, FFI_TYPE_VOID, NULL+};++FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8, const);+FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8, const);+FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16, const);+FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16, const);+FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32, const);+FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32, const);+FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64, const);+FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64, const);++FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER, const);++FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT, const);+FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE, const);++#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__+#define FFI_LDBL_CONST const+#else+#define FFI_LDBL_CONST+#endif++#ifdef __alpha__+/* Even if we're not configured to default to 128-bit long double,+   maintain binary compatibility, as -mlong-double-128 can be used+   at any time.  */+/* Validate the hard-coded number below.  */+# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4+#  error FFI_TYPE_LONGDOUBLE out of date+# endif+const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };+#else+FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE, FFI_LDBL_CONST);+#endif++#ifdef FFI_TARGET_HAS_COMPLEX_TYPE+FFI_COMPLEX_TYPEDEF(float, float, const);+FFI_COMPLEX_TYPEDEF(double, double, const);+FFI_COMPLEX_TYPEDEF(longdouble, long double, FFI_LDBL_CONST);+#endif
+ src/vax/elfbsd.S view
@@ -0,0 +1,195 @@+/*+ * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>+ *+ * Permission is hereby granted, free of charge, to any person obtaining+ * a copy of this software and associated documentation files (the+ * ``Software''), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ * + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++/*+ * vax Foreign Function Interface+ */++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>++	.text++/*+ * void *					%r0+ * ffi_call_elfbsd(extended_cif *ecif,		4(%ap)+ *		   unsigned bytes,		8(%ap)+ *		   unsigned flags,		12(%ap)+ *		   void *rvalue,		16(%ap)+ *		   void (*fn)());		20(%ap)+ */+	.globl	ffi_call_elfbsd+	.type	ffi_call_elfbsd,@function+	.align	2+ffi_call_elfbsd:+	.word	0x00c		# save R2 and R3++	# Allocate stack space for the args+	subl2	8(%ap), %sp++	# Call ffi_prep_args+	pushl	%sp+	pushl	4(%ap)+	calls	$2, ffi_prep_args++	# Get function pointer+	movl	20(%ap), %r1++	# Build a CALLS frame+	ashl	$-2, 8(%ap), %r0+	pushl	%r0		# argument stack usage+	movl	%sp, %r0	# future %ap+	# saved registers+	bbc	$11, 0(%r1), 1f+	pushl	%r11+1:	bbc	$10, 0(%r1), 1f+	pushl	%r10+1:	bbc	$9, 0(%r1), 1f+	pushl	%r9+1:	bbc	$8, 0(%r1), 1f+	pushl	%r8+1:	bbc	$7, 0(%r1), 1f+	pushl	%r7+1:	bbc	$6, 0(%r1), 1f+	pushl	%r6+1:	bbc	$5, 0(%r1), 1f+	pushl	%r5+1:	bbc	$4, 0(%r1), 1f+	pushl	%r4+1:	bbc	$3, 0(%r1), 1f+	pushl	%r3+1:	bbc	$2, 0(%r1), 1f+	pushl	%r2+1:	+	pushal	9f+	pushl	%fp+	pushl	%ap+	movl	16(%ap), %r3	# struct return address, if needed+	movl	%r0, %ap+	movzwl	4(%fp), %r0	# previous PSW, without the saved registers mask+	bisl2	$0x20000000, %r0 # calls frame+	movzwl	0(%r1), %r2+	bicw2	$0xf003, %r2	# only keep R11-R2+	ashl	$16, %r2, %r2+	bisl2	%r2, %r0	# saved register mask of the called function+	pushl	%r0	+	pushl	$0+	movl	%sp, %fp++	# Invoke the function+	pushal	2(%r1)		# skip procedure entry mask+	movl	%r3, %r1+	bicpsw	$0x000f+	rsb++9:+	# Copy return value if necessary+	tstl	16(%ap)+	jeql	9f+	movl	16(%ap), %r2++	bbc	$0, 12(%ap), 1f	# CIF_FLAGS_CHAR+	movb	%r0, 0(%r2)+	brb	9f+1:+	bbc	$1, 12(%ap), 1f	# CIF_FLAGS_SHORT+	movw	%r0, 0(%r2)+	brb	9f+1:+	bbc	$2, 12(%ap), 1f	# CIF_FLAGS_INT+	movl	%r0, 0(%r2)+	brb	9f+1:+	bbc	$3, 12(%ap), 1f	# CIF_FLAGS_DINT+	movq	%r0, 0(%r2)+	brb	9f+1:+	movl	%r1, %r0	# might have been a struct+	#brb	9f++9:+	ret++/*+ * ffi_closure_elfbsd(void);+ * invoked with	%r0: ffi_closure *closure+ */+	.globl	ffi_closure_elfbsd+	.type	ffi_closure_elfbsd, @function+	.align	2+ffi_closure_elfbsd:+	.word	0++	# Allocate room on stack for return value+	subl2	$8, %sp++	# Invoke the closure function+	pushal	4(%ap)		# calling stack+	pushal	4(%sp)		# return value+	pushl	%r0		# closure+	calls	$3, ffi_closure_elfbsd_inner++	# Copy return value if necessary+	bitb	$1, %r0		# CIF_FLAGS_CHAR+	beql	1f+	movb	0(%sp), %r0+	brb	9f+1:+	bitb	$2, %r0		# CIF_FLAGS_SHORT+	beql	1f+	movw	0(%sp), %r0+	brb	9f+1:+	bitb	$4, %r0		# CIF_FLAGS_INT+	beql	1f+	movl	0(%sp), %r0+	brb	9f+1:+	bitb	$8, %r0		# CIF_FLAGS_DINT+	beql	1f+	movq	0(%sp), %r0+	#brb	9f+1:++9:+	ret++/*+ * ffi_closure_struct_elfbsd(void);+ * invoked with	%r0: ffi_closure *closure+ *		%r1: struct return address+ */+	.globl	ffi_closure_struct_elfbsd+	.type	ffi_closure_struct_elfbsd, @function+	.align	2+ffi_closure_struct_elfbsd:+	.word	0++	# Invoke the closure function+	pushal	4(%ap)		# calling stack+	pushl	%r1		# return value+	pushl	%r0		# closure+	calls	$3, ffi_closure_elfbsd_inner++	ret
+ src/vax/ffi.c view
@@ -0,0 +1,276 @@+/*+ * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>+ *+ * Permission is hereby granted, free of charge, to any person obtaining+ * a copy of this software and associated documentation files (the+ * ``Software''), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ * + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++/*+ * vax Foreign Function Interface+ *+ * This file attempts to provide all the FFI entry points which can reliably+ * be implemented in C.+ */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <unistd.h>++#define CIF_FLAGS_CHAR		1	/* for struct only */+#define CIF_FLAGS_SHORT		2	/* for struct only */+#define CIF_FLAGS_INT		4+#define CIF_FLAGS_DINT		8++/*+ * Foreign Function Interface API+ */++void ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *,+		       void (*) ());+void *ffi_prep_args (extended_cif *ecif, void *stack);++void *+ffi_prep_args (extended_cif *ecif, void *stack)+{+  unsigned int i;+  void **p_argv;+  char *argp;+  ffi_type **p_arg;+  void *struct_value_ptr;++  argp = stack;++  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT+      && !ecif->cif->flags)+    struct_value_ptr = ecif->rvalue;+  else+    struct_value_ptr = NULL;++  p_argv = ecif->avalue;++  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;+       i != 0;+       i--, p_arg++)+    {+      size_t z;++      z = (*p_arg)->size;+      if (z < sizeof (int))+	{+	  switch ((*p_arg)->type)+	    {+	    case FFI_TYPE_SINT8:+	      *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;+	      break;++	    case FFI_TYPE_UINT8:+	      *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;+	      break;++	    case FFI_TYPE_SINT16:+	      *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;+	      break;++	    case FFI_TYPE_UINT16:+	      *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;+	      break;++	    case FFI_TYPE_STRUCT:+	      memcpy (argp, *p_argv, z);+	      break;++	    default:+	      FFI_ASSERT (0);+	    }+	  z = sizeof (int);+	}+      else+	{+	  memcpy (argp, *p_argv, z);++	  /* Align if necessary.  */+	  if ((sizeof(int) - 1) & z)+	    z = FFI_ALIGN(z, sizeof(int));+	}++      p_argv++;+      argp += z;+    }++  return struct_value_ptr;+}++ffi_status+ffi_prep_cif_machdep (ffi_cif *cif)+{+  /* Set the return type flag */+  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      cif->flags = 0;+      break;++    case FFI_TYPE_STRUCT:+      if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT &&+	  cif->rtype->elements[1])+	{+	  cif->flags = 0;+	  break;+	}++      if (cif->rtype->size == sizeof (char))+	cif->flags = CIF_FLAGS_CHAR;+      else if (cif->rtype->size == sizeof (short))+	cif->flags = CIF_FLAGS_SHORT;+      else if (cif->rtype->size == sizeof (int))+	cif->flags = CIF_FLAGS_INT;+      else if (cif->rtype->size == 2 * sizeof (int))+	cif->flags = CIF_FLAGS_DINT;+      else+	cif->flags = 0;+      break;++    default:+      if (cif->rtype->size <= sizeof (int))+	cif->flags = CIF_FLAGS_INT;+      else+	cif->flags = CIF_FLAGS_DINT;+      break;+    }++  return FFI_OK;+}++void+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)+{+  extended_cif ecif;++  ecif.cif = cif;+  ecif.avalue = avalue;++  /* If the return value is a struct and we don't have a return value+     address then we need to make one.  */++  if (rvalue == NULL+      && cif->rtype->type == FFI_TYPE_STRUCT+      && cif->flags == 0)+    ecif.rvalue = alloca (cif->rtype->size);+  else+    ecif.rvalue = rvalue;++  switch (cif->abi)+    {+    case FFI_ELFBSD:+      ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn);+      break;++    default:+      FFI_ASSERT (0);+      break;+    }+}++/*+ * Closure API+ */++void ffi_closure_elfbsd (void);+void ffi_closure_struct_elfbsd (void);+unsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *);++static void+ffi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp)+{+  unsigned int i;+  void **p_argv;+  ffi_type **p_arg;++  p_argv = avalue;++  for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)+    {+      size_t z;++      z = (*p_arg)->size;+      *p_argv = stackp;++      /* Align if necessary */+      if ((sizeof (int) - 1) & z)+	z = FFI_ALIGN(z, sizeof (int));++      p_argv++;+      stackp += z;+    }+}++unsigned int+ffi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack)+{+  ffi_cif *cif;+  void **arg_area;++  cif = closure->cif;+  arg_area = (void **) alloca (cif->nargs * sizeof (void *));++  ffi_prep_closure_elfbsd (cif, arg_area, stack);++  (closure->fun) (cif, resp, arg_area, closure->user_data);++  return cif->flags;+}++ffi_status+ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,+		      void (*fun)(ffi_cif *, void *, void **, void *),+		      void *user_data, void *codeloc)+{+  char *tramp = (char *) codeloc;+  void *fn;++  FFI_ASSERT (cif->abi == FFI_ELFBSD);++  /* entry mask */+  *(unsigned short *)(tramp + 0) = 0x0000;+  /* movl #closure, r0 */+  tramp[2] = 0xd0;+  tramp[3] = 0x8f;+  *(unsigned int *)(tramp + 4) = (unsigned int) closure;+  tramp[8] = 0x50;++  if (cif->rtype->type == FFI_TYPE_STRUCT+      && !cif->flags)+    fn = &ffi_closure_struct_elfbsd;+  else+    fn = &ffi_closure_elfbsd;++  /* jmpl #fn */+  tramp[9] = 0x17;+  tramp[10] = 0xef;+  *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 -+				  (unsigned int)tramp - 9 - 6;++  closure->cif = cif;+  closure->user_data = user_data;+  closure->fun = fun;++  return FFI_OK;+}
+ src/vax/ffitarget.h view
@@ -0,0 +1,49 @@+/*+ * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>+ *+ * Permission is hereby granted, free of charge, to any person obtaining+ * a copy of this software and associated documentation files (the+ * ``Software''), to deal in the Software without restriction, including+ * without limitation the rights to use, copy, modify, merge, publish,+ * distribute, sublicense, and/or sell copies of the Software, and to+ * permit persons to whom the Software is furnished to do so, subject to+ * the following conditions:+ * + * The above copyright notice and this permission notice shall be included+ * in all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ */++/*+ * vax Foreign Function Interface+ */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_ASM+typedef unsigned long ffi_arg;+typedef signed long ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_ELFBSD,+  FFI_DEFAULT_ABI = FFI_ELFBSD,+  FFI_LAST_ABI = FFI_DEFAULT_ABI + 1+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_TRAMPOLINE_SIZE 15+#define FFI_NATIVE_RAW_API 0++#endif
+ src/wasm/ffi.c view
@@ -0,0 +1,798 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2018-2023  Hood Chatham, Brion Vibber, Kleis Auke Wolthuizen, and others.++   wasm32/emscripten Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdint.h>++#include <emscripten/emscripten.h>++#ifdef DEBUG_F+#define LOG_DEBUG(args...)  \+  console.warn(`====LIBFFI(line __LINE__)`, args)+#else+#define LOG_DEBUG(args...) 0+#endif++#define EM_JS_MACROS(ret, name, args, body...) EM_JS(ret, name, args, body)++EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$convertJsFunctionToWasm");++#define DEREF_U8(addr, offset) HEAPU8[addr + offset]+#define DEREF_S8(addr, offset) HEAP8[addr + offset]+#define DEREF_U16(addr, offset) HEAPU16[(addr >> 1) + offset]+#define DEREF_S16(addr, offset) HEAP16[(addr >> 1) + offset]+#define DEREF_U32(addr, offset) HEAPU32[(addr >> 2) + offset]+#define DEREF_S32(addr, offset) HEAP32[(addr >> 2) + offset]++#define DEREF_F32(addr, offset) HEAPF32[(addr >> 2) + offset]+#define DEREF_F64(addr, offset) HEAPF64[(addr >> 3) + offset]+#define DEREF_U64(addr, offset) HEAPU64[(addr >> 3) + offset]++#define CHECK_FIELD_OFFSET(struct, field, offset)                                  \+  _Static_assert(                                                                  \+    offsetof(struct, field) == offset,                                             \+    "Memory layout of '" #struct "' has changed: '" #field "' is in an unexpected location");++#if __SIZEOF_POINTER__ == 4++#define FFI_EMSCRIPTEN_ABI FFI_WASM32_EMSCRIPTEN+#define PTR_SIG 'i'++#define DEC_PTR(p) p+#define ENC_PTR(p) p++#define DEREF_PTR(addr, offset) DEREF_U32(addr, offset)+#define DEREF_PTR_NUMBER(addr, offset) DEREF_PTR(addr, offset)++CHECK_FIELD_OFFSET(ffi_cif, abi, 4*0);+CHECK_FIELD_OFFSET(ffi_cif, nargs, 4*1);+CHECK_FIELD_OFFSET(ffi_cif, arg_types, 4*2);+CHECK_FIELD_OFFSET(ffi_cif, rtype, 4*3);+CHECK_FIELD_OFFSET(ffi_cif, flags, 4*5);+CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 4*6);++#define CIF__ABI(addr) DEREF_U32(addr, 0)+#define CIF__NARGS(addr) DEREF_U32(addr, 1)+#define CIF__ARGTYPES(addr) DEREF_U32(addr, 2)+#define CIF__RTYPE(addr) DEREF_U32(addr, 3)+#define CIF__FLAGS(addr) DEREF_U32(addr, 5)+#define CIF__NFIXEDARGS(addr) DEREF_U32(addr, 6)++CHECK_FIELD_OFFSET(ffi_type, size, 0);+CHECK_FIELD_OFFSET(ffi_type, alignment, 4);+CHECK_FIELD_OFFSET(ffi_type, type, 6);+CHECK_FIELD_OFFSET(ffi_type, elements, 8);++#define FFI_TYPE__SIZE(addr) DEREF_U32(addr, 0)+#define FFI_TYPE__ALIGN(addr) DEREF_U16(addr + 4, 0)+#define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 6, 0)+#define FFI_TYPE__ELEMENTS(addr) DEREF_U32(addr + 8, 0)++#elif __SIZEOF_POINTER__ == 8++#define FFI_EMSCRIPTEN_ABI FFI_WASM64_EMSCRIPTEN+#define PTR_SIG 'j'++// DEC_PTR casts a pointer value (comming from Wasm) represented as BigInt (i64) to Number (i53).+// This should be used for a pointer that is expected to be within the i53 range. If the pointer+// value is outside the Number's range, the value will become NaN.+#define DEC_PTR(p) bigintToI53Checked(p)+// ENC_PTR casts a pointer value represented as Number to BigInt (i64)+#define ENC_PTR(p) BigInt(p)++#define DEREF_PTR(addr, offset) DEREF_U64(addr, offset)+#define DEREF_PTR_NUMBER(addr, offset) DEC_PTR(DEREF_PTR(addr, offset))++CHECK_FIELD_OFFSET(ffi_cif, abi, 0);+CHECK_FIELD_OFFSET(ffi_cif, nargs, 4);+CHECK_FIELD_OFFSET(ffi_cif, arg_types, 8);+CHECK_FIELD_OFFSET(ffi_cif, rtype, 16);+CHECK_FIELD_OFFSET(ffi_cif, flags, 28);+CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 32);++#define CIF__ABI(addr) DEREF_U32(addr, 0)+#define CIF__NARGS(addr) DEREF_U32(addr + 4,  0)+#define CIF__ARGTYPES(addr) DEREF_U64(addr + 8,  0)+#define CIF__RTYPE(addr) DEREF_U64(addr + 16, 0)+#define CIF__FLAGS(addr) DEREF_U32(addr + 28, 0)+#define CIF__NFIXEDARGS(addr) DEREF_U32(addr + 32, 0)++CHECK_FIELD_OFFSET(ffi_type, size, 0);+CHECK_FIELD_OFFSET(ffi_type, alignment, 8);+CHECK_FIELD_OFFSET(ffi_type, type, 10);+CHECK_FIELD_OFFSET(ffi_type, elements, 16);++#define FFI_TYPE__SIZE(addr) DEREF_U64(addr, 0)+#define FFI_TYPE__ALIGN(addr) DEREF_U16(addr + 8, 0)+#define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 10, 0)+#define FFI_TYPE__ELEMENTS(addr) DEREF_U64(addr + 16, 0)++#else+#error "Unknown pointer size"+#endif++#define ALIGN_ADDRESS(addr, align) (addr &= (~((align) - 1)))+#define STACK_ALLOC(stack, size, align) ((stack -= (size)), ALIGN_ADDRESS(stack, align))++// Most wasm runtimes support at most 1000 Js trampoline args.+#define MAX_ARGS 1000++#include <stddef.h>++#define VARARGS_FLAG 1++#define FFI_OK_MACRO 0+_Static_assert(FFI_OK_MACRO == FFI_OK, "FFI_OK must be 0");++#define FFI_BAD_TYPEDEF_MACRO 1+_Static_assert(FFI_BAD_TYPEDEF_MACRO == FFI_BAD_TYPEDEF, "FFI_BAD_TYPEDEF must be 1");++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep(ffi_cif *cif)+{+  if (cif->abi != FFI_EMSCRIPTEN_ABI)+    return FFI_BAD_ABI;+  // This is called after ffi_prep_cif_machdep_var so we need to avoid+  // overwriting cif->nfixedargs.+  if (!(cif->flags & VARARGS_FLAG))+    cif->nfixedargs = cif->nargs;+  if (cif->nargs > MAX_ARGS)+    return FFI_BAD_TYPEDEF;+  if (cif->rtype->type == FFI_TYPE_COMPLEX)+    return FFI_BAD_TYPEDEF;+  // If they put the COMPLEX type into a struct we won't notice, but whatever.+  for (int i = 0; i < cif->nargs; i++)+    if (cif->arg_types[i]->type == FFI_TYPE_COMPLEX)+      return FFI_BAD_TYPEDEF;+  return FFI_OK;+}++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs)+{+  cif->flags |= VARARGS_FLAG;+  cif->nfixedargs = nfixedargs;+  // The varargs takes up one extra argument+  if (cif->nfixedargs + 1 > MAX_ARGS)+    return FFI_BAD_TYPEDEF;+  return FFI_OK;+}++/**+ * A Javascript helper function. This takes an argument typ which is a wasm+ * pointer to an ffi_type object. It returns a pair a type and a type id.+ *+ *    - If it is not a struct, return its type and its typeid field.+ *    - If it is a struct of size >= 2, return the type and its typeid (which+ *      will be FFI_TYPE_STRUCT)+ *    - If it is a struct of size 0, return FFI_TYPE_VOID (????? this is broken)+ *    - If it is a struct of size 1, replace it with the single field and apply+ *      the same logic again to that.+ *+ * By always unboxing structs up front, we can avoid messy casework later.+ */+EM_JS_MACROS(+void,+unbox_small_structs, (ffi_type type_ptr), {+  type_ptr = DEC_PTR(type_ptr);+  var type_id = FFI_TYPE__TYPEID(type_ptr);+  while (type_id === FFI_TYPE_STRUCT) {+    // Don't unbox single element structs if they are bigger than 16 bytes. This+    // is a work around for the fact that Python will give incorrect values for+    // the size of the field in these cases: it says that the struct has pointer+    // size and alignment and are of type pointer, even though it is more+    // accurately a struct and has a larger size. Keeping it as a struct here+    // will let us get the ABI right (which is in fact that the true argument is+    // a pointer to the stack... so maybe Python issn't so wrong??)+    //+    // See the Python comment here:+    // https://github.com/python/cpython/blob/a16a9f978f42b8a09297c1efbf33877f6388c403/Modules/_ctypes/stgdict.c#L718-L779+    if (DEC_PTR(FFI_TYPE__SIZE(type_ptr)) > 16) {+      break;+    }+    var elements = DEC_PTR(FFI_TYPE__ELEMENTS(type_ptr));+    var first_element = DEREF_PTR_NUMBER(elements, 0);+    if (first_element === 0) {+      type_id = FFI_TYPE_VOID;+      break;+    } else if (DEREF_PTR_NUMBER(elements, 1) === 0) {+      type_ptr = first_element;+      type_id = FFI_TYPE__TYPEID(first_element);+    } else {+      break;+    }+  }+  return [type_ptr, type_id];+})++EM_JS_MACROS(+void,+ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),+{+  cif = DEC_PTR(cif);+  fn = DEC_PTR(fn);+  rvalue = DEC_PTR(rvalue);+  avalue = DEC_PTR(avalue);+  var abi = CIF__ABI(cif);+  var nargs = CIF__NARGS(cif);+  var nfixedargs = CIF__NFIXEDARGS(cif);+  var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif));+  var flags = CIF__FLAGS(cif);+  var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif));+  var rtype_ptr = rtype_unboxed[0];+  var rtype_id = rtype_unboxed[1];+  var orig_stack_ptr = stackSave();+  var cur_stack_ptr = orig_stack_ptr;++  var args = [];+  // Does our onwards call return by argument or normally? We return by argument+  // no matter what.+  var ret_by_arg = false;++  if (rtype_id === FFI_TYPE_COMPLEX) {+    throw new Error('complex ret marshalling nyi');+  }+  if (rtype_id < 0 || rtype_id > FFI_TYPE_LAST) {+    throw new Error('Unexpected rtype ' + rtype_id);+  }+  // If the return type is a struct with multiple entries or a long double, the+  // function takes an extra first argument which is a pointer to return value.+  // Conveniently, we've already received a pointer to return value, so we can+  // just use this. We also mark a flag that we don't need to convert the return+  // value of the dynamic call back to C.+  if (rtype_id === FFI_TYPE_LONGDOUBLE || rtype_id === FFI_TYPE_STRUCT) {+    args.push(ENC_PTR(rvalue));+    ret_by_arg = true;+  }++  // Accumulate a Javascript list of arguments for the Javascript wrapper for+  // the wasm function. The Javascript wrapper does a type conversion from+  // Javascript to C automatically, here we manually do the inverse conversion+  // from C to Javascript.+  for (var i = 0; i < nfixedargs; i++) {+    var arg_ptr = DEREF_PTR_NUMBER(avalue, i);+    var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));+    var arg_type_ptr = arg_unboxed[0];+    var arg_type_id = arg_unboxed[1];++    // It's okay here to always use unsigned integers as long as the size is 32+    // or 64 bits. Smaller sizes get extended to 32 bits differently according+    // to whether they are signed or unsigned.+    switch (arg_type_id) {+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+      args.push(DEREF_U32(arg_ptr, 0));+      break;+    case FFI_TYPE_FLOAT:+      args.push(DEREF_F32(arg_ptr, 0));+      break;+    case FFI_TYPE_DOUBLE:+      args.push(DEREF_F64(arg_ptr, 0));+      break;+    case FFI_TYPE_UINT8:+      args.push(DEREF_U8(arg_ptr, 0));+      break;+    case FFI_TYPE_SINT8:+      args.push(DEREF_S8(arg_ptr, 0));+      break;+    case FFI_TYPE_UINT16:+      args.push(DEREF_U16(arg_ptr, 0));+      break;+    case FFI_TYPE_SINT16:+      args.push(DEREF_S16(arg_ptr, 0));+      break;+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      args.push(DEREF_U64(arg_ptr, 0));+      break;+    case FFI_TYPE_LONGDOUBLE:+      // long double is passed as a pair of BigInts.+      args.push(DEREF_U64(arg_ptr, 0));+      args.push(DEREF_U64(arg_ptr, 1));+      break;+    case FFI_TYPE_STRUCT:+      // Nontrivial structs are passed by pointer.+      // Have to copy the struct onto the stack though because C ABI says it's+      // call by value.+      var size = DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr));+      var align = FFI_TYPE__ALIGN(arg_type_ptr);+      STACK_ALLOC(cur_stack_ptr, size, align);+      HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));+      args.push(ENC_PTR(cur_stack_ptr));+      break;+    case FFI_TYPE_POINTER:+      args.push(DEREF_PTR(arg_ptr, 0));+      break;+    case FFI_TYPE_COMPLEX:+      throw new Error('complex marshalling nyi');+    default:+      throw new Error('Unexpected type ' + arg_type_id);+    }+  }++  // Wasm functions can't directly manipulate the callstack, so varargs+  // arguments have to go on a separate stack. A varags function takes one extra+  // argument which is a pointer to where on the separate stack the args are+  // located. Because stacks are allocated backwards, we have to loop over the+  // varargs backwards.+  //+  // We don't have any way of knowing how many args were actually passed, so we+  // just always copy extra nonsense past the end. The ownwards call will know+  // not to look at it.+  if (flags & VARARGS_FLAG) {+    var struct_arg_info = [];+    for (var i = nargs - 1;  i >= nfixedargs; i--) {+      var arg_ptr = DEREF_PTR_NUMBER(avalue, i);+      var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));+      var arg_type_ptr = arg_unboxed[0];+      var arg_type_id = arg_unboxed[1];+      switch (arg_type_id) {+      case FFI_TYPE_UINT8:+      case FFI_TYPE_SINT8:+        STACK_ALLOC(cur_stack_ptr, 1, 1);+        DEREF_U8(cur_stack_ptr, 0) = DEREF_U8(arg_ptr, 0);+        break;+      case FFI_TYPE_UINT16:+      case FFI_TYPE_SINT16:+        STACK_ALLOC(cur_stack_ptr, 2, 2);+        DEREF_U16(cur_stack_ptr, 0) = DEREF_U16(arg_ptr, 0);+        break;+      case FFI_TYPE_INT:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_SINT32:+      case FFI_TYPE_FLOAT:+        STACK_ALLOC(cur_stack_ptr, 4, 4);+        DEREF_U32(cur_stack_ptr, 0) = DEREF_U32(arg_ptr, 0);+        break;+      case FFI_TYPE_DOUBLE:+      case FFI_TYPE_UINT64:+      case FFI_TYPE_SINT64:+        STACK_ALLOC(cur_stack_ptr, 8, 8);+        DEREF_U32(cur_stack_ptr, 0) = DEREF_U32(arg_ptr, 0);+        DEREF_U32(cur_stack_ptr, 1) = DEREF_U32(arg_ptr, 1);+        break;+      case FFI_TYPE_LONGDOUBLE:+        STACK_ALLOC(cur_stack_ptr, 16, 8);+        DEREF_U32(cur_stack_ptr, 0) = DEREF_U32(arg_ptr, 0);+        DEREF_U32(cur_stack_ptr, 1) = DEREF_U32(arg_ptr, 1);+        DEREF_U32(cur_stack_ptr, 2) = DEREF_U32(arg_ptr, 2);+        DEREF_U32(cur_stack_ptr, 3) = DEREF_U32(arg_ptr, 3);+        break;+      case FFI_TYPE_STRUCT:+        // Again, struct must be passed by pointer.+        // But ABI is by value, so have to copy struct onto stack.+        // Currently arguments are going onto stack so we can't put it there now. Come back for this.+        STACK_ALLOC(cur_stack_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__);+        struct_arg_info.push([cur_stack_ptr, arg_ptr, DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)), FFI_TYPE__ALIGN(arg_type_ptr)]);+        break;+      case FFI_TYPE_POINTER:+        STACK_ALLOC(cur_stack_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__);+        DEREF_PTR(cur_stack_ptr, 0) = DEREF_PTR(arg_ptr, 0);+        break;+      case FFI_TYPE_COMPLEX:+        throw new Error('complex arg marshalling nyi');+      default:+        throw new Error('Unexpected argtype ' + arg_type_id);+      }+    }+    // extra normal argument which is the pointer to the varargs.+    args.push(ENC_PTR(cur_stack_ptr));+    // Now allocate variable struct args on stack too.+    for (var i = 0; i < struct_arg_info.length; i++) {+      var struct_info = struct_arg_info[i];+      var arg_target = struct_info[0];+      var arg_ptr = struct_info[1];+      var size = struct_info[2];+      var align = struct_info[3];+      STACK_ALLOC(cur_stack_ptr, size, align);+      HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));+      DEREF_PTR(arg_target, 0) = ENC_PTR(cur_stack_ptr);+    }+  }+  stackRestore(cur_stack_ptr);+  stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer+  LOG_DEBUG("CALL_FUNC_PTR", "fn:", fn, "args:", args);+  var result = getWasmTableEntry(fn).apply(null, args);+  // Put the stack pointer back (we moved it if there were any struct args or we+  // made a varargs call)+  stackRestore(orig_stack_ptr);++  // We need to return by argument. If return value was a nontrivial struct or+  // long double, the onwards call already put the return value in rvalue+  if (ret_by_arg) {+    return;+  }++  // Otherwise the result was automatically converted from C into Javascript and+  // we need to manually convert it back to C.+  switch (rtype_id) {+  case FFI_TYPE_VOID:+    break;+  case FFI_TYPE_INT:+  case FFI_TYPE_UINT32:+  case FFI_TYPE_SINT32:+    DEREF_U32(rvalue, 0) = result;+    break;+  case FFI_TYPE_FLOAT:+    DEREF_F32(rvalue, 0) = result;+    break;+  case FFI_TYPE_DOUBLE:+    DEREF_F64(rvalue, 0) = result;+    break;+  case FFI_TYPE_UINT8:+  case FFI_TYPE_SINT8:+    DEREF_U8(rvalue, 0) = result;+    break;+  case FFI_TYPE_UINT16:+  case FFI_TYPE_SINT16:+    DEREF_U16(rvalue, 0) = result;+    break;+  case FFI_TYPE_UINT64:+  case FFI_TYPE_SINT64:+    DEREF_U64(rvalue, 0) = result;+    break;+  case FFI_TYPE_POINTER:+    DEREF_PTR(rvalue, 0) = result;+    break;+  case FFI_TYPE_COMPLEX:+    throw new Error('complex ret marshalling nyi');+  default:+    throw new Error('Unexpected rtype ' + rtype_id);+  }+});++void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) {+  ffi_call_js(cif, fn, rvalue, avalue);+}++#if __SIZEOF_POINTER__ == 4++CHECK_FIELD_OFFSET(ffi_closure, ftramp, 4*0);+CHECK_FIELD_OFFSET(ffi_closure, cif, 4*1);+CHECK_FIELD_OFFSET(ffi_closure, fun, 4*2);+CHECK_FIELD_OFFSET(ffi_closure, user_data, 4*3);++#define CLOSURE__wrapper(addr) DEREF_U32(addr, 0)+#define CLOSURE__cif(addr) DEREF_U32(addr, 1)+#define CLOSURE__fun(addr) DEREF_U32(addr, 2)+#define CLOSURE__user_data(addr) DEREF_U32(addr, 3)++#elif __SIZEOF_POINTER__ == 8++CHECK_FIELD_OFFSET(ffi_closure, ftramp, 0);+CHECK_FIELD_OFFSET(ffi_closure, cif, 8);+CHECK_FIELD_OFFSET(ffi_closure, fun, 16);+CHECK_FIELD_OFFSET(ffi_closure, user_data, 24);++#define CLOSURE__wrapper(addr) DEREF_U64(addr, 0)+#define CLOSURE__cif(addr) DEREF_U64(addr, 1)+#define CLOSURE__fun(addr) DEREF_U64(addr, 2)+#define CLOSURE__user_data(addr) DEREF_U64(addr, 3)++#else+#error "Unknown pointer size"+#endif++EM_JS_MACROS(void *, ffi_closure_alloc_js, (size_t size, void **code), {+  size = DEC_PTR(size);+  code = DEC_PTR(code);+  var closure = _malloc(size);+  var index = getEmptyTableSlot();+  DEREF_PTR(code, 0) = ENC_PTR(index);+  CLOSURE__wrapper(closure) = ENC_PTR(index);+  return ENC_PTR(closure);+})++void * __attribute__ ((visibility ("default")))+ffi_closure_alloc(size_t size, void **code) {+  return ffi_closure_alloc_js(size, code);+}++EM_JS_MACROS(void, ffi_closure_free_js, (void *closure), {+  closure = DEC_PTR(closure);+  var index = DEC_PTR(CLOSURE__wrapper(closure));+  freeTableIndexes.push(index);+  _free(closure);+})++void __attribute__ ((visibility ("default")))+ffi_closure_free(void *closure) {+  return ffi_closure_free_js(closure);+}++EM_JS_MACROS(+ffi_status,+ffi_prep_closure_loc_js,+(ffi_closure *closure, ffi_cif *cif, void *fun, void *user_data, void *codeloc),+{+  closure = DEC_PTR(closure);+  cif = DEC_PTR(cif);+  fun = DEC_PTR(fun);+  user_data = DEC_PTR(user_data);+  codeloc = DEC_PTR(codeloc);+  var abi = CIF__ABI(cif);+  var nargs = CIF__NARGS(cif);+  var nfixedargs = CIF__NFIXEDARGS(cif);+  var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif));+  var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif));+  var rtype_ptr = rtype_unboxed[0];+  var rtype_id = rtype_unboxed[1];++  // First construct the signature of the javascript trampoline we are going to create.+  // Important: this is the signature for calling us, the onward call always has sig viiii.+  var sig;+  var ret_by_arg = false;+  switch (rtype_id) {+  case FFI_TYPE_VOID:+    sig = 'v';+    break;+  case FFI_TYPE_STRUCT:+  case FFI_TYPE_LONGDOUBLE:+    // Return via a first pointer argument.+    sig = 'v' + PTR_SIG;+    ret_by_arg = true;+    break;+  case FFI_TYPE_INT:+  case FFI_TYPE_UINT8:+  case FFI_TYPE_SINT8:+  case FFI_TYPE_UINT16:+  case FFI_TYPE_SINT16:+  case FFI_TYPE_UINT32:+  case FFI_TYPE_SINT32:+    sig = 'i';+    break;+  case FFI_TYPE_FLOAT:+    sig = 'f';+    break;+  case FFI_TYPE_DOUBLE:+    sig = 'd';+    break;+  case FFI_TYPE_UINT64:+  case FFI_TYPE_SINT64:+    sig = 'j';+    break;+  case FFI_TYPE_POINTER:+    sig = PTR_SIG;+    break;+  case FFI_TYPE_COMPLEX:+    throw new Error('complex ret marshalling nyi');+  default:+    throw new Error('Unexpected rtype ' + rtype_id);+  }+  var unboxed_arg_type_id_list = [];+  var unboxed_arg_type_info_list = [];+  for (var i = 0; i < nargs; i++) {+    var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));+    var arg_type_ptr = arg_unboxed[0];+    var arg_type_id = arg_unboxed[1];+    unboxed_arg_type_id_list.push(arg_type_id);+    unboxed_arg_type_info_list.push([DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)), FFI_TYPE__ALIGN(arg_type_ptr)]);+  }+  for (var i = 0; i < nfixedargs; i++) {+    switch (unboxed_arg_type_id_list[i]) {+    case FFI_TYPE_INT:+    case FFI_TYPE_UINT8:+    case FFI_TYPE_SINT8:+    case FFI_TYPE_UINT16:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_SINT32:+      sig += 'i';+      break;+    case FFI_TYPE_FLOAT:+      sig += 'f';+      break;+    case FFI_TYPE_DOUBLE:+      sig += 'd';+      break;+    case FFI_TYPE_LONGDOUBLE:+      sig += 'jj';+      break;+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      sig += 'j';+      break;+    case FFI_TYPE_STRUCT:+    case FFI_TYPE_POINTER:+      sig += PTR_SIG;+      break;+    case FFI_TYPE_COMPLEX:+      throw new Error('complex marshalling nyi');+    default:+      throw new Error('Unexpected argtype ' + arg_type_id);+    }+  }+  if (nfixedargs < nargs) {+    // extra pointer to varargs stack+    sig += PTR_SIG;+  }+  LOG_DEBUG("CREATE_CLOSURE", "sig:", sig);+  function trampoline() {+    var args = Array.prototype.slice.call(arguments);+    var size = 0;+    var orig_stack_ptr = stackSave();+    var cur_ptr = orig_stack_ptr;+    var ret_ptr;+    var jsarg_idx = 0;+    // Should we return by argument or not? The onwards call returns by argument+    // no matter what. (Warning: ret_by_arg means the opposite in ffi_call)+    if (ret_by_arg) {+      ret_ptr = args[jsarg_idx++];+    } else {+      // We might return 4 bytes or 8 bytes, allocate 8 just in case.+      STACK_ALLOC(cur_ptr, 8, 8);+      ret_ptr = cur_ptr;+    }+    cur_ptr -= __SIZEOF_POINTER__ * nargs;+    var args_ptr = cur_ptr;+    var carg_idx = 0;+    // Here we either have the actual argument, or a pair of BigInts for long+    // double, or a pointer to struct. We have to store into args_ptr[i] a+    // pointer to the ith argument. If the argument is a struct, just store the+    // pointer. Otherwise allocate stack space and copy the js argument onto the+    // stack.+    for (; carg_idx < nfixedargs; carg_idx++) {+      // jsarg_idx might start out as 0 or 1 depending on ret_by_arg+      // it advances an extra time for long double+      var cur_arg = args[jsarg_idx++];+      var arg_type_info = unboxed_arg_type_info_list[carg_idx];+      var arg_size = arg_type_info[0];+      var arg_align = arg_type_info[1];+      var arg_type_id = unboxed_arg_type_id_list[carg_idx];+      switch (arg_type_id) {+      case FFI_TYPE_UINT8:+      case FFI_TYPE_SINT8:+        // Bad things happen if we don't align to 4 here+        STACK_ALLOC(cur_ptr, 1, 4);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_U8(cur_ptr, 0) = cur_arg;+        break;+      case FFI_TYPE_UINT16:+      case FFI_TYPE_SINT16:+        // Bad things happen if we don't align to 4 here+        STACK_ALLOC(cur_ptr, 2, 4);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_U16(cur_ptr, 0) = cur_arg;+        break;+      case FFI_TYPE_INT:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_SINT32:+        STACK_ALLOC(cur_ptr, 4, 4);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_U32(cur_ptr, 0) = cur_arg;+        break;+      case FFI_TYPE_STRUCT:+        // cur_arg is already a pointer to struct+        // copy it onto stack to pass by value+        STACK_ALLOC(cur_ptr, arg_size, arg_align);+        HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(DEC_PTR(cur_arg), DEC_PTR(cur_arg) + arg_size));+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        break;+      case FFI_TYPE_FLOAT:+        STACK_ALLOC(cur_ptr, 4, 4);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_F32(cur_ptr, 0) = cur_arg;+        break;+      case FFI_TYPE_DOUBLE:+        STACK_ALLOC(cur_ptr, 8, 8);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_F64(cur_ptr, 0) = cur_arg;+        break;+      case FFI_TYPE_UINT64:+      case FFI_TYPE_SINT64:+        STACK_ALLOC(cur_ptr, 8, 8);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_U64(cur_ptr, 0) = cur_arg;+        break;+      case FFI_TYPE_LONGDOUBLE:+        STACK_ALLOC(cur_ptr, 16, 8);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_U64(cur_ptr, 0) = cur_arg;+        cur_arg = args[jsarg_idx++];+        DEREF_U64(cur_ptr, 1) = cur_arg;+        break;+      case FFI_TYPE_POINTER:+        STACK_ALLOC(cur_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__);+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+        DEREF_PTR(cur_ptr, 0) = cur_arg;+        break;+      }+    }+    // If its a varargs call, last js argument is a pointer to the varargs.+    var varargs = DEC_PTR(args[args.length - 1]);+    // We have no way of knowing how many varargs were actually provided, this+    // fills the rest of the stack space allocated with nonsense. The onward+    // call will know to ignore the nonsense.++    // We either have a pointer to the argument if the argument is not a struct+    // or a pointer to pointer to struct. We need to store a pointer to the+    // argument into args_ptr[i]+    for (; carg_idx < nargs; carg_idx++) {+      var arg_type_id = unboxed_arg_type_id_list[carg_idx];+      var arg_type_info = unboxed_arg_type_info_list[carg_idx];+      var arg_size = arg_type_info[0];+      var arg_align = arg_type_info[1];+      if (arg_type_id === FFI_TYPE_STRUCT) {+        // In this case varargs is a pointer to pointer to struct so we need to+        // deref once+        var struct_ptr = DEREF_PTR_NUMBER(varargs, 0);+        STACK_ALLOC(cur_ptr, arg_size, arg_align);+        HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(struct_ptr, struct_ptr + arg_size));+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);+      } else {+        DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(varargs);+      }+      varargs += __SIZEOF_POINTER__;+    }+    stackRestore(cur_ptr);+    stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer+    LOG_DEBUG("CALL_CLOSURE", "closure:", closure, "fptr", CLOSURE__fun(closure), "cif", CLOSURE__cif(closure));+    getWasmTableEntry(CLOSURE__fun(closure))(+        CLOSURE__cif(closure), ENC_PTR(ret_ptr), ENC_PTR(args_ptr),+        CLOSURE__user_data(closure)+    );+    stackRestore(orig_stack_ptr);++    // If we aren't supposed to return by argument, figure out what to return.+    if (!ret_by_arg) {+      switch (sig[0]) {+      case 'i':+        return DEREF_U32(ret_ptr, 0);+      case 'j':+        return DEREF_U64(ret_ptr, 0);+      case 'd':+        return DEREF_F64(ret_ptr, 0);+      case 'f':+        return DEREF_F32(ret_ptr, 0);+      }+    }+  }+  try {+    var wasm_trampoline = convertJsFunctionToWasm(trampoline, sig);+  } catch(e) {+    return FFI_BAD_TYPEDEF_MACRO;+  }+  setWasmTableEntry(codeloc, wasm_trampoline);+  CLOSURE__cif(closure) = ENC_PTR(cif);+  CLOSURE__fun(closure) = ENC_PTR(fun);+  CLOSURE__user_data(closure) = ENC_PTR(user_data);+  return FFI_OK_MACRO;+})++// EM_JS does not correctly handle function pointer arguments, so we need a+// helper+ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif,+                                void (*fun)(ffi_cif *, void *, void **, void *),+                                void *user_data, void *codeloc) {+  if (cif->abi != FFI_EMSCRIPTEN_ABI)+    return FFI_BAD_ABI;+  return ffi_prep_closure_loc_js(closure, cif, (void *)fun, user_data,+                                     codeloc);+}
+ src/wasm/ffitarget.h view
@@ -0,0 +1,79 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2018-2023  Hood Chatham, Brion Vibber, Kleis Auke Wolthuizen, and others.++   Target configuration macros for wasm32.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- Generic type definitions ----------------------------------------- */++typedef unsigned long ffi_arg;+typedef signed long ffi_sarg;++// TODO: https://github.com/emscripten-core/emscripten/issues/9868+typedef void (*ffi_fp)(void);++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+#if __SIZEOF_POINTER__ == 4+  FFI_WASM32, // "raw", no structures, varargs, or closures (not implemented!)+  FFI_WASM32_EMSCRIPTEN, // structures, varargs, and split 64-bit params+#elif __SIZEOF_POINTER__ == 8+  FFI_WASM64,+  FFI_WASM64_EMSCRIPTEN,+#else+#error "Unknown pointer size"+#endif+  FFI_LAST_ABI,+#if __SIZEOF_POINTER__ == 4+#ifdef __EMSCRIPTEN__+  FFI_DEFAULT_ABI = FFI_WASM32_EMSCRIPTEN+#else+  FFI_DEFAULT_ABI = FFI_WASM32+#endif+#elif __SIZEOF_POINTER__ == 8+#ifdef __EMSCRIPTEN__+  FFI_DEFAULT_ABI = FFI_WASM64_EMSCRIPTEN+#else+  FFI_DEFAULT_ABI = FFI_WASM64+#endif+#else+#error "Unknown pointer size"+#endif+} ffi_abi;++#define FFI_CLOSURES 1+// #define FFI_GO_CLOSURES 0+#define FFI_TRAMPOLINE_SIZE 4+// #define FFI_NATIVE_RAW_API 0+#define FFI_TARGET_SPECIFIC_VARIADIC 1+#define FFI_EXTRA_CIF_FIELDS  unsigned int nfixedargs++#endif
+ src/x86/asmnames.h view
@@ -0,0 +1,30 @@+#ifndef ASMNAMES_H+#define ASMNAMES_H++#define C2(X, Y)  X ## Y+#define C1(X, Y)  C2(X, Y)+#ifdef __USER_LABEL_PREFIX__+# define C(X)     C1(__USER_LABEL_PREFIX__, X)+#else+# define C(X)     X+#endif++#ifdef __APPLE__+# define L(X)     C1(L, X)+#else+# define L(X)     C1(.L, X)+#endif++#if defined(__ELF__) && defined(__PIC__)+# define PLT(X)	  X@PLT+#else+# define PLT(X)	  X+#endif++#ifdef __ELF__+# define ENDF(X)  .type	X,@function; .size X, . - X+#else+# define ENDF(X)+#endif++#endif /* ASMNAMES_H */
+ src/x86/ffi.c view
@@ -0,0 +1,835 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2017, 2022  Anthony Green+           Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008  Red Hat, Inc.+           Copyright (c) 2002  Ranjit Mathew+           Copyright (c) 2002  Bo Thorsen+           Copyright (c) 2002  Roger Sayle+           Copyright (C) 2008, 2010  Free Software Foundation, Inc.++   x86 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#if defined(__i386__) || defined(_M_IX86)+#include <ffi.h>+#include <ffi_common.h>+#include <stdint.h>+#include <stdlib.h>+#include <tramp.h>+#include "internal.h"++/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;+   all further uses in this file will refer to the 80-bit type.  */+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+# if FFI_TYPE_LONGDOUBLE != 4+#  error FFI_TYPE_LONGDOUBLE out of date+# endif+#else+# undef FFI_TYPE_LONGDOUBLE+# define FFI_TYPE_LONGDOUBLE 4+#endif++#if defined(__GNUC__) && !defined(__declspec)+# define __declspec(x)  __attribute__((x))+#endif++#if defined(_MSC_VER) && defined(_M_IX86)+/* Stack is not 16-byte aligned on Windows.  */+#define STACK_ALIGN(bytes) (bytes)+#else+#define STACK_ALIGN(bytes) FFI_ALIGN (bytes, 16)+#endif++/* Perform machine dependent cif processing.  */+ffi_status FFI_HIDDEN+ffi_prep_cif_machdep(ffi_cif *cif)+{+  size_t bytes = 0;+  int i, n, flags, cabi = cif->abi;++  switch (cabi)+    {+    case FFI_SYSV:+    case FFI_STDCALL:+    case FFI_THISCALL:+    case FFI_FASTCALL:+    case FFI_MS_CDECL:+    case FFI_PASCAL:+    case FFI_REGISTER:+      break;+    default:+      return FFI_BAD_ABI;+    }++  switch (cif->rtype->type)+    {+    case FFI_TYPE_VOID:+      flags = X86_RET_VOID;+      break;+    case FFI_TYPE_FLOAT:+      flags = X86_RET_FLOAT;+      break;+    case FFI_TYPE_DOUBLE:+      flags = X86_RET_DOUBLE;+      break;+    case FFI_TYPE_LONGDOUBLE:+      flags = X86_RET_LDOUBLE;+      break;+    case FFI_TYPE_UINT8:+      flags = X86_RET_UINT8;+      break;+    case FFI_TYPE_UINT16:+      flags = X86_RET_UINT16;+      break;+    case FFI_TYPE_SINT8:+      flags = X86_RET_SINT8;+      break;+    case FFI_TYPE_SINT16:+      flags = X86_RET_SINT16;+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_POINTER:+      flags = X86_RET_INT32;+      break;+    case FFI_TYPE_SINT64:+    case FFI_TYPE_UINT64:+      flags = X86_RET_INT64;+      break;+    case FFI_TYPE_STRUCT:+      {+#if defined(X86_WIN32) || defined(X86_DARWIN)+        size_t size = cif->rtype->size;+        if (size == 1)+          flags = X86_RET_STRUCT_1B;+        else if (size == 2)+          flags = X86_RET_STRUCT_2B;+        else if (size == 4)+          flags = X86_RET_INT32;+        else if (size == 8)+          flags = X86_RET_INT64;+        else+#endif+          {+          do_struct:+            switch (cabi)+              {+              case FFI_THISCALL:+              case FFI_FASTCALL:+              case FFI_STDCALL:+              case FFI_MS_CDECL:+                flags = X86_RET_STRUCTARG;+                break;+              default:+                flags = X86_RET_STRUCTPOP;+                break;+              }+            /* Allocate space for return value pointer.  */+            bytes += FFI_ALIGN (sizeof(void*), FFI_SIZEOF_ARG);+          }+      }+      break;+    case FFI_TYPE_COMPLEX:+      switch (cif->rtype->elements[0]->type)+	{+	case FFI_TYPE_DOUBLE:+	case FFI_TYPE_LONGDOUBLE:+	case FFI_TYPE_SINT64:+	case FFI_TYPE_UINT64:+	  goto do_struct;+	case FFI_TYPE_FLOAT:+	case FFI_TYPE_INT:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT32:+	  flags = X86_RET_INT64;+	  break;+	case FFI_TYPE_SINT16:+	case FFI_TYPE_UINT16:+	  flags = X86_RET_INT32;+	  break;+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT8:+	  flags = X86_RET_STRUCT_2B;+	  break;+	default:+	  return FFI_BAD_TYPEDEF;+	}+      break;+    default:+      return FFI_BAD_TYPEDEF;+    }+  cif->flags = flags;++  for (i = 0, n = cif->nargs; i < n; i++)+    {+      ffi_type *t = cif->arg_types[i];++#if defined(X86_WIN32)+      if (cabi == FFI_STDCALL)+        bytes = FFI_ALIGN (bytes, FFI_SIZEOF_ARG);+      else+#endif+        bytes = FFI_ALIGN (bytes, t->alignment);+      bytes += FFI_ALIGN (t->size, FFI_SIZEOF_ARG);+    }+  cif->bytes = bytes;++  return FFI_OK;+}++static ffi_arg+extend_basic_type(void *arg, int type)+{+  switch (type)+    {+    case FFI_TYPE_SINT8:+      return *(SINT8 *)arg;+    case FFI_TYPE_UINT8:+      return *(UINT8 *)arg;+    case FFI_TYPE_SINT16:+      return *(SINT16 *)arg;+    case FFI_TYPE_UINT16:+      return *(UINT16 *)arg;++    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_POINTER:+    case FFI_TYPE_FLOAT:+      return *(UINT32 *)arg;++    default:+      abort();+    }+}++struct call_frame+{+  void *ebp;		/* 0 */+  void *retaddr;	/* 4 */+  void (*fn)(void);	/* 8 */+  int flags;		/* 12 */+  void *rvalue;		/* 16 */+  unsigned regs[3];	/* 20-28 */+};++struct abi_params+{+  int dir;		/* parameter growth direction */+  int static_chain;	/* the static chain register used by gcc */+  int nregs;		/* number of register parameters */+  int regs[3];+};++static const struct abi_params abi_params[FFI_LAST_ABI] = {+  [FFI_SYSV] = { 1, R_ECX, 0 },+  [FFI_THISCALL] = { 1, R_EAX, 1, { R_ECX } },+  [FFI_FASTCALL] = { 1, R_EAX, 2, { R_ECX, R_EDX } },+  [FFI_STDCALL] = { 1, R_ECX, 0 },+  [FFI_PASCAL] = { -1, R_ECX, 0 },+  /* ??? No defined static chain; gcc does not support REGISTER.  */+  [FFI_REGISTER] = { -1, R_ECX, 3, { R_EAX, R_EDX, R_ECX } },+  [FFI_MS_CDECL] = { 1, R_ECX, 0 }+};++#ifdef HAVE_FASTCALL+  #ifdef _MSC_VER+    #define FFI_DECLARE_FASTCALL __fastcall+  #else+    #define FFI_DECLARE_FASTCALL __declspec(fastcall)+  #endif+#else+  #define FFI_DECLARE_FASTCALL+#endif++extern void FFI_DECLARE_FASTCALL ffi_call_i386(struct call_frame *, char *) FFI_HIDDEN;++/* We perform some black magic here to use some of the parent's stack frame in+ * ffi_call_i386() that breaks with the MSVC compiler with the /RTCs or /GZ+ * flags.  Disable the 'Stack frame run time error checking' for this function+ * so we don't hit weird exceptions in debug builds. */+#if defined(_MSC_VER)+#pragma runtime_checks("s", off)+#endif+/* n.b. ffi_call_unix64 will steal the alloca'd `stack` variable here for use+   _as its own stack_ - so we need to compile this function without ASAN */+FFI_ASAN_NO_SANITIZE+static void+ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,+	      void **avalue, void *closure)+{+  size_t rsize, bytes;+  struct call_frame *frame;+  char *stack, *argp;+  ffi_type **arg_types;+  int flags, cabi, i, n, dir, narg_reg;+  const struct abi_params *pabi;++  flags = cif->flags;+  cabi = cif->abi;+  pabi = &abi_params[cabi];+  dir = pabi->dir;++  rsize = 0;+  if (rvalue == NULL)+    {+      switch (flags)+	{+	case X86_RET_FLOAT:+	case X86_RET_DOUBLE:+	case X86_RET_LDOUBLE:+	case X86_RET_STRUCTPOP:+	case X86_RET_STRUCTARG:+	  /* The float cases need to pop the 387 stack.+	     The struct cases need to pass a valid pointer to the callee.  */+	  rsize = cif->rtype->size;+	  break;+	default:+	  /* We can pretend that the callee returns nothing.  */+	  flags = X86_RET_VOID;+	  break;+	}+    }++  bytes = STACK_ALIGN (cif->bytes);+  stack = alloca(bytes + sizeof(*frame) + rsize);+  argp = (dir < 0 ? stack + bytes : stack);+  frame = (struct call_frame *)(stack + bytes);+  if (rsize)+    rvalue = frame + 1;++  frame->fn = fn;+  frame->flags = flags;+  frame->rvalue = rvalue;+  frame->regs[pabi->static_chain] = (unsigned)closure;++  narg_reg = 0;+  switch (flags)+    {+    case X86_RET_STRUCTARG:+      /* The pointer is passed as the first argument.  */+      if (pabi->nregs > 0)+	{+	  frame->regs[pabi->regs[0]] = (unsigned)rvalue;+	  narg_reg = 1;+	  break;+	}+      /* fallthru */+    case X86_RET_STRUCTPOP:+      *(void **)argp = rvalue;+      argp += sizeof(void *);+      break;+    }++  arg_types = cif->arg_types;+  for (i = 0, n = cif->nargs; i < n; i++)+    {+      ffi_type *ty = arg_types[i];+      void *valp = avalue[i];+      size_t z = ty->size;+      int t = ty->type;++      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)+        {+	  ffi_arg val = extend_basic_type (valp, t);++	  if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)+	    frame->regs[pabi->regs[narg_reg++]] = val;+	  else if (dir < 0)+	    {+	      argp -= 4;+	      *(ffi_arg *)argp = val;+	    }+	  else+	    {+	      *(ffi_arg *)argp = val;+	      argp += 4;+	    }+	}+      else+	{+	  size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);+	  size_t align = FFI_SIZEOF_ARG;++	  /* Issue 434: For thiscall and fastcall, if the paramter passed+	     as 64-bit integer or struct, all following integer parameters+	     will be passed on stack.  */+	  if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)+	      && (t == FFI_TYPE_SINT64+		  || t == FFI_TYPE_UINT64+		  || t == FFI_TYPE_STRUCT))+	    narg_reg = 2;++	  /* Alignment rules for arguments are quite complex.  Vectors and+	     structures with 16 byte alignment get it.  Note that long double+	     on Darwin does have 16 byte alignment, and does not get this+	     alignment if passed directly; a structure with a long double+	     inside, however, would get 16 byte alignment.  Since libffi does+	     not support vectors, we need non concern ourselves with other+	     cases.  */+	  if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)+	    align = 16;++	  if (dir < 0)+	    {+	      /* ??? These reverse argument ABIs are probably too old+		 to have cared about alignment.  Someone should check.  */+	      argp -= za;+	      memcpy (argp, valp, z);+	    }+	  else+	    {+	      argp = (char *)FFI_ALIGN (argp, align);+	      memcpy (argp, valp, z);+	      argp += za;+	    }+	}+    }+  FFI_ASSERT (dir > 0 || argp == stack);++  ffi_call_i386 (frame, stack);+}+#if defined(_MSC_VER)+#pragma runtime_checks("s", restore)+#endif++void+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++#ifdef FFI_GO_CLOSURES+void+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}+#endif++/** private members **/++void FFI_HIDDEN ffi_closure_i386(void);+void FFI_HIDDEN ffi_closure_STDCALL(void);+void FFI_HIDDEN ffi_closure_REGISTER(void);+#if defined(FFI_EXEC_STATIC_TRAMP)+void FFI_HIDDEN ffi_closure_i386_alt(void);+void FFI_HIDDEN ffi_closure_STDCALL_alt(void);+void FFI_HIDDEN ffi_closure_REGISTER_alt(void);+#endif++struct closure_frame+{+  unsigned rettemp[4];				/* 0 */+  unsigned regs[3];				/* 16-24 */+  ffi_cif *cif;					/* 28 */+  void (*fun)(ffi_cif*,void*,void**,void*);	/* 32 */+  void *user_data;				/* 36 */+};++int FFI_HIDDEN FFI_DECLARE_FASTCALL+ffi_closure_inner (struct closure_frame *frame, char *stack)+{+  ffi_cif *cif = frame->cif;+  int cabi, i, n, flags, dir, narg_reg;+  const struct abi_params *pabi;+  ffi_type **arg_types;+  char *argp;+  void *rvalue;+  void **avalue;++  cabi = cif->abi;+  flags = cif->flags;+  narg_reg = 0;+  rvalue = frame->rettemp;+  pabi = &abi_params[cabi];+  dir = pabi->dir;+  argp = (dir < 0 ? stack + STACK_ALIGN (cif->bytes) : stack);++  switch (flags)+    {+    case X86_RET_STRUCTARG:+      if (pabi->nregs > 0)+	{+	  rvalue = (void *)frame->regs[pabi->regs[0]];+	  narg_reg = 1;+	  frame->rettemp[0] = (unsigned)rvalue;+	  break;+	}+      /* fallthru */+    case X86_RET_STRUCTPOP:+      rvalue = *(void **)argp;+      argp += sizeof(void *);+      frame->rettemp[0] = (unsigned)rvalue;+      break;+    }++  n = cif->nargs;+  avalue = alloca(sizeof(void *) * n);++  arg_types = cif->arg_types;+  for (i = 0; i < n; ++i)+    {+      ffi_type *ty = arg_types[i];+      size_t z = ty->size;+      int t = ty->type;+      void *valp;++      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT)+	{+	  if (t != FFI_TYPE_FLOAT && narg_reg < pabi->nregs)+	    valp = &frame->regs[pabi->regs[narg_reg++]];+	  else if (dir < 0)+	    {+	      argp -= 4;+	      valp = argp;+	    }+	  else+	    {+	      valp = argp;+	      argp += 4;+	    }+	}+      else+	{+	  size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);+	  size_t align = FFI_SIZEOF_ARG;++	  /* See the comment in ffi_call_int.  */+	  if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)+	    align = 16;++	  /* Issue 434: For thiscall and fastcall, if the paramter passed+	     as 64-bit integer or struct, all following integer parameters+	     will be passed on stack.  */+	  if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)+	      && (t == FFI_TYPE_SINT64+		  || t == FFI_TYPE_UINT64+		  || t == FFI_TYPE_STRUCT))+	    narg_reg = 2;++	  if (dir < 0)+	    {+	      /* ??? These reverse argument ABIs are probably too old+		 to have cared about alignment.  Someone should check.  */+	      argp -= za;+	      valp = argp;+	    }+	  else+	    {+	      argp = (char *)FFI_ALIGN (argp, align);+	      valp = argp;+	      argp += za;+	    }+	}++      avalue[i] = valp;+    }++  frame->fun (cif, rvalue, avalue, frame->user_data);++  switch (cabi)+    {+    case FFI_STDCALL:+      return flags | (cif->bytes << X86_RET_POP_SHIFT);+    case FFI_THISCALL:+    case FFI_FASTCALL:+      return flags | ((cif->bytes - (narg_reg * FFI_SIZEOF_ARG))+          << X86_RET_POP_SHIFT);+    default:+      return flags;+    }+}++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+                      ffi_cif* cif,+                      void (*fun)(ffi_cif*,void*,void**,void*),+                      void *user_data,+                      void *codeloc)+{+  char *tramp = closure->tramp;+  void (*dest)(void);+  int op = 0xb8;  /* movl imm, %eax */++  switch (cif->abi)+    {+    case FFI_SYSV:+    case FFI_MS_CDECL:+      dest = ffi_closure_i386;+      break;+    case FFI_STDCALL:+    case FFI_THISCALL:+    case FFI_FASTCALL:+    case FFI_PASCAL:+      dest = ffi_closure_STDCALL;+      break;+    case FFI_REGISTER:+      dest = ffi_closure_REGISTER;+      op = 0x68;  /* pushl imm */+      break;+    default:+      return FFI_BAD_ABI;+    }++#if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      if (dest == ffi_closure_i386)+        dest = ffi_closure_i386_alt;+      else if (dest == ffi_closure_STDCALL)+        dest = ffi_closure_STDCALL_alt;+      else+        dest = ffi_closure_REGISTER_alt;+      ffi_tramp_set_parms (closure->ftramp, dest, closure);+      goto out;+    }+#endif++  /* Initialize the dynamic trampoline. */+  /* endbr32.  */+  *(UINT32 *) tramp = 0xfb1e0ff3;++  /* movl or pushl immediate.  */+  tramp[4] = op;+  *(void **)(tramp + 5) = codeloc;++  /* jmp dest */+  tramp[9] = 0xe9;+  *(unsigned *)(tramp + 10) = (unsigned)dest - ((unsigned)codeloc + 14);++#if defined(FFI_EXEC_STATIC_TRAMP)+out:+#endif+  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++#ifdef FFI_GO_CLOSURES++void FFI_HIDDEN ffi_go_closure_EAX(void);+void FFI_HIDDEN ffi_go_closure_ECX(void);+void FFI_HIDDEN ffi_go_closure_STDCALL(void);++ffi_status+ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,+		     void (*fun)(ffi_cif*,void*,void**,void*))+{+  void (*dest)(void);++  switch (cif->abi)+    {+    case FFI_SYSV:+    case FFI_MS_CDECL:+      dest = ffi_go_closure_ECX;+      break;+    case FFI_THISCALL:+    case FFI_FASTCALL:+      dest = ffi_go_closure_EAX;+      break;+    case FFI_STDCALL:+    case FFI_PASCAL:+      dest = ffi_go_closure_STDCALL;+      break;+    case FFI_REGISTER:+    default:+      return FFI_BAD_ABI;+    }++  closure->tramp = dest;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++#endif /* FFI_GO_CLOSURES */++/* ------- Native raw API support -------------------------------- */++#if !FFI_NO_RAW_API++void FFI_HIDDEN ffi_closure_raw_SYSV(void);+void FFI_HIDDEN ffi_closure_raw_THISCALL(void);++ffi_status+ffi_prep_raw_closure_loc (ffi_raw_closure *closure,+                          ffi_cif *cif,+                          void (*fun)(ffi_cif*,void*,ffi_raw*,void*),+                          void *user_data,+                          void *codeloc)+{+  char *tramp = closure->tramp;+  void (*dest)(void);+  int i;++  /* We currently don't support certain kinds of arguments for raw+     closures.  This should be implemented by a separate assembly+     language routine, since it would require argument processing,+     something we don't do now for performance.  */+  for (i = cif->nargs-1; i >= 0; i--)+    switch (cif->arg_types[i]->type)+      {+      case FFI_TYPE_STRUCT:+      case FFI_TYPE_LONGDOUBLE:+	return FFI_BAD_TYPEDEF;+      }++  switch (cif->abi)+    {+    case FFI_THISCALL:+      dest = ffi_closure_raw_THISCALL;+      break;+    case FFI_SYSV:+      dest = ffi_closure_raw_SYSV;+      break;+    default:+      return FFI_BAD_ABI;+    }++  /* movl imm, %eax.  */+  tramp[0] = 0xb8;+  *(void **)(tramp + 1) = codeloc;++  /* jmp dest */+  tramp[5] = 0xe9;+  *(unsigned *)(tramp + 6) = (unsigned)dest - ((unsigned)codeloc + 10);++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++void+ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)+{+  size_t rsize, bytes;+  struct call_frame *frame;+  char *stack, *argp;+  ffi_type **arg_types;+  int flags, cabi, i, n, narg_reg;+  const struct abi_params *pabi;++  flags = cif->flags;+  cabi = cif->abi;+  pabi = &abi_params[cabi];++  rsize = 0;+  if (rvalue == NULL)+    {+      switch (flags)+	{+	case X86_RET_FLOAT:+	case X86_RET_DOUBLE:+	case X86_RET_LDOUBLE:+	case X86_RET_STRUCTPOP:+	case X86_RET_STRUCTARG:+	  /* The float cases need to pop the 387 stack.+	     The struct cases need to pass a valid pointer to the callee.  */+	  rsize = cif->rtype->size;+	  break;+	default:+	  /* We can pretend that the callee returns nothing.  */+	  flags = X86_RET_VOID;+	  break;+	}+    }++  bytes = STACK_ALIGN (cif->bytes);+  argp = stack =+      (void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);+  frame = (struct call_frame *)(stack + bytes);+  if (rsize)+    rvalue = frame + 1;++  frame->fn = fn;+  frame->flags = flags;+  frame->rvalue = rvalue;++  narg_reg = 0;+  switch (flags)+    {+    case X86_RET_STRUCTARG:+      /* The pointer is passed as the first argument.  */+      if (pabi->nregs > 0)+	{+	  frame->regs[pabi->regs[0]] = (unsigned)rvalue;+	  narg_reg = 1;+	  break;+	}+      /* fallthru */+    case X86_RET_STRUCTPOP:+      *(void **)argp = rvalue;+      argp += sizeof(void *);+      bytes -= sizeof(void *);+      break;+    }++  arg_types = cif->arg_types;+  for (i = 0, n = cif->nargs; narg_reg < pabi->nregs && i < n; i++)+    {+      ffi_type *ty = arg_types[i];+      size_t z = ty->size;+      int t = ty->type;++      if (z <= FFI_SIZEOF_ARG && t != FFI_TYPE_STRUCT && t != FFI_TYPE_FLOAT)+	{+	  ffi_arg val = extend_basic_type (avalue, t);+	  frame->regs[pabi->regs[narg_reg++]] = val;+	  z = FFI_SIZEOF_ARG;+	}+      else+	{+	  memcpy (argp, avalue, z);+	  z = FFI_ALIGN (z, FFI_SIZEOF_ARG);+	  argp += z;+	}+      avalue += z;+      bytes -= z;+    }+  if (i < n)+    memcpy (argp, avalue, bytes);++  ffi_call_i386 (frame, stack);+}+#endif /* !FFI_NO_RAW_API */++#if defined(FFI_EXEC_STATIC_TRAMP)+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;++  *map_size = X86_TRAMP_MAP_SIZE;+  *tramp_size = X86_TRAMP_SIZE;+  return &trampoline_code_table;+}+#endif++#endif /* __i386__ */
+ src/x86/ffi64.c view
@@ -0,0 +1,953 @@+/* -----------------------------------------------------------------------+   ffi64.c - Copyright (c) 2011, 2018, 2022  Anthony Green+             Copyright (c) 2013  The Written Word, Inc.+             Copyright (c) 2008, 2010  Red Hat, Inc.+             Copyright (c) 2002, 2007  Bo Thorsen <bo@suse.de>++   x86-64 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#include <ffi.h>+#include <ffi_common.h>++#include <stdlib.h>+#include <stdarg.h>+#include <stdint.h>+#include <tramp.h>+#include "internal64.h"++#ifdef __x86_64__++#define MAX_GPR_REGS 6+#define MAX_SSE_REGS 8++#if defined(__INTEL_COMPILER)+#include "xmmintrin.h"+#define UINT128 __m128+#else+#if defined(__SUNPRO_C)+#include <sunmedia_types.h>+#define UINT128 __m128i+#else+#define UINT128 __int128_t+#endif+#endif++union big_int_union+{+  UINT32 i32;+  UINT64 i64;+  UINT128 i128;+};++struct register_args+{+  /* Registers for argument passing.  */+  UINT64 gpr[MAX_GPR_REGS];+  union big_int_union sse[MAX_SSE_REGS];+  UINT64 rax;	/* ssecount */+  UINT64 r10;	/* static chain */+};++extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,+			     void *raddr, void (*fnaddr)(void)) FFI_HIDDEN;++/* All reference to register classes here is identical to the code in+   gcc/config/i386/i386.c. Do *not* change one without the other.  */++/* Register class used for passing given 64bit part of the argument.+   These represent classes as documented by the PS ABI, with the+   exception of SSESF, SSEDF classes, that are basically SSE class,+   just gcc will use SF or DFmode move instead of DImode to avoid+   reformatting penalties.++   Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves+   whenever possible (upper half does contain padding).  */+enum x86_64_reg_class+  {+    X86_64_NO_CLASS,+    X86_64_INTEGER_CLASS,+    X86_64_INTEGERSI_CLASS,+    X86_64_SSE_CLASS,+    X86_64_SSESF_CLASS,+    X86_64_SSEDF_CLASS,+    X86_64_SSEUP_CLASS,+    X86_64_X87_CLASS,+    X86_64_X87UP_CLASS,+    X86_64_COMPLEX_X87_CLASS,+    X86_64_MEMORY_CLASS+  };++#define MAX_CLASSES 4++#define SSE_CLASS_P(X)	((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS)++/* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal+   of this code is to classify each 8bytes of incoming argument by the register+   class and assign registers accordingly.  */++/* Return the union class of CLASS1 and CLASS2.+   See the x86-64 PS ABI for details.  */++static enum x86_64_reg_class+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)+{+  /* Rule #1: If both classes are equal, this is the resulting class.  */+  if (class1 == class2)+    return class1;++  /* Rule #2: If one of the classes is NO_CLASS, the resulting class is+     the other class.  */+  if (class1 == X86_64_NO_CLASS)+    return class2;+  if (class2 == X86_64_NO_CLASS)+    return class1;++  /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */+  if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)+    return X86_64_MEMORY_CLASS;++  /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */+  if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)+      || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))+    return X86_64_INTEGERSI_CLASS;+  if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS+      || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)+    return X86_64_INTEGER_CLASS;++  /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,+     MEMORY is used.  */+  if (class1 == X86_64_X87_CLASS+      || class1 == X86_64_X87UP_CLASS+      || class1 == X86_64_COMPLEX_X87_CLASS+      || class2 == X86_64_X87_CLASS+      || class2 == X86_64_X87UP_CLASS+      || class2 == X86_64_COMPLEX_X87_CLASS)+    return X86_64_MEMORY_CLASS;++  /* Rule #6: Otherwise class SSE is used.  */+  return X86_64_SSE_CLASS;+}++/* Classify the argument of type TYPE and mode MODE.+   CLASSES will be filled by the register class used to pass each word+   of the operand.  The number of words is returned.  In case the parameter+   should be passed in memory, 0 is returned. As a special case for zero+   sized containers, classes[0] will be NO_CLASS and 1 is returned.++   See the x86-64 PS ABI for details.+*/+static size_t+classify_argument (ffi_type *type, enum x86_64_reg_class classes[],+		   size_t byte_offset)+{+  switch (type->type)+    {+    case FFI_TYPE_UINT8:+    case FFI_TYPE_SINT8:+    case FFI_TYPE_UINT16:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_UINT32:+    case FFI_TYPE_SINT32:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+    case FFI_TYPE_POINTER:+    do_integer:+      {+	size_t size = byte_offset + type->size;++	if (size <= 4)+	  {+	    classes[0] = X86_64_INTEGERSI_CLASS;+	    return 1;+	  }+	else if (size <= 8)+	  {+	    classes[0] = X86_64_INTEGER_CLASS;+	    return 1;+	  }+	else if (size <= 12)+	  {+	    classes[0] = X86_64_INTEGER_CLASS;+	    classes[1] = X86_64_INTEGERSI_CLASS;+	    return 2;+	  }+	else if (size <= 16)+	  {+	    classes[0] = classes[1] = X86_64_INTEGER_CLASS;+	    return 2;+	  }+	else+	  FFI_ASSERT (0);+      }+    case FFI_TYPE_FLOAT:+      if (!(byte_offset % 8))+	classes[0] = X86_64_SSESF_CLASS;+      else+	classes[0] = X86_64_SSE_CLASS;+      return 1;+    case FFI_TYPE_DOUBLE:+      classes[0] = X86_64_SSEDF_CLASS;+      return 1;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+    case FFI_TYPE_LONGDOUBLE:+      classes[0] = X86_64_X87_CLASS;+      classes[1] = X86_64_X87UP_CLASS;+      return 2;+#endif+    case FFI_TYPE_STRUCT:+      {+	const size_t UNITS_PER_WORD = 8;+        size_t words = (type->size + byte_offset + UNITS_PER_WORD - 1)+                       / UNITS_PER_WORD;+	ffi_type **ptr;+	unsigned int i;+	enum x86_64_reg_class subclasses[MAX_CLASSES];++	/* If the struct is larger than 32 bytes, pass it on the stack.  */+	if (type->size > 32)+	  return 0;++	for (i = 0; i < words; i++)+	  classes[i] = X86_64_NO_CLASS;++	/* Zero sized arrays or structures are NO_CLASS.  We return 0 to+	   signalize memory class, so handle it as special case.  */+	if (!words)+	  {+    case FFI_TYPE_VOID:+	    classes[0] = X86_64_NO_CLASS;+	    return 1;+	  }++	/* Merge the fields of structure.  */+	for (ptr = type->elements; *ptr != NULL; ptr++)+	  {+	    size_t num, pos;++	    byte_offset = FFI_ALIGN (byte_offset, (*ptr)->alignment);++	    num = classify_argument (*ptr, subclasses, byte_offset % 8);+	    if (num == 0)+	      return 0;+            pos = byte_offset / 8;+            for (i = 0; i < num && (i + pos) < words; i++)+	      {+		size_t pos = byte_offset / 8;+		classes[i + pos] =+		  merge_classes (subclasses[i], classes[i + pos]);+	      }++	    byte_offset += (*ptr)->size;+	  }++	if (words > 2)+	  {+	    /* When size > 16 bytes, if the first one isn't+	       X86_64_SSE_CLASS or any other ones aren't+	       X86_64_SSEUP_CLASS, everything should be passed in+	       memory.  */+	    if (classes[0] != X86_64_SSE_CLASS)+	      return 0;++	    for (i = 1; i < words; i++)+	      if (classes[i] != X86_64_SSEUP_CLASS)+		return 0;+	  }++	/* Final merger cleanup.  */+	for (i = 0; i < words; i++)+	  {+	    /* If one class is MEMORY, everything should be passed in+	       memory.  */+	    if (classes[i] == X86_64_MEMORY_CLASS)+	      return 0;++	    /* The X86_64_SSEUP_CLASS should be always preceded by+	       X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */+	    if (i > 1 && classes[i] == X86_64_SSEUP_CLASS+		&& classes[i - 1] != X86_64_SSE_CLASS+		&& classes[i - 1] != X86_64_SSEUP_CLASS)+	      {+		/* The first one should never be X86_64_SSEUP_CLASS.  */+		FFI_ASSERT (i != 0);+		classes[i] = X86_64_SSE_CLASS;+	      }++	    /*  If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,+		everything should be passed in memory.  */+	    if (i > 1 && classes[i] == X86_64_X87UP_CLASS+		&& (classes[i - 1] != X86_64_X87_CLASS))+	      {+		/* The first one should never be X86_64_X87UP_CLASS.  */+		FFI_ASSERT (i != 0);+		return 0;+	      }+	  }+	return words;+      }+    case FFI_TYPE_COMPLEX:+      {+	ffi_type *inner = type->elements[0];+	switch (inner->type)+	  {+	  case FFI_TYPE_INT:+	  case FFI_TYPE_UINT8:+	  case FFI_TYPE_SINT8:+	  case FFI_TYPE_UINT16:+	  case FFI_TYPE_SINT16:+	  case FFI_TYPE_UINT32:+	  case FFI_TYPE_SINT32:+	  case FFI_TYPE_UINT64:+	  case FFI_TYPE_SINT64:+	    goto do_integer;++	  case FFI_TYPE_FLOAT:+	    classes[0] = X86_64_SSE_CLASS;+	    if (byte_offset % 8)+	      {+		classes[1] = X86_64_SSESF_CLASS;+		return 2;+	      }+	    return 1;+	  case FFI_TYPE_DOUBLE:+	    classes[0] = classes[1] = X86_64_SSEDF_CLASS;+	    return 2;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	  case FFI_TYPE_LONGDOUBLE:+	    classes[0] = X86_64_COMPLEX_X87_CLASS;+	    return 1;+#endif+	  }+      }+    }+  abort();+}++/* Examine the argument and return set number of register required in each+   class.  Return zero iff parameter should be passed in memory, otherwise+   the number of registers.  */++static size_t+examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],+		  _Bool in_return, int *pngpr, int *pnsse)+{+  size_t n;+  unsigned int i;+  int ngpr, nsse;++  n = classify_argument (type, classes, 0);+  if (n == 0)+    return 0;++  ngpr = nsse = 0;+  for (i = 0; i < n; ++i)+    switch (classes[i])+      {+      case X86_64_INTEGER_CLASS:+      case X86_64_INTEGERSI_CLASS:+	ngpr++;+	break;+      case X86_64_SSE_CLASS:+      case X86_64_SSESF_CLASS:+      case X86_64_SSEDF_CLASS:+	nsse++;+	break;+      case X86_64_NO_CLASS:+      case X86_64_SSEUP_CLASS:+	break;+      case X86_64_X87_CLASS:+      case X86_64_X87UP_CLASS:+      case X86_64_COMPLEX_X87_CLASS:+	return in_return != 0;+      default:+	abort ();+      }++  *pngpr = ngpr;+  *pnsse = nsse;++  return n;+}++/* Perform machine dependent cif processing.  */++#ifndef __ILP32__+extern ffi_status+ffi_prep_cif_machdep_efi64(ffi_cif *cif);+#endif++ffi_status FFI_HIDDEN+ffi_prep_cif_machdep (ffi_cif *cif)+{+  int gprcount, ssecount, i, avn, ngpr, nsse;+  unsigned flags;+  enum x86_64_reg_class classes[MAX_CLASSES];+  size_t bytes, n, rtype_size;+  ffi_type *rtype;++#ifndef __ILP32__+  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)+    return ffi_prep_cif_machdep_efi64(cif);+#endif+  if (cif->abi != FFI_UNIX64)+    return FFI_BAD_ABI;++  gprcount = ssecount = 0;++  rtype = cif->rtype;+  rtype_size = rtype->size;+  switch (rtype->type)+    {+    case FFI_TYPE_VOID:+      flags = UNIX64_RET_VOID;+      break;+    case FFI_TYPE_UINT8:+      flags = UNIX64_RET_UINT8;+      break;+    case FFI_TYPE_SINT8:+      flags = UNIX64_RET_SINT8;+      break;+    case FFI_TYPE_UINT16:+      flags = UNIX64_RET_UINT16;+      break;+    case FFI_TYPE_SINT16:+      flags = UNIX64_RET_SINT16;+      break;+    case FFI_TYPE_UINT32:+      flags = UNIX64_RET_UINT32;+      break;+    case FFI_TYPE_INT:+    case FFI_TYPE_SINT32:+      flags = UNIX64_RET_SINT32;+      break;+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      flags = UNIX64_RET_INT64;+      break;+    case FFI_TYPE_POINTER:+      flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);+      break;+    case FFI_TYPE_FLOAT:+      flags = UNIX64_RET_XMM32;+      break;+    case FFI_TYPE_DOUBLE:+      flags = UNIX64_RET_XMM64;+      break;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+    case FFI_TYPE_LONGDOUBLE:+      flags = UNIX64_RET_X87;+      break;+#endif+    case FFI_TYPE_STRUCT:+      n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);+      if (n == 0)+	{+	  /* The return value is passed in memory.  A pointer to that+	     memory is the first argument.  Allocate a register for it.  */+	  gprcount++;+	  /* We don't have to do anything in asm for the return.  */+	  flags = UNIX64_RET_VOID | UNIX64_FLAG_RET_IN_MEM;+	}+      else+	{+	  _Bool sse0 = SSE_CLASS_P (classes[0]);++	  if (rtype_size == 4 && sse0)+	    flags = UNIX64_RET_XMM32;+	  else if (rtype_size == 8)+	    flags = sse0 ? UNIX64_RET_XMM64 : UNIX64_RET_INT64;+	  else+	    {+	      _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);+	      if (sse0 && sse1)+		flags = UNIX64_RET_ST_XMM0_XMM1;+	      else if (sse0)+		flags = UNIX64_RET_ST_XMM0_RAX;+	      else if (sse1)+		flags = UNIX64_RET_ST_RAX_XMM0;+	      else+		flags = UNIX64_RET_ST_RAX_RDX;+	      flags |= rtype_size << UNIX64_SIZE_SHIFT;+	    }+	}+      break;+    case FFI_TYPE_COMPLEX:+      switch (rtype->elements[0]->type)+	{+	case FFI_TYPE_UINT8:+	case FFI_TYPE_SINT8:+	case FFI_TYPE_UINT16:+	case FFI_TYPE_SINT16:+	case FFI_TYPE_INT:+	case FFI_TYPE_UINT32:+	case FFI_TYPE_SINT32:+	case FFI_TYPE_UINT64:+	case FFI_TYPE_SINT64:+	  flags = UNIX64_RET_ST_RAX_RDX | ((unsigned) rtype_size << UNIX64_SIZE_SHIFT);+	  break;+	case FFI_TYPE_FLOAT:+	  flags = UNIX64_RET_XMM64;+	  break;+	case FFI_TYPE_DOUBLE:+	  flags = UNIX64_RET_ST_XMM0_XMM1 | (16 << UNIX64_SIZE_SHIFT);+	  break;+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE+	case FFI_TYPE_LONGDOUBLE:+	  flags = UNIX64_RET_X87_2;+	  break;+#endif+	default:+	  return FFI_BAD_TYPEDEF;+	}+      break;+    default:+      return FFI_BAD_TYPEDEF;+    }++  /* Go over all arguments and determine the way they should be passed.+     If it's in a register and there is space for it, let that be so. If+     not, add it's size to the stack byte count.  */+  for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++)+    {+      if (examine_argument (cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0+	  || gprcount + ngpr > MAX_GPR_REGS+	  || ssecount + nsse > MAX_SSE_REGS)+	{+	  long align = cif->arg_types[i]->alignment;++	  if (align < 8)+	    align = 8;++	  bytes = FFI_ALIGN (bytes, align);+	  bytes += cif->arg_types[i]->size;+	}+      else+	{+	  gprcount += ngpr;+	  ssecount += nsse;+	}+    }+  if (ssecount)+    flags |= UNIX64_FLAG_XMM_ARGS;++  cif->flags = flags;+  cif->bytes = (unsigned) FFI_ALIGN (bytes, 8);++  return FFI_OK;+}++/* n.b. ffi_call_unix64 will steal the alloca'd `stack` variable here for use+   _as its own stack_ - so we need to compile this function without ASAN */+FFI_ASAN_NO_SANITIZE+static void+ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,+	      void **avalue, void *closure)+{+  enum x86_64_reg_class classes[MAX_CLASSES];+  char *stack, *argp;+  ffi_type **arg_types;+  int gprcount, ssecount, ngpr, nsse, i, avn, flags;+  struct register_args *reg_args;++  /* Can't call 32-bit mode from 64-bit mode.  */+  FFI_ASSERT (cif->abi == FFI_UNIX64);++  /* If the return value is a struct and we don't have a return value+     address then we need to make one.  Otherwise we can ignore it.  */+  flags = cif->flags;+  if (rvalue == NULL)+    {+      if (flags & UNIX64_FLAG_RET_IN_MEM)+	rvalue = alloca (cif->rtype->size);+      else+	flags = UNIX64_RET_VOID;+    }++  arg_types = cif->arg_types;+  avn = cif->nargs;++  /* Allocate the space for the arguments, plus 4 words of temp space.  */+  stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);+  reg_args = (struct register_args *) stack;+  argp = stack + sizeof (struct register_args);++  reg_args->r10 = (uintptr_t) closure;++  gprcount = ssecount = 0;++  /* If the return value is passed in memory, add the pointer as the+     first integer argument.  */+  if (flags & UNIX64_FLAG_RET_IN_MEM)+    reg_args->gpr[gprcount++] = (unsigned long) rvalue;++  for (i = 0; i < avn; ++i)+    {+      size_t n, size = arg_types[i]->size;++      n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);+      if (n == 0+	  || gprcount + ngpr > MAX_GPR_REGS+	  || ssecount + nsse > MAX_SSE_REGS)+	{+	  long align = arg_types[i]->alignment;++	  /* Stack arguments are *always* at least 8 byte aligned.  */+	  if (align < 8)+	    align = 8;++          /* Pass this argument in memory.  */+          argp = (void *) FFI_ALIGN (argp, align);+          memcpy (argp, avalue[i], size);++          argp += size;+        }+      else+	{+	  /* The argument is passed entirely in registers.  */+	  char *a = (char *) avalue[i];+	  unsigned int j;++	  for (j = 0; j < n; j++, a += 8, size -= 8)+	    {+	      switch (classes[j])+		{+		case X86_64_NO_CLASS:+		case X86_64_SSEUP_CLASS:+		  break;+		case X86_64_INTEGER_CLASS:+		case X86_64_INTEGERSI_CLASS:+		  /* Sign-extend integer arguments passed in general+		     purpose registers, to cope with the fact that+		     LLVM incorrectly assumes that this will be done+		     (the x86-64 PS ABI does not specify this). */+		  switch (arg_types[i]->type)+		    {+		    case FFI_TYPE_SINT8:+		      reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a);+		      break;+		    case FFI_TYPE_SINT16:+		      reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a);+		      break;+		    case FFI_TYPE_SINT32:+		      reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a);+		      break;+		    default:+		      reg_args->gpr[gprcount] = 0;+		      memcpy (&reg_args->gpr[gprcount], a, size <= 8 ? size : 8);+		    }+		  gprcount++;+		  break;+		case X86_64_SSE_CLASS:+		case X86_64_SSEDF_CLASS:+		  memcpy (&reg_args->sse[ssecount++].i64, a, sizeof(UINT64));+		  break;+		case X86_64_SSESF_CLASS:+		  memcpy (&reg_args->sse[ssecount++].i32, a, sizeof(UINT32));+		  break;+		default:+		  abort();+		}+	    }+	}+    }+  reg_args->rax = ssecount;++  ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),+		   flags, rvalue, fn);+}++#ifndef __ILP32__+extern void+ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);+#endif++void+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_type **arg_types = cif->arg_types;+  int i, nargs = cif->nargs;+  const int max_reg_struct_size = cif->abi == FFI_GNUW64 ? 8 : 16;++  /* If we have any large structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT && size > max_reg_struct_size)+        {+          char *argcopy = alloca (size);+          memcpy (argcopy, avalue[i], size);+          avalue[i] = argcopy;+        }+    }++#ifndef __ILP32__+  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)+    {+      ffi_call_efi64(cif, fn, rvalue, avalue);+      return;+    }+#endif+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++#ifdef FFI_GO_CLOSURES++#ifndef __ILP32__+extern void+ffi_call_go_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue,+		  void **avalue, void *closure);+#endif++void+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+#ifndef __ILP32__+  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)+    {+      ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);+      return;+    }+#endif+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}++#endif /* FFI_GO_CLOSURES */++extern void ffi_closure_unix64(void) FFI_HIDDEN;+extern void ffi_closure_unix64_sse(void) FFI_HIDDEN;+#if defined(FFI_EXEC_STATIC_TRAMP)+extern void ffi_closure_unix64_alt(void) FFI_HIDDEN;+extern void ffi_closure_unix64_sse_alt(void) FFI_HIDDEN;+#endif++#ifndef __ILP32__+extern ffi_status+ffi_prep_closure_loc_efi64(ffi_closure* closure,+			   ffi_cif* cif,+			   void (*fun)(ffi_cif*, void*, void**, void*),+			   void *user_data,+			   void *codeloc);+#endif++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif*, void*, void**, void*),+		      void *user_data,+		      void *codeloc)+{+  static const unsigned char trampoline[24] = {+    /* endbr64 */+    0xf3, 0x0f, 0x1e, 0xfa,+    /* leaq  -0xb(%rip),%r10   # 0x0  */+    0x4c, 0x8d, 0x15, 0xf5, 0xff, 0xff, 0xff,+    /* jmpq  *0x7(%rip)        # 0x18 */+    0xff, 0x25, 0x07, 0x00, 0x00, 0x00,+    /* nopl  0(%rax) */+    0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00+  };+  void (*dest)(void);+  char *tramp = closure->tramp;++#ifndef __ILP32__+  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)+    return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);+#endif+  if (cif->abi != FFI_UNIX64)+    return FFI_BAD_ABI;++  if (cif->flags & UNIX64_FLAG_XMM_ARGS)+    dest = ffi_closure_unix64_sse;+  else+    dest = ffi_closure_unix64;++#if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      if (dest == ffi_closure_unix64_sse)+        dest = ffi_closure_unix64_sse_alt;+      else+        dest = ffi_closure_unix64_alt;+      ffi_tramp_set_parms (closure->ftramp, dest, closure);+      goto out;+    }+#endif++  /* Initialize the dynamic trampoline. */+  memcpy (tramp, trampoline, sizeof(trampoline));+  *(UINT64 *)(tramp + sizeof (trampoline)) = (uintptr_t)dest;++#if defined(FFI_EXEC_STATIC_TRAMP)+out:+#endif+  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++int FFI_HIDDEN+ffi_closure_unix64_inner(ffi_cif *cif,+			 void (*fun)(ffi_cif*, void*, void**, void*),+			 void *user_data,+			 void *rvalue,+			 struct register_args *reg_args,+			 char *argp)+{+  void **avalue;+  ffi_type **arg_types;+  long i, avn;+  int gprcount, ssecount, ngpr, nsse;+  int flags;++  avn = cif->nargs;+  flags = cif->flags;+  avalue = alloca(avn * sizeof(void *));+  gprcount = ssecount = 0;++  if (flags & UNIX64_FLAG_RET_IN_MEM)+    {+      /* On return, %rax will contain the address that was passed+	 by the caller in %rdi.  */+      void *r = (void *)(uintptr_t)reg_args->gpr[gprcount++];+      *(void **)rvalue = r;+      rvalue = r;+      flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);+    }++  arg_types = cif->arg_types;+  for (i = 0; i < avn; ++i)+    {+      enum x86_64_reg_class classes[MAX_CLASSES];+      size_t n;++      n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);+      if (n == 0+	  || gprcount + ngpr > MAX_GPR_REGS+	  || ssecount + nsse > MAX_SSE_REGS)+	{+	  long align = arg_types[i]->alignment;++	  /* Stack arguments are *always* at least 8 byte aligned.  */+	  if (align < 8)+	    align = 8;++	  /* Pass this argument in memory.  */+	  argp = (void *) FFI_ALIGN (argp, align);+	  avalue[i] = argp;+	  argp += arg_types[i]->size;+	}+      /* If the argument is in a single register, or two consecutive+	 integer registers, then we can use that address directly.  */+      else if (n == 1+	       || (n == 2 && !(SSE_CLASS_P (classes[0])+			       || SSE_CLASS_P (classes[1]))))+	{+	  /* The argument is in a single register.  */+	  if (SSE_CLASS_P (classes[0]))+	    {+	      avalue[i] = &reg_args->sse[ssecount];+	      ssecount += n;+	    }+	  else+	    {+	      avalue[i] = &reg_args->gpr[gprcount];+	      gprcount += n;+	    }+	}+      /* Otherwise, allocate space to make them consecutive.  */+      else+	{+	  char *a = alloca (16);+	  unsigned int j;++	  avalue[i] = a;+	  for (j = 0; j < n; j++, a += 8)+	    {+	      if (SSE_CLASS_P (classes[j]))+		memcpy (a, &reg_args->sse[ssecount++], 8);+	      else+		memcpy (a, &reg_args->gpr[gprcount++], 8);+	    }+	}+    }++  /* Invoke the closure.  */+  fun (cif, rvalue, avalue, user_data);++  /* Tell assembly how to perform return type promotions.  */+  return flags;+}++#ifdef FFI_GO_CLOSURES++extern void ffi_go_closure_unix64(void) FFI_HIDDEN;+extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;++#ifndef __ILP32__+extern ffi_status+ffi_prep_go_closure_efi64(ffi_go_closure* closure, ffi_cif* cif,+			  void (*fun)(ffi_cif*, void*, void**, void*));+#endif++ffi_status+ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,+		     void (*fun)(ffi_cif*, void*, void**, void*))+{+#ifndef __ILP32__+  if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)+    return ffi_prep_go_closure_efi64(closure, cif, fun);+#endif+  if (cif->abi != FFI_UNIX64)+    return FFI_BAD_ABI;++  closure->tramp = (cif->flags & UNIX64_FLAG_XMM_ARGS+		    ? ffi_go_closure_unix64_sse+		    : ffi_go_closure_unix64);+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}++#endif /* FFI_GO_CLOSURES */++#if defined(FFI_EXEC_STATIC_TRAMP)+void *+ffi_tramp_arch (size_t *tramp_size, size_t *map_size)+{+  extern void *trampoline_code_table;++  *map_size = UNIX64_TRAMP_MAP_SIZE;+  *tramp_size = UNIX64_TRAMP_SIZE;+  return &trampoline_code_table;+}+#endif++#endif /* __x86_64__ */
+ src/x86/ffitarget.h view
@@ -0,0 +1,164 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2012, 2014, 2018  Anthony Green+                 Copyright (c) 1996-2003, 2010  Red Hat, Inc.+                 Copyright (C) 2008  Free Software Foundation, Inc.++   Target configuration macros for x86 and x86-64.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.++   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++/* ---- System specific configurations ----------------------------------- */++/* For code common to all platforms on x86 and x86_64. */+#define X86_ANY++#if defined (X86_64) && defined (__i386__)+#undef X86_64+#warning ******************************************************+#warning ********** X86 IS DEFINED ****************************+#warning ******************************************************+#define X86+#endif++#ifdef X86_WIN64+#define FFI_SIZEOF_ARG 8+#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */+#endif++#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION+#ifndef _MSC_VER+#define FFI_TARGET_HAS_COMPLEX_TYPE+#endif++/* ---- Generic type definitions ----------------------------------------- */++#ifndef LIBFFI_ASM+#ifdef X86_WIN64+#ifdef _MSC_VER+typedef unsigned __int64       ffi_arg;+typedef __int64                ffi_sarg;+#else+typedef unsigned long long     ffi_arg;+typedef long long              ffi_sarg;+#endif+#else+#if defined __x86_64__ && defined __ILP32__+#define FFI_SIZEOF_ARG 8+#define FFI_SIZEOF_JAVA_RAW  4+typedef unsigned long long     ffi_arg;+typedef long long              ffi_sarg;+#else+typedef unsigned long          ffi_arg;+typedef signed long            ffi_sarg;+#endif+#endif++typedef enum ffi_abi {+#if defined(X86_WIN64)+  FFI_FIRST_ABI = 0,+  FFI_WIN64,            /* sizeof(long double) == 8  - microsoft compilers */+  FFI_GNUW64,           /* sizeof(long double) == 16 - GNU compilers */+  FFI_LAST_ABI,+#ifdef __GNUC__+  FFI_DEFAULT_ABI = FFI_GNUW64+#else+  FFI_DEFAULT_ABI = FFI_WIN64+#endif++#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))+  FFI_FIRST_ABI = 1,+  FFI_UNIX64,+  FFI_WIN64,+  FFI_EFI64 = FFI_WIN64,+  FFI_GNUW64,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_UNIX64++#elif defined(X86_WIN32)+  FFI_FIRST_ABI = 0,+  FFI_SYSV      = 1,+  FFI_STDCALL   = 2,+  FFI_THISCALL  = 3,+  FFI_FASTCALL  = 4,+  FFI_MS_CDECL  = 5,+  FFI_PASCAL    = 6,+  FFI_REGISTER  = 7,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_MS_CDECL+#else+  FFI_FIRST_ABI = 0,+  FFI_SYSV      = 1,+  FFI_THISCALL  = 3,+  FFI_FASTCALL  = 4,+  FFI_STDCALL   = 5,+  FFI_PASCAL    = 6,+  FFI_REGISTER  = 7,+  FFI_MS_CDECL  = 8,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+#endif+} ffi_abi;+#endif++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_GO_CLOSURES 1++#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)+#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)+#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)+#define FFI_TYPE_MS_STRUCT       (FFI_TYPE_LAST + 4)++#if defined (X86_64) || defined(X86_WIN64) \+    || (defined (__x86_64__) && defined (X86_DARWIN))+/* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP+   + 8 bytes of pointer.  */+# define FFI_TRAMPOLINE_SIZE 32+# define FFI_NATIVE_RAW_API 0+#else+/* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused+   bytes.  */+# define FFI_TRAMPOLINE_SIZE 16+# define FFI_NATIVE_RAW_API 1  /* x86 has native raw api support */+#endif++#if !defined(GENERATE_LIBFFI_MAP) && defined(__CET__)+# include <cet.h>+# if (__CET__ & 1) != 0+#   define ENDBR_PRESENT+# endif+# define _CET_NOTRACK notrack+#else+# define _CET_ENDBR+# define _CET_NOTRACK+#endif++#endif
+ src/x86/ffiw64.c view
@@ -0,0 +1,361 @@+/* -----------------------------------------------------------------------+   ffiw64.c - Copyright (c) 2018 Anthony Green+              Copyright (c) 2014 Red Hat, Inc.++   x86 win64 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#if defined(__x86_64__) || defined(_M_AMD64)+#include <ffi.h>+#include <ffi_common.h>+#include <stdlib.h>+#include <stdint.h>+#include <tramp.h>++#ifdef X86_WIN64+#define EFI64(name) name+#else+#define EFI64(name) FFI_HIDDEN name##_efi64+#endif++struct win64_call_frame+{+  UINT64 rbp;		/* 0 */+  UINT64 retaddr;	/* 8 */+  UINT64 fn;		/* 16 */+  UINT64 flags;		/* 24 */+  UINT64 rvalue;	/* 32 */+};++extern void ffi_call_win64 (void *stack, struct win64_call_frame *,+			    void *closure) FFI_HIDDEN;++ffi_status FFI_HIDDEN+EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)+{+  int flags, n;++  switch (cif->abi)+    {+    case FFI_WIN64:+    case FFI_GNUW64:+      break;+    default:+      return FFI_BAD_ABI;+    }++  flags = cif->rtype->type;+  switch (flags)+    {+    default:+      break;+    case FFI_TYPE_LONGDOUBLE:+      /* GCC returns long double values by reference, like a struct */+      if (cif->abi == FFI_GNUW64)+	flags = FFI_TYPE_STRUCT;+      break;+    case FFI_TYPE_COMPLEX:+      flags = FFI_TYPE_STRUCT;+      /* FALLTHRU */+    case FFI_TYPE_STRUCT:+      switch (cif->rtype->size)+	{+	case 8:+	  flags = FFI_TYPE_UINT64;+	  break;+	case 4:+	  flags = FFI_TYPE_SMALL_STRUCT_4B;+	  break;+	case 2:+	  flags = FFI_TYPE_SMALL_STRUCT_2B;+	  break;+	case 1:+	  flags = FFI_TYPE_SMALL_STRUCT_1B;+	  break;+	}+      break;+    }+  cif->flags = flags;++  /* Each argument either fits in a register, an 8 byte slot, or is+     passed by reference with the pointer in the 8 byte slot.  */+  n = cif->nargs;+  n += (flags == FFI_TYPE_STRUCT);+  if (n < 4)+    n = 4;+  cif->bytes = n * 8;++  return FFI_OK;+}++/* We perform some black magic here to use some of the parent's stack frame in+ * ffi_call_win64() that breaks with the MSVC compiler with the /RTCs or /GZ+ * flags.  Disable the 'Stack frame run time error checking' for this function+ * so we don't hit weird exceptions in debug builds. */+#if defined(_MSC_VER)+#pragma runtime_checks("s", off)+#endif+static void+ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,+	      void **avalue, void *closure)+{+  int i, j, n, flags;+  UINT64 *stack;+  size_t rsize;+  struct win64_call_frame *frame;+  ffi_type **arg_types = cif->arg_types;+  int nargs = cif->nargs;++  FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64);++  /* If we have any large structure arguments, make a copy so we are passing+     by value.  */+  for (i = 0; i < nargs; i++)+    {+      ffi_type *at = arg_types[i];+      int size = at->size;+      if (at->type == FFI_TYPE_STRUCT && size > 8)+        {+          char *argcopy = alloca (size);+          memcpy (argcopy, avalue[i], size);+          avalue[i] = argcopy;+        }+    }++  flags = cif->flags;+  rsize = 0;++  /* If we have no return value for a structure, we need to create one.+     Otherwise we can ignore the return type entirely.  */+  if (rvalue == NULL)+    {+      if (flags == FFI_TYPE_STRUCT)+	rsize = cif->rtype->size;+      else+	flags = FFI_TYPE_VOID;+    }++  stack = alloca(cif->bytes + sizeof(struct win64_call_frame) + rsize);+  frame = (struct win64_call_frame *)((char *)stack + cif->bytes);+  if (rsize)+    rvalue = frame + 1;++  frame->fn = (uintptr_t)fn;+  frame->flags = flags;+  frame->rvalue = (uintptr_t)rvalue;++  j = 0;+  if (flags == FFI_TYPE_STRUCT)+    {+      stack[0] = (uintptr_t)rvalue;+      j = 1;+    }++  for (i = 0, n = cif->nargs; i < n; ++i, ++j)+    {+      switch (cif->arg_types[i]->size)+	{+	case 8:+	  stack[j] = *(UINT64 *)avalue[i];+	  break;+	case 4:+	  stack[j] = *(UINT32 *)avalue[i];+	  break;+	case 2:+	  stack[j] = *(UINT16 *)avalue[i];+	  break;+	case 1:+	  stack[j] = *(UINT8 *)avalue[i];+	  break;+	default:+	  stack[j] = (uintptr_t)avalue[i];+	  break;+	}+    }++  ffi_call_win64 (stack, frame, closure);+}+#if defined(_MSC_VER)+#pragma runtime_checks("s", restore)+#endif++void+EFI64(ffi_call)(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)+{+  ffi_call_int (cif, fn, rvalue, avalue, NULL);+}++void+EFI64(ffi_call_go)(ffi_cif *cif, void (*fn)(void), void *rvalue,+	     void **avalue, void *closure)+{+  ffi_call_int (cif, fn, rvalue, avalue, closure);+}+++extern void ffi_closure_win64(void) FFI_HIDDEN;+#if defined(FFI_EXEC_STATIC_TRAMP)+extern void ffi_closure_win64_alt(void) FFI_HIDDEN;+#endif++#ifdef FFI_GO_CLOSURES+extern void ffi_go_closure_win64(void) FFI_HIDDEN;+#endif++ffi_status+EFI64(ffi_prep_closure_loc)(ffi_closure* closure,+		      ffi_cif* cif,+		      void (*fun)(ffi_cif*, void*, void**, void*),+		      void *user_data,+		      void *codeloc MAYBE_UNUSED)+{+  static const unsigned char trampoline[FFI_TRAMPOLINE_SIZE - 8] = {+    /* endbr64 */+    0xf3, 0x0f, 0x1e, 0xfa,+    /* leaq  -0xb(%rip),%r10   # 0x0  */+    0x4c, 0x8d, 0x15, 0xf5, 0xff, 0xff, 0xff,+    /* jmpq  *0x7(%rip)        # 0x18 */+    0xff, 0x25, 0x07, 0x00, 0x00, 0x00,+    /* nopl  0(%rax) */+    0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00+  };+  char *tramp = closure->tramp;++  switch (cif->abi)+    {+    case FFI_WIN64:+    case FFI_GNUW64:+      break;+    default:+      return FFI_BAD_ABI;+    }++#if defined(FFI_EXEC_STATIC_TRAMP)+  if (ffi_tramp_is_present(closure))+    {+      /* Initialize the static trampoline's parameters. */+      ffi_tramp_set_parms (closure->ftramp, ffi_closure_win64_alt, closure);+      goto out;+    }+#endif++  /* Initialize the dynamic trampoline. */+  memcpy (tramp, trampoline, sizeof(trampoline));+  *(UINT64 *)(tramp + sizeof (trampoline)) = (uintptr_t)ffi_closure_win64;++#if defined(FFI_EXEC_STATIC_TRAMP)+out:+#endif+  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;++  return FFI_OK;+}++#ifdef FFI_GO_CLOSURES+ffi_status+EFI64(ffi_prep_go_closure)(ffi_go_closure* closure, ffi_cif* cif,+		     void (*fun)(ffi_cif*, void*, void**, void*))+{+  switch (cif->abi)+    {+    case FFI_WIN64:+    case FFI_GNUW64:+      break;+    default:+      return FFI_BAD_ABI;+    }++  closure->tramp = ffi_go_closure_win64;+  closure->cif = cif;+  closure->fun = fun;++  return FFI_OK;+}+#endif++struct win64_closure_frame+{+  UINT64 rvalue[2];+  UINT64 fargs[4];+  UINT64 retaddr;+  UINT64 args[];+};++/* 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,+			struct win64_closure_frame *frame)+{+  void **avalue;+  void *rvalue;+  int i, n, nreg, flags;++  avalue = alloca(cif->nargs * sizeof(void *));+  rvalue = frame->rvalue;+  nreg = 0;++  /* When returning a structure, the address is in the first argument.+     We must also be prepared to return the same address in eax, so+     install that address in the frame and pretend we return a pointer.  */+  flags = cif->flags;+  if (flags == FFI_TYPE_STRUCT)+    {+      rvalue = (void *)(uintptr_t)frame->args[0];+      frame->rvalue[0] = frame->args[0];+      nreg = 1;+    }++  for (i = 0, n = cif->nargs; i < n; ++i, ++nreg)+    {+      size_t size = cif->arg_types[i]->size;+      size_t type = cif->arg_types[i]->type;+      void *a;++      if (type == FFI_TYPE_DOUBLE || type == FFI_TYPE_FLOAT)+	{+	  if (nreg < 4)+	    a = &frame->fargs[nreg];+	  else+	    a = &frame->args[nreg];+	}+      else if (size == 1 || size == 2 || size == 4 || size == 8)+	a = &frame->args[nreg];+      else+	a = (void *)(uintptr_t)frame->args[nreg];++      avalue[i] = a;+    }++  /* Invoke the closure.  */+  fun (cif, rvalue, avalue, user_data);+  return flags;+}++#endif /* __x86_64__ */
+ src/x86/internal.h view
@@ -0,0 +1,43 @@+#define X86_RET_FLOAT		0+#define X86_RET_DOUBLE		1+#define X86_RET_LDOUBLE		2+#define X86_RET_SINT8		3+#define X86_RET_SINT16		4+#define X86_RET_UINT8		5+#define X86_RET_UINT16		6+#define X86_RET_INT64		7+#define X86_RET_INT32		8+#define X86_RET_VOID		9+#define X86_RET_STRUCTPOP	10+#define X86_RET_STRUCTARG       11+#define X86_RET_STRUCT_1B	12+#define X86_RET_STRUCT_2B	13+#define X86_RET_UNUSED14	14+#define X86_RET_UNUSED15	15++#define X86_RET_TYPE_MASK	15+#define X86_RET_POP_SHIFT	4++#define R_EAX	0+#define R_EDX	1+#define R_ECX	2++#ifdef __PCC__+# define HAVE_FASTCALL 0+#else+# define HAVE_FASTCALL 1+#endif++#if defined(FFI_EXEC_STATIC_TRAMP)+/*+ * For the trampoline code table mapping, a mapping size of 4K (base page size)+ * is chosen.+ */+#define X86_TRAMP_MAP_SHIFT	12+#define X86_TRAMP_MAP_SIZE	(1 << X86_TRAMP_MAP_SHIFT)+#ifdef ENDBR_PRESENT+#define X86_TRAMP_SIZE		44+#else+#define X86_TRAMP_SIZE		40+#endif+#endif
+ src/x86/internal64.h view
@@ -0,0 +1,36 @@+#define UNIX64_RET_VOID		0+#define UNIX64_RET_UINT8	1+#define UNIX64_RET_UINT16	2+#define UNIX64_RET_UINT32	3+#define UNIX64_RET_SINT8	4+#define UNIX64_RET_SINT16	5+#define UNIX64_RET_SINT32	6+#define UNIX64_RET_INT64	7+#define UNIX64_RET_XMM32	8+#define UNIX64_RET_XMM64	9+#define UNIX64_RET_X87		10+#define UNIX64_RET_X87_2	11+#define UNIX64_RET_ST_XMM0_RAX	12+#define UNIX64_RET_ST_RAX_XMM0	13+#define UNIX64_RET_ST_XMM0_XMM1	14+#define UNIX64_RET_ST_RAX_RDX	15++#define UNIX64_RET_LAST		15++#define UNIX64_FLAG_RET_IN_MEM	(1 << 10)+#define UNIX64_FLAG_XMM_ARGS	(1 << 11)+#define UNIX64_SIZE_SHIFT	12++#if defined(FFI_EXEC_STATIC_TRAMP)+/*+ * For the trampoline code table mapping, a mapping size of 4K (base page size)+ * is chosen.+ */+#define UNIX64_TRAMP_MAP_SHIFT	12+#define UNIX64_TRAMP_MAP_SIZE	(1 << UNIX64_TRAMP_MAP_SHIFT)+#ifdef ENDBR_PRESENT+#define UNIX64_TRAMP_SIZE	40+#else+#define UNIX64_TRAMP_SIZE	32+#endif+#endif
+ src/x86/sysv.S view
@@ -0,0 +1,1272 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2017  Anthony Green+          - Copyright (c) 2013  The Written Word, Inc.+          - Copyright (c) 1996,1998,2001-2003,2005,2008,2010  Red Hat, Inc.+   +   X86 Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifdef __i386__+#ifndef _MSC_VER++#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>+#include "internal.h"++#define C2(X, Y)  X ## Y+#define C1(X, Y)  C2(X, Y)+#ifdef __USER_LABEL_PREFIX__+# define C(X)     C1(__USER_LABEL_PREFIX__, X)+#else+# define C(X)     X+#endif++#ifdef X86_DARWIN+# define L(X)     C1(L, X)+#else+# define L(X)     C1(.L, X)+#endif++#ifdef __ELF__+# define ENDF(X)  .type	X,@function; .size X, . - X+#else+# define ENDF(X)+#endif++/* Handle win32 fastcall name mangling.  */+#ifdef X86_WIN32+# define ffi_call_i386		"@ffi_call_i386@8"+# define ffi_closure_inner	"@ffi_closure_inner@8"+#else+# define ffi_call_i386		C(ffi_call_i386)+# define ffi_closure_inner	C(ffi_closure_inner)+#endif++/* 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+	.balign	16+	.globl	ffi_call_i386+	FFI_HIDDEN(ffi_call_i386)++/* This is declared as++   void ffi_call_i386(struct call_frame *frame, char *argp)+        __attribute__((fastcall));++   Thus the arguments are present in++        ecx: frame+        edx: argp+*/++ffi_call_i386:+L(UW0):+	# cfi_startproc+	_CET_ENDBR+#if !HAVE_FASTCALL+	movl	4(%esp), %ecx+	movl	8(%esp), %edx+#endif+	movl	(%esp), %eax		/* move the return address */+	movl	%ebp, (%ecx)		/* store %ebp into local frame */+	movl	%eax, 4(%ecx)		/* store retaddr into local frame */++	/* New stack frame based off ebp.  This is a itty bit of unwind+	   trickery in that the CFA *has* changed.  There is no easy way+	   to describe it correctly on entry to the function.  Fortunately,+	   it doesn't matter too much since at all points we can correctly+	   unwind back to ffi_call.  Note that the location to which we+	   moved the return address is (the new) CFA-4, so from the+	   perspective of the unwind info, it hasn't moved.  */+	movl	%ecx, %ebp+L(UW1):+	# cfi_def_cfa(%ebp, 8)+	# cfi_rel_offset(%ebp, 0)++	movl	%edx, %esp		/* set outgoing argument stack */+	movl	20+R_EAX*4(%ebp), %eax	/* set register arguments */+	movl	20+R_EDX*4(%ebp), %edx+	movl	20+R_ECX*4(%ebp), %ecx++	call	*8(%ebp)++	movl	12(%ebp), %ecx		/* load return type code */+	movl	%ebx, 8(%ebp)		/* preserve %ebx */+L(UW2):+	# cfi_rel_offset(%ebx, 8)++	andl	$X86_RET_TYPE_MASK, %ecx+#ifdef __PIC__+	call	C(__x86.get_pc_thunk.bx)+L(pc1):+	leal	L(store_table)-L(pc1)(%ebx, %ecx, 8), %ebx+#else+	leal	L(store_table)(,%ecx, 8), %ebx+#endif+	movl	16(%ebp), %ecx		/* load result address */+	_CET_NOTRACK jmp *%ebx++	.balign	8+L(store_table):+E(L(store_table), X86_RET_FLOAT)+	fstps	(%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_DOUBLE)+	fstpl	(%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_LDOUBLE)+	fstpt	(%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_SINT8)+	movsbl	%al, %eax+	mov	%eax, (%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_SINT16)+	movswl	%ax, %eax+	mov	%eax, (%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_UINT8)+	movzbl	%al, %eax+	mov	%eax, (%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_UINT16)+	movzwl	%ax, %eax+	mov	%eax, (%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_INT64)+	movl	%edx, 4(%ecx)+	/* fallthru */+E(L(store_table), X86_RET_INT32)+	movl	%eax, (%ecx)+	/* fallthru */+E(L(store_table), X86_RET_VOID)+L(e1):+	movl	8(%ebp), %ebx+	movl	%ebp, %esp+	popl	%ebp+L(UW3):+	# cfi_remember_state+	# cfi_def_cfa(%esp, 4)+	# cfi_restore(%ebx)+	# cfi_restore(%ebp)+	ret+L(UW4):+	# cfi_restore_state++E(L(store_table), X86_RET_STRUCTPOP)+	jmp	L(e1)+E(L(store_table), X86_RET_STRUCTARG)+	jmp	L(e1)+E(L(store_table), X86_RET_STRUCT_1B)+	movb	%al, (%ecx)+	jmp	L(e1)+E(L(store_table), X86_RET_STRUCT_2B)+	movw	%ax, (%ecx)+	jmp	L(e1)++	/* Fill out the table so that bad values are predictable.  */+E(L(store_table), X86_RET_UNUSED14)+	ud2+E(L(store_table), X86_RET_UNUSED15)+	ud2++L(UW5):+	# cfi_endproc+ENDF(ffi_call_i386)++/* The inner helper is declared as++   void ffi_closure_inner(struct closure_frame *frame, char *argp)+	__attribute_((fastcall))++   Thus the arguments are placed in++	ecx:	frame+	edx:	argp+*/++/* Macros to help setting up the closure_data structure.  */++#if HAVE_FASTCALL+# define closure_FS	(40 + 4)+# define closure_CF	0+#else+# define closure_FS	(8 + 40 + 12)+# define closure_CF	8+#endif++#define FFI_CLOSURE_SAVE_REGS		\+	movl	%eax, closure_CF+16+R_EAX*4(%esp);	\+	movl	%edx, closure_CF+16+R_EDX*4(%esp);	\+	movl	%ecx, closure_CF+16+R_ECX*4(%esp)++#define FFI_CLOSURE_COPY_TRAMP_DATA					\+	movl	FFI_TRAMPOLINE_SIZE(%eax), %edx;	/* copy cif */	\+	movl	FFI_TRAMPOLINE_SIZE+4(%eax), %ecx;	/* copy fun */	\+	movl	FFI_TRAMPOLINE_SIZE+8(%eax), %eax;	/* copy user_data */ \+	movl	%edx, closure_CF+28(%esp);				\+	movl	%ecx, closure_CF+32(%esp);				\+	movl	%eax, closure_CF+36(%esp)++#if HAVE_FASTCALL+# define FFI_CLOSURE_PREP_CALL						\+	movl	%esp, %ecx;			/* load closure_data */	\+	leal	closure_FS+4(%esp), %edx;	/* load incoming stack */+#else+# define FFI_CLOSURE_PREP_CALL						\+	leal	closure_CF(%esp), %ecx;		/* load closure_data */	\+	leal	closure_FS+4(%esp), %edx;	/* load incoming stack */ \+	movl	%ecx, (%esp);						\+	movl	%edx, 4(%esp)+#endif++#define FFI_CLOSURE_CALL_INNER(UWN) \+	call	ffi_closure_inner++#define FFI_CLOSURE_MASK_AND_JUMP(N, UW)				\+	andl	$X86_RET_TYPE_MASK, %eax;				\+	leal	L(C1(load_table,N))(, %eax, 8), %edx;			\+	movl	closure_CF(%esp), %eax;		/* optimiztic load */	\+	_CET_NOTRACK jmp *%edx++#ifdef __PIC__+# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE+#  undef FFI_CLOSURE_MASK_AND_JUMP+#  define FFI_CLOSURE_MASK_AND_JUMP(N, UW)				\+	andl	$X86_RET_TYPE_MASK, %eax;				\+	call	C(__x86.get_pc_thunk.dx);				\+L(C1(pc,N)):								\+	leal	L(C1(load_table,N))-L(C1(pc,N))(%edx, %eax, 8), %edx;	\+	movl	closure_CF(%esp), %eax;		/* optimiztic load */	\+	_CET_NOTRACK jmp *%edx+# else+#  define FFI_CLOSURE_CALL_INNER_SAVE_EBX+#  undef FFI_CLOSURE_CALL_INNER+#  define FFI_CLOSURE_CALL_INNER(UWN)					\+	movl	%ebx, 40(%esp);			/* save ebx */		\+L(C1(UW,UWN)):								\+	/* cfi_rel_offset(%ebx, 40); */					\+	call	C(__x86.get_pc_thunk.bx);	/* load got register */	\+	addl	$C(_GLOBAL_OFFSET_TABLE_), %ebx;			\+	call	ffi_closure_inner@PLT+#  undef FFI_CLOSURE_MASK_AND_JUMP+#  define FFI_CLOSURE_MASK_AND_JUMP(N, UWN)				\+	andl	$X86_RET_TYPE_MASK, %eax;				\+	leal	L(C1(load_table,N))@GOTOFF(%ebx, %eax, 8), %edx;	\+	movl	40(%esp), %ebx;			/* restore ebx */	\+L(C1(UW,UWN)):								\+	/* cfi_restore(%ebx); */					\+	movl	closure_CF(%esp), %eax;		/* optimiztic load */	\+	_CET_NOTRACK jmp *%edx+# endif /* DARWIN || HIDDEN */+#endif /* __PIC__ */++	.balign	16+	.globl	C(ffi_go_closure_EAX)+	FFI_HIDDEN(C(ffi_go_closure_EAX))+C(ffi_go_closure_EAX):+L(UW6):+	# cfi_startproc+	_CET_ENDBR+	subl	$closure_FS, %esp+L(UW7):+	# cfi_def_cfa_offset(closure_FS + 4)+	FFI_CLOSURE_SAVE_REGS+	movl	4(%eax), %edx			/* copy cif */+	movl	8(%eax), %ecx			/* copy fun */+	movl	%edx, closure_CF+28(%esp)+	movl	%ecx, closure_CF+32(%esp)+	movl	%eax, closure_CF+36(%esp)	/* closure is user_data */+	jmp	L(do_closure_i386)+L(UW8):+	# cfi_endproc+ENDF(C(ffi_go_closure_EAX))++	.balign	16+	.globl	C(ffi_go_closure_ECX)+	FFI_HIDDEN(C(ffi_go_closure_ECX))+C(ffi_go_closure_ECX):+L(UW9):+	# cfi_startproc+	_CET_ENDBR+	subl	$closure_FS, %esp+L(UW10):+	# cfi_def_cfa_offset(closure_FS + 4)+	FFI_CLOSURE_SAVE_REGS+	movl	4(%ecx), %edx			/* copy cif */+	movl	8(%ecx), %eax			/* copy fun */+	movl	%edx, closure_CF+28(%esp)+	movl	%eax, closure_CF+32(%esp)+	movl	%ecx, closure_CF+36(%esp)	/* closure is user_data */+	jmp	L(do_closure_i386)+L(UW11):+	# cfi_endproc+ENDF(C(ffi_go_closure_ECX))++/* The closure entry points are reached from the ffi_closure trampoline.+   On entry, %eax contains the address of the ffi_closure.  */++	.balign	16+	.globl	C(ffi_closure_i386)+	FFI_HIDDEN(C(ffi_closure_i386))++C(ffi_closure_i386):+L(UW12):+	# cfi_startproc+	_CET_ENDBR+	subl	$closure_FS, %esp+L(UW13):+	# cfi_def_cfa_offset(closure_FS + 4)++	FFI_CLOSURE_SAVE_REGS+	FFI_CLOSURE_COPY_TRAMP_DATA++	/* Entry point from preceeding Go closures.  */+L(do_closure_i386):++	FFI_CLOSURE_PREP_CALL+	FFI_CLOSURE_CALL_INNER(14)+	FFI_CLOSURE_MASK_AND_JUMP(2, 15)++	.balign	8+L(load_table2):+E(L(load_table2), X86_RET_FLOAT)+	flds	closure_CF(%esp)+	jmp	L(e2)+E(L(load_table2), X86_RET_DOUBLE)+	fldl	closure_CF(%esp)+	jmp	L(e2)+E(L(load_table2), X86_RET_LDOUBLE)+	fldt	closure_CF(%esp)+	jmp	L(e2)+E(L(load_table2), X86_RET_SINT8)+	movsbl	%al, %eax+	jmp	L(e2)+E(L(load_table2), X86_RET_SINT16)+	movswl	%ax, %eax+	jmp	L(e2)+E(L(load_table2), X86_RET_UINT8)+	movzbl	%al, %eax+	jmp	L(e2)+E(L(load_table2), X86_RET_UINT16)+	movzwl	%ax, %eax+	jmp	L(e2)+E(L(load_table2), X86_RET_INT64)+	movl	closure_CF+4(%esp), %edx+	jmp	L(e2)+E(L(load_table2), X86_RET_INT32)+	nop+	/* fallthru */+E(L(load_table2), X86_RET_VOID)+L(e2):+	addl	$closure_FS, %esp+L(UW16):+	# cfi_adjust_cfa_offset(-closure_FS)+	ret+L(UW17):+	# cfi_adjust_cfa_offset(closure_FS)+E(L(load_table2), X86_RET_STRUCTPOP)+	addl	$closure_FS, %esp+L(UW18):+	# cfi_adjust_cfa_offset(-closure_FS)+	ret	$4+L(UW19):+	# cfi_adjust_cfa_offset(closure_FS)+E(L(load_table2), X86_RET_STRUCTARG)+	jmp	L(e2)+E(L(load_table2), X86_RET_STRUCT_1B)+	movzbl	%al, %eax+	jmp	L(e2)+E(L(load_table2), X86_RET_STRUCT_2B)+	movzwl	%ax, %eax+	jmp	L(e2)++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table2), X86_RET_UNUSED14)+	ud2+E(L(load_table2), X86_RET_UNUSED15)+	ud2++L(UW20):+	# cfi_endproc+ENDF(C(ffi_closure_i386))++	.balign	16+	.globl	C(ffi_go_closure_STDCALL)+	FFI_HIDDEN(C(ffi_go_closure_STDCALL))+C(ffi_go_closure_STDCALL):+L(UW21):+	# cfi_startproc+	_CET_ENDBR+	subl	$closure_FS, %esp+L(UW22):+	# cfi_def_cfa_offset(closure_FS + 4)+	FFI_CLOSURE_SAVE_REGS+	movl	4(%ecx), %edx			/* copy cif */+	movl	8(%ecx), %eax			/* copy fun */+	movl	%edx, closure_CF+28(%esp)+	movl	%eax, closure_CF+32(%esp)+	movl	%ecx, closure_CF+36(%esp)	/* closure is user_data */+	jmp	L(do_closure_STDCALL)+L(UW23):+	# cfi_endproc+ENDF(C(ffi_go_closure_STDCALL))++/* For REGISTER, we have no available parameter registers, and so we+   enter here having pushed the closure onto the stack.  */++	.balign	16+	.globl	C(ffi_closure_REGISTER)+	FFI_HIDDEN(C(ffi_closure_REGISTER))+C(ffi_closure_REGISTER):+L(UW24):+	# cfi_startproc+	# cfi_def_cfa(%esp, 8)+	# cfi_offset(%eip, -8)+	_CET_ENDBR+	subl	$closure_FS-4, %esp+L(UW25):+	# cfi_def_cfa_offset(closure_FS + 4)+	FFI_CLOSURE_SAVE_REGS+	movl	closure_FS-4(%esp), %ecx	/* load retaddr */+	movl	closure_FS(%esp), %eax		/* load closure */+	movl	%ecx, closure_FS(%esp)		/* move retaddr */+	jmp	L(do_closure_REGISTER)+L(UW26):+	# cfi_endproc+ENDF(C(ffi_closure_REGISTER))++/* For STDCALL (and others), we need to pop N bytes of arguments off+   the stack following the closure.  The amount needing to be popped+   is returned to us from ffi_closure_inner.  */++	.balign	16+	.globl	C(ffi_closure_STDCALL)+	FFI_HIDDEN(C(ffi_closure_STDCALL))+C(ffi_closure_STDCALL):+L(UW27):+	# cfi_startproc+	_CET_ENDBR+	subl	$closure_FS, %esp+L(UW28):+	# cfi_def_cfa_offset(closure_FS + 4)++	FFI_CLOSURE_SAVE_REGS++	/* Entry point from ffi_closure_REGISTER.  */+L(do_closure_REGISTER):++	FFI_CLOSURE_COPY_TRAMP_DATA++	/* Entry point from preceeding Go closure.  */+L(do_closure_STDCALL):++	FFI_CLOSURE_PREP_CALL+	FFI_CLOSURE_CALL_INNER(29)++	movl	%eax, %ecx+	shrl	$X86_RET_POP_SHIFT, %ecx	/* isolate pop count */+	leal	closure_FS(%esp, %ecx), %ecx	/* compute popped esp */+	movl	closure_FS(%esp), %edx		/* move return address */+	movl	%edx, (%ecx)++	/* From this point on, the value of %esp upon return is %ecx+4,+	   and we've copied the return address to %ecx to make return easy.+	   There's no point in representing this in the unwind info, as+	   there is always a window between the mov and the ret which+	   will be wrong from one point of view or another.  */++	FFI_CLOSURE_MASK_AND_JUMP(3, 30)++	.balign	8+L(load_table3):+E(L(load_table3), X86_RET_FLOAT)+	flds    closure_CF(%esp)+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_DOUBLE)+	fldl    closure_CF(%esp)+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_LDOUBLE)+	fldt    closure_CF(%esp)+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_SINT8)+	movsbl  %al, %eax+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_SINT16)+	movswl  %ax, %eax+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_UINT8)+	movzbl  %al, %eax+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_UINT16)+	movzwl  %ax, %eax+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_INT64)+	movl	closure_CF+4(%esp), %edx+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_INT32)+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_VOID)+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_STRUCTPOP)+	movl    %ecx, %esp+	ret+E(L(load_table3), X86_RET_STRUCTARG)+	movl	%ecx, %esp+	ret+E(L(load_table3), X86_RET_STRUCT_1B)+	movzbl	%al, %eax+	movl	%ecx, %esp+	ret+E(L(load_table3), X86_RET_STRUCT_2B)+	movzwl	%ax, %eax+	movl	%ecx, %esp+	ret++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table3), X86_RET_UNUSED14)+	ud2+E(L(load_table3), X86_RET_UNUSED15)+	ud2++L(UW31):+	# cfi_endproc+ENDF(C(ffi_closure_STDCALL))++#if defined(FFI_EXEC_STATIC_TRAMP)+	.balign	16+	.globl	C(ffi_closure_i386_alt)+	FFI_HIDDEN(C(ffi_closure_i386_alt))+C(ffi_closure_i386_alt):+	/* See the comments above trampoline_code_table. */+	_CET_ENDBR+	movl	4(%esp), %eax			/* Load closure in eax */+	add	$8, %esp			/* Restore the stack */+	jmp	C(ffi_closure_i386)+ENDF(C(ffi_closure_i386_alt))++	.balign	16+	.globl	C(ffi_closure_REGISTER_alt)+	FFI_HIDDEN(C(ffi_closure_REGISTER_alt))+C(ffi_closure_REGISTER_alt):+	/* See the comments above trampoline_code_table. */+	_CET_ENDBR+	movl	(%esp), %eax			/* Restore eax */+	add	$4, %esp			/* Leave closure on stack */+	jmp	C(ffi_closure_REGISTER)+ENDF(C(ffi_closure_REGISTER_alt))++	.balign	16+	.globl	C(ffi_closure_STDCALL_alt)+	FFI_HIDDEN(C(ffi_closure_STDCALL_alt))+C(ffi_closure_STDCALL_alt):+	/* See the comments above trampoline_code_table. */+	_CET_ENDBR+	movl	4(%esp), %eax			/* Load closure in eax */+	add	$8, %esp			/* Restore the stack */+	jmp	C(ffi_closure_STDCALL)+ENDF(C(ffi_closure_STDCALL_alt))++/*+ * Below is the definition of the trampoline code table. Each element in+ * the code table is a trampoline.+ *+ * Because we jump to the trampoline, we place a _CET_ENDBR at the+ * beginning of the trampoline to mark it as a valid branch target. This is+ * part of the the Intel CET (Control Flow Enforcement Technology).+ */+/*+ * The trampoline uses register eax.  It saves the original value of eax on+ * the stack.+ *+ * The trampoline has two parameters - target code to jump to and data for+ * the target code. The trampoline extracts the parameters from its parameter+ * block (see tramp_table_map()). The trampoline saves the data address on+ * the stack. Finally, it jumps to the target code.+ *+ * The target code can choose to:+ *+ * - restore the value of eax+ * - load the data address in a register+ * - restore the stack pointer to what it was when the trampoline was invoked.+ */+#ifdef ENDBR_PRESENT+#define X86_DATA_OFFSET		4081+#define X86_CODE_OFFSET		4070+#else+#define X86_DATA_OFFSET		4085+#define X86_CODE_OFFSET		4074+#endif++	.align	X86_TRAMP_MAP_SIZE+	.globl	C(trampoline_code_table)+	FFI_HIDDEN(C(trampoline_code_table))+C(trampoline_code_table):+	.rept	X86_TRAMP_MAP_SIZE / X86_TRAMP_SIZE+	_CET_ENDBR+	sub	$8, %esp+	movl	%eax, (%esp)			/* Save %eax on stack */+	call	1f				/* Get next PC into %eax */+	movl	X86_DATA_OFFSET(%eax), %eax	/* Copy data into %eax */+	movl	%eax, 4(%esp)			/* Save data on stack */+	call	1f				/* Get next PC into %eax */+	movl	X86_CODE_OFFSET(%eax), %eax	/* Copy code into %eax */+	jmp	*%eax				/* Jump to code */+1:+	mov	(%esp), %eax+	ret+	.align	4+	.endr+ENDF(C(trampoline_code_table))+	.align	X86_TRAMP_MAP_SIZE+#endif /* FFI_EXEC_STATIC_TRAMP */++#if !FFI_NO_RAW_API++#define raw_closure_S_FS	(16+16+12)++	.balign	16+	.globl	C(ffi_closure_raw_SYSV)+	FFI_HIDDEN(C(ffi_closure_raw_SYSV))+C(ffi_closure_raw_SYSV):+L(UW32):+	# cfi_startproc+	_CET_ENDBR+	subl	$raw_closure_S_FS, %esp+L(UW33):+	# cfi_def_cfa_offset(raw_closure_S_FS + 4)+	movl	%ebx, raw_closure_S_FS-4(%esp)+L(UW34):+	# cfi_rel_offset(%ebx, raw_closure_S_FS-4)++	movl	FFI_TRAMPOLINE_SIZE+8(%eax), %edx	/* load cl->user_data */+	movl	%edx, 12(%esp)+	leal	raw_closure_S_FS+4(%esp), %edx		/* load raw_args */+	movl	%edx, 8(%esp)+	leal	16(%esp), %edx				/* load &res */+	movl	%edx, 4(%esp)+	movl	FFI_TRAMPOLINE_SIZE(%eax), %ebx		/* load cl->cif */+	movl	%ebx, (%esp)+	call	*FFI_TRAMPOLINE_SIZE+4(%eax)		/* call cl->fun */++	movl	20(%ebx), %eax				/* load cif->flags */+	andl	$X86_RET_TYPE_MASK, %eax+#ifdef __PIC__+	call	C(__x86.get_pc_thunk.bx)+L(pc4):+	leal	L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx+#else+	leal	L(load_table4)(,%eax, 8), %ecx+#endif+	movl	raw_closure_S_FS-4(%esp), %ebx+L(UW35):+	# cfi_restore(%ebx)+	movl	16(%esp), %eax				/* Optimistic load */+	jmp	*%ecx++	.balign	8+L(load_table4):+E(L(load_table4), X86_RET_FLOAT)+	flds	16(%esp)+	jmp	L(e4)+E(L(load_table4), X86_RET_DOUBLE)+	fldl	16(%esp)+	jmp	L(e4)+E(L(load_table4), X86_RET_LDOUBLE)+	fldt	16(%esp)+	jmp	L(e4)+E(L(load_table4), X86_RET_SINT8)+	movsbl	%al, %eax+	jmp	L(e4)+E(L(load_table4), X86_RET_SINT16)+	movswl	%ax, %eax+	jmp	L(e4)+E(L(load_table4), X86_RET_UINT8)+	movzbl	%al, %eax+	jmp	L(e4)+E(L(load_table4), X86_RET_UINT16)+	movzwl	%ax, %eax+	jmp	L(e4)+E(L(load_table4), X86_RET_INT64)+	movl	16+4(%esp), %edx+	jmp	L(e4)+E(L(load_table4), X86_RET_INT32)+	nop+	/* fallthru */+E(L(load_table4), X86_RET_VOID)+L(e4):+	addl	$raw_closure_S_FS, %esp+L(UW36):+	# cfi_adjust_cfa_offset(-raw_closure_S_FS)+	ret+L(UW37):+	# cfi_adjust_cfa_offset(raw_closure_S_FS)+E(L(load_table4), X86_RET_STRUCTPOP)+	addl	$raw_closure_S_FS, %esp+L(UW38):+	# cfi_adjust_cfa_offset(-raw_closure_S_FS)+	ret	$4+L(UW39):+	# cfi_adjust_cfa_offset(raw_closure_S_FS)+E(L(load_table4), X86_RET_STRUCTARG)+	jmp	L(e4)+E(L(load_table4), X86_RET_STRUCT_1B)+	movzbl	%al, %eax+	jmp	L(e4)+E(L(load_table4), X86_RET_STRUCT_2B)+	movzwl	%ax, %eax+	jmp	L(e4)++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table4), X86_RET_UNUSED14)+	ud2+E(L(load_table4), X86_RET_UNUSED15)+	ud2++L(UW40):+	# cfi_endproc+ENDF(C(ffi_closure_raw_SYSV))++#define raw_closure_T_FS	(16+16+8)++	.balign	16+	.globl	C(ffi_closure_raw_THISCALL)+	FFI_HIDDEN(C(ffi_closure_raw_THISCALL))+C(ffi_closure_raw_THISCALL):+L(UW41):+	# cfi_startproc+	_CET_ENDBR+	/* Rearrange the stack such that %ecx is the first argument.+	   This means moving the return address.  */+	popl	%edx+L(UW42):+	# cfi_def_cfa_offset(0)+	# cfi_register(%eip, %edx)+	pushl	%ecx+L(UW43):+	# cfi_adjust_cfa_offset(4)+	pushl	%edx+L(UW44):+	# cfi_adjust_cfa_offset(4)+	# cfi_rel_offset(%eip, 0)+	subl	$raw_closure_T_FS, %esp+L(UW45):+	# cfi_adjust_cfa_offset(raw_closure_T_FS)+	movl	%ebx, raw_closure_T_FS-4(%esp)+L(UW46):+	# cfi_rel_offset(%ebx, raw_closure_T_FS-4)++	movl	FFI_TRAMPOLINE_SIZE+8(%eax), %edx	/* load cl->user_data */+	movl	%edx, 12(%esp)+	leal	raw_closure_T_FS+4(%esp), %edx		/* load raw_args */+	movl	%edx, 8(%esp)+	leal	16(%esp), %edx				/* load &res */+	movl	%edx, 4(%esp)+	movl	FFI_TRAMPOLINE_SIZE(%eax), %ebx		/* load cl->cif */+	movl	%ebx, (%esp)+	call	*FFI_TRAMPOLINE_SIZE+4(%eax)		/* call cl->fun */++	movl	20(%ebx), %eax				/* load cif->flags */+	andl	$X86_RET_TYPE_MASK, %eax+#ifdef __PIC__+	call	C(__x86.get_pc_thunk.bx)+L(pc5):+	leal	L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx+#else+	leal	L(load_table5)(,%eax, 8), %ecx+#endif+	movl	raw_closure_T_FS-4(%esp), %ebx+L(UW47):+	# cfi_restore(%ebx)+	movl	16(%esp), %eax				/* Optimistic load */+	jmp	*%ecx++	.balign	8+L(load_table5):+E(L(load_table5), X86_RET_FLOAT)+	flds	16(%esp)+	jmp	L(e5)+E(L(load_table5), X86_RET_DOUBLE)+	fldl	16(%esp)+	jmp	L(e5)+E(L(load_table5), X86_RET_LDOUBLE)+	fldt	16(%esp)+	jmp	L(e5)+E(L(load_table5), X86_RET_SINT8)+	movsbl	%al, %eax+	jmp	L(e5)+E(L(load_table5), X86_RET_SINT16)+	movswl	%ax, %eax+	jmp	L(e5)+E(L(load_table5), X86_RET_UINT8)+	movzbl	%al, %eax+	jmp	L(e5)+E(L(load_table5), X86_RET_UINT16)+	movzwl	%ax, %eax+	jmp	L(e5)+E(L(load_table5), X86_RET_INT64)+	movl	16+4(%esp), %edx+	jmp	L(e5)+E(L(load_table5), X86_RET_INT32)+	nop+	/* fallthru */+E(L(load_table5), X86_RET_VOID)+L(e5):+	addl	$raw_closure_T_FS, %esp+L(UW48):+	# cfi_adjust_cfa_offset(-raw_closure_T_FS)+	/* Remove the extra %ecx argument we pushed.  */+	ret	$4+L(UW49):+	# cfi_adjust_cfa_offset(raw_closure_T_FS)+E(L(load_table5), X86_RET_STRUCTPOP)+	addl	$raw_closure_T_FS, %esp+L(UW50):+	# cfi_adjust_cfa_offset(-raw_closure_T_FS)+	ret	$8+L(UW51):+	# cfi_adjust_cfa_offset(raw_closure_T_FS)+E(L(load_table5), X86_RET_STRUCTARG)+	jmp	L(e5)+E(L(load_table5), X86_RET_STRUCT_1B)+	movzbl	%al, %eax+	jmp	L(e5)+E(L(load_table5), X86_RET_STRUCT_2B)+	movzwl	%ax, %eax+	jmp	L(e5)++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table5), X86_RET_UNUSED14)+	ud2+E(L(load_table5), X86_RET_UNUSED15)+	ud2++L(UW52):+	# cfi_endproc+ENDF(C(ffi_closure_raw_THISCALL))++#endif /* !FFI_NO_RAW_API */++#ifdef X86_DARWIN+/* The linker in use on earlier Darwin needs weak definitions to be+   placed in a coalesced section.  That section should not be called+   __TEXT,__text since that would be re-defining the attributes of the+   .text section (which is an error for earlier tools). Here we use+   '__textcoal_nt' which is what GCC emits for this.+   Later linker versions are happy to use a normal section and, after+   Darwin12 / OSX 10.8, the tools warn that using coalesced sections+   for this is deprecated so we must switch to avoid build fails and/or+   deprecation warnings.  */+# if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) &&		\+   __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1080+#  define COMDAT(X)							\+        .section __TEXT,__textcoal_nt,coalesced,pure_instructions;	\+        .weak_definition X;						\+        FFI_HIDDEN(X)+# else+#  define COMDAT(X)							\+        .text;								\+        .weak_definition X;						\+        FFI_HIDDEN(X)+# endif+#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))+# define COMDAT(X)							\+	.section .text.X,"axG",@progbits,X,comdat;			\+	.globl	X;							\+	FFI_HIDDEN(X)+#else+# define COMDAT(X)+#endif++#if defined(__PIC__)+	COMDAT(C(__x86.get_pc_thunk.bx))+C(__x86.get_pc_thunk.bx):+	movl	(%esp), %ebx+	ret+ENDF(C(__x86.get_pc_thunk.bx))+# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE+	COMDAT(C(__x86.get_pc_thunk.dx))+C(__x86.get_pc_thunk.dx):+	movl	(%esp), %edx+	ret+ENDF(C(__x86.get_pc_thunk.dx))+#endif /* DARWIN || HIDDEN */+#endif /* __PIC__ */++/* Sadly, OSX cctools-as does not understand .cfi directives at all so+   we build an eh frame by hand.  */++#ifdef __APPLE__+/* The cctools assembler will try to make a difference between two local+   symbols into a relocation against, which will not work in the eh (produces+   link-time fails).+   To avoid this, we compute the symbol difference with a .set directive and+   then substitute this value.  */+# define LEN(N, P)	.set Llen$N$P,L(N)-L(P); .long Llen$N$P+/* Note, this assume DW_CFA_advance_loc1 fits into 7 bits.  */+# define ADV(N, P)	.set Ladv$N$P,L(N)-L(P); .byte 2, Ladv$N$P+/* For historical reasons, the EH reg numbers for SP and FP are swapped from+   the DWARF ones for 32b Darwin.  */+# define SP 5+# define FP 4+# define ENC 0x10+#else+# define LEN(N, P)	.long L(N)-L(P)+/* Assume DW_CFA_advance_loc1 fits.  */+# define ADV(N, P)	.byte 2, L(N)-L(P)+# define SP 4+# define FP 5+# define ENC 0x1b+#endif++#ifdef HAVE_AS_X86_PCREL+# define PCREL(X)	X-.+#else+# define PCREL(X)	X@rel+#endif++#ifdef __APPLE__+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support+EHFrame0:+#elif defined(X86_WIN32)+.section .eh_frame,"r"+#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)+.section .eh_frame,EH_FRAME_FLAGS,@unwind+#else+.section .eh_frame,EH_FRAME_FLAGS,@progbits+#endif+#ifndef __APPLE__+/* EH sections are already suitably aligned on Darwin.  */+	.balign 4+#endif++L(CIE):+	.set	L(set0),L(ECIE)-L(SCIE)+	.long	L(set0)			/* CIE Length */+L(SCIE):+	.long	0			/* CIE Identifier Tag */+	.byte	1			/* CIE Version */+	.ascii	"zR\0"			/* CIE Augmentation */+	.byte	1			/* CIE Code Alignment Factor */+	.byte	0x7c			/* CIE Data Alignment Factor */+	.byte	0x8			/* CIE RA Column */+	.byte	1			/* Augmentation size */+	.byte	ENC			/* FDE Encoding (pcrel abs/4byte) */+	.byte	0xc, SP, 4		/* DW_CFA_def_cfa, %esp offset 4 */+	.byte	0x80+8, 1		/* DW_CFA_offset, %eip offset 1*-4 */+	.balign 4+L(ECIE):++	.set	L(set1),L(EFDE1)-L(SFDE1)+	.long	L(set1)			/* FDE Length */+L(SFDE1):+	LEN(SFDE1, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW0))		/* Initial location */+	LEN(UW5, UW0)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW1, UW0)+	.byte	0xc, FP, 8		/* DW_CFA_def_cfa, %ebp 8 */+	.byte	0x80+FP, 2		/* DW_CFA_offset, %ebp 2*-4 */+	ADV(UW2, UW1)+	.byte	0x80+3, 0		/* DW_CFA_offset, %ebx 0*-4 */+	ADV(UW3, UW2)+	.byte	0xa			/* DW_CFA_remember_state */+	.byte	0xc, SP, 4		/* DW_CFA_def_cfa, %esp 4 */+	.byte	0xc0+3			/* DW_CFA_restore, %ebx */+	.byte	0xc0+FP			/* DW_CFA_restore, %ebp */+	ADV(UW4, UW3)+	.byte	0xb			/* DW_CFA_restore_state */+	.balign	4+L(EFDE1):++	.set	L(set2),L(EFDE2)-L(SFDE2)+	.long	L(set2)			/* FDE Length */+L(SFDE2):+	LEN(SFDE2, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW6))		/* Initial location */+	LEN(UW8,UW6)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW7, UW6)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE2):++	.set	L(set3),L(EFDE3)-L(SFDE3)+	.long	L(set3)			/* FDE Length */+L(SFDE3):+	LEN(SFDE3, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW9))		/* Initial location */+	LEN(UW11, UW9)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW10, UW9)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE3):++	.set	L(set4),L(EFDE4)-L(SFDE4)+	.long	L(set4)			/* FDE Length */+L(SFDE4):+	LEN(SFDE4, CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW12))		/* Initial location */+	LEN(UW20, UW12)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW13, UW12)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX+	ADV(UW14, UW13)+	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */+	ADV(UW15, UW14)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+	ADV(UW16, UW15)+#else+	ADV(UW16, UW13)+#endif+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW17, UW16)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	ADV(UW18, UW17)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW19, UW18)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE4):++	.set	L(set5),L(EFDE5)-L(SFDE5)+	.long	L(set5)			/* FDE Length */+L(SFDE5):+	LEN(SFDE5, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW21))		/* Initial location */+	LEN(UW23, UW21)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW22, UW21)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE5):++	.set	L(set6),L(EFDE6)-L(SFDE6)+	.long	L(set6)			/* FDE Length */+L(SFDE6):+	LEN(SFDE6, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW24))		/* Initial location */+	LEN(UW26, UW24)			/* Address range */+	.byte	0			/* Augmentation size */+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	.byte	0x80+8, 2		/* DW_CFA_offset %eip, 2*-4 */+	ADV(UW25, UW24)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE6):++	.set	L(set7),L(EFDE7)-L(SFDE7)+	.long	L(set7)			/* FDE Length */+L(SFDE7):+	LEN(SFDE7, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW27))		/* Initial location */+	LEN(UW31, UW27)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW28, UW27)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX+	ADV(UW29, UW28)+	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */+	ADV(UW30, UW29)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+#endif+	.balign	4+L(EFDE7):+#if !FFI_NO_RAW_API+	.set	L(set8),L(EFDE8)-L(SFDE8)+	.long	L(set8)			/* FDE Length */+L(SFDE8):+	LEN(SFDE8, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW32))		/* Initial location */+	LEN(UW40, UW32)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW33, UW32)+	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */+	ADV(UW34, UW33)+	.byte	0x80+3, 2		/* DW_CFA_offset %ebx 2*-4 */+	ADV(UW35, UW34)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+	ADV(UW36, UW35)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW37, UW36)+	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */+	ADV(UW38, UW37)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW39, UW38)+	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE8):++	.set	L(set9),L(EFDE9)-L(SFDE9)+	.long	L(set9)			/* FDE Length */+L(SFDE9):+	LEN(SFDE9, CIE)			/* FDE CIE offset */+	.long	PCREL(L(UW41))		/* Initial location */+	LEN(UW52, UW41)			/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW42, UW41)+	.byte	0xe, 0			/* DW_CFA_def_cfa_offset */+	.byte	0x9, 8, 2		/* DW_CFA_register %eip, %edx */+	ADV(UW43, UW42)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW44, UW43)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	.byte	0x80+8, 2		/* DW_CFA_offset %eip 2*-4 */+	ADV(UW45, UW44)+	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */+	ADV(UW46, UW45)+	.byte	0x80+3, 3		/* DW_CFA_offset %ebx 3*-4 */+	ADV(UW47, UW46)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+	ADV(UW48, UW47)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	ADV(UW49, UW48)+	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */+	ADV(UW50, UW49)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	ADV(UW51, UW50)+	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE9):+#endif /* !FFI_NO_RAW_API */++#ifdef _WIN32+	.def	 @feat.00;+	.scl	3;+	.type	0;+	.endef+	.globl	@feat.00+@feat.00 = 1+#endif++#if defined(__APPLE__)+    .subsections_via_symbols+# if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) &&		\+   __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070 && __clang__+/* compact unwind is not used with GCC at present, was not present before 10.6+   but has some bugs there, so do not emit until 10.7.  */+    .section __LD,__compact_unwind,regular,debug++    /* compact unwind for ffi_call_i386 */+    .long    C(ffi_call_i386)+    .set     L1,L(UW5)-L(UW0)+    .long    L1+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_go_closure_EAX */+    .long    C(ffi_go_closure_EAX)+    .set     L2,L(UW8)-L(UW6)+    .long    L2+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_go_closure_ECX */+    .long    C(ffi_go_closure_ECX)+    .set     L3,L(UW11)-L(UW9)+    .long    L3+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_closure_i386 */+    .long    C(ffi_closure_i386)+    .set     L4,L(UW20)-L(UW12)+    .long    L4+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_go_closure_STDCALL */+    .long    C(ffi_go_closure_STDCALL)+    .set     L5,L(UW23)-L(UW21)+    .long    L5+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_closure_REGISTER */+    .long    C(ffi_closure_REGISTER)+    .set     L6,L(UW26)-L(UW24)+    .long    L6+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_closure_STDCALL */+    .long    C(ffi_closure_STDCALL)+    .set     L7,L(UW31)-L(UW27)+    .long    L7+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_closure_raw_SYSV */+    .long    C(ffi_closure_raw_SYSV)+    .set     L8,L(UW40)-L(UW32)+    .long    L8+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0++    /* compact unwind for ffi_closure_raw_THISCALL */+    .long    C(ffi_closure_raw_THISCALL)+    .set     L9,L(UW52)-L(UW41)+    .long    L9+    .long    0x04000000 /* use dwarf unwind info */+    .long    0+    .long    0+#endif /* use compact unwind */+#endif /* __APPLE__ */++#endif /* ifndef _MSC_VER */++#endif /* ifdef __i386__ */++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/x86/sysv_intel.S view
@@ -0,0 +1,998 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2017, 2022  Anthony Green+          - Copyright (c) 2013  The Written Word, Inc.+          - Copyright (c) 1996,1998,2001-2003,2005,2008,2010  Red Hat, Inc.++   X86 Foreign Function Interface++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifndef __x86_64__+#ifdef _MSC_VER++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "internal.h"++#define C2(X, Y)  X ## Y+#define C1(X, Y)  C2(X, Y)+#define L(X)     C1(L, X)+# define ENDF(X) X ENDP++/* 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)	ALIGN 8+#else+# define E(BASE, X)	ALIGN 8; ORG BASE + X * 8+#endif++    .686P+    .MODEL FLAT++EXTRN	@ffi_closure_inner@8:PROC+_TEXT SEGMENT++/* This is declared as++   void ffi_call_i386(struct call_frame *frame, char *argp)+        __attribute__((fastcall));++   Thus the arguments are present in++        ecx: frame+        edx: argp+*/++ALIGN 16+PUBLIC @ffi_call_i386@8+@ffi_call_i386@8 PROC+L(UW0):+	cfi_startproc+ #if !HAVE_FASTCALL+	mov	    ecx, [esp+4]+	mov 	edx, [esp+8]+ #endif+	mov	    eax, [esp]		/* move the return address */+	mov	    [ecx], ebp		/* store ebp into local frame */+	mov 	[ecx+4], eax	/* store retaddr into local frame */++	/* New stack frame based off ebp.  This is a itty bit of unwind+	   trickery in that the CFA *has* changed.  There is no easy way+	   to describe it correctly on entry to the function.  Fortunately,+	   it doesn't matter too much since at all points we can correctly+	   unwind back to ffi_call.  Note that the location to which we+	   moved the return address is (the new) CFA-4, so from the+	   perspective of the unwind info, it hasn't moved.  */+	mov 	ebp, ecx+L(UW1):+	/* cfi_def_cfa(%ebp, 8) */+	/* cfi_rel_offset(%ebp, 0) */++	mov 	esp, edx		/* set outgoing argument stack */+	mov 	eax, [20+R_EAX*4+ebp]	/* set register arguments */+	mov 	edx, [20+R_EDX*4+ebp]+	mov	    ecx, [20+R_ECX*4+ebp]++	call	dword ptr [ebp+8]++	mov	    ecx, [12+ebp]		/* load return type code */+	mov 	[ebp+8], ebx		/* preserve %ebx */+L(UW2):+	/* cfi_rel_offset(%ebx, 8) */++	and 	ecx, X86_RET_TYPE_MASK+	lea 	ebx, [L(store_table) + ecx * 8]+	mov 	ecx, [ebp+16]		/* load result address */+	jmp	    ebx++	ALIGN	8+L(store_table):+E(L(store_table), X86_RET_FLOAT)+	fstp	DWORD PTR [ecx]+	jmp	L(e1)+E(L(store_table), X86_RET_DOUBLE)+	fstp	QWORD PTR [ecx]+	jmp	L(e1)+E(L(store_table), X86_RET_LDOUBLE)+	fstp	QWORD PTR [ecx]+	jmp	L(e1)+E(L(store_table), X86_RET_SINT8)+	movsx	eax, al+	mov	[ecx], eax+	jmp	L(e1)+E(L(store_table), X86_RET_SINT16)+	movsx	eax, ax+	mov	[ecx], eax+	jmp	L(e1)+E(L(store_table), X86_RET_UINT8)+	movzx	eax, al+	mov	[ecx], eax+	jmp	L(e1)+E(L(store_table), X86_RET_UINT16)+	movzx	eax, ax+	mov	[ecx], eax+	jmp	L(e1)+E(L(store_table), X86_RET_INT64)+	mov	[ecx+4], edx+	/* fallthru */+E(L(store_table), X86_RET_int 32)+	mov	[ecx], eax+	/* fallthru */+E(L(store_table), X86_RET_VOID)+L(e1):+	mov	    ebx, [ebp+8]+	mov	    esp, ebp+	pop 	ebp+L(UW3):+	/* cfi_remember_state */+	/* cfi_def_cfa(%esp, 4) */+	/* cfi_restore(%ebx) */+	/* cfi_restore(%ebp) */+	ret+L(UW4):+	/* cfi_restore_state */++E(L(store_table), X86_RET_STRUCTPOP)+	jmp	    L(e1)+E(L(store_table), X86_RET_STRUCTARG)+	jmp	    L(e1)+E(L(store_table), X86_RET_STRUCT_1B)+	mov 	[ecx], al+	jmp	    L(e1)+E(L(store_table), X86_RET_STRUCT_2B)+	mov 	[ecx], ax+	jmp	    L(e1)++	/* Fill out the table so that bad values are predictable.  */+E(L(store_table), X86_RET_UNUSED14)+	int 3+E(L(store_table), X86_RET_UNUSED15)+	int 3++L(UW5):+	/* cfi_endproc */+ENDF(@ffi_call_i386@8)++/* The inner helper is declared as++   void ffi_closure_inner(struct closure_frame *frame, char *argp)+	__attribute_((fastcall))++   Thus the arguments are placed in++	ecx:	frame+	edx:	argp+*/++/* Macros to help setting up the closure_data structure.  */++#if HAVE_FASTCALL+# define closure_FS	(40 + 4)+# define closure_CF	0+#else+# define closure_FS	(8 + 40 + 12)+# define closure_CF	8+#endif++FFI_CLOSURE_SAVE_REGS MACRO+	mov 	[esp + closure_CF+16+R_EAX*4], eax+	mov 	[esp + closure_CF+16+R_EDX*4], edx+	mov 	[esp + closure_CF+16+R_ECX*4], ecx+ENDM++FFI_CLOSURE_COPY_TRAMP_DATA MACRO+	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE]      /* copy cif */+	mov 	ecx, [eax+FFI_TRAMPOLINE_SIZE+4]    /* copy fun */+	mov 	eax, [eax+FFI_TRAMPOLINE_SIZE+8];   /* copy user_data */+	mov 	[esp+closure_CF+28], edx+	mov 	[esp+closure_CF+32], ecx+	mov 	[esp+closure_CF+36], eax+ENDM++#if HAVE_FASTCALL+FFI_CLOSURE_PREP_CALL MACRO+	mov	    ecx, esp                    /* load closure_data */+	lea 	edx, [esp+closure_FS+4]     /* load incoming stack */+ENDM+#else+FFI_CLOSURE_PREP_CALL MACRO+	lea 	ecx, [esp+closure_CF]       /* load closure_data */+	lea 	edx, [esp+closure_FS+4]     /* load incoming stack */+	mov 	[esp], ecx+	mov 	[esp+4], edx+ENDM+#endif++FFI_CLOSURE_CALL_INNER MACRO UWN+	call	@ffi_closure_inner@8+ENDM++FFI_CLOSURE_MASK_AND_JUMP MACRO LABEL+	and	    eax, X86_RET_TYPE_MASK+	lea 	edx, [LABEL+eax*8]+	mov 	eax, [esp+closure_CF]       /* optimiztic load */+	jmp	    edx+ENDM++ALIGN 16+PUBLIC ffi_go_closure_EAX+ffi_go_closure_EAX PROC C+L(UW6):+	/* cfi_startproc */+	sub	esp, closure_FS+L(UW7):+	/* cfi_def_cfa_offset(closure_FS + 4) */+	FFI_CLOSURE_SAVE_REGS+	mov     edx, [eax+4]			/* copy cif */+	mov 	ecx, [eax +8]			/* copy fun */+	mov 	[esp+closure_CF+28], edx+	mov 	[esp+closure_CF+32], ecx+	mov 	[esp+closure_CF+36], eax	/* closure is user_data */+	jmp	L(do_closure_i386)+L(UW8):+	/* cfi_endproc */+ENDF(ffi_go_closure_EAX)++ALIGN 16+PUBLIC ffi_go_closure_ECX+ffi_go_closure_ECX PROC C+L(UW9):+	/* cfi_startproc */+	sub 	esp, closure_FS+L(UW10):+	/* cfi_def_cfa_offset(closure_FS + 4) */+	FFI_CLOSURE_SAVE_REGS+	mov 	edx, [ecx+4]			/* copy cif */+	mov 	eax, [ecx+8]			/* copy fun */+	mov 	[esp+closure_CF+28], edx+	mov 	[esp+closure_CF+32], eax+	mov 	[esp+closure_CF+36], ecx	/* closure is user_data */+	jmp	L(do_closure_i386)+L(UW11):+	/* cfi_endproc */+ENDF(ffi_go_closure_ECX)++/* The closure entry points are reached from the ffi_closure trampoline.+   On entry, %eax contains the address of the ffi_closure.  */++ALIGN 16+PUBLIC ffi_closure_i386+ffi_closure_i386 PROC C+L(UW12):+	/* cfi_startproc */+	sub	    esp, closure_FS+L(UW13):+	/* cfi_def_cfa_offset(closure_FS + 4) */++	FFI_CLOSURE_SAVE_REGS+	FFI_CLOSURE_COPY_TRAMP_DATA++	/* Entry point from preceeding Go closures.  */+L(do_closure_i386)::++	FFI_CLOSURE_PREP_CALL+	FFI_CLOSURE_CALL_INNER(14)+	FFI_CLOSURE_MASK_AND_JUMP L(C1(load_table,2))++    ALIGN 8+L(load_table2):+E(L(load_table2), X86_RET_FLOAT)+	fld 	dword ptr [esp+closure_CF]+	jmp	L(e2)+E(L(load_table2), X86_RET_DOUBLE)+	fld 	qword ptr [esp+closure_CF]+	jmp	L(e2)+E(L(load_table2), X86_RET_LDOUBLE)+	fld 	qword ptr [esp+closure_CF]+	jmp	L(e2)+E(L(load_table2), X86_RET_SINT8)+	movsx	eax, al+	jmp	L(e2)+E(L(load_table2), X86_RET_SINT16)+	movsx	eax, ax+	jmp	L(e2)+E(L(load_table2), X86_RET_UINT8)+	movzx	eax, al+	jmp	L(e2)+E(L(load_table2), X86_RET_UINT16)+	movzx	eax, ax+	jmp	L(e2)+E(L(load_table2), X86_RET_INT64)+	mov 	edx, [esp+closure_CF+4]+	jmp	L(e2)+E(L(load_table2), X86_RET_INT32)+	nop+	/* fallthru */+E(L(load_table2), X86_RET_VOID)+L(e2):+	add 	esp, closure_FS+L(UW16):+	/* cfi_adjust_cfa_offset(-closure_FS) */+	ret+L(UW17):+	/* cfi_adjust_cfa_offset(closure_FS) */+E(L(load_table2), X86_RET_STRUCTPOP)+	add 	esp, closure_FS+L(UW18):+	/* cfi_adjust_cfa_offset(-closure_FS) */+	ret	4+L(UW19):+	/* cfi_adjust_cfa_offset(closure_FS) */+E(L(load_table2), X86_RET_STRUCTARG)+	jmp	L(e2)+E(L(load_table2), X86_RET_STRUCT_1B)+	movzx	eax, al+	jmp	L(e2)+E(L(load_table2), X86_RET_STRUCT_2B)+	movzx	eax, ax+	jmp	L(e2)++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table2), X86_RET_UNUSED14)+	int 3+E(L(load_table2), X86_RET_UNUSED15)+	int 3++L(UW20):+	/* cfi_endproc */+ENDF(ffi_closure_i386)++ALIGN 16+PUBLIC	ffi_go_closure_STDCALL+ffi_go_closure_STDCALL PROC C+L(UW21):+	/* cfi_startproc */+	sub 	esp, closure_FS+L(UW22):+	/* cfi_def_cfa_offset(closure_FS + 4) */+	FFI_CLOSURE_SAVE_REGS+	mov 	edx, [ecx+4]			/* copy cif */+	mov 	eax, [ecx+8]			/* copy fun */+	mov 	[esp+closure_CF+28], edx+	mov 	[esp+closure_CF+32], eax+	mov 	[esp+closure_CF+36], ecx	/* closure is user_data */+	jmp	L(do_closure_STDCALL)+L(UW23):+	/* cfi_endproc */+ENDF(ffi_go_closure_STDCALL)++/* For REGISTER, we have no available parameter registers, and so we+   enter here having pushed the closure onto the stack.  */++ALIGN 16+PUBLIC ffi_closure_REGISTER+ffi_closure_REGISTER PROC C+L(UW24):+	/* cfi_startproc */+	/* cfi_def_cfa(%esp, 8) */+	/* cfi_offset(%eip, -8) */+	sub 	esp, closure_FS-4+L(UW25):+	/* cfi_def_cfa_offset(closure_FS + 4) */+	FFI_CLOSURE_SAVE_REGS+	mov	ecx, [esp+closure_FS-4] 	/* load retaddr */+	mov	eax, [esp+closure_FS]		/* load closure */+	mov	[esp+closure_FS], ecx		/* move retaddr */+	jmp	L(do_closure_REGISTER)+L(UW26):+	/* cfi_endproc */+ENDF(ffi_closure_REGISTER)++/* For STDCALL (and others), we need to pop N bytes of arguments off+   the stack following the closure.  The amount needing to be popped+   is returned to us from ffi_closure_inner.  */++ALIGN 16+PUBLIC ffi_closure_STDCALL+ffi_closure_STDCALL PROC C+L(UW27):+	/* cfi_startproc */+	sub 	esp, closure_FS+L(UW28):+	/* cfi_def_cfa_offset(closure_FS + 4) */++	FFI_CLOSURE_SAVE_REGS++	/* Entry point from ffi_closure_REGISTER.  */+L(do_closure_REGISTER)::++	FFI_CLOSURE_COPY_TRAMP_DATA++	/* Entry point from preceeding Go closure.  */+L(do_closure_STDCALL)::++	FFI_CLOSURE_PREP_CALL+	FFI_CLOSURE_CALL_INNER(29)++	mov 	ecx, eax+	shr 	ecx, X86_RET_POP_SHIFT	    /* isolate pop count */+	lea 	ecx, [esp+closure_FS+ecx]	/* compute popped esp */+	mov 	edx, [esp+closure_FS]		/* move return address */+	mov 	[ecx], edx++	/* From this point on, the value of %esp upon return is %ecx+4,+	   and we've copied the return address to %ecx to make return easy.+	   There's no point in representing this in the unwind info, as+	   there is always a window between the mov and the ret which+	   will be wrong from one point of view or another.  */++	FFI_CLOSURE_MASK_AND_JUMP  L(C1(load_table,3))++    ALIGN 8+L(load_table3):+E(L(load_table3), X86_RET_FLOAT)+	fld    DWORD PTR [esp+closure_CF]+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_DOUBLE)+	fld    QWORD PTR [esp+closure_CF]+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_LDOUBLE)+	fld    QWORD PTR [esp+closure_CF]+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_SINT8)+	movsx   eax, al+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_SINT16)+	movsx   eax, ax+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_UINT8)+	movzx   eax, al+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_UINT16)+	movzx   eax, ax+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_INT64)+	mov 	edx, [esp+closure_CF+4]+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_int 32)+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_VOID)+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_STRUCTPOP)+	mov     esp, ecx+	ret+E(L(load_table3), X86_RET_STRUCTARG)+	mov 	esp, ecx+	ret+E(L(load_table3), X86_RET_STRUCT_1B)+	movzx	eax, al+	mov 	esp, ecx+	ret+E(L(load_table3), X86_RET_STRUCT_2B)+	movzx	eax, ax+	mov 	esp, ecx+	ret++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table3), X86_RET_UNUSED14)+	int 3+E(L(load_table3), X86_RET_UNUSED15)+	int 3++L(UW31):+	/* cfi_endproc */+ENDF(ffi_closure_STDCALL)++#if !FFI_NO_RAW_API++#define raw_closure_S_FS	(16+16+12)++ALIGN 16+PUBLIC ffi_closure_raw_SYSV+ffi_closure_raw_SYSV PROC C+L(UW32):+	/* cfi_startproc */+	sub 	esp, raw_closure_S_FS+L(UW33):+	/* cfi_def_cfa_offset(raw_closure_S_FS + 4) */+	mov 	[esp+raw_closure_S_FS-4], ebx+L(UW34):+	/* cfi_rel_offset(%ebx, raw_closure_S_FS-4) */++	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE+8]	/* load cl->user_data */+	mov 	[esp+12], edx+	lea 	edx, [esp+raw_closure_S_FS+4]		/* load raw_args */+	mov 	[esp+8], edx+	lea 	edx, [esp+16]				/* load &res */+	mov 	[esp+4], edx+	mov 	ebx, [eax+FFI_TRAMPOLINE_SIZE]		/* load cl->cif */+	mov 	[esp], ebx+	call	DWORD PTR [eax+FFI_TRAMPOLINE_SIZE+4]		/* call cl->fun */++	mov 	eax, [ebx+20]			/* load cif->flags */+	and 	eax, X86_RET_TYPE_MASK+/* #ifdef __PIC__ */+/* 	call	__x86.get_pc_thunk.bx */+/* L(pc4): */+/* 	lea 	ecx, L(load_table4)-L(pc4)(%ebx, %eax, 8), %ecx */+/* #else */+	lea 	ecx, [L(load_table4)+eax+8]+/* #endif */+	mov 	ebx, [esp+raw_closure_S_FS-4]+L(UW35):+	/* cfi_restore(%ebx) */+	mov 	eax, [esp+16]				/* Optimistic load */+	jmp	    dword ptr [ecx]++	ALIGN 8+L(load_table4):+E(L(load_table4), X86_RET_FLOAT)+	fld 	DWORD PTR [esp +16]+	jmp	L(e4)+E(L(load_table4), X86_RET_DOUBLE)+	fld 	QWORD PTR [esp +16]+	jmp	L(e4)+E(L(load_table4), X86_RET_LDOUBLE)+	fld 	QWORD PTR [esp +16]+	jmp	L(e4)+E(L(load_table4), X86_RET_SINT8)+	movsx	eax, al+	jmp	L(e4)+E(L(load_table4), X86_RET_SINT16)+	movsx	eax, ax+	jmp	L(e4)+E(L(load_table4), X86_RET_UINT8)+	movzx	eax, al+	jmp	L(e4)+E(L(load_table4), X86_RET_UINT16)+	movzx	eax, ax+	jmp	L(e4)+E(L(load_table4), X86_RET_INT64)+	mov 	edx, [esp+16+4]+	jmp	L(e4)+E(L(load_table4), X86_RET_int 32)+	nop+	/* fallthru */+E(L(load_table4), X86_RET_VOID)+L(e4):+	add 	esp, raw_closure_S_FS+L(UW36):+	/* cfi_adjust_cfa_offset(-raw_closure_S_FS) */+	ret+L(UW37):+	/* cfi_adjust_cfa_offset(raw_closure_S_FS) */+E(L(load_table4), X86_RET_STRUCTPOP)+	add 	esp, raw_closure_S_FS+L(UW38):+	/* cfi_adjust_cfa_offset(-raw_closure_S_FS) */+	ret	4+L(UW39):+	/* cfi_adjust_cfa_offset(raw_closure_S_FS) */+E(L(load_table4), X86_RET_STRUCTARG)+	jmp	L(e4)+E(L(load_table4), X86_RET_STRUCT_1B)+	movzx	eax, al+	jmp	L(e4)+E(L(load_table4), X86_RET_STRUCT_2B)+	movzx	eax, ax+	jmp	L(e4)++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table4), X86_RET_UNUSED14)+	int 3+E(L(load_table4), X86_RET_UNUSED15)+	int 3++L(UW40):+	/* cfi_endproc */+ENDF(ffi_closure_raw_SYSV)++#define raw_closure_T_FS	(16+16+8)++ALIGN 16+PUBLIC ffi_closure_raw_THISCALL+ffi_closure_raw_THISCALL PROC C+L(UW41):+	/* cfi_startproc */+	/* Rearrange the stack such that %ecx is the first argument.+	   This means moving the return address.  */+	pop 	edx+L(UW42):+	/* cfi_def_cfa_offset(0) */+	/* cfi_register(%eip, %edx) */+	push	ecx+L(UW43):+	/* cfi_adjust_cfa_offset(4) */+	push 	edx+L(UW44):+	/* cfi_adjust_cfa_offset(4) */+	/* cfi_rel_offset(%eip, 0) */+	sub 	esp, raw_closure_T_FS+L(UW45):+	/* cfi_adjust_cfa_offset(raw_closure_T_FS) */+	mov 	[esp+raw_closure_T_FS-4], ebx+L(UW46):+	/* cfi_rel_offset(%ebx, raw_closure_T_FS-4) */++	mov 	edx, [eax+FFI_TRAMPOLINE_SIZE+8]	/* load cl->user_data */+	mov 	[esp+12], edx+	lea 	edx, [esp+raw_closure_T_FS+4]		/* load raw_args */+	mov 	[esp+8], edx+	lea 	edx, [esp+16]				/* load &res */+	mov 	[esp+4], edx+	mov 	ebx, [eax+FFI_TRAMPOLINE_SIZE]		/* load cl->cif */+	mov 	[esp], ebx+	call	DWORD PTR [eax+FFI_TRAMPOLINE_SIZE+4]		/* call cl->fun */++	mov 	eax, [ebx+20]				/* load cif->flags */+	and 	eax, X86_RET_TYPE_MASK+/* #ifdef __PIC__ */+/* 	call	__x86.get_pc_thunk.bx */+/* L(pc5): */+/* 	leal	L(load_table5)-L(pc5)(%ebx, %eax, 8), %ecx */+/* #else */+	lea 	ecx, [L(load_table5)+eax*8]+/*#endif */+	mov 	ebx, [esp+raw_closure_T_FS-4]+L(UW47):+	/* cfi_restore(%ebx) */+	mov 	eax, [esp+16]				/* Optimistic load */+	jmp	    DWORD PTR [ecx]++	AlIGN 4+L(load_table5):+E(L(load_table5), X86_RET_FLOAT)+	fld	DWORD PTR [esp +16]+	jmp	L(e5)+E(L(load_table5), X86_RET_DOUBLE)+	fld	QWORD PTR [esp +16]+	jmp	L(e5)+E(L(load_table5), X86_RET_LDOUBLE)+	fld	QWORD PTR [esp+16]+	jmp	L(e5)+E(L(load_table5), X86_RET_SINT8)+	movsx	eax, al+	jmp	L(e5)+E(L(load_table5), X86_RET_SINT16)+	movsx	eax, ax+	jmp	L(e5)+E(L(load_table5), X86_RET_UINT8)+	movzx	eax, al+	jmp	L(e5)+E(L(load_table5), X86_RET_UINT16)+	movzx	eax, ax+	jmp	L(e5)+E(L(load_table5), X86_RET_INT64)+	mov 	edx, [esp+16+4]+	jmp	L(e5)+E(L(load_table5), X86_RET_int 32)+	nop+	/* fallthru */+E(L(load_table5), X86_RET_VOID)+L(e5):+	add 	esp, raw_closure_T_FS+L(UW48):+	/* cfi_adjust_cfa_offset(-raw_closure_T_FS) */+	/* Remove the extra %ecx argument we pushed.  */+	ret	4+L(UW49):+	/* cfi_adjust_cfa_offset(raw_closure_T_FS) */+E(L(load_table5), X86_RET_STRUCTPOP)+	add 	esp, raw_closure_T_FS+L(UW50):+	/* cfi_adjust_cfa_offset(-raw_closure_T_FS) */+	ret	8+L(UW51):+	/* cfi_adjust_cfa_offset(raw_closure_T_FS) */+E(L(load_table5), X86_RET_STRUCTARG)+	jmp	L(e5)+E(L(load_table5), X86_RET_STRUCT_1B)+	movzx	eax, al+	jmp	L(e5)+E(L(load_table5), X86_RET_STRUCT_2B)+	movzx	eax, ax+	jmp	L(e5)++	/* Fill out the table so that bad values are predictable.  */+E(L(load_table5), X86_RET_UNUSED14)+	int 3+E(L(load_table5), X86_RET_UNUSED15)+	int 3++L(UW52):+	/* cfi_endproc */+ENDF(ffi_closure_raw_THISCALL)++#endif /* !FFI_NO_RAW_API */++#ifdef X86_DARWIN+# define COMDAT(X)							\+        .section __TEXT,__text,coalesced,pure_instructions;		\+        .weak_definition X;						\+        FFI_HIDDEN(X)+#elif defined __ELF__ && !(defined(__sun__) && defined(__svr4__))+# define COMDAT(X)							\+	.section .text.X,"axG",@progbits,X,comdat;			\+	PUBLIC	X;							\+	FFI_HIDDEN(X)+#else+# define COMDAT(X)+#endif++#if 0+#if defined(__PIC__)+	COMDAT(C(__x86.get_pc_thunk.bx))+C(__x86.get_pc_thunk.bx):+	movl	(%esp), %ebx+	ret+ENDF(C(__x86.get_pc_thunk.bx))+# if defined X86_DARWIN || defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE+	COMDAT(C(__x86.get_pc_thunk.dx))+C(__x86.get_pc_thunk.dx):+	movl	(%esp), %edx+	ret+ENDF(C(__x86.get_pc_thunk.dx))+#endif /* DARWIN || HIDDEN */+#endif /* __PIC__ */+#endif+++#if 0+/* Sadly, OSX cctools-as doesn't understand .cfi directives at all.  */++#ifdef __APPLE__+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support+EHFrame0:+#elif defined(X86_WIN32)+.section .eh_frame,"r"+#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)+.section .eh_frame,EH_FRAME_FLAGS,@unwind+#else+.section .eh_frame,EH_FRAME_FLAGS,@progbits+#endif++#ifdef HAVE_AS_X86_PCREL+# define PCREL(X)	X - .+#else+# define PCREL(X)	X@rel+#endif++/* Simplify advancing between labels.  Assume DW_CFA_advance_loc1 fits.  */+#define ADV(N, P)	.byte 2, L(N)-L(P)++	.balign 4+L(CIE):+	.set	L(set0),L(ECIE)-L(SCIE)+	.long	L(set0)			/* CIE Length */+L(SCIE):+	.long	0			/* CIE Identifier Tag */+	.byte	1			/* CIE Version */+	.ascii	"zR\0"			/* CIE Augmentation */+	.byte	1			/* CIE Code Alignment Factor */+	.byte	0x7c			/* CIE Data Alignment Factor */+	.byte	0x8			/* CIE RA Column */+	.byte	1			/* Augmentation size */+	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */+	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp offset 4 */+	.byte	0x80+8, 1		/* DW_CFA_offset, %eip offset 1*-4 */+	.balign 4+L(ECIE):++	.set	L(set1),L(EFDE1)-L(SFDE1)+	.long	L(set1)			/* FDE Length */+L(SFDE1):+	.long	L(SFDE1)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW0))		/* Initial location */+	.long	L(UW5)-L(UW0)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW1, UW0)+	.byte	0xc, 5, 8		/* DW_CFA_def_cfa, %ebp 8 */+	.byte	0x80+5, 2		/* DW_CFA_offset, %ebp 2*-4 */+	ADV(UW2, UW1)+	.byte	0x80+3, 0		/* DW_CFA_offset, %ebx 0*-4 */+	ADV(UW3, UW2)+	.byte	0xa			/* DW_CFA_remember_state */+	.byte	0xc, 4, 4		/* DW_CFA_def_cfa, %esp 4 */+	.byte	0xc0+3			/* DW_CFA_restore, %ebx */+	.byte	0xc0+5			/* DW_CFA_restore, %ebp */+	ADV(UW4, UW3)+	.byte	0xb			/* DW_CFA_restore_state */+	.balign	4+L(EFDE1):++	.set	L(set2),L(EFDE2)-L(SFDE2)+	.long	L(set2)			/* FDE Length */+L(SFDE2):+	.long	L(SFDE2)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW6))		/* Initial location */+	.long	L(UW8)-L(UW6)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW7, UW6)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE2):++	.set	L(set3),L(EFDE3)-L(SFDE3)+	.long	L(set3)			/* FDE Length */+L(SFDE3):+	.long	L(SFDE3)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW9))		/* Initial location */+	.long	L(UW11)-L(UW9)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW10, UW9)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE3):++	.set	L(set4),L(EFDE4)-L(SFDE4)+	.long	L(set4)			/* FDE Length */+L(SFDE4):+	.long	L(SFDE4)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW12))		/* Initial location */+	.long	L(UW20)-L(UW12)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW13, UW12)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX+	ADV(UW14, UW13)+	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */+	ADV(UW15, UW14)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+	ADV(UW16, UW15)+#else+	ADV(UW16, UW13)+#endif+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW17, UW16)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	ADV(UW18, UW17)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW19, UW18)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE4):++	.set	L(set5),L(EFDE5)-L(SFDE5)+	.long	L(set5)			/* FDE Length */+L(SFDE5):+	.long	L(SFDE5)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW21))		/* Initial location */+	.long	L(UW23)-L(UW21)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW22, UW21)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE5):++	.set	L(set6),L(EFDE6)-L(SFDE6)+	.long	L(set6)			/* FDE Length */+L(SFDE6):+	.long	L(SFDE6)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW24))		/* Initial location */+	.long	L(UW26)-L(UW24)		/* Address range */+	.byte	0			/* Augmentation size */+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	.byte	0x80+8, 2		/* DW_CFA_offset %eip, 2*-4 */+	ADV(UW25, UW24)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE6):++	.set	L(set7),L(EFDE7)-L(SFDE7)+	.long	L(set7)			/* FDE Length */+L(SFDE7):+	.long	L(SFDE7)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW27))		/* Initial location */+	.long	L(UW31)-L(UW27)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW28, UW27)+	.byte	0xe, closure_FS+4	/* DW_CFA_def_cfa_offset */+#ifdef FFI_CLOSURE_CALL_INNER_SAVE_EBX+	ADV(UW29, UW28)+	.byte	0x80+3, (40-(closure_FS+4))/-4  /* DW_CFA_offset %ebx */+	ADV(UW30, UW29)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+#endif+	.balign	4+L(EFDE7):++#if !FFI_NO_RAW_API+	.set	L(set8),L(EFDE8)-L(SFDE8)+	.long	L(set8)			/* FDE Length */+L(SFDE8):+	.long	L(SFDE8)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW32))		/* Initial location */+	.long	L(UW40)-L(UW32)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW33, UW32)+	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */+	ADV(UW34, UW33)+	.byte	0x80+3, 2		/* DW_CFA_offset %ebx 2*-4 */+	ADV(UW35, UW34)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+	ADV(UW36, UW35)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW37, UW36)+	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */+	ADV(UW38, UW37)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW39, UW38)+	.byte	0xe, raw_closure_S_FS+4	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE8):++	.set	L(set9),L(EFDE9)-L(SFDE9)+	.long	L(set9)			/* FDE Length */+L(SFDE9):+	.long	L(SFDE9)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW41))		/* Initial location */+	.long	L(UW52)-L(UW41)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW42, UW41)+	.byte	0xe, 0			/* DW_CFA_def_cfa_offset */+	.byte	0x9, 8, 2		/* DW_CFA_register %eip, %edx */+	ADV(UW43, UW42)+	.byte	0xe, 4			/* DW_CFA_def_cfa_offset */+	ADV(UW44, UW43)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	.byte	0x80+8, 2		/* DW_CFA_offset %eip 2*-4 */+	ADV(UW45, UW44)+	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */+	ADV(UW46, UW45)+	.byte	0x80+3, 3		/* DW_CFA_offset %ebx 3*-4 */+	ADV(UW47, UW46)+	.byte	0xc0+3			/* DW_CFA_restore %ebx */+	ADV(UW48, UW47)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	ADV(UW49, UW48)+	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */+	ADV(UW50, UW49)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset */+	ADV(UW51, UW50)+	.byte	0xe, raw_closure_T_FS+8	/* DW_CFA_def_cfa_offset */+	.balign	4+L(EFDE9):+#endif /* !FFI_NO_RAW_API */++#ifdef _WIN32+	.def	 @feat.00;+	.scl	3;+	.type	0;+	.endef+	PUBLIC	@feat.00+@feat.00 = 1+#endif++#endif /* ifndef _MSC_VER */+#endif /* ifndef __x86_64__ */++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif+#endif++END
+ src/x86/unix64.S view
@@ -0,0 +1,711 @@+/* -----------------------------------------------------------------------+   unix64.S - Copyright (c) 2013  The Written Word, Inc.+	    - Copyright (c) 2008  Red Hat, Inc+	    - Copyright (c) 2002  Bo Thorsen <bo@suse.de>++   x86-64 Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifdef __x86_64__+#define LIBFFI_ASM	+#include <fficonfig.h>+#include <ffi.h>+#include "internal64.h"+#include "asmnames.h"++	.text++/* 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.  */+#ifdef __CET__+/* Double slot size to 16 byte to add 4 bytes of ENDBR64.  */+# define E(BASE, X)	.balign 8; .org BASE + X * 16+#elif 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++/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,+	            void *raddr, void (*fnaddr)(void));++   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame+   for this function.  This has been allocated by ffi_call.  We also+   deallocate some of the stack that has been alloca'd.  */++	.balign	8+	.globl	C(ffi_call_unix64)+	FFI_HIDDEN(C(ffi_call_unix64))++C(ffi_call_unix64):+L(UW0):+	_CET_ENDBR+	movq	(%rsp), %r10		/* Load return address.  */+	leaq	(%rdi, %rsi), %rax	/* Find local stack base.  */+	movq	%rdx, (%rax)		/* Save flags.  */+	movq	%rcx, 8(%rax)		/* Save raddr.  */+	movq	%rbp, 16(%rax)		/* Save old frame pointer.  */+	movq	%r10, 24(%rax)		/* Relocate return address.  */+	movq	%rax, %rbp		/* Finalize local stack frame.  */++	/* New stack frame based off rbp.  This is a itty bit of unwind+	   trickery in that the CFA *has* changed.  There is no easy way+	   to describe it correctly on entry to the function.  Fortunately,+	   it doesn't matter too much since at all points we can correctly+	   unwind back to ffi_call.  Note that the location to which we+	   moved the return address is (the new) CFA-8, so from the+	   perspective of the unwind info, it hasn't moved.  */+L(UW1):+	/* cfi_def_cfa(%rbp, 32) */+	/* cfi_rel_offset(%rbp, 16) */++	movq	%rdi, %r10		/* Save a copy of the register area. */+	movq	%r8, %r11		/* Save a copy of the target fn.  */++	/* Load up all argument registers.  */+	movq	(%r10), %rdi+	movq	0x08(%r10), %rsi+	movq	0x10(%r10), %rdx+	movq	0x18(%r10), %rcx+	movq	0x20(%r10), %r8+	movq	0x28(%r10), %r9+	movl	0xb0(%r10), %eax	/* Set number of SSE registers.  */+	testl	%eax, %eax+	jnz	L(load_sse)+L(ret_from_load_sse):++	/* Deallocate the reg arg area, except for r10, then load via pop.  */+	leaq	0xb8(%r10), %rsp+	popq	%r10++	/* Call the user function.  */+	call	*%r11++	/* Deallocate stack arg area; local stack frame in redzone.  */+	leaq	24(%rbp), %rsp++	movq	0(%rbp), %rcx		/* Reload flags.  */+	movq	8(%rbp), %rdi		/* Reload raddr.  */+	movq	16(%rbp), %rbp		/* Reload old frame pointer.  */+L(UW2):+	/* cfi_remember_state */+	/* cfi_def_cfa(%rsp, 8) */+	/* cfi_restore(%rbp) */++	/* The first byte of the flags contains the FFI_TYPE.  */+	cmpb	$UNIX64_RET_LAST, %cl+	movzbl	%cl, %r10d+	leaq	L(store_table)(%rip), %r11+	ja	L(sa)+#ifdef __CET__+	/* NB: Originally, each slot is 8 byte.  4 bytes of ENDBR64 ++	   4 bytes NOP padding double slot size to 16 bytes.  */+	addl	%r10d, %r10d+#endif+	leaq	(%r11, %r10, 8), %r10++	/* Prep for the structure cases: scratch area in redzone.  */+	leaq	-20(%rsp), %rsi+	jmp	*%r10++	.balign	8+L(store_table):+E(L(store_table), UNIX64_RET_VOID)+	_CET_ENDBR+	ret+E(L(store_table), UNIX64_RET_UINT8)+	_CET_ENDBR+	movzbl	%al, %eax+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_UINT16)+	_CET_ENDBR+	movzwl	%ax, %eax+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_UINT32)+	_CET_ENDBR+	movl	%eax, %eax+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_SINT8)+	_CET_ENDBR+	movsbq	%al, %rax+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_SINT16)+	_CET_ENDBR+	movswq	%ax, %rax+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_SINT32)+	_CET_ENDBR+	cltq+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_INT64)+	_CET_ENDBR+	movq	%rax, (%rdi)+	ret+E(L(store_table), UNIX64_RET_XMM32)+	_CET_ENDBR+	movd	%xmm0, (%rdi)+	ret+E(L(store_table), UNIX64_RET_XMM64)+	_CET_ENDBR+	movq	%xmm0, (%rdi)+	ret+E(L(store_table), UNIX64_RET_X87)+	_CET_ENDBR+	fstpt	(%rdi)+	ret+E(L(store_table), UNIX64_RET_X87_2)+	_CET_ENDBR+	fstpt	(%rdi)+	fstpt	16(%rdi)+	ret+E(L(store_table), UNIX64_RET_ST_XMM0_RAX)+	_CET_ENDBR+	movq	%rax, 8(%rsi)+	jmp	L(s3)+E(L(store_table), UNIX64_RET_ST_RAX_XMM0)+	_CET_ENDBR+	movq	%xmm0, 8(%rsi)+	jmp	L(s2)+E(L(store_table), UNIX64_RET_ST_XMM0_XMM1)+	_CET_ENDBR+	movq	%xmm1, 8(%rsi)+	jmp	L(s3)+E(L(store_table), UNIX64_RET_ST_RAX_RDX)+	_CET_ENDBR+	movq	%rdx, 8(%rsi)+L(s2):+	movq	%rax, (%rsi)+	shrl	$UNIX64_SIZE_SHIFT, %ecx+	rep movsb+	ret+	.balign 8+L(s3):+	movq	%xmm0, (%rsi)+	shrl	$UNIX64_SIZE_SHIFT, %ecx+	rep movsb+	ret++L(sa):	call	PLT(C(abort))++	/* Many times we can avoid loading any SSE registers at all.+	   It's not worth an indirect jump to load the exact set of+	   SSE registers needed; zero or all is a good compromise.  */+	.balign 2+L(UW3):+	/* cfi_restore_state */+L(load_sse):+	movdqa	0x30(%r10), %xmm0+	movdqa	0x40(%r10), %xmm1+	movdqa	0x50(%r10), %xmm2+	movdqa	0x60(%r10), %xmm3+	movdqa	0x70(%r10), %xmm4+	movdqa	0x80(%r10), %xmm5+	movdqa	0x90(%r10), %xmm6+	movdqa	0xa0(%r10), %xmm7+	jmp	L(ret_from_load_sse)++L(UW4):+ENDF(C(ffi_call_unix64))++/* 6 general registers, 8 vector registers,+   32 bytes of rvalue, 8 bytes of alignment.  */+#define ffi_closure_OFS_G	0+#define ffi_closure_OFS_V	(6*8)+#define ffi_closure_OFS_RVALUE	(ffi_closure_OFS_V + 8*16)+#define ffi_closure_FS		(ffi_closure_OFS_RVALUE + 32 + 8)++/* The location of rvalue within the red zone after deallocating the frame.  */+#define ffi_closure_RED_RVALUE	(ffi_closure_OFS_RVALUE - ffi_closure_FS)++	.balign	2+	.globl	C(ffi_closure_unix64_sse)+	FFI_HIDDEN(C(ffi_closure_unix64_sse))++C(ffi_closure_unix64_sse):+L(UW5):+	_CET_ENDBR+	subq	$ffi_closure_FS, %rsp+L(UW6):+	/* cfi_adjust_cfa_offset(ffi_closure_FS) */++	movdqa	%xmm0, ffi_closure_OFS_V+0x00(%rsp)+	movdqa	%xmm1, ffi_closure_OFS_V+0x10(%rsp)+	movdqa	%xmm2, ffi_closure_OFS_V+0x20(%rsp)+	movdqa	%xmm3, ffi_closure_OFS_V+0x30(%rsp)+	movdqa	%xmm4, ffi_closure_OFS_V+0x40(%rsp)+	movdqa	%xmm5, ffi_closure_OFS_V+0x50(%rsp)+	movdqa	%xmm6, ffi_closure_OFS_V+0x60(%rsp)+	movdqa	%xmm7, ffi_closure_OFS_V+0x70(%rsp)+	jmp	L(sse_entry1)++L(UW7):+ENDF(C(ffi_closure_unix64_sse))++	.balign	2+	.globl	C(ffi_closure_unix64)+	FFI_HIDDEN(C(ffi_closure_unix64))++C(ffi_closure_unix64):+L(UW8):+	_CET_ENDBR+	subq	$ffi_closure_FS, %rsp+L(UW9):+	/* cfi_adjust_cfa_offset(ffi_closure_FS) */+L(sse_entry1):+	movq	%rdi, ffi_closure_OFS_G+0x00(%rsp)+	movq    %rsi, ffi_closure_OFS_G+0x08(%rsp)+	movq    %rdx, ffi_closure_OFS_G+0x10(%rsp)+	movq    %rcx, ffi_closure_OFS_G+0x18(%rsp)+	movq    %r8,  ffi_closure_OFS_G+0x20(%rsp)+	movq    %r9,  ffi_closure_OFS_G+0x28(%rsp)++#ifdef __ILP32__+	movl	FFI_TRAMPOLINE_SIZE(%r10), %edi		/* Load cif */+	movl	FFI_TRAMPOLINE_SIZE+4(%r10), %esi	/* Load fun */+	movl	FFI_TRAMPOLINE_SIZE+8(%r10), %edx	/* Load user_data */+#else+	movq	FFI_TRAMPOLINE_SIZE(%r10), %rdi		/* Load cif */+	movq	FFI_TRAMPOLINE_SIZE+8(%r10), %rsi	/* Load fun */+	movq	FFI_TRAMPOLINE_SIZE+16(%r10), %rdx	/* Load user_data */+#endif+L(do_closure):+	leaq	ffi_closure_OFS_RVALUE(%rsp), %rcx	/* Load rvalue */+	movq	%rsp, %r8				/* Load reg_args */+	leaq	ffi_closure_FS+8(%rsp), %r9		/* Load argp */+	call	PLT(C(ffi_closure_unix64_inner))++	/* Deallocate stack frame early; return value is now in redzone.  */+	addq	$ffi_closure_FS, %rsp+L(UW10):+	/* cfi_adjust_cfa_offset(-ffi_closure_FS) */++	/* The first byte of the return value contains the FFI_TYPE.  */+	cmpb	$UNIX64_RET_LAST, %al+	movzbl	%al, %r10d+	leaq	L(load_table)(%rip), %r11+	ja	L(la)+#ifdef __CET__+	/* NB: Originally, each slot is 8 byte.  4 bytes of ENDBR64 ++	   4 bytes NOP padding double slot size to 16 bytes.  */+	addl	%r10d, %r10d+#endif+	leaq	(%r11, %r10, 8), %r10+	leaq	ffi_closure_RED_RVALUE(%rsp), %rsi+	jmp	*%r10++	.balign	8+L(load_table):+E(L(load_table), UNIX64_RET_VOID)+	_CET_ENDBR+	ret+E(L(load_table), UNIX64_RET_UINT8)+	_CET_ENDBR+	movzbl	(%rsi), %eax+	ret+E(L(load_table), UNIX64_RET_UINT16)+	_CET_ENDBR+	movzwl	(%rsi), %eax+	ret+E(L(load_table), UNIX64_RET_UINT32)+	_CET_ENDBR+	movl	(%rsi), %eax+	ret+E(L(load_table), UNIX64_RET_SINT8)+	_CET_ENDBR+	movsbl	(%rsi), %eax+	ret+E(L(load_table), UNIX64_RET_SINT16)+	_CET_ENDBR+	movswl	(%rsi), %eax+	ret+E(L(load_table), UNIX64_RET_SINT32)+	_CET_ENDBR+	movl	(%rsi), %eax+	ret+E(L(load_table), UNIX64_RET_INT64)+	_CET_ENDBR+	movq	(%rsi), %rax+	ret+E(L(load_table), UNIX64_RET_XMM32)+	_CET_ENDBR+	movd	(%rsi), %xmm0+	ret+E(L(load_table), UNIX64_RET_XMM64)+	_CET_ENDBR+	movq	(%rsi), %xmm0+	ret+E(L(load_table), UNIX64_RET_X87)+	_CET_ENDBR+	fldt	(%rsi)+	ret+E(L(load_table), UNIX64_RET_X87_2)+	_CET_ENDBR+	fldt	16(%rsi)+	fldt	(%rsi)+	ret+E(L(load_table), UNIX64_RET_ST_XMM0_RAX)+	_CET_ENDBR+	movq	8(%rsi), %rax+	jmp	L(l3)+E(L(load_table), UNIX64_RET_ST_RAX_XMM0)+	_CET_ENDBR+	movq	8(%rsi), %xmm0+	jmp	L(l2)+E(L(load_table), UNIX64_RET_ST_XMM0_XMM1)+	_CET_ENDBR+	movq	8(%rsi), %xmm1+	jmp	L(l3)+E(L(load_table), UNIX64_RET_ST_RAX_RDX)+	_CET_ENDBR+	movq	8(%rsi), %rdx+L(l2):+	movq	(%rsi), %rax+	ret+	.balign	8+L(l3):+	movq	(%rsi), %xmm0+	ret++L(la):	call	PLT(C(abort))++L(UW11):+ENDF(C(ffi_closure_unix64))++	.balign	2+	.globl	C(ffi_go_closure_unix64_sse)+	FFI_HIDDEN(C(ffi_go_closure_unix64_sse))++C(ffi_go_closure_unix64_sse):+L(UW12):+	_CET_ENDBR+	subq	$ffi_closure_FS, %rsp+L(UW13):+	/* cfi_adjust_cfa_offset(ffi_closure_FS) */++	movdqa	%xmm0, ffi_closure_OFS_V+0x00(%rsp)+	movdqa	%xmm1, ffi_closure_OFS_V+0x10(%rsp)+	movdqa	%xmm2, ffi_closure_OFS_V+0x20(%rsp)+	movdqa	%xmm3, ffi_closure_OFS_V+0x30(%rsp)+	movdqa	%xmm4, ffi_closure_OFS_V+0x40(%rsp)+	movdqa	%xmm5, ffi_closure_OFS_V+0x50(%rsp)+	movdqa	%xmm6, ffi_closure_OFS_V+0x60(%rsp)+	movdqa	%xmm7, ffi_closure_OFS_V+0x70(%rsp)+	jmp	L(sse_entry2)++L(UW14):+ENDF(C(ffi_go_closure_unix64_sse))++	.balign	2+	.globl	C(ffi_go_closure_unix64)+	FFI_HIDDEN(C(ffi_go_closure_unix64))++C(ffi_go_closure_unix64):+L(UW15):+	_CET_ENDBR+	subq	$ffi_closure_FS, %rsp+L(UW16):+	/* cfi_adjust_cfa_offset(ffi_closure_FS) */+L(sse_entry2):+	movq	%rdi, ffi_closure_OFS_G+0x00(%rsp)+	movq    %rsi, ffi_closure_OFS_G+0x08(%rsp)+	movq    %rdx, ffi_closure_OFS_G+0x10(%rsp)+	movq    %rcx, ffi_closure_OFS_G+0x18(%rsp)+	movq    %r8,  ffi_closure_OFS_G+0x20(%rsp)+	movq    %r9,  ffi_closure_OFS_G+0x28(%rsp)++#ifdef __ILP32__+	movl	4(%r10), %edi		/* Load cif */+	movl	8(%r10), %esi		/* Load fun */+	movl	%r10d, %edx		/* Load closure (user_data) */+#else+	movq	8(%r10), %rdi		/* Load cif */+	movq	16(%r10), %rsi		/* Load fun */+	movq	%r10, %rdx		/* Load closure (user_data) */+#endif+	jmp	L(do_closure)++L(UW17):+ENDF(C(ffi_go_closure_unix64))++#if defined(FFI_EXEC_STATIC_TRAMP)+	.balign	8+	.globl	C(ffi_closure_unix64_sse_alt)+	FFI_HIDDEN(C(ffi_closure_unix64_sse_alt))++C(ffi_closure_unix64_sse_alt):+	/* See the comments above trampoline_code_table. */+	_CET_ENDBR+	movq	8(%rsp), %r10			/* Load closure in r10 */+	addq	$16, %rsp			/* Restore the stack */+	jmp	C(ffi_closure_unix64_sse)+ENDF(C(ffi_closure_unix64_sse_alt))++	.balign	8+	.globl	C(ffi_closure_unix64_alt)+	FFI_HIDDEN(C(ffi_closure_unix64_alt))++C(ffi_closure_unix64_alt):+	/* See the comments above trampoline_code_table. */+	_CET_ENDBR+	movq	8(%rsp), %r10			/* Load closure in r10 */+	addq	$16, %rsp			/* Restore the stack */+	jmp	C(ffi_closure_unix64)+	ENDF(C(ffi_closure_unix64_alt))++/*+ * Below is the definition of the trampoline code table. Each element in+ * the code table is a trampoline.+ *+ * Because we jump to the trampoline, we place a _CET_ENDBR at the+ * beginning of the trampoline to mark it as a valid branch target. This is+ * part of the the Intel CET (Control Flow Enforcement Technology).+ */+/*+ * The trampoline uses register r10. It saves the original value of r10 on+ * the stack.+ *+ * The trampoline has two parameters - target code to jump to and data for+ * the target code. The trampoline extracts the parameters from its parameter+ * block (see tramp_table_map()). The trampoline saves the data address on+ * the stack. Finally, it jumps to the target code.+ *+ * The target code can choose to:+ *+ * - restore the value of r10+ * - load the data address in a register+ * - restore the stack pointer to what it was when the trampoline was invoked.+ */+#ifdef ENDBR_PRESENT+# define X86_DATA_OFFSET	4077+# ifdef __ILP32__+#  define X86_CODE_OFFSET	4069+# else+#  define X86_CODE_OFFSET	4073+# endif+#else+# define X86_DATA_OFFSET	4081+# ifdef __ILP32__+#  define X86_CODE_OFFSET	4073+# else+#  define X86_CODE_OFFSET	4077+# endif+#endif++	.align	UNIX64_TRAMP_MAP_SIZE+	.globl	trampoline_code_table+	FFI_HIDDEN(C(trampoline_code_table))++C(trampoline_code_table):+	.rept	UNIX64_TRAMP_MAP_SIZE / UNIX64_TRAMP_SIZE+	_CET_ENDBR+	subq	$16, %rsp			/* Make space on the stack */+	movq	%r10, (%rsp)			/* Save %r10 on stack */+#ifdef __ILP32__+	movl	X86_DATA_OFFSET(%rip), %r10d	/* Copy data into %r10 */+#else+	movq	X86_DATA_OFFSET(%rip), %r10	/* Copy data into %r10 */+#endif+	movq	%r10, 8(%rsp)			/* Save data on stack */+#ifdef __ILP32__+	movl	X86_CODE_OFFSET(%rip), %r10d	/* Copy code into %r10 */+#else+	movq	X86_CODE_OFFSET(%rip), %r10	/* Copy code into %r10 */+#endif+	jmp	*%r10				/* Jump to code */+	.align	8+	.endr+ENDF(C(trampoline_code_table))+	.align	UNIX64_TRAMP_MAP_SIZE+#endif /* FFI_EXEC_STATIC_TRAMP */++/* Sadly, OSX cctools-as doesn't understand .cfi directives at all.  */++#ifdef __APPLE__+.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support+EHFrame0:+#elif defined(HAVE_AS_X86_64_UNWIND_SECTION_TYPE)+.section .eh_frame,"a",@unwind+#else+.section .eh_frame,"a",@progbits+#endif++#ifdef HAVE_AS_X86_PCREL+# define PCREL(X)	X - .+#else+# define PCREL(X)	X@rel+#endif++/* Simplify advancing between labels.  Assume DW_CFA_advance_loc1 fits.  */+#ifdef __CET__+/* Use DW_CFA_advance_loc2 when IBT is enabled.  */+# define ADV(N, P)	.byte 3; .2byte L(N)-L(P)+#else+# define ADV(N, P)	.byte 2, L(N)-L(P)+#endif++	.balign 8+L(CIE):+	.set	L(set0),L(ECIE)-L(SCIE)+	.long	L(set0)			/* CIE Length */+L(SCIE):+	.long	0			/* CIE Identifier Tag */+	.byte	1			/* CIE Version */+	.ascii	"zR\0"			/* CIE Augmentation */+	.byte	1			/* CIE Code Alignment Factor */+	.byte	0x78			/* CIE Data Alignment Factor */+	.byte	0x10			/* CIE RA Column */+	.byte	1			/* Augmentation size */+	.byte	0x1b			/* FDE Encoding (pcrel sdata4) */+	.byte	0xc, 7, 8		/* DW_CFA_def_cfa, %rsp offset 8 */+	.byte	0x80+16, 1		/* DW_CFA_offset, %rip offset 1*-8 */+	.balign 8+L(ECIE):++	.set	L(set1),L(EFDE1)-L(SFDE1)+	.long	L(set1)			/* FDE Length */+L(SFDE1):+	.long	L(SFDE1)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW0))		/* Initial location */+	.long	L(UW4)-L(UW0)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW1, UW0)+	.byte	0xc, 6, 32		/* DW_CFA_def_cfa, %rbp 32 */+	.byte	0x80+6, 2		/* DW_CFA_offset, %rbp 2*-8 */+	ADV(UW2, UW1)+	.byte	0xa			/* DW_CFA_remember_state */+	.byte	0xc, 7, 8		/* DW_CFA_def_cfa, %rsp 8 */+	.byte	0xc0+6			/* DW_CFA_restore, %rbp */+	ADV(UW3, UW2)+	.byte	0xb			/* DW_CFA_restore_state */+	.balign	8+L(EFDE1):++	.set	L(set2),L(EFDE2)-L(SFDE2)+	.long	L(set2)			/* FDE Length */+L(SFDE2):+	.long	L(SFDE2)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW5))		/* Initial location */+	.long	L(UW7)-L(UW5)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW6, UW5)+	.byte	0xe			/* DW_CFA_def_cfa_offset */+	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */+	.balign	8+L(EFDE2):++	.set	L(set3),L(EFDE3)-L(SFDE3)+	.long	L(set3)			/* FDE Length */+L(SFDE3):+	.long	L(SFDE3)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW8))		/* Initial location */+	.long	L(UW11)-L(UW8)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW9, UW8)+	.byte	0xe			/* DW_CFA_def_cfa_offset */+	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */+	ADV(UW10, UW9)+	.byte	0xe, 8			/* DW_CFA_def_cfa_offset 8 */+L(EFDE3):++	.set	L(set4),L(EFDE4)-L(SFDE4)+	.long	L(set4)			/* FDE Length */+L(SFDE4):+	.long	L(SFDE4)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW12))		/* Initial location */+	.long	L(UW14)-L(UW12)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW13, UW12)+	.byte	0xe			/* DW_CFA_def_cfa_offset */+	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */+	.balign	8+L(EFDE4):++	.set	L(set5),L(EFDE5)-L(SFDE5)+	.long	L(set5)			/* FDE Length */+L(SFDE5):+	.long	L(SFDE5)-L(CIE)		/* FDE CIE offset */+	.long	PCREL(L(UW15))		/* Initial location */+	.long	L(UW17)-L(UW15)		/* Address range */+	.byte	0			/* Augmentation size */+	ADV(UW16, UW15)+	.byte	0xe			/* DW_CFA_def_cfa_offset */+	.byte	ffi_closure_FS + 8, 1	/* uleb128, assuming 128 <= FS < 255 */+	.balign	8+L(EFDE5):+#ifdef __APPLE__+	.subsections_via_symbols+	.section __LD,__compact_unwind,regular,debug++	/* compact unwind for ffi_call_unix64 */+	.quad    C(ffi_call_unix64)+	.set     L1,L(UW4)-L(UW0)+	.long    L1+	.long    0x04000000 /* use dwarf unwind info */+	.quad    0+	.quad    0++	/* compact unwind for ffi_closure_unix64_sse */+	.quad    C(ffi_closure_unix64_sse)+	.set     L2,L(UW7)-L(UW5)+	.long    L2+	.long    0x04000000 /* use dwarf unwind info */+	.quad    0+	.quad    0++	/* compact unwind for ffi_closure_unix64 */+	.quad    C(ffi_closure_unix64)+	.set     L3,L(UW11)-L(UW8)+	.long    L3+	.long    0x04000000 /* use dwarf unwind info */+	.quad    0+	.quad    0++	/* compact unwind for ffi_go_closure_unix64_sse */+	.quad    C(ffi_go_closure_unix64_sse)+	.set     L4,L(UW14)-L(UW12)+	.long    L4+	.long    0x04000000 /* use dwarf unwind info */+	.quad    0+	.quad    0++	/* compact unwind for ffi_go_closure_unix64 */+	.quad    C(ffi_go_closure_unix64)+	.set     L5,L(UW17)-L(UW15)+	.long    L5+	.long    0x04000000 /* use dwarf unwind info */+	.quad    0+	.quad    0+#endif++#endif /* __x86_64__ */+#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/x86/win64.S view
@@ -0,0 +1,254 @@+#ifdef __x86_64__+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "asmnames.h"++#if defined(HAVE_AS_CFI_PSEUDO_OP)+        .cfi_sections   .debug_frame+#endif++#ifdef X86_WIN64+#define SEH(...) __VA_ARGS__+#define arg0	%rcx+#define arg1	%rdx+#define arg2	%r8+#define arg3	%r9+#else+#define SEH(...)+#define arg0	%rdi+#define arg1	%rsi+#define arg2	%rdx+#define arg3	%rcx+#endif++/* 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++/* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10)++   Bit o trickiness here -- FRAME is the base of the stack frame+   for this function.  This has been allocated by ffi_call.  We also+   deallocate some of the stack that has been alloca'd.  */++	.align	8+	.globl	C(ffi_call_win64)+	FFI_HIDDEN(C(ffi_call_win64))++	SEH(.seh_proc ffi_call_win64)+C(ffi_call_win64):+	cfi_startproc+	_CET_ENDBR+	/* Set up the local stack frame and install it in rbp/rsp.  */+	movq	(%rsp), %rax+	movq	%rbp, (arg1)+	movq	%rax, 8(arg1)+	movq	arg1, %rbp+	cfi_def_cfa(%rbp, 16)+	cfi_rel_offset(%rbp, 0)+	SEH(.seh_pushreg %rbp)+	SEH(.seh_setframe %rbp, 0)+	SEH(.seh_endprologue)+	movq	arg0, %rsp++	movq	arg2, %r10++	/* Load all slots into both general and xmm registers.  */+	movq	(%rsp), %rcx+	movsd	(%rsp), %xmm0+	movq	8(%rsp), %rdx+	movsd	8(%rsp), %xmm1+	movq	16(%rsp), %r8+	movsd	16(%rsp), %xmm2+	movq	24(%rsp), %r9+	movsd	24(%rsp), %xmm3++	call	*16(%rbp)++	movl	24(%rbp), %ecx+	movq	32(%rbp), %r8+	leaq	0f(%rip), %r10+	cmpl	$FFI_TYPE_SMALL_STRUCT_4B, %ecx+	leaq	(%r10, %rcx, 8), %r10+	ja	99f+	_CET_NOTRACK jmp *%r10++/* Below, we're space constrained most of the time.  Thus we eschew the+   modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes).  */+#define epilogue		\+	leaveq;			\+	cfi_remember_state;	\+	cfi_def_cfa(%rsp, 8);	\+	cfi_restore(%rbp);	\+	ret;			\+	cfi_restore_state++	.align	8+0:+E(0b, FFI_TYPE_VOID)+	epilogue+E(0b, FFI_TYPE_INT)+	movslq	%eax, %rax+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_FLOAT)+	movss	%xmm0, (%r8)+	epilogue+E(0b, FFI_TYPE_DOUBLE)+	movsd	%xmm0, (%r8)+	epilogue+// FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here.+E(0b, FFI_TYPE_DOUBLE + 1)+	call	PLT(C(abort))+E(0b, FFI_TYPE_UINT8)+	movzbl	%al, %eax+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT8)+	movsbq	%al, %rax+	jmp	98f+E(0b, FFI_TYPE_UINT16)+	movzwl	%ax, %eax+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT16)+	movswq	%ax, %rax+	jmp	98f+E(0b, FFI_TYPE_UINT32)+	movl	%eax, %eax+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT32)+	movslq	%eax, %rax+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_UINT64)+98:	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT64)+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_STRUCT)+	epilogue+E(0b, FFI_TYPE_POINTER)+	movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_COMPLEX)+	call	PLT(C(abort))+E(0b, FFI_TYPE_SMALL_STRUCT_1B)+	movb	%al, (%r8)+	epilogue+E(0b, FFI_TYPE_SMALL_STRUCT_2B)+	movw	%ax, (%r8)+	epilogue+E(0b, FFI_TYPE_SMALL_STRUCT_4B)+	movl	%eax, (%r8)+	epilogue++	.align	8+99:	call	PLT(C(abort))++	epilogue++	cfi_endproc+	SEH(.seh_endproc)+++/* 32 bytes of outgoing register stack space, 8 bytes of alignment,+   16 bytes of result, 32 bytes of xmm registers.  */+#define ffi_clo_FS	(32+8+16+32)+#define ffi_clo_OFF_R	(32+8)+#define ffi_clo_OFF_X	(32+8+16)++	.align	8+	.globl	C(ffi_go_closure_win64)+	FFI_HIDDEN(C(ffi_go_closure_win64))++	SEH(.seh_proc ffi_go_closure_win64)+C(ffi_go_closure_win64):+	cfi_startproc+	_CET_ENDBR+	/* Save all integer arguments into the incoming reg stack space.  */+	movq	%rcx, 8(%rsp)+	movq	%rdx, 16(%rsp)+	movq	%r8, 24(%rsp)+	movq	%r9, 32(%rsp)++	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	C(ffi_closure_win64)+	FFI_HIDDEN(C(ffi_closure_win64))++	SEH(.seh_proc ffi_closure_win64)+C(ffi_closure_win64):+	cfi_startproc+	_CET_ENDBR+	/* Save all integer arguments into the incoming reg stack space.  */+	movq	%rcx, 8(%rsp)+	movq	%rdx, 16(%rsp)+	movq	%r8, 24(%rsp)+	movq	%r9, 32(%rsp)++	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)+	SEH(.seh_stackalloc ffi_clo_FS)+	SEH(.seh_endprologue)++	/* Save all sse arguments into the stack frame.  */+	movsd	%xmm0, ffi_clo_OFF_X(%rsp)+	movsd	%xmm1, ffi_clo_OFF_X+8(%rsp)+	movsd	%xmm2, ffi_clo_OFF_X+16(%rsp)+	movsd	%xmm3, ffi_clo_OFF_X+24(%rsp)++	leaq	ffi_clo_OFF_R(%rsp), %r9+	call	PLT(C(ffi_closure_win64_inner))++	/* Load the result into both possible result registers.  */+	movq    ffi_clo_OFF_R(%rsp), %rax+	movsd   ffi_clo_OFF_R(%rsp), %xmm0++	addq	$ffi_clo_FS, %rsp+	cfi_adjust_cfa_offset(-ffi_clo_FS)+	ret++	cfi_endproc+	SEH(.seh_endproc)++#if defined(FFI_EXEC_STATIC_TRAMP)+	.align	8+	.globl	C(ffi_closure_win64_alt)+	FFI_HIDDEN(C(ffi_closure_win64_alt))++	SEH(.seh_proc ffi_closure_win64_alt)+C(ffi_closure_win64_alt):+	_CET_ENDBR+	movq	8(%rsp), %r10+	addq	$16, %rsp+	jmp	C(ffi_closure_win64)+	SEH(.seh_endproc)+#endif+#endif /* __x86_64__ */++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif
+ src/x86/win64_intel.S view
@@ -0,0 +1,238 @@+#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>+#include <ffi_cfi.h>+#include "asmnames.h"++#if defined(HAVE_AS_CFI_PSEUDO_OP)+        .cfi_sections   .debug_frame+#endif++#ifdef X86_WIN64+#define SEH(...) __VA_ARGS__+#define arg0	rcx+#define arg1	rdx+#define arg2	r8+#define arg3	r9+#else+#define SEH(...)+#define arg0	rdi+#define arg1	rsi+#define arg2	rdx+#define arg3	rcx+#endif++/* 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)	ALIGN 8+#else+# define E(BASE, X)	ALIGN 8; ORG BASE + (X) * 8+#endif++	.CODE+	extern PLT(C(abort)):near+	extern C(ffi_closure_win64_inner):near++/* ffi_call_win64 (void *stack, struct win64_call_frame *frame, void *r10)++   Bit o trickiness here -- FRAME is the base of the stack frame+   for this function.  This has been allocated by ffi_call.  We also+   deallocate some of the stack that has been alloca'd.  */++	ALIGN	8+	PUBLIC	C(ffi_call_win64)++	; SEH(.safesh ffi_call_win64)+C(ffi_call_win64) proc SEH(frame)+	cfi_startproc+	/* Set up the local stack frame and install it in rbp/rsp.  */+	mov	RAX, [RSP] ; 	movq	(%rsp), %rax+	mov [arg1], RBP ; movq	%rbp, (arg1)+	mov [arg1 + 8], RAX;	movq	%rax, 8(arg1)+	mov	 RBP, arg1; movq	arg1, %rbp+	cfi_def_cfa(rbp, 16)+	cfi_rel_offset(rbp, 0)+	SEH(.pushreg rbp)+	SEH(.setframe rbp, 0)+	SEH(.endprolog)+	mov	RSP, arg0 ;	movq	arg0, %rsp++	mov	R10, arg2 ; movq	arg2, %r10++	/* Load all slots into both general and xmm registers.  */+	mov	RCX, [RSP] ;	movq	(%rsp), %rcx+	movsd XMM0, qword ptr [RSP] ; movsd	(%rsp), %xmm0+	mov	RDX, [RSP + 8] ;movq	8(%rsp), %rdx+	movsd XMM1, qword ptr [RSP + 8];	movsd	8(%rsp), %xmm1+	mov R8, [RSP + 16] ; movq	16(%rsp), %r8+	movsd	XMM2, qword ptr [RSP + 16] ; movsd	16(%rsp), %xmm2+	mov	R9, [RSP + 24] ; movq	24(%rsp), %r9+	movsd	XMM3, qword ptr [RSP + 24] ;movsd	24(%rsp), %xmm3++	CALL qword ptr [RBP + 16] ; call	*16(%rbp)++	mov	 ECX, [RBP + 24] ; movl	24(%rbp), %ecx+	mov	R8, [RBP + 32] ; movq	32(%rbp), %r8+	LEA	R10, ffi_call_win64_tab ; leaq	0f(%rip), %r10+	CMP	ECX, FFI_TYPE_SMALL_STRUCT_4B ; cmpl	$FFI_TYPE_SMALL_STRUCT_4B, %ecx+	LEA	R10, [R10 + RCX*8] ; leaq	(%r10, %rcx, 8), %r10+	JA	L99 ; ja	99f+	JMP	R10 ; jmp	*%r10++/* Below, we're space constrained most of the time.  Thus we eschew the+   modern "mov, pop, ret" sequence (5 bytes) for "leave, ret" (2 bytes).  */+epilogue macro+	LEAVE+	cfi_remember_state+	cfi_def_cfa(rsp, 8)+	cfi_restore(rbp)+	RET+	cfi_restore_state+endm++	ALIGN 8+ffi_call_win64_tab LABEL NEAR+E(0b, FFI_TYPE_VOID)+	epilogue+E(0b, FFI_TYPE_INT)+	movsxd rax, eax ; movslq	%eax, %rax+	mov qword ptr [r8], rax; movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_FLOAT)+	movss dword ptr [r8], xmm0 ; movss	%xmm0, (%r8)+	epilogue+E(0b, FFI_TYPE_DOUBLE)+	movsd qword ptr[r8], xmm0; movsd	%xmm0, (%r8)+	epilogue+// FFI_TYPE_LONGDOUBLE may be FFI_TYPE_DOUBLE but we need a different value here.+E(0b, FFI_TYPE_DOUBLE + 1)+	call	PLT(C(abort))+E(0b, FFI_TYPE_UINT8)+	movzx eax, al ;movzbl	%al, %eax+	mov qword ptr[r8], rax; movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT8)+	movsx rax, al ; movsbq	%al, %rax+	jmp	L98+E(0b, FFI_TYPE_UINT16)+	movzx eax, ax ; movzwl	%ax, %eax+	mov qword ptr[r8], rax; movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT16)+	movsx rax, ax; movswq	%ax, %rax+	jmp	L98+E(0b, FFI_TYPE_UINT32)+	mov eax, eax; movl	%eax, %eax+	mov qword ptr[r8], rax ; movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT32)+	movsxd rax, eax; movslq	%eax, %rax+	mov qword ptr [r8], rax; movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_UINT64)+L98 LABEL near+	mov qword ptr [r8], rax ; movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_SINT64)+	mov qword ptr [r8], rax;movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_STRUCT)+	epilogue+E(0b, FFI_TYPE_POINTER)+	mov qword ptr [r8], rax ;movq	%rax, (%r8)+	epilogue+E(0b, FFI_TYPE_COMPLEX)+	call	PLT(C(abort))+E(0b, FFI_TYPE_SMALL_STRUCT_1B)+	mov byte ptr [r8], al ; movb	%al, (%r8)+	epilogue+E(0b, FFI_TYPE_SMALL_STRUCT_2B)+	mov word ptr [r8], ax ; movw	%ax, (%r8)+	epilogue+E(0b, FFI_TYPE_SMALL_STRUCT_4B)+	mov dword ptr [r8], eax ; movl	%eax, (%r8)+	epilogue++	align	8+L99 LABEL near+	call	PLT(C(abort))++	epilogue++	cfi_endproc+	C(ffi_call_win64) endp+++/* 32 bytes of outgoing register stack space, 8 bytes of alignment,+   16 bytes of result, 32 bytes of xmm registers.  */+#define ffi_clo_FS	(32+8+16+32)+#define ffi_clo_OFF_R	(32+8)+#define ffi_clo_OFF_X	(32+8+16)++	align	8+	PUBLIC	C(ffi_go_closure_win64)++C(ffi_go_closure_win64) proc+	cfi_startproc+	/* Save all integer arguments into the incoming reg stack space.  */+	mov qword ptr [rsp + 8], rcx; movq	%rcx, 8(%rsp)+	mov qword ptr [rsp + 16], rdx; movq	%rdx, 16(%rsp)+	mov qword ptr [rsp + 24], r8; movq	%r8, 24(%rsp)+	mov qword ptr [rsp + 32], r9 ;movq	%r9, 32(%rsp)++	mov rcx, qword ptr [r10 + 8]; movq	8(%r10), %rcx			/* load cif */+	mov rdx, qword ptr [r10 + 16];  movq	16(%r10), %rdx			/* load fun */+	mov r8, r10 ; movq	%r10, %r8			/* closure is user_data */+	jmp	ffi_closure_win64_2+	cfi_endproc+	C(ffi_go_closure_win64) endp++	align	8+	+PUBLIC C(ffi_closure_win64)+C(ffi_closure_win64) PROC FRAME+	cfi_startproc+	/* Save all integer arguments into the incoming reg stack space.  */+	mov qword ptr [rsp + 8], rcx; movq	%rcx, 8(%rsp)+	mov qword ptr [rsp + 16], rdx;	movq	%rdx, 16(%rsp)+	mov qword ptr [rsp + 24], r8; 	movq	%r8, 24(%rsp)+	mov qword ptr [rsp + 32], r9;	movq	%r9, 32(%rsp)++	mov rcx, qword ptr [FFI_TRAMPOLINE_SIZE + r10]	;movq	FFI_TRAMPOLINE_SIZE(%r10), %rcx		/* load cif */+	mov rdx, qword ptr [FFI_TRAMPOLINE_SIZE + 8 + r10] ;	movq	FFI_TRAMPOLINE_SIZE+8(%r10), %rdx	/* load fun */+	mov r8, qword ptr [FFI_TRAMPOLINE_SIZE+16+r10] ;movq	FFI_TRAMPOLINE_SIZE+16(%r10), %r8	/* load user_data */+ffi_closure_win64_2 LABEL near+	sub rsp, ffi_clo_FS ;subq	$ffi_clo_FS, %rsp+	cfi_adjust_cfa_offset(ffi_clo_FS)+	SEH(.allocstack ffi_clo_FS)+	SEH(.endprolog)++	/* Save all sse arguments into the stack frame.  */+	movsd qword ptr [ffi_clo_OFF_X + rsp], xmm0	; movsd	%xmm0, ffi_clo_OFF_X(%rsp)+	movsd qword ptr [ffi_clo_OFF_X+8+rsp], xmm1 ; movsd	%xmm1, ffi_clo_OFF_X+8(%rsp)+	movsd qword ptr [ffi_clo_OFF_X+16+rsp], xmm2 ; movsd %xmm2, ffi_clo_OFF_X+16(%rsp)+	movsd qword ptr [ffi_clo_OFF_X+24+rsp], xmm3 ; movsd %xmm3, ffi_clo_OFF_X+24(%rsp)++	lea	r9, [ffi_clo_OFF_R + rsp] ; leaq	ffi_clo_OFF_R(%rsp), %r9+	call C(ffi_closure_win64_inner)++	/* Load the result into both possible result registers.  */+	+	mov rax, qword ptr [ffi_clo_OFF_R + rsp] ;movq    ffi_clo_OFF_R(%rsp), %rax+	movsd xmm0, qword ptr [rsp + ffi_clo_OFF_R] ;movsd   ffi_clo_OFF_R(%rsp), %xmm0++	add rsp, ffi_clo_FS ;addq	$ffi_clo_FS, %rsp+	cfi_adjust_cfa_offset(-ffi_clo_FS)+	ret++	cfi_endproc+	C(ffi_closure_win64) endp++#if defined __ELF__ && defined __linux__+	.section	.note.GNU-stack,"",@progbits+#endif+_text ends+end
+ src/xtensa/ffi.c view
@@ -0,0 +1,306 @@+/* -----------------------------------------------------------------------+   ffi.c - Copyright (c) 2013 Tensilica, Inc.++   XTENSA 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>++/*+                                 |----------------------------------------|+                                 |                                        |+    on entry to ffi_call ---->   |----------------------------------------|+                                 | caller stack frame for registers a0-a3 |+                                 |----------------------------------------|+                                 |                                        |+                                 |         additional arguments           |+    entry of the function --->   |----------------------------------------|+                                 |    copy of function arguments a2-a7    |+                                 | -  -  -  -  -  -  -  -  -  -  -  -  -  |+                                 |                                        |++    The area below the entry line becomes the new stack frame for the function.++*/+++#define FFI_TYPE_STRUCT_REGS FFI_TYPE_LAST+++extern void ffi_call_SYSV(void *rvalue, unsigned rsize, unsigned flags,+			  void(*fn)(void), unsigned nbytes, extended_cif*);+extern void ffi_closure_SYSV(void) FFI_HIDDEN;++ffi_status ffi_prep_cif_machdep(ffi_cif *cif)+{+  switch(cif->rtype->type) {+    case FFI_TYPE_SINT8:+    case FFI_TYPE_UINT8:+    case FFI_TYPE_SINT16:+    case FFI_TYPE_UINT16:+      cif->flags = cif->rtype->type;+      break;+    case FFI_TYPE_VOID:+    case FFI_TYPE_FLOAT:+      cif->flags = FFI_TYPE_UINT32;+      break;+    case FFI_TYPE_DOUBLE:+    case FFI_TYPE_UINT64:+    case FFI_TYPE_SINT64:+      cif->flags = FFI_TYPE_UINT64; // cif->rtype->type;+      break;+    case FFI_TYPE_STRUCT:+      cif->flags = FFI_TYPE_STRUCT; //_REGS;+      /* Up to 16 bytes are returned in registers */+      if (cif->rtype->size > 4 * 4) {+        /* returned structure is referenced by a register; use 8 bytes+           (including 4 bytes for potential additional alignment) */+        cif->flags = FFI_TYPE_STRUCT;	+        cif->bytes += 8;+      }+      break;++    default:+      cif->flags = FFI_TYPE_UINT32;+      break;+  }++  /* Round up stack size needed for arguments.+     Allocate FFI_REGISTER_ARGS_SPACE bytes when there are only arguments+     passed in registers, round space reserved for arguments passed on stack+     up to ABI-specified alignment.  */+  if (cif->bytes < FFI_REGISTER_NARGS * 4)+    cif->bytes = FFI_REGISTER_ARGS_SPACE;+  else+    cif->bytes = FFI_REGISTER_ARGS_SPACE ++	    FFI_ALIGN(cif->bytes - FFI_REGISTER_NARGS * 4,+		      XTENSA_STACK_ALIGNMENT);+  return FFI_OK;+}++void ffi_prep_args(extended_cif *ecif, unsigned char* stack)+{+  unsigned int i;+  unsigned long *addr;+  ffi_type **ptr;++  union {+    void **v;+    char **c;+    signed char **sc;+    unsigned char **uc;+    signed short **ss;+    unsigned short **us;+    unsigned int **i;+    long long **ll;+    float **f;+    double **d;+  } p_argv;++  /* Verify that everything is aligned up properly */+  FFI_ASSERT (((unsigned long) stack & 0x7) == 0);++  p_argv.v = ecif->avalue;+  addr = (unsigned long*)stack;++  /* structures with a size greater than 16 bytes are passed in memory */+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && ecif->cif->rtype->size > 16)+  {+    *addr++ = (unsigned long)ecif->rvalue;+  }++  for (i = ecif->cif->nargs, ptr = ecif->cif->arg_types;+       i > 0;+       i--, ptr++, p_argv.v++)+  {+    switch ((*ptr)->type)+    {+      case FFI_TYPE_SINT8:+        *addr++ = **p_argv.sc;+        break;+      case FFI_TYPE_UINT8:+        *addr++ = **p_argv.uc;+        break;+      case FFI_TYPE_SINT16:+        *addr++ = **p_argv.ss;+        break;+      case FFI_TYPE_UINT16:+        *addr++ = **p_argv.us;+        break;+      case FFI_TYPE_FLOAT:+      case FFI_TYPE_INT:+      case FFI_TYPE_UINT32:+      case FFI_TYPE_SINT32:+      case FFI_TYPE_POINTER:+        *addr++ = **p_argv.i;+        break;+      case FFI_TYPE_DOUBLE:+      case FFI_TYPE_UINT64:+      case FFI_TYPE_SINT64:+        if (((unsigned long)addr & 4) != 0)+          addr++;+        *(unsigned long long*)addr = **p_argv.ll;+	addr += sizeof(unsigned long long) / sizeof (addr);+        break;++      case FFI_TYPE_STRUCT:+      {+        unsigned long offs;+        unsigned long size;++        if (((unsigned long)addr & 4) != 0 && (*ptr)->alignment > 4)+          addr++;++        offs = (unsigned long) addr - (unsigned long) stack;+        size = (*ptr)->size;++        /* Entire structure must fit the argument registers or referenced */+        if (offs < FFI_REGISTER_NARGS * 4+            && offs + size > FFI_REGISTER_NARGS * 4)+          addr = (unsigned long*) (stack + FFI_REGISTER_NARGS * 4);++        memcpy((char*) addr, *p_argv.c, size);+        addr += (size + 3) / 4;+        break;+      }++      default:+        FFI_ASSERT(0);+    }+  }+}+++void ffi_call(ffi_cif* cif, void(*fn)(void), void *rvalue, void **avalue)+{+  extended_cif ecif;+  unsigned long rsize = cif->rtype->size;+  int flags = cif->flags;+  void *alloc = NULL;++  ecif.cif = cif;+  ecif.avalue = avalue;++  /* Note that for structures that are returned in registers (size <= 16 bytes)+     we allocate a temporary buffer and use memcpy to copy it to the final +     destination. The reason is that the target address might be misaligned or+     the length not a multiple of 4 bytes. Handling all those cases would be+     very complex.  */++  if (flags == FFI_TYPE_STRUCT && (rsize <= 16 || rvalue == NULL))+  {+    alloc = alloca(FFI_ALIGN(rsize, 4));+    ecif.rvalue = alloc;+  }+  else+  {+    ecif.rvalue = rvalue;+  }++  if (cif->abi != FFI_SYSV)+    FFI_ASSERT(0);++  ffi_call_SYSV (ecif.rvalue, rsize, cif->flags, fn, cif->bytes, &ecif);++  if (alloc != NULL && rvalue != NULL)+    memcpy(rvalue, alloc, rsize);+}++extern void ffi_trampoline();+extern void ffi_cacheflush(void* start, void* end);++ffi_status+ffi_prep_closure_loc (ffi_closure* closure,+                      ffi_cif* cif,+                      void (*fun)(ffi_cif*, void*, void**, void*),+                      void *user_data,+                      void *codeloc)+{+  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  /* copye trampoline to stack and patch 'ffi_closure_SYSV' pointer */+  memcpy(closure->tramp, ffi_trampoline, FFI_TRAMPOLINE_SIZE);+  *(unsigned int*)(&closure->tramp[8]) = (unsigned int)ffi_closure_SYSV;++  // Do we have this function?+  // __builtin___clear_cache(closer->tramp, closer->tramp + FFI_TRAMPOLINE_SIZE)+  ffi_cacheflush(closure->tramp, closure->tramp + FFI_TRAMPOLINE_SIZE);++  closure->cif = cif;+  closure->fun = fun;+  closure->user_data = user_data;+  return FFI_OK; +}+++long FFI_HIDDEN+ffi_closure_SYSV_inner(ffi_closure *closure, void **values, void *rvalue)+{+  ffi_cif *cif;+  ffi_type **arg_types;+  void **avalue;+  int i, areg;++  cif = closure->cif;+  if (cif->abi != FFI_SYSV)+    return FFI_BAD_ABI;++  areg = 0;++  int rtype = cif->rtype->type;+  if (rtype == FFI_TYPE_STRUCT && cif->rtype->size > 4 * 4)+  {+    rvalue = *values;+    areg++;+  }++  cif = closure->cif; +  arg_types = cif->arg_types;+  avalue = alloca(cif->nargs * sizeof(void *));++  for (i = 0; i < cif->nargs; i++)+  {+    if (arg_types[i]->alignment == 8 && (areg & 1) != 0)+      areg++;++    // skip the entry a1, * framework, see ffi_trampoline+    if (areg == FFI_REGISTER_NARGS)+      areg = (FFI_REGISTER_ARGS_SPACE + 32) / 4;++    if (arg_types[i]->type == FFI_TYPE_STRUCT)+    {+      int numregs = ((arg_types[i]->size + 3) & ~3) / 4;+      if (areg < FFI_REGISTER_NARGS && areg + numregs > FFI_REGISTER_NARGS)+        areg = (FFI_REGISTER_ARGS_SPACE + 32) / 4;+    }++    avalue[i] = &values[areg];+    areg += (arg_types[i]->size + 3) / 4;+  }++  (closure->fun)(cif, rvalue, avalue, closure->user_data);++  return rtype;+}
+ src/xtensa/ffitarget.h view
@@ -0,0 +1,57 @@+/* -----------------------------------------------------------------*-C-*-+   ffitarget.h - Copyright (c) 2013 Tensilica, Inc.+   Target configuration macros for XTENSA.++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#ifndef LIBFFI_TARGET_H+#define LIBFFI_TARGET_H++#ifndef LIBFFI_H+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."+#endif++#ifndef LIBFFI_ASM+typedef unsigned long	ffi_arg;+typedef signed long	ffi_sarg;++typedef enum ffi_abi {+  FFI_FIRST_ABI = 0,+  FFI_SYSV,+  FFI_LAST_ABI,+  FFI_DEFAULT_ABI = FFI_SYSV+} ffi_abi;+#endif++#define FFI_REGISTER_NARGS	6+#define XTENSA_STACK_ALIGNMENT	16+#define FFI_REGISTER_ARGS_SPACE ((FFI_REGISTER_NARGS * 4 + \+				  XTENSA_STACK_ALIGNMENT - 1) & \+				  -XTENSA_STACK_ALIGNMENT)++/* ---- Definitions for closures ----------------------------------------- */++#define FFI_CLOSURES 1+#define FFI_NATIVE_RAW_API 0+#define FFI_TRAMPOLINE_SIZE 24++#endif
+ src/xtensa/sysv.S view
@@ -0,0 +1,268 @@+/* -----------------------------------------------------------------------+   sysv.S - Copyright (c) 2013 Tensilica, Inc.+   +   XTENSA Foreign Function Interface ++   Permission is hereby granted, free of charge, to any person obtaining+   a copy of this software and associated documentation files (the+   ``Software''), to deal in the Software without restriction, including+   without limitation the rights to use, copy, modify, merge, publish,+   distribute, sublicense, and/or sell copies of the Software, and to+   permit persons to whom the Software is furnished to do so, subject to+   the following conditions:++   The above copyright notice and this permission notice shall be included+   in all copies or substantial portions of the Software.++   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+   DEALINGS IN THE SOFTWARE.+   ----------------------------------------------------------------------- */++#define LIBFFI_ASM+#include <fficonfig.h>+#include <ffi.h>++#define ENTRY(name) .text; .globl name; .type  name,@function; .align 4; name:+#define END(name) .size name , . - name++/* Assert that the table below is in sync with ffi.h.  */++#if	   FFI_TYPE_UINT8 != 5          \+        || FFI_TYPE_SINT8 != 6          \+        || FFI_TYPE_UINT16 != 7         \+        || FFI_TYPE_SINT16 != 8         \+        || FFI_TYPE_UINT32 != 9         \+        || FFI_TYPE_SINT32 != 10        \+        || FFI_TYPE_UINT64 != 11+#error "xtensa/sysv.S out of sync with ffi.h"+#endif++#define FFI_REGISTER_ARGS_OFFSET ((XTENSA_STACK_ALIGNMENT - \+				   FFI_REGISTER_NARGS * 4) & \+				   (XTENSA_STACK_ALIGNMENT - 1))++/* ffi_call_SYSV (rvalue, rbytes, flags, (*fnaddr)(), bytes, ecif)+      void *rvalue;            a2+      unsigned long rbytes;    a3+      unsigned flags;          a4+      void (*fnaddr)();        a5+      unsigned long bytes;     a6+      extended_cif* ecif)      a7+*/++ENTRY(ffi_call_SYSV)++	entry	a1, 32              # 32 byte frame for using call8 below++	mov	a10, a7             # a10(->arg0): ecif+	sub	a11, a1, a6         # a11(->arg1): stack pointer+	mov	a7, a1              # fp+	movsp	a1, a11             # set new sp = old_sp - bytes++	# align ffi_prep_args stack argument so that arguments+	# passed on stack if any start on 16-byte aligned boundary++	addi	a11, a11, FFI_REGISTER_ARGS_OFFSET++	movi	a8, ffi_prep_args+	callx8	a8                  # ffi_prep_args(ecif, stack)++	# prepare to move stack pointer back+	# to point to arguments passed on stack++	addi	a6, a1, FFI_REGISTER_ARGS_SPACE+	+	# we can pass up to 6 arguments in registers+	# for simplicity, just load 6 arguments++	l32i	a10, a1, FFI_REGISTER_ARGS_OFFSET + 0+	l32i	a11, a1, FFI_REGISTER_ARGS_OFFSET + 4+	l32i	a12, a1, FFI_REGISTER_ARGS_OFFSET + 8+	l32i	a13, a1, FFI_REGISTER_ARGS_OFFSET + 12+	l32i	a14, a1, FFI_REGISTER_ARGS_OFFSET + 16+	l32i	a15, a1, FFI_REGISTER_ARGS_OFFSET + 20++	# move stack pointer++	movsp	a1, a6++	callx8	a5                  # (*fn)(args...)++	# Handle return value(s)++	beqz	a2, .Lexit++	movi	a5, FFI_TYPE_STRUCT+	bne	a4, a5, .Lstore+	movi	a5, 16+	blt	a5, a3, .Lexit++	s32i	a10, a2, 0+	blti	a3, 5, .Lexit+	addi	a3, a3, -1+	s32i	a11, a2, 4+	blti	a3, 8, .Lexit+	s32i	a12, a2, 8+	blti	a3, 12, .Lexit+	s32i	a13, a2, 12++.Lexit:	retw++.Lstore:+	addi	a4, a4, -FFI_TYPE_UINT8+	bgei	a4, 7, .Lexit	# should never happen+	movi	a6, store_calls+	add	a4, a4, a4+	addx4	a6, a4, a6	# store_table + idx * 8+	jx	a6++	.align	8+store_calls:+	# UINT8+	s8i	a10, a2, 0+	retw++	# SINT8+	.align	8+	s8i	a10, a2, 0+	retw++	# UINT16+	.align	8+	s16i	a10, a2, 0+	retw++	# SINT16+	.align	8+	s16i	a10, a2, 0+	retw++	# UINT32+	.align	8+	s32i	a10, a2, 0+	retw++	# SINT32+	.align	8+	s32i	a10, a2, 0+	retw++	# UINT64+	.align	8+	s32i	a10, a2, 0+	s32i	a11, a2, 4+	retw++END(ffi_call_SYSV)+++/*+ * void ffi_cacheflush (unsigned long start, unsigned long end)+ */++#define EXTRA_ARGS_SIZE	24++ENTRY(ffi_cacheflush)++	entry	a1, 32++1:	+#if XCHAL_DCACHE_SIZE+	dhwbi	a2, 0+#endif+#if XCHAL_ICACHE_SIZE+	ihi	a2, 0+#endif+	addi	a2, a2, 4+	blt	a2, a3, 1b++	retw++END(ffi_cacheflush)++/* ffi_trampoline is copied to the stack */++ENTRY(ffi_trampoline)++	/* 32 bytes for spill + spill overflow area of a frame that uses+	   call8,+	   FFI_REGISTER_NARGS * 4 bytes for arguments passed in registers,+	   aligned up to 4 to maintain 16 byte stack alignment,+	   4 * 4 bytes for the result.+	   This size must be in sync with ffi_closure_SYSV_inner logic.+	 */+	entry	a1, 32 + FFI_REGISTER_ARGS_SPACE + (4 * 4)   # [ 0]+	j	2f                                # [ 3]+	.align	4                                 # [ 6]+1:	.long	0                                 # [ 8]+2:	l32r	a15, 1b                           # [12]+	_mov 	a14, a0                           # [15]+	callx0	a15                               # [18]+                                                  # [21]+END(ffi_trampoline)++/*+ * ffi_closure()+ *+ * a0:  closure + 21+ * a14: return address (a0)+ */++ENTRY(ffi_closure_SYSV)++	/* intentionally omitting entry here */++	# restore return address (a0) and move pointer to closure to a10+	addi	a10, a0, -21+	mov	a0, a14++	# allow up to 4 arguments as return values+	addi	a11, a1, 4 * 4++	# save up to 6 arguments to stack (allocated by entry below)+	s32i	a2, a11,  0+	s32i	a3, a11,  4+	s32i	a4, a11,  8+	s32i	a5, a11, 12+	s32i	a6, a11, 16+	s32i	a7, a11, 20++	movi	a8, ffi_closure_SYSV_inner+	mov	a12, a1+	callx8	a8			# .._inner(*closure, **avalue, *rvalue)++	# load up to four return arguments+	l32i	a2, a1,  0+	l32i	a3, a1,  4+	l32i	a4, a1,  8+	l32i	a5, a1, 12++	# (sign-)extend return value+	movi	a11, FFI_TYPE_UINT8+	bne	a10, a11, 1f+	extui	a2, a2, 0, 8+	retw++1:	movi	a11, FFI_TYPE_SINT8+	bne	a10, a11, 1f+	sext	a2, a2, 7+	retw++1:	movi	a11, FFI_TYPE_UINT16+	bne	a10, a11, 1f+	extui	a2, a2, 0, 16+	retw++1:	movi	a11, FFI_TYPE_SINT16+	bne	a10, a11, 1f+	sext	a2, a2, 15++1:	retw++END(ffi_closure_SYSV)