libffi-clib (empty) → 3.5.2
raw patch · 174 files changed
+105542/−0 lines, 174 filessetup-changed
Files
- CHANGELOG.md +5/−0
- Setup.hs +2/−0
- aclocal.m4 +787/−0
- compile +351/−0
- config.guess +1812/−0
- config.sub +1973/−0
- configure +23128/−0
- configure.ac +395/−0
- configure.host +336/−0
- fficonfig.h.in +182/−0
- include/ffi.h.in +536/−0
- include/ffi_cfi.h +78/−0
- include/ffi_common.h +201/−0
- include/tramp.h +45/−0
- install-sh +541/−0
- libffi-clib.buildinfo.in +7/−0
- libffi-clib.cabal +92/−0
- ltmain.sh +11517/−0
- m4/asmcfi.m4 +30/−0
- m4/ax_cc_maxopt.m4 +198/−0
- m4/ax_cflags_warn_all.m4 +158/−0
- m4/ax_check_compile_flag.m4 +63/−0
- m4/ax_compiler_vendor.m4 +119/−0
- m4/ax_configure_args.m4 +49/−0
- m4/ax_enable_builddir.m4 +302/−0
- m4/ax_gcc_archflag.m4 +267/−0
- m4/ax_gcc_x86_cpuid.m4 +89/−0
- m4/ax_prepend_flag.m4 +51/−0
- m4/ax_require_defined.m4 +37/−0
- m4/libtool.m4 +8491/−0
- m4/lt_undescore.m4 +38/−0
- m4/ltoptions.m4 +467/−0
- m4/ltsugar.m4 +124/−0
- m4/ltversion.m4 +24/−0
- m4/lt~obsolete.m4 +99/−0
- src/aarch64/ffi.c +1145/−0
- src/aarch64/ffitarget.h +97/−0
- src/aarch64/internal.h +146/−0
- src/aarch64/sysv.S +699/−0
- src/aarch64/win64_armasm.S +506/−0
- src/alpha/ffi.c +521/−0
- src/alpha/ffitarget.h +57/−0
- src/alpha/internal.h +23/−0
- src/alpha/osf.S +282/−0
- src/arc/arcompact.S +210/−0
- src/arc/ffi.c +447/−0
- src/arc/ffitarget.h +67/−0
- src/arm/ffi.c +921/−0
- src/arm/ffitarget.h +89/−0
- src/arm/internal.h +17/−0
- src/arm/sysv.S +456/−0
- src/arm/sysv_msvc_arm32.S +311/−0
- src/avr32/ffi.c +423/−0
- src/avr32/ffitarget.h +55/−0
- src/avr32/sysv.S +208/−0
- src/bfin/ffi.c +196/−0
- src/bfin/ffitarget.h +43/−0
- src/bfin/sysv.S +179/−0
- src/closures.c +1107/−0
- src/cris/ffi.c +386/−0
- src/cris/ffitarget.h +56/−0
- src/cris/sysv.S +215/−0
- src/csky/ffi.c +395/−0
- src/csky/ffitarget.h +63/−0
- src/csky/sysv.S +371/−0
- src/debug.c +64/−0
- src/dlmalloc.c +5172/−0
- src/frv/eabi.S +128/−0
- src/frv/ffi.c +292/−0
- src/frv/ffitarget.h +62/−0
- src/ia64/ffi.c +616/−0
- src/ia64/ffitarget.h +56/−0
- src/ia64/ia64_flags.h +40/−0
- src/ia64/unix.S +585/−0
- src/java_raw_api.c +374/−0
- src/kvx/asm.h +5/−0
- src/kvx/ffi.c +273/−0
- src/kvx/ffitarget.h +75/−0
- src/kvx/sysv.S +127/−0
- src/loongarch64/ffi.c +624/−0
- src/loongarch64/ffitarget.h +82/−0
- src/loongarch64/sysv.S +327/−0
- src/m32r/ffi.c +249/−0
- src/m32r/ffitarget.h +53/−0
- src/m32r/sysv.S +121/−0
- src/m68k/ffi.c +362/−0
- src/m68k/ffitarget.h +54/−0
- src/m68k/sysv.S +357/−0
- src/m88k/ffi.c +400/−0
- src/m88k/ffitarget.h +49/−0
- src/m88k/obsd.S +209/−0
- src/metag/ffi.c +330/−0
- src/metag/ffitarget.h +53/−0
- src/metag/sysv.S +311/−0
- src/microblaze/ffi.c +321/−0
- src/microblaze/ffitarget.h +53/−0
- src/microblaze/sysv.S +302/−0
- src/mips/ffi.c +1317/−0
- src/mips/ffitarget.h +249/−0
- src/mips/n32.S +827/−0
- src/mips/o32.S +565/−0
- src/moxie/eabi.S +101/−0
- src/moxie/ffi.c +310/−0
- src/moxie/ffitarget.h +52/−0
- src/or1k/ffi.c +341/−0
- src/or1k/ffitarget.h +58/−0
- src/or1k/sysv.S +107/−0
- src/pa/ffi.c +673/−0
- src/pa/ffitarget.h +94/−0
- src/pa/hpux32.S +417/−0
- src/pa/hpux64.S +681/−0
- src/pa/linux.S +431/−0
- src/powerpc/aix.S +566/−0
- src/powerpc/aix_closure.S +694/−0
- src/powerpc/asm.h +125/−0
- src/powerpc/darwin.S +378/−0
- src/powerpc/darwin_closure.S +571/−0
- src/powerpc/ffi.c +194/−0
- src/powerpc/ffi_darwin.c +1464/−0
- src/powerpc/ffi_linux64.c +1160/−0
- src/powerpc/ffi_powerpc.h +105/−0
- src/powerpc/ffi_sysv.c +933/−0
- src/powerpc/ffitarget.h +204/−0
- src/powerpc/internal.h +10/−0
- src/powerpc/linux64.S +293/−0
- src/powerpc/linux64_closure.S +613/−0
- src/powerpc/ppc_closure.S +421/−0
- src/powerpc/sysv.S +173/−0
- src/prep_cif.c +280/−0
- src/raw_api.c +267/−0
- src/riscv/ffi.c +514/−0
- src/riscv/ffitarget.h +69/−0
- src/riscv/sysv.S +293/−0
- src/s390/ffi.c +783/−0
- src/s390/ffitarget.h +70/−0
- src/s390/internal.h +22/−0
- src/s390/sysv.S +363/−0
- src/sh/ffi.c +717/−0
- src/sh/ffitarget.h +54/−0
- src/sh/sysv.S +850/−0
- src/sh64/ffi.c +469/−0
- src/sh64/ffitarget.h +58/−0
- src/sh64/sysv.S +539/−0
- src/sparc/ffi.c +484/−0
- src/sparc/ffi64.c +630/−0
- src/sparc/ffitarget.h +81/−0
- src/sparc/internal.h +26/−0
- src/sparc/v8.S +443/−0
- src/sparc/v9.S +440/−0
- src/tile/ffi.c +355/−0
- src/tile/ffitarget.h +65/−0
- src/tile/tile.S +360/−0
- src/tramp.c +721/−0
- src/types.c +128/−0
- src/vax/elfbsd.S +195/−0
- src/vax/ffi.c +276/−0
- src/vax/ffitarget.h +49/−0
- src/wasm/ffi.c +798/−0
- src/wasm/ffitarget.h +79/−0
- src/x86/asmnames.h +30/−0
- src/x86/ffi.c +835/−0
- src/x86/ffi64.c +953/−0
- src/x86/ffitarget.h +164/−0
- src/x86/ffiw64.c +361/−0
- src/x86/internal.h +43/−0
- src/x86/internal64.h +36/−0
- src/x86/sysv.S +1272/−0
- src/x86/sysv_intel.S +998/−0
- src/x86/unix64.S +711/−0
- src/x86/win64.S +254/−0
- src/x86/win64_intel.S +238/−0
- src/xtensa/ffi.c +306/−0
- src/xtensa/ffitarget.h +57/−0
- src/xtensa/sysv.S +268/−0
+ 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 *) <_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 *)®ister_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 *) ®ister_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 *) ®ister_args[6])+ ptr = stack_args;+ else if (ptr == (char *) ®ister_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 == ®ister_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 = ®_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 (®_args->gpr[gprcount], a, size <= 8 ? size : 8);+ }+ gprcount++;+ break;+ case X86_64_SSE_CLASS:+ case X86_64_SSEDF_CLASS:+ memcpy (®_args->sse[ssecount++].i64, a, sizeof(UINT64));+ break;+ case X86_64_SSESF_CLASS:+ memcpy (®_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] = ®_args->sse[ssecount];+ ssecount += n;+ }+ else+ {+ avalue[i] = ®_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, ®_args->sse[ssecount++], 8);+ else+ memcpy (a, ®_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)