Преглед изворни кода

pub.libffi. Initial Import.

woollybah пре 6 година
родитељ
комит
11709c4d35
100 измењених фајлова са 36023 додато и 0 уклоњено
  1. 36 0
      libffi.mod/examples/example_01.bmx
  2. 85 0
      libffi.mod/examples/glue_01.c
  3. 515 0
      libffi.mod/include/ffi.h
  4. 202 0
      libffi.mod/include/win32/fficonfig.h
  5. 11 0
      libffi.mod/libffi.bmx
  6. 50 0
      libffi.mod/libffi/.appveyor.yml
  7. 38 0
      libffi.mod/libffi/.gitignore
  8. 34 0
      libffi.mod/libffi/.travis.yml
  9. 584 0
      libffi.mod/libffi/ChangeLog.libffi
  10. 6000 0
      libffi.mod/libffi/ChangeLog.libffi-3.1
  11. 40 0
      libffi.mod/libffi/ChangeLog.libgcj
  12. 764 0
      libffi.mod/libffi/ChangeLog.v1
  13. 21 0
      libffi.mod/libffi/LICENSE
  14. 352 0
      libffi.mod/libffi/LICENSE-BUILDTOOLS
  15. 166 0
      libffi.mod/libffi/Makefile.am
  16. 461 0
      libffi.mod/libffi/README.md
  17. 479 0
      libffi.mod/libffi/acinclude.m4
  18. 2 0
      libffi.mod/libffi/autogen.sh
  19. 1466 0
      libffi.mod/libffi/config.guess
  20. 1836 0
      libffi.mod/libffi/config.sub
  21. 394 0
      libffi.mod/libffi/configure.ac
  22. 287 0
      libffi.mod/libffi/configure.host
  23. 3 0
      libffi.mod/libffi/doc/Makefile.am
  24. 985 0
      libffi.mod/libffi/doc/libffi.texi
  25. 4 0
      libffi.mod/libffi/doc/version.texi
  26. 203 0
      libffi.mod/libffi/generate-darwin-source-and-headers.py
  27. 9 0
      libffi.mod/libffi/include/Makefile.am
  28. 515 0
      libffi.mod/libffi/include/ffi.h.in
  29. 55 0
      libffi.mod/libffi/include/ffi_cfi.h
  30. 153 0
      libffi.mod/libffi/include/ffi_common.h
  31. 80 0
      libffi.mod/libffi/libffi.map.in
  32. 11 0
      libffi.mod/libffi/libffi.pc.in
  33. 1043 0
      libffi.mod/libffi/libffi.xcodeproj/project.pbxproj
  34. 29 0
      libffi.mod/libffi/libtool-version
  35. 13 0
      libffi.mod/libffi/m4/asmcfi.m4
  36. 71 0
      libffi.mod/libffi/m4/ax_append_flag.m4
  37. 194 0
      libffi.mod/libffi/m4/ax_cc_maxopt.m4
  38. 122 0
      libffi.mod/libffi/m4/ax_cflags_warn_all.m4
  39. 74 0
      libffi.mod/libffi/m4/ax_check_compile_flag.m4
  40. 87 0
      libffi.mod/libffi/m4/ax_compiler_vendor.m4
  41. 70 0
      libffi.mod/libffi/m4/ax_configure_args.m4
  42. 302 0
      libffi.mod/libffi/m4/ax_enable_builddir.m4
  43. 263 0
      libffi.mod/libffi/m4/ax_gcc_archflag.m4
  44. 89 0
      libffi.mod/libffi/m4/ax_gcc_x86_cpuid.m4
  45. 37 0
      libffi.mod/libffi/m4/ax_require_defined.m4
  46. 8 0
      libffi.mod/libffi/man/Makefile.am
  47. 41 0
      libffi.mod/libffi/man/ffi.3
  48. 103 0
      libffi.mod/libffi/man/ffi_call.3
  49. 68 0
      libffi.mod/libffi/man/ffi_prep_cif.3
  50. 73 0
      libffi.mod/libffi/man/ffi_prep_cif_var.3
  51. 328 0
      libffi.mod/libffi/msvcc.sh
  52. 948 0
      libffi.mod/libffi/src/aarch64/ffi.c
  53. 81 0
      libffi.mod/libffi/src/aarch64/ffitarget.h
  54. 67 0
      libffi.mod/libffi/src/aarch64/internal.h
  55. 440 0
      libffi.mod/libffi/src/aarch64/sysv.S
  56. 521 0
      libffi.mod/libffi/src/alpha/ffi.c
  57. 57 0
      libffi.mod/libffi/src/alpha/ffitarget.h
  58. 23 0
      libffi.mod/libffi/src/alpha/internal.h
  59. 282 0
      libffi.mod/libffi/src/alpha/osf.S
  60. 135 0
      libffi.mod/libffi/src/arc/arcompact.S
  61. 266 0
      libffi.mod/libffi/src/arc/ffi.c
  62. 53 0
      libffi.mod/libffi/src/arc/ffitarget.h
  63. 822 0
      libffi.mod/libffi/src/arm/ffi.c
  64. 82 0
      libffi.mod/libffi/src/arm/ffitarget.h
  65. 7 0
      libffi.mod/libffi/src/arm/internal.h
  66. 385 0
      libffi.mod/libffi/src/arm/sysv.S
  67. 423 0
      libffi.mod/libffi/src/avr32/ffi.c
  68. 55 0
      libffi.mod/libffi/src/avr32/ffitarget.h
  69. 208 0
      libffi.mod/libffi/src/avr32/sysv.S
  70. 196 0
      libffi.mod/libffi/src/bfin/ffi.c
  71. 43 0
      libffi.mod/libffi/src/bfin/ffitarget.h
  72. 179 0
      libffi.mod/libffi/src/bfin/sysv.S
  73. 979 0
      libffi.mod/libffi/src/closures.c
  74. 386 0
      libffi.mod/libffi/src/cris/ffi.c
  75. 56 0
      libffi.mod/libffi/src/cris/ffitarget.h
  76. 215 0
      libffi.mod/libffi/src/cris/sysv.S
  77. 64 0
      libffi.mod/libffi/src/debug.c
  78. 5166 0
      libffi.mod/libffi/src/dlmalloc.c
  79. 128 0
      libffi.mod/libffi/src/frv/eabi.S
  80. 292 0
      libffi.mod/libffi/src/frv/ffi.c
  81. 62 0
      libffi.mod/libffi/src/frv/ffitarget.h
  82. 604 0
      libffi.mod/libffi/src/ia64/ffi.c
  83. 56 0
      libffi.mod/libffi/src/ia64/ffitarget.h
  84. 40 0
      libffi.mod/libffi/src/ia64/ia64_flags.h
  85. 567 0
      libffi.mod/libffi/src/ia64/unix.S
  86. 374 0
      libffi.mod/libffi/src/java_raw_api.c
  87. 232 0
      libffi.mod/libffi/src/m32r/ffi.c
  88. 53 0
      libffi.mod/libffi/src/m32r/ffitarget.h
  89. 121 0
      libffi.mod/libffi/src/m32r/sysv.S
  90. 362 0
      libffi.mod/libffi/src/m68k/ffi.c
  91. 54 0
      libffi.mod/libffi/src/m68k/ffitarget.h
  92. 357 0
      libffi.mod/libffi/src/m68k/sysv.S
  93. 400 0
      libffi.mod/libffi/src/m88k/ffi.c
  94. 49 0
      libffi.mod/libffi/src/m88k/ffitarget.h
  95. 209 0
      libffi.mod/libffi/src/m88k/obsd.S
  96. 330 0
      libffi.mod/libffi/src/metag/ffi.c
  97. 53 0
      libffi.mod/libffi/src/metag/ffitarget.h
  98. 311 0
      libffi.mod/libffi/src/metag/sysv.S
  99. 321 0
      libffi.mod/libffi/src/microblaze/ffi.c
  100. 53 0
      libffi.mod/libffi/src/microblaze/ffitarget.h

+ 36 - 0
libffi.mod/examples/example_01.bmx

@@ -0,0 +1,36 @@
+SuperStrict
+
+Framework brl.standardio
+Import pub.libffi
+
+Import "glue_01.c"
+
+test(inc)
+testAdd(Add)
+testStruct(StructFunc, "hi")
+
+Function Inc:Int(x:Int)
+	Return x + 1
+End Function
+
+Function Add:Int(a:Int, b:Int)
+	Return a + b
+End Function
+
+Function StructFunc:STest(s:STest)
+	s.a :+ 1
+	s.c :- 1
+	Return s
+End Function
+
+Extern
+	Function test(func:Byte Ptr)
+	Function testAdd(func:Byte Ptr)
+	Function testStruct(func:Byte Ptr, txt:String)
+End Extern
+
+Struct STest
+	Field a:Int
+	Field b:String
+	Field c:Int
+End Struct

+ 85 - 0
libffi.mod/examples/glue_01.c

@@ -0,0 +1,85 @@
+
+#include "pub.mod/libffi.mod/include/win32/fficonfig.h"
+#include "pub.mod/libffi.mod/include/ffi.h"
+
+#include <stdio.h>
+#include "brl.mod/blitz.mod/blitz.h"
+
+void test(void * func) {
+	ffi_cif cif;
+
+	ffi_type* rtype = &ffi_type_sint32;
+	ffi_type* atypes[] = {&ffi_type_sint32};
+	ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, rtype, atypes);
+	printf("cif status: %d\n", status);
+
+	int r = 0;
+	void* rvalue = &r;
+	int a0 = 3;
+	void* avalues[] = {&a0};
+	ffi_call(&cif, func, rvalue, avalues);
+	printf("result = %d\n", r);
+	
+	fflush(stdout);
+}
+
+void testAdd(void * func) {
+	ffi_cif cif;
+	ffi_type* rtype = &ffi_type_sint32;
+	ffi_type* atypes[] = {&ffi_type_sint32, &ffi_type_sint32};
+	ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, rtype, atypes);
+	printf("cif status: %d\n", status);
+	
+	int r = 0;
+	void* rvalue = &r;
+	int a0 = 3;
+	int a1 = 5;
+	void* avalues[] = {&a0, &a1};
+	ffi_call(&cif, func, rvalue, avalues);
+	printf("result = %d\n", r);
+	
+	fflush(stdout);
+}
+
+struct stest {
+	int a;
+	BBString * b;
+	int c;
+};
+
+void testStruct(void * func, BBString * txt) {
+
+	ffi_type stesttype;
+	stesttype.size = 0;
+	stesttype.alignment = 0;
+	stesttype.type = FFI_TYPE_STRUCT;
+	ffi_type* stesttypeelements[4];
+	stesttype.elements = &stesttypeelements;
+	stesttypeelements[0] = &ffi_type_sint32;
+	stesttypeelements[1] = &ffi_type_pointer;
+	stesttypeelements[2] = &ffi_type_sint32;
+	stesttypeelements[3] = NULL;
+	
+	ffi_cif cif;
+	ffi_type* rtype = &stesttype;
+	ffi_type* atypes[] = {&stesttype};
+	ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, rtype, atypes);
+	printf("cif status: %d\n", status);
+	
+	struct stest r;
+	struct stest a0;
+	a0.a = 3;
+	a0.b = txt;
+	a0.c = 3;
+
+	void* rvalue = &r;
+	void* avalues[] = {&a0};
+	printf("s=%d,a=%d\n", stesttype.size,stesttype.alignment);
+	fflush(stdout);
+
+	ffi_call(&cif, func, rvalue, avalues);
+	
+	printf("a = %d, c = %d\n", r.a, r.c);
+	
+	fflush(stdout);
+}

+ 515 - 0
libffi.mod/include/ffi.h

@@ -0,0 +1,515 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi 3.3.0 - Copyright (c) 2011, 2014 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 --------------------------------- */
+
+#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
+# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
+#  define FFI_API __declspec(dllexport)
+# elif !defined FFI_BUILDING  /* Importing libffi.DLL */
+#  define FFI_API __declspec(dllimport)
+# else                        /* Building/linking static library */
+#  define FFI_API
+# 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;
+
+#if HAVE_LONG_DOUBLE
+FFI_EXTERN ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+FFI_EXTERN ffi_type ffi_type_complex_float;
+FFI_EXTERN ffi_type ffi_type_complex_double;
+#if HAVE_LONG_DOUBLE
+FFI_EXTERN ffi_type ffi_type_complex_longdouble;
+#else
+#define ffi_type_complex_longdouble ffi_type_complex_double
+#endif
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI
+} 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);
+#endif
+
+FFI_API
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+FFI_API
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+FFI_API
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+#ifdef _MSC_VER
+__declspec(align(8))
+#endif
+typedef struct {
+#if 0
+  void *trampoline_table;
+  void *trampoline_table_entry;
+#else
+  char tramp[FFI_TRAMPOLINE_SIZE];
+#endif
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+} 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 0
+  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 transaltion, void** -> ffi_raw*.  */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+#if 0
+  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);
+
+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);
+#endif
+
+#endif /* FFI_CLOSURES */
+
+#if 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);
+
+/* Useful for eliminating compiler warnings.  */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if HAVE_LONG_DOUBLE
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+#define FFI_TYPE_COMPLEX    15
+
+/* This should always refer to the last type code (for sanity checks).  */
+#define FFI_TYPE_LAST       FFI_TYPE_COMPLEX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 202 - 0
libffi.mod/include/win32/fficonfig.h

@@ -0,0 +1,202 @@
+/* fficonfig.h.  Generated from fficonfig.h.in by configure.  */
+/* fficonfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+#define C_ALLOCA 1
+
+/* 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 */
+
+/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
+/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
+
+/* Cannot use malloc on this target, so, we revert to alternative means */
+/* #undef FFI_MMAP_EXEC_WRIT */
+
+/* Define this is you do not want support for the raw API. */
+/* #undef FFI_NO_RAW_API */
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+/* #undef HAVE_ALLOCA */
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if your assembler supports .ascii. */
+/* #undef HAVE_AS_ASCII_PSEUDO_OP */
+
+/* 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 your assembler and linker support unaligned PC relative relocs.
+   */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+/* Define if your assembler supports .string. */
+/* #undef HAVE_AS_STRING_PSEUDO_OP */
+
+/* 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 to 1 if you have the `memcpy' function. */
+/* #undef HAVE_MEMCPY */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+/* #undef HAVE_MMAP_ANON */
+
+/* Define if mmap of /dev/zero works. */
+/* #undef HAVE_MMAP_DEV_ZERO */
+
+/* Define if read-only mmap of a plain file works. */
+/* #undef HAVE_MMAP_FILE */
+
+/* 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. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* 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. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+/* #undef HAVE_SYS_MMAN_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+#define PACKAGE "libffi"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://github.com/atgreen/libffi/issues"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libffi"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libffi 3.3.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libffi"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.3.0"
+
+/* The size of `double', as computed by sizeof. */
+#define SIZEOF_DOUBLE (sizeof(double))
+
+/* The size of `long double', as computed by sizeof. */
+#define SIZEOF_LONG_DOUBLE (sizeof(long double))
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#define STACK_DIRECTION -1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if symbols are underscored. */
+/* #undef SYMBOL_UNDERSCORE */
+
+/* Define this if you are using Purify and want to suppress spurious messages.
+   */
+/* #undef USING_PURIFY */
+
+/* Version number of package */
+#define VERSION "3.2.1"
+
+/* 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
+#  define WORDS_BIGENDIAN 1
+# endif
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif

+ 11 - 0
libffi.mod/libffi.bmx

@@ -0,0 +1,11 @@
+SuperStrict
+
+Module pub.libffi
+
+?win32x64
+ModuleInfo "CC_OPTS: -DX86_WIN64 -DHAVE_LONG_DOUBLE"
+?win32x86
+ModuleInfo "CC_OPTS: -DX86_WIN32"
+?
+
+Import "source.bmx"

+ 50 - 0
libffi.mod/libffi/.appveyor.yml

@@ -0,0 +1,50 @@
+shallow_clone: true
+
+# We're currently only testing 64-bit libffi built with Microsoft's
+# tools.
+# This matrix should be expanded to include at least:
+#  32- and 64-bit gcc/cygwin
+#  32- and 64-bit gcc/mingw
+#  32- and 64-bit clang/mingw
+#  and perhaps more.
+
+image: Visual Studio 2013
+platform:
+  - x64
+
+environment:
+  global:
+    CYG_ROOT: C:/cygwin
+    CYG_CACHE: C:/cygwin/var/cache/setup
+    CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
+  matrix:
+    - VSVER: 12
+
+install:
+  - ps: >-
+      If ($env:Platform -Match "x86") {
+          $env:VCVARS_PLATFORM="x86"
+          $env:BUILD="x86-pc-cygwin"
+          $env:HOST="x86-pc-windows"
+        } Else {
+          $env:VCVARS_PLATFORM="amd64"
+          $env:BUILD="x86_64-w64-cygwin"
+          $env:HOST="x86_64-w64-cygwin"
+      }
+  - 'appveyor DownloadFile https://cygwin.com/setup-x86.exe -FileName setup.exe'
+  - 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu >NUL'
+  - '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"'
+  - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
+  - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%"
+  - call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM%
+
+build_script:
+  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./autogen.sh;)"
+  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='/cygdrive/c/projects/libffi/msvcc.sh -m64' CXX='/cygdrive/c/projects/libffi/msvcc.sh -m64' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)"
+  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/x86/ffitarget.h include; make; find .;)"
+  - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)"
+
+# FIXME: "make check" currently fails.  It just looks like msvcc needs
+# to learn about -L and -l options.  If you add "make check; cat `find
+# ./ -name libffi.log" to the end of that build command you'll see
+# what I mean.

+ 38 - 0
libffi.mod/libffi/.gitignore

@@ -0,0 +1,38 @@
+.libs
+.deps
+*.o
+*.lo
+.dirstamp
+*.la
+Makefile
+!testsuite/libffi.bhaible/Makefile
+Makefile.in
+aclocal.m4
+compile
+!.travis/compile
+configure
+depcomp
+doc/libffi.info
+*~
+fficonfig.h.in
+fficonfig.h
+include/ffi.h
+include/ffitarget.h
+install-sh
+libffi.pc
+libtool
+libtool-ldflags
+ltmain.sh
+m4/libtool.m4
+m4/lt*.m4
+mdate-sh
+missing
+stamp-h1
+libffi*gz
+autom4te.cache
+libffi.xcodeproj/xcuserdata
+libffi.xcodeproj/project.xcworkspace
+build_*/
+darwin_*/
+src/arm/trampoline.S
+**/texinfo.tex

+ 34 - 0
libffi.mod/libffi/.travis.yml

@@ -0,0 +1,34 @@
+---
+sudo: required
+
+language: cpp
+
+matrix:
+  include:
+    - os: osx
+      env: HOST=arm-apple-darwin
+    - os: linux
+      compiler: gcc
+      env: HOST=i386-pc-linux-gnu MEVAL='export CC="$CC -m32" && CXX="$CXX -m32"'
+    - os: linux
+      compiler: gcc
+    - os: linux
+      compiler: gcc
+      env: CONFIGURE_OPTIONS=--disable-shared
+    - os: linux
+      compiler: clang
+    - os: linux
+      compiler: clang
+      env: CONFIGURE_OPTIONS=--disable-shared
+    - os: linux
+      env: HOST=moxie-elf MEVAL='export PATH=/opt/moxielogic/bin:$PATH && CC=moxie-elf-gcc && CXX=moxie-elf-g++' LDFLAGS=-Tsim.ld RUNTESTFLAGS="--target_board moxie-sim" DEJAGNU="$TRAVIS_BUILD_DIR/.travis/site.exp"
+
+before_install:
+  - if test x"$MEVAL" != x; then eval ${MEVAL}; fi
+
+install:
+  - ./.travis/install.sh
+
+script:
+  - if ! test x"$MEVAL" = x; then eval ${MEVAL}; fi
+  - ./.travis/build.sh

+ 584 - 0
libffi.mod/libffi/ChangeLog.libffi

@@ -0,0 +1,584 @@
+2011-02-08  Andreas Tobler  <[email protected]>
+
+	* testsuite/lib/libffi.exp: Tweak for stand-alone mode.
+
+2009-12-25  Samuli Suominen  <[email protected]>
+
+	* configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64.
+	* configure: Rebuilt.
+	* fficonfig.h.in: Rebuilt.
+
+2009-06-16  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	* testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs.
+	* testsuite/libffi.call/float2.c: Fix dg-excess-errors.
+	* testsuite/libffi.call/ffitest.h,
+	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
+
+2009-06-12  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	testsuite/libffi.special/unwindtest.cc: include stdint.h.
+
+2009-06-11  Timothy Wall  <[email protected]>
+
+	* Makefile.am,
+        configure.ac,
+        include/ffi.h.in,
+        include/ffi_common.h,
+        src/closures.c,
+        src/dlmalloc.c,
+        src/x86/ffi.c,
+        src/x86/ffitarget.h,
+        src/x86/win64.S (new),
+	README: Added win64 support (mingw or MSVC)
+        * Makefile.in,
+        include/Makefile.in,
+        man/Makefile.in,
+        testsuite/Makefile.in,
+        configure,
+        aclocal.m4: Regenerated
+        * ltcf-c.sh: properly escape cygwin/w32 path
+        * man/ffi_call.3: Clarify size requirements for return value.
+        * src/x86/ffi64.c: Fix filename in comment.
+        * src/x86/win32.S: Remove unused extern.
+
+        * testsuite/libffi.call/closure_fn0.c,
+        testsuite/libffi.call/closure_fn1.c,
+        testsuite/libffi.call/closure_fn2.c,
+        testsuite/libffi.call/closure_fn3.c,
+        testsuite/libffi.call/closure_fn4.c,
+        testsuite/libffi.call/closure_fn5.c,
+        testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+ 	testsuite/libffi.call/cls_3byte2.c,
+ 	testsuite/libffi.call/cls_4_1byte.c,
+ 	testsuite/libffi.call/cls_4byte.c,
+ 	testsuite/libffi.call/cls_5_1_byte.c,
+ 	testsuite/libffi.call/cls_5byte.c,
+ 	testsuite/libffi.call/cls_64byte.c,
+ 	testsuite/libffi.call/cls_6_1_byte.c,
+ 	testsuite/libffi.call/cls_6byte.c,
+ 	testsuite/libffi.call/cls_7_1_byte.c,
+ 	testsuite/libffi.call/cls_7byte.c,
+ 	testsuite/libffi.call/cls_8byte.c,
+ 	testsuite/libffi.call/cls_9byte1.c,
+ 	testsuite/libffi.call/cls_9byte2.c,
+ 	testsuite/libffi.call/cls_align_double.c,
+ 	testsuite/libffi.call/cls_align_float.c,
+ 	testsuite/libffi.call/cls_align_longdouble.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split2.c,
+ 	testsuite/libffi.call/cls_align_pointer.c,
+ 	testsuite/libffi.call/cls_align_sint16.c,
+ 	testsuite/libffi.call/cls_align_sint32.c,
+ 	testsuite/libffi.call/cls_align_sint64.c,
+ 	testsuite/libffi.call/cls_align_uint16.c,
+ 	testsuite/libffi.call/cls_align_uint32.c,
+ 	testsuite/libffi.call/cls_align_uint64.c,
+ 	testsuite/libffi.call/cls_dbls_struct.c,
+ 	testsuite/libffi.call/cls_double.c,
+ 	testsuite/libffi.call/cls_double_va.c,
+ 	testsuite/libffi.call/cls_float.c,
+ 	testsuite/libffi.call/cls_longdouble.c,
+ 	testsuite/libffi.call/cls_longdouble_va.c,
+ 	testsuite/libffi.call/cls_multi_schar.c,
+ 	testsuite/libffi.call/cls_multi_sshort.c,
+ 	testsuite/libffi.call/cls_multi_sshortchar.c,
+ 	testsuite/libffi.call/cls_multi_uchar.c,
+ 	testsuite/libffi.call/cls_multi_ushort.c,
+ 	testsuite/libffi.call/cls_multi_ushortchar.c,
+ 	testsuite/libffi.call/cls_pointer.c,
+ 	testsuite/libffi.call/cls_pointer_stack.c,
+ 	testsuite/libffi.call/cls_schar.c,
+ 	testsuite/libffi.call/cls_sint.c,
+ 	testsuite/libffi.call/cls_sshort.c,
+ 	testsuite/libffi.call/cls_uchar.c,
+ 	testsuite/libffi.call/cls_uint.c,
+ 	testsuite/libffi.call/cls_ulonglong.c,
+ 	testsuite/libffi.call/cls_ushort.c,
+ 	testsuite/libffi.call/err_bad_abi.c,
+ 	testsuite/libffi.call/err_bad_typedef.c,
+ 	testsuite/libffi.call/float2.c,
+ 	testsuite/libffi.call/huge_struct.c,
+ 	testsuite/libffi.call/nested_struct.c,
+ 	testsuite/libffi.call/nested_struct1.c,
+ 	testsuite/libffi.call/nested_struct10.c,
+ 	testsuite/libffi.call/nested_struct2.c,
+ 	testsuite/libffi.call/nested_struct3.c,
+ 	testsuite/libffi.call/nested_struct4.c,
+ 	testsuite/libffi.call/nested_struct5.c,
+ 	testsuite/libffi.call/nested_struct6.c,
+ 	testsuite/libffi.call/nested_struct7.c,
+ 	testsuite/libffi.call/nested_struct8.c,
+ 	testsuite/libffi.call/nested_struct9.c,
+ 	testsuite/libffi.call/problem1.c,
+ 	testsuite/libffi.call/return_ldl.c,
+ 	testsuite/libffi.call/return_ll1.c,
+ 	testsuite/libffi.call/stret_large.c,
+ 	testsuite/libffi.call/stret_large2.c,
+ 	testsuite/libffi.call/stret_medium.c,
+ 	testsuite/libffi.call/stret_medium2.c,
+        testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
+        of checking for MMAP.  Use intptr_t instead of long casts.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/powerpc/ffitarget.h: Fix misapplied merge from gcc.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/mips/o32.S,
+	src/mips/n32.S: Fix licence formatting.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/x86/darwin.S: Fix licence formatting.
+	src/x86/win32.S: Likewise.
+	src/sh64/sysv.S: Likewise.
+	src/sh/sysv.S: Likewise.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/sh64/ffi.c: Remove lint directives.  Was missing from merge
+	of Andreas Tobler's patch from 2006-04-22.
+	
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of
+	2007-03-07.
+
+2008-12-26  Timothy Wall  <[email protected]>
+
+	* testsuite/libffi.call/cls_longdouble.c,
+        testsuite/libffi.call/cls_longdouble_va.c,
+        testsuite/libffi.call/cls_align_longdouble.c,
+        testsuite/libffi.call/cls_align_longdouble_split.c,
+        testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
+        failures on x86_64 cygwin/mingw.
+
+2008-12-22  Timothy Wall  <[email protected]>
+
+	* testsuite/libffi.call/closure_fn0.c,
+        testsuite/libffi.call/closure_fn1.c,    
+        testsuite/libffi.call/closure_fn2.c,    
+        testsuite/libffi.call/closure_fn3.c,    
+        testsuite/libffi.call/closure_fn4.c,    
+        testsuite/libffi.call/closure_fn5.c,    
+        testsuite/libffi.call/closure_fn6.c,    
+        testsuite/libffi.call/closure_loc_fn0.c,    
+        testsuite/libffi.call/closure_stdcall.c,    
+        testsuite/libffi.call/cls_align_pointer.c,    
+        testsuite/libffi.call/cls_pointer.c,    
+        testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
+        pointer to integer (intptr_t).
+        * testsuite/libffi.call/cls_longdouble.c: disable for win64.
+	
+2008-12-19  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.8.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-11-11  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.7.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-08-25  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
+	FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
+	Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
+	Adjust copyright notice.
+	* src/powerpc/ffi.c: Add two new flags to indicate if we have one
+	register or two register to use for FFI_SYSV structs.
+	(ffi_prep_cif_machdep): Pass the right register flag introduced above.
+	(ffi_closure_helper_SYSV): Fix the return type for
+	FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
+	Adjust copyright notice.
+
+2008-07-24  Anthony Green  <[email protected]>
+
+	* testsuite/libffi.call/cls_dbls_struct.c,
+	testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c,
+	testsuite/libffi.call/err_bad_abi.c: Clean up failures from
+	compiler warnings.
+
+2008-07-17  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.6.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.  Add documentation.
+	* README: Update for new release.
+
+2008-07-16  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
+	int.
+
+2008-07-16  Kaz Kojima  <[email protected]>
+
+	* src/sh/sysv.S: Add .note.GNU-stack on Linux.
+	* src/sh64/sysv.S: Likewise.
+
+2008-04-03  Anthony Green  <[email protected]>
+
+	* libffi.pc.in (Libs): Add -L${libdir}.
+	* configure.ac: Bump version to 3.0.5.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-04-03  Anthony Green  <[email protected]>
+	    Xerces Ranby  <[email protected]>
+
+	* include/ffi.h.in: Wrap definition of target architecture to
+	protect from double definitions.
+
+2008-03-22  Moriyoshi Koizumi  <[email protected]>
+
+	* src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in
+	closure_loc_fn0.c.
+	* testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0):
+	New test.
+
+2008-03-04  Anthony Green  <[email protected]>
+	    Blake Chaffin
+	    [email protected]
+
+	* testsuite/libffi.call/cls_align_longdouble_split2.c
+          testsuite/libffi.call/cls_align_longdouble_split.c
+          testsuite/libffi.call/cls_dbls_struct.c
+          testsuite/libffi.call/cls_double_va.c
+          testsuite/libffi.call/cls_longdouble.c
+          testsuite/libffi.call/cls_longdouble_va.c
+          testsuite/libffi.call/cls_pointer.c
+          testsuite/libffi.call/cls_pointer_stack.c
+          testsuite/libffi.call/err_bad_abi.c
+          testsuite/libffi.call/err_bad_typedef.c
+          testsuite/libffi.call/huge_struct.c
+          testsuite/libffi.call/stret_large2.c
+          testsuite/libffi.call/stret_large.c
+          testsuite/libffi.call/stret_medium2.c
+          testsuite/libffi.call/stret_medium.c: New tests from Apple.
+
+2008-02-26  Jakub Jelinek  <[email protected]>
+            Anthony Green  <[email protected]>
+
+	* src/alpha/osf.S: Add .note.GNU-stack on Linux.
+	* src/s390/sysv.S: Likewise.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.
+	* src/powerpc/sysv.S: Likewise.
+	* src/x86/unix64.S: Likewise.
+	* src/x86/sysv.S: Likewise.
+	* src/sparc/v8.S: Likewise.
+	* src/sparc/v9.S: Likewise.
+	* src/m68k/sysv.S: Likewise.
+	* src/ia64/unix.S: Likewise.
+	* src/arm/sysv.S: Likewise.
+
+2008-02-26  Anthony Green  <[email protected]>
+            Thomas Heller  <[email protected]>
+
+	* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
+	comment.
+
+2008-02-26  Anthony Green  <[email protected]>
+            Thomas Heller  <[email protected]>
+
+	* include/ffi.h.in: Change void (*)() to void (*)(void).
+
+2008-02-26  Anthony Green  <[email protected]>
+            Thomas Heller  <[email protected]>
+
+	* src/alpha/ffi.c: Change void (*)() to void (*)(void).
+	src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c,
+	src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c,
+	src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S,
+	src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c,
+	src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c,
+	src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,
+	src/x86/ffi64.c: Ditto.
+
+2008-02-24  Anthony Green  <[email protected]>
+
+	* configure.ac: Accept openbsd*, not just openbsd.
+	Bump version to 3.0.4.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-02-22  Anthony Green  <[email protected]>
+
+	* README: Clean up list of tested platforms.
+
+2008-02-22  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.3.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.  Clean up test docs.
+
+2008-02-22  Bjoern Koenig  <[email protected]>
+	    Andreas Tobler  <[email protected]>
+
+	* configure.ac: Add amd64-*-freebsd* target.
+	* configure: Regenerate.
+
+2008-02-22  Thomas Heller <[email protected]>
+
+	* configure.ac: Add x86 OpenBSD support.
+	* configure: Rebuilt.
+
+2008-02-21  Thomas Heller <[email protected]>
+
+	* README: Change "make test" to "make check".
+
+2008-02-21  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.2.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-02-21  Björn König <[email protected]>
+
+	* src/x86/freebsd.S: New file.
+	* configure.ac: Add x86 FreeBSD support.
+	* Makefile.am: Ditto.
+
+2008-02-15  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.1.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* libtool-version: Increment revision.
+	* README: Update for new release.
+
+2008-02-15  David Daney	 <[email protected]>
+
+	* src/mips/ffi.c: Remove extra '>' from include directive.
+	(ffi_prep_closure_loc): Use clear_location instead of tramp.
+
+2008-02-15  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 3.0.0.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-15  David Daney	 <[email protected]>
+
+	* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
+	Define (conditionally), and use it to include cachectl.h.
+	(ffi_prep_closure_loc): Fix cache flushing.
+	* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
+
+2008-02-15  Anthony Green  <[email protected]>
+
+        * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3:
+	Update dates and remove all references to ffi_prep_closure.
+	* configure.ac: Bump version to 2.99.9.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-15  Anthony Green  <[email protected]>
+
+	* man/ffi_prep_closure.3: Delete.
+	* man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3.
+	(man_MANS): Ditto.
+	* man/Makefile.in: Rebuilt.
+	* configure.ac: Bump version to 2.99.8.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 2.99.7.
+	* configure, doc/stamp-vti, doc/version.texi: Rebuilt.
+	* include/ffi.h.in LICENSE src/debug.c src/closures.c
+          src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h
+          src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c
+          src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S
+          src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c
+          src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c
+          src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S
+          src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h
+          src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c
+          src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S
+          src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h
+          src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h
+          src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S
+          src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h
+          src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S
+          src/arm/ffitarget.h src/prep_cif.c: Update license text.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* README: Update tested platforms.
+	* configure.ac: Bump version to 2.99.6.
+	* configure: Rebuilt.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* configure.ac: Bump version to 2.99.5.
+	* configure: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Add darwin64.S
+	* Makefile.in: Rebuilt.
+	* testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree.
+	* LICENSE: Update WARRANTY.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* libffi.pc.in (libdir): Fix libdir definition.
+	* configure.ac: Bump version to 2.99.4.
+	* configure: Rebuilt.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* README: Update.
+	* libffi.info: New file.
+	* doc/stamp-vti: New file.
+	* configure.ac: Bump version to 2.99.3.
+	* configure: Rebuilt.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* Makefile.am (SUBDIRS): Add man dir.
+	* Makefile.in: Rebuilt.
+	* configure.ac: Create Makefile.
+	* configure: Rebuilt.
+        * man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3
+          man/Makefile.am man/Makefile.in: New files.
+
+2008-02-14  Tom Tromey  <[email protected]>
+
+	* aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt.
+	* mdate-sh, texinfo.tex: New files.
+	* Makefile.am (info_TEXINFOS): New variable.
+	* doc/libffi.texi: New file.
+	* doc/version.texi: Likewise.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET).
+	(lib_LTLIBRARIES): Define.
+	(toolexeclib_LIBRARIES): Undefine.
+	* Makefile.in: Rebuilt.
+	* configure.ac: Reset version to 2.99.1.
+	* configure.in: Rebuilt.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION@.
+	* configure.ac: Reset version to 2.99.1.
+	* configure.in: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Add ChangeLog.libffi.
+	* Makefile.in: Rebuilt.
+	* LICENSE: Update copyright notice.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* include/Makefile.am (nodist_includes_HEADERS): Define.  Don't
+	distribute ffitarget.h or ffi.h from the build include dir.
+	* Makefile.in: Rebuilt.
+
+2008-02-14  Anthony Green  <[email protected]>
+
+	* include/Makefile.am (includesdir): Install headers under libdir.
+	(pkgconfigdir): Define. Install libffi.pc.
+	* include/Makefile.in: Rebuilt.
+	* libffi.pc.in: Create.
+	* libtool-version: Increment CURRENT
+	* configure.ac: Add libffi.pc.in
+	* configure: Rebuilt.
+
+2008-02-03  Anthony Green  <[email protected]>
+
+	* include/Makefile.am (includesdir): Fix header install with
+	DESTDIR.
+	* include/Makefile.in: Rebuilt.
+
+2008-02-03  Timothy Wall  <[email protected]>
+
+	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
+          offset based on code pointer, not data pointer.
+
+2008-02-01  Anthony Green  <[email protected]>
+
+	* include/Makefile.am: Fix header installs.
+	* Makefile.am: Ditto.
+	* include/Makefile.in: Rebuilt.
+	* Makefile.in: Ditto.
+
+2008-02-01  Anthony Green  <[email protected]>
+
+	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL,
+	FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last
+	patch.
+
+2008-01-31  Anthony Green  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add missing files.
+	* testsuite/Makefile.am: Ditto.
+	* Makefile.in, testsuite/Makefile.in: Rebuilt.
+
+2008-01-31  Timothy Wall <[email protected]>
+
+	* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
+	closures.
+	* src/x86/ffitarget.h: Increase size of trampoline for stdcall
+	closures.
+	* src/x86/win32.S: Add assembly for stdcall closure.
+	* src/x86/ffi.c: Initialize stdcall closure trampoline.
+
+2008-01-30  H.J. Lu <[email protected]>
+
+	PR libffi/34612
+	* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
+	returning struct.
+
+	* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
+	tests.
+
+2008-01-30  Anthony Green  <[email protected]>
+
+	* Makefile.am, include/Makefile.am: Move headers to
+	libffi_la_SOURCES for new automake.
+	* Makefile.in, include/Makefile.in: Rebuilt.
+
+	* testsuite/lib/wrapper.exp: Copied from gcc tree to allow for
+	execution outside of gcc tree.
+	* testsuite/lib/target-libpath.exp: Ditto.
+
+	* testsuite/lib/libffi-dg.exp: Many changes to allow for execution
+	outside of gcc tree.
+

+ 6000 - 0
libffi.mod/libffi/ChangeLog.libffi-3.1

@@ -0,0 +1,6000 @@
+2014-03-16  Josh Triplett  <[email protected]>
+
+	* ChangeLog: Archive to ChangeLog.libffi-3.1 and delete.  Future
+	changelogs will come from git, with autogenerated snapshots shipped in
+	distributed tarballs.
+
+2014-03-16  Josh Triplett  <[email protected]>
+
+	Add support for stdcall, thiscall, and fastcall on non-Windows
+	x86-32.
+
+	Linux supports the stdcall calling convention, either via
+	functions explicitly declared with the stdcall attribute, or via
+	code compiled with -mrtd which effectively makes stdcall the
+	default.
+
+	This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on
+	non-Windows x86-32 platforms, as non-default calling conventions.
+
+	* Makefile.am: Compile in src/x86/win32.S on non-Windows x86-32.
+	* src/x86/ffitarget.h: Add FFI_STDCALL, FFI_THISCALL, and
+	FFI_FASTCALL on non-Windows x86-32.  Increase trampoline size to
+	accomodate these calling conventions, and unify some ifdeffery.
+	* src/x86/ffi.c: Add support for FFI_STDCALL, FFI_THISCALL, and
+	FFI_FASTCALL on non-Windows x86-32 platforms; update ifdeffery.
+	* src/x86/win32.S: Support compiling on non-Windows x86-32
+	platforms.  On those platforms, avoid redefining the SYSV symbols
+	already provided by src/x86/sysv.S.
+	* testsuite/libffi.call/closure_stdcall.c: Run on non-Windows.
+	#define __stdcall if needed.
+	* testsuite/libffi.call/closure_thiscall.c: Run on non-Windows.
+	#define __fastcall if needed.
+	* testsuite/libffi.call/fastthis1_win32.c: Run on non-Windows.
+	* testsuite/libffi.call/fastthis2_win32.c: Ditto.
+	* testsuite/libffi.call/fastthis3_win32.c: Ditto.
+	* testsuite/libffi.call/many2_win32.c: Ditto.
+	* testsuite/libffi.call/many_win32.c: Ditto.
+	* testsuite/libffi.call/strlen2_win32.c: Ditto.
+	* testsuite/libffi.call/strlen_win32.c: Ditto.
+	* testsuite/libffi.call/struct1_win32.c: Ditto.
+	* testsuite/libffi.call/struct2_win32.c: Ditto.
+
+2014-03-16  Josh Triplett  <[email protected]>
+
+	* prep_cif.c: Remove unnecessary ifdef for X86_WIN32.
+	ffi_prep_cif_core had a special case for X86_WIN32, checking for
+	FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI
+	range before returning FFI_BAD_ABI.  However, on X86_WIN32,
+	FFI_THISCALL already falls in that range, making the special case
+	unnecessary.  Remove it.
+
+2014-03-16  Josh Triplett  <[email protected]>
+
+	* testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/closure_thiscall.c: Remove fragile stack
+	pointer checks.  These files included inline assembly to save the
+	stack pointer before and after the call, and compare the values.
+	However, compilers can and do leave the stack in different states
+	for these two pieces of inline assembly, such as by saving a
+	temporary value on the stack across the call; observed with gcc
+	-Os, and verified as spurious through careful inspection of
+	disassembly.
+
+2014-03-16  Josh Triplett  <[email protected]>
+
+	* testsuite/libffi.call/many.c: Avoid spurious failure due to
+	excess floating-point precision.
+	* testsuite/libffi.call/many_win32.c: Ditto.
+
+2014-03-16  Josh Triplett <[email protected]>
+
+	* libtool-ldflags: Re-add.
+
+2014-03-16  Josh Triplett <[email protected]>
+
+	* Makefile.in, aclocal.m4, compile, config.guess, config.sub,
+	configure, depcomp, include/Makefile.in, install-sh,
+	libtool-ldflags, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4,
+	m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4,
+	man/Makefile.in, mdate-sh, missing, testsuite/Makefile.in: Delete
+	autogenerated files from version control.
+	* .gitignore: Add autogenerated files.
+	* autogen.sh: New script to generate the autogenerated files.
+	* README: Document requirement to run autogen.sh when building
+	directly from version control.
+	* .travis.yml: Run autogen.sh
+
+2014-03-14  Anthony Green <[email protected]>
+
+	* configure, Makefile.in: Rebuilt.
+
+2014-03-10  Mike Hommey <[email protected]>
+
+	* configure.ac: Allow building for mipsel with Android NDK r8.
+	* Makefile.am (AM_MAKEFLAGS): Replace double quotes with single
+	quotes.
+
+2014-03-10  Landry Breuil <[email protected]>
+
+	* configure.ac: Ensure the linker supports @unwind sections in libffi.
+
+2014-03-01  Anthony Green  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Replace old scripts with
+	generate-darwin-source-and-headers.py.
+	* Makefile.in: Rebuilt.
+
+2014-02-28  Anthony Green  <[email protected]>
+
+	* Makefile.am (AM_CFLAGS): Reintroduce missing -DFFI_DEBUG for
+	--enable-debug builds.
+	* Makefile.in: Rebuilt.
+
+2014-02-28  Makoto Kato  <[email protected]>
+
+	* src/closures.c: Fix build failure when using clang for Android.
+
+2014-02-28  Marcin Wojdyr  <[email protected]>
+
+	* libffi.pc.in (toolexeclibdir): use -L${toolexeclibdir} instead
+	of -L${libdir}.
+
+2014-02-28  Paulo Pizarro  <[email protected]>
+
+	* src/bfin/sysv.S: Calling functions in shared libraries requires
+	considering the GOT.
+
+2014-02-28  Josh Triplett  <[email protected]>
+
+	* src/x86/ffi64.c (classify_argument): Handle case where
+	FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE.
+
+2014-02-28  Anthony Green  <[email protected]>
+
+	* ltmain.sh: Generate with libtool-2.4.2.418.
+	* m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: Ditto.
+	* configure: Rebuilt.
+
+2014-02-28  Dominik Vogt  <[email protected]>
+
+	* configure.ac (AC_ARG_ENABLE struct): Fix typo in help
+	message.
+	(AC_ARG_ENABLE raw_api): Ditto.
+	* configure, fficonfig.h.in: Rebuilt.
+
+2014-02-28  Will Newton  <[email protected]>
+
+	* src/arm/sysv.S: Initialize IP register with FP.
+
+2014-02-28  Yufeng Zhang  <[email protected]>
+
+	* src/aarch64/sysv.S (ffi_closure_SYSV): Use x29 as the
+	main CFA reg; update cfi_rel_offset.
+
+2014-02-15  Marcus Comstedt  <[email protected]>
+
+	* src/powerpc/ffi_linux64.c, src/powerpc/linux64_closure.S: Remove
+	assumption on contents of r11 in closure.
+
+2014-02-09  Heiher  <[email protected]>
+
+	* src/mips/n32.S: Fix call floating point va function.
+
+2014-01-21  Zachary Waldowski  <[email protected]>
+
+	* src/aarch64/ffi.c: Fix missing semicolons on assertions under
+	debug mode.
+
+2013-12-30  Zachary Waldowski  <[email protected]>
+
+	* .gitignore: Exclude darwin_* generated source and build_* trees.
+	* src/aarch64/ffi.c, src/arm/ffi.c, src/x86/ffi.c: Inhibit Clang
+	previous prototype warnings.
+	* src/arm/ffi.c: Prevent NULL dereference, fix short type warning
+	* src/dlmalloc.c: Fix warnings from set_segment_flags return type,
+	and the native use of size_t for malloc on platforms
+	* src/arm/sysv.S: Use unified syntax. Clang clean-ups for
+	ARM_FUNC_START.
+	* generate-osx-source-and-headers.py: Remove.
+	* build-ios.sh: Remove.
+	* libffi.xcodeproj/project.pbxproj: Rebuild targets. Include
+	x86_64+aarch64 pieces in library.  Export headers properly.
+	* src/x86/ffi64.c: More Clang warning clean-ups.
+	* src/closures.c (open_temp_exec_file_dir): Use size_t.
+	* src/prep_cif.c (ffi_prep_cif_core): Cast ALIGN result.
+	* src/aarch64/sysv.S: Use CNAME for global symbols.  Only use
+	.size for ELF targets.
+	* src/aarch64/ffi.c: Clean up for double == long double.  Clean up
+	from Clang warnings.  Use Clang cache invalidation builtin.  Use
+	size_t in place of unsigned in many places.  Accommodate for
+	differences in Apple AArch64 ABI.
+
+2013-12-02  Daniel Rodríguez Troitiño  <[email protected]>
+
+	* generate-darwin-source-and-headers.py: Clean up, modernize,
+	merged version of previous scripts.
+
+2013-11-21  Anthony Green  <[email protected]>
+
+	* configure, Makefile.in, include/Makefile.in, include/ffi.h.in,
+	man/Makefile.in, testsuite/Makefile.in, fficonfig.h.in: Rebuilt.
+
+2013-11-21  Alan Modra  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add new src/powerpc files.
+	(nodist_libffi_la_SOURCES <POWERPC, POWERPC_FREEBSD>): Likewise.
+	* configure.ac (HAVE_LONG_DOUBLE_VARIANT): Define for powerpc.
+	* include/ffi.h.in (ffi_prep_types): Declare.
+	* src/prep_cif.c (ffi_prep_cif_core): Call ffi_prep_types.
+	* src/types.c (FFI_NONCONST_TYPEDEF): Define and use for
+	HAVE_LONG_DOUBLE_VARIANT.
+	* src/powerpc/ffi_powerpc.h: New file.
+	* src/powerpc/ffi.c: Split into..
+	* src/powerpc/ffi_sysv.c: ..new file, and..
+	* src/powerpc/ffi_linux64.c: ..new file, rewriting parts.
+	* src/powerpc/ffitarget.h (enum ffi_abi): Rewrite powerpc ABI
+	selection as bits controlling features.
+	* src/powerpc/linux64.S: For consistency, use POWERPC64 rather
+	than __powerpc64__.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.  Move .note.FNU-stack
+	inside guard.
+	* src/powerpc/sysv.S: Likewise.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* Makefile.in: Regenerate.
+
+2013-11-20  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use
+	NUM_FPR_ARG_REGISTERS64 and NUM_GPR_ARG_REGISTERS64 not their
+	32-bit versions for 64-bit code.
+	* src/powerpc/linux64_closure.S: Don't use the return value area
+	as a parameter save area on ELFv2.
+
+2013-11-18  Iain Sandoe  <[email protected]>
+
+	* src/powerpc/darwin.S (EH): Correct use of pcrel FDE encoding.
+	* src/powerpc/darwin_closure.S (EH): Likewise. Modernise picbase
+	labels.
+
+2013-11-18  Anthony Green  <[email protected]>
+
+	* src/arm/ffi.c (ffi_call): Hoist declaration of temp to top of
+	function.
+	* src/arm/ffi.c (ffi_closure_inner): Moderize function declaration
+	to appease compiler.
+	Thanks for Gregory P. Smith <[email protected]>.
+
+2013-11-18  Anthony Green  <[email protected]>
+
+	* README (tested): Mention PowerPC ELFv2.
+
+2013-11-16  Alan Modra  <[email protected]>
+
+	* src/powerpc/ppc_closure.S: Move errant #endif to where it belongs.
+	Don't bl .Luint128.
+
+2013-11-16  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use #if _CALL_ELF
+	test to select parameter save sizing for ELFv2 vs. ELFv1.
+	* src/powerpc/ffitarget.h (FFI_V2_TYPE_FLOAT_HOMOG,
+	FFI_V2_TYPE_DOUBLE_HOMOG, FFI_V2_TYPE_SMALL_STRUCT): Define.
+	(FFI_TRAMPOLINE_SIZE): Define variant for ELFv2.
+	* src/powerpc/ffi.c (FLAG_ARG_NEEDS_PSAVE): Define.
+	(discover_homogeneous_aggregate): New function.
+	(ffi_prep_args64): Adjust start of param save area for ELFv2.
+	Handle homogenous floating point struct parms.
+	(ffi_prep_cif_machdep_core): Adjust space calculation for ELFv2.
+	Handle ELFv2 return values.  Set FLAG_ARG_NEEDS_PSAVE.  Handle
+	homogenous floating point structs.
+	(ffi_call): Increase size of smst_buffer for ELFv2.  Handle ELFv2.
+	(flush_icache): Compile for ELFv2.
+	(ffi_prep_closure_loc): Set up ELFv2 trampoline.
+	(ffi_closure_helper_LINUX64): Don't return all structs directly
+	to caller.  Handle homogenous floating point structs.  Handle
+	ELFv2 struct return values.
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Set up r2 for
+	ELFv2.  Adjust toc save location.  Call function pointer using
+	r12.  Handle FLAG_RETURNS_SMST.  Don't predict branches.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Set up r2
+	for ELFv2.  Define ELFv2 versions of STACKFRAME, PARMSAVE, and
+	RETVAL.  Handle possibly missing parameter save area.  Handle
+	ELFv2 return values.
+	(.note.GNU-stack): Move inside outer #ifdef.
+
+2013-11-16  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Revert 2013-02-08
+	change.  Do not consume an int arg when returning a small struct
+	for FFI_SYSV ABI.
+	(ffi_call): Only use bounce buffer when FLAG_RETURNS_SMST.
+	Properly copy bounce buffer to destination.
+	* src/powerpc/sysv.S: Revert 2013-02-08 change.
+	* src/powerpc/ppc_closure.S: Remove stray '+'.
+
+2013-11-16  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args64): Align struct parameters
+	according to __STRUCT_PARM_ALIGN__.
+	(ffi_prep_cif_machdep_core): Likewise.
+	(ffi_closure_helper_LINUX64): Likewise.
+
+2013-11-16  Alan Modra  <[email protected]>
+
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Tweak restore of r28.
+	(.note.GNU-stack): Move inside outer #ifdef.
+	* src/powerpc/linux64_closure.S (STACKFRAME, PARMSAVE,
+	RETVAL): Define and use throughout.
+	(ffi_closure_LINUX64): Save fprs before buying stack.
+	(.note.GNU-stack): Move inside outer #ifdef.
+
+2013-11-16  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define.
+	(FFI_EXTRA_CIF_FIELDS): Define.
+	* src/powerpc/ffi.c (ffi_prep_args64): Save fprs as per the
+	ABI, not to both fpr and param save area.
+	(ffi_prep_cif_machdep_core): Renamed from ffi_prep_cif_machdep.
+	Keep initial flags.  Formatting.  Remove dead FFI_LINUX_SOFT_FLOAT
+	code.
+	(ffi_prep_cif_machdep, ffi_prep_cif_machdep_var): New functions.
+	(ffi_closure_helper_LINUX64): Pass floating point as per ABI,
+	not to both fpr and parameter save areas.
+
+	* libffi/testsuite/libffi.call/cls_double_va.c (main): Correct
+	function cast and don't call ffi_prep_cif.
+	* libffi/testsuite/libffi.call/cls_longdouble_va.c (main): Likewise.
+
+2013-11-15  Andrew Haley  <[email protected]>
+
+	* doc/libffi.texi (Closure Example): Fix the sample code.
+	* doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2013-11-15  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/va_struct1.c (main): Fix broken test.
+	* testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise
+	* testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise.
+	* testsuite/libffi.call/va_1.c (main): Likewise.
+
+2013-11-14  David Schneider  <[email protected]>
+
+	* src/arm/ffi.c: Fix register allocation for mixed float and
+	doubles.
+	* testsuite/libffi.call/cls_many_mixed_float_double.c: Testcase
+	for many mixed float and double arguments.
+
+2013-11-13  Alan Modra  <[email protected]>
+
+	* doc/libffi.texi (Simple Example): Correct example code.
+	* doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt.
+
+2013-11-13  Anthony Green  <[email protected]>
+
+	* include/ffi_common.h: Respect HAVE_ALLOCA_H for GNU compiler
+	based build. (Thanks to tmr111116 on github)
+
+2013-11-09  Anthony Green  <[email protected]>
+
+	* m4/libtool.m4: Refresh.
+	* configure, Makefile.in: Rebuilt.
+	* README: Add more notes about next release.
+
+2013-11-09  Shigeharu TAKENO  <[email protected]>
+
+	* m4/ax_gcc_archflag.m4 (ax_gcc_arch): Don't recognize
+	UltraSPARC-IIi as ultrasparc3.
+
+2013-11-06  Mark Kettenis  <[email protected]>
+
+	* src/x86/freebsd.S (ffi_call_SYSV): Align the stack pointer to
+        16-bytes.
+
+2013-11-06  Konstantin Belousov <[email protected]>
+
+	* src/x86/freebsd.S (ffi_closure_raw_SYSV): Mark the assembler
+	source as not requiring executable stack.
+
+2013-11-02  Anthony Green  <[email protected]>
+
+	* doc/libffi.texi (The Basics): Clarify return value buffer size
+	requirements.  Also, NULL result buffer pointers are no longer
+	supported.
+	* doc/libffi.info: Rebuilt.
+
+2013-11-02  Mischa Jonker  <[email protected]>
+
+	* Makefile.am (nodist_libffi_la_SOURCES): Fix build error.
+	* Makefile.in: Rebuilt.
+
+2013-11-02  David Schneider  <[email protected]>
+
+	* src/arm/ffi.c: more robust argument handling for closures on arm hardfloat
+	* testsuite/libffi.call/many_mixed.c: New file.
+	* testsuite/libffi.call/cls_many_mixed_args.c: More tests.
+
+2013-11-02  Vitaly Budovski
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32.
+
+2013-10-23  Mark H Weaver  <[email protected]>
+
+	* src/mips/ffi.c: Fix handling of uint32_t arguments on the
+	MIPS N32 ABI.
+
+2013-10-13  Sandra Loosemore  <[email protected]>
+
+	* README: Add Nios II to table of supported platforms.
+	* Makefile.am (EXTRA_DIST): Add nios2 files.
+	(nodist_libffi_la_SOURCES): Likewise.
+	* Makefile.in: Regenerated.
+	* configure.ac (nios2*-linux*): New host.
+	(NIOS2): Add AM_CONDITIONAL.
+	* configure: Regenerated.
+	* src/nios2/ffi.c: New.
+	* src/nios2/ffitarget.h: New.
+	* src/nios2/sysv.S: New.
+	* src/prep_cif.c (initialize_aggregate): Handle extra structure
+	alignment via FFI_AGGREGATE_ALIGNMENT.
+	(ffi_prep_cif_core): Conditionalize structure return for NIOS2.
+
+2013-10-10  Sandra Loosemore  <[email protected]>
+
+	* testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn):
+	Fix uninitialized variable.
+
+2013-10-11  Marcus Shawcroft  <[email protected]>
+
+	* testsuite/libffi.call/many.c (many): Replace * with +.
+
+2013-10-08  Ondřej Bílka  <[email protected]>
+
+	* src/aarch64/ffi.c, src/aarch64/sysv.S, src/arm/ffi.c,
+	src/arm/gentramp.sh, src/bfin/sysv.S, src/closures.c,
+	src/dlmalloc.c, src/ia64/ffi.c, src/microblaze/ffi.c,
+	src/microblaze/sysv.S, src/powerpc/darwin_closure.S,
+	src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/sh/ffi.c,
+	src/tile/tile.S, testsuite/libffi.call/nested_struct11.c: Fix
+	spelling errors.
+
+2013-10-08  Anthony Green  <[email protected]>
+
+	* aclocal.m4, compile, config.guess, config.sub, depcomp,
+	install-sh, mdate-sh, missing, texinfo.tex: Update from upstream.
+	* configure.ac: Update version to 3.0.14-rc0.
+	* Makefile.in, configure, Makefile.in, include/Makefile.in,
+	man/Makefile.in, testsuite/Makefile.in: Rebuilt.
+	* README: Mention M88K and VAX.
+
+2013-07-15  Miod Vallat  <[email protected]>
+
+	* Makefile.am,
+	configure.ac,
+	src/m88k/ffi.c,
+	src/m88k/ffitarget.h,
+	src/m88k/obsd.S,
+	src/vax/elfbsd.S,
+	src/vax/ffi.c,
+	src/vax/ffitarget.h: Add m88k and vax support.
+
+2013-06-24 Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration
+	before statements.
+	(ffi_prep_args64): Support little-endian.
+	(ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise.
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise.
+
+2013-06-12  Mischa Jonker  <[email protected]>
+
+	 * configure.ac: Add support for ARC.
+	 * Makefile.am: Likewise.
+	 * README: Add ARC details.
+	 * src/arc/arcompact.S: New.
+	 * src/arc/ffi.c: Likewise.
+	 * src/arc/ffitarget.h: Likewise.
+
+2013-03-28  David Schneider  <[email protected]>
+
+	 * src/arm/ffi.c: Fix support for ARM hard-float calling convention.
+	 * src/arm/sysv.S: call different methods for SYSV and VFP ABIs.
+	 * testsuite/libffi.call/cls_many_mixed_args.c: testcase for a closure with
+	 mixed arguments, many doubles.
+	 * testsuite/libffi.call/many_double.c: testcase for calling a function using
+	 more than 8 doubles.
+	 * testcase/libffi.call/many.c: use absolute value to check result against an
+	 epsilon
+
+2013-03-17  Anthony Green  <[email protected]>
+
+	* README: Update for 3.0.13.
+	* configure.ac: Ditto.
+	* configure: Rebuilt.
+	* doc/*: Update version.
+
+2013-03-17  Dave Korn  <[email protected]>
+
+	* src/closures.c (is_emutramp_enabled
+	[!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside
+	enclosing #if scope.
+
+2013-03-17  Anthony Green  <[email protected]>
+
+	* configure.ac: Only modify toolexecdir in certain cases.
+	* configure: Rebuilt.
+
+2013-03-16  Gilles Talis  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use
+	fparg_count,etc on __NO_FPRS__ targets.
+
+2013-03-16  Alan Hourihane  <[email protected]>
+
+	* src/m68k/sysv.S (epilogue): Don't use extb instruction on
+	m680000 machines.
+
+2013-03-16  Alex Gaynor <[email protected]>
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack.
+
+2013-03-13  Markos Chandras <[email protected]>
+
+	* configure.ac: Add support for Imagination Technologies Meta.
+	* Makefile.am: Likewise.
+	* README: Add Imagination Technologies Meta details.
+	* src/metag/ffi.c: New.
+	* src/metag/ffitarget.h: Likewise.
+	* src/metag/sysv.S: Likewise.
+
+2013-02-24  Andreas Schwab  <[email protected]>
+
+	* doc/libffi.texi (Structures): Fix missing category argument of
+	@deftp.
+
+2013-02-11  Anthony Green <[email protected]>
+
+	* configure.ac: Update release number to 3.0.12.
+	* configure: Rebuilt.
+	* README: Update release info.
+
+2013-02-10  Anthony Green <[email protected]>
+
+	* README: Add Moxie.
+	* src/moxie/ffi.c: Created.
+	* src/moxie/eabi.S: Created.
+	* src/moxie/ffitarget.h: Created.
+	* Makefile.am (nodist_libffi_la_SOURCES): Add Moxie.
+	* Makefile.in: Rebuilt.
+	* configure.ac: Add Moxie.
+	* configure: Rebuilt.
+	* testsuite/libffi.call/huge_struct.c: Disable format string
+	warnings for moxie*-*-elf tests.
+
+2013-02-10  Anthony Green <[email protected]>
+
+	* Makefile.am (LTLDFLAGS): Fix reference.
+	* Makefile.in: Rebuilt.
+
+2013-02-10  Anthony Green <[email protected]>
+
+	* README: Update supported platforms.  Update test results link.
+
+2013-02-09  Anthony Green <[email protected]>
+
+	* testsuite/libffi.call/negint.c: Remove forced -O2.
+	* testsuite/libffi.call/many2.c (foo): Remove GCCism.
+	* testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition.
+
+	* src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong
+	closure return type fix developed by Martin v. Löwis for cpython
+	fork.
+
+2013-02-08  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct
+	support.
+	* src/powerpc/sysv.S: Ditto.
+
+2013-02-08  Anthony Green <[email protected]>
+
+	* testsuite/libffi.call/cls_longdouble.c: Remove xfail for
+	arm*-*-*.
+
+2013-02-08  Anthony Green <[email protected]>
+
+	* src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC.
+
+2013-02-08  Matthias Klose  <[email protected]>
+
+	* man/ffi_prep_cif.3: Clean up for debian linter.
+
+2013-02-08  Peter Bergner  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed
+	on the stack.
+
+2013-02-08  Anthony Green <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add missing files.
+	* testsuite/Makefile.am (EXTRA_DIST): Ditto.
+	* Makefile.in: Rebuilt.
+
+2013-02-08  Anthony Green <[email protected]>
+
+	* configure.ac: Move sparc asm config checks to within functions
+	for compatibility with sun tools.
+	* configure: Rebuilt.
+	* src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9
+	systems.
+	* src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache
+	flusher.
+
+2013-02-08  Nathan Rossi <[email protected]>
+
+	* src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of
+	small big-endian structures.
+	(ffi_prep_args): Ditto.
+
+2013-02-07  Anthony Green <[email protected]>
+
+	* src/sparc/v8.S (ffi_call_v8): Fix typo from last patch
+	(effectively hiding ffi_call_v8).
+
+2013-02-07  Anthony Green <[email protected]>
+
+	* configure.ac: Update bug reporting address.
+	* configure.in: Rebuild.
+
+	* src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for
+	Sun compiler.
+	* src/sparc/ffi.c (ffi_call): Remove warning.
+	Call ffi_flush_icache for non-GCC builds.
+	(ffi_prep_closure_loc): Use ffi_flush_icache.
+
+	* Makefile.am (EXTRA_DIST): Add libtool-ldflags.
+	* Makefile.in: Rebuilt.
+	* libtool-ldflags: New file.
+
+2013-02-07  Daniel Schepler <[email protected]>
+
+	* configure.ac: Correctly identify x32 systems as 64-bit.
+	* m4/libtool.m4: Remove libtool expr error.
+	* aclocal.m4, configure: Rebuilt.
+
+2013-02-07  Anthony Green <[email protected]>
+
+	* configure.ac: Fix GCC usage test.
+	* configure: Rebuilt.
+	* README: Mention LLVM/GCC x86_64 issue.
+	* testsuite/Makefile.in: Rebuilt.
+
+2013-02-07  Anthony Green <[email protected]>
+
+	* testsuite/libffi.call/cls_double_va.c (main): Replace // style
+	comments with /* */ for xlc compiler.
+	* testsuite/libffi.call/stret_large.c (main): Ditto.
+	* testsuite/libffi.call/stret_large2.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct1.c (main): Ditto.
+	* testsuite/libffi.call/huge_struct.c (main): Ditto.
+	* testsuite/libffi.call/float_va.c (main): Ditto.
+	* testsuite/libffi.call/cls_struct_va1.c (main): Ditto.
+	* testsuite/libffi.call/cls_pointer_stack.c (main): Ditto.
+	* testsuite/libffi.call/cls_pointer.c (main): Ditto.
+	* testsuite/libffi.call/cls_longdouble_va.c (main): Ditto.
+
+2013-02-06  Anthony Green <[email protected]>
+
+	* man/ffi_prep_cif.3: Clean up for debian lintian checker.
+
+2013-02-06  Anthony Green <[email protected]>
+
+	* Makefile.am (pkgconfigdir): Add missing pkgconfig install bits.
+	* Makefile.in: Rebuild.
+
+2013-02-02  Mark H Weaver <[email protected]>
+
+	* src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed
+	via general purpose registers.
+
+2013-01-21  Nathan Rossi <[email protected]>
+
+	* README: Add MicroBlaze details.
+	* Makefile.am: Add MicroBlaze support.
+	* configure.ac: Likewise.
+	* src/microblaze/ffi.c: New.
+	* src/microblaze/ffitarget.h: Likewise.
+	* src/microblaze/sysv.S: Likewise.
+
+2013-01-21  Nathan Rossi <[email protected]>
+	* testsuite/libffi.call/return_uc.c: Fixed issue.
+
+2013-01-21  Chris Zankel   <[email protected]>
+
+	* README: Add Xtensa support.
+	* Makefile.am: Likewise.
+	* configure.ac: Likewise.
+	* Makefile.in Regenerate.
+	* configure: Likewise.
+	* src/prep_cif.c: Handle Xtensa.
+	* src/xtensa: New directory.
+	* src/xtensa/ffi.c: New file.
+	* src/xtensa/ffitarget.h: Ditto.
+	* src/xtensa/sysv.S: Ditto.
+
+2013-01-11  Anthony Green  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style
+	comments with /* */ for xlc compiler.
+	* src/powerpc/aix.S (ffi_call_AIX): Ditto.
+	* testsuite/libffi.call/ffitest.h (allocate_mmap): Delete
+	deprecated inline function.
+	* testsuite/libffi.special/ffitestcxx.h: Ditto.
+	* README: Add update for AIX support.
+
+2013-01-11  Anthony Green  <[email protected]>
+
+	* configure.ac: Robustify pc relative reloc check.
+	* m4/ax_cc_maxopt.m4: Don't -malign-double.  This is an ABI
+	changing option for 32-bit x86.
+	* aclocal.m4, configure: Rebuilt.
+	* README: Update supported target list.
+
+2013-01-10  Anthony Green  <[email protected]>
+
+	* README (tested): Add Compiler column to table.
+
+2013-01-10  Anthony Green  <[email protected]>
+
+	* src/x86/ffi64.c (struct register_args): Make sse array and array
+	of unions for sunpro compiler compatibility.
+
+2013-01-10  Anthony Green  <[email protected]>
+
+	* configure.ac: Test target platform size_t size.  Handle both 32
+	and 64-bit builds for x86_64-* and i?86-* targets (allowing for
+	CFLAG option to change default settings).
+	* configure, aclocal.m4: Rebuilt.
+
+2013-01-10  Anthony Green  <[email protected]>
+
+	* testsuite/libffi.special/special.exp: Only run exception
+	handling tests when using GNU compiler.
+
+	* m4/ax_compiler_vendor.m4: New file.
+	* configure.ac: Test for compiler vendor and don't use
+	AX_CFLAGS_WARN_ALL with the sun compiler.
+	* aclocal.m4, configure: Rebuilt.
+
+2013-01-10  Anthony Green  <[email protected]>
+
+	* include/ffi_common.h: Don't use GCCisms to define types when
+	building with the SUNPRO compiler.
+
+2013-01-10  Anthony Green  <[email protected]>
+
+	* configure.ac: Put local.exp in the right place.
+	* configure: Rebuilt.
+
+	* src/x86/ffi.c: Update comment about regparm function attributes.
+	* src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires
+	that all function arguments be passed on the stack (no regparm
+	support).
+
+2013-01-08  Anthony Green  <[email protected]>
+
+	* configure.ac: Generate local.exp.  This sets CC_FOR_TARGET
+	when we are using the vendor compiler.
+	* testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to
+	../local.exp.
+	* configure, testsuite/Makefile.in: Rebuilt.
+
+	* testsuite/libffi.call/call.exp: Run tests with different
+	options, depending on whether or not we are using gcc or the
+	vendor compiler.
+	* testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on
+	whether or not we are building/testing with gcc.
+
+2013-01-08  Anthony Green  <[email protected]>
+
+	* configure.ac: Switch x86 solaris target to X86 by default.
+	* configure: Rebuilt.
+
+2013-01-08  Anthony Green  <[email protected]>
+
+	* configure.ac: Fix test for read-only eh_frame.
+	* configure: Rebuilt.
+
+2013-01-08  Anthony Green  <[email protected]>
+
+	* src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info
+	when building with the GNU toolchain.
+	* testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor
+	compiler.
+
+2013-01-07  Thorsten Glaser <[email protected]>
+
+	* testsuite/libffi.call/cls_uchar_va.c,
+	testsuite/libffi.call/cls_ushort_va.c,
+	testsuite/libffi.call/va_1.c: Testsuite fixes.
+
+2013-01-07  Thorsten Glaser <[email protected]>
+
+	* src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define.
+	(ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls.
+	* src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto.
+
+2013-01-04  Anthony Green  <[email protected]>
+
+	* Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions
+	and -Wall.  This is set in the configure script after testing for
+	GCC.
+	* Makefile.in: Rebuilt.
+
+2013-01-02  rofl0r <https://github.com/rofl0r>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc
+	when long double == double.
+
+2013-01-02  Reini Urban  <[email protected]>
+
+	* Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS
+	(required for shared libs on cygwin/mingw).
+	* Makefile.in: Rebuilt.
+
+2012-10-31  Alan Modra  <[email protected]>
+
+	* src/powerpc/linux64_closure.S: Add new ABI support.
+	* src/powerpc/linux64.S: Likewise.
+
+2012-10-30  Magnus Granberg  <[email protected]>
+	    Pavel Labushev  <[email protected]>
+
+	* configure.ac: New options pax_emutramp
+	* configure, fficonfig.h.in: Regenerated
+	* src/closures.c: New function emutramp_enabled_check() and
+	checks.
+
+2012-10-30  Frederick Cheung  <[email protected]>
+
+	* configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain
+	lion) and future version.
+	* configure: Rebuild.
+
+2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
+            Marcus Shawcroft  <marcus.shawcroft at arm.com>
+
+        * README: Add details of aarch64 port.
+        * src/aarch64/ffi.c: New.
+        * src/aarch64/ffitarget.h: Likewise.
+        * src/aarch64/sysv.S: Likewise.
+	* Makefile.am: Support aarch64.
+	* configure.ac: Support aarch64.
+	* Makefile.in, configure: Rebuilt.
+
+2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
+            Marcus Shawcroft  <marcus.shawcroft at arm.com>
+
+        * testsuite/lib/libffi.exp: Add support for aarch64.
+        * testsuite/libffi.call/cls_struct_va1.c: New.
+        * testsuite/libffi.call/cls_uchar_va.c: Likewise.
+        * testsuite/libffi.call/cls_uint_va.c: Likewise.
+        * testsuite/libffi.call/cls_ulong_va.c: Likewise.
+        * testsuite/libffi.call/cls_ushort_va.c: Likewise.
+        * testsuite/libffi.call/nested_struct11.c: Likewise.
+        * testsuite/libffi.call/uninitialized.c: Likewise.
+        * testsuite/libffi.call/va_1.c: Likewise.
+        * testsuite/libffi.call/va_struct1.c: Likewise.
+        * testsuite/libffi.call/va_struct2.c: Likewise.
+        * testsuite/libffi.call/va_struct3.c: Likewise.
+
+2012-10-12  Walter Lee  <[email protected]>
+
+        * Makefile.am: Add TILE-Gx/TILEPro support.
+        * configure.ac: Likewise.
+        * Makefile.in: Regenerate.
+        * configure: Likewise.
+        * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro.
+        * src/tile: New directory.
+        * src/tile/ffi.c: New file.
+        * src/tile/ffitarget.h: Ditto.
+        * src/tile/tile.S: Ditto.
+
+2012-10-12  Matthias Klose  <[email protected]>
+
+	* generate-osx-source-and-headers.py: Normalize whitespace.
+
+2012-09-14  David Edelsohn  <[email protected]>
+
+	* configure: Regenerated.
+
+2012-08-26  Andrew Pinski  <[email protected]>
+
+	PR libffi/53014
+	* src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with
+	soft-float.
+
+2012-08-08  Uros Bizjak  <[email protected]>
+
+	* src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
+	just return FFI_BAD_ABI when things are wrong.
+
+2012-07-18  H.J. Lu  <[email protected]>
+
+	PR libffi/53982
+	PR libffi/53973
+	* src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32.
+	(FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32.
+
+2012-05-16  H.J. Lu  <[email protected]>
+
+	* configure: Regenerated.
+
+2012-05-05  Nicolas Lelong
+
+	* libffi.xcodeproj/project.pbxproj: Fixes.
+	* README: Update for iOS builds.
+
+2012-04-23  Alexandre Keunecke I. de Mendonca <[email protected]>
+
+	* configure.ac: Add Blackfin/sysv support
+	* Makefile.am: Add Blackfin/sysv support
+	* src/bfin/ffi.c:  Add Blackfin/sysv support
+	* src/bfin/ffitarget.h: Add Blackfin/sysv support
+
+2012-04-11  Anthony Green  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add new script.
+	* Makefile.in: Rebuilt.
+
+2012-04-11  Zachary Waldowski  <[email protected]>
+
+	* generate-ios-source-and-headers.py,
+	libffi.xcodeproj/project.pbxproj: Support a Mac static library via
+	Xcode. Set iOS compatibility to 4.0.  Move iOS trampoline
+	generation into an Xcode "run script" phase.  Include both as
+	Xcode build scripts. Don't always regenerate config files.
+
+2012-04-10  Anthony Green  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon.
+
+2012-04-06  Anthony Green  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add new iOS/xcode files.
+	* Makefile.in: Rebuilt.
+
+2012-04-06  Mike Lewis  <[email protected]>
+
+	* generate-ios-source-and-headers.py: New file.
+	* libffi.xcodeproj/project.pbxproj: New file.
+	* README: Update instructions on building iOS binary.
+	* build-ios.sh: Delete.
+
+2012-04-06  Anthony Green  <[email protected]>
+
+	* src/x86/ffi64.c (UINT128): Define differently for Intel and GNU
+	compilers, then use it.
+
+2012-04-06  H.J. Lu  <[email protected]>
+
+	* m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32.
+
+2012-04-06  Anthony Green  <[email protected]>
+
+	* testsuite/Makefile.am (EXTRA_DIST): Add missing test cases.
+	* testsuite/Makefile.in: Rebuilt.
+
+2012-04-05  Zachary Waldowski  <[email protected]>
+
+	* include/ffi.h.in: Add missing trampoline table fields.
+	* src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references
+	in CNAME.
+	* src/x86/ffi.c: Wrap Windows specific code in ifdefs.
+
+2012-04-02  Peter Bergner  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp.
+	Silence casting pointer to integer of different size warning.
+	Delete goto to previously deleted label.
+	(ffi_call): Silence possibly undefined warning.
+	(ffi_closure_helper_SYSV): Declare variable type.
+
+2012-04-02  Peter Rosin  <[email protected]>
+
+	* src/x86/win32.S (ffi_call_win32): Sign/zero extend the return
+	value in the Intel version as is already done for the AT&T version.
+	(ffi_closure_SYSV): Likewise.
+	(ffi_closure_raw_SYSV): Likewise.
+	(ffi_closure_STDCALL): Likewise.
+
+2012-03-29  Peter Rosin  <[email protected]>
+
+	* src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame
+	generation, fix the ENDP label and remove the surplus third arg
+	from the 'lea' insn.
+
+2012-03-29  Peter Rosin  <[email protected]>
+
+	* src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label
+	visible outside the PROC, so that ffi_closure_raw_THISCALL can see
+	it.  Also instruct the assembler to add a frame to the function.
+
+2012-03-23  Peter Rosin  <[email protected]>
+
+	* Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING.
+	* Makefile.in: Rebuilt.
+	* include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations
+	to all data exports, when compiling libffi clients using MSVC.
+
+2012-03-29  Peter Rosin  <[email protected]>
+
+	* src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and
+	make it the default for MSVC.
+	(FFI_TYPE_MS_STRUCT): New structure return convention.
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure
+	return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT
+	instead of an ordinary FFI_TYPE_STRUCT.
+	(ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+	(ffi_call): Likewise.
+	(ffi_prep_incoming_args_SYSV): Likewise.
+	(ffi_raw_call): Likewise.
+	(ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV.
+	* src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT,
+	return a pointer to the result structure in eax and don't pop
+	that pointer from the stack, the caller takes care of it.
+	(ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT.
+	(ffi_closure_raw_SYSV): Likewise.
+
+2012-03-22  Peter Rosin  <[email protected]>
+
+	* testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline
+	assembly version with Intel syntax.
+	* testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise.
+
+2012-03-23  Peter Rosin  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h: Provide abstration of
+	__attribute__((fastcall)) in the form of a __FASTCALL__
+	define.  Define it to __fastcall for MSVC.
+	* testsuite/libffi.call/fastthis1_win32.c: Use the above.
+	* testsuite/libffi.call/fastthis2_win32.c: Likewise.
+	* testsuite/libffi.call/fastthis3_win32.c: Likewise.
+	* testsuite/libffi.call/strlen2_win32.c: Likewise.
+	* testsuite/libffi.call/struct1_win32.c: Likewise.
+	* testsuite/libffi.call/struct2_win32.c: Likewise.
+
+2012-03-22  Peter Rosin  <[email protected]>
+
+	* src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual
+	frame on function entry, MASM adds one automatically.
+
+2012-03-22  Peter Rosin  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing
+	bits in the MSVC headers.
+
+2012-03-22  Peter Rosin  <[email protected]>
+
+	* testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style
+	with no declarations after statements.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_align_double.c: Likewise.
+	* testsuite/libffi.call/cls_align_float.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble_split.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
+	* testsuite/libffi.call/cls_dbls_struct.c: Likewise.
+	* testsuite/libffi.call/cls_pointer_stack.c: Likewise.
+	* testsuite/libffi.call/err_bad_typedef.c: Likewise.
+	* testsuite/libffi.call/huge_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/nested_struct10.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+	* testsuite/libffi.call/nested_struct4.c: Likewise.
+	* testsuite/libffi.call/nested_struct5.c: Likewise.
+	* testsuite/libffi.call/nested_struct6.c: Likewise.
+	* testsuite/libffi.call/nested_struct7.c: Likewise.
+	* testsuite/libffi.call/nested_struct8.c: Likewise.
+	* testsuite/libffi.call/nested_struct9.c: Likewise.
+	* testsuite/libffi.call/stret_large.c: Likewise.
+	* testsuite/libffi.call/stret_large2.c: Likewise.
+	* testsuite/libffi.call/stret_medium.c: Likewise.
+	* testsuite/libffi.call/stret_medium2.c: Likewise.
+	* testsuite/libffi.call/struct1.c: Likewise.
+	* testsuite/libffi.call/struct1_win32.c: Likewise.
+	* testsuite/libffi.call/struct2.c: Likewise.
+	* testsuite/libffi.call/struct2_win32.c: Likewise.
+	* testsuite/libffi.call/struct3.c: Likewise.
+	* testsuite/libffi.call/struct4.c: Likewise.
+	* testsuite/libffi.call/struct5.c: Likewise.
+	* testsuite/libffi.call/struct6.c: Likewise.
+	* testsuite/libffi.call/struct7.c: Likewise.
+	* testsuite/libffi.call/struct8.c: Likewise.
+	* testsuite/libffi.call/struct9.c: Likewise.
+	* testsuite/libffi.call/testclosure.c: Likewise.
+
+2012-03-21  Peter Rosin	 <[email protected]>
+
+	* testsuite/libffi.call/float_va.c (float_va_fn): Use %f when
+	printing doubles (%lf is for long doubles).
+	(main): Likewise.
+
+2012-03-21  Peter Rosin  <[email protected]>
+
+	* testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*]
+	(set_ld_library_path_env_vars): Add the library search dir to PATH
+	(and save PATH for later).
+	(restore_ld_library_path_env_vars): Restore PATH.
+
+2012-03-21  Peter Rosin  <[email protected]>
+
+	* testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*]
+	(set_ld_library_path_env_vars): Add the library search dir to PATH
+	(and save PATH for later).
+	(restore_ld_library_path_env_vars): Restore PATH.
+
+2012-03-20  Peter Rosin  <[email protected]>
+
+	* testsuite/libffi.call/strlen2_win32.c (main): Remove bug.
+	* src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label
+	visible outside the PROC, so that ffi_closure_THISCALL can see it.
+
+2012-03-20  Peter Rosin  <[email protected]>
+
+	* testsuite/libffi.call/strlen2_win32.c (main): Remove bug.
+	* src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label
+	visible outside the PROC, so that ffi_closure_THISCALL can see it.
+
+2012-03-19  Alan Hourihane  <[email protected]>
+
+	* src/m68k/ffi.c: Add MINT support.
+	* src/m68k/sysv.S: Ditto.
+
+2012-03-06  Chung-Lin Tang  <[email protected]>
+
+	* src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to
+	ffi_call_VFP().
+	(ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of
+	ffi_closure_VFP.
+	* src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code.
+
+2012-03-19  chennam  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure
+	support.
+
+2012-03-13  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
+	just return FFI_BAD_ABI when things are wrong.
+	* src/sh64/ffi.c (ffi_prep_closure_loc): Ditto.
+
+2012-03-09  David Edelsohn  <[email protected]>
+
+	* src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64
+	change to return value of ffi_closure_helper_DARWIN and load type
+	from return type.
+
+2012-03-03  H.J. Lu  <[email protected]>
+
+	* src/x86/ffi64.c (ffi_call): Cast the return value to unsigned
+	long.
+	(ffi_prep_closure_loc): Cast to 64bit address in trampoline.
+	(ffi_closure_unix64_inner): Cast return pointer to unsigned long
+	first.
+
+	* src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32.
+	(ffi_arg): Set to unsigned long long for x32.
+	(ffi_sarg): Set to long long for x32.
+
+2012-03-03  H.J. Lu  <[email protected]>
+
+	* src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI.
+
+2012-03-03  Andoni Morales Alastruey  <[email protected]>
+
+	* configure.ac: Add -no-undefined for both 32- and 64-bit x86
+	windows-like hosts.
+	* configure: Rebuilt.
+
+2012-02-27  Mikael Pettersson  <[email protected]>
+
+	PR libffi/52223
+	* Makefile.am (FLAGS_TO_PASS): Define.
+	* Makefile.in: Regenerate.
+
+2012-02-23  Anthony Green  <[email protected]>
+
+	* src/*/ffitarget.h: Ensure that users never include ffitarget.h
+	directly.
+
+2012-02-23  Kai Tietz  <[email protected]>
+
+	PR libffi/52221
+	* src/x86/ffi.c (ffi_closure_raw_THISCALL): New
+	prototype.
+	(ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for
+	thiscall-convention.
+	(ffi_raw_call): Use ffi_prep_args_raw.
+	* src/x86/win32.S (ffi_closure_raw_THISCALL): Add
+	implementation for stub.
+
+2012-02-10  Kai Tietz  <[email protected]>
+
+	* configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64
+	windows target.
+	* configure: Regenerated.
+
+2012-02-08  Kai Tietz  <[email protected]>
+
+	* src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32
+	also FFI_THISCALL.
+	* src/x86/ffi.c (ffi_closure_THISCALL): Add prototype.
+	(FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code.
+	(ffi_prep_closure_loc): Add FFI_THISCALL support.
+	* src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size.
+	* src/x86/win32.S (ffi_closure_THISCALL): New closure code
+	for thiscall-calling convention.
+	* testsuite/libffi.call/closure_thiscall.c: New test.
+
+2012-01-28  Kai Tietz  <[email protected]>
+
+	* src/libffi/src/x86/ffi.c (ffi_call_win32): Add new
+	argument to prototype for specify calling-convention.
+	(ffi_call): Add support for stdcall/thiscall convention.
+	(ffi_prep_args): Likewise.
+	(ffi_raw_call): Likewise.
+	* src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and
+	FFI_FASTCALL.
+	* src/x86/win32.S (_ffi_call_win32): Add support for
+	fastcall/thiscall calling-convention calls.
+	* testsuite/libffi.call/fastthis1_win32.c: New test.
+	* testsuite/libffi.call/fastthis2_win32.c: New test.
+	* testsuite/libffi.call/fastthis3_win32.c: New test.
+	* testsuite/libffi.call/strlen2_win32.c: New test.
+	* testsuite/libffi.call/many2_win32.c: New test.
+	* testsuite/libffi.call/struct1_win32.c: New test.
+	* testsuite/libffi.call/struct2_win32.c: New test.
+
+2012-01-23  Uros Bizjak  <[email protected]>
+
+	* src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI.
+
+2012-01-23  Anthony Green  <[email protected]>
+	    Chris Young  <[email protected]>
+
+	* configure.ac: Add Amiga support.
+	* configure: Rebuilt.
+
+2012-01-23  Dmitry Nadezhin  <[email protected]>
+
+	* include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions.
+
+2012-01-23  Andreas Schwab  <[email protected]>
+
+	* src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain
+	mc68000.  Test for __HAVE_68881__ in addition to __MC68881__.
+
+2012-01-19  Jakub Jelinek  <[email protected]>
+
+	PR rtl-optimization/48496
+	* src/ia64/ffi.c (ffi_call): Fix up aliasing violations.
+
+2012-01-09  Rainer Orth  <[email protected]>
+
+	* configure.ac (i?86-*-*): Set TARGET to X86_64.
+	* configure: Regenerate.
+
+2011-12-07  Andrew Pinski  <[email protected]>
+
+	PR libffi/50051
+	* src/mips/n32.S: Add ".set mips4".
+
+2011-11-21  Andreas Tobler  <[email protected]>
+
+	* configure: Regenerate.
+
+2011-11-12  David Gilbert <[email protected]>
+
+	* doc/libffi.texi, include/ffi.h.in, include/ffi_common.h,
+	man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3,
+	man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h,
+	src/cris/ffi.c, src/prep_cif.c,
+	testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/float_va.c: Many changes to support variadic
+	function calls.
+
+2011-11-12  Kyle Moffett <[email protected]>
+
+	* src/powerpc/ffi.c, src/powerpc/ffitarget.h,
+	src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for
+	softfloat powerpc variants.
+
+2011-11-12  Petr Salinger <[email protected]>
+
+	* configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support.
+	* configure: Rebuilt.
+
+2011-11-12  Timothy Wall  <[email protected]>
+
+	* src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max
+	alignment of 4 for wince on ARM.
+
+2011-11-12  Kyle Moffett <[email protected]>
+	    Anthony Green <[email protected]>
+
+	* src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string
+	instructions (not available on some cores, like the PPC440).
+
+2011-11-12  Kimura Wataru  <[email protected]>
+
+	* m4/ax_enable_builddir: Change from string comparison to numeric
+	comparison for wc output.
+	* configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS
+	X 10.7.
+	* configure: Rebuilt.
+
+2011-11-12  Anthony Green  <[email protected]>
+
+	* Makefile.am (AM_CCASFLAGS): Add -g option to build assembly
+	files with debug info.
+	* Makefile.in: Rebuilt.
+
+2011-11-12  Jasper Lievisse Adriaanse <[email protected]>
+
+	* README: Update list of supported OpenBSD systems.
+
+2011-11-12  Anthony Green  <[email protected]>
+
+	* libtool-version: Update.
+	* Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if
+	FFI_DEBUG.
+	(libffi_la_SOURCES): Remove src/debug.c
+	(EXTRA_DIST): Add src/debug.c
+	* Makefile.in: Rebuilt.
+	* README: Update for 3.0.11.
+
+2011-11-10  Richard Henderson  <[email protected]>
+
+	* configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check.
+	* configure, aclocal.m4: Rebuild.
+
+2011-09-04  Iain Sandoe  <[email protected]>
+
+	PR libffi/49594
+	* src/powerpc/darwin_closure.S (stubs): Make the stub binding
+	helper reference track the architecture pointer size.
+
+2011-08-25  Andrew Haley  <[email protected]>
+
+	* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly
+	instructions.
+	* src/arm/sysv.S (ffi_arm_trampoline): Put them here instead.
+
+2011-07-11  Andrew Haley  <[email protected]>
+
+        * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache.
+
+2011-06-29  Rainer Orth  <[email protected]>
+
+	* testsuite/libffi.call/cls_double_va.c: Move PR number to comment.
+	* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
+
+2011-06-29  Rainer Orth  <[email protected]>
+
+	PR libffi/46660
+	* testsuite/libffi.call/cls_double_va.c: xfail dg-output on
+	mips-sgi-irix6*.
+	* testsuite/libffi.call/cls_longdouble_va.c: Likewise.
+
+2011-06-14  Rainer Orth  <[email protected]>
+
+	* testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8,
+	PRId8 instead of %hhu, %hhd.
+	* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8,
+	PRIu8): Define.
+	[__sgi__] (PRId8, PRIu8): Define.
+
+2011-04-29  Rainer Orth  <[email protected]>
+
+	* src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE):
+	Define.
+	Use them to handle ELF vs. ECOFF differences.
+	[__osf__] (_GLOBAL__F_ffi_call_osf): Define.
+
+2011-03-30  Timothy Wall  <[email protected]>
+
+	* src/powerpc/darwin.S: Fix unknown FDE encoding.
+	* src/powerpc/darwin_closure.S: ditto.
+
+2011-02-25  Anthony Green  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more
+	32-bit ABIs.
+
+2011-02-15  Anthony Green  <[email protected]>
+
+	* m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math.
+	* configure: Rebuilt.
+
+2011-02-13  Ralf Wildenhues  <[email protected]>
+
+	* configure: Regenerate.
+
+2011-02-13  Anthony Green  <[email protected]>
+
+	* include/ffi_common.h (UNLIKELY, LIKELY): Define.
+	* src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition.
+	* src/prep_cif.c (UNLIKELY, LIKELY): Remove definition.
+
+	* src/prep_cif.c (initialize_aggregate): Convert assertion into
+	FFI_BAD_TYPEDEF return.  Initialize arg size and alignment to 0.
+
+	* src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
+	just return FFI_BAD_ABI when things are wrong.
+	* src/arm/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/mips/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/ia64/ffi.c (ffi_prep_closure_loc): Ditto.
+	* src/avr32/ffi.c (ffi_prep_closure_loc): Ditto.
+
+2011-02-11  Anthony Green  <[email protected]>
+
+	* src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
+	just return FFI_BAD_ABI when things are wrong.
+
+2012-02-11  Eric Botcazou  <[email protected]>
+
+	* src/sparc/v9.S (STACKFRAME): Bump to 176.
+
+2011-02-09  Stuart Shelton  <[email protected]>
+
+	http://bugs.gentoo.org/show_bug.cgi?id=286911
+	* src/mips/ffitarget.h: Clean up error messages.
+	* src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to
+	ffi_raw*.
+	* include/ffi.h.in: Add pragma for SGI compiler.
+
+2011-02-09  Anthony Green  <[email protected]>
+
+	* configure.ac: Add powerpc64-*-darwin* support.
+
+2011-02-09  Anthony Green <[email protected]>
+
+	* README: Mention Interix.
+
+2011-02-09  Jonathan Callen  <[email protected]>
+
+	* configure.ac: Add Interix to win32/cygwin/mingw case.
+	* configure: Ditto.
+	* src/closures.c: Treat Interix like Cygwin, instead of as a
+	generic win32.
+
+2011-02-09  Anthony Green <[email protected]>
+
+	* testsuite/libffi.call/err_bad_typedef.c: Remove xfail.
+	* testsuite/libffi.call/err_bad_abi.c: Remove xfail.
+	* src/x86/ffi64.c (UNLIKELY, LIKELY): Define.
+	(ffi_prep_closure_loc): Check for bad ABI.
+	* src/prep_cif.c (UNLIKELY, LIKELY): Define.
+	(initialize_aggregate): Check for bad types.
+
+2011-02-09  Landon Fuller <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh,
+	src/arm/trampoline.S.
+	(nodist_libffi_la_SOURCES): Add src/arc/trampoline.S.
+	* configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define.
+	* src/arm/ffi.c (ffi_trampoline_table)
+	(ffi_closure_trampoline_table_page, ffi_trampoline_table_entry)
+	(FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET)
+	(FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables)
+	(ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free):
+	Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS).
+	(ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case
+	separately.
+	* src/arm/sysv.S: Handle Apple iOS host.
+	* src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case.
+	* build-ios.sh: New file.
+	* fficonfig.h.in, configure, Makefile.in: Rebuilt.
+	* README: Mention ARM iOS.
+
+2011-02-08  Oren Held  <[email protected]>
+
+	* src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid
+	redefinition of mallinfo on HP-UX.
+
+2011-02-08  Ginn Chen  <[email protected]>
+
+	* src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio
+	aggregate return ABI.  Flush cache.
+	(ffi_prep_closure_loc): Flush cache.
+
+2011-02-11  Anthony Green  <[email protected]>
+
+	From Tom Honermann <[email protected]>:
+	* src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on
+	AIX.  Declare .ffi_prep_args.  Insert nops after branch
+	instructions so that the AIX linker can insert TOC reload
+	instructions.
+	* src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN.
+
+2011-02-08  Ed  <[email protected]>
+
+	* src/powerpc/asm.h: Fix grammar nit in comment.
+
+2011-02-08  Uli Link  <[email protected]>
+
+	* include/ffi.h.in (FFI_64_BIT_MAX): Define and use.
+
+2011-02-09  Rainer Orth  <[email protected]>
+
+	PR libffi/46661
+	* testsuite/libffi.call/cls_pointer.c (main): Cast void * to
+	uintptr_t first.
+	* testsuite/libffi.call/cls_pointer_stack.c (main): Likewise.
+
+2011-02-08  Rafael Avila de Espindola  <[email protected]>
+
+	* configure.ac: Fix x86 test for pc related relocs.
+	* configure: Rebuilt.
+
+2011-02-07  Joel Sherrill <[email protected]>
+
+	* libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing.
+	Handle case when CPU variant does not have long double support.
+	* libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire,
+	and cores with soft floating point.
+
+2011-02-07  Joel Sherrill <[email protected]>
+
+	* configure.ac: Add mips*-*-rtems* support.
+	* configure: Regenerate.
+	* src/mips/ffitarget.h: Ensure needed constants are available
+	for targets which do not have sgidefs.h.
+
+2011-01-26  Dave Korn  <[email protected]>
+
+	PR target/40125
+	* configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs.
+	* configure: Regenerate.
+
+2010-12-18  Iain Sandoe  <[email protected]>
+
+	PR libffi/29152
+	PR libffi/42378
+	* src/powerpc/darwin_closure.S: Provide Darwin64 implementation,
+	update comments.
+	* src/powerpc/ffitarget.h (POWERPC_DARWIN64): New,
+	(FFI_TRAMPOLINE_SIZE): Update for Darwin64.
+	* src/powerpc/darwin.S: Provide Darwin64 implementation,
+	update comments.
+	* src/powerpc/ffi_darwin.c: Likewise.
+
+2010-12-06  Rainer Orth  <[email protected]>
+
+	* configure.ac (libffi_cv_as_ascii_pseudo_op): Use double
+	backslashes.
+	(libffi_cv_as_string_pseudo_op): Likewise.
+	* configure: Regenerate.
+
+2010-12-03  Chung-Lin Tang  <[email protected]>
+
+	* src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive.
+	(ffi_closure_VFP): Same.
+	(ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp'
+	directive.
+
+2010-12-01  Rainer Orth  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define.
+	(PRIuPTR): Define.
+
+2010-11-29  Richard Henderson  <[email protected]>
+	    Rainer Orth  <[email protected]>
+
+	* src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define.
+	(.eh_frame): Use FDE_ENCODING.
+	(.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE.
+
+2010-11-22  Jacek Caban <[email protected]>
+
+	* configure.ac: Check for symbol underscores on mingw-w64.
+	* configure: Rebuilt.
+	* src/x86/win64.S: Correctly access extern symbols in respect to
+	underscores.
+
+2010-11-15  Rainer Orth  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Rename ...
+	* testsuite/lib/libffi.exp: ... to this.
+	* libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp.
+	* libffi/testsuite/libffi.special/special.exp: Likewise.
+
+2010-10-28  Chung-Lin Tang  <[email protected]>
+
+	* src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling
+	code, new parameter, and return value. Update comments.
+	(ffi_prep_cif_machdep): Add case for VFP struct return values. Add
+	call to layout_vfp_args().
+	(ffi_call_SYSV): Update declaration.
+	(ffi_call_VFP): New declaration.
+	(ffi_call): Add VFP struct return conditions. Call ffi_call_VFP()
+	when ABI is FFI_VFP.
+	(ffi_closure_VFP): New declaration.
+	(ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to
+	ffi_prep_incoming_args_SYSV().
+	(ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument
+	case handling.
+	(ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline
+	construction under VFP hard-float.
+	(rec_vfp_type_p): New function.
+	(vfp_type_p): Same.
+	(place_vfp_arg): Same.
+	(layout_vfp_args): Same.
+	* src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI
+	based on __ARM_PCS_VFP.
+	(FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific
+	fields.
+	(FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code.
+	(FFI_TYPE_STRUCT_VFP_DOUBLE): Same.
+	* src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to
+	direct call. Move function pointer load upwards.
+	(ffi_call_VFP): New function.
+	(ffi_closure_VFP): Same.
+
+	* testsuite/lib/libffi-dg.exp (check-flags): New function.
+	(dg-skip-if): New function.
+	* testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-*
+	and compiler options include -mfloat-abi=hard.
+	* testsuite/libffi.call/cls_longdouble_va.c: Same.
+
+2010-10-01  Jakub Jelinek  <[email protected]>
+
+	PR libffi/45677
+	* src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is
+	a multiple of 8.
+	* testsuite/libffi.call/many2.c: New test.
+
+2010-08-20  Mark Wielaard  <[email protected]>
+
+	* src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r
+	returns NULL.
+
+2010-08-09  Andreas Tobler  <[email protected]>
+
+	* configure.ac: Add target powerpc64-*-freebsd*.
+	* configure: Regenerate.
+	* testsuite/libffi.call/cls_align_longdouble_split.c: Pass
+	-mlong-double-128 only to linux targets.
+	* testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise.
+	* testsuite/libffi.call/cls_longdouble.c: Likewise.
+	* testsuite/libffi.call/huge_struct.c: Likewise.
+
+2010-08-05  Dan Witte  <[email protected]>
+
+        * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the
+        debug CRT when --enable-debug is given.
+        * configure.ac: Define it.
+        * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately.
+
+2010-08-04  Dan Witte  <[email protected]>
+
+	* src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64
+	platforms.
+	* src/x86/ffi.c: Remove redundant ifdef checks.
+	* src/prep_cif.c: Push stack space computation into src/x86/ffi.c
+	for X86_ANY so return value space doesn't get added twice.
+
+2010-08-03  Neil Rashbrooke <[email protected]>
+
+	* msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy.
+
+2010-07-22  Dan Witte  <[email protected]>
+
+	* src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI.
+	* src/prep_cif.c: Fix ABI assertion.
+        * src/cris/ffi.c: Ditto.
+
+2010-07-10  Evan Phoenix  <[email protected]>
+
+	* src/closures.c (selinux_enabled_check): Fix strncmp usage bug.
+
+2010-07-07  Dan Horák <[email protected]>
+
+	* include/ffi.h.in: Protect #define with #ifndef.
+	* src/powerpc/ffitarget.h: Ditto.
+	* src/s390/ffitarget.h: Ditto.
+	* src/sparc/ffitarget.h: Ditto.
+
+2010-07-07   Neil Roberts <[email protected]>
+
+	* src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to
+	16-bytes.
+
+2010-07-02  Jakub Jelinek  <[email protected]>
+
+	* Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes.
+	* Makefile.in: Regenerated.
+
+2010-05-19  Rainer Orth  <[email protected]>
+
+	* configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as
+	output, too.
+	(libffi_cv_as_ascii_pseudo_op): Check for .ascii.
+	(libffi_cv_as_string_pseudo_op): Check for .string.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* src/x86/sysv.S (.eh_frame): Use .ascii, .string or error.
+
+2010-05-11  Dan Witte  <[email protected]>
+
+	* doc/libffi.tex: Document previous change.
+
+2010-05-11  Makoto Kato <[email protected]>
+
+	* src/x86/ffi.c (ffi_call): Don't copy structs passed by value.
+
+2010-05-05  Michael Kohler <[email protected]>
+
+	* src/dlmalloc.c (dlfree): Fix spelling.
+	* src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto.
+	* configure.ac: Ditto.
+	* configure: Rebuilt.
+
+2010-04-13  Dan Witte  <[email protected]>
+
+	* msvcc.sh: Build with -W3 instead of -Wall.
+	* src/powerpc/ffi_darwin.c: Remove build warnings.
+	* src/x86/ffi.c: Ditto.
+	* src/x86/ffitarget.h: Ditto.
+
+2010-04-12  Dan Witte  <[email protected]>
+	    Walter Meinl <[email protected]>
+
+	* configure.ac: Add OS/2 support.
+	* configure: Rebuilt.
+	* src/closures.c: Ditto.
+	* src/dlmalloc.c: Ditto.
+	* src/x86/win32.S: Ditto.
+
+2010-04-07  Jakub Jelinek  <[email protected]>
+
+	* testsuite/libffi.call/err_bad_abi.c: Remove unused args variable.
+
+2010-04-02  Ralf Wildenhues  <[email protected]>
+
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* man/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2010-03-30  Dan Witte  <[email protected]>
+
+	* msvcc.sh: Disable build warnings.
+	* README (tested): Clarify windows build procedure.
+
+2010-03-15  Rainer Orth  <[email protected]>
+
+	* configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* libffi/src/x86/unix64.S (.eh_frame)
+	[HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type.
+
+2010-03-14  Matthias Klose  <[email protected]>
+
+	* src/x86/ffi64.c: Fix typo in comment.
+	* src/x86/ffi.c: Use /* ... */ comment style.
+
+2010-02-24  Rainer Orth  <[email protected]>
+
+	* doc/libffi.texi (The Closure API): Fix typo.
+	* doc/libffi.info: Remove.
+
+2010-02-15  Matthias Klose  <[email protected]>
+
+	* src/arm/sysv.S (__ARM_ARCH__): Define for processor
+	__ARM_ARCH_7EM__.
+
+2010-01-15  Anthony Green  <[email protected]>
+
+	* README: Add notes on building with Microsoft Visual C++.
+
+2010-01-15  Daniel Witte  <[email protected]>
+
+	* msvcc.sh: New file.
+
+	* src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
+	* src/x86/ffi.c: Tweak function declaration and remove excess
+	parens.
+	* include/ffi.h.in: Add __declspec(align(8)) to typedef struct
+	ffi_closure.
+
+	* src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
+	function ffi_call_win32 on X86_WIN32.
+	* src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
+	(ffi_call_STDCALL): Remove.
+
+	* src/prep_cif.c (ffi_prep_cif): Move stack space allocation code
+	to ffi_prep_cif_machdep for x86.
+	* src/x86/ffi.c (ffi_prep_cif_machdep): To here.
+
+2010-01-15  Oliver Kiddle  <[email protected]>
+
+	* src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for
+	Sun Studio compiler compatibility.
+
+2010-01-12  Conrad Irwin <[email protected]>
+
+	* doc/libffi.texi: Add closure example.
+
+2010-01-07  Rainer Orth  <[email protected]>
+
+	PR libffi/40701
+	* testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL,
+	PRIuLL, PRId64, PRIu64, PRIuPTR): Define.
+	* testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on
+	alpha*-dec-osf*.
+	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/return_ll1.c: Likewise.
+	* testsuite/libffi.call/stret_medium2.c: Likewise.
+	* testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast
+	MAP_FAILED to char *.
+
+2010-01-06  Rainer Orth  <[email protected]>
+
+	* src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__.
+
+2009-12-31  Anthony Green  <[email protected]>
+
+	* README: Update for libffi 3.0.9.
+
+2009-12-27  Matthias Klose  <[email protected]>
+
+	* configure.ac (HAVE_LONG_DOUBLE): Define for mips when
+	appropriate.
+	* configure: Rebuilt.
+
+2009-12-26  Anthony Green  <[email protected]>
+
+	* testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for
+	avr32*-*-*.
+	* testsuite/libffi.call/cls_double_va.c: Ditto.
+
+2009-12-26  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h: Conditionally include stdint.h
+	and inttypes.h.
+	* testsuite/libffi.special/unwindtest.cc: Ditto.
+
+2009-12-26  Andreas Tobler  <[email protected]>
+
+	* configure.ac: Add amd64-*-openbsd*.
+	* configure: Rebuilt.
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Link
+	openbsd programs with -lpthread.
+
+2009-12-26  Anthony Green  <[email protected]>
+
+	* testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for
+	mips*-*-* and arm*-*-*.
+	* testsuite/libffi.call/cls_align_longdouble_split.c,
+	testsuite/libffi.call/cls_align_longdouble_split2.c,
+	testsuite/libffi.call/stret_medium2.c,
+	testsuite/libffi.call/stret_medium.c,
+	testsuite/libffi.call/stret_large.c,
+	testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*.
+
+2009-12-31  Kay Tietz  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h,
+	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix
+	definitions.
+
+2009-12-31  Carlo Bramini  <[email protected]>
+
+	* configure.ac (AM_LTLDFLAGS): Define for windows hosts.
+	* Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS.
+	* configure: Rebuilt.
+	* Makefile.in: Rebuilt.
+
+2009-12-31  Anthony Green  <[email protected]>
+	    Blake Chaffin.
+
+	* testsuite/libffi.call/huge_struct.c: New test case from Blake
+	Chaffin @ Apple.
+
+2009-12-28  David Edelsohn  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to
+	local variables.
+	(aix_adjust_aggregate_sizes): New function.
+	(ffi_prep_cif_machdep): Call it.
+
+2009-12-26  Andreas Tobler  <[email protected]>
+
+	* configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets.
+	* configure: Regenerate.
+	* fficonfig.h.in: Likewise.
+	* src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for
+	Solaris/x86.
+
+2009-12-26  Andreas Schwab  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count
+	when a float arguments is passed in memory.
+	(ffi_closure_helper_SYSV): Mark general registers as used up when
+	a 64bit or soft-float long double argument is passed in memory.
+
+2009-12-25  Matthias Klose  <[email protected]>
+
+	* man/ffi_call.3: Fix #include in examples.
+	* doc/libffi.texi: Add dircategory.
+
+2009-12-25  Frank Everdij <[email protected]>
+
+	* include/ffi.h.in: Placed '__GNUC__' ifdef around
+	'__attribute__((aligned(8)))' in ffi_closure, fixes compile for
+	IRIX MIPSPro c99.
+	* include/ffi_common.h: Added '__sgi' define to non
+	'__attribute__((__mode__()))' integer typedefs.
+	* src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32,
+	ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check.
+	(ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added
+	FFI_LONGDOUBLE support and alignment(N32 only).
+	* src/mips/ffitarget.h: Corrected '#include <sgidefs.h>' for IRIX and
+	fixed non '__attribute__((__mode__()))' integer typedefs.
+	* src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame'
+	since they are Linux/GNU Assembler specific.
+
+2009-12-25  Bradley Smith  <[email protected]>
+
+	* configure.ac, Makefile.am, src/avr32/ffi.c,
+	src/avr32/ffitarget.h,
+	src/avr32/sysv.S: Add AVR32 port.
+	* configure, Makefile.in: Rebuilt.
+
+2009-12-21  Andreas Tobler  <[email protected]>
+
+	* configure.ac: Make i?86 build on FreeBSD and OpenBSD.
+	* configure: Regenerate.
+
+2009-12-15  John David Anglin  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX.
+
+2009-12-13  John David Anglin  <[email protected]>
+
+	* src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE
+	type on HP-UX.
+
+2012-02-13  Kai Tietz  <[email protected]>
+
+	PR libffi/52221
+	* src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall
+	support for X86_WIN32.
+	(FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement.
+
+2009-12-11  Eric Botcazou  <[email protected]>
+
+	* src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long
+	double' arguments.
+
+2009-12-11  Eric Botcazou  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10.
+
+2009-12-10  Rainer Orth  <[email protected]>
+
+	PR libffi/40700
+	* src/closures.c [X86_64 && __sun__ && __svr4__]
+	(FFI_MMAP_EXEC_WRIT): Define.
+
+2009-12-08  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-*
+	* testsuite/libffi.call/cls_align_longdouble_split2.c: Same.
+	* testsuite/libffi.call/stret_large.c: Same.
+	* testsuite/libffi.call/cls_align_longdouble_split.c: Same.
+	* testsuite/libffi.call/stret_large2.c: Same.
+	* testsuite/libffi.call/stret_medium2.c: Same.
+
+2009-12-07  David Edelsohn  <[email protected]>
+
+	* src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump
+	typo.
+
+2009-12-05  David Edelsohn  <[email protected]>
+
+	* src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64
+	code.
+	* src/powerpc/aix_closure.S: Same.
+
+2009-12-05  Ralf Wildenhues  <[email protected]>
+
+	* Makefile.in: Regenerate.
+	* configure: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* man/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2009-12-04  David Edelsohn  <[email protected]>
+
+	* src/powerpc/aix_closure.S: Reorganize 64-bit code to match
+	linux64_closure.S.
+
+2009-12-04  Uros Bizjak  <[email protected]>
+
+	PR libffi/41908
+	* src/x86/ffi64.c (classify_argument): Update from
+	gcc/config/i386/i386.c.
+	(ffi_closure_unix64_inner): Do not use the address of two consecutive
+	SSE registers directly.
+	* testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail
+	for x86_64 linux targets.
+
+2009-12-04  David Edelsohn  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment
+	pfr for long double split between fpr13 and stack.
+
+2009-12-03  David Edelsohn  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and
+	fparg_count twice for long double.
+
+2009-12-03  David Edelsohn  <[email protected]>
+
+	PR libffi/42243
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses.
+
+2009-12-03  Uros Bizjak  <[email protected]>
+
+	* testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string.
+	Remove xfails for x86 linux targets.
+
+2009-12-02  David Edelsohn  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64
+	case.
+
+2009-12-01  David Edelsohn  <[email protected]>
+
+	* src/powerpc/aix.S (ffi_call_AIX): Convert to more standard
+	register usage.  Call ffi_prep_args directly.  Add long double
+	return value support.
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment
+	applies to FFI_TYPE_DOUBLE.  Correct fpr_base increment typo.
+	Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases.
+	(ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit
+	mode.
+	(ffi_closure_helper_DARWIN): Remove nf and ng counters.  Move temp
+	into case.
+	* src/powerpc/aix_closure.S: Maintain 16 byte stack alignment.
+	Allocate result area between params and FPRs.
+
+2009-11-30  David Edelsohn  <[email protected]>
+
+	PR target/35484
+	* src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
+	AIX64.
+	* src/powerpc/aix.S: Implement AIX64 version.
+	* src/powerpc/aix_closure.S: Implement AIX64 version.
+	(ffi_closure_ASM): Use extsb, lha and displament addresses.
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
+	support.
+	(ffi_prep_cif_machdep): Same.
+	(ffi_call): Same.
+	(ffi_closure_helper_DARWIN): Same.
+
+2009-11-02  Andreas Tobler  <[email protected]>
+
+	PR libffi/41908
+	* testsuite/libffi.call/testclosure.c: New test.
+
+2009-09-28  Kai Tietz  <[email protected]>
+
+	* src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu
+	assembly version use of ___chkstk.
+
+2009-09-23  Matthias Klose  <[email protected]>
+
+	PR libffi/40242, PR libffi/41443
+	* src/arm/sysv.S (__ARM_ARCH__): Define for processors
+	__ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__,
+	__ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__.
+	Change the conditionals to __SOFTFP__ || __ARM_EABI__
+	for -mfloat-abi=softfp to work.
+
+2009-09-17  Loren J. Rittle  <[email protected]>
+
+	PR testsuite/32843 (strikes again)
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to
+	enable proper extension on char and short.
+
+2009-09-15  David Daney  <[email protected]>
+
+	* src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special
+	handling for FFI_TYPE_POINTER.
+	* src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT,
+	FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT,
+	FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT,
+	FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines.
+	(FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations.
+	(enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float.
+	* src/mips/n32.S (ffi_call_N32): Add handling for soft-float
+	structure and pointer returns.
+	(ffi_closure_N32): Add handling for pointer returns.
+	* src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags,
+	calc_n32_return_struct_flags): Handle soft-float.
+	(ffi_prep_cif_machdep):  Handle soft-float, fix pointer handling.
+	(ffi_call_N32): Declare proper argument types.
+	(ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle
+	soft-float.
+
+2009-08-24  Ralf Wildenhues  <[email protected]>
+
+	* configure.ac (AC_PREREQ): Bump to 2.64.
+
+2009-08-22  Ralf Wildenhues  <[email protected]>
+
+	* Makefile.am (install-html, install-pdf): Remove.
+	* Makefile.in: Regenerate.
+
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* man/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2011-08-22  Jasper Lievisse Adriaanse <[email protected]>
+
+	* configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support.
+	* configure: Rebuilt.
+
+2009-07-30  Ralf Wildenhues  <[email protected]>
+
+	* configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force.
+
+2009-07-24  Dave Korn  <[email protected]>
+
+	PR libffi/40807
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending
+	return types for X86_WIN32.
+	* src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types.
+	(_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV,
+	_ffi_closure_STDCALL): Likewise.
+
+	* src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin.
+	(dlmmap, dlmunmap): Also use these functions on Cygwin.
+
+2009-07-11  Richard Sandiford  <[email protected]>
+
+	PR testsuite/40699
+	PR testsuite/40707
+	PR testsuite/40709
+	* testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and
+	2009-06-30 commits.
+
+2009-07-01  Richard Sandiford  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path
+	to "" before adding paths.  (This reinstates an assignment that
+	was removed by my 2009-06-30 commit, but changes the initial
+	value from "." to "".)
+
+2009-07-01  H.J. Lu  <[email protected]>
+
+	PR testsuite/40601
+	* testsuite/lib/libffi-dg.exp (libffi-init): Properly set
+	gccdir.  Adjust ld_library_path for gcc only if gccdir isn't
+	empty.
+
+2009-06-30  Richard Sandiford  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp (libffi-init): Don't add "."
+	to ld_library_path.  Use add_path.  Add just find_libgcc_s
+	to ld_library_path, not every libgcc multilib directory.
+
+2009-06-16  Wim Lewis  <[email protected]>
+
+	* src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
+	supposed to be callee-saved.
+	* src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
+	return buffer for odd-size structs.
+
+2009-06-16  Andreas Tobler  <[email protected]>
+
+	PR libffi/40444
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Add
+	allow_stack_execute for Darwin.
+
+2009-06-16  Andrew Haley  <[email protected]>
+
+	* configure.ac (TARGETDIR): Add missing blank lines.
+	* configure: Regenerate.
+
+2009-06-16  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	* testsuite/libffi.call/ffitest.h,
+	testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
+
+2009-06-15  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/err_bad_typedef.c: xfail everywhere.
+	* testsuite/libffi.call/err_bad_abi.c: Likewise.
+
+2009-06-12  Andrew Haley  <[email protected]>
+
+	* Makefile.am: Remove info_TEXINFOS.
+
+2009-06-12  Andrew Haley  <[email protected]>
+
+	* ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/return_ll1.c,
+	testsuite/libffi.call/stret_medium2.c: Fix printf format
+	specifiers.
+	testsuite/libffi.special/unwindtest.cc: include stdint.h.
+
+2009-06-11  Timothy Wall  <[email protected]>
+
+	* Makefile.am,
+	configure.ac,
+	include/ffi.h.in,
+	include/ffi_common.h,
+	src/closures.c,
+	src/dlmalloc.c,
+	src/x86/ffi.c,
+	src/x86/ffitarget.h,
+	src/x86/win64.S (new),
+	README: Added win64 support (mingw or MSVC)
+	* Makefile.in,
+	include/Makefile.in,
+	man/Makefile.in,
+	testsuite/Makefile.in,
+	configure,
+	aclocal.m4: Regenerated
+	* ltcf-c.sh: properly escape cygwin/w32 path
+	* man/ffi_call.3: Clarify size requirements for return value.
+	* src/x86/ffi64.c: Fix filename in comment.
+	* src/x86/win32.S: Remove unused extern.
+
+	* testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+ 	testsuite/libffi.call/cls_3byte2.c,
+ 	testsuite/libffi.call/cls_4_1byte.c,
+ 	testsuite/libffi.call/cls_4byte.c,
+ 	testsuite/libffi.call/cls_5_1_byte.c,
+ 	testsuite/libffi.call/cls_5byte.c,
+ 	testsuite/libffi.call/cls_64byte.c,
+ 	testsuite/libffi.call/cls_6_1_byte.c,
+ 	testsuite/libffi.call/cls_6byte.c,
+ 	testsuite/libffi.call/cls_7_1_byte.c,
+ 	testsuite/libffi.call/cls_7byte.c,
+ 	testsuite/libffi.call/cls_8byte.c,
+ 	testsuite/libffi.call/cls_9byte1.c,
+ 	testsuite/libffi.call/cls_9byte2.c,
+ 	testsuite/libffi.call/cls_align_double.c,
+ 	testsuite/libffi.call/cls_align_float.c,
+ 	testsuite/libffi.call/cls_align_longdouble.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split.c,
+ 	testsuite/libffi.call/cls_align_longdouble_split2.c,
+ 	testsuite/libffi.call/cls_align_pointer.c,
+ 	testsuite/libffi.call/cls_align_sint16.c,
+ 	testsuite/libffi.call/cls_align_sint32.c,
+ 	testsuite/libffi.call/cls_align_sint64.c,
+ 	testsuite/libffi.call/cls_align_uint16.c,
+ 	testsuite/libffi.call/cls_align_uint32.c,
+ 	testsuite/libffi.call/cls_align_uint64.c,
+ 	testsuite/libffi.call/cls_dbls_struct.c,
+ 	testsuite/libffi.call/cls_double.c,
+ 	testsuite/libffi.call/cls_double_va.c,
+ 	testsuite/libffi.call/cls_float.c,
+ 	testsuite/libffi.call/cls_longdouble.c,
+ 	testsuite/libffi.call/cls_longdouble_va.c,
+ 	testsuite/libffi.call/cls_multi_schar.c,
+ 	testsuite/libffi.call/cls_multi_sshort.c,
+ 	testsuite/libffi.call/cls_multi_sshortchar.c,
+ 	testsuite/libffi.call/cls_multi_uchar.c,
+ 	testsuite/libffi.call/cls_multi_ushort.c,
+ 	testsuite/libffi.call/cls_multi_ushortchar.c,
+ 	testsuite/libffi.call/cls_pointer.c,
+ 	testsuite/libffi.call/cls_pointer_stack.c,
+ 	testsuite/libffi.call/cls_schar.c,
+ 	testsuite/libffi.call/cls_sint.c,
+ 	testsuite/libffi.call/cls_sshort.c,
+ 	testsuite/libffi.call/cls_uchar.c,
+ 	testsuite/libffi.call/cls_uint.c,
+ 	testsuite/libffi.call/cls_ulonglong.c,
+ 	testsuite/libffi.call/cls_ushort.c,
+ 	testsuite/libffi.call/err_bad_abi.c,
+ 	testsuite/libffi.call/err_bad_typedef.c,
+ 	testsuite/libffi.call/float2.c,
+ 	testsuite/libffi.call/huge_struct.c,
+ 	testsuite/libffi.call/nested_struct.c,
+ 	testsuite/libffi.call/nested_struct1.c,
+ 	testsuite/libffi.call/nested_struct10.c,
+ 	testsuite/libffi.call/nested_struct2.c,
+ 	testsuite/libffi.call/nested_struct3.c,
+ 	testsuite/libffi.call/nested_struct4.c,
+ 	testsuite/libffi.call/nested_struct5.c,
+ 	testsuite/libffi.call/nested_struct6.c,
+ 	testsuite/libffi.call/nested_struct7.c,
+ 	testsuite/libffi.call/nested_struct8.c,
+ 	testsuite/libffi.call/nested_struct9.c,
+ 	testsuite/libffi.call/problem1.c,
+ 	testsuite/libffi.call/return_ldl.c,
+ 	testsuite/libffi.call/return_ll1.c,
+ 	testsuite/libffi.call/stret_large.c,
+ 	testsuite/libffi.call/stret_large2.c,
+ 	testsuite/libffi.call/stret_medium.c,
+ 	testsuite/libffi.call/stret_medium2.c,
+	testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
+	of checking for MMAP.  Use intptr_t instead of long casts.
+
+2009-06-11  Kaz Kojima  <[email protected]>
+
+	* testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*.
+	* testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*.
+	* testsuite/libffi.call/err_bad_typedef.c: Likewise.
+
+2009-06-09  Andrew Haley  <[email protected]>
+
+	* src/x86/freebsd.S: Add missing file.
+
+2009-06-08  Andrew Haley  <[email protected]>
+
+	Import from libffi 3.0.8:
+
+	* doc/libffi.texi: New file.
+	* doc/libffi.info: Likewise.
+	* doc/stamp-vti: Likewise.
+	* man/Makefile.am: New file.
+	* man/ffi_call.3: New file.
+
+	* Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S,
+	src/dlmalloc.c.
+	(nodist_libffi_la_SOURCES): Add X86_FREEBSD.
+
+	* configure.ac: Bump version to 3.0.8.
+	parisc*-*-linux*: Add.
+	i386-*-freebsd* | i386-*-openbsd*: Add.
+	powerpc-*-beos*: Add.
+	AM_CONDITIONAL X86_FREEBSD: Add.
+	AC_CONFIG_FILES: Add man/Makefile.
+
+	* include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void).
+
+2009-06-08  Andrew Haley  <[email protected]>
+
+	* README: Import from libffi 3.0.8.
+
+2009-06-08  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/err_bad_abi.c: Add xfails.
+	* testsuite/libffi.call/cls_longdouble_va.c: Add xfails.
+	* testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*.
+	* testsuite/libffi.call/err_bad_typedef.c: Add xfails.
+
+	* testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args.
+	* testsuite/libffi.call/stret_medium.c: Likewise.
+	* testsuite/libffi.call/stret_large2.c: Likewise.
+	* testsuite/libffi.call/stret_large.c:  Likewise.
+
+2008-12-26  Timothy Wall  <[email protected]>
+
+	* testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_align_longdouble.c,
+	testsuite/libffi.call/cls_align_longdouble_split.c,
+	testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
+	failures on x86_64 cygwin/mingw.
+
+2008-12-22  Timothy Wall  <[email protected]>
+
+	* testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/closure_loc_fn0.c,
+	testsuite/libffi.call/closure_stdcall.c,
+	testsuite/libffi.call/cls_align_pointer.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
+	pointer to integer (intptr_t).
+	* testsuite/libffi.call/cls_longdouble.c: disable for win64.
+
+2008-07-24  Anthony Green  <[email protected]>
+
+	* testsuite/libffi.call/cls_dbls_struct.c,
+	testsuite/libffi.call/cls_double_va.c,
+	testsuite/libffi.call/cls_longdouble.c,
+	testsuite/libffi.call/cls_longdouble_va.c,
+	testsuite/libffi.call/cls_pointer.c,
+	testsuite/libffi.call/cls_pointer_stack.c,
+	testsuite/libffi.call/err_bad_abi.c: Clean up failures from
+	compiler warnings.
+
+2008-03-04  Anthony Green  <[email protected]>
+	    Blake Chaffin
+	    [email protected]
+
+	* testsuite/libffi.call/cls_align_longdouble_split2.c
+	  testsuite/libffi.call/cls_align_longdouble_split.c
+	  testsuite/libffi.call/cls_dbls_struct.c
+	  testsuite/libffi.call/cls_double_va.c
+	  testsuite/libffi.call/cls_longdouble.c
+	  testsuite/libffi.call/cls_longdouble_va.c
+	  testsuite/libffi.call/cls_pointer.c
+	  testsuite/libffi.call/cls_pointer_stack.c
+	  testsuite/libffi.call/err_bad_abi.c
+	  testsuite/libffi.call/err_bad_typedef.c
+	  testsuite/libffi.call/stret_large2.c
+	  testsuite/libffi.call/stret_large.c
+	  testsuite/libffi.call/stret_medium2.c
+	  testsuite/libffi.call/stret_medium.c: New tests from Apple.
+
+2009-06-05  Andrew Haley  <[email protected]>
+
+	* src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from
+	libffi.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out
+	stdcall changes.
+
+2008-02-26  Anthony Green  <[email protected]>
+	    Thomas Heller  <[email protected]>
+
+	* src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
+	comment.
+
+2008-02-03  Timothy Wall  <[email protected]>
+
+	* src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
+	  offset based on code pointer, not data pointer.
+
+2008-01-31  Timothy Wall <[email protected]>
+
+	* testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
+	closures.
+	* src/x86/ffitarget.h: Increase size of trampoline for stdcall
+	closures.
+	* src/x86/win32.S: Add assembly for stdcall closure.
+	* src/x86/ffi.c: Initialize stdcall closure trampoline.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* include/ffi.h.in: Change void (*)() to void (*)(void).
+	* src/x86/ffi.c: Likewise.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	* src/powerpc/ppc_closure.S: Insert licence header.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/m68k/sysv.S: Likewise.
+
+	* src/sh64/ffi.c: Change void (*)() to void (*)(void).
+	* src/powerpc/ffi.c: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+	* src/m32r/ffi.c: Likewise.
+	* src/sh64/ffi.c: Likewise.
+	* src/x86/ffi64.c: Likewise.
+	* src/alpha/ffi.c: Likewise.
+	* src/alpha/osf.S: Likewise.
+	* src/frv/ffi.c: Likewise.
+	* src/s390/ffi.c: Likewise.
+	* src/pa/ffi.c: Likewise.
+	* src/pa/hpux32.S: Likewise.
+	* src/ia64/unix.S: Likewise.
+	* src/ia64/ffi.c: Likewise.
+	* src/sparc/ffi.c: Likewise.
+	* src/mips/ffi.c: Likewise.
+	* src/sh/ffi.c: Likewise.
+
+2008-02-15  David Daney  <[email protected]>
+
+	* src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
+	Define (conditionally), and use it to include cachectl.h.
+	(ffi_prep_closure_loc): Fix cache flushing.
+	* src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
+
+2009-06-04  Andrew Haley  <[email protected]>
+
+	include/ffi.h.in,
+	src/arm/ffitarget.h,
+	src/arm/ffi.c,
+	src/arm/sysv.S,
+	src/powerpc/ffitarget.h,
+	src/closures.c,
+	src/sh64/ffitarget.h,
+	src/sh64/ffi.c,
+	src/sh64/sysv.S,
+	src/types.c,
+	src/x86/ffi64.c,
+	src/x86/ffitarget.h,
+	src/x86/win32.S,
+	src/x86/darwin.S,
+	src/x86/ffi.c,
+	src/x86/sysv.S,
+	src/x86/unix64.S,
+	src/alpha/ffitarget.h,
+	src/alpha/ffi.c,
+	src/alpha/osf.S,
+	src/m68k/ffitarget.h,
+	src/frv/ffitarget.h,
+	src/frv/ffi.c,
+	src/s390/ffitarget.h,
+	src/s390/sysv.S,
+	src/cris/ffitarget.h,
+	src/pa/linux.S,
+	src/pa/ffitarget.h,
+	src/pa/ffi.c,
+	src/raw_api.c,
+	src/ia64/ffitarget.h,
+	src/ia64/unix.S,
+	src/ia64/ffi.c,
+	src/ia64/ia64_flags.h,
+	src/java_raw_api.c,
+	src/debug.c,
+	src/sparc/v9.S,
+	src/sparc/ffitarget.h,
+	src/sparc/ffi.c,
+	src/sparc/v8.S,
+	src/mips/ffitarget.h,
+	src/mips/n32.S,
+	src/mips/o32.S,
+	src/mips/ffi.c,
+	src/prep_cif.c,
+	src/sh/ffitarget.h,
+	src/sh/ffi.c,
+	src/sh/sysv.S: Update license text.
+
+2009-05-22  Dave Korn  <[email protected]>
+
+	* src/x86/win32.S (_ffi_closure_STDCALL):  New function.
+	(.eh_frame):  Add FDE for it.
+
+2009-05-22  Dave Korn  <[email protected]>
+
+	* configure.ac:  Also check if assembler supports pc-relative
+	relocs on X86_WIN32 targets.
+	* configure:  Regenerate.
+	* src/x86/win32.S (ffi_prep_args):  Declare extern, not global.
+	(_ffi_call_SYSV):  Add missing function type symbol .def and
+	add EH markup labels.
+	(_ffi_call_STDCALL):  Likewise.
+	(_ffi_closure_SYSV):  Likewise.
+	(_ffi_closure_raw_SYSV):  Likewise.
+	(.eh_frame):  Add hand-crafted EH data.
+
+2009-04-09  Jakub Jelinek  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Change copyright header to refer to
+	version 3 of the GNU General Public License and to point readers
+	at the COPYING3 file and the FSF's license web page.
+	* testsuite/libffi.call/call.exp: Likewise.
+	* testsuite/libffi.special/special.exp: Likewise.
+
+2009-03-01  Ralf Wildenhues  <[email protected]>
+
+	* configure: Regenerate.
+
+2008-12-18  Rainer Orth  <[email protected]>
+
+	PR libffi/26048
+	* configure.ac (HAVE_AS_X86_PCREL): New test.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate
+	RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET,
+	RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler.
+	(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
+	* src/x86/unix64.S (.Lstore_table): Move to .text section.
+	(.Lload_table): Likewise.
+	(.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL.
+
+2008-12-18  Ralf Wildenhues  <[email protected]>
+
+	* configure: Regenerate.
+
+2008-11-21  Eric Botcazou  <[email protected]>
+
+	* src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for
+	signed/unsigned int8/16 return values.
+	* src/sparc/v8.S (ffi_call_v8): Likewise.
+	(ffi_closure_v8): Likewise.
+
+2008-09-26  Peter O'Gorman  <[email protected]>
+	    Steve Ellcey  <[email protected]>
+
+	* configure: Regenerate for new libtool.
+	* Makefile.in: Ditto.
+	* include/Makefile.in: Ditto.
+	* aclocal.m4: Ditto.
+
+2008-08-25  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and
+	FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum.
+	Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT.
+	Adjust copyright notice.
+	* src/powerpc/ffi.c: Add two new flags to indicate if we have one
+	register or two register to use for FFI_SYSV structs.
+	(ffi_prep_cif_machdep): Pass the right register flag introduced above.
+	(ffi_closure_helper_SYSV): Fix the return type for
+	FFI_SYSV_TYPE_SMALL_STRUCT. Comment.
+	Adjust copyright notice.
+
+2008-07-16  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
+	int.
+
+2008-06-17  Ralf Wildenhues  <[email protected]>
+
+	* configure: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2008-06-07  Joseph Myers  <[email protected]>
+
+	* configure.ac (parisc*-*-linux*, powerpc-*-sysv*,
+	powerpc-*-beos*): Remove.
+	* configure: Regenerate.
+
+2008-05-09  Julian Brown  <[email protected]>
+
+	* Makefile.am (LTLDFLAGS): New.
+	(libffi_la_LDFLAGS): Use above.
+	* Makefile.in: Regenerate.
+
+2008-04-18  Paolo Bonzini  <[email protected]>
+
+	PR bootstrap/35457
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+
+2008-03-26  Kaz Kojima  <[email protected]>
+
+	* src/sh/sysv.S: Add .note.GNU-stack on Linux.
+	* src/sh64/sysv.S: Likewise.
+
+2008-03-26  Daniel Jacobowitz  <[email protected]>
+
+	* src/arm/sysv.S: Fix ARM comment marker.
+
+2008-03-26  Jakub Jelinek  <[email protected]>
+
+	* src/alpha/osf.S: Add .note.GNU-stack on Linux.
+	* src/s390/sysv.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.
+	* src/powerpc/sysv.S: Likewise.
+	* src/x86/unix64.S: Likewise.
+	* src/x86/sysv.S: Likewise.
+	* src/sparc/v8.S: Likewise.
+	* src/sparc/v9.S: Likewise.
+	* src/m68k/sysv.S: Likewise.
+	* src/arm/sysv.S: Likewise.
+
+2008-03-16  Ralf Wildenhues  <[email protected]>
+
+	* aclocal.m4: Regenerate.
+	* configure: Likewise.
+	* Makefile.in: Likewise.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+
+2008-02-12  Bjoern Koenig  <[email protected]>
+	    Andreas Tobler  <[email protected]>
+
+	* configure.ac: Add amd64-*-freebsd* target.
+	* configure: Regenerate.
+
+2008-01-30  H.J. Lu  <[email protected]>
+
+	PR libffi/34612
+	* src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when
+	returning struct.
+
+	* testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer"
+	tests.
+
+2008-01-24  David Edelsohn  <[email protected]>
+
+	* configure: Regenerate.
+
+2008-01-06  Andreas Tobler  <[email protected]>
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko.
+
+2008-01-05  Andreas Tobler  <[email protected]>
+
+	PR testsuite/32843
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Add code for
+	signed/unsigned int8/16 for X86_DARWIN.
+	Updated copyright info.
+	Handle one and two byte structs with special cif->flags.
+	* src/x86/ffitarget.h: Add special types for one and two byte structs.
+	Updated copyright info.
+	* src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like
+	sysv.S
+	Remove code to pop args from the stack after call.
+	Special-case signed/unsigned for int8/16, one and two byte structs.
+	(ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
+	FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
+	FFI_TYPE_SINT32.
+	Updated copyright info.
+
+2007-12-08  David Daney  <[email protected]>
+
+	* src/mips/n32.S (ffi_call_N32):  Replace dadd with ADDU, dsub with
+	SUBU, add with ADDU and use smaller code sequences.
+
+2007-12-07  David Daney  <[email protected]>
+
+	* src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return
+	type.
+
+2007-12-06  David Daney  <[email protected]>
+
+	* include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not	already
+	defined.
+	(ffi_java_raw): New typedef.
+	(ffi_java_raw_call, ffi_java_ptrarray_to_raw,
+	ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to
+	ffi_java_raw.
+	(ffi_java_raw_closure) : Same.
+	(ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change
+	parameter types.
+	* src/java_raw_api.c (ffi_java_raw_size):  Replace FFI_SIZEOF_ARG with
+	FFI_SIZEOF_JAVA_RAW.
+	(ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw.
+	Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use
+	sizeof(ffi_java_raw) for alignment calculations.
+	(ffi_java_ptrarray_to_raw): Same.
+	(ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER
+	if FFI_SIZEOF_JAVA_RAW == 4.
+	(ffi_java_raw_to_rvalue): Same.
+	(ffi_java_raw_call): Change type of raw to ffi_java_raw.
+	(ffi_java_translate_args): Same.
+	(ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change
+	parameter types.
+	* src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI.
+
+2007-12-06  David Daney  <[email protected]>
+
+	* src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on
+	pointer values.
+
+2007-12-01  Andreas Tobler  <[email protected]>
+
+	PR libffi/31937
+	* src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT.
+	Add local FFI_TYPE_UINT128 to handle soft-float long-double-128.
+	* src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and
+	set the NUM_FPR_ARG_REGISTERS according to.
+	Add support for potential soft-float support under hard-float
+	architecture.
+	(ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of
+	FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according
+	to the FFI_LINUX_SOFT_FLOAT ABI.
+	(ffi_prep_cif_machdep): Likewise.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/powerpc/ppc_closure.S: Make sure not to store float/double
+	on archs where __NO_FPRS__ is true.
+	Add FFI_TYPE_UINT128 support.
+	* src/powerpc/sysv.S: Add support for soft-float long-double-128.
+	Adjust copyright notice.
+
+2007-11-25  Andreas Tobler  <[email protected]>
+
+	* src/closures.c: Move defintion of MAYBE_UNUSED from here to ...
+	* include/ffi_common.h: ... here.
+	Update copyright.
+
+2007-11-17  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/sysv.S: Load correct cr to compare if we have long double.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/ffi.c: Add a comment to show which part goes into cr6.
+	* testsuite/libffi.call/return_ldl.c: New test.
+
+2007-09-04    <[email protected]>
+
+	* src/arm/sysv.S (UNWIND): New.
+	(Whole file): Conditionally compile unwinder directives.
+	* src/arm/sysv.S: Add unwinder directives.
+
+	* src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes.
+	Only treat r0 as a struct address if we're actually returning a
+	struct by address.
+	Only copy the bytes that are actually within a struct.
+	(ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes
+	is returned in r0, not passed by address.
+	(ffi_call): Allocate a word-sized temporary for the case where
+	a composite is returned in r0.
+	(ffi_prep_incoming_args_SYSV): Align as necessary.
+
+2007-08-05  Steven Newbury  <[email protected]>
+
+	* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of
+	directly using the sys_cacheflush syscall.
+
+2007-07-27  Andrew Haley  <[email protected]>
+
+	* src/arm/sysv.S (ffi_closure_SYSV): Add soft-float.
+
+2007-09-03  Maciej W. Rozycki  <[email protected]>
+
+	* Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS.
+	* configure.ac: Likewise.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* configure: Likewise.
+
+2007-08-24  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/return_sl.c: New test.
+
+2007-08-10  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/cls_multi_ushort.c,
+	testsuite/libffi.call/cls_align_uint16.c,
+	testsuite/libffi.call/nested_struct1.c,
+	testsuite/libffi.call/nested_struct3.c,
+	testsuite/libffi.call/cls_7_1_byte.c,
+	testsuite/libffi.call/nested_struct5.c,
+	testsuite/libffi.call/cls_double.c,
+	testsuite/libffi.call/nested_struct7.c,
+	testsuite/libffi.call/cls_sint.c,
+	testsuite/libffi.call/nested_struct9.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_multi_sshortchar.c,
+	testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_3byte2.c,
+	testsuite/libffi.call/cls_multi_schar.c,
+	testsuite/libffi.call/cls_multi_uchar.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_9byte1.c,
+	testsuite/libffi.call/cls_align_float.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/problem1.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/cls_sshort.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/cls_align_double.c,
+	testsuite/libffi.call/nested_struct.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/nested_struct10.c,
+	testsuite/libffi.call/cls_4byte.c,
+	testsuite/libffi.call/cls_6byte.c,
+	testsuite/libffi.call/cls_8byte.c,
+	testsuite/libffi.call/cls_multi_sshort.c,
+	testsuite/libffi.call/cls_align_sint16.c,
+	testsuite/libffi.call/cls_align_uint32.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_float.c,
+	testsuite/libffi.call/nested_struct2.c,
+	testsuite/libffi.call/cls_5_1_byte.c,
+	testsuite/libffi.call/nested_struct4.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/nested_struct6.c,
+	testsuite/libffi.call/cls_64byte.c,
+	testsuite/libffi.call/nested_struct8.c,
+	testsuite/libffi.call/cls_uint.c,
+	testsuite/libffi.call/cls_multi_ushortchar.c,
+	testsuite/libffi.call/cls_schar.c,
+	testsuite/libffi.call/cls_uchar.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/cls_align_longdouble.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+	testsuite/libffi.call/cls_4_1byte.c,
+	testsuite/libffi.call/cls_6_1_byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/cls_9byte2.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/cls_ushort.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/cls_5byte.c,
+	testsuite/libffi.call/cls_align_pointer.c,
+	testsuite/libffi.call/cls_7byte.c,
+	testsuite/libffi.call/cls_align_sint32.c,
+	testsuite/libffi.special/unwindtest_ffi_call.cc,
+	testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*.
+
+2007-08-10  David Daney  <[email protected]>
+
+	PR libffi/28313
+	* configure.ac: Don't treat mips64 as a special case.
+	* Makefile.am (nodist_libffi_la_SOURCES): Add n32.S.
+	* configure: Regenerate
+	* Makefile.in: Ditto.
+	* fficonfig.h.in: Ditto.
+	* src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent.
+	(LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros.
+	(FFI_DEFAULT_ABI): Set for n64 case.
+	(FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases.
+	* src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE.
+	(ffi_closure_N32): New function.
+	(.eh_frame): New section
+	* src/mips/o32.S: Clean up comments.
+	(ffi_closure_O32): Pass ffi_closure parameter in $12.
+	* src/mips/ffi.c: Use FFI_MIPS_N32 instead of
+	_MIPS_SIM == _ABIN32 throughout.
+	(FFI_MIPS_STOP_HERE): New, use in place of
+	ffi_stop_here.
+	(ffi_prep_args): Use unsigned long to hold pointer values.  Rewrite
+	to support n32/n64 ABIs.
+	(calc_n32_struct_flags): Rewrite.
+	(calc_n32_return_struct_flags): Remove unused variable.  Reverse
+	position of flag bits.
+	(ffi_prep_cif_machdep): Rewrite n32 portion.
+	(ffi_call): Enable for n64.  Add special handling for small structure
+	return values.
+	(ffi_prep_closure_loc): Add n32 and n64 support.
+	(ffi_closure_mips_inner_O32): Add cast to silence warning.
+	(copy_struct_N32, ffi_closure_mips_inner_N32): New functions.
+
+2007-08-08  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition.
+	* testsuite/libffi.call/cls_align_uint16.c (main): Use correct type
+	specifiers.
+	* testsuite/libffi.call/nested_struct1.c (main): Ditto.
+	* testsuite/libffi.call/cls_sint.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct9.c (main): Ditto.
+	* testsuite/libffi.call/cls_20byte1.c (main): Ditto.
+	* testsuite/libffi.call/cls_9byte1.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn1.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn3.c (main): Ditto.
+	* testsuite/libffi.call/return_dbl2.c (main): Ditto.
+	* testsuite/libffi.call/cls_sshort.c (main): Ditto.
+	* testsuite/libffi.call/return_fl3.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn5.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct10.c (main): Ditto.
+	* testsuite/libffi.call/return_ll1.c (main): Ditto.
+	* testsuite/libffi.call/cls_8byte.c (main): Ditto.
+	* testsuite/libffi.call/cls_align_uint32.c (main): Ditto.
+	* testsuite/libffi.call/cls_align_sint16.c (main): Ditto.
+	* testsuite/libffi.call/cls_20byte.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct2.c (main): Ditto.
+	* testsuite/libffi.call/cls_24byte.c (main): Ditto.
+	* testsuite/libffi.call/nested_struct6.c (main): Ditto.
+	* testsuite/libffi.call/cls_uint.c (main): Ditto.
+	* testsuite/libffi.call/cls_12byte.c (main): Ditto.
+	* testsuite/libffi.call/cls_16byte.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn0.c (main): Ditto.
+	* testsuite/libffi.call/cls_9byte2.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn2.c (main): Ditto.
+	* testsuite/libffi.call/return_dbl1.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn4.c (main): Ditto.
+	* testsuite/libffi.call/closure_fn6.c (main): Ditto.
+	* testsuite/libffi.call/cls_align_sint32.c (main): Ditto.
+
+2007-08-07  Andrew Haley  <[email protected]>
+
+	* src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous
+	checkin.
+
+2007-08-06  Andrew Haley  <[email protected]>
+
+	PR testsuite/32843
+	* src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8,
+	FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32,
+	FFI_TYPE_SINT32.
+
+2007-08-02  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/return_ul.c (main): Define return type as
+	ffi_arg.  Use proper printf conversion specifier.
+
+2007-07-30  Andrew Haley  <[email protected]>
+
+	PR testsuite/32843
+	* src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for
+	signed/unsigned int8/16.
+	* src/x86/sysv.S (ffi_call_SYSV): Rewrite to:
+	Use a jump table.
+	Remove code to pop args from the stack after call.
+	Special-case signed/unsigned int8/16.
+	* testsuite/libffi.call/return_sc.c (main): Revert.
+
+2007-07-26  Richard Guenther  <[email protected]>
+
+	PR testsuite/32843
+	* testsuite/libffi.call/return_sc.c (main): Verify call
+	result as signed char, not ffi_arg.
+
+2007-07-16  Rainer Orth  <[email protected]>
+
+	* configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64.
+	* configure: Regenerate.
+
+2007-07-11  David Daney  <[email protected]>
+
+	* src/mips/ffi.c: Don't include sys/cachectl.h.
+	(ffi_prep_closure_loc): Use __builtin___clear_cache() instead of
+	cacheflush().
+
+2007-05-18  Aurelien Jarno  <[email protected]>
+
+	* src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted
+	from (ffi_prep_closure): ... this.
+	(FFI_INIT_TRAMPOLINE): Adjust.
+
+2005-12-31  Phil Blundell  <[email protected]>
+
+	* src/arm/ffi.c (ffi_prep_incoming_args_SYSV,
+	ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support.
+	* src/arm/sysv.S(ffi_closure_SYSV): Likewise.
+	* src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_CLOSURES): Enable closure support.
+
+2007-07-03  Andrew Haley  <[email protected]>
+
+	* testsuite/libffi.call/cls_multi_ushort.c,
+	testsuite/libffi.call/cls_align_uint16.c,
+	testsuite/libffi.call/nested_struct1.c,
+	testsuite/libffi.call/nested_struct3.c,
+	testsuite/libffi.call/cls_7_1_byte.c,
+	testsuite/libffi.call/cls_double.c,
+	testsuite/libffi.call/nested_struct5.c,
+	testsuite/libffi.call/nested_struct7.c,
+	testsuite/libffi.call/cls_sint.c,
+	testsuite/libffi.call/nested_struct9.c,
+	testsuite/libffi.call/cls_20byte1.c,
+	testsuite/libffi.call/cls_multi_sshortchar.c,
+	testsuite/libffi.call/cls_align_sint64.c,
+	testsuite/libffi.call/cls_3byte2.c,
+	testsuite/libffi.call/cls_multi_schar.c,
+	testsuite/libffi.call/cls_multi_uchar.c,
+	testsuite/libffi.call/cls_19byte.c,
+	testsuite/libffi.call/cls_9byte1.c,
+	testsuite/libffi.call/cls_align_float.c,
+	testsuite/libffi.call/closure_fn1.c,
+	testsuite/libffi.call/problem1.c,
+	testsuite/libffi.call/closure_fn3.c,
+	testsuite/libffi.call/cls_sshort.c,
+	testsuite/libffi.call/closure_fn5.c,
+	testsuite/libffi.call/cls_align_double.c,
+	testsuite/libffi.call/cls_2byte.c,
+	testsuite/libffi.call/nested_struct.c,
+	testsuite/libffi.call/nested_struct10.c,
+	testsuite/libffi.call/cls_4byte.c,
+	testsuite/libffi.call/cls_6byte.c,
+	testsuite/libffi.call/cls_8byte.c,
+	testsuite/libffi.call/cls_multi_sshort.c,
+	testsuite/libffi.call/cls_align_uint32.c,
+	testsuite/libffi.call/cls_align_sint16.c,
+	testsuite/libffi.call/cls_float.c,
+	testsuite/libffi.call/cls_20byte.c,
+	testsuite/libffi.call/cls_5_1_byte.c,
+	testsuite/libffi.call/nested_struct2.c,
+	testsuite/libffi.call/cls_24byte.c,
+	testsuite/libffi.call/nested_struct4.c,
+	testsuite/libffi.call/nested_struct6.c,
+	testsuite/libffi.call/cls_64byte.c,
+	testsuite/libffi.call/nested_struct8.c,
+	testsuite/libffi.call/cls_uint.c,
+	testsuite/libffi.call/cls_multi_ushortchar.c,
+	testsuite/libffi.call/cls_schar.c,
+	testsuite/libffi.call/cls_uchar.c,
+	testsuite/libffi.call/cls_align_uint64.c,
+	testsuite/libffi.call/cls_ulonglong.c,
+	testsuite/libffi.call/cls_align_longdouble.c,
+	testsuite/libffi.call/cls_1_1byte.c,
+	testsuite/libffi.call/cls_12byte.c,
+	testsuite/libffi.call/cls_3_1byte.c,
+	testsuite/libffi.call/cls_3byte1.c,
+	testsuite/libffi.call/cls_4_1byte.c,
+	testsuite/libffi.call/cls_6_1_byte.c,
+	testsuite/libffi.call/cls_16byte.c,
+	testsuite/libffi.call/cls_18byte.c,
+	testsuite/libffi.call/closure_fn0.c,
+	testsuite/libffi.call/cls_9byte2.c,
+	testsuite/libffi.call/closure_fn2.c,
+	testsuite/libffi.call/closure_fn4.c,
+	testsuite/libffi.call/cls_ushort.c,
+	testsuite/libffi.call/closure_fn6.c,
+	testsuite/libffi.call/cls_5byte.c,
+	testsuite/libffi.call/cls_align_pointer.c,
+	testsuite/libffi.call/cls_7byte.c,
+	testsuite/libffi.call/cls_align_sint32.c,
+	testsuite/libffi.special/unwindtest_ffi_call.cc,
+	testsuite/libffi.special/unwindtest.cc: Enable for ARM.
+
+2007-07-05  H.J. Lu  <[email protected]>
+
+	* aclocal.m4: Regenerated.
+
+2007-06-02  Paolo Bonzini  <[email protected]>
+
+	* configure: Regenerate.
+
+2007-05-23  Steve Ellcey  <[email protected]>
+
+	* Makefile.in: Regenerate.
+	* configure: Regenerate.
+	* aclocal.m4: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2007-05-10  Roman Zippel <[email protected]>
+
+	* src/m68k/ffi.c (ffi_prep_incoming_args_SYSV,
+	ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support.
+	* src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise.
+	* src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_CLOSURES): Enable closure support.
+
+2007-05-10  Roman Zippel <[email protected]>
+
+	* configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test.
+	* configure: Regenerate.
+	* fficonfig.h.in: Regenerate.
+	* src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC,
+	CFI_OFFSET,CFI_DEF_CFA): New macros.
+	(ffi_call_SYSV): Add callframe annotation.
+
+2007-05-10  Roman Zippel <[email protected]>
+
+	* src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix
+	numerous test suite failures.
+	* src/m68k/sysv.S (ffi_call_SYSV): Likewise.
+
+2007-04-11  Paolo Bonzini  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Bring up to date.
+	* Makefile.in: Regenerate.
+	* src/frv/eabi.S: Remove RCS keyword.
+
+2007-04-06  Richard Henderson  <[email protected]>
+
+	* configure.ac: Tidy target case.
+	(HAVE_LONG_DOUBLE): Allow the target to override.
+	* configure: Regenerate.
+	* include/ffi.h.in: Don't define ffi_type_foo if
+	LIBFFI_HIDE_BASIC_TYPES is defined.
+	(ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define
+	to ffi_type_double.
+	* types.c (LIBFFI_HIDE_BASIC_TYPES): Define.
+	(FFI_TYPEDEF, ffi_type_void): Mark the data const.
+	(ffi_type_longdouble): Special case for Alpha.  Don't define
+	if long double == double.
+
+	* src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value.
+	(ffi_prep_cif_machdep): Handle it as the 128-bit type.
+	(ffi_call, ffi_closure_osf_inner): Likewise.
+	(ffi_closure_osf_inner): Likewise.  Mark hidden.
+	(ffi_call_osf, ffi_closure_osf): Mark hidden.
+	* src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition.
+	* src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden.
+	(load_table): Handle 128-bit long double.
+
+	* testsuite/libffi.call/float4.c: Add -mieee for alpha.
+
+2007-04-06  Tom Tromey  <[email protected]>
+
+	PR libffi/31491:
+	* README: Fixed bug in example.
+
+2007-04-03  Jakub Jelinek  <[email protected]>
+
+	* src/closures.c: Include sys/statfs.h.
+	(_GNU_SOURCE): Define on Linux.
+	(FFI_MMAP_EXEC_SELINUX): Define.
+	(selinux_enabled): New variable.
+	(selinux_enabled_check): New function.
+	(is_selinux_enabled): Define.
+	(dlmmap): Use it.
+
+2007-03-24  Uros Bizjak  <[email protected]>
+
+	* testsuite/libffi.call/return_fl2.c (return_fl): Mark as static.
+	Use 'volatile float sum' to create sum of floats to avoid false
+	negative due to excess precision on ix86 targets.
+	(main): Ditto.
+
+2007-03-08  Alexandre Oliva  <[email protected]>
+
+	* src/powerpc/ffi.c (flush_icache): Fix left-over from previous
+	patch.
+	(ffi_prep_closure_loc): Remove unneeded casts.  Add needed ones.
+
+2007-03-07  Alexandre Oliva  <[email protected]>
+
+	* include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New.
+	(ffi_prep_closure_loc): New.
+	(ffi_prep_raw_closure_loc): New.
+	(ffi_prep_java_raw_closure_loc): New.
+	* src/closures.c: New file.
+	* src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment):
+	Replace sflags with exec_offset.
+	[FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset,
+	sub_segment_exec_offset): New macros.
+	(get_segment_flags, set_segment_flags, check_segment_merge): New
+	macros.
+	(is_mmapped_segment, is_extern_segment): Use get_segment_flags.
+	(add_segment, sys_alloc, create_mspace, create_mspace_with_base,
+	destroy_mspace): Use new macros.
+	(sys_alloc): Silence warning.
+	* Makefile.am (libffi_la_SOURCES): Add src/closures.c.
+	* Makefile.in: Rebuilt.
+	* src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in
+	terms of ffi_prep_closure_loc.
+	* src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted
+	from...
+	(ffi_prep_raw_closure): ... this.  Re-implement in terms of the
+	renamed version.
+	* src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and
+	adjusted from...
+	(ffi_prep_java_raw_closure): ... this.  Re-implement in terms of
+	the renamed version.
+	* src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from
+	(ffi_prep_closure): ... this.
+	* src/pa/ffi.c: Likewise.
+	* src/cris/ffi.c: Likewise.  Adjust.
+	* src/frv/ffi.c: Likewise.
+	* src/ia64/ffi.c: Likewise.
+	* src/mips/ffi.c: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+	* src/s390/ffi.c: Likewise.
+	* src/sh/ffi.c: Likewise.
+	* src/sh64/ffi.c: Likewise.
+	* src/sparc/ffi.c: Likewise.
+	* src/x86/ffi64.c: Likewise.
+	* src/x86/ffi.c: Likewise.
+	(FFI_INIT_TRAMPOLINE): Adjust.
+	(ffi_prep_raw_closure_loc): Renamed and adjusted from...
+	(ffi_prep_raw_closure): ... this.
+	* src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from
+	(ffi_prep_closure): ... this.
+	(flush_icache): Adjust.
+
+2007-03-07  Alexandre Oliva  <[email protected]>
+
+	* src/dlmalloc.c: New file, imported version 2.8.3 of Doug
+	Lea's malloc.
+
+2007-03-01  Brooks Moses  <[email protected]>
+
+	* Makefile.am: Add dummy install-pdf target.
+	* Makefile.in: Regenerate
+
+2007-02-13  Andreas Krebbel  <[email protected]>
+
+	* src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep,
+	ffi_closure_helper_SYSV): Add long double handling.
+
+2007-02-02  Jakub Jelinek  <[email protected]>
+
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2
+	immediately after bctrl instruction.
+
+2007-01-18  Alexandre Oliva  <[email protected]>
+
+	* Makefile.am (all-recursive, install-recursive,
+	mostlyclean-recursive, clean-recursive, distclean-recursive,
+	maintainer-clean-recursive): Add missing targets.
+	* Makefile.in: Rebuilt.
+
+2006-12-14  Andreas Tobler  <[email protected]>
+
+	* configure.ac: Add TARGET for x86_64-*-darwin*.
+	* Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources
+	for X86_DARWIN.
+	* src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*.
+	* src/x86/darwin64.S: New file for x86_64-*-darwin* support.
+	* configure: Regenerate.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+	* testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for
+	ffi_call only.
+
+2006-12-13  Andreas Tobler <[email protected]>
+
+	* aclocal.m4: Regenerate with aclocal -I .. as written in the
+	Makefile.am.
+
+2006-10-31  Geoffrey Keating  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New.
+	(ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for
+	Darwin.
+	* testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL.
+	* testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL.
+
+2006-10-10  Paolo Bonzini  <[email protected]>
+	    Sandro Tolaini  <[email protected]>
+
+	* configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and
+	conditional.
+	* configure: Regenerated.
+	* Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case.
+	(EXTRA_DIST): Add src/x86/darwin.S.
+	* Makefile.in: Regenerated.
+	* include/Makefile.in: Regenerated.
+	* testsuite/Makefile.in: Regenerated.
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like
+	X86_WIN32, and additionally align stack to 16 bytes.
+	* src/x86/darwin.S: New, based on sysv.S.
+	* src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs.
+
+2006-09-12  David Daney  <[email protected]>
+
+	PR libffi/23935
+	* include/Makefile.am: Install both ffi.h and ffitarget.h in
+	$(libdir)/gcc/$(target_alias)/$(gcc_version)/include.
+	* aclocal.m4: Regenerated for automake 1.9.6.
+	* Makefile.in: Regenerated.
+	* include/Makefile.in: Regenerated.
+	* testsuite/Makefile.in: Regenerated.
+
+2006-08-17  Andreas Tobler  <[email protected]>
+
+	* include/ffi_common.h (struct): Revert accidental commit.
+
+2006-08-15  Andreas Tobler  <[email protected]>
+
+	* include/ffi_common.h: Remove lint directives.
+	* include/ffi.h.in: Likewise.
+
+2006-07-25  Torsten Schoenfeld  <[email protected]>
+
+	* include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly
+	for 32-bit architectures.
+	* testsuite/libffi.call/return_ul.c: New test case.
+
+2006-07-19  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/closure_fn6.c: Remove xfail for mips,
+	xfail remains for mips64.
+
+2006-05-23  Carlos O'Donell  <[email protected]>
+
+	* Makefile.am: Add install-html target. Add install-html to .PHONY
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2006-05-18  John David Anglin  <[email protected]>
+
+	* pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from
+	stack slot.
+
+2006-04-22  Andreas Tobler  <[email protected]>
+
+	* README: Remove notice about 'Crazy Comments'.
+	* src/debug.c: Remove lint directives. Cleanup white spaces.
+	* src/java_raw_api.c: Likewise.
+	* src/prep_cif.c: Likewise.
+	* src/raw_api.c: Likewise.
+	* src/ffitest.c: Delete. No longer needed, all test cases migrated
+	to the testsuite.
+	* src/arm/ffi.c: Remove lint directives.
+	* src/m32r/ffi.c: Likewise.
+	* src/pa/ffi.c: Likewise.
+	* src/powerpc/ffi.c: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+	* src/sh/ffi.c: Likewise.
+	* src/sh64/ffi.c: Likewise.
+	* src/x86/ffi.c: Likewise.
+	* testsuite/libffi.call/float2.c: Likewise.
+	* testsuite/libffi.call/promotion.c: Likewise.
+	* testsuite/libffi.call/struct1.c: Likewise.
+
+2006-04-13  Andreas Tobler  <[email protected]>
+
+	* src/pa/hpux32.S: Correct unwind offset calculation for
+	ffi_closure_pa32.
+	* src/pa/linux.S: Likewise.
+
+2006-04-12  James E Wilson  <[email protected]>
+
+	PR libgcj/26483
+	* src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros.
+	(hfa_type_load): Call stf_spill.
+	(hfa_type_store): Call ldf_fill.
+	(ffi_call): Adjust calls to above routines.  Add local temps for
+	macro result.
+
+2006-04-10  Matthias Klose  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib
+	directory names containing underscores.
+
+2006-04-07  James E Wilson  <[email protected]>
+
+	* testsuite/libffi.call/float4.c: New testcase.
+
+2006-04-05  John David Anglin  <[email protected]>
+	    Andreas Tobler  <[email protected]>
+
+	* Makefile.am: Add PA_HPUX port.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* configure.ac: Add PA_HPUX rules.
+	* configure: Regenerate.
+	* src/pa/ffitarget.h: Rename linux target to PA_LINUX.
+	Add PA_HPUX and PA64_HPUX.
+	Rename FFI_LINUX ABI to FFI_PA32 ABI.
+	(FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets.
+	(FFI_TYPE_SMALL_STRUCT2): Define.
+	(FFI_TYPE_SMALL_STRUCT4): Likewise.
+	(FFI_TYPE_SMALL_STRUCT8): Likewise.
+	(FFI_TYPE_SMALL_STRUCT3): Redefine.
+	(FFI_TYPE_SMALL_STRUCT5): Likewise.
+	(FFI_TYPE_SMALL_STRUCT6): Likewise.
+	(FFI_TYPE_SMALL_STRUCT7): Likewise.
+	* src/pa/ffi.c (ROUND_DOWN): Delete.
+	(fldw, fstw, fldd, fstd): Use '__asm__'.
+	(ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2,
+	FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8.
+	(ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment.
+	Simplify incrementing of stack slot variable. Change type of local
+	'n' to unsigned int.
+	(ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long
+	double on PA_HPUX.
+	(ffi_prep_cif_machdep): Likewise.
+	(ffi_call): Likewise.
+	(ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change
+	return type to ffi_status. Simplify incrementing of stack slot
+	variable. Only copy floating point argument registers when PA_LINUX
+	is true. Reformat debug statement.
+	Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and
+	FFI_TYPE_SMALL_STRUCT8.
+	(ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to
+	declaration.
+	(ffi_prep_closure): Make linux trampoline conditional on PA_LINUX.
+	Add nops to cache flush.  Add trampoline for PA_HPUX.
+	* src/pa/hpux32.S: New file.
+	* src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename
+	ffi_prep_args_LINUX to ffi_prep_args_pa32.
+	Localize labels. Add support for 2, 4 and 8-byte small structs. Handle
+	unaligned destinations in 3, 5, 6 and 7-byte small structs. Order
+	argument type checks so that common argument types appear first.
+	(ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename
+	ffi_closure_inner_LINUX to ffi_closure_inner_pa32.
+
+2006-03-24  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX.  Default
+	for 32-bit using IBM extended double format.  Fix FFI_LAST_ABI.
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of
+	FFI_TYPE_LONGDOUBLE.
+	(ffi_prep_args64): Assert using IBM extended double.
+	(ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type.
+	Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args.
+	(ffi_call): Handle FFI_LINUX.
+	(ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs
+	gpr3 return pointer as for struct return.  Handle FFI_LINUX
+	FFI_TYPE_LONGDOUBLE return and args.  Don't increment "nf"
+	unnecessarily.
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2
+	for FFI_TYPE_LONGDOUBLE.  Move epilogue insns into case table.
+	Don't use r6 as pointer to results, instead use sp offset.  Don't
+	make a special call to load lr with case table address, instead
+	use offset from previous call.
+	* src/powerpc/sysv.S (ffi_call_SYSV): Save long double return.
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double
+	return.
+
+2006-03-15  Kaz Kojima  <[email protected]>
+
+	* src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments
+	passed with FP registers correctly.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/sh64/sysv.S: Likewise.
+
+2006-03-01  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif,
+	args and userdata unused.
+	(closure_test_fn1): Mark cif and userdata unused.
+	(main): Remove unused res.
+
+2006-02-28  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for
+	-O2, -O3, -Os and the warning flags -W -Wall.
+	* testsuite/libffi.special/special.exp: Likewise.
+	* testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark
+	unused parameter unused for gcc or else do nothing.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+	* testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif
+	and userdata unused.
+	* testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise.
+	* testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise.
+	* testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise.
+	* testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise.
+	* testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise.
+	* testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise.
+	* testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise.
+	* testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise.
+	* testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise.
+	* testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise.
+	* testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise.
+	* testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise.
+	* testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise.
+	* testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise.
+	* testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise.
+	* testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise.
+	* testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise.
+	* testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise.
+	* testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise.
+	* testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise.
+	* testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast
+	void* to avoid compiler warning.
+	(main): Likewise.
+	(cls_struct_align_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn):
+	Likewise.
+	* testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise.
+	* testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise.
+	* testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif
+	and data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and
+	data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif
+	and data unused.
+	(main): Cast res_call to silence gcc.
+	* testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and
+	userdata unused.
+	(cls_ret_schar_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and
+	userdata unused.
+	(cls_ret_sint_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and
+	userdata unused.
+	(cls_ret_sshort_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn):  Mark cif and
+	userdata unused.
+	(cls_ret_uchar_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and
+	userdata unused.
+	(cls_ret_uint_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif
+	and userdata unused.
+	* testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and
+	userdata unused.
+	(cls_ret_ushort_fn): Cast printf parameter to silence gcc.
+	* testsuite/libffi.call/float.c (floating): Remove unused parameter e.
+	* testsuite/libffi.call/float1.c (main): Remove unused variable i.
+	Cleanup white spaces.
+	* testsuite/libffi.call/negint.c (checking): Remove unused variable i.
+	* testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark
+	cif and userdata unused.
+	* testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn):
+	Likewise.
+	* testsuite/libffi.call/nested_struct10.c (B_gn): Likewise.
+	* testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf
+	formatters to silence gcc.
+	(B_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata
+	unused.
+	* testsuite/libffi.call/nested_struct4.c: Mention related PR.
+	(B_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata
+	unused.
+	* testsuite/libffi.call/nested_struct6.c: Mention related PR.
+	(B_gn): Mark cif and userdata unused.
+	* testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata
+	unused.
+	* testsuite/libffi.call/nested_struct8.c (B_gn): Likewise.
+	* testsuite/libffi.call/nested_struct9.c (B_gn): Likewise.
+	* testsuite/libffi.call/problem1.c (stub): Likewise.
+	* testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence
+	gcc.
+	* testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned
+	in the last commit for this test case in the test case itself.
+	* testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as
+	unused.
+	* testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise.
+	* testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise.
+	* testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise.
+	* testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise.
+	* testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise.
+	* testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise.
+
+2006-02-22  Kaz Kojima  <[email protected]>
+
+	* src/sh/sysv.S: Fix register numbers in the FDE for
+	ffi_closure_SYSV.
+
+2006-02-20  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/return_fl2.c (return_fl): Remove static
+	declaration to avoid a false negative on ix86. See PR323.
+
+2006-02-18  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable
+	and cast integer to void * if needed.  Update the pointer to
+	the FP register saved area correctly.
+
+2006-02-17  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630
+	is fixed.
+	* testsuite/libffi.call/nested_struct4.c: Likewise.
+
+2006-02-16  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/return_dbl.c: New test case.
+	* testsuite/libffi.call/return_dbl1.c: Likewise.
+	* testsuite/libffi.call/return_dbl2.c: Likewise.
+	* testsuite/libffi.call/return_fl.c: Likewise.
+	* testsuite/libffi.call/return_fl1.c: Likewise.
+	* testsuite/libffi.call/return_fl2.c: Likewise.
+	* testsuite/libffi.call/return_fl3.c: Likewise.
+	* testsuite/libffi.call/closure_fn6.c: Likewise.
+
+	* testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong
+	definition.
+	* testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition
+	here to be used by other test cases too.
+
+	* testsuite/libffi.call/nested_struct10.c: New test case.
+	* testsuite/libffi.call/nested_struct9.c: Likewise.
+	* testsuite/libffi.call/nested_struct8.c: Likewise.
+	* testsuite/libffi.call/nested_struct7.c: Likewise.
+	* testsuite/libffi.call/nested_struct6.c: Likewise.
+	* testsuite/libffi.call/nested_struct5.c: Likewise.
+	* testsuite/libffi.call/nested_struct4.c: Likewise.
+
+2006-01-21  Andreas Tobler  <[email protected]>
+
+	* configure.ac: Enable libffi for sparc64-*-freebsd*.
+	* configure: Rebuilt.
+
+2006-01-18  Jakub Jelinek  <[email protected]>
+
+	* src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3,
+	instead do the shifting inline.
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5
+	shift count unconditionally.  Simplify load sequences for 1, 2, 3, 4
+	and 8 byte structs, for the remaining struct sizes don't call
+	__lshrdi3, instead do the shifting inline.
+
+2005-12-07  Thiemo Seufer  <[email protected]>
+
+	* src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add
+	missing parentheses.
+	* src/mips/o32.S (ffi_call_O32): Code formatting. Define
+	and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations.
+	(ffi_closure_O32): Likewise, but with newly defined A3_OFF2,
+	A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2,
+	V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2,
+	FA_0_0_OFF2.
+	* src/mips/ffi.c (ffi_prep_args): Code formatting. Fix
+	endianness bugs.
+	(ffi_prep_closure): Improve trampoline instruction scheduling.
+	(ffi_closure_mips_inner_O32): Fix endianness bugs.
+
+2005-12-03  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c: Formatting.
+	(ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
+	(ffi_prep_args64): Likewise.
+
+2005-09-30  Geoffrey Keating  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): For
+	darwin, use -shared-libgcc not -lgcc_s, and explain why.
+
+2005-09-26  Tom Tromey  <[email protected]>
+
+	* testsuite/libffi.call/float1.c (value_type): New typedef.
+	(CANARY): New define.
+	(main): Check for result buffer overflow.
+	* src/powerpc/linux64.S: Handle linux64 long double returns.
+	* src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant.
+	(ffi_prep_cif_machdep): Handle linux64 long double returns.
+
+2005-08-25  Alan Modra  <[email protected]>
+
+	PR target/23404
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack
+	homed fp args.
+	(ffi_status ffi_prep_cif_machdep): Correct stack sizing for same.
+
+2005-08-11  Jakub Jelinek  <[email protected]>
+
+	* configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test.
+	(AH_BOTTOM): Add FFI_HIDDEN definition.
+	* configure: Rebuilt.
+	* fficonfig.h.in: Rebuilt.
+	* src/powerpc/ffi.c (hidden): Remove.
+	(ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64,
+	ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64,
+	.ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden.
+	* src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove,
+	add FFI_HIDDEN to its prototype.
+	(ffi_closure_SYSV_inner): New.
+	* src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
+	* src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New.
+
+2005-08-10  Alfred M. Szmidt  <[email protected]>
+
+	PR libffi/21819:
+	* configure: Rebuilt.
+	* configure.ac: Handle i*86-*-gnu*.
+
+2005-08-09  Jakub Jelinek  <[email protected]>
+
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use
+	DW_CFA_offset_extended_sf rather than
+	DW_CFA_GNU_negative_offset_extended.
+	* src/powerpc/sysv.S (ffi_call_SYSV): Likewise.
+
+2005-07-22  SUGIOKA Toshinobu  <[email protected]>
+
+	* src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly
+	on sh3.
+	(ffi_closure_SYSV): Change the stack layout for sh3 struct argument.
+	* src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is
+	partially on register.
+	(ffi_closure_helper_SYSV): Likewise.
+	(ffi_prep_cif_machdep): Don't set too many cif->flags.
+
+2005-07-20  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_call): Handle small structures correctly.
+	Remove empty line.
+	* src/sh64/ffi.c (simple_type): Remove.
+	(return_type): Handle small structures correctly.
+	(ffi_prep_args): Likewise.
+	(ffi_call): Likewise.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return.
+	Emit position independent code if PIC and remove wrong datalabel
+	prefixes from EH data.
+
+2005-07-19  Andreas Tobler  <[email protected]>
+
+	* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* configure.ac: Add POWERPC_FREEBSD rules.
+	* configure: Regenerate.
+	* src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules.
+	(FFI_SYSV_TYPE_SMALL_STRUCT): Define.
+	* src/powerpc/ffi.c: Add flags to handle small structure returns
+	in ffi_call_SYSV.
+	(ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI.
+	Aka FFI_SYSV.
+	(ffi_closure_helper_SYSV): Likewise.
+	* src/powerpc/ppc_closure.S: Add return types for small structures.
+	* src/powerpc/sysv.S: Add bits to handle small structures for
+	final SYSV 4 ABI.
+
+2005-07-10  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/cls_5_1_byte.c: New test file.
+	* testsuite/libffi.call/cls_6_1_byte.c: Likewise.
+	* testsuite/libffi.call/cls_7_1_byte.c: Likewise.
+
+2005-07-05  Randolph Chung  <[email protected]>
+
+	* src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1
+	as FFI_TYPE_SMALL_STRUCT3.  Break out handling for 5-7 byte
+	structures.  Kill compilation warnings.
+	(ffi_closure_inner_LINUX): Print return values as hex in debug
+	message.  Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3.
+	Properly handle 5-7 byte structure returns.
+	* src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1)
+	(FFI_TYPE_SMALL_STRUCT2): Remove.
+	(FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5)
+	(FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define.
+	* src/pa/linux.S: Mark source file as using PA1.1 assembly.
+	(checksmst1, checksmst2): Remove.
+	(checksmst3): Optimize handling of 3-byte struct returns.
+	(checksmst567): Properly handle 5-7 byte struct returns.
+
+2005-06-15  Rainer Orth  <[email protected]>
+
+	PR libgcj/21943
+	* src/mips/n32.S: Enforce PIC code.
+	* src/mips/o32.S: Likewise.
+
+2005-06-15  Rainer Orth  <[email protected]>
+
+	* configure.ac: Treat i*86-*-solaris2.10 and up as X86_64.
+	* configure: Regenerate.
+
+2005-06-01  Alan Modra  <[email protected]>
+
+	* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET
+	to call ffi_closure_helper_SYSV.  Append @local instead.
+	* src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV.
+
+2005-05-17  Kelley Cook  <[email protected]>
+
+	* configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS.
+	Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF.
+	* Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config.
+	* aclocal.m4, configure, fficonfig.h.in, Makefile.in,
+	include/Makefile.in, testsuite/Makefile.in: Regenerate.
+
+2005-05-09  Mike Stump  <[email protected]>
+
+	* configure: Regenerate.
+
+2005-05-08  Richard Henderson  <[email protected]>
+
+	PR libffi/21285
+	* src/alpha/osf.S: Update unwind into to match code.
+
+2005-05-04  Andreas Degert <[email protected]>
+	    Richard Henderson  <[email protected]>
+
+	* src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in
+	bit 11 of flags.
+	(ffi_call): Mask return type field.  Pass ssecount to ffi_call_unix64.
+	(ffi_prep_closure): Set carry bit if sse-used flag set.
+	* src/x86/unix64.S (ffi_call_unix64): Add ssecount argument.
+	Only load sse registers if ssecount non-zero.
+	(ffi_closure_unix64): Only save sse registers if carry set on entry.
+
+2005-04-29  Ralf Corsepius  <[email protected]>
+
+	* configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*,
+	powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*.
+	* configure: Regenerate.
+
+2005-04-20  Hans-Peter Nilsson  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use,
+	have Tcl8.3-compatible intermediate variable.
+
+2005-04-18  Simon Posnjak <[email protected]>
+	    Hans-Peter Nilsson  <[email protected]>
+
+	* Makefile.am: Add CRIS support.
+	* configure.ac: Likewise.
+	* Makefile.in, configure, testsuite/Makefile.in,
+	include/Makefile.in: Regenerate.
+	* src/cris: New directory.
+	* src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files.
+	* src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__.
+
+	* testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with
+	\r?\n in output tests.
+
+2005-04-12  Mike Stump  <[email protected]>
+
+	* configure: Regenerate.
+
+2005-03-30  Hans Boehm  <[email protected]>
+
+	* src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI.
+
+2005-03-30  Steve Ellcey  <[email protected]>
+
+	* src/ia64/ffitarget.h (ffi_arg) ADD DI attribute.
+	(ffi_sarg) Ditto.
+	* src/ia64/unix.S (ffi_closure_unix): Extend gp
+	to 64 bits in ILP32 mode.
+	Load 64 bits even for short data.
+
+2005-03-23  Mike Stump  <[email protected]>
+
+	* src/powerpc/darwin.S: Update for -m64 multilib.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2005-03-21  Zack Weinberg  <[email protected]>
+
+	* configure.ac: Do not invoke TL_AC_GCC_VERSION.
+	Do not set tool_include_dir.
+	* aclocal.m4, configure, Makefile.in, testsuite/Makefile.in:
+	Regenerate.
+	* include/Makefile.am: Set gcc_version and toollibffidir.
+	* include/Makefile.in: Regenerate.
+
+2005-02-22  Andrew Haley  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to
+	odd-numbered register pairs for 64-bit integer types.
+
+2005-02-23  Andreas Tobler  <[email protected]>
+
+	PR libffi/20104
+	* testsuite/libffi.call/return_ll1.c: New test case.
+
+2005-02-11  Janis Johnson  <[email protected]>
+
+	* testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options.
+	* testsuite/libffi.call/float.c: Ditto.
+	* testsuite/libffi.call/float2.c: Ditto.
+	* testsuite/libffi.call/float3.c: Ditto.
+
+2005-02-08  Andreas Tobler  <[email protected]>
+
+	* src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv.
+
+2005-01-12  Eric Botcazou  <[email protected]>
+
+	* testsuite/libffi.special/special.exp (cxx_options): Add
+	-shared-libgcc.
+
+2004-12-31  Richard Henderson  <[email protected]>
+
+	* src/types.c (FFI_AGGREGATE_TYPEDEF): Remove.
+	(FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF.  Replace size and
+	offset parameters with a type parameter; deduce size and structure
+	alignment.  Update all users.
+
+2004-12-31  Richard Henderson  <[email protected]>
+
+	* src/types.c (FFI_TYPE_POINTER): Define with sizeof.
+	(FFI_TYPE_LONGDOUBLE): Fix for ia64.
+	* src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move
+	into ffi_prep_closure.
+	* src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite
+	from scratch.
+
+2004-12-27  Richard Henderson  <[email protected]>
+
+	* src/x86/unix64.S: Fix typo in unwind info.
+
+2004-12-25  Richard Henderson  <[email protected]>
+
+	* src/x86/ffi64.c (struct register_args): Rename from stackLayout.
+	(enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS.
+	(merge_classes): Check for it.
+	(SSE_CLASS_P): New.
+	(classify_argument): Pass byte_offset by value; perform all updates
+	inside struct case.
+	(examine_argument): Add classes argument; handle
+	X86_64_COMPLEX_X87_CLASS.
+	(ffi_prep_args): Merge into ...
+	(ffi_call): ... here.  Share stack frame with ffi_call_unix64.
+	(ffi_prep_cif_machdep): Setup cif->flags for proper structure return.
+	(ffi_fill_return_value): Remove.
+	(ffi_prep_closure): Remove dead assert.
+	(ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner.
+	Rewrite to use struct register_args instead of va_list.  Create
+	flags for handling structure returns.
+	* src/x86/unix64.S: Remove dead strings.
+	(ffi_call_unix64): Rename from ffi_call_UNIX64.  Rewrite to share
+	stack frame with ffi_call.  Handle structure returns properly.
+	(float2sse, floatfloat2sse, double2sse): Remove.
+	(sse2float, sse2double, sse2floatfloat): Remove.
+	(ffi_closure_unix64): Rename from ffi_closure_UNIX64.  Rewrite
+	to handle structure returns properly.
+
+2004-12-08  David Edelsohn  <[email protected]>
+
+	* Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and
+	PICFLAG.
+	* Makefile.in: Regenerated.
+
+2004-12-02  Richard Sandiford  <[email protected]>
+
+	* configure.ac: Use TL_AC_GCC_VERSION to set gcc_version.
+	* configure, aclocal.m4, Makefile.in: Regenerate.
+	* include/Makefile.in, testsuite/Makefile.in: Regenerate.
+
+2004-11-29  Kelley Cook  <[email protected]>
+
+	* configure: Regenerate for libtool change.
+
+2004-11-25  Kelley Cook  <[email protected]>
+
+	* configure: Regenerate for libtool reversion.
+
+2004-11-24  Kelley Cook  <[email protected]>
+
+	* configure: Regenerate for libtool change.
+
+2004-11-23  John David Anglin  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp.
+
+2004-11-23  Richard Sandiford  <[email protected]>
+
+	* src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead
+	of jal.  Use an absolute encoding for the frame information.
+
+2004-11-23  Kelley Cook  <[email protected]>
+
+	* Makefile.am: Remove no-dependencies.  Add ACLOCAL_AMFLAGS.
+	* acinclude.m4: Delete logic for sincludes.
+	* aclocal.m4, Makefile.in, configure: Regenerate.
+	* include/Makefile: Likewise.
+	* testsuite/Makefile: Likewise.
+
+2004-11-22  Eric Botcazou  <[email protected]>
+
+	* src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers
+	on a 8-byte boundary.
+	* src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments.
+
+2004-10-27  Richard Earnshaw  <[email protected]>
+
+	* src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return
+	long long values.  Round stack allocation to a multiple of 8 bytes
+	for ATPCS compatibility.
+	* src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register
+	names.  Handle returning long long types.  Add Thumb and interworking
+	support.  Improve soft-float code.
+
+2004-10-27  Richard Earnshaw  <[email protected]>
+
+	* testsuite/lib/libffi-db.exp (load_gcc_lib): New function.
+	(libffi_exit): New function.
+	(libffi_init): Build the testglue wrapper if needed.
+
+2004-10-25  Eric Botcazou  <[email protected]>
+
+	PR other/18138
+	* testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc.
+
+2004-10-25  Kazuhiro Inaoka <[email protected]>
+
+	* src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0.
+
+2004-10-20  Kaz Kojima  <[email protected]>
+
+	* src/sh/sysv.S (ffi_call_SYSV): Don't align for double data.
+	* testsuite/libffi.call/float3.c: New test case.
+
+2004-10-18  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for
+	the function returning a structure pointed with R2.
+	* src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to
+	the structure return value if T bit set.  Emit position
+	independent code and EH data if PIC.
+
+2004-10-13  Kazuhiro Inaoka  <[email protected]>
+
+	* Makefile.am: Add m32r support.
+	* configure.ac: Likewise.
+	* Makefile.in: Regenerate.
+	* confiugre: Regenerate.
+	* src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF
+	(uint64, sint64, double, longdouble)
+	* src/m32r: New directory.
+	* src/m32r/ffi.c: New file.
+	* src/m32r/sysv.S: Likewise.
+	* src/m32r/ffitarget.h: Likewise.
+
+2004-10-02  Kaz Kojima  <[email protected]>
+
+	* testsuite/libffi.call/negint.c: New test case.
+
+2004-09-14  H.J. Lu  <[email protected]>
+
+	PR libgcj/17465
+	* testsuite/lib/libffi-dg.exp: Don't use global ld_library_path.
+	Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH,
+	LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and
+	DYLD_LIBRARY_PATH.
+
+2004-09-05  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/many_win32.c: Remove whitespaces.
+	* testsuite/libffi.call/promotion.c: Likewise.
+	* testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup
+	whitespaces.
+	* testsuite/libffi.call/return_sc.c: Likewise.
+	* testsuite/libffi.call/return_uc.c: Likewise.
+
+2004-09-05  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/darwin.S: Fix comments and identation.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2004-09-02  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c: Add flag for longdouble return values.
+	(ffi_prep_args): Handle longdouble arguments.
+	(ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for
+	longdouble.
+	(ffi_closure_helper_DARWIN): Add closure handling for longdouble.
+	* src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble
+	values.
+	* src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise.
+	* src/types.c: Defined longdouble size and alignment for darwin.
+
+2004-09-02  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/aix.S: Remove whitespaces.
+	* src/powerpc/aix_closure.S: Likewise.
+	* src/powerpc/asm.h: Likewise.
+	* src/powerpc/ffi.c: Likewise.
+	* src/powerpc/ffitarget.h: Likewise.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/linux64_closure.S: Likewise.
+	* src/powerpc/ppc_closure.S: Likewise.
+	* src/powerpc/sysv.S: Likewise.
+
+2004-08-30  Anthony Green  <[email protected]>
+
+	* Makefile.am: Add frv support.
+	* Makefile.in, testsuite/Makefile.in: Rebuilt.
+	* configure.ac: Read configure.host.
+	* configure.in: Read configure.host.
+	* configure.host: New file.  frv-elf needs libgloss.
+	* include/ffi.h.in: Force ffi_closure to have a nice big (8)
+	alignment.  This is needed to frv and shouldn't harm the others.
+	* include/ffi_common.h (ALIGN_DOWN): New macro.
+	* src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files.
+
+2004-08-24  David Daney  <[email protected]>
+
+	* testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c  Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_align_double.c: Likewise.
+	* testsuite/libffi.call/cls_align_float.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint64.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_multi_schar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushort.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise and set return value
+	to zero.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+
+2004-08-23  David Daney <[email protected]>
+
+	PR libgcj/13141
+	* src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI.
+	* src/mips/ffi.c (ffi_prep_args): Fix alignment calculation.
+	(ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point
+	parameters and return types.
+	(ffi_call): Handle FFI_O32_SOFT_FLOAT ABI.
+	(ffi_prep_closure): Ditto.
+	(ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix
+	alignment calculations.
+	* src/mips/o32.S (ffi_closure_O32): Don't use floating point
+	instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant.
+
+2004-08-14  Casey Marshall <[email protected]>
+
+	* src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to
+	contain `FFI_TYPE_UINT64' as return type for any 64-bit
+	integer (O32 ABI only).
+	(ffi_prep_closure): new function.
+	(ffi_closure_mips_inner_O32): new function.
+	* src/mips/ffitarget.h: Define `FFI_CLOSURES' and
+	`FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32.
+	* src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return
+	64 bit integers correctly.
+	(ffi_closure_O32): new function.
+	Added DWARF-2 unwind info for both functions.
+
+2004-08-10  Andrew Haley  <[email protected]>
+
+	* src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments.
+
+2004-08-01  Robert Millan  <[email protected]>
+
+	* configure.ac: Detect knetbsd-gnu and kfreebsd-gnu.
+	* configure: Regenerate.
+
+2004-07-30  Maciej W. Rozycki  <[email protected]>
+
+	* acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for <sys/mman.h>
+	and mmap() explicitly instead of relying on preset autoconf cache
+	variables.
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+
+2004-07-11  Ulrich Weigand  <[email protected]>
+
+	* src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation.
+	(ffi_check_float_struct): Remove unused prototype.
+
+2004-06-30  Geoffrey Keating  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment
+	character on Darwin, use '\n\t' instead.
+
+2004-06-26  Matthias Klose  <[email protected]>
+
+	* libtool-version: Fix typo in revision/age.
+
+2004-06-17  Matthias Klose  <[email protected]>
+
+	* libtool-version: New.
+	* Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname.
+	* Makefile.in: Regenerate.
+
+2004-06-15  Paolo Bonzini  <[email protected]>
+
+	* Makefile.am: Remove useless multilib rules.
+	* Makefile.in: Regenerate.
+	* aclocal.m4: Regenerate with automake 1.8.5.
+	* configure.ac: Remove useless multilib configury.
+	* configure: Regenerate.
+
+2004-06-15  Paolo Bonzini  <[email protected]>
+
+	* .cvsignore: New file.
+
+2004-06-10  Jakub Jelinek  <[email protected]>
+
+	* src/ia64/unix.S (ffi_call_unix): Insert group barrier break
+	fp_done.
+	(ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever
+	changed from 8.
+
+2004-06-06  Sean McNeil  <[email protected]>
+
+	* configure.ac: Add x86_64-*-freebsd* support.
+	* configure: Regenerate.
+
+2004-04-26  Joe Buck <[email protected]>
+
+	Bug 15093
+	* configure.ac: Test for existence of mmap and sys/mman.h before
+	checking blacklist.  Fix suggested by Jim Wilson.
+	* configure: Regenerate.
+
+2004-04-26  Matt Austern  <[email protected]>
+
+	* src/powerpc/darwin.S: Go through a non-lazy pointer for initial
+	FDE location.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2004-04-24  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization
+	error. Reported by Thomas Heller <[email protected]>.
+	* testsuite/libffi.call/cls_multi_sshort.c (main): Likewise.
+	* testsuite/libffi.call/cls_multi_ushort.c (main): Likewise.
+
+2004-03-20  Matthias Klose  <[email protected]>
+
+	* src/pa/linux.S: Fix typo.
+
+2004-03-19  Matthias Klose  <[email protected]>
+
+	* Makefile.am: Update.
+	* Makefile.in: Regenerate.
+	* src/pa/ffi.h.in: Remove.
+	* src/pa/ffitarget.h: New file.
+
+2004-02-10  Randolph Chung  <[email protected]>
+
+	* Makefile.am: Add PA support.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* configure.ac: Add PA target.
+	* configure: Regenerate.
+	* src/pa/ffi.c: New file.
+	* src/pa/ffi.h.in: Add PA support.
+	* src/pa/linux.S: New file.
+	* prep_cif.c: Add PA support.
+
+2004-03-16  Hosaka Yuji  <[email protected]>
+
+	* src/types.c: Fix alignment size of X86_WIN32 case int64 and
+	double.
+	* src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type
+	with ecif->cif->flags.
+	(ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type
+	with cif->flags.
+	(ffi_prep_cif_machdep): Add X86_WIN32 struct case.
+	(ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32.
+	* src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b,
+	sc_retstruct2b): Add for 1 or 2-bytes struct case.
+
+2004-03-15 Kelley Cook <[email protected]>
+
+	* configure.in: Rename file to ...
+	* configure.ac: ... this.
+	* fficonfig.h.in: Regenerate.
+	* Makefile.in: Regenerate.
+	* include/Makefile.in: Regenerate.
+	* testsuite/Makefile.in: Regenerate.
+
+2004-03-12  Matt Austern  <[email protected]>
+
+	* src/powerpc/darwin.S: Fix EH information so it corresponds to
+	changes in EH format resulting from addition of linkonce support.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2004-03-11  Andreas Tobler  <[email protected]>
+	    Paolo Bonzini  <[email protected]>
+
+	* Makefile.am (AUTOMAKE_OPTIONS): Set them.
+	Remove VPATH. Remove rules for object files. Remove multilib support.
+	(AM_CCASFLAGS): Add.
+	* configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER.
+	(AC_PREREQ): Bump version to 2.59.
+	(AC_INIT): Fill with version info and bug address.
+	(ORIGINAL_LD_FOR_MULTILIBS): Remove.
+	(AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE.
+	De-precious CC so that the right flags are passed down to multilibs.
+	(AC_MSG_ERROR): Replace obsolete macro AC_ERROR.
+	(AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES.
+	(AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS.
+	* configure: Rebuilt.
+	* aclocal.m4: Likewise.
+	* Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise.
+	* fficonfig.h.in: Likewise.
+
+2004-03-11  Andreas Schwab  <[email protected]>
+
+	* src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point
+	arguments from fp registers only for the first 8 parameter slots.
+	Don't convert a float parameter when passed in memory.
+
+2004-03-09  Hans-Peter Nilsson  <[email protected]>
+
+	* configure: Regenerate for config/accross.m4 correction.
+
+2004-02-25  Matt Kraai  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Change
+	ecif->cif->bytes to bytes.
+	(ffi_prep_cif_machdep): Add braces around nested if statement.
+
+2004-02-09  Alan Modra  <[email protected]>
+
+	* src/types.c (pointer): POWERPC64 has 8 byte pointers.
+
+	* src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling.
+	(ffi_closure_helper_LINUX64): Fix typo.
+	* testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128
+	for powerpc64-*-*.
+	* testsuite/libffi.call/float.c: Likewise.
+	* testsuite/libffi.call/float2.c: Likewise.
+
+2004-02-08  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_cif_machdep <FFI_LINUX64>): Correct
+	long double function return and long double arg handling.
+	(ffi_closure_helper_LINUX64): Formatting.  Delete unused "ng" var.
+	Use "end_pfr" instead of "nf".  Correct long double handling.
+	Localise "temp".
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double
+	return value.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate
+	space for long double return value.  Adjust stack frame and offsets.
+	Load f2 long double return.
+
+2004-02-07  Alan Modra  <[email protected]>
+
+	* src/types.c: Use 16 byte long double for POWERPC64.
+
+2004-01-25  Eric Botcazou  <[email protected]>
+
+	* src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array
+	when the structure return address is passed in %o0.
+	(ffi_V9_return_struct): Rename into ffi_v9_layout_struct.
+	(ffi_v9_layout_struct): Align the field following a nested structure
+	on a word boundary.  Use memmove instead of memcpy.
+	(ffi_call): Update call to ffi_V9_return_struct.
+	(ffi_prep_closure): Define 'ctx' only for V8.
+	(ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8
+	and ffi_closure_sparc_inner_v9.
+	(ffi_closure_sparc_inner_v8): Return long doubles by reference.
+	Always skip the structure return address.  For structures and long
+	doubles, copy the argument directly.
+	(ffi_closure_sparc_inner_v9): Skip the structure return address only
+	if required.  Shift the maximum floating-point slot accordingly.  For
+	big structures, copy the argument directly; otherwise, left-justify the
+	argument and call ffi_v9_layout_struct to lay out the structure on
+	the stack.
+	* src/sparc/v8.S: Undef STACKFRAME before defining it.
+	(ffi_closure_v8): Pass the structure return address.  Update call to
+	ffi_closure_sparc_inner_v8.  Short-circuit FFI_TYPE_INT handling.
+	Skip the 'unimp' insn when returning long doubles and structures.
+	* src/sparc/v9.S: Undef STACKFRAME before defining it.
+	(ffi_closure_v9): Increase the frame size by 2 words.  Short-circuit
+	FFI_TYPE_INT handling.  Load structures both in integers and
+	floating-point registers on return.
+	* README: Update status of the SPARC port.
+
+2004-01-24  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/pyobjc-tc.c (main): Treat result value
+	as of type ffi_arg.
+	* testsuite/libffi.call/struct3.c (main): Fix CHECK.
+
+2004-01-22  Ulrich Weigand  <[email protected]>
+
+	* testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result
+	value as of type ffi_arg, not unsigned int.
+
+2004-01-21  Michael Ritzert  <[email protected]>
+
+	* ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead
+	of the LHS.
+
+2004-01-12  Andreas Tobler  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for
+	Solaris.
+
+2004-01-08  Rainer Orth  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED
+	to void *.
+
+2003-12-10  Richard Henderson  <[email protected]>
+
+	* testsuite/libffi.call/cls_align_pointer.c: Cast pointers to
+	size_t instead of int.
+
+2003-12-04  Hosaka Yuji  <[email protected]>
+
+	* testsuite/libffi.call/many_win32.c: Include <float.h>.
+	* testsuite/libffi.call/many_win32.c (main): Replace variable
+	int i with unsigned long ul.
+
+	* testsuite/libffi.call/cls_align_uint64.c: New test case.
+	* testsuite/libffi.call/cls_align_sint64.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint32.c: Likewise.
+	* testsuite/libffi.call/cls_align_uint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_sint16.c: Likewise.
+	* testsuite/libffi.call/cls_align_float.c: Likewise.
+	* testsuite/libffi.call/cls_align_double.c: Likewise.
+	* testsuite/libffi.call/cls_align_longdouble.c: Likewise.
+	* testsuite/libffi.call/cls_align_pointer.c: Likewise.
+
+2003-12-02  Hosaka Yuji  <[email protected]>
+
+	PR other/13221
+	* src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV):
+	Align arguments to 32 bits.
+
+2003-12-01  Andreas Tobler  <[email protected]>
+
+	PR other/13221
+	* testsuite/libffi.call/cls_multi_sshort.c: New test case.
+	* testsuite/libffi.call/cls_multi_sshortchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_schar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushortchar.c: Likewise.
+	* testsuite/libffi.call/cls_multi_ushort.c: Likewise.
+
+	* testsuite/libffi.special/unwindtest.cc: Cosmetics.
+
+2003-11-26  Kaveh R. Ghazi  <[email protected]>
+
+	* testsuite/libffi.call/ffitest.h: Include <fcntl.h>.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+
+2003-11-22  Andreas Tobler  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+	* configure: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Convert the mmap to
+	the right type.
+
+2003-11-21  Andreas Jaeger  <[email protected]>
+	    Andreas Tobler  <[email protected]>
+
+	* acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST.
+	* configure.in: Call AC_FUNC_MMAP_BLACKLIST.
+	* Makefile.in: Rebuilt.
+	* aclocal.m4: Likewise.
+	* configure: Likewise.
+	* fficonfig.h.in: Likewise.
+	* testsuite/lib/libffi-dg.exp: Add include dir.
+	* testsuite/libffi.call/ffitest.h: Add MMAP definitions.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+	* testsuite/libffi.call/closure_fn0.c: Use MMAP functionality
+	for ffi_closure if available.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+
+2003-11-20  Andreas Tobler  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional.
+
+2003-11-19  Andreas Tobler  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin.
+	Add -lgcc_s to additional flags.
+
+2003-11-12  Andreas Tobler  <[email protected]>
+
+	* configure.in, include/Makefile.am: PR libgcj/11147, install
+	the ffitarget.h header file in a gcc versioned and target
+	dependent place.
+	* configure: Regenerated.
+	* Makefile.in, include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+
+2003-11-09  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/closure_fn0.c: Print result and check
+	with dg-output to make debugging easier.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_9byte2.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+
+	* testsuite/libffi.special/unwindtest.cc: Make ffi_closure
+	static.
+
+2003-11-08  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/cls_9byte2.c: New test case.
+	* testsuite/libffi.call/cls_9byte1.c: Likewise.
+	* testsuite/libffi.call/cls_64byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte1.c: Likewise.
+	* testsuite/libffi.call/cls_19byte.c: Likewise.
+	* testsuite/libffi.call/cls_18byte.c: Likewise.
+	* testsuite/libffi.call/closure_fn4.c: Likewise.
+	* testsuite/libffi.call/closure_fn5.c: Likewise.
+	* testsuite/libffi.call/cls_schar.c: Likewise.
+	* testsuite/libffi.call/cls_sint.c: Likewise.
+	* testsuite/libffi.call/cls_sshort.c: Likewise.
+	* testsuite/libffi.call/nested_struct2.c: Likewise.
+	* testsuite/libffi.call/nested_struct3.c: Likewise.
+
+2003-11-08  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/cls_double.c: Do a check on the result.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/return_sc.c: Cleanup whitespaces.
+
+2003-11-06  Andreas Tobler  <[email protected]>
+
+	* src/prep_cif.c (ffi_prep_cif): Move the validity check after
+	the initialization.
+
+2003-10-23  Andreas Tobler  <[email protected]>
+
+	* src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace
+	FFI_ASSERT(FALSE) with FFI_ASSERT(0).
+
+2003-10-22  David Daney  <[email protected]>
+
+	* src/mips/ffitarget.h: Replace undefined UINT32 and friends with
+	__attribute__((__mode__(__SI__))) and friends.
+
+2003-10-22  Andreas Schwab  <[email protected]>
+
+	* src/ia64/ffi.c: Replace FALSE/TRUE with false/true.
+
+2003-10-21  Andreas Tobler  <[email protected]>
+
+	* configure.in: AC_LINK_FILES(ffitarget.h).
+	* configure: Regenerate.
+	* Makefile.in: Likewise.
+	* include/Makefile.in: Likewise.
+	* testsuite/Makefile.in: Likewise.
+	* fficonfig.h.in: Likewise.
+
+2003-10-21  Paolo Bonzini  <[email protected]>
+	    Richard Henderson  <[email protected]>
+
+	Avoid that ffi.h includes fficonfig.h.
+
+	* Makefile.am (EXTRA_DIST): Include ffitarget.h files
+	(TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
+	(TARGET_SRC_MIPS_SGI): Removed.
+	(MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX.
+	(MIPS_SGI): Removed.
+	(CLEANFILES): Removed.
+	(mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New
+	targets.
+	* acconfig.h: Removed.
+	* configure.in: Compute sizeofs only for double and long double.
+	Use them to define and subst HAVE_LONG_DOUBLE.  Include comments
+	into AC_DEFINE instead of using acconfig.h.  Create
+	include/ffitarget.h instead of include/fficonfig.h.  Rename
+	MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree.
+	AC_DEFINE EH_FRAME_FLAGS.
+	* include/Makefile.am (DISTCLEANFILES): New automake macro.
+	(hack_DATA): Add ffitarget.h.
+	* include/ffi.h.in: Remove all system specific definitions.
+	Declare raw API even if it is not installed, why bother?
+	Use limits.h instead of SIZEOF_* to define ffi_type_*.  Do
+	not define EH_FRAME_FLAGS, it is in fficonfig.h now.  Include
+	ffitarget.h instead of fficonfig.h.  Remove ALIGN macro.
+	(UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead.
+	* include/ffi_common.h (bool): Do not define.
+	(ffi_assert): Accept failed assertion.
+	(ffi_type_test): Return void and accept file/line.
+	(FFI_ASSERT): Pass stringized failed assertion.
+	(FFI_ASSERT_AT): New macro.
+	(FFI_ASSERT_VALID_TYPE): New macro.
+	(UINT8, SINT8, UINT16, SINT16, UINT32, SINT32,
+	UINT64, SINT64): Define here with gcc's __attribute__ macro
+	instead of in ffi.h
+	(FLOAT32, ALIGN): Define here instead of in ffi.h
+	* include/ffi-mips.h: Removed.  Its content moved to
+	src/mips/ffitarget.h after separating assembly and C sections.
+	* src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c
+	src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c,
+	src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S,
+	src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c:
+	SIZEOF_ARG -> FFI_SIZEOF_ARG.
+	* src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+).
+	* src/debug.c (ffi_assert): Accept stringized failed assertion.
+	(ffi_type_test): Rewritten.
+	* src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call
+	FFI_ASSERT_VALID_TYPE.
+	* src/alpha/ffitarget.h, src/arm/ffitarget.h,
+	src/ia64/ffitarget.h, src/m68k/ffitarget.h,
+	src/mips/ffitarget.h, src/powerpc/ffitarget.h,
+	src/s390/ffitarget.h, src/sh/ffitarget.h,
+	src/sh64/ffitarget.h, src/sparc/ffitarget.h,
+	src/x86/ffitarget.h: New files.
+	* src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S,
+	src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S,
+	src/powerpc/aix.S, src/powerpc/darwin.S,
+	src/powerpc/ffi_darwin.c, src/powerpc/linux64.S,
+	src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S,
+	src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S,
+	src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S,
+	src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S:
+	include fficonfig.h
+
+2003-10-20  Rainer Orth  <[email protected]>
+
+	* src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external
+	_MIPS_SIM_NABI32, _MIPS_SIM_ABI32.
+
+2003-10-19  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again.
+	Used when FFI_DEBUG = 1.
+
+2003-10-14  Alan Modra  <[email protected]>
+
+	* src/types.c (double, longdouble): Default POWERPC64 to 8 byte size
+	and align.
+
+2003-10-06  Rainer Orth  <[email protected]>
+
+	* include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs,
+	FFI_MIPS_O32 for O32 ABI.
+
+2003-10-01  Andreas Tobler  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for
+	SPARC64. Cleanup whitespaces.
+
+2003-09-19  Andreas Tobler  <[email protected]>
+
+	* testsuite/libffi.call/closure_fn0.c: Xfail mips, arm,
+	strongarm, xscale. Cleanup whitespaces.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+	* testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces.
+
+2003-09-18  David Edelsohn  <[email protected]>
+
+	* src/powerpc/aix.S: Cleanup whitespaces.
+	* src/powerpc/aix_closure.S: Likewise.
+
+2003-09-18  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/darwin.S: Cleanup whitespaces, comment formatting.
+	* src/powerpc/darwin_closure.S: Likewise.
+	* src/powerpc/ffi_darwin.c: Likewise.
+
+2003-09-18  Andreas Tobler  <[email protected]>
+	    David Edelsohn  <[email protected]>
+
+	* src/types.c (double): Add AIX and Darwin to the right TYPEDEF.
+	* src/powerpc/aix_closure.S: Remove the pointer to the outgoing
+	parameter stack.
+	* src/powerpc/darwin_closure.S: Likewise.
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures
+	according to the Darwin/AIX ABI.
+	(ffi_prep_cif_machdep): Likewise.
+	(ffi_closure_helper_DARWIN): Likewise.
+	Remove the outgoing parameter stack logic. Simplify the evaluation
+	of the different CASE types.
+	(ffi_prep_clousure): Avoid the casts on lvalues. Change the branch
+	statement in the trampoline code.
+
+2003-09-18  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (ffi_prep_args): Take account into the alignement
+	for the register size.
+	(ffi_closure_helper_SYSV): Handle the structure return value
+	address correctly.
+	(ffi_closure_helper_SYSV): Return the appropriate type when
+	the registers are used for the structure return value.
+	* src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for
+	the 64-bit return value.  Update copyright years.
+
+2003-09-17  Rainer Orth  <[email protected]>
+
+	* testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in
+	srcdir for ffi_mips.h.
+
+2003-09-12  Alan Modra  <[email protected]>
+
+	* src/prep_cif.c (initialize_aggregate): Include tail padding in
+	structure size.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct
+	placement of float result.
+	* testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct
+	cast of "resp" for big-endian 64 bit machines.
+
+2003-09-11  Alan Modra  <[email protected]>
+
+	* src/types.c (double, longdouble): Merge identical SH and ARM
+	typedefs, and add POWERPC64.
+	* src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for
+	struct split over gpr and rest.
+	(ffi_prep_cif_machdep): Correct intarg_count for structures.
+	* src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets.
+
+2003-09-09  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct
+	passing correctly.
+
+2003-09-09  Alan Modra  <[email protected]>
+
+	* configure: Regenerate.
+
+2003-09-04  Andreas Tobler  <[email protected]>
+
+	* Makefile.am: Remove build rules for ffitest.
+	* Makefile.in: Rebuilt.
+
+2003-09-04  Andreas Tobler  <[email protected]>
+
+	* src/java_raw_api.c: Include <stdlib.h> to fix compiler warning
+	about implicit declaration of abort().
+
+2003-09-04  Andreas Tobler  <[email protected]>
+
+	* Makefile.am: Add dejagnu test framework. Fixes PR other/11411.
+	* Makefile.in: Rebuilt.
+	* configure.in: Add dejagnu test framework.
+	* configure: Rebuilt.
+
+	* testsuite/Makefile.am: New file.
+	* testsuite/Makefile.in: Built
+	* testsuite/lib/libffi-dg.exp: New file.
+	* testsuite/config/default.exp: Likewise.
+	* testsuite/libffi.call/call.exp: Likewise.
+	* testsuite/libffi.call/ffitest.h: Likewise.
+	* testsuite/libffi.call/closure_fn0.c: Likewise.
+	* testsuite/libffi.call/closure_fn1.c: Likewise.
+	* testsuite/libffi.call/closure_fn2.c: Likewise.
+	* testsuite/libffi.call/closure_fn3.c: Likewise.
+	* testsuite/libffi.call/cls_1_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_3_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_4_1byte.c: Likewise.
+	* testsuite/libffi.call/cls_2byte.c: Likewise.
+	* testsuite/libffi.call/cls_3byte1.c: Likewise.
+	* testsuite/libffi.call/cls_3byte2.c: Likewise.
+	* testsuite/libffi.call/cls_4byte.c: Likewise.
+	* testsuite/libffi.call/cls_5byte.c: Likewise.
+	* testsuite/libffi.call/cls_6byte.c: Likewise.
+	* testsuite/libffi.call/cls_7byte.c: Likewise.
+	* testsuite/libffi.call/cls_8byte.c: Likewise.
+	* testsuite/libffi.call/cls_12byte.c: Likewise.
+	* testsuite/libffi.call/cls_16byte.c: Likewise.
+	* testsuite/libffi.call/cls_20byte.c: Likewise.
+	* testsuite/libffi.call/cls_24byte.c: Likewise.
+	* testsuite/libffi.call/cls_double.c: Likewise.
+	* testsuite/libffi.call/cls_float.c: Likewise.
+	* testsuite/libffi.call/cls_uchar.c: Likewise.
+	* testsuite/libffi.call/cls_uint.c: Likewise.
+	* testsuite/libffi.call/cls_ulonglong.c: Likewise.
+	* testsuite/libffi.call/cls_ushort.c: Likewise.
+	* testsuite/libffi.call/float.c: Likewise.
+	* testsuite/libffi.call/float1.c: Likewise.
+	* testsuite/libffi.call/float2.c: Likewise.
+	* testsuite/libffi.call/many.c: Likewise.
+	* testsuite/libffi.call/many_win32.c: Likewise.
+	* testsuite/libffi.call/nested_struct.c: Likewise.
+	* testsuite/libffi.call/nested_struct1.c: Likewise.
+	* testsuite/libffi.call/pyobjc-tc.c: Likewise.
+	* testsuite/libffi.call/problem1.c: Likewise.
+	* testsuite/libffi.call/promotion.c: Likewise.
+	* testsuite/libffi.call/return_ll.c: Likewise.
+	* testsuite/libffi.call/return_sc.c: Likewise.
+	* testsuite/libffi.call/return_uc.c: Likewise.
+	* testsuite/libffi.call/strlen.c: Likewise.
+	* testsuite/libffi.call/strlen_win32.c: Likewise.
+	* testsuite/libffi.call/struct1.c: Likewise.
+	* testsuite/libffi.call/struct2.c: Likewise.
+	* testsuite/libffi.call/struct3.c: Likewise.
+	* testsuite/libffi.call/struct4.c: Likewise.
+	* testsuite/libffi.call/struct5.c: Likewise.
+	* testsuite/libffi.call/struct6.c: Likewise.
+	* testsuite/libffi.call/struct7.c: Likewise.
+	* testsuite/libffi.call/struct8.c: Likewise.
+	* testsuite/libffi.call/struct9.c: Likewise.
+	* testsuite/libffi.special/special.exp: New file.
+	* testsuite/libffi.special/ffitestcxx.h: Likewise.
+	* testsuite/libffi.special/unwindtest.cc: Likewise.
+
+
+2003-08-13  Kaz Kojima  <[email protected]>
+
+	* src/sh/ffi.c (OFS_INT16): Set 0 for little endian case.  Update
+	copyright years.
+
+2003-08-02  Alan Modra  <[email protected]>
+
+	* src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc
+	structure passing.
+	(ffi_closure_helper_LINUX64): Likewise.
+	* src/powerpc/linux64.S: Remove code writing to parm save area.
+	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return
+	address in lr from ffi_closure_helper_LINUX64 call to calculate
+	table address.  Optimize function tail.
+
+2003-07-28  Andreas Tobler  <[email protected]>
+
+	* src/sparc/ffi.c: Handle all floating point registers.
+	* src/sparc/v9.S: Likewise. Fixes second part of PR target/11410.
+
+2003-07-11  Gerald Pfeifer  <[email protected]>
+
+	* README: Note that libffi is not part of GCC.  Update the project
+	URL and status.
+
+2003-06-19  Franz Sirl  <[email protected]>
+
+	* src/powerpc/ppc_closure.S: Include ffi.h.
+
+2003-06-13  Rainer Orth  <[email protected]>
+
+	* src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives.
+	Use C style comments.
+
+2003-06-13  Kaz Kojima  <[email protected]>
+
+	* Makefile.am: Add SHmedia support.  Fix a typo of SH support.
+	* Makefile.in: Regenerate.
+	* configure.in (sh64-*-linux*, sh5*-*-linux*): Add target.
+	* configure: Regenerate.
+	* include/ffi.h.in: Add SHmedia support.
+	* src/sh64/ffi.c: New file.
+	* src/sh64/sysv.S: New file.
+
+2003-05-16  Jakub Jelinek  <[email protected]>
+
+	* configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section
+	should be read-only.
+	* configure: Rebuilt.
+	* fficonfig.h.in: Rebuilt.
+	* include/ffi.h.in (EH_FRAME_FLAGS): Define.
+	* src/alpha/osf.S: Use EH_FRAME_FLAGS.
+	* src/powerpc/linux64.S: Likewise.
+	* src/powerpc/linux64_closure.S: Likewise.  Include ffi.h.
+	* src/powerpc/sysv.S: Use EH_FRAME_FLAGS.  Use pcrel encoding
+	if -fpic/-fPIC/-mrelocatable.
+	* src/powerpc/powerpc_closure.S: Likewise.
+	* src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include
+	#write in .eh_frame flags.
+	* src/sparc/v9.S: Likewise.
+	* src/x86/unix64.S: Use EH_FRAME_FLAGS.
+	* src/x86/sysv.S: Likewise.  Use pcrel encoding if -fpic/-fPIC.
+	* src/s390/sysv.S: Use EH_FRAME_FLAGS.  Include ffi.h.
+
+2003-05-07  Jeff Sturm  <[email protected]>
+
+	Fixes PR bootstrap/10656
+	* configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler
+	support for .register pseudo-op.
+	* src/sparc/v8.S: Use it.
+	* fficonfig.h.in: Rebuilt.
+	* configure: Rebuilt.
+
+2003-04-18  Jakub Jelinek  <[email protected]>
+
+	* include/ffi.h.in (POWERPC64): Define if 64-bit.
+	(enum ffi_abi): Add FFI_LINUX64 on POWERPC.
+	Make it the default on POWERPC64.
+	(FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64.
+	* configure.in: Change powerpc-*-linux* into powerpc*-*-linux*.
+	* configure: Rebuilt.
+	* src/powerpc/ffi.c (hidden): Define.
+	(ffi_prep_args_SYSV): Renamed from
+	ffi_prep_args.  Cast pointers to unsigned long to shut up warnings.
+	(NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64,
+	ASM_NEEDS_REGISTERS64): New.
+	(ffi_prep_args64): New function.
+	(ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI.
+	(ffi_call): Likewise.
+	(ffi_prep_closure): Likewise.
+	(flush_icache): Surround by #ifndef POWERPC64.
+	(ffi_dblfl): New union type.
+	(ffi_closure_helper_SYSV): Use it to avoid aliasing problems.
+	(ffi_closure_helper_LINUX64): New function.
+	* src/powerpc/ppc_closure.S: Surround whole file by #ifndef
+	__powerpc64__.
+	* src/powerpc/sysv.S: Likewise.
+	(ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV.
+	* src/powerpc/linux64.S: New file.
+	* src/powerpc/linux64_closure.S: New file.
+	* Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and
+	src/powerpc/linux64_closure.S.
+	(TARGET_SRC_POWERPC): Likewise.
+
+	* src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2,
+	closure_test_fn3): Fix result printing on big-endian 64-bit
+	machines.
+	(main): Print tst2_arg instead of uninitialized tst2_result.
+
+	* src/ffitest.c (main): Hide what closure pointer really points to
+	from the compiler.
+
+2003-04-16  Richard Earnshaw  <[email protected]>
+
+	* configure.in (arm-*-netbsdelf*): Add configuration.
+	(configure): Regenerated.
+
+2003-04-04  Loren J. Rittle  <[email protected]>
+
+	* include/Makefile.in: Regenerate.
+
+2003-03-21  Zdenek Dvorak  <[email protected]>
+
+	* libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32
+	bit mode.
+	* libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV):
+	Receive closure pointer through parameter, read args using
+	__builtin_dwarf_cfa.
+	(FFI_INIT_TRAMPOLINE): Send closure reference through eax.
+
+2003-03-12  Andreas Schwab  <[email protected]>
+
+	* configure.in: Avoid trailing /. in toolexeclibdir.
+	* configure: Rebuilt.
+
+2003-03-03  Andreas Tobler <[email protected]>
+
+	* src/powerpc/darwin_closure.S: Recode to fit dynamic libraries.
+
+2003-02-06  Andreas Tobler <[email protected]>
+
+	* libffi/src/powerpc/darwin_closure.S:
+	Fix alignement bug, allocate 8 bytes for the result.
+	* libffi/src/powerpc/aix_closure.S:
+	Likewise.
+	* libffi/src/powerpc/ffi_darwin.c:
+	Update stackframe description for aix/darwin_closure.S.
+
+2003-02-06  Jakub Jelinek  <[email protected]>
+
+	* src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility
+	attribute.
+
+2003-01-31  Christian Cornelssen  <[email protected]>,
+	    Andreas Schwab  <[email protected]>
+
+	* configure.in: Adjust command to source config-ml.in to account
+	for changes to the libffi_basedir definition.
+	(libffi_basedir): Remove ${srcdir} from value and include trailing
+	slash if nonempty.
+
+	* configure: Regenerate.
+
+2003-01-29  Franz Sirl  <[email protected]>
+
+	* src/powerpc/ppc_closure.S: Recode to fit shared libs.
+
+2003-01-28  Andrew Haley  <[email protected]>
+
+	* include/ffi.h.in: Enable FFI_CLOSURES for x86_64.
+	* src/x86/ffi64.c (ffi_prep_closure): New.
+	(ffi_closure_UNIX64_inner): New.
+	* src/x86/unix64.S (ffi_closure_UNIX64): New.
+
+2003-01-27  Alexandre Oliva  <[email protected]>
+
+	* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
+	Remove USE_LIBDIR conditional.
+	* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
+	* Makefile.in, configure: Rebuilt.
+
+2003-01027  David Edelsohn  <[email protected]>
+
+	* Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo.
+	* Makefile.in: Regenerate.
+
+2003-01-22  Andrew Haley  <[email protected]>
+
+	* src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to
+	unwind info.
+
+2003-01-21  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/darwin.S: Add unwind info.
+	* src/powerpc/darwin_closure.S: Likewise.
+
+2003-01-14  Andrew Haley  <[email protected]>
+
+	* src/x86/ffi64.c (ffi_prep_args): Check for void retval.
+	(ffi_prep_cif_machdep): Likewise.
+	* src/x86/unix64.S: Add unwind info.
+
+2003-01-14  Andreas Jaeger  <[email protected]>
+
+	* src/ffitest.c (main): Only use ffi_closures if those are
+	supported.
+
+2003-01-13 Andreas Tobler <[email protected]>
+
+	* libffi/src/ffitest.c
+	 add closure testcases
+
+2003-01-13 Kevin B. Hendricks <[email protected]>
+
+	* libffi/src/powerpc/ffi.c
+	 fix alignment bug for float (4 byte aligned iso 8 byte)
+
+2003-01-09  Geoffrey Keating  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c: Remove RCS version string.
+	* src/powerpc/darwin.S: Remove RCS version string.
+
+2003-01-03  Jeff Sturm  <[email protected]>
+
+	* include/ffi.h.in: Add closure defines for SPARC, SPARC64.
+	* src/ffitest.c (main): Use static storage for closure.
+	* src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New.
+	* src/sparc/v8.S (ffi_closure_v8): New.
+	* src/sparc/v9.S (ffi_closure_v9): New.
+
+2002-11-10  Ranjit Mathew <[email protected]>
+
+	* include/ffi.h.in: Added FFI_STDCALL ffi_type
+	  enumeration for X86_WIN32.
+	* src/x86/win32.S: Added ffi_call_STDCALL function
+	  definition.
+	* src/x86/ffi.c (ffi_call/ffi_raw_call): Added
+	  switch cases for recognising FFI_STDCALL and
+	  calling ffi_call_STDCALL if target is X86_WIN32.
+	* src/ffitest.c (my_stdcall_strlen/stdcall_many):
+	  stdcall versions of the "my_strlen" and "many"
+	  test functions (for X86_WIN32).
+	  Added test cases to test stdcall invocation using
+	  these functions.
+
+2002-12-02  Kaz Kojima  <[email protected]>
+
+	* src/sh/sysv.S: Add DWARF2 unwind info.
+
+2002-11-27  Ulrich Weigand  <[email protected]>
+
+	* src/s390/sysv.S (.eh_frame section): Make section read-only.
+
+2002-11-26  Jim Wilson  <[email protected]>
+
+	* src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64.
+
+2002-11-23  H.J. Lu <[email protected]>
+
+	* acinclude.m4: Add dummy AM_PROG_LIBTOOL.
+	Include ../config/accross.m4.
+	* aclocal.m4; Rebuild.
+	* configure: Likewise.
+
+2002-11-15  Ulrich Weigand  <[email protected]>
+
+	* src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding.
+
+2002-11-11  DJ Delorie  <[email protected]>
+
+	* configure.in: Look for common files in the right place.
+
+2002-10-08  Ulrich Weigand  <[email protected]>
+
+	* src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret
+	raw data as _Jv_word values, not ffi_raw.
+	(ffi_java_ptrarray_to_raw): Likewise.
+	(ffi_java_rvalue_to_raw): New function.
+	(ffi_java_raw_call): Call it.
+	(ffi_java_raw_to_rvalue): New function.
+	(ffi_java_translate_args): Call it.
+	* src/ffitest.c (closure_test_fn): Interpret return value
+	as ffi_arg, not int.
+	* src/s390/ffi.c (ffi_prep_cif_machdep): Add missing
+	FFI_TYPE_POINTER case.
+	(ffi_closure_helper_SYSV): Likewise.  Also, assume return
+	values extended to word size.
+
+2002-10-02  Andreas Jaeger  <[email protected]>
+
+	* src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output.
+
+2002-10-01  Bo Thorsen  <[email protected]>
+
+	* include/ffi.h.in: Fix i386 win32 compilation.
+
+2002-09-30  Ulrich Weigand  <[email protected]>
+
+	* configure.in: Add s390x-*-linux-* target.
+	* configure: Regenerate.
+	* include/ffi.h.in: Define S390X for s390x targets.
+	(FFI_CLOSURES): Define for s390/s390x.
+	(FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_NATIVE_RAW_API): Likewise.
+	* src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390.
+	* src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x.
+	* src/s390/ffi.c: Major rework of existing code.  Add support for
+	s390x targets.  Add closure support.
+	* src/s390/sysv.S: Likewise.
+
+2002-09-29  Richard Earnshaw  <[email protected]>
+
+	* src/arm/sysv.S: Fix typo.
+
+2002-09-28  Richard Earnshaw  <[email protected]>
+
+	* src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor
+	has defined __USER_LABEL_PREFIX__, then use it in CNAME.
+	(ffi_call_SYSV): Handle soft-float.
+
+2002-09-27  Bo Thorsen  <[email protected]>
+
+	* include/ffi.h.in: Fix multilib x86-64 support.
+
+2002-09-22  Kaveh R. Ghazi  <[email protected]>
+
+	* Makefile.am (all-multi): Fix multilib parallel build.
+
+2002-07-19  Kaz Kojima  <[email protected]>
+
+	* configure.in (sh[34]*-*-linux*): Add brackets.
+	* configure: Regenerate.
+
+2002-07-18  Kaz Kojima  <[email protected]>
+
+	* Makefile.am: Add SH support.
+	* Makefile.in: Regenerate.
+	* configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target.
+	* configure: Regenerate.
+	* include/ffi.h.in: Add SH support.
+	* src/sh/ffi.c: New file.
+	* src/sh/sysv.S: New file.
+	* src/types.c: Add SH support.
+
+2002-07-16  Bo Thorsen  <[email protected]>
+
+	* src/x86/ffi64.c: New file that adds x86-64 support.
+	* src/x86/unix64.S: New file that handles argument setup for
+	x86-64.
+	* src/x86/sysv.S: Don't use this on x86-64.
+	* src/x86/ffi.c: Don't use this on x86-64.
+	Remove unused vars.
+	* src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
+	for x86-64.
+	* src/ffitest.c (struct6): New test that tests a special case in
+	the x86-64 ABI.
+	(struct7): Likewise.
+	(struct8): Likewise.
+	(struct9): Likewise.
+	(closure_test_fn): Silence warning about this when it's not used.
+	(main): Add the new tests.
+	(main): Fix a couple of wrong casts and silence some compiler warnings.
+	* include/ffi.h.in: Add x86-64 ABI definition.
+	* fficonfig.h.in: Regenerate.
+	* Makefile.am: Add x86-64 support.
+	* configure.in: Likewise.
+	* Makefile.in: Regenerate.
+	* configure: Likewise.
+
+2002-06-24  Bo Thorsen  <[email protected]>
+
+	* src/types.c: Merge settings for similar architectures.
+	Add x86-64 sizes and alignments.
+
+2002-06-23  Bo Thorsen  <[email protected]>
+
+	* src/arm/ffi.c (ffi_prep_args): Remove unused vars.
+	* src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
+	* src/mips/ffi.c (ffi_prep_args): Likewise.
+	* src/m68k/ffi.c (ffi_prep_args): Likewise.
+
+2002-07-18  H.J. Lu  ([email protected])
+
+	* Makefile.am (TARGET_SRC_MIPS_LINUX): New.
+	(libffi_la_SOURCES): Support MIPS_LINUX.
+	(libffi_convenience_la_SOURCES): Likewise.
+	* Makefile.in: Regenerated.
+
+	* configure.in (mips64*-*): Skip.
+	(mips*-*-linux*): New.
+	* configure: Regenerated.
+
+	* src/mips/ffi.c: Include <sgidefs.h>.
+
+2002-06-06  Ulrich Weigand  <[email protected]>
+
+	* src/s390/sysv.S: Save/restore %r6.  Add DWARF-2 unwind info.
+
+2002-05-27  Roger Sayle  <[email protected]>
+
+	* src/x86/ffi.c (ffi_prep_args): Remove reference to avn.
+
+2002-05-27  Bo Thorsen  <[email protected]>
+
+	* src/x86/ffi.c (ffi_prep_args): Remove unused variable and
+	fix formatting.
+
+2002-05-13  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at
+	beginning of function (for older apple cc).
+
+2002-05-08  Alexandre Oliva  <[email protected]>
+
+	* configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at
+	script entry, and set LD to it when configuring multilibs.
+	* configure: Rebuilt.
+
+2002-05-05  Jason Thorpe  <[email protected]>
+
+	* configure.in (sparc64-*-netbsd*): Add target.
+	(sparc-*-netbsdelf*): Likewise.
+	* configure: Regenerate.
+
+2002-04-28  David S. Miller  <[email protected]>
+
+	* configure.in, configure: Fix SPARC test in previous change.
+
+2002-04-29  Gerhard Tonn  <[email protected]>
+
+	* Makefile.am: Add Linux for S/390 support.
+	* Makefile.in: Regenerate.
+	* configure.in: Add Linux for S/390 support.
+	* configure: Regenerate.
+	* include/ffi.h.in: Add Linux for S/390 support.
+	* src/s390/ffi.c: New file from libffi CVS tree.
+	* src/s390/sysv.S: New file from libffi CVS tree.
+
+2002-04-28  Jakub Jelinek  <[email protected]>
+
+	* configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working
+	%r_disp32().
+	* src/sparc/v8.S: Use it.
+	* src/sparc/v9.S: Likewise.
+	* fficonfig.h.in: Rebuilt.
+	* configure: Rebuilt.
+
+2002-04-08  Hans Boehm  <[email protected]>
+
+	* src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE
+	correctly.
+	* src/ia64/unix.S: Add unwind information. Fix comments.
+	Save sp in a way that's compatible with unwind info.
+	(ffi_call_unix): Correctly restore sp in all cases.
+	* src/ia64/ffi.c: Add, fix comments.
+
+2002-04-08  Jakub Jelinek  <[email protected]>
+
+	* src/sparc/v8.S: Make .eh_frame dependent on target word size.
+
+2002-04-06  Jason Thorpe  <[email protected]>
+
+	* configure.in (alpha*-*-netbsd*): Add target.
+	* configure: Regenerate.
+
+2002-04-04  Jeff Sturm  <[email protected]>
+
+	* src/sparc/v8.S: Add unwind info.
+	* src/sparc/v9.S: Likewise.
+
+2002-03-30  Krister Walfridsson  <[email protected]>
+
+	* configure.in: Enable i*86-*-netbsdelf*.
+	* configure: Rebuilt.
+
+2002-03-29  David Billinghurst <[email protected]>
+
+	PR other/2620
+	* src/mips/n32.s: Delete
+	* src/mips/o32.s: Delete
+
+2002-03-21  Loren J. Rittle  <[email protected]>
+
+	* configure.in: Enable alpha*-*-freebsd*.
+	* configure: Rebuilt.
+
+2002-03-17  Bryce McKinlay  <[email protected]>
+
+	* Makefile.am: libfficonvenience -> libffi_convenience.
+	* Makefile.in: Rebuilt.
+
+	* Makefile.am: Define ffitest_OBJECTS.
+	* Makefile.in: Rebuilt.
+
+2002-03-07  Andreas Tobler  <[email protected]>
+	    David Edelsohn  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
+	(TARGET_SRC_POWERPC_AIX): Add aix_closure.S.
+	(TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S.
+	* Makefile.in: Regenerate.
+	* include/ffi.h.in: Add AIX and Darwin closure definitions.
+	* src/powerpc/ffi_darwin.c (ffi_prep_closure): New function.
+	(flush_icache, flush_range): New functions.
+	(ffi_closure_helper_DARWIN): New function.
+	* src/powerpc/aix_closure.S: New file.
+	* src/powerpc/darwin_closure.S: New file.
+
+2002-02-24  Jeff Sturm  <[email protected]>
+
+	* include/ffi.h.in: Add typedef for ffi_arg.
+	* src/ffitest.c (main): Declare rint with ffi_arg.
+
+2002-02-21  Andreas Tobler  <[email protected]>
+
+	* src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate
+	number of GPRs for floating-point arguments.
+
+2002-01-31  Anthony Green  <[email protected]>
+
+	* configure: Rebuilt.
+	* configure.in: Replace CHECK_SIZEOF and endian tests with
+	cross-compiler friendly macros.
+	* aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New
+	macros.
+
+2002-01-18  David Edelsohn  <[email protected]>
+
+	* src/powerpc/darwin.S (_ffi_call_AIX): New.
+	* src/powerpc/aix.S (ffi_call_DARWIN): New.
+
+2002-01-17  David Edelsohn  <[email protected]>
+
+	* Makefile.am (EXTRA_DIST): Add Darwin and AIX files.
+	(TARGET_SRC_POWERPC_AIX): New.
+	(POWERPC_AIX): New stanza.
+	* Makefile.in: Regenerate.
+	* configure.in: Add AIX case.
+	* configure: Regenerate.
+	* include/ffi.h.in (ffi_abi): Add FFI_AIX.
+	* src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame
+	size.  Fix "long double" support.
+	(ffi_call): Add FFI_AIX case.
+	* src/powerpc/aix.S: New.
+
+2001-10-09  John Hornkvist  <[email protected]>
+
+	Implement Darwin PowerPC ABI.
+	* configure.in: Handle powerpc-*-darwin*.
+	* Makefile.am: Set source files for POWERPC_DARWIN.
+	* configure: Rebuilt.
+	* Makefile.in: Rebuilt.
+	* include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for
+	POWERPC_DARWIN.
+	* src/powerpc/darwin.S: New file.
+	* src/powerpc/ffi_darwin.c: New file.
+
+2001-10-07  Joseph S. Myers  <[email protected]>
+
+	* src/x86/ffi.c: Fix spelling error of "separate" as "seperate".
+
+2001-07-16  Rainer Orth  <[email protected]>
+
+	* src/x86/sysv.S: Avoid gas-only .balign directive.
+	Use C style comments.
+
+2001-07-16  Rainer Orth  <[email protected]>
+
+	* src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic.
+	Fixes PR bootstrap/3563.
+
+2001-06-26  Rainer Orth  <[email protected]>
+
+	* src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF.
+
+2001-06-25  Rainer Orth  <[email protected]>
+
+	* configure.in: Recognize sparc*-sun-* host.
+	* configure: Regenerate.
+
+2001-06-06  Andrew Haley  <[email protected]>
+
+	* src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF.
+
+2001-06-03  Andrew Haley  <[email protected]>
+
+	* src/alpha/osf.S: Add unwind info.
+	* src/powerpc/sysv.S: Add unwind info.
+	* src/powerpc/ppc_closure.S: Likewise.
+
+2000-05-31  Jeff Sturm  <[email protected]>
+
+	* configure.in: Fix AC_ARG_ENABLE usage.
+	* configure: Rebuilt.
+
+2001-05-06  Bryce McKinlay  <[email protected]>
+
+	* configure.in: Remove warning about beta code.
+	* configure: Rebuilt.
+
+2001-04-25  Hans Boehm <[email protected]>
+
+	* src/ia64/unix.S: Restore stack pointer when returning from
+	ffi_closure_UNIX.
+	* src/ia64/ffi.c: Fix typo in comment.
+
+2001-04-18  Jim Wilson  <[email protected]>
+
+	* src/ia64/unix.S: Delete unnecessary increment and decrement of loc2
+	to eliminate RAW DV.
+
+2001-04-12  Bryce McKinlay  <[email protected]>
+
+	* Makefile.am: Make a libtool convenience library.
+	* Makefile.in: Rebuilt.
+
+2001-03-29  Bryce McKinlay  <[email protected]>
+
+	* configure.in: Use different syntax for subdirectory creation.
+	* configure: Rebuilt.
+
+2001-03-27  Jon Beniston  <[email protected]>
+
+	* configure.in: Added X86_WIN32 target (Win32, CygWin, MingW).
+	* configure: Rebuilt.
+	* Makefile.am: Added X86_WIN32 target support.
+	* Makefile.in: Rebuilt.
+
+	* include/ffi.h.in: Added X86_WIN32 target support.
+
+	* src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets.
+	* src/types.c: Added X86_WIN32 target support.
+
+	* src/x86/win32.S: New file. Based on sysv.S, but with EH
+	stuff removed and made to work with CygWin's gas.
+
+2001-03-26  Bryce McKinlay  <[email protected]>
+
+	* configure.in: Make target subdirectory in build dir.
+	* Makefile.am: Override suffix based rules to specify correct output
+	subdirectory.
+	* Makefile.in: Rebuilt.
+	* configure: Rebuilt.
+
+2001-03-23  Kevin B Hendricks  <[email protected]>
+
+	* src/powerpc/ppc_closure.S: New file.
+	* src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug
+	involving long long and register pairs.
+	(ffi_prep_closure): New function.
+	(flush_icache): Likewise.
+	(ffi_closure_helper_SYSV): Likewise.
+	* include/ffi.h.in (FFI_CLOSURES): Define on PPC.
+	(FFI_TRAMPOLINE_SIZE): Likewise.
+	(FFI_NATIVE_RAW_API): Likewise.
+	* Makefile.in: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S.
+	(TARGET_SRC_POWERPC): Likewise.
+
+2001-03-19  Tom Tromey  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (ffitest_LDFLAGS): New macro.
+
+2001-03-02  Nick Clifton  <[email protected]>
+
+	* include/ffi.h.in: Remove RCS ident string.
+	* include/ffi_mips.h: Remove RCS ident string.
+	* src/debug.c: Remove RCS ident string.
+	* src/ffitest.c: Remove RCS ident string.
+	* src/prep_cif.c: Remove RCS ident string.
+	* src/types.c: Remove RCS ident string.
+	* src/alpha/ffi.c: Remove RCS ident string.
+	* src/alpha/osf.S: Remove RCS ident string.
+	* src/arm/ffi.c: Remove RCS ident string.
+	* src/arm/sysv.S: Remove RCS ident string.
+	* src/mips/ffi.c: Remove RCS ident string.
+	* src/mips/n32.S: Remove RCS ident string.
+	* src/mips/o32.S: Remove RCS ident string.
+	* src/sparc/ffi.c: Remove RCS ident string.
+	* src/sparc/v8.S: Remove RCS ident string.
+	* src/sparc/v9.S: Remove RCS ident string.
+	* src/x86/ffi.c: Remove RCS ident string.
+	* src/x86/sysv.S: Remove RCS ident string.
+
+2001-02-08  Joseph S. Myers  <[email protected]>
+
+	* include/ffi.h.in: Change sourceware.cygnus.com references to
+	gcc.gnu.org.
+
+2000-12-09  Richard Henderson  <[email protected]>
+
+	* src/alpha/ffi.c (ffi_call): Simplify struct return test.
+	(ffi_closure_osf_inner): Index rather than increment avalue
+	and arg_types.  Give ffi_closure_osf the raw return value type.
+	* src/alpha/osf.S (ffi_closure_osf): Handle return value type
+	promotion.
+
+2000-12-07  Richard Henderson  <[email protected]>
+
+	* src/raw_api.c (ffi_translate_args): Fix typo.
+	(ffi_prep_closure): Likewise.
+
+	* include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and
+	FFI_TRAMPOLINE_SIZE.
+	* src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal
+	cif->bytes for new ffi_call_osf implementation.
+	(ffi_prep_args): Absorb into ...
+	(ffi_call): ... here.  Do all stack allocation here and
+	avoid a callback function.
+	(ffi_prep_closure, ffi_closure_osf_inner): New.
+	* src/alpha/osf.S (ffi_call_osf): Reimplement with no callback.
+	(ffi_closure_osf): New.
+
+2000-09-10  Alexandre Oliva  <[email protected]>
+
+	* config.guess, config.sub, install-sh: Removed.
+	* ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise.
+	* Makefile.in: Rebuilt.
+
+	* acinclude.m4: Include libtool macros from the top level.
+	* aclocal.m4, configure: Rebuilt.
+
+2000-08-22  Alexandre Oliva  <[email protected]>
+
+	* configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set.
+	* configure: Rebuilt.
+
+2000-05-11  Scott Bambrough  <[email protected]>
+
+	* libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to
+	memory correctly.  Use conditional instructions, not branches where
+	possible.
+
+2000-05-04  Tom Tromey  <[email protected]>
+
+	* configure: Rebuilt.
+	* configure.in: Match `arm*-*-linux-*'.
+	From Chris Dornan <[email protected]>.
+
+2000-04-28  Jakub Jelinek  <[email protected]>
+
+	* Makefile.am (SUBDIRS): Define.
+	(AM_MAKEFLAGS): Likewise.
+	(Multilib support.): Add section.
+	* Makefile.in: Rebuilt.
+	* ltconfig (extra_compiler_flags, extra_compiler_flags_value):
+	New variables. Set for gcc using -print-multi-lib. Export them
+	to libtool.
+	(sparc64-*-linux-gnu*): Use libsuff 64 for search paths.
+	* ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options
+	for -shared links.
+	(extra_compiler_flags_value, extra_compiler_flags): Check these
+	for extra compiler options which need to be passed down in
+	compiler_flags.
+
+2000-04-16  Anthony Green  <[email protected]>
+
+	* configure: Rebuilt.
+	* configure.in: Change i*86-pc-linux* to i*86-*-linux*.
+
+2000-04-14  Jakub Jelinek  <[email protected]>
+
+	* include/ffi.h.in (SPARC64): Define for 64bit SPARC builds.
+	Set SPARC FFI_DEFAULT_ABI based on SPARC64 define.
+	* src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args.
+	Replace all void * sizeofs with sizeof(int).
+	Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is
+	different than DOUBLE.
+	Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere).
+	(ffi_prep_args_v9): New function.
+	(ffi_prep_cif_machdep): Handle V9 ABI and long long on V8.
+	(ffi_V9_return_struct): New function.
+	(ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from
+	32bit code (not yet cross-arch calls).
+	* src/sparc/v8.S: Add struct return delay nop.
+	Handle long long.
+	* src/sparc/v9.S: New file.
+	* src/prep_cif.c (ffi_prep_cif): Return structure pointer
+	is used on sparc64 only for structures larger than 32 bytes.
+	Pass by reference for structures is done for structure arguments
+	larger than 16 bytes.
+	* src/ffitest.c (main): Use 64bit rint on sparc64.
+	Run long long tests on sparc.
+	* src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and
+	sparc64.
+	(FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits
+	on sparc64.
+	* configure.in (sparc-*-linux*): New supported target.
+	(sparc64-*-linux*): Likewise.
+	* configure: Rebuilt.
+	* Makefile.am: Add v9.S to SPARC files.
+	* Makefile.in: Likewise.
+	(LINK): Surround $(CCLD) into double quotes, so that multilib
+	compiles work correctly.
+
+2000-04-04  Alexandre Petit-Bianco  <[email protected]>
+
+	* configure: Rebuilt.
+	* configure.in: (i*86-*-solaris*): New libffi target. Patch
+	proposed by Bryce McKinlay.
+
+2000-03-20  Tom Tromey  <[email protected]>
+
+	* Makefile.in: Hand edit for java_raw_api.lo.
+
+2000-03-08  Bryce McKinlay  <[email protected]>
+
+	* config.guess, config.sub: Update from the gcc tree.
+	Fix for PR libgcj/168.
+
+2000-03-03  Tom Tromey  <[email protected]>
+
+	* Makefile.in: Fixed ia64 by hand.
+
+	* configure: Rebuilt.
+	* configure.in (--enable-multilib): New option.
+	(libffi_basedir): New subst.
+	(AC_OUTPUT): Added multilib code.
+
+2000-03-02  Tom Tromey  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as
+	directory name.
+
+2000-02-25  Hans Boehm <[email protected]>
+
+	* src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New
+	files.
+	* src/raw_api.c (ffi_translate_args): Fixed typo in argument
+	list.
+	(ffi_prep_raw_closure): Use ffi_translate_args, not
+	ffi_closure_translate.
+	* src/java_raw_api.c: New file.
+	* src/ffitest.c (closure_test_fn): New function.
+	(main): Define `rint' as long long on IA64.  Added new test when
+	FFI_CLOSURES is defined.
+	* include/ffi.h.in (ALIGN): Use size_t, not unsigned.
+	(ffi_abi): Recognize IA64.
+	(ffi_raw): Added `flt' field.
+	Added "Java raw API" code.
+	* configure.in: Recognize ia64.
+	* Makefile.am (TARGET_SRC_IA64): New macro.
+	(libffi_la_common_SOURCES): Added java_raw_api.c.
+	(libffi_la_SOURCES): Define in IA64 case.
+
+2000-01-04  Tom Tromey  <[email protected]>
+
+	* Makefile.in: Rebuilt with newer automake.
+
+1999-12-31  Tom Tromey  <[email protected]>
+
+	* Makefile.am (INCLUDES): Added -I$(top_srcdir)/src.
+
+1999-09-01  Tom Tromey  <[email protected]>
+
+	* include/ffi.h.in: Removed PACKAGE and VERSION defines and
+	undefs.
+	* fficonfig.h.in: Rebuilt.
+	* configure: Rebuilt.
+	* configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE.
+	Use AM_PROG_LIBTOOL (automake 1.4 compatibility).
+	* acconfig.h: Don't #undef PACKAGE or VERSION.
+
+1999-08-09  Anthony Green  <[email protected]>
+
+	* include/ffi.h.in: Try to work around messy header problem
+	with PACKAGE and VERSION.
+
+	* configure: Rebuilt.
+	* configure.in: Change version to 2.00-beta.
+
+	* fficonfig.h.in: Rebuilt.
+	* acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define.
+
+	* src/x86/ffi.c (ffi_raw_call): Rename.
+
+1999-08-02  Kresten Krab Thorup  <[email protected]>
+
+	* src/x86/ffi.c (ffi_closure_SYSV): New function.
+	(ffi_prep_incoming_args_SYSV): Ditto.
+	(ffi_prep_closure): Ditto.
+	(ffi_closure_raw_SYSV): Ditto.
+	(ffi_prep_raw_closure): More ditto.
+	(ffi_call_raw): Final ditto.
+
+	* include/ffi.h.in: Add definitions for closure and raw API.
+
+	* src/x86/ffi.c (ffi_prep_cif_machdep): Added case for
+	FFI_TYPE_UINT64.
+
+	* Makefile.am (libffi_la_common_SOURCES): Added raw_api.c
+
+	* src/raw_api.c: New file.
+
+	* include/ffi.h.in (ffi_raw): New type.
+	(UINT_ARG, SINT_ARG): New defines.
+	(ffi_closure, ffi_raw_closure): New types.
+	(ffi_prep_closure, ffi_prep_raw_closure): New declarations.
+
+	* configure.in: Add check for endianness and sizeof void*.
+
+	* src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument,
+	instead of directly.
+
+	* configure: Rebuilt.
+
+Thu Jul  8 14:28:42 1999  Anthony Green  <[email protected]>
+
+	* configure.in: Add x86 and powerpc BeOS configurations.
+	From Makoto Kato <[email protected]>.
+
+1999-05-09  Anthony Green  <[email protected]>
+
+	* configure.in: Add warning about this being beta code.
+	Remove src/Makefile.am from the picture.
+	* configure: Rebuilt.
+
+	* Makefile.am: Move logic from src/Makefile.am.  Add changes
+	to support libffi as a target library.
+	* Makefile.in: Rebuilt.
+
+	* aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh:
+	Upgraded to new autoconf, automake, libtool.
+
+	* README: Tweaks.
+
+	* LICENSE: Update copyright date.
+
+	* src/Makefile.am, src/Makefile.in: Removed.
+
+1998-11-29  Anthony Green  <[email protected]>
+
+	* include/ChangeLog: Removed.
+	* src/ChangeLog: Removed.
+	* src/mips/ChangeLog: Removed.
+	* src/sparc/ChangeLog: Remboved.
+	* src/x86/ChangeLog: Removed.
+
+	* ChangeLog.v1: Created.

+ 40 - 0
libffi.mod/libffi/ChangeLog.libgcj

@@ -0,0 +1,40 @@
+2004-01-14  Kelley Cook  <[email protected]>
+
+	* configure.in: Add in AC_PREREQ(2.13)
+
+2003-02-20  Alexandre Oliva  <[email protected]>
+
+	* configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
+	config.status.
+	* configure: Rebuilt.
+
+2002-01-27  Alexandre Oliva  <[email protected]>
+
+	* configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
+	Remove USE_LIBDIR conditional.
+	* Makefile.am (toolexecdir, toolexeclibdir): Don't override.
+	* Makefile.in, configure: Rebuilt.
+
+Mon Aug  9 18:33:38 1999  Rainer Orth  <[email protected]>
+
+	* include/Makefile.in: Rebuilt.
+	* Makefile.in: Rebuilt
+	* Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native
+	builds.
+	Use USE_LIBDIR.
+
+	* configure: Rebuilt.
+	* configure.in (USE_LIBDIR): Define for native builds.
+	Use lowercase in configure --help explanations.
+
+1999-08-08  Anthony Green  <[email protected]>
+
+	* include/ffi.h.in (FFI_FN): Remove `...'.
+
+1999-08-08  Anthony Green  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (AM_CFLAGS): Compile with -fexceptions.
+
+	* src/x86/sysv.S: Add exception handling metadata.
+

+ 764 - 0
libffi.mod/libffi/ChangeLog.v1

@@ -0,0 +1,764 @@
+The libffi version 1 ChangeLog archive.
+
+Version 1 of libffi had per-directory ChangeLogs.  Current and future
+versions have a single ChangeLog file in the root directory.  The
+version 1 ChangeLogs have all been concatenated into this file for
+future reference only.
+
+--- libffi ----------------------------------------------------------------
+
+Mon Oct  5 02:17:50 1998  Anthony Green  <[email protected]>
+
+	* configure.in: Boosted rev.
+	* configure, Makefile.in, aclocal.m4: Rebuilt.
+	* README: Boosted rev and updated release notes.
+
+Mon Oct  5 01:03:03 1998  Anthony Green  <[email protected]>
+
+	* configure.in: Boosted rev.
+	* configure, Makefile.in, aclocal.m4: Rebuilt.
+	* README: Boosted rev and updated release notes.
+
+1998-07-25  Andreas Schwab  <[email protected]>
+
+	* m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags.
+	Correctly handle small structures.
+	(ffi_prep_args): Also handle small structures.
+	(ffi_call): Pass size of return type to ffi_call_SYSV.
+	* m68k/sysv.S: Adjust for above changes.  Correctly align small
+	structures in the return value.
+
+	* types.c (uint64, sint64) [M68K]: Change alignment to 4.
+
+Fri Apr 17 17:26:58 1998  Anthony Green  <[email protected]>
+
+	* configure.in: Boosted rev.
+	* configure,Makefile.in,aclocal.m4: Rebuilt.
+	* README: Boosted rev and added release notes.
+
+Sun Feb 22 00:50:41 1998  Geoff Keating  <[email protected]>
+
+	* configure.in: Add PowerPC config bits.
+
+1998-02-14  Andreas Schwab  <[email protected]>
+
+	* configure.in: Add m68k config bits.  Change AC_CANONICAL_SYSTEM
+	to AC_CANONICAL_HOST, this is not a compiler.  Use $host instead
+	of $target.  Remove AC_CHECK_SIZEOF(char), we already know the
+	result.  Fix argument of AC_ARG_ENABLE.
+	* configure, fficonfig.h.in: Rebuilt.
+
+Tue Feb 10 20:53:40 1998  Richard Henderson  <[email protected]>
+
+	* configure.in: Add Alpha config bits.
+
+Tue May 13 13:39:20 1997  Anthony Green  <[email protected]>
+
+	* README: Updated dates and reworded Irix comments.
+
+	* configure.in: Removed AC_PROG_RANLIB.
+
+	* Makefile.in, aclocal.m4, config.guess, config.sub, configure,
+	ltmain.sh, */Makefile.in: libtoolized again and	rebuilt with 
+	automake and autoconf.
+	
+Sat May 10 18:44:50 1997  Tom Tromey  <[email protected]>
+
+	* configure, aclocal.m4: Rebuilt.
+	* configure.in: Don't compute EXTRADIST; now handled in
+	src/Makefile.in.  Removed macros implied by AM_INIT_AUTOMAKE.
+	Don't run AM_MAINTAINER_MODE.
+
+Thu May  8 14:34:05 1997  Anthony Green  <[email protected]>
+
+	* missing, ltmain.sh, ltconfig.sh: Created. These are new files
+	required by automake and libtool.
+
+	* README: Boosted rev to 1.14. Added notes.
+
+	* acconfig.h: Moved PACKAGE and VERSION for new automake.
+	
+	* configure.in: Changes for libtool.
+	
+	* Makefile.am (check): make test now make check. Uses libtool now.
+
+	* Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt.
+
+Thu May  1 16:27:07 1997  Anthony Green  <[email protected]>
+
+	* missing: Added file required by new automake.
+
+Tue Nov 26 14:10:42 1996  Anthony Green  <[email protected]>
+
+	* acconfig.h: Added USING_PURIFY flag. This is defined when
+	--enable-purify-safety was used at configure time.
+
+	* configure.in (allsources): Added --enable-purify-safety switch.
+	(VERSION): Boosted rev to 1.13.
+	* configure: Rebuilt.
+
+Fri Nov 22 06:46:12 1996  Anthony Green  <[email protected]>
+
+	* configure.in (VERSION): Boosted rev to 1.12.
+	Removed special CFLAGS hack for gcc.
+	* configure: Rebuilt.
+
+	* README: Boosted rev to 1.12. Added notes.
+
+	* Many files: Cygnus Support changed to Cygnus Solutions.
+
+Wed Oct 30 11:15:25 1996  Anthony Green  <[email protected]>
+
+	* configure.in (VERSION): Boosted rev to 1.11.
+	* configure: Rebuilt.
+
+	* README: Boosted rev to 1.11. Added notes about GNU make.
+
+Tue Oct 29 12:25:12 1996  Anthony Green  <[email protected]>
+
+	* configure.in: Fixed -Wall trick.
+	(VERSION): Boosted rev.
+	* configure: Rebuilt
+
+	* acconfig.h: Needed for --enable-debug configure switch.
+
+	* README: Boosted rev to 1.09. Added more notes on building
+	libffi, and LCLint.
+
+	* configure.in: Added --enable-debug switch. Boosted rev to
+	1.09.
+	* configure: Rebuilt
+
+Tue Oct 15 13:11:28 1996  Anthony Green  <[email protected]>
+
+	* configure.in (VERSION): Boosted rev to 1.08
+	* configure: Rebuilt.
+
+	* README: Added n32 bug fix notes.
+
+	* Makefile.am: Added "make lint" production. 
+	* Makefile.in: Rebuilt.
+
+Mon Oct 14 10:54:46 1996  Anthony Green  <[email protected]>
+
+	* README: Added web page reference.
+
+	* configure.in, README: Boosted rev to 1.05
+	* configure: Rebuilt.
+
+	* README: Fixed n32 sample code.
+
+Fri Oct 11 17:09:28 1996  Anthony Green  <[email protected]>
+
+	* README: Added sparc notes.
+
+	* configure.in, README: Boosted rev to 1.04.
+	* configure: Rebuilt.
+
+Thu Oct 10 10:31:03 1996  Anthony Green  <[email protected]>
+
+	* configure.in, README: Boosted rev to 1.03.
+	* configure: Rebuilt.
+
+	* README: Added struct notes. 
+
+	* Makefile.am (EXTRA_DIST): Added LICENSE to distribution.
+	* Makefile.in: Rebuilt.
+
+	* README: Removed Linux section. No special notes now
+	because aggregates arg/return types work.
+
+Wed Oct  9 16:16:42 1996  Anthony Green  <[email protected]>
+
+	* README, configure.in (VERSION): Boosted rev to 1.02
+	* configure: Rebuilt.
+
+Tue Oct  8 11:56:33 1996  Anthony Green  <[email protected]>
+
+	* README (NOTE): Added n32 notes.
+
+	* Makefile.am: Added test production.
+	* Makefile: Rebuilt
+
+	* README: spell checked!
+
+	* configure.in (VERSION): Boosted rev to 1.01
+	* configure: Rebuilt.
+
+Mon Oct  7 15:50:22 1996  Anthony Green  <[email protected]>
+
+	* configure.in: Added nasty bit to support SGI tools.
+	* configure: Rebuilt.
+	
+	* README: Added SGI notes. Added note about automake bug.
+
+Mon Oct  7 11:00:28 1996  Anthony Green  <[email protected]>
+
+	* README: Rewrote intro, and fixed examples.
+
+Fri Oct  4 10:19:55 1996  Anthony Green  <[email protected]>
+
+	* configure.in: -D$TARGET is no longer used as a compiler switch.
+	It is now inserted into ffi.h at configure time.
+	* configure: Rebuilt.
+
+	* FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status.
+
+Thu Oct  3 13:47:34 1996  Anthony Green  <[email protected]>
+
+	* README, LICENSE: Created. Wrote some docs.
+
+	* configure.in: Don't barf on i586-unknown-linuxaout.
+	Added EXTRADIST code for "make dist".
+	* configure: Rebuilt.
+
+	* */Makefile.in: Rebuilt with patched automake. 
+
+Tue Oct  1 17:12:25 1996  Anthony Green  <[email protected]>
+
+	* Makefile.am, aclocal.m4, config.guess, config.sub,
+	configure.in, fficonfig.h.in, install-sh, mkinstalldirs, 
+	stamp-h.in: Created
+	* Makefile.in, configure: Generated
+
+--- libffi/include --------------------------------------------------------
+
+Tue Feb 24 13:09:36 1998  Anthony Green  <[email protected]>
+
+	* ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on
+	ffi.h.in changes.  This is a work-around for SGI's "simple"
+	assembler.
+
+Sun Feb 22 00:51:55 1998  Geoff Keating  <[email protected]>
+
+	* ffi.h.in: PowerPC support.
+
+1998-02-14  Andreas Schwab  <[email protected]>
+
+	* ffi.h.in: Add m68k support.
+	(FFI_TYPE_LONGDOUBLE): Make it a separate value.
+
+Tue Feb 10 20:55:16 1998  Richard Henderson  <[email protected]>
+
+	* ffi.h.in (SIZEOF_ARG): Use a pointer type by default.
+
+	* ffi.h.in: Alpha support.
+
+Fri Nov 22 06:48:45 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions.
+
+Wed Nov 20 22:31:01 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: Added ffi_type_void definition.
+
+Tue Oct 29 12:22:40 1996  Anthony Green  <[email protected]>
+
+	* Makefile.am (hack_DATA): Always install ffi_mips.h.
+
+	* ffi.h.in: Removed FFI_DEBUG. It's now in the correct
+	place (acconfig.h).
+	Added #include <stddef.h> for size_t definition.
+
+Tue Oct 15 17:23:35 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in, ffi_common.h, ffi_mips.h: More clean up.
+	Commented out #define of FFI_DEBUG.
+
+Tue Oct 15 13:01:06 1996  Anthony Green  <[email protected]>
+
+	* ffi_common.h: Added bool definition.
+
+	* ffi.h.in, ffi_common.h: Clean up based on LCLint output.
+	Added funny /*@...@*/ comments to annotate source.
+
+Mon Oct 14 12:29:23 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: Interface changes based on feedback from Jim
+	Blandy.
+
+Fri Oct 11 16:49:35 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: Small change for sparc support.
+
+Thu Oct 10 14:53:37 1996  Anthony Green  <[email protected]>
+
+	* ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for 
+	special structure return types.
+
+Wed Oct  9 13:55:57 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: Added SIZEOF_ARG definition for X86
+
+Tue Oct  8 11:40:36 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings.
+	Use it to case your function pointers to the proper type.
+
+	* ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug.
+
+	* Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST.
+	* Makefile: Rebuilt.
+
+	* ffi_mips.h: Created. Moved all common mips definitions here.
+
+Mon Oct  7 10:58:12 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: The SGI assember is very picky about parens. Redefined
+ 	some macros to avoid problems.
+
+	* ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added
+	externs for pointer, and 64bit integral ffi_types.
+
+Fri Oct  4 09:51:37 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: Added FFI_ABI member to ffi_cif and changed
+	function prototypes accordingly.
+	Added #define @TARGET@. Now programs including ffi.h don't 
+	have to specify this themselves.
+
+Thu Oct  3 15:36:44 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in: Changed ffi_prep_cif's values from void* to void**
+
+	* Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist"
+	to work.
+	* Makefile.in: Regenerated.
+
+Wed Oct  2 10:16:59 1996  Anthony Green  <[email protected]>
+
+	* Makefile.am: Created
+	* Makefile.in: Generated
+
+	* ffi_common.h: Added rcsid comment
+
+Tue Oct  1 17:13:51 1996  Anthony Green  <[email protected]>
+
+	* ffi.h.in, ffi_common.h: Created
+
+--- libffi/src ------------------------------------------------------------
+
+Mon Oct  5 02:17:50 1998  Anthony Green  <[email protected]>
+
+	* arm/ffi.c, arm/sysv.S: Created.
+
+	* Makefile.am: Added arm files.
+	* Makefile.in: Rebuilt.
+
+Mon Oct  5 01:41:38 1998  Anthony Green  <[email protected]>
+
+	* Makefile.am (libffi_la_LDFLAGS): Incremented revision.
+
+Sun Oct  4 16:27:17 1998  Anthony Green  <[email protected]>
+
+	* alpha/osf.S (ffi_call_osf): Patch for DU assembler.
+
+	* ffitest.c (main): long long and long double return values work
+	for x86.
+
+Fri Apr 17 11:50:58 1998  Anthony Green  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+
+	* ffitest.c (main): Floating point tests not executed for systems
+ 	with broken lond double (SunOS 4 w/ GCC).
+
+	* types.c: Fixed x86 alignment info for long long types.
+
+Thu Apr 16 07:15:28 1998  Anthony Green  <[email protected]>
+
+	* ffitest.c: Added more notes about GCC bugs under Irix 6.
+
+Wed Apr 15 08:42:22 1998  Anthony Green  <[email protected]>
+
+	* ffitest.c (struct5): New test function.
+	(main): New test with struct5.
+
+Thu Mar  5 10:48:11 1998  Anthony Green  <[email protected]>
+
+	* prep_cif.c (initialize_aggregate): Fix assertion for
+	nested structures.
+
+Tue Feb 24 16:33:41 1998  Anthony Green  <[email protected]>
+
+	* prep_cif.c (ffi_prep_cif): Added long double support for sparc.
+
+Sun Feb 22 00:52:18 1998  Geoff Keating  <[email protected]>
+
+	* powerpc/asm.h: New file.
+	* powerpc/ffi.c: New file.
+	* powerpc/sysv.S: New file.
+	* Makefile.am: PowerPC port.
+	* ffitest.c (main): Allow all tests to run even in presence of gcc
+ 	bug on PowerPC.
+
+1998-02-17  Anthony Green  <[email protected]>
+
+	* mips/ffi.c: Fixed comment typo.
+
+	* x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat): 
+	Fixed x86 long double return handling.
+
+	* types.c: Fixed x86 long double alignment info.
+
+1998-02-14  Andreas Schwab  <[email protected]>
+
+	* types.c: Add m68k support.
+
+	* ffitest.c (floating): Add long double parameter.
+	(return_ll, ldblit): New functions to test long long and long
+	double return value.
+	(main): Fix type error in assignment of ts[1-4]_type.elements.
+	Add tests for long long and long double arguments and return
+	values.
+
+	* prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for
+	struct value pointer.
+
+	* m68k/ffi.c, m68k/sysv.S: New files.
+	* Makefile.am: Add bits for m68k port.  Add kludge to work around
+	automake deficiency.
+	(test): Don't require "." in $PATH.
+	* Makefile.in: Rebuilt.
+
+Wed Feb 11 07:36:50 1998  Anthony Green  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+
+Tue Feb 10 20:56:00 1998  Richard Henderson  <[email protected]>
+
+	* alpha/ffi.c, alpha/osf.S: New files.
+	* Makefile.am: Alpha port.
+
+Tue Nov 18 14:12:07 1997  Anthony Green  <[email protected]>
+
+	* mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag
+	for n32.
+
+Tue Jun  3 17:18:20 1997  Anthony Green  <[email protected]>
+
+	* ffitest.c (main): Added hack to get structure tests working
+	correctly.
+
+Sat May 10 19:06:42 1997  Tom Tromey  <[email protected]>
+
+	* Makefile.in: Rebuilt.
+	* Makefile.am (EXTRA_DIST): Explicitly list all distributable
+	files in subdirs.
+	(VERSION, CC): Removed.
+
+Thu May  8 17:19:01 1997  Anthony Green  <[email protected]>
+
+	* Makefile.am: Many changes for new automake and libtool.
+	* Makefile.in: Rebuilt.
+
+Fri Nov 22 06:57:56 1996  Anthony Green  <[email protected]>
+
+	* ffitest.c (main): Fixed test case for non mips machines.
+
+Wed Nov 20 22:31:59 1996  Anthony Green  <[email protected]>
+
+	* types.c: Added ffi_type_void declaration.
+
+Tue Oct 29 13:07:19 1996  Anthony Green  <[email protected]>
+
+	* ffitest.c (main): Fixed character constants.
+	(main): Emit warning for structure test 3 failure on Sun.
+
+	* Makefile.am (VPATH): Fixed VPATH def'n so automake won't
+	strip it out. 
+	Moved distdir hack from libffi to automake. 
+	(ffitest): Added missing -c for $(COMPILE) (change in automake).
+	* Makefile.in: Rebuilt.
+	
+Tue Oct 15 13:08:20 1996  Anthony Green  <[email protected]>
+
+	* Makefile.am: Added "make lint" production. 
+	* Makefile.in: Rebuilt.
+
+	* prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro.
+  	Clean up based on LCLint output. Added funny /*@...@*/ comments to
+ 	annotate source.
+
+	* ffitest.c, debug.c: Cleaned up code.
+
+Mon Oct 14 12:26:56 1996  Anthony Green  <[email protected]>
+
+	* ffitest.c: Changes based on interface changes.
+
+	* prep_cif.c (ffi_prep_cif): Cleaned up interface based on
+	feedback from Jim Blandy.
+
+Fri Oct 11 15:53:18 1996  Anthony Green  <[email protected]>
+
+	* ffitest.c: Reordered tests while porting to sparc.
+	Made changes to handle lame structure passing for sparc.
+	Removed calls to fflush().
+
+	* prep_cif.c (ffi_prep_cif): Added special case for sparc
+	aggregate type arguments.
+
+Thu Oct 10 09:56:51 1996  Anthony Green  <[email protected]>
+
+	* ffitest.c (main): Added structure passing/returning tests.
+
+	* prep_cif.c (ffi_prep_cif): Perform proper initialization
+	of structure return types if needed.
+	(initialize_aggregate): Bug fix
+
+Wed Oct  9 16:04:20 1996  Anthony Green  <[email protected]>
+
+	* types.c: Added special definitions for x86 (double doesn't
+	need double word alignment).
+
+	* ffitest.c: Added many tests
+
+Tue Oct  8 09:19:22 1996  Anthony Green  <[email protected]>
+
+	* prep_cif.c (ffi_prep_cif): Fixed assertion.
+
+	* debug.c (ffi_assert): Must return a non void now.
+
+	* Makefile.am: Added test production.
+	* Makefile: Rebuilt.
+
+	* ffitest.c (main): Created. 
+
+	* types.c: Created. Stripped common code out of */ffi.c.
+
+	* prep_cif.c: Added missing stdlib.h include.
+
+	* debug.c (ffi_type_test): Used "a" to eliminate compiler
+	warnings in non-debug builds. Included ffi_common.h.
+
+Mon Oct  7 15:36:42 1996  Anthony Green  <[email protected]>
+
+	* Makefile.am: Added a rule for .s -> .o
+	This is required by the SGI compiler.
+	* Makefile: Rebuilt.
+
+Fri Oct  4 09:51:08 1996  Anthony Green  <[email protected]>
+
+	* prep_cif.c (initialize_aggregate): Moved abi specification
+	to ffi_prep_cif().
+
+Thu Oct  3 15:37:37 1996  Anthony Green  <[email protected]>
+
+	* prep_cif.c (ffi_prep_cif): Changed values from void* to void**.
+	(initialize_aggregate): Fixed aggregate type initialization.
+
+	* Makefile.am (EXTRA_DIST): Added support code for "make dist".
+	* Makefile.in: Regenerated.
+
+Wed Oct  2 11:41:57 1996  Anthony Green  <[email protected]>
+
+	* debug.c, prep_cif: Created.
+
+	* Makefile.am: Added debug.o and prep_cif.o to OBJ.
+	* Makefile.in: Regenerated.
+
+	* Makefile.am (INCLUDES): Added missing -I../include
+	* Makefile.in: Regenerated.
+
+Tue Oct  1 17:11:51 1996  Anthony Green  <[email protected]>
+
+	* error.c, Makefile.am: Created.
+	* Makefile.in: Generated.
+
+--- libffi/src/x86 --------------------------------------------------------
+
+Sun Oct  4 16:27:17 1998  Anthony Green  <[email protected]>
+
+	* sysv.S (retlongdouble): Fixed long long return value support.
+	* ffi.c (ffi_prep_cif_machdep): Ditto.
+
+Wed May 13 04:30:33 1998  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_prep_cif_machdep): Fixed long double return value
+	support.
+
+Wed Apr 15 08:43:20 1998  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_prep_args): small struct support was missing.
+
+Thu May  8 16:53:58 1997  Anthony Green  <[email protected]>
+
+	* objects.mak: Removed.
+
+Mon Dec  2 15:12:58 1996  Tom Tromey  <[email protected]>
+
+	* sysv.S: Use .balign, for a.out Linux boxes.
+
+Tue Oct 15 13:06:50 1996  Anthony Green  <[email protected]>
+
+	* ffi.c: Clean up based on LCLint output.
+	Added funny /*@...@*/ comments to annotate source.
+
+Fri Oct 11 16:43:38 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_call): Added assertion for bad ABIs.
+
+Wed Oct  9 13:57:27 1996  Anthony Green  <[email protected]>
+
+	* sysv.S (retdouble): Fixed double return problems.
+
+	* ffi.c	(ffi_call): Corrected fn arg definition.
+	(ffi_prep_cif_machdep): Fixed double return problems
+
+Tue Oct  8 12:12:49 1996  Anthony Green  <[email protected]>
+
+	* ffi.c: Moved ffi_type definitions to types.c.
+	(ffi_prep_args): Fixed type promotion bug.
+
+Mon Oct  7 15:53:06 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
+
+Fri Oct  4 09:54:53 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
+	remaining args.
+
+Wed Oct  2 10:07:05 1996  Anthony Green  <[email protected]>
+
+	* ffi.c, sysv.S, objects.mak: Created.
+	(ffi_prep_cif): cif->rvalue no longer initialized to NULL.
+	(ffi_prep_cif_machdep): Moved machine independent cif processing
+	to src/prep_cif.c. Introduced ffi_prep_cif_machdep().
+
+--- libffi/src/mips -------------------------------------------------------
+
+Tue Feb 17 17:18:07 1998  Anthony Green  <[email protected]>
+
+	* o32.S: Fixed typo in comment.
+
+	* ffi.c (ffi_prep_cif_machdep): Fixed argument processing.
+
+Thu May  8 16:53:58 1997  Anthony Green  <[email protected]>
+
+	* o32.s, n32.s: Wrappers for SGI tool support.
+
+	* objects.mak: Removed.
+
+Tue Oct 29 14:37:45 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_prep_args): Changed int z to size_t z.
+
+Tue Oct 15 13:17:25 1996  Anthony Green  <[email protected]>
+
+	* n32.S: Fixed bad stack munging. 
+
+	* ffi.c: Moved prototypes for ffi_call_?32() to here from
+	ffi_mips.h because extended_cif is not defined in ffi_mips.h.
+
+Mon Oct 14 12:42:02 1996  Anthony Green  <[email protected]>
+
+	* ffi.c: Interface changes based on feedback from Jim Blandy.
+
+Thu Oct 10 11:22:16 1996  Anthony Green  <[email protected]>
+
+	* n32.S, ffi.c: Lots of changes to support passing and 
+	returning structures with the n32 calling convention.
+
+	* n32.S: Fixed fn pointer bug.
+
+	* ffi.c (ffi_prep_cif_machdep): Fix for o32 structure
+	return values.
+	(ffi_prep_args): Fixed n32 structure passing when structures
+	partially fit in registers.
+
+Wed Oct  9 13:49:25 1996  Anthony Green  <[email protected]>
+
+	* objects.mak: Added n32.o.
+
+	* n32.S: Created.
+
+	* ffi.c (ffi_prep_args): Added magic to support proper
+	n32 processing.
+
+Tue Oct  8 10:37:35 1996  Anthony Green  <[email protected]>
+
+	* ffi.c: Moved ffi_type definitions to types.c.
+	(ffi_prep_args): Fixed type promotion bug.
+
+	* o32.S: This code is only built for o32 compiles.
+	A lot of the #define cruft has moved to ffi_mips.h.
+
+	* ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg
+	is only processed if the first is either a float or double.
+
+Mon Oct  7 15:33:59 1996  Anthony Green  <[email protected]>
+
+	* o32.S: Modified to compile under each of o32, n32 and n64.
+
+	* ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
+
+Fri Oct  4 09:53:25 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
+	remaining args.
+
+Wed Oct  2 17:41:22 1996  Anthony Green  <[email protected]>
+
+	* o32.S: Removed crufty definitions.
+
+Wed Oct  2 12:53:42 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
+	(ffi_prep_cif_machdep): Moved all machine independent cif processing
+	to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types
+	of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT.
+
+Tue Oct  1 17:11:02 1996  Anthony Green  <[email protected]>
+
+	* ffi.c, o32.S, object.mak: Created
+	
+--- libffi/src/sparc ------------------------------------------------------
+
+Tue Feb 24 16:33:18 1998  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_prep_args): Added long double support.
+
+Thu May  8 16:53:58 1997  Anthony Green  <[email protected]>
+
+	* objects.mak: Removed.
+
+Thu May  1 16:07:56 1997  Anthony Green  <[email protected]>
+
+	* v8.S: Fixed minor portability problem reported by 
+	Russ McManus <[email protected]>.
+
+Tue Nov 26 14:12:43 1996  Anthony Green  <[email protected]>
+
+	* v8.S: Used STACKFRAME define elsewhere. 
+
+	* ffi.c (ffi_prep_args): Zero out space when USING_PURIFY
+	is set.
+	(ffi_prep_cif_machdep): Allocate the correct stack frame 
+	space for functions with < 6 args.
+
+Tue Oct 29 15:08:55 1996  Anthony Green  <[email protected]>
+
+	* ffi.c (ffi_prep_args): int z is now size_t z.
+
+Mon Oct 14 13:31:24 1996  Anthony Green  <[email protected]>
+
+	* v8.S (ffi_call_V8): Gordon rewrites this again. It looks
+	great now.
+
+	* ffi.c (ffi_call): The comment about hijacked registers
+	is no longer valid after gordoni hacked v8.S.
+
+        * v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler.
+	
+	* v8.S, ffi.c: ffi_call() had changed to accept more than
+	two args, so v8.S had to change (because it hijacks incoming
+	arg registers).
+
+	* ffi.c: Interface changes based on feedback from Jim Blandy.
+
+Thu Oct 10 17:48:16 1996  Anthony Green  <[email protected]>
+
+	* ffi.c, v8.S, objects.mak: Created.
+	
+

+ 21 - 0
libffi.mod/libffi/LICENSE

@@ -0,0 +1,21 @@
+libffi - Copyright (c) 1996-2014  Anthony Green, Red Hat, Inc and others.
+See source files for details.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY 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.

+ 352 - 0
libffi.mod/libffi/LICENSE-BUILDTOOLS

@@ -0,0 +1,352 @@
+The libffi source distribution contains certain code that is not part
+of libffi, and is only used as tooling to assist with the building and
+testing of libffi.  This includes the msvcc.sh script used to wrap the
+Microsoft compiler with GNU compatible command-line options, and the
+libffi test code distributed in the testsuite/libffi.bhaible
+directory.  This code is distributed with libffi for the purpose of
+convenience only, and libffi is in no way derived from this code.
+
+msvcc.sh an testsuite/libffi.bhaible are both distributed under the
+terms of the GNU GPL version 2, as below.
+
+
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (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, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.

+ 166 - 0
libffi.mod/libffi/Makefile.am

@@ -0,0 +1,166 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign subdir-objects
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = include testsuite man
+if BUILD_DOCS
+## This hack is needed because it doesn't seem possible to make a
+## conditional info_TEXINFOS in Automake.  At least Automake 1.14
+## either gives errors -- if this attempted in the most
+## straightforward way -- or simply unconditionally tries to build the
+## info file.
+SUBDIRS += doc
+endif
+
+EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj			\
+	ChangeLog.libffi ChangeLog.libffi-3.1				\
+	m4/libtool.m4 m4/lt~obsolete.m4					\
+	 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4			\
+	 m4/ltversion.m4 src/debug.c msvcc.sh				\
+	generate-darwin-source-and-headers.py				\
+	libffi.xcodeproj/project.pbxproj				\
+	libtool-ldflags libtool-version configure.host README.md        \
+	libffi.map.in
+
+# local.exp is generated by configure
+DISTCLEANFILES = local.exp
+
+# Subdir rules rely on $(FLAGS_TO_PASS)
+FLAGS_TO_PASS = $(AM_MAKEFLAGS)
+
+MAKEOVERRIDES=
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libffi.pc
+
+toolexeclib_LTLIBRARIES = libffi.la
+noinst_LTLIBRARIES = libffi_convenience.la
+
+libffi_la_SOURCES = src/prep_cif.c src/types.c \
+		src/raw_api.c src/java_raw_api.c src/closures.c
+
+if FFI_DEBUG
+libffi_la_SOURCES += src/debug.c
+endif
+
+noinst_HEADERS = \
+	src/aarch64/ffitarget.h src/aarch64/internal.h			\
+	src/alpha/ffitarget.h src/alpha/internal.h			\
+	src/arc/ffitarget.h						\
+	src/arm/ffitarget.h src/arm/internal.h				\
+	src/avr32/ffitarget.h						\
+	src/bfin/ffitarget.h						\
+	src/cris/ffitarget.h						\
+	src/frv/ffitarget.h						\
+	src/ia64/ffitarget.h src/ia64/ia64_flags.h			\
+	src/m32r/ffitarget.h						\
+	src/m68k/ffitarget.h						\
+	src/m88k/ffitarget.h						\
+	src/metag/ffitarget.h						\
+	src/microblaze/ffitarget.h					\
+	src/mips/ffitarget.h						\
+	src/moxie/ffitarget.h						\
+	src/nios2/ffitarget.h						\
+	src/or1k/ffitarget.h						\
+	src/pa/ffitarget.h						\
+	src/powerpc/ffitarget.h src/powerpc/asm.h src/powerpc/ffi_powerpc.h \
+	src/riscv/ffitarget.h						\
+	src/s390/ffitarget.h src/s390/internal.h			\
+	src/sh/ffitarget.h						\
+	src/sh64/ffitarget.h						\
+	src/sparc/ffitarget.h src/sparc/internal.h			\
+	src/tile/ffitarget.h						\
+	src/vax/ffitarget.h						\
+	src/x86/ffitarget.h src/x86/internal.h src/x86/internal64.h src/x86/asmnames.h \
+	src/xtensa/ffitarget.h						\
+	src/dlmalloc.c
+
+EXTRA_libffi_la_SOURCES = \
+	src/aarch64/ffi.c src/aarch64/sysv.S				\
+	src/alpha/ffi.c src/alpha/osf.S					\
+	src/arc/ffi.c src/arc/arcompact.S				\
+	src/arm/ffi.c src/arm/sysv.S					\
+	src/avr32/ffi.c src/avr32/sysv.S				\
+	src/bfin/ffi.c src/bfin/sysv.S					\
+	src/cris/ffi.c src/cris/sysv.S					\
+	src/frv/ffi.c src/frv/eabi.S					\
+	src/ia64/ffi.c src/ia64/unix.S					\
+	src/m32r/ffi.c src/m32r/sysv.S					\
+	src/m68k/ffi.c src/m68k/sysv.S					\
+	src/m88k/ffi.c src/m88k/obsd.S					\
+	src/metag/ffi.c src/metag/sysv.S				\
+	src/microblaze/ffi.c src/microblaze/sysv.S			\
+	src/mips/ffi.c src/mips/o32.S src/mips/n32.S			\
+	src/moxie/ffi.c src/moxie/eabi.S				\
+	src/nios2/ffi.c src/nios2/sysv.S				\
+	src/or1k/ffi.c src/or1k/sysv.S					\
+	src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S			\
+	src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c \
+	 src/powerpc/sysv.S src/powerpc/linux64.S			\
+	 src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S	\
+	 src/powerpc/aix.S src/powerpc/darwin.S src/powerpc/aix_closure.S \
+	 src/powerpc/darwin_closure.S src/powerpc/ffi_darwin.c		\
+	src/riscv/ffi.c src/riscv/sysv.S				\
+	src/s390/ffi.c src/s390/sysv.S					\
+	src/sh/ffi.c src/sh/sysv.S					\
+	src/sh64/ffi.c src/sh64/sysv.S					\
+	src/sparc/ffi.c src/sparc/ffi64.c src/sparc/v8.S src/sparc/v9.S	\
+	src/tile/ffi.c src/tile/tile.S					\
+	src/vax/ffi.c src/vax/elfbsd.S					\
+	src/x86/ffi.c src/x86/sysv.S					\
+	 src/x86/ffiw64.c src/x86/win64.S 				\
+	 src/x86/ffi64.c src/x86/unix64.S				\
+	src/xtensa/ffi.c src/xtensa/sysv.S
+
+TARGET_OBJ = @TARGET_OBJ@
+libffi_la_LIBADD = $(TARGET_OBJ)
+
+libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
+EXTRA_libffi_convenience_la_SOURCES = $(EXTRA_libffi_la_SOURCES)
+libffi_convenience_la_LIBADD = $(libffi_la_LIBADD)
+libffi_convenience_la_DEPENDENCIES = $(libffi_la_DEPENDENCIES)
+nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
+
+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS))
+
+AM_CFLAGS =
+if FFI_DEBUG
+# Build debug. Define FFI_DEBUG on the commandline so that, when building with
+# MSVC, it can link against the debug CRT.
+AM_CFLAGS += -DFFI_DEBUG
+endif
+
+if LIBFFI_BUILD_VERSIONED_SHLIB
+if LIBFFI_BUILD_VERSIONED_SHLIB_GNU
+libffi_version_script = -Wl,--version-script,libffi.map
+libffi_version_dep = libffi.map
+endif
+if LIBFFI_BUILD_VERSIONED_SHLIB_SUN
+libffi_version_script = -Wl,-M,libffi.map-sun
+libffi_version_dep = libffi.map-sun
+libffi.map-sun : libffi.map $(top_srcdir)/../contrib/make_sunver.pl \
+		 $(libffi_la_OBJECTS) $(libffi_la_LIBADD)
+	perl $(top_srcdir)/../contrib/make_sunver.pl libffi.map \
+	 `echo $(libffi_la_OBJECTS) $(libffi_la_LIBADD) | \
+	    sed 's,\([^/        ]*\)\.l\([ao]\),.libs/\1.\2,g'` \
+	 > $@ || (rm -f $@ ; exit 1)
+endif
+else
+libffi_version_script =
+libffi_version_dep =
+endif
+libffi_version_info = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
+
+libffi.map: $(top_srcdir)/libffi.map.in
+	$(COMPILE) -D$(TARGET) -E -x assembler-with-cpp -o $@ $<
+
+libffi_la_LDFLAGS = -no-undefined $(libffi_version_info) $(libffi_version_script) $(LTLDFLAGS) $(AM_LTLDFLAGS)
+libffi_la_DEPENDENCIES = $(libffi_la_LIBADD) $(libffi_version_dep)
+
+AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
+AM_CCASFLAGS = $(AM_CPPFLAGS)
+
+dist-hook:
+	if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog

+ 461 - 0
libffi.mod/libffi/README.md

@@ -0,0 +1,461 @@
+Status
+======
+
+[![Build Status](https://travis-ci.org/libffi/libffi.svg?branch=master)](https://travis-ci.org/libffi/libffi)
+[![Build status](https://ci.appveyor.com/api/projects/status/8lko9vagbx4w2kxq?svg=true)](https://ci.appveyor.com/project/atgreen/libffi)
+
+libffi-3.3-rc0 was released on April 2, 2018.  Check the libffi web
+page for updates: <URL:http://sourceware.org/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.  
+
+FFI stands for Foreign Function Interface.  A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms
+===================
+
+Libffi has been ported to many different platforms.
+
+At the time of release, the following basic configurations have been
+tested:
+
+| Architecture    | Operating System | Compiler                |
+| --------------- | ---------------- | ----------------------- |
+| AArch64 (ARM64) | iOS              | Clang                   |
+| AArch64         | Linux            | GCC                     |
+| Alpha           | Linux            | GCC                     |
+| Alpha           | Tru64            | GCC                     |
+| ARC             | Linux            | GCC                     |
+| ARM             | Linux            | GCC                     |
+| ARM             | iOS              | GCC                     |
+| AVR32           | Linux            | GCC                     |
+| Blackfin        | uClinux          | GCC                     |
+| HPPA            | HPUX             | GCC                     |
+| IA-64           | Linux            | GCC                     |
+| M68K            | FreeMiNT         | GCC                     |
+| M68K            | Linux            | GCC                     |
+| M68K            | RTEMS            | GCC                     |
+| M88K            | OpenBSD/mvme88k  | GCC                     |
+| Meta            | Linux            | GCC                     |
+| MicroBlaze      | Linux            | GCC                     |
+| MIPS            | IRIX             | GCC                     |
+| MIPS            | Linux            | GCC                     |
+| MIPS            | RTEMS            | GCC                     |
+| MIPS64          | Linux            | GCC                     |
+| Moxie           | Bare metal       | GCC                     |
+| Nios II         | Linux            | GCC                     |
+| OpenRISC        | Linux            | GCC                     |
+| PowerPC 32-bit  | AIX              | IBM XL C                |
+| PowerPC 64-bit  | AIX              | IBM XL C                |
+| PowerPC         | AMIGA            | GCC                     |
+| PowerPC         | Linux            | GCC                     |
+| PowerPC         | Mac OSX          | GCC                     |
+| PowerPC         | FreeBSD          | GCC                     |
+| PowerPC 64-bit  | FreeBSD          | GCC                     |
+| PowerPC 64-bit  | Linux ELFv1      | GCC                     |
+| PowerPC 64-bit  | Linux ELFv2      | GCC                     |
+| RISC-V 32-bit   | Linux            | GCC                     |
+| RISC-V 64-bit   | Linux            | GCC                     |
+| S390            | Linux            | GCC                     |
+| S390X           | Linux            | GCC                     |
+| SPARC           | Linux            | GCC                     |
+| SPARC           | Solaris          | GCC                     |
+| SPARC           | Solaris          | Oracle Solaris Studio C |
+| SPARC64         | Linux            | GCC                     |
+| SPARC64         | FreeBSD          | GCC                     |
+| SPARC64         | Solaris          | Oracle Solaris Studio C |
+| TILE-Gx/TILEPro | Linux            | GCC                     |
+| VAX             | OpenBSD/vax      | GCC                     |
+| X86             | FreeBSD          | GCC                     |
+| X86             | GNU HURD         | GCC                     |
+| X86             | Interix          | GCC                     |
+| X86             | kFreeBSD         | GCC                     |
+| X86             | Linux            | GCC                     |
+| X86             | Mac OSX          | GCC                     |
+| X86             | OpenBSD          | GCC                     |
+| X86             | OS/2             | GCC                     |
+| X86             | Solaris          | GCC                     |
+| X86             | Solaris          | Oracle Solaris Studio C |
+| X86             | Windows/Cygwin   | GCC                     |
+| X86             | Windows/MingW    | GCC                     |
+| X86-64          | FreeBSD          | GCC                     |
+| X86-64          | Linux            | GCC                     |
+| X86-64          | Linux/x32        | GCC                     |
+| X86-64          | OpenBSD          | GCC                     |
+| X86-64          | Solaris          | Oracle Solaris Studio C |
+| X86-64          | Windows/Cygwin   | GCC                     |
+| X86-64          | Windows/MingW    | GCC                     |
+| X86-64          | Mac OSX          | GCC                     |
+| Xtensa          | Linux            | GCC                     |
+
+Please send additional platform test results to
[email protected].
+
+Installing libffi
+=================
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.  Note that building libffi requires a C99 compatible
+compiler.
+
+If you're building libffi directly from git hosted sources, configure
+won't exist yet; run ./autogen.sh first.  This will require that you
+install autoconf, automake and libtool.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the ``--prefix`` configure switch.  Libffi
+will install under /usr/local by default. 
+
+If you want to enable extra run-time debugging checks use the the
+``--enable-debug`` configure switch. This is useful when your program dies
+mysteriously while using libffi. 
+
+Another useful configure switch is ``--enable-purify-safety``. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using 
+Purify, as it will slow down the library.
+
+If you don't want to build documentation, use the ``--disable-docs``
+configure switch.
+
+It's also possible to build libffi on Windows platforms with
+Microsoft's Visual C++ compiler.  In this case, use the msvcc.sh
+wrapper script during configuration like so:
+
+    path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP"
+
+For 64-bit Windows builds, use ``CC="path/to/msvcc.sh -m64"`` and
+``CXX="path/to/msvcc.sh -m64"``.  You may also need to specify
+``--build`` appropriately.
+
+It is also possible to build libffi on Windows platforms with the LLVM
+project's clang-cl compiler, like below:
+
+    path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP"
+
+When building with MSVC under a MingW environment, you may need to
+remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
+command.  ('cygpath' is not present in MingW, and is not required when
+using MingW-style paths.)
+
+SPARC Solaris builds require the use of the GNU assembler and linker.
+Point ``AS`` and ``LD`` environment variables at those tool prior to
+configuration.
+
+For iOS builds, the ``libffi.xcodeproj`` Xcode project is available.
+
+Configure has many other options. Use ``configure --help`` to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make.  You can ftp GNU make from ftp.gnu.org:/pub/gnu/make .
+
+To ensure that libffi is working as advertised, type "make check".
+This will require that you have DejaGNU installed.
+
+To install the library and header files, type ``make install``.
+
+
+History
+=======
+
+See the git log for details at http://github.com/libffi/libffi.
+
+    3.3 TBD
+        Add RISC-V support.
+        New API in support of GO closures.
+        Default to Microsoft's 64 bit long double ABI with Visual C++.
+          GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
+	Many new tests cases and bug fixes.
+    
+    3.2.1 Nov-12-14
+        Build fix for non-iOS AArch64 targets.
+    
+    3.2 Nov-11-14
+        Add C99 Complex Type support (currently only supported on
+          s390).
+        Add support for PASCAL and REGISTER calling conventions on x86
+          Windows/Linux.
+        Add OpenRISC and Cygwin-64 support.
+        Bug fixes.
+    
+    3.1 May-19-14
+        Add AArch64 (ARM64) iOS support.
+        Add Nios II support.
+        Add m88k and DEC VAX support.
+        Add support for stdcall, thiscall, and fastcall on non-Windows
+          32-bit x86 targets such as Linux.
+        Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi
+          fixes.
+        Make the testsuite more robust: eliminate several spurious
+          failures, and respect the $CC and $CXX environment variables.
+        Archive off the manually maintained ChangeLog in favor of git
+          log.
+    
+    3.0.13 Mar-17-13
+        Add Meta support.
+        Add missing Moxie bits.
+        Fix stack alignment bug on 32-bit x86.
+        Build fix for m68000 targets.
+        Build fix for soft-float Power targets.
+        Fix the install dir location for some platforms when building
+          with GCC (OS X, Solaris).
+        Fix Cygwin regression.
+    
+    3.0.12 Feb-11-13
+        Add Moxie support.
+        Add AArch64 support.
+        Add Blackfin support.
+        Add TILE-Gx/TILEPro support.
+        Add MicroBlaze support.
+        Add Xtensa support.
+        Add support for PaX enabled kernels with MPROTECT.
+        Add support for native vendor compilers on
+          Solaris and AIX.
+        Work around LLVM/GCC interoperability issue on x86_64.
+    
+    3.0.11 Apr-11-12
+        Lots of build fixes.
+        Add support for variadic functions (ffi_prep_cif_var).
+        Add Linux/x32 support.
+        Add thiscall, fastcall and MSVC cdecl support on Windows.
+        Add Amiga and newer MacOS support.
+        Add m68k FreeMiNT support.
+        Integration with iOS' xcode build tools.
+        Fix Octeon and MC68881 support.
+        Fix code pessimizations.
+    
+    3.0.10 Aug-23-11
+        Add support for Apple's iOS.
+        Add support for ARM VFP ABI.
+        Add RTEMS support for MIPS and M68K.
+        Fix instruction cache clearing problems on
+          ARM and SPARC.
+        Fix the N64 build on mips-sgi-irix6.5.
+        Enable builds with Microsoft's compiler.
+        Enable x86 builds with Oracle's Solaris compiler.
+        Fix support for calling code compiled with Oracle's Sparc
+          Solaris compiler.
+        Testsuite fixes for Tru64 Unix.
+        Additional platform support.
+    
+    3.0.9 Dec-31-09
+        Add AVR32 and win64 ports.  Add ARM softfp support.
+        Many fixes for AIX, Solaris, HP-UX, *BSD.
+        Several PowerPC and x86-64 bug fixes.
+        Build DLL for windows.
+    
+    3.0.8 Dec-19-08
+        Add *BSD, BeOS, and PA-Linux support.
+    
+    3.0.7 Nov-11-08
+        Fix for ppc FreeBSD.
+        (thanks to Andreas Tobler)
+    
+    3.0.6 Jul-17-08
+        Fix for closures on sh.
+        Mark the sh/sh64 stack as non-executable.
+        (both thanks to Kaz Kojima)
+    
+    3.0.5 Apr-3-08
+        Fix libffi.pc file.
+        Fix #define ARM for IcedTea users.
+        Fix x86 closure bug.
+    
+    3.0.4 Feb-24-08
+        Fix x86 OpenBSD configury.
+    
+    3.0.3 Feb-22-08
+        Enable x86 OpenBSD thanks to Thomas Heller, and
+          x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
+        Clean up test instruction in README.
+    
+    3.0.2 Feb-21-08
+        Improved x86 FreeBSD support.
+        Thanks to Björn König.
+    
+    3.0.1 Feb-15-08
+        Fix instruction cache flushing bug on MIPS.
+        Thanks to David Daney.
+    
+    3.0.0 Feb-15-08
+        Many changes, mostly thanks to the GCC project.
+        Cygnus Solutions is now Red Hat.
+    
+      [10 years go by...]
+    
+    1.20 Oct-5-98
+        Raffaele Sena produces ARM port.
+    
+    1.19 Oct-5-98
+        Fixed x86 long double and long long return support.
+        m68k bug fixes from Andreas Schwab.
+        Patch for DU assembler compatibility for the Alpha from Richard
+          Henderson.
+    
+    1.18 Apr-17-98
+        Bug fixes and MIPS configuration changes.
+    
+    1.17 Feb-24-98
+        Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+        Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+    
+    1.16 Feb-11-98
+        Richard Henderson produces Alpha port.
+    
+    1.15 Dec-4-97
+        Fixed an n32 ABI bug. New libtool, auto* support.
+    
+    1.14 May-13-97
+        libtool is now used to generate shared and static libraries.
+        Fixed a minor portability problem reported by Russ McManus
+        <[email protected]>.
+    
+    1.13 Dec-2-96
+        Added --enable-purify-safety to keep Purify from complaining
+          about certain low level code.
+        Sparc fix for calling functions with < 6 args.
+        Linux x86 a.out fix.
+    
+    1.12 Nov-22-96
+        Added missing ffi_type_void, needed for supporting void return 
+          types. Fixed test case for non MIPS machines. Cygnus Support 
+          is now Cygnus Solutions. 
+    
+    1.11 Oct-30-96
+        Added notes about GNU make.
+    
+    1.10 Oct-29-96
+        Added configuration fix for non GNU compilers.
+    
+    1.09 Oct-29-96
+        Added --enable-debug configure switch. Clean-ups based on LCLint 
+        feedback. ffi_mips.h is always installed. Many configuration 
+        fixes. Fixed ffitest.c for sparc builds.
+    
+    1.08 Oct-15-96
+        Fixed n32 problem. Many clean-ups.
+    
+    1.07 Oct-14-96
+        Gordon Irlam rewrites v8.S again. Bug fixes.
+    
+    1.06 Oct-14-96
+        Gordon Irlam improved the sparc port. 
+    
+    1.05 Oct-14-96
+        Interface changes based on feedback.
+    
+    1.04 Oct-11-96
+        Sparc port complete (modulo struct passing bug).
+    
+    1.03 Oct-10-96
+        Passing struct args, and returning struct values works for
+        all architectures/calling conventions. Expanded tests.
+    
+    1.02 Oct-9-96
+        Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+        Added "make test".
+    
+    1.01 Oct-8-96
+        Fixed float passing bug in mips version. Restructured some
+        of the code. Builds cleanly with SGI tools.
+    
+    1.00 Oct-7-96
+        First release. No public announcement.
+
+Authors & Credits
+=================
+
+libffi was originally written by Anthony Green <[email protected]>.
+
+The developers of the GNU Compiler Collection project have made
+innumerable valuable contributions.  See the ChangeLog file for
+details.
+
+Some of the ideas behind libffi were inspired by Gianni Mariani's free
+gencall library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented by Kresten Krab
+Thorup.
+
+Major processor architecture ports were contributed by the following
+developers:
+
+    aarch64             Marcus Shawcroft, James Greenhalgh
+    alpha               Richard Henderson
+    arm                 Raffaele Sena
+    blackfin            Alexandre Keunecke I. de Mendonca
+    cris                Simon Posnjak, Hans-Peter Nilsson
+    frv                 Anthony Green
+    ia64                Hans Boehm
+    m32r                Kazuhiro Inaoka
+    m68k                Andreas Schwab
+    m88k                Miod Vallat
+    microblaze          Nathan Rossi
+    mips                Anthony Green, Casey Marshall
+    mips64              David Daney
+    moxie               Anthony Green
+    nios ii             Sandra Loosemore
+    openrisc            Sebastian Macke
+    pa                  Randolph Chung, Dave Anglin, Andreas Tobler
+    powerpc             Geoffrey Keating, Andreas Tobler,
+                        David Edelsohn, John Hornkvist
+    powerpc64           Jakub Jelinek
+    s390                Gerhard Tonn, Ulrich Weigand
+    sh                  Kaz Kojima
+    sh64                Kaz Kojima
+    sparc               Anthony Green, Gordon Irlam
+    tile-gx/tilepro     Walter Lee
+    vax                 Miod Vallat
+    x86                 Anthony Green, Jon Beniston
+    x86-64              Bo Thorsen
+    xtensa              Chris Zankel
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes, documentation and
+configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+Andreas Tobler has done a tremendous amount of work on the testsuite.
+
+Alex Oliva solved the executable page problem for SElinux.
+
+The list above is almost certainly incomplete and inaccurate.  I'm
+happy to make corrections or additions upon request.
+
+If you have a problem, or have found a bug, please send a note to the
+author at [email protected], or the project mailing list at
[email protected].

+ 479 - 0
libffi.mod/libffi/acinclude.m4

@@ -0,0 +1,479 @@
+# mmap(2) blacklisting.  Some platforms provide the mmap library routine
+# but don't support all of the features we need from it.
+AC_DEFUN([AC_FUNC_MMAP_BLACKLIST],
+[
+AC_CHECK_HEADER([sys/mman.h],
+		[libffi_header_sys_mman_h=yes], [libffi_header_sys_mman_h=no])
+AC_CHECK_FUNC([mmap], [libffi_func_mmap=yes], [libffi_func_mmap=no])
+if test "$libffi_header_sys_mman_h" != yes \
+ || test "$libffi_func_mmap" != yes; then
+   ac_cv_func_mmap_file=no
+   ac_cv_func_mmap_dev_zero=no
+   ac_cv_func_mmap_anon=no
+else
+   AC_CACHE_CHECK([whether read-only mmap of a plain file works],
+  ac_cv_func_mmap_file,
+  [# Add a system to this blacklist if
+   # mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
+   # memory area containing the same data that you'd get if you applied
+   # read() to the same fd.  The only system known to have a problem here
+   # is VMS, where text files have record structure.
+   case "$host_os" in
+     vms* | ultrix*)
+	ac_cv_func_mmap_file=no ;;
+     *)
+	ac_cv_func_mmap_file=yes;;
+   esac])
+   AC_CACHE_CHECK([whether mmap from /dev/zero works],
+  ac_cv_func_mmap_dev_zero,
+  [# Add a system to this blacklist if it has mmap() but /dev/zero
+   # does not exist, or if mmapping /dev/zero does not give anonymous
+   # zeroed pages with both the following properties:
+   # 1. If you map N consecutive pages in with one call, and then
+   #    unmap any subset of those pages, the pages that were not
+   #    explicitly unmapped remain accessible.
+   # 2. If you map two adjacent blocks of memory and then unmap them
+   #    both at once, they must both go away.
+   # Systems known to be in this category are Windows (all variants),
+   # VMS, and Darwin.
+   case "$host_os" in
+     vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
+	ac_cv_func_mmap_dev_zero=no ;;
+     *)
+	ac_cv_func_mmap_dev_zero=yes;;
+   esac])
+
+   # Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
+   AC_CACHE_CHECK([for MAP_ANON(YMOUS)], ac_cv_decl_map_anon,
+    [AC_TRY_COMPILE(
+[#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+],
+[int n = MAP_ANONYMOUS;],
+    ac_cv_decl_map_anon=yes,
+    ac_cv_decl_map_anon=no)])
+
+   if test $ac_cv_decl_map_anon = no; then
+     ac_cv_func_mmap_anon=no
+   else
+     AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
+     ac_cv_func_mmap_anon,
+  [# Add a system to this blacklist if it has mmap() and MAP_ANON or
+   # MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
+   # doesn't give anonymous zeroed pages with the same properties listed
+   # above for use of /dev/zero.
+   # Systems known to be in this category are Windows, VMS, and SCO Unix.
+   case "$host_os" in
+     vms* | cygwin* | pe | mingw* | sco* | udk* )
+	ac_cv_func_mmap_anon=no ;;
+     *)
+	ac_cv_func_mmap_anon=yes;;
+   esac])
+   fi
+fi
+
+if test $ac_cv_func_mmap_file = yes; then
+  AC_DEFINE(HAVE_MMAP_FILE, 1,
+	    [Define if read-only mmap of a plain file works.])
+fi
+if test $ac_cv_func_mmap_dev_zero = yes; then
+  AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
+	    [Define if mmap of /dev/zero works.])
+fi
+if test $ac_cv_func_mmap_anon = yes; then
+  AC_DEFINE(HAVE_MMAP_ANON, 1,
+	    [Define if mmap with MAP_ANON(YMOUS) works.])
+fi
+])
+
+dnl ----------------------------------------------------------------------
+dnl This whole bit snagged from libstdc++-v3, via libatomic.
+
+dnl
+dnl LIBFFI_ENABLE
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
+dnl    (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
+dnl
+dnl See docs/html/17_intro/configury.html#enable for documentation.
+dnl
+m4_define([LIBFFI_ENABLE],[dnl
+m4_define([_g_switch],[--enable-$1])dnl
+m4_define([_g_help],[AC_HELP_STRING(_g_switch$3,[$4 @<:@default=$2@:>@])])dnl
+ AC_ARG_ENABLE($1,_g_help,
+  m4_bmatch([$5],
+   [^permit ],
+     [[
+      case "$enableval" in
+       m4_bpatsubst([$5],[permit ])) ;;
+       *) AC_MSG_ERROR(Unknown argument to enable/disable $1) ;;
+          dnl Idea for future:  generate a URL pointing to
+          dnl "onlinedocs/configopts.html#whatever"
+      esac
+     ]],
+   [^$],
+     [[
+      case "$enableval" in
+       yes|no) ;;
+       *) AC_MSG_ERROR(Argument to enable/disable $1 must be yes or no) ;;
+      esac
+     ]],
+   [[$5]]),
+  [enable_]m4_bpatsubst([$1],-,_)[=][$2])
+m4_undefine([_g_switch])dnl
+m4_undefine([_g_help])dnl
+])
+
+dnl
+dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
+dnl the native linker is in use, all variables will be defined to something
+dnl safe (like an empty string).
+dnl
+dnl Defines:
+dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
+dnl  OPT_LDFLAGS='-Wl,-O1' if possible
+dnl  LD (as a side effect of testing)
+dnl Sets:
+dnl  with_gnu_ld
+dnl  libat_ld_is_gold (possibly)
+dnl  libat_gnu_ld_version (possibly)
+dnl
+dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
+dnl set libat_gnu_ld_version to 12345.  Zeros cause problems.
+dnl
+AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
+  # If we're not using GNU ld, then there's no point in even trying these
+  # tests.  Check for that first.  We should have already tested for gld
+  # by now (in libtool), but require it now just to be safe...
+  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+  AC_REQUIRE([AC_PROG_LD])
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # The name set by libtool depends on the version of libtool.  Shame on us
+  # for depending on an impl detail, but c'est la vie.  Older versions used
+  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+  # set (hence we're using an older libtool), then set it.
+  if test x${with_gnu_ld+set} != xset; then
+    if test x${ac_cv_prog_gnu_ld+set} != xset; then
+      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+      with_gnu_ld=no
+    else
+      with_gnu_ld=$ac_cv_prog_gnu_ld
+    fi
+  fi
+
+  # Start by getting the version number.  I think the libtool test already
+  # does some of this, but throws away the result.
+  libat_ld_is_gold=no
+  if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
+    libat_ld_is_gold=yes
+  fi
+  changequote(,)
+  ldver=`$LD --version 2>/dev/null |
+         sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
+  changequote([,])
+  libat_gnu_ld_version=`echo $ldver | \
+         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
+
+  # Set --gc-sections.
+  if test "$with_gnu_ld" = "notbroken"; then
+    # GNU ld it is!  Joy and bunny rabbits!
+
+    # All these tests are for C++; save the language and the compiler flags.
+    # Need to do this so that g++ won't try to link in libstdc++
+    ac_test_CFLAGS="${CFLAGS+set}"
+    ac_save_CFLAGS="$CFLAGS"
+    CFLAGS='-x c++  -Wl,--gc-sections'
+
+    # Check for -Wl,--gc-sections
+    # XXX This test is broken at the moment, as symbols required for linking
+    # are now in libsupc++ (not built yet).  In addition, this test has
+    # cored on solaris in the past.  In addition, --gc-sections doesn't
+    # really work at the moment (keeps on discarding used sections, first
+    # .eh_frame and now some of the glibc sections for iconv).
+    # Bzzzzt.  Thanks for playing, maybe next time.
+    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
+    AC_TRY_RUN([
+     int main(void)
+     {
+       try { throw 1; }
+       catch (...) { };
+       return 0;
+     }
+    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
+    if test "$ac_test_CFLAGS" = set; then
+      CFLAGS="$ac_save_CFLAGS"
+    else
+      # this is the suspicious part
+      CFLAGS=''
+    fi
+    if test "$ac_sectionLDflags" = "yes"; then
+      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+    fi
+    AC_MSG_RESULT($ac_sectionLDflags)
+  fi
+
+  # Set linker optimization flags.
+  if test x"$with_gnu_ld" = x"yes"; then
+    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+  fi
+
+  AC_SUBST(SECTION_LDFLAGS)
+  AC_SUBST(OPT_LDFLAGS)
+])
+
+
+dnl
+dnl If GNU ld is in use, check to see if tricky linker opts can be used.  If
+dnl the native linker is in use, all variables will be defined to something
+dnl safe (like an empty string).
+dnl
+dnl Defines:
+dnl  SECTION_LDFLAGS='-Wl,--gc-sections' if possible
+dnl  OPT_LDFLAGS='-Wl,-O1' if possible
+dnl  LD (as a side effect of testing)
+dnl Sets:
+dnl  with_gnu_ld
+dnl  libat_ld_is_gold (possibly)
+dnl  libat_gnu_ld_version (possibly)
+dnl
+dnl The last will be a single integer, e.g., version 1.23.45.0.67.89 will
+dnl set libat_gnu_ld_version to 12345.  Zeros cause problems.
+dnl
+AC_DEFUN([LIBFFI_CHECK_LINKER_FEATURES], [
+  # If we're not using GNU ld, then there's no point in even trying these
+  # tests.  Check for that first.  We should have already tested for gld
+  # by now (in libtool), but require it now just to be safe...
+  test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+  test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+  AC_REQUIRE([AC_PROG_LD])
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # The name set by libtool depends on the version of libtool.  Shame on us
+  # for depending on an impl detail, but c'est la vie.  Older versions used
+  # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+  # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+  # makes sense).  We'll test with_gnu_ld everywhere else, so if that isn't
+  # set (hence we're using an older libtool), then set it.
+  if test x${with_gnu_ld+set} != xset; then
+    if test x${ac_cv_prog_gnu_ld+set} != xset; then
+      # We got through "ac_require(ac_prog_ld)" and still not set?  Huh?
+      with_gnu_ld=no
+    else
+      with_gnu_ld=$ac_cv_prog_gnu_ld
+    fi
+  fi
+
+  # Start by getting the version number.  I think the libtool test already
+  # does some of this, but throws away the result.
+  libat_ld_is_gold=no
+  if $LD --version 2>/dev/null | grep 'GNU gold'> /dev/null 2>&1; then
+    libat_ld_is_gold=yes
+  fi
+  libat_ld_is_lld=no
+  if $LD --version 2>/dev/null | grep 'LLD '> /dev/null 2>&1; then
+    libat_ld_is_lld=yes
+  fi
+  changequote(,)
+  ldver=`$LD --version 2>/dev/null |
+         sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
+  changequote([,])
+  libat_gnu_ld_version=`echo $ldver | \
+         $AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
+
+  # Set --gc-sections.
+  if test "$with_gnu_ld" = "notbroken"; then
+    # GNU ld it is!  Joy and bunny rabbits!
+
+    # All these tests are for C++; save the language and the compiler flags.
+    # Need to do this so that g++ won't try to link in libstdc++
+    ac_test_CFLAGS="${CFLAGS+set}"
+    ac_save_CFLAGS="$CFLAGS"
+    CFLAGS='-x c++  -Wl,--gc-sections'
+
+    # Check for -Wl,--gc-sections
+    # XXX This test is broken at the moment, as symbols required for linking
+    # are now in libsupc++ (not built yet).  In addition, this test has
+    # cored on solaris in the past.  In addition, --gc-sections doesn't
+    # really work at the moment (keeps on discarding used sections, first
+    # .eh_frame and now some of the glibc sections for iconv).
+    # Bzzzzt.  Thanks for playing, maybe next time.
+    AC_MSG_CHECKING([for ld that supports -Wl,--gc-sections])
+    AC_TRY_RUN([
+     int main(void)
+     {
+       try { throw 1; }
+       catch (...) { };
+       return 0;
+     }
+    ], [ac_sectionLDflags=yes],[ac_sectionLDflags=no], [ac_sectionLDflags=yes])
+    if test "$ac_test_CFLAGS" = set; then
+      CFLAGS="$ac_save_CFLAGS"
+    else
+      # this is the suspicious part
+      CFLAGS=''
+    fi
+    if test "$ac_sectionLDflags" = "yes"; then
+      SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+    fi
+    AC_MSG_RESULT($ac_sectionLDflags)
+  fi
+
+  # Set linker optimization flags.
+  if test x"$with_gnu_ld" = x"yes"; then
+    OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+  fi
+
+  AC_SUBST(SECTION_LDFLAGS)
+  AC_SUBST(OPT_LDFLAGS)
+])
+
+
+dnl
+dnl Add version tags to symbols in shared library (or not), additionally
+dnl marking other symbols as private/local (or not).
+dnl
+dnl --enable-symvers=style adds a version script to the linker call when
+dnl       creating the shared library.  The choice of version script is
+dnl       controlled by 'style'.
+dnl --disable-symvers does not.
+dnl  +  Usage:  LIBFFI_ENABLE_SYMVERS[(DEFAULT)]
+dnl       Where DEFAULT is either 'yes' or 'no'.  Passing `yes' tries to
+dnl       choose a default style based on linker characteristics.  Passing
+dnl       'no' disables versioning.
+dnl
+AC_DEFUN([LIBFFI_ENABLE_SYMVERS], [
+
+LIBFFI_ENABLE(symvers,yes,[=STYLE],
+  [enables symbol versioning of the shared library],
+  [permit yes|no|gnu*|sun])
+
+# If we never went through the LIBFFI_CHECK_LINKER_FEATURES macro, then we
+# don't know enough about $LD to do tricks...
+AC_REQUIRE([LIBFFI_CHECK_LINKER_FEATURES])
+
+# Turn a 'yes' into a suitable default.
+if test x$enable_symvers = xyes ; then
+  # FIXME  The following test is too strict, in theory.
+  if test $enable_shared = no || test "x$LD" = x; then
+    enable_symvers=no
+  else
+    if test $with_gnu_ld = yes ; then
+      enable_symvers=gnu
+    else
+      case ${target_os} in
+        # Sun symbol versioning exists since Solaris 2.5.
+        solaris2.[[5-9]]* | solaris2.1[[0-9]]*)
+          enable_symvers=sun ;;
+        *)
+          enable_symvers=no ;;
+      esac
+    fi
+  fi
+fi
+
+# Check if 'sun' was requested on non-Solaris 2 platforms.
+if test x$enable_symvers = xsun ; then
+  case ${target_os} in
+    solaris2*)
+      # All fine.
+      ;;
+    *)
+      # Unlikely to work.
+      AC_MSG_WARN([=== You have requested Sun symbol versioning, but])
+      AC_MSG_WARN([=== you are not targetting Solaris 2.])
+      AC_MSG_WARN([=== Symbol versioning will be disabled.])
+      enable_symvers=no
+      ;;
+  esac
+fi
+
+# Check to see if libgcc_s exists, indicating that shared libgcc is possible.
+if test $enable_symvers != no; then
+  AC_MSG_CHECKING([for shared libgcc])
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=' -lgcc_s'
+  AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes, libat_shared_libgcc=no)
+  CFLAGS="$ac_save_CFLAGS"
+  if test $libat_shared_libgcc = no; then
+    cat > conftest.c <<EOF
+int main (void) { return 0; }
+EOF
+changequote(,)dnl
+    libat_libgcc_s_suffix=`${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
+			     -shared -shared-libgcc -o conftest.so \
+			     conftest.c -v 2>&1 >/dev/null \
+			     | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'`
+changequote([,])dnl
+    rm -f conftest.c conftest.so
+    if test x${libat_libgcc_s_suffix+set} = xset; then
+      CFLAGS=" -lgcc_s$libat_libgcc_s_suffix"
+      AC_TRY_LINK(, [return 0;], libat_shared_libgcc=yes)
+      CFLAGS="$ac_save_CFLAGS"
+    fi
+  fi
+  AC_MSG_RESULT($libat_shared_libgcc)
+fi
+
+# For GNU ld, we need at least this version.  The format is described in
+# LIBFFI_CHECK_LINKER_FEATURES above.
+libat_min_gnu_ld_version=21400
+# XXXXXXXXXXX libat_gnu_ld_version=21390
+
+# Check to see if unspecified "yes" value can win, given results above.
+# Change "yes" into either "no" or a style name.
+if test $enable_symvers != no && test $libat_shared_libgcc = yes; then
+  if test $with_gnu_ld = yes; then
+    if test $libat_gnu_ld_version -ge $libat_min_gnu_ld_version ; then
+      enable_symvers=gnu
+    elif test $libat_ld_is_gold = yes ; then
+      enable_symvers=gnu
+    elif test $libat_ld_is_lld = yes ; then
+      enable_symvers=gnu
+    else
+      # The right tools, the right setup, but too old.  Fallbacks?
+      AC_MSG_WARN(=== Linker version $libat_gnu_ld_version is too old for)
+      AC_MSG_WARN(=== full symbol versioning support in this release of GCC.)
+      AC_MSG_WARN(=== You would need to upgrade your binutils to version)
+      AC_MSG_WARN(=== $libat_min_gnu_ld_version or later and rebuild GCC.)
+      if test $libat_gnu_ld_version -ge 21200 ; then
+        # Globbing fix is present, proper block support is not.
+        dnl AC_MSG_WARN([=== Dude, you are soooo close.  Maybe we can fake it.])
+        dnl enable_symvers=???
+        AC_MSG_WARN([=== Symbol versioning will be disabled.])
+        enable_symvers=no
+      else
+        # 2.11 or older.
+        AC_MSG_WARN([=== Symbol versioning will be disabled.])
+        enable_symvers=no
+      fi
+    fi
+  elif test $enable_symvers = sun; then
+    : All interesting versions of Sun ld support sun style symbol versioning.
+  else
+    # just fail for now
+    AC_MSG_WARN([=== You have requested some kind of symbol versioning, but])
+    AC_MSG_WARN([=== either you are not using a supported linker, or you are])
+    AC_MSG_WARN([=== not building a shared libgcc_s (which is required).])
+    AC_MSG_WARN([=== Symbol versioning will be disabled.])
+    enable_symvers=no
+  fi
+fi
+if test $enable_symvers = gnu; then
+  AC_DEFINE(LIBFFI_GNU_SYMBOL_VERSIONING, 1,
+	    [Define to 1 if GNU symbol versioning is used for libatomic.])
+fi
+
+AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB, test $enable_symvers != no)
+AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_GNU, test $enable_symvers = gnu)
+AM_CONDITIONAL(LIBFFI_BUILD_VERSIONED_SHLIB_SUN, test $enable_symvers = sun)
+AC_MSG_NOTICE(versioning on shared library symbols is $enable_symvers)
+])

+ 2 - 0
libffi.mod/libffi/autogen.sh

@@ -0,0 +1,2 @@
+#!/bin/sh
+exec autoreconf -v -i

+ 1466 - 0
libffi.mod/libffi/config.guess

@@ -0,0 +1,1466 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright 1992-2017 Free Software Foundation, Inc.
+
+timestamp='2017-05-11'
+
+# 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 <http://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:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
+# Please send patches to <[email protected]>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -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 <[email protected]>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2017 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
+
+trap 'exit 1' 1 2 15
+
+# 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.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { 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) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; 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 ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# ([email protected] 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; 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/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	;;
+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".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+	    /sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || \
+	    echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    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)
+		eval $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.
+	echo "${machine}-${os}${release}${abi}"
+	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:LibertyBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:Sortix:*:*)
+	echo ${UNAME_MACHINE}-unknown-sortix
+	exit ;;
+    alpha:OSF1:*:*)
+	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.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# [email protected] (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $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 [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH=x86_64
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    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.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    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'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    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)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # 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:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $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; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $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
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *: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 [ -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
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    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 [ -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 [ "${HP_ARCH}" = "" ]; then
+		    eval $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 [ ${HP_ARCH} = hppa2.0w ]
+	then
+	    eval $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
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $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; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    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*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    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:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    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/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    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/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		UNAME_PROCESSOR=x86_64 ;;
+	    i386)
+		UNAME_PROCESSOR=i586 ;;
+	esac
+	echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    *:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` 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
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    e2k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    k1om:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    mips64el:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:* | or1k*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    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.
+	echo i386-sequent-sysv4
+	exit ;;
+    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.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    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
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${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
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    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.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    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*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <[email protected]>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <[email protected]>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From [email protected].
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From [email protected].
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From [email protected].
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-ACE:SUPER-UX:*:*)
+	echo sxace-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$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
+	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
+	fi
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = x86; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-*:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-*:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSX-*:NONSTOP_KERNEL:*:*)
+	echo nsx-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *: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
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+    amd64:Isilon\ OneFS:*:*)
+	echo x86_64-unknown-onefs
+	exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to [email protected] 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
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

+ 1836 - 0
libffi.mod/libffi/config.sub

@@ -0,0 +1,1836 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright 1992-2017 Free Software Foundation, Inc.
+
+timestamp='2017-04-02'
+
+# 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 <http://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 <[email protected]>.
+#
+# 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:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=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.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -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 <[email protected]>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2017 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"
+       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
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -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*)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| ba \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| e2k | epiphany \
+	| fido | fr30 | frv | ft32 \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia16 | ia64 \
+	| ip2k | iq2000 \
+	| k1om \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 | or1k | or1knd | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pru \
+	| pyramid \
+	| riscv32 | riscv64 \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| visium \
+	| wasm32 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	leon|leon[3-9])
+		basic_machine=sparc-$basic_machine
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# 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)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| ba-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| e2k-* | elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| k1om-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| or1k*-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pru-* \
+	| pyramid-* \
+	| riscv32-* | riscv64-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| visium-* \
+	| wasm32-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	asmjs)
+		basic_machine=asmjs-unknown
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	e500v[12])
+		basic_machine=powerpc-unknown
+		os=$os"spe"
+		;;
+	e500v[12]-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=$os"spe"
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	leon-*|leon[3-9]-*)
+		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	moxiebox)
+		basic_machine=moxie-unknown
+		os=-moxiebox
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	nsx-tandem)
+		basic_machine=nsx-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	wasm32)
+		basic_machine=wasm32-unknown
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# 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)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+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
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-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
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# 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
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-ios)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+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.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-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=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	pru-*)
+		os=-elf
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-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
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-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=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $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
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				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
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

+ 394 - 0
libffi.mod/libffi/configure.ac

@@ -0,0 +1,394 @@
+dnl Process this with autoconf to create configure
+
+AC_PREREQ(2.68)
+
+AC_INIT([libffi], [3.3-rc0], [http://github.com/libffi/libffi/issues])
+AC_CONFIG_HEADERS([fficonfig.h])
+
+AC_CANONICAL_SYSTEM
+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
+
+AM_INIT_AUTOMAKE
+
+# The same as in boehm-gc and libstdc++. Have to borrow it from there.
+# We must force CC to /not/ be precious variables; otherwise
+# the wrong, non-multilib-adjusted value will be used in multilibs.
+# As a side effect, we have to subst CFLAGS ourselves.
+# Also save and restore CFLAGS, since AC_PROG_CC will come up with
+# defaults of its own if none are provided.
+
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+save_CFLAGS=$CFLAGS
+AC_PROG_CC
+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_LIBTOOL
+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"
+EOF
+
+AM_MAINTAINER_MODE
+
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_FUNCS([mmap mkostemp])
+AC_FUNC_MMAP_BLACKLIST
+
+dnl The -no-testsuite modules omit the test subdir.
+AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
+
+TARGETDIR="unknown"
+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)
+
+AC_HEADER_STDC
+AC_CHECK_FUNCS(memcpy)
+AC_FUNC_ALLOCA
+
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(long double)
+
+# Also AC_SUBST this variable for ffi.h.
+if test -z "$HAVE_LONG_DOUBLE"; then
+  HAVE_LONG_DOUBLE=0
+  if test $ac_cv_sizeof_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
+
+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_TRY_LINK([asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");],,
+		    [libffi_cv_as_sparc_ua_pcrel=yes],
+		    [libffi_cv_as_sparc_ua_pcrel=no])
+	CFLAGS="$save_CFLAGS"
+	LDFLAGS="$save_LDFLAGS"])
+    if test "x$libffi_cv_as_sparc_ua_pcrel" = xyes; then
+	AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+		  [Define if your assembler and linker support unaligned PC relative relocs.])
+    fi
+
+    AC_CACHE_CHECK([assembler .register pseudo-op support],
+       libffi_cv_as_register_pseudo_op, [
+       libffi_cv_as_register_pseudo_op=unknown
+       # Check if we have .register
+       AC_TRY_COMPILE(,[asm (".register %g2, #scratch");],
+		       [libffi_cv_as_register_pseudo_op=yes],
+		       [libffi_cv_as_register_pseudo_op=no])
+    ])
+    if test "x$libffi_cv_as_register_pseudo_op" = xyes; then
+       AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
+	       [Define if your assembler supports .register.])
+    fi
+    ;;
+
+  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
+    ;;
+esac
+
+# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
+AC_ARG_ENABLE(pax_emutramp,
+  [  --enable-pax_emutramp       enable pax emulated trampolines, for we can't use PROT_EXEC],
+  if test "$enable_pax_emutramp" = "yes"; then
+    AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1,
+      [Define this if you want to enable pax emulated trampolines])
+  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-* | *-*-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
+  AC_CACHE_CHECK([whether .eh_frame section should be read-only],
+      libffi_cv_ro_eh_frame, [
+  	libffi_cv_ro_eh_frame=no
+  	echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c
+  	if $CC $CFLAGS -c -fpic -fexceptions -o conftest.o conftest.c > /dev/null 2>&1; then
+	    objdump -h conftest.o > conftest.dump 2>&1
+	    libffi_eh_frame_line=`grep -n eh_frame conftest.dump | cut -d: -f 1`
+	    if test "x$libffi_eh_frame_line" != "x"; then
+	        libffi_test_line=`expr $libffi_eh_frame_line + 1`p
+	        sed -n $libffi_test_line conftest.dump > conftest.line
+	        if grep READONLY conftest.line > /dev/null; then
+	            libffi_cv_ro_eh_frame=yes
+	        fi
+	    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' 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
+
+AC_ARG_ENABLE(docs,
+              AC_HELP_STRING([--disable-docs],
+                             [Disable building of docs (default: no)]),
+              [enable_docs=no],
+              [enable_docs=yes])
+AM_CONDITIONAL(BUILD_DOCS, [test x$enable_docs = xyes])
+
+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)
+
+changequote(<,>)
+TARGET_OBJ=
+for i in $SOURCES; do
+  TARGET_OBJ="${TARGET_OBJ} src/${TARGETDIR}/"`echo $i | sed 's/[cS]$/lo/'`
+done
+changequote([,])
+AC_SUBST(TARGET_OBJ)
+
+AC_SUBST(SHELL)
+
+AC_ARG_ENABLE(debug,
+[  --enable-debug          debugging mode],
+  if test "$enable_debug" = "yes"; then
+    AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.])
+  fi)
+AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes")
+
+AC_ARG_ENABLE(structs,
+[  --disable-structs       omit code for struct support],
+  if test "$enable_structs" = "no"; then
+    AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this 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(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)
+
+AC_ARG_ENABLE(multi-os-directory,
+[  --disable-multi-os-directory
+                          disable use of gcc --print-multi-os-directory to change the library installation directory])
+                          
+# These variables are only ever used when we cross-build to X86_WIN32.
+# And we only support this with GCC, so...
+if test "x$GCC" = "xyes"; then
+  if test -n "$with_cross_host" &&
+     test x"$with_cross_host" != x"no"; then
+    toolexecdir='${exec_prefix}'/'$(target_alias)'
+    toolexeclibdir='${toolexecdir}'/lib
+  else
+    toolexecdir='${libdir}'/gcc-lib/'$(target_alias)'
+    toolexeclibdir='${libdir}'
+  fi
+  if test x"$enable_multi_os_directory" != x"no"; then
+    multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
+    case $multi_os_directory in
+      .) ;; # Avoid trailing /.
+      ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+    esac
+  fi
+  AC_SUBST(toolexecdir)
+else
+  toolexeclibdir='${libdir}'
+fi
+AC_SUBST(toolexeclibdir)
+
+# Check linker support.
+LIBFFI_ENABLE_SYMVERS
+
+AC_CONFIG_COMMANDS(include, [test -d include || mkdir include])
+AC_CONFIG_COMMANDS(src, [
+test -d src || mkdir src
+test -d src/$TARGETDIR || mkdir src/$TARGETDIR
+], [TARGETDIR="$TARGETDIR"])
+
+AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile doc/Makefile libffi.pc)
+
+AC_OUTPUT
+
+# Copy this file instead of using AC_CONFIG_LINK in order to support
+# compiling with MSVC, which won't understand cygwin style symlinks.
+cp ${srcdir}/src/$TARGETDIR/ffitarget.h include/ffitarget.h

+ 287 - 0
libffi.mod/libffi/configure.host

@@ -0,0 +1,287 @@
+# 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*-*-*)
+	TARGET=AARCH64; TARGETDIR=aarch64
+	SOURCES="ffi.c 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 osf.S"
+	;;
+
+  arc*-*-*)
+	TARGET=ARC; TARGETDIR=arc
+	SOURCES="ffi.c arcompact.S"
+	;;
+
+  arm*-*-*)
+	TARGET=ARM; TARGETDIR=arm
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  avr32*-*-*)
+	TARGET=AVR32; TARGETDIR=avr32
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  bfin*)
+	TARGET=BFIN; TARGETDIR=bfin
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  cris-*-*)
+	TARGET=LIBFFI_CRIS; TARGETDIR=cris
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  frv-*-*)
+	TARGET=FRV; TARGETDIR=frv
+	SOURCES="ffi.c eabi.S"
+	;;
+
+  hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*)
+	TARGET=PA_LINUX; TARGETDIR=pa
+	SOURCES="ffi.c linux.S"
+	;;
+  hppa*64-*-hpux*)
+	TARGET=PA64_HPUX; TARGETDIR=pa
+	;;
+  hppa*-*-hpux*)
+	TARGET=PA_HPUX; TARGETDIR=pa
+	SOURCES="ffi.c hpux32.S"
+	;;
+
+  i?86-*-freebsd* | i?86-*-openbsd*)
+	TARGET=X86_FREEBSD; TARGETDIR=x86
+	;;
+
+  i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix* \
+  | x86_64-*-cygwin* | 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
+	  case "$host" in
+	    x86_64-*x32|x86_64-x32-*)
+	      TARGET_X32=yes
+	      TARGET=X86_64
+	      ;;
+	    *)
+	      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.*
+	      ;;
+          esac
+	else
+	  TARGET=X86_64;
+	fi
+	;;
+
+  ia64*-*-*)
+	TARGET=IA64; TARGETDIR=ia64
+	SOURCES="ffi.c unix.S"
+	;;
+
+  m32r*-*-*)
+	TARGET=M32R; TARGETDIR=m32r
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  m68k-*-*)
+	TARGET=M68K; TARGETDIR=m68k
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  m88k-*-*)
+	TARGET=M88K; TARGETDIR=m88k
+	SOURCES="ffi.c obsd.S"
+	;;
+
+  microblaze*-*-*)
+	TARGET=MICROBLAZE; TARGETDIR=microblaze
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  moxie-*-*)
+	TARGET=MOXIE; TARGETDIR=moxie
+	SOURCES="ffi.c eabi.S"
+	;;
+
+  metag-*-*)
+	TARGET=METAG; TARGETDIR=metag
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+  mips*-*linux* | mips*-*-openbsd*)
+	# Support 128-bit long double for NewABI.
+	HAVE_LONG_DOUBLE='defined(__mips64)'
+	TARGET=MIPS; TARGETDIR=mips
+	;;
+
+  nios2*-linux*)
+	TARGET=NIOS2; TARGETDIR=nios2
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  or1k*-linux*)
+	TARGET=OR1K; TARGETDIR=or1k
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  powerpc*-*-linux* | powerpc-*-sysv*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	HAVE_LONG_DOUBLE_VARIANT=1
+	;;
+  powerpc-*-amigaos*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-beos*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc-*-darwin* | powerpc64-*-darwin*)
+	TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
+	;;
+  powerpc-*-aix* | rs6000-*-aix*)
+	TARGET=POWERPC_AIX; TARGETDIR=powerpc
+	;;
+  powerpc-*-freebsd* | powerpc-*-openbsd* | powerpc-*-netbsd*)
+	TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
+	HAVE_LONG_DOUBLE_VARIANT=1
+	;;
+  powerpc64-*-freebsd*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+  powerpc*-*-rtems*)
+	TARGET=POWERPC; TARGETDIR=powerpc
+	;;
+
+  riscv*-*)
+	TARGET=RISCV; TARGETDIR=riscv
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  s390-*-* | s390x-*-*)
+	TARGET=S390; TARGETDIR=s390
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  sh-*-* | sh[34]*-*-*)
+	TARGET=SH; TARGETDIR=sh
+	SOURCES="ffi.c sysv.S"
+	;;
+  sh64-*-* | sh5*-*-*)
+	TARGET=SH64; TARGETDIR=sh64
+	SOURCES="ffi.c sysv.S"
+	;;
+
+  sparc*-*-*)
+	TARGET=SPARC; TARGETDIR=sparc
+	SOURCES="ffi.c ffi64.c v8.S v9.S"
+	;;
+
+  tile*-*)
+        TARGET=TILE; TARGETDIR=tile
+	SOURCES="ffi.c tile.S"
+        ;;
+
+  vax-*-*)
+	TARGET=VAX; TARGETDIR=vax
+	SOURCES="ffi.c elfbsd.S"
+	;;
+
+  xtensa*-*)
+	TARGET=XTENSA; TARGETDIR=xtensa
+	SOURCES="ffi.c sysv.S"
+	;;
+esac
+
+# ... but some of the cases above share configury.
+case "${TARGET}" in
+  MIPS)
+	SOURCES="ffi.c o32.S n32.S"
+	;;
+  POWERPC)
+	SOURCES="ffi.c ffi_sysv.c ffi_linux64.c sysv.S ppc_closure.S"
+	SOURCES="${SOURCES} linux64.S linux64_closure.S"
+	;;
+  POWERPC_AIX)
+	SOURCES="ffi_darwin.c aix.S aix_closure.S"
+	;;
+  POWERPC_DARWIN)
+	SOURCES="ffi_darwin.c darwin.S darwin_closure.S"
+	;;
+  POWERPC_FREEBSD)
+	SOURCES="ffi.c ffi_sysv.c sysv.S ppc_closure.S"
+	;;
+  X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32)
+	if test "$MSVC" = 1; then
+		SOURCES="ffi.c sysv_intel.S"
+	else
+		SOURCES="ffi.c sysv.S"
+	fi
+	;;
+  X86_64)
+	if test x"$TARGET_X32" = xyes; then
+		SOURCES="ffi64.c unix64.S"
+	else
+		SOURCES="ffi64.c unix64.S ffiw64.c win64.S"
+	fi
+	;;
+  X86_WIN64)
+	if test "$MSVC" = 1; then
+		SOURCES="ffiw64.c win64_intel.S"
+	else
+		SOURCES="ffiw64.c win64.S"
+	fi
+	;;
+esac
+
+# If we failed to configure SOURCES, we can't do anything.
+if test -z "${SOURCES}"; then
+  UNSUPPORTED=1
+fi

+ 3 - 0
libffi.mod/libffi/doc/Makefile.am

@@ -0,0 +1,3 @@
+## Process this with automake to create Makefile.in
+
+info_TEXINFOS = libffi.texi

+ 985 - 0
libffi.mod/libffi/doc/libffi.texi

@@ -0,0 +1,985 @@
+\input texinfo   @c -*-texinfo-*-
+@c %**start of header
+@setfilename libffi.info
+@settitle libffi
+@setchapternewpage off
+@c %**end of header
+
+@c Merge the standard indexes into a single one.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@include version.texi
+
+@copying
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+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.  A copy of the license is included in the
+section entitled ``GNU General Public License''.
+
+@end quotation
+@end copying
+
+@dircategory Development
+@direntry
+* libffi: (libffi).             Portable foreign-function interface library.
+@end direntry
+
+@titlepage
+@title Libffi
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+
+@ifnottex
+@node Top
+@top libffi
+
+@insertcopying
+
+@menu
+* Introduction::                What is libffi?
+* Using libffi::                How to use libffi.
+* Missing Features::            Things libffi can't do.
+* Index::                       Index.
+@end menu
+
+@end ifnottex
+
+
+@node Introduction
+@chapter What is libffi?
+
+Compilers for high level languages generate code that follow certain
+conventions.  These conventions are necessary, in part, for separate
+compilation to work.  One such convention is the @dfn{calling
+convention}.  The calling convention is a set of assumptions made by
+the compiler about where function arguments will be found on entry to
+a function.  A calling convention also specifies where the return
+value for a function is found.  The calling convention is also
+sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}.
+@cindex calling convention
+@cindex ABI
+@cindex Application Binary Interface
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function.  For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function.  @samp{Libffi} can be used in such programs to
+provide a bridge from the interpreter program to compiled code.
+
+The @samp{libffi} library provides a portable, high level programming
+interface to various calling conventions.  This allows a programmer to
+call any function specified by a call interface description at run
+time.
+
+@acronym{FFI} stands for Foreign Function Interface.  A foreign
+function interface is the popular name for the interface that allows
+code written in one language to call code written in another language.
+The @samp{libffi} library really only provides the lowest, machine
+dependent layer of a fully featured foreign function interface.  A
+layer must exist above @samp{libffi} that handles type conversions for
+values passed between the two languages.
+@cindex FFI
+@cindex Foreign Function Interface
+
+
+@node Using libffi
+@chapter Using libffi
+
+@menu
+* The Basics::                  The basic libffi API.
+* Simple Example::              A simple example.
+* Types::                       libffi type descriptions.
+* Multiple ABIs::               Different passing styles on one platform.
+* The Closure API::             Writing a generic function.
+* Closure Example::             A closure example.
+* Thread Safety::               Thread safety.
+@end menu
+
+
+@node The Basics
+@section The Basics
+
+@samp{Libffi} assumes that you have a pointer to the function you wish
+to call and that you know the number and types of arguments to pass
+it, as well as the return type of the function.
+
+The first thing you must do is create an @code{ffi_cif} object that
+matches the signature of the function you wish to call.  This is a
+separate step because it is common to make multiple calls using a
+single @code{ffi_cif}.  The @dfn{cif} in @code{ffi_cif} stands for
+Call InterFace.  To prepare a call interface object, use the function
+@code{ffi_prep_cif}.
+@cindex cif
+
+@findex ffi_prep_cif
+@defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
+This initializes @var{cif} according to the given parameters.
+
+@var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what
+you want.  @ref{Multiple ABIs} for more information.
+
+@var{nargs} is the number of arguments that this function accepts.
+
+@var{rtype} is a pointer to an @code{ffi_type} structure that
+describes the return type of the function.  @xref{Types}.
+
+@var{argtypes} is a vector of @code{ffi_type} pointers.
+@var{argtypes} must have @var{nargs} elements.  If @var{nargs} is 0,
+this argument is ignored.
+
+@code{ffi_prep_cif} returns a @code{libffi} status code, of type
+@code{ffi_status}.  This will be either @code{FFI_OK} if everything
+worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type}
+objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter
+is invalid.
+@end defun
+
+If the function being called is variadic (varargs) then
+@code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}.
+
+@findex ffi_prep_cif_var
+@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nfixedargs}, unsigned int @var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
+This initializes @var{cif} according to the given parameters for
+a call to a variadic function.  In general its operation is the
+same as for @code{ffi_prep_cif} except that:
+
+@var{nfixedargs} is the number of fixed arguments, prior to any
+variadic arguments.  It must be greater than zero.
+
+@var{ntotalargs} the total number of arguments, including variadic
+and fixed arguments.  @var{argtypes} must have this many elements.
+
+Note that, different cif's must be prepped for calls to the same
+function when different numbers of arguments are passed.
+
+Also note that a call to @code{ffi_prep_cif_var} with
+@var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to
+@code{ffi_prep_cif}.
+
+@end defun
+
+Note that the resulting @code{ffi_cif} holds pointers to all the
+@code{ffi_type} objects that were used during initialization.  You
+must ensure that these type objects have a lifetime at least as long
+as that of the @code{ffi_cif}.
+
+To call a function using an initialized @code{ffi_cif}, use the
+@code{ffi_call} function:
+
+@findex ffi_call
+@defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues})
+This calls the function @var{fn} according to the description given in
+@var{cif}.  @var{cif} must have already been prepared using
+@code{ffi_prep_cif}.
+
+@var{rvalue} is a pointer to a chunk of memory that will hold the
+result of the function call.  This must be large enough to hold the
+result, no smaller than the system register size (generally 32 or 64
+bits), and must be suitably aligned; it is the caller's responsibility
+to ensure this.  If @var{cif} declares that the function returns
+@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
+ignored.
+
+In most situations, @samp{libffi} will handle promotion according to
+the ABI.  However, for historical reasons, there is a special case
+with return values that must be handled by your code.  In particular,
+for integral (not @code{struct}) types that are narrower than the
+system register size, the return value will be widened by
+@samp{libffi}.  @samp{libffi} provides a type, @code{ffi_arg}, that
+can be used as the return type.  For example, if the CIF was defined
+with a return type of @code{char}, @samp{libffi} will try to store a
+full @code{ffi_arg} into the return value.
+
+@var{avalues} is a vector of @code{void *} pointers that point to the
+memory locations holding the argument values for a call.  If @var{cif}
+declares that the function has no arguments (i.e., @var{nargs} was 0),
+then @var{avalues} is ignored.  Note that argument values may be
+modified by the callee (for instance, structs passed by value); the
+burden of copying pass-by-value arguments is placed on the caller.
+
+Note that while the return value must be register-sized, arguments
+should exactly match their declared type.  For example, if an argument
+is a @code{short}, then the entry in @var{avalues} should point to an
+object declared as @code{short}; but if the return type is
+@code{short}, then @var{rvalue} should point to an object declared as
+a larger type -- usually @code{ffi_arg}.
+@end defun
+
+
+@node Simple Example
+@section Simple Example
+
+Here is a trivial example that calls @code{puts} a few times.
+
+@example
+#include <stdio.h>
+#include <ffi.h>
+
+int main()
+@{
+  ffi_cif cif;
+  ffi_type *args[1];
+  void *values[1];
+  char *s;
+  ffi_arg rc;
+  
+  /* Initialize the argument info vectors */    
+  args[0] = &ffi_type_pointer;
+  values[0] = &s;
+  
+  /* Initialize the cif */
+  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
+		       &ffi_type_sint, args) == FFI_OK)
+    @{
+      s = "Hello World!";
+      ffi_call(&cif, puts, &rc, values);
+      /* rc now holds the result of the call to puts */
+      
+      /* values holds a pointer to the function's arg, so to 
+         call puts() again all we need to do is change the 
+         value of s */
+      s = "This is cool!";
+      ffi_call(&cif, puts, &rc, values);
+    @}
+  
+  return 0;
+@}
+@end example
+
+
+@node Types
+@section Types
+
+@menu
+* Primitive Types::             Built-in types.
+* Structures::                  Structure types.
+* Size and Alignment::          Size and alignment of types.
+* Arrays Unions Enums::         Arrays, unions, and enumerations.
+* Type Example::                Structure type example.
+* Complex::                     Complex types.
+* Complex Type Example::        Complex type example.
+@end menu
+
+@node Primitive Types
+@subsection Primitive Types
+
+@code{Libffi} provides a number of built-in type descriptors that can
+be used to describe argument and return types:
+
+@table @code
+@item ffi_type_void
+@tindex ffi_type_void
+The type @code{void}.  This cannot be used for argument types, only
+for return values.
+
+@item ffi_type_uint8
+@tindex ffi_type_uint8
+An unsigned, 8-bit integer type.
+
+@item ffi_type_sint8
+@tindex ffi_type_sint8
+A signed, 8-bit integer type.
+
+@item ffi_type_uint16
+@tindex ffi_type_uint16
+An unsigned, 16-bit integer type.
+
+@item ffi_type_sint16
+@tindex ffi_type_sint16
+A signed, 16-bit integer type.
+
+@item ffi_type_uint32
+@tindex ffi_type_uint32
+An unsigned, 32-bit integer type.
+
+@item ffi_type_sint32
+@tindex ffi_type_sint32
+A signed, 32-bit integer type.
+
+@item ffi_type_uint64
+@tindex ffi_type_uint64
+An unsigned, 64-bit integer type.
+
+@item ffi_type_sint64
+@tindex ffi_type_sint64
+A signed, 64-bit integer type.
+
+@item ffi_type_float
+@tindex ffi_type_float
+The C @code{float} type.
+
+@item ffi_type_double
+@tindex ffi_type_double
+The C @code{double} type.
+
+@item ffi_type_uchar
+@tindex ffi_type_uchar
+The C @code{unsigned char} type.
+
+@item ffi_type_schar
+@tindex ffi_type_schar
+The C @code{signed char} type.  (Note that there is not an exact
+equivalent to the C @code{char} type in @code{libffi}; ordinarily you
+should either use @code{ffi_type_schar} or @code{ffi_type_uchar}
+depending on whether @code{char} is signed.)
+
+@item ffi_type_ushort
+@tindex ffi_type_ushort
+The C @code{unsigned short} type.
+
+@item ffi_type_sshort
+@tindex ffi_type_sshort
+The C @code{short} type.
+
+@item ffi_type_uint
+@tindex ffi_type_uint
+The C @code{unsigned int} type.
+
+@item ffi_type_sint
+@tindex ffi_type_sint
+The C @code{int} type.
+
+@item ffi_type_ulong
+@tindex ffi_type_ulong
+The C @code{unsigned long} type.
+
+@item ffi_type_slong
+@tindex ffi_type_slong
+The C @code{long} type.
+
+@item ffi_type_longdouble
+@tindex ffi_type_longdouble
+On platforms that have a C @code{long double} type, this is defined.
+On other platforms, it is not.
+
+@item ffi_type_pointer
+@tindex ffi_type_pointer
+A generic @code{void *} pointer.  You should use this for all
+pointers, regardless of their real type.
+
+@item ffi_type_complex_float
+@tindex ffi_type_complex_float
+The C @code{_Complex float} type.
+
+@item ffi_type_complex_double
+@tindex ffi_type_complex_double
+The C @code{_Complex double} type.
+
+@item ffi_type_complex_longdouble
+@tindex ffi_type_complex_longdouble
+The C @code{_Complex long double} type.
+On platforms that have a C @code{long double} type, this is defined.
+On other platforms, it is not.
+@end table
+
+Each of these is of type @code{ffi_type}, so you must take the address
+when passing to @code{ffi_prep_cif}.
+
+
+@node Structures
+@subsection Structures
+
+@samp{libffi} is perfectly happy passing structures back and forth.
+You must first describe the structure to @samp{libffi} by creating a
+new @code{ffi_type} object for it.
+
+@tindex ffi_type
+@deftp {Data type} ffi_type
+The @code{ffi_type} has the following members:
+@table @code
+@item size_t size
+This is set by @code{libffi}; you should initialize it to zero.
+
+@item unsigned short alignment
+This is set by @code{libffi}; you should initialize it to zero.
+
+@item unsigned short type
+For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
+
+@item ffi_type **elements
+This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
+objects.  There is one element per field of the struct.
+
+Note that @samp{libffi} has no special support for bit-fields.  You
+must manage these manually.
+@end table
+@end deftp
+
+The @code{size} and @code{alignment} fields will be filled in by
+@code{ffi_prep_cif} or @code{ffi_prep_cif_var}, as needed.
+
+@node Size and Alignment
+@subsection Size and Alignment
+
+@code{libffi} will set the @code{size} and @code{alignment} fields of
+an @code{ffi_type} object for you.  It does so using its knowledge of
+the ABI.
+
+You might expect that you can simply read these fields for a type that
+has been laid out by @code{libffi}.  However, there are some caveats.
+
+@itemize @bullet
+@item
+The size or alignment of some of the built-in types may vary depending
+on the chosen ABI.
+
+@item
+The size and alignment of a new structure type will not be set by
+@code{libffi} until it has been passed to @code{ffi_prep_cif} or
+@code{ffi_get_struct_offsets}.
+
+@item
+A structure type cannot be shared across ABIs.  Instead each ABI needs
+its own copy of the structure type.
+@end itemize
+
+So, before examining these fields, it is safest to pass the
+@code{ffi_type} object to @code{ffi_prep_cif} or
+@code{ffi_get_struct_offsets} first.  This function will do all the
+needed setup.
+
+@example
+ffi_type *desired_type;
+ffi_abi desired_abi;
+@dots{}
+ffi_cif cif;
+if (ffi_prep_cif (&cif, desired_abi, 0, desired_type, NULL) == FFI_OK)
+  @{
+    size_t size = desired_type->size;
+    unsigned short alignment = desired_type->alignment;
+  @}
+@end example
+
+@code{libffi} also provides a way to get the offsets of the members of
+a structure.
+
+@findex ffi_get_struct_offsets
+@defun ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, size_t *offsets)
+Compute the offset of each element of the given structure type.
+@var{abi} is the ABI to use; this is needed because in some cases the
+layout depends on the ABI.
+
+@var{offsets} is an out parameter.  The caller is responsible for
+providing enough space for all the results to be written -- one
+element per element type in @var{struct_type}.  If @var{offsets} is
+@code{NULL}, then the type will be laid out but not otherwise
+modified.  This can be useful for accessing the type's size or layout,
+as mentioned above.
+
+This function returns @code{FFI_OK} on success; @code{FFI_BAD_ABI} if
+@var{abi} is invalid; or @code{FFI_BAD_TYPEDEF} if @var{struct_type}
+is invalid in some way.  Note that only @code{FFI_STRUCT} types are
+valid here.
+@end defun
+
+@node Arrays Unions Enums
+@subsection Arrays, Unions, and Enumerations
+
+@subsubsection Arrays
+
+@samp{libffi} does not have direct support for arrays or unions.
+However, they can be emulated using structures.
+
+To emulate an array, simply create an @code{ffi_type} using
+@code{FFI_TYPE_STRUCT} with as many members as there are elements in
+the array.
+
+@example
+ffi_type array_type;
+ffi_type **elements
+int i;
+
+elements = malloc ((n + 1) * sizeof (ffi_type *));
+for (i = 0; i < n; ++i)
+  elements[i] = array_element_type;
+elements[n] = NULL;
+
+array_type.size = array_type.alignment = 0;
+array_type.type = FFI_TYPE_STRUCT;
+array_type.elements = elements;
+@end example
+
+Note that arrays cannot be passed or returned by value in C --
+structure types created like this should only be used to refer to
+members of real @code{FFI_TYPE_STRUCT} objects.
+
+However, a phony array type like this will not cause any errors from
+@samp{libffi} if you use it as an argument or return type.  This may
+be confusing.
+
+@subsubsection Unions
+
+A union can also be emulated using @code{FFI_TYPE_STRUCT}.  In this
+case, however, you must make sure that the size and alignment match
+the real requirements of the union.
+
+One simple way to do this is to ensue that each element type is laid
+out.  Then, give the new structure type a single element; the size of
+the largest element; and the largest alignment seen as well.
+
+This example uses the @code{ffi_prep_cif} trick to ensure that each
+element type is laid out.
+
+@example
+ffi_abi desired_abi;
+ffi_type union_type;
+ffi_type **union_elements;
+
+int i;
+ffi_type element_types[2];
+
+element_types[1] = NULL;
+
+union_type.size = union_type.alignment = 0;
+union_type.type = FFI_TYPE_STRUCT;
+union_type.elements = element_types;
+
+for (i = 0; union_elements[i]; ++i)
+  @{
+    ffi_cif cif;
+    if (ffi_prep_cif (&cif, desired_abi, 0, union_elements[i], NULL) == FFI_OK)
+      @{
+        if (union_elements[i]->size > union_type.size)
+          @{
+            union_type.size = union_elements[i];
+            size = union_elements[i]->size;
+          @}
+        if (union_elements[i]->alignment > union_type.alignment)
+          union_type.alignment = union_elements[i]->alignment;
+      @}
+  @}
+@end example
+
+@subsubsection Enumerations
+
+@code{libffi} does not have any special support for C @code{enum}s.
+Although any given @code{enum} is implemented using a specific
+underlying integral type, exactly which type will be used cannot be
+determined by @code{libffi} -- it may depend on the values in the
+enumeration or on compiler flags such as @option{-fshort-enums}.
+@xref{Structures unions enumerations and bit-fields implementation, , , gcc},
+for more information about how GCC handles enumerations.
+
+@node Type Example
+@subsection Type Example
+
+The following example initializes a @code{ffi_type} object
+representing the @code{tm} struct from Linux's @file{time.h}.
+
+Here is how the struct is defined:
+
+@example
+struct tm @{
+    int tm_sec;
+    int tm_min;
+    int tm_hour;
+    int tm_mday;
+    int tm_mon;
+    int tm_year;
+    int tm_wday;
+    int tm_yday;
+    int tm_isdst;
+    /* Those are for future use. */
+    long int __tm_gmtoff__;
+    __const char *__tm_zone__;
+@};
+@end example
+
+Here is the corresponding code to describe this struct to
+@code{libffi}:
+
+@example
+    @{
+      ffi_type tm_type;
+      ffi_type *tm_type_elements[12];
+      int i;
+
+      tm_type.size = tm_type.alignment = 0;
+      tm_type.type = FFI_TYPE_STRUCT;
+      tm_type.elements = &tm_type_elements;
+    
+      for (i = 0; i < 9; i++)
+          tm_type_elements[i] = &ffi_type_sint;
+
+      tm_type_elements[9] = &ffi_type_slong;
+      tm_type_elements[10] = &ffi_type_pointer;
+      tm_type_elements[11] = NULL;
+
+      /* tm_type can now be used to represent tm argument types and
+	 return types for ffi_prep_cif() */
+    @}
+@end example
+
+@node Complex
+@subsection Complex Types
+
+@samp{libffi} supports the complex types defined by the C99
+standard (@code{_Complex float}, @code{_Complex double} and
+@code{_Complex long double} with the built-in type descriptors
+@code{ffi_type_complex_float}, @code{ffi_type_complex_double} and
+@code{ffi_type_complex_longdouble}.
+
+Custom complex types like @code{_Complex int} can also be used.
+An @code{ffi_type} object has to be defined to describe the
+complex type to @samp{libffi}.
+
+@tindex ffi_type
+@deftp {Data type} ffi_type
+@table @code
+@item size_t size
+This must be manually set to the size of the complex type.
+
+@item unsigned short alignment
+This must be manually set to the alignment of the complex type.
+
+@item unsigned short type
+For a complex type, this must be set to @code{FFI_TYPE_COMPLEX}.
+
+@item ffi_type **elements
+
+This is a @samp{NULL}-terminated array of pointers to
+@code{ffi_type} objects.  The first element is set to the
+@code{ffi_type} of the complex's base type.  The second element
+must be set to @code{NULL}.
+@end table
+@end deftp
+
+The section @ref{Complex Type Example} shows a way to determine
+the @code{size} and @code{alignment} members in a platform
+independent way.
+
+For platforms that have no complex support in @code{libffi} yet,
+the functions @code{ffi_prep_cif} and @code{ffi_prep_args} abort
+the program if they encounter a complex type.
+
+@node Complex Type Example
+@subsection Complex Type Example
+
+This example demonstrates how to use complex types:
+
+@example
+#include <stdio.h>
+#include <ffi.h>
+#include <complex.h>
+
+void complex_fn(_Complex float cf,
+                _Complex double cd,
+                _Complex long double cld)
+@{
+  printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n",
+         (float)creal (cf), (float)cimag (cf),
+         (float)creal (cd), (float)cimag (cd),
+         (float)creal (cld), (float)cimag (cld));
+@}
+
+int main()
+@{
+  ffi_cif cif;
+  ffi_type *args[3];
+  void *values[3];
+  _Complex float cf;
+  _Complex double cd;
+  _Complex long double cld;
+
+  /* Initialize the argument info vectors */
+  args[0] = &ffi_type_complex_float;
+  args[1] = &ffi_type_complex_double;
+  args[2] = &ffi_type_complex_longdouble;
+  values[0] = &cf;
+  values[1] = &cd;
+  values[2] = &cld;
+
+  /* Initialize the cif */
+  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
+                   &ffi_type_void, args) == FFI_OK)
+    @{
+      cf = 1.0 + 20.0 * I;
+      cd = 300.0 + 4000.0 * I;
+      cld = 50000.0 + 600000.0 * I;
+      /* Call the function */
+      ffi_call(&cif, (void (*)(void))complex_fn, 0, values);
+    @}
+
+  return 0;
+@}
+@end example
+
+This is an example for defining a custom complex type descriptor
+for compilers that support them:
+
+@example
+/*
+ * This macro can be used to define new complex type descriptors
+ * in a platform independent way.
+ *
+ * name: Name of the new descriptor is ffi_type_complex_<name>.
+ * type: The C base type of the complex type.
+ */
+#define FFI_COMPLEX_TYPEDEF(name, type, ffitype)             \
+  static ffi_type *ffi_elements_complex_##name [2] = @{      \
+    (ffi_type *)(&ffitype), NULL                             \
+  @};                                                        \
+  struct struct_align_complex_##name @{                      \
+    char c;                                                  \
+    _Complex type x;                                         \
+  @};                                                        \
+  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                 \
+  @}
+
+/* Define new complex type descriptors using the macro: */
+/* ffi_type_complex_sint */
+FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint);
+/* ffi_type_complex_uchar */
+FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8);
+@end example
+
+The new type descriptors can then be used like one of the built-in
+type descriptors in the previous example.
+
+@node Multiple ABIs
+@section Multiple ABIs
+
+A given platform may provide multiple different ABIs at once.  For
+instance, the x86 platform has both @samp{stdcall} and @samp{fastcall}
+functions.
+
+@code{libffi} provides some support for this.  However, this is
+necessarily platform-specific.
+
+@c FIXME: document the platforms
+
+@node The Closure API
+@section The Closure API
+
+@code{libffi} also provides a way to write a generic function -- a
+function that can accept and decode any combination of arguments.
+This can be useful when writing an interpreter, or to provide wrappers
+for arbitrary functions.
+
+This facility is called the @dfn{closure API}.  Closures are not
+supported on all platforms; you can check the @code{FFI_CLOSURES}
+define to determine whether they are supported on the current
+platform.
+@cindex closures
+@cindex closure API
+@findex FFI_CLOSURES
+
+Because closures work by assembling a tiny function at runtime, they
+require special allocation on platforms that have a non-executable
+heap.  Memory management for closures is handled by a pair of
+functions:
+
+@findex ffi_closure_alloc
+@defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code})
+Allocate a chunk of memory holding @var{size} bytes.  This returns a
+pointer to the writable address, and sets *@var{code} to the
+corresponding executable address.
+
+@var{size} should be sufficient to hold a @code{ffi_closure} object.
+@end defun
+
+@findex ffi_closure_free
+@defun void ffi_closure_free (void *@var{writable})
+Free memory allocated using @code{ffi_closure_alloc}.  The argument is
+the writable address that was returned.
+@end defun
+
+
+Once you have allocated the memory for a closure, you must construct a
+@code{ffi_cif} describing the function call.  Finally you can prepare
+the closure function:
+
+@findex ffi_prep_closure_loc
+@defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
+Prepare a closure function.  The arguments to
+@code{ffi_prep_closure_loc} are:
+
+@table @var
+@item closure
+The address of a @code{ffi_closure} object; this is the writable
+address returned by @code{ffi_closure_alloc}.
+
+@item cif
+The @code{ffi_cif} describing the function parameters.  Note that this
+object, and the types to which it refers, must be kept alive until the
+closure itself is freed.
+
+@item user_data
+An arbitrary datum that is passed, uninterpreted, to your closure
+function.
+
+@item codeloc
+The executable address returned by @code{ffi_closure_alloc}.
+
+@item fun
+The function which will be called when the closure is invoked.  It is
+called with the arguments:
+
+@table @var
+@item cif
+The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
+
+@item ret
+A pointer to the memory used for the function's return value.
+
+If the function is declared as returning @code{void}, then this value
+is garbage and should not be used.
+
+Otherwise, @var{fun} must fill the object to which this points,
+following the same special promotion behavior as @code{ffi_call}.
+That is, in most cases, @var{ret} points to an object of exactly the
+size of the type specified when @var{cif} was constructed.  However,
+integral types narrower than the system register size are widened.  In
+these cases your program may assume that @var{ret} points to an
+@code{ffi_arg} object.
+
+@item args
+A vector of pointers to memory holding the arguments to the function.
+
+@item user_data
+The same @var{user_data} that was passed to
+@code{ffi_prep_closure_loc}.
+@end table
+@end table
+
+@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
+went ok, and one of the other @code{ffi_status} values on error.
+
+After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
+to the appropriate pointer-to-function type.
+@end defun
+
+You may see old code referring to @code{ffi_prep_closure}.  This
+function is deprecated, as it cannot handle the need for separate
+writable and executable addresses.
+
+@node Closure Example
+@section Closure Example
+
+A trivial example that creates a new @code{puts} by binding 
+@code{fputs} with @code{stdout}.
+
+@example
+#include <stdio.h>
+#include <ffi.h>
+
+/* Acts like puts with the file given at time of enclosure. */
+void puts_binding(ffi_cif *cif, void *ret, void* args[],
+                  void *stream)
+@{
+  *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream);
+@}
+
+typedef int (*puts_t)(char *);
+
+int main()
+@{
+  ffi_cif cif;
+  ffi_type *args[1];
+  ffi_closure *closure;
+
+  void *bound_puts;
+  int rc;
+
+  /* Allocate closure and bound_puts */
+  closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
+
+  if (closure)
+    @{
+      /* Initialize the argument info vectors */
+      args[0] = &ffi_type_pointer;
+
+      /* Initialize the cif */
+      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+                       &ffi_type_sint, args) == FFI_OK)
+        @{
+          /* Initialize the closure, setting stream to stdout */
+          if (ffi_prep_closure_loc(closure, &cif, puts_binding,
+                                   stdout, bound_puts) == FFI_OK)
+            @{
+              rc = ((puts_t)bound_puts)("Hello World!");
+              /* rc now holds the result of the call to fputs */
+            @}
+        @}
+    @}
+
+  /* Deallocate both closure, and bound_puts */
+  ffi_closure_free(closure);
+
+  return 0;
+@}
+
+@end example
+
+@node Thread Safety
+@section Thread Safety
+
+@code{libffi} is not completely thread-safe.  However, many parts are,
+and if you follow some simple rules, you can use it safely in a
+multi-threaded program.
+
+@itemize @bullet
+@item
+@code{ffi_prep_cif} may modify the @code{ffi_type} objects passed to
+it.  It is best to ensure that only a single thread prepares a given
+@code{ffi_cif} at a time.
+
+@item
+On some platforms, @code{ffi_prep_cif} may modify the size and
+alignment of some types, depending on the chosen ABI.  On these
+platforms, if you switch between ABIs, you must ensure that there is
+only one call to @code{ffi_prep_cif} at a time.
+
+Currently the only affected platform is PowerPC and the only affected
+type is @code{long double}.
+@end itemize
+
+@node Missing Features
+@chapter Missing Features
+
+@code{libffi} is missing a few features.  We welcome patches to add
+support for these.
+
+@itemize @bullet
+@item
+Variadic closures.
+
+@item
+There is no support for bit fields in structures.
+
+@item
+The ``raw'' API is undocumented.
+@c anything else?
+
+@item
+The Go API is undocumented.
+@end itemize
+
+Note that variadic support is very new and tested on a relatively
+small number of platforms.
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye

+ 4 - 0
libffi.mod/libffi/doc/version.texi

@@ -0,0 +1,4 @@
+@set UPDATED 2 April 2018
+@set UPDATED-MONTH April 2018
+@set EDITION 3.3-rc0
+@set VERSION 3.3-rc0

+ 203 - 0
libffi.mod/libffi/generate-darwin-source-and-headers.py

@@ -0,0 +1,203 @@
+#!/usr/bin/env python
+import subprocess
+import os
+import errno
+import collections
+import glob
+import argparse
+
+class Platform(object):
+    pass
+
+class simulator_platform(Platform):
+    directory = 'darwin_ios'
+    sdk = 'iphonesimulator'
+    arch = 'i386'
+    triple = 'i386-apple-darwin11'
+    version_min = '-miphoneos-version-min=7.0'
+
+    prefix = "#ifdef __i386__\n\n"
+    suffix = "\n\n#endif"
+    src_dir = 'x86'
+    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+
+
+class simulator64_platform(Platform):
+    directory = 'darwin_ios'
+    sdk = 'iphonesimulator'
+    arch = 'x86_64'
+    triple = 'x86_64-apple-darwin13'
+    version_min = '-miphoneos-version-min=7.0'
+
+    prefix = "#ifdef __x86_64__\n\n"
+    suffix = "\n\n#endif"
+    src_dir = 'x86'
+    src_files = ['unix64.S', 'ffi64.c', 'ffiw64.c', 'win64.S', 'internal64.h', 'asmnames.h']
+
+
+class device_platform(Platform):
+    directory = 'darwin_ios'
+    sdk = 'iphoneos'
+    arch = 'armv7'
+    triple = 'arm-apple-darwin11'
+    version_min = '-miphoneos-version-min=7.0'
+
+    prefix = "#ifdef __arm__\n\n"
+    suffix = "\n\n#endif"
+    src_dir = 'arm'
+    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+
+
+class device64_platform(Platform):
+    directory = 'darwin_ios'
+    sdk = 'iphoneos'
+    arch = 'arm64'
+    triple = 'aarch64-apple-darwin13'
+    version_min = '-miphoneos-version-min=7.0'
+
+    prefix = "#ifdef __arm64__\n\n"
+    suffix = "\n\n#endif"
+    src_dir = 'aarch64'
+    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+
+
+class desktop32_platform(Platform):
+    directory = 'darwin_osx'
+    sdk = 'macosx'
+    arch = 'i386'
+    triple = 'i386-apple-darwin10'
+    version_min = '-mmacosx-version-min=10.6'
+    src_dir = 'x86'
+    src_files = ['sysv.S', 'ffi.c', 'internal.h']
+
+    prefix = "#ifdef __i386__\n\n"
+    suffix = "\n\n#endif"
+
+
+class desktop64_platform(Platform):
+    directory = 'darwin_osx'
+    sdk = 'macosx'
+    arch = 'x86_64'
+    triple = 'x86_64-apple-darwin10'
+    version_min = '-mmacosx-version-min=10.6'
+
+    prefix = "#ifdef __x86_64__\n\n"
+    suffix = "\n\n#endif"
+    src_dir = 'x86'
+    src_files = ['unix64.S', 'ffi64.c', 'ffiw64.c', 'win64.S', 'internal64.h', 'asmnames.h']
+
+
+def mkdir_p(path):
+    try:
+        os.makedirs(path)
+    except OSError as exc:  # Python >2.5
+        if exc.errno != errno.EEXIST:
+            raise
+
+
+def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
+    mkdir_p(dst_dir)
+    out_filename = filename
+
+    if file_suffix:
+        if filename in ['internal64.h', 'asmnames.h', 'internal.h']:
+            out_filename = filename
+        else:
+            split_name = os.path.splitext(filename)
+            out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1])
+
+    with open(os.path.join(src_dir, filename)) as in_file:
+        with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
+            if prefix:
+                out_file.write(prefix)
+
+            out_file.write(in_file.read())
+
+            if suffix:
+                out_file.write(suffix)
+
+
+def list_files(src_dir, pattern=None, filelist=None):
+    if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern))
+    for file in filelist:
+        yield os.path.basename(file)
+
+
+def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None):
+    for filename in list_files(src_dir, pattern=pattern, filelist=filelist):
+        move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix)
+
+
+def copy_src_platform_files(platform):
+    src_dir = os.path.join('src', platform.src_dir)
+    dst_dir = os.path.join(platform.directory, 'src', platform.src_dir)
+    copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix)
+
+
+def build_target(platform, platform_headers):
+    def xcrun_cmd(cmd):
+        return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch)
+
+    tag='%s-%s' % (platform.sdk, platform.arch)
+    build_dir = 'build_%s' % tag
+    mkdir_p(build_dir)
+    env = dict(CC=xcrun_cmd('clang'),
+               LD=xcrun_cmd('ld'),
+               CFLAGS='%s' % (platform.version_min))
+    working_dir = os.getcwd()
+    try:
+        os.chdir(build_dir)
+        subprocess.check_call(['../configure', '-host', platform.triple], env=env)
+    finally:
+        os.chdir(working_dir)
+
+    for src_dir in [build_dir, os.path.join(build_dir, 'include')]:
+        copy_files(src_dir,
+                   os.path.join(platform.directory, 'include'),
+                   pattern='*.h',
+                   file_suffix=platform.arch,
+                   prefix=platform.prefix,
+                   suffix=platform.suffix)
+
+        for filename in list_files(src_dir, pattern='*.h'):
+            platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix))
+
+
+def generate_source_and_headers(generate_osx=True, generate_ios=True):
+    copy_files('src', 'darwin_common/src', pattern='*.c')
+    copy_files('include', 'darwin_common/include', pattern='*.h')
+
+    if generate_ios:
+        copy_src_platform_files(simulator_platform)
+        copy_src_platform_files(simulator64_platform)
+        copy_src_platform_files(device_platform)
+        copy_src_platform_files(device64_platform)
+    if generate_osx:
+        copy_src_platform_files(desktop32_platform)
+        copy_src_platform_files(desktop64_platform)
+
+    platform_headers = collections.defaultdict(set)
+
+    if generate_ios:
+        build_target(simulator_platform, platform_headers)
+        build_target(simulator64_platform, platform_headers)
+        build_target(device_platform, platform_headers)
+        build_target(device64_platform, platform_headers)
+    if generate_osx:
+        build_target(desktop32_platform, platform_headers)
+        build_target(desktop64_platform, platform_headers)
+
+    mkdir_p('darwin_common/include')
+    for header_name, tag_tuples in platform_headers.iteritems():
+        basename, suffix = os.path.splitext(header_name)
+        with open(os.path.join('darwin_common/include', header_name), 'w') as header:
+            for tag_tuple in tag_tuples:
+                header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2]))
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--only-ios', action='store_true', default=False)
+    parser.add_argument('--only-osx', action='store_true', default=False)
+    args = parser.parse_args()
+
+    generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx)

+ 9 - 0
libffi.mod/libffi/include/Makefile.am

@@ -0,0 +1,9 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS=foreign
+
+DISTCLEANFILES=ffitarget.h
+noinst_HEADERS=ffi_common.h ffi_cfi.h
+EXTRA_DIST=ffi.h.in
+
+nodist_include_HEADERS = ffi.h ffitarget.h

+ 515 - 0
libffi.mod/libffi/include/ffi.h.in

@@ -0,0 +1,515 @@
+/* -----------------------------------------------------------------*-C-*-
+   libffi @VERSION@ - Copyright (c) 2011, 2014 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 --------------------------------- */
+
+#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
+# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
+#  define FFI_API __declspec(dllexport)
+# elif !defined FFI_BUILDING  /* Importing libffi.DLL */
+#  define FFI_API __declspec(dllimport)
+# else                        /* Building/linking static library */
+#  define FFI_API
+# 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;
+
+#if @HAVE_LONG_DOUBLE@
+FFI_EXTERN ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+FFI_EXTERN ffi_type ffi_type_complex_float;
+FFI_EXTERN ffi_type ffi_type_complex_double;
+#if @HAVE_LONG_DOUBLE@
+FFI_EXTERN ffi_type ffi_type_complex_longdouble;
+#else
+#define ffi_type_complex_longdouble ffi_type_complex_double
+#endif
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+  FFI_OK = 0,
+  FFI_BAD_TYPEDEF,
+  FFI_BAD_ABI
+} 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);
+#endif
+
+FFI_API
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+FFI_API
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+FFI_API
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- 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
+  char tramp[FFI_TRAMPOLINE_SIZE];
+#endif
+  ffi_cif   *cif;
+  void     (*fun)(ffi_cif*,void*,void**,void*);
+  void      *user_data;
+} 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 transaltion, void** -> ffi_raw*.  */
+
+  void     (*translate_args)(ffi_cif*,void*,void**,void*);
+  void      *this_closure;
+
+#endif
+
+  void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+  void      *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+#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);
+
+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);
+#endif
+
+#endif /* FFI_CLOSURES */
+
+#if 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);
+
+/* Useful for eliminating compiler warnings.  */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID       0    
+#define FFI_TYPE_INT        1
+#define FFI_TYPE_FLOAT      2    
+#define FFI_TYPE_DOUBLE     3
+#if @HAVE_LONG_DOUBLE@
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8      5   
+#define FFI_TYPE_SINT8      6
+#define FFI_TYPE_UINT16     7 
+#define FFI_TYPE_SINT16     8
+#define FFI_TYPE_UINT32     9
+#define FFI_TYPE_SINT32     10
+#define FFI_TYPE_UINT64     11
+#define FFI_TYPE_SINT64     12
+#define FFI_TYPE_STRUCT     13
+#define FFI_TYPE_POINTER    14
+#define FFI_TYPE_COMPLEX    15
+
+/* This should always refer to the last type code (for sanity checks).  */
+#define FFI_TYPE_LAST       FFI_TYPE_COMPLEX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 55 - 0
libffi.mod/libffi/include/ffi_cfi.h

@@ -0,0 +1,55 @@
+/* -----------------------------------------------------------------------
+   ffi_cfi.h - Copyright (c) 2014  Red Hat, Inc.
+
+   Conditionally assemble cfi directives. Only necessary for building libffi.
+   ----------------------------------------------------------------------- */
+
+#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__
+
+#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(...)
+
+#endif /* HAVE_AS_CFI_PSEUDO_OP */
+#endif /* FFI_CFI_H */

+ 153 - 0
libffi.mod/libffi/include/ffi_common.h

@@ -0,0 +1,153 @@
+/* -----------------------------------------------------------------------
+   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.
+   ----------------------------------------------------------------------- */
+
+#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__))
+#else
+# define MAYBE_UNUSED
+# 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
+
+#ifdef FFI_DEBUG
+void ffi_assert(char *expr, char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(ffi_type *a, 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;
+
+/* 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

+ 80 - 0
libffi.mod/libffi/libffi.map.in

@@ -0,0 +1,80 @@
+#define LIBFFI_ASM
+#define LIBFFI_H
+#include <fficonfig.h>
+#include <ffitarget.h>
+
+/* These version numbers correspond to the libtool-version abi numbers,
+   not to the libffi release numbers.  */
+
+LIBFFI_BASE_7.0 {
+  global:
+	/* Exported data variables.  */
+	ffi_type_void;
+	ffi_type_uint8;
+	ffi_type_sint8;
+	ffi_type_uint16;
+	ffi_type_sint16;
+	ffi_type_uint32;
+	ffi_type_sint32;
+	ffi_type_uint64;
+	ffi_type_sint64;
+	ffi_type_float;
+	ffi_type_double;
+	ffi_type_longdouble;
+	ffi_type_pointer;
+
+	/* Exported functions.  */
+	ffi_call;
+	ffi_prep_cif;
+	ffi_prep_cif_var;
+
+	ffi_raw_call;
+	ffi_ptrarray_to_raw;
+	ffi_raw_to_ptrarray;
+	ffi_raw_size;
+
+	ffi_java_raw_call;
+	ffi_java_ptrarray_to_raw;
+	ffi_java_raw_to_ptrarray;
+	ffi_java_raw_size;
+
+  local:
+	*;
+};
+
+LIBFFI_BASE_7.1 {
+  global:
+	ffi_get_struct_offsets;
+} LIBFFI_BASE_7.0;
+
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+LIBFFI_COMPLEX_7.0 {
+  global:
+	/* Exported data variables.  */
+	ffi_type_complex_float;
+	ffi_type_complex_double;
+	ffi_type_complex_longdouble;
+} LIBFFI_BASE_7.0;
+#endif
+
+#if FFI_CLOSURES
+LIBFFI_CLOSURE_7.0 {
+  global:
+	ffi_closure_alloc;
+	ffi_closure_free;
+	ffi_prep_closure;
+	ffi_prep_closure_loc;
+	ffi_prep_raw_closure;
+	ffi_prep_raw_closure_loc;
+	ffi_prep_java_raw_closure;
+	ffi_prep_java_raw_closure_loc;
+} LIBFFI_BASE_7.0;
+#endif
+
+#if FFI_GO_CLOSURES
+LIBFFI_GO_CLOSURE_7.0 {
+  global:
+	ffi_call_go;
+	ffi_prep_go_closure;
+} LIBFFI_CLOSURE_7.0;
+#endif

+ 11 - 0
libffi.mod/libffi/libffi.pc.in

@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+toolexeclibdir=@toolexeclibdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Description: Library supporting Foreign Function Interfaces
+Version: @PACKAGE_VERSION@
+Libs: -L${toolexeclibdir} -lffi
+Cflags: -I${includedir}

+ 1043 - 0
libffi.mod/libffi/libffi.xcodeproj/project.pbxproj

@@ -0,0 +1,1043 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		43B5D3F81D35473200D1E1FD /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */; };
+		43B5D3FA1D3547CE00D1E1FD /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */; };
+		43E9A5C71D352C1500926A8F /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C51D352C1500926A8F /* sysv_i386.S */; };
+		43E9A5C81D352C1500926A8F /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C61D352C1500926A8F /* unix64_x86_64.S */; };
+		DBFA714A187F1D8600A76262 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
+		DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713F187F1D8600A76262 /* ffi_common.h */; };
+		DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7140187F1D8600A76262 /* fficonfig.h */; };
+		DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
+		DBFA714E187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; };
+		DBFA714F187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; };
+		DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; };
+		DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; };
+		DBFA7158187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; };
+		DBFA7159187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; };
+		DBFA715A187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; };
+		DBFA715B187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; };
+		DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716C187F1D9B00A76262 /* ffi_arm64.c */; };
+		DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; };
+		DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; };
+		DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; };
+		DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; };
+		DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; };
+		DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7182187F1DA100A76262 /* ffi_i386.h */; };
+		DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; };
+		DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7184187F1DA100A76262 /* fficonfig_i386.h */; };
+		DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */; };
+		DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7186187F1DA100A76262 /* ffitarget_i386.h */; };
+		DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; };
+		DBFA7194187F1DA100A76262 /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* unix64_x86_64.S */; };
+		DBFA7195187F1DA100A76262 /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* sysv_i386.S */; };
+		DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; };
+		DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; };
+		FDB52FB31F6144FA00AA92E6 /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C61D352C1500926A8F /* unix64_x86_64.S */; };
+		FDB52FB41F6144FA00AA92E6 /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = 43E9A5C51D352C1500926A8F /* sysv_i386.S */; };
+		FDB52FB51F6144FA00AA92E6 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; };
+		FDB52FB61F6144FA00AA92E6 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; };
+		FDB52FB71F6144FA00AA92E6 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; };
+		FDB52FB81F6144FA00AA92E6 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; };
+		FDB52FB91F6144FA00AA92E6 /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */; };
+		FDB52FBA1F6144FA00AA92E6 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; };
+		FDB52FBB1F6144FA00AA92E6 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; };
+		FDB52FBC1F6144FA00AA92E6 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; };
+		FDB52FBD1F6144FA00AA92E6 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; };
+		FDB52FBE1F6144FA00AA92E6 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; };
+		FDB52FBF1F6144FA00AA92E6 /* ffi_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716C187F1D9B00A76262 /* ffi_arm64.c */; };
+		FDB52FC01F6144FA00AA92E6 /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = 43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */; };
+		FDB52FD01F614A8B00AA92E6 /* ffi.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
+		FDB52FD11F614AA700AA92E6 /* ffi_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA715E187F1D9B00A76262 /* ffi_arm64.h */; };
+		FDB52FD21F614AAB00AA92E6 /* ffi_armv7.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA715F187F1D9B00A76262 /* ffi_armv7.h */; };
+		FDB52FD31F614AB000AA92E6 /* ffi_i386.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7160187F1D9B00A76262 /* ffi_i386.h */; };
+		FDB52FD41F614AB500AA92E6 /* ffi_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */; };
+		FDB52FD51F614AE200AA92E6 /* ffi.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
+		FDB52FD61F614AEA00AA92E6 /* ffi_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA715E187F1D9B00A76262 /* ffi_arm64.h */; };
+		FDB52FD71F614AED00AA92E6 /* ffi_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */; };
+		FDB52FD81F614B8700AA92E6 /* ffitarget.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
+		FDB52FD91F614B8E00AA92E6 /* ffitarget_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */; };
+		FDB52FDA1F614B9300AA92E6 /* ffitarget_armv7.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */; };
+		FDB52FDB1F614B9700AA92E6 /* ffitarget_i386.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */; };
+		FDB52FDD1F614BA900AA92E6 /* ffitarget_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */; };
+		FDB52FDE1F6155E300AA92E6 /* ffitarget.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
+		FDB52FDF1F6155EA00AA92E6 /* ffitarget_arm64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */; };
+		FDB52FE01F6155EF00AA92E6 /* ffitarget_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */; };
+		FDB52FE21F6156FA00AA92E6 /* ffi.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; };
+		FDB52FE31F61571A00AA92E6 /* ffi_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; };
+		FDB52FE41F61571D00AA92E6 /* ffitarget.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; };
+		FDB52FE61F61573100AA92E6 /* ffitarget_x86_64.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; };
+		FDDB2F411F5D66E200EF414E /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */; };
+		FDDB2F461F5D691E00EF414E /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F441F5D68C900EF414E /* win64_x86_64.S */; };
+		FDDB2F4A1F5D846400EF414E /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; };
+		FDDB2F4B1F5D846400EF414E /* sysv_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* sysv_i386.S */; };
+		FDDB2F4C1F5D846400EF414E /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; };
+		FDDB2F4D1F5D846400EF414E /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; };
+		FDDB2F4E1F5D846400EF414E /* ffiw64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */; };
+		FDDB2F4F1F5D846400EF414E /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; };
+		FDDB2F501F5D846400EF414E /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; };
+		FDDB2F511F5D846400EF414E /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; };
+		FDDB2F521F5D846400EF414E /* unix64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* unix64_x86_64.S */; };
+		FDDB2F531F5D846400EF414E /* win64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = FDDB2F441F5D68C900EF414E /* win64_x86_64.S */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		DB13B1641849DF1E0010F42D /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 12;
+			dstPath = "include/$(PRODUCT_NAME)";
+			dstSubfolderSpec = 16;
+			files = (
+				FDB52FD01F614A8B00AA92E6 /* ffi.h in CopyFiles */,
+				FDB52FD11F614AA700AA92E6 /* ffi_arm64.h in CopyFiles */,
+				FDB52FD21F614AAB00AA92E6 /* ffi_armv7.h in CopyFiles */,
+				FDB52FD31F614AB000AA92E6 /* ffi_i386.h in CopyFiles */,
+				FDB52FD41F614AB500AA92E6 /* ffi_x86_64.h in CopyFiles */,
+				FDB52FD81F614B8700AA92E6 /* ffitarget.h in CopyFiles */,
+				FDB52FD91F614B8E00AA92E6 /* ffitarget_arm64.h in CopyFiles */,
+				FDB52FDA1F614B9300AA92E6 /* ffitarget_armv7.h in CopyFiles */,
+				FDB52FDB1F614B9700AA92E6 /* ffitarget_i386.h in CopyFiles */,
+				FDB52FDD1F614BA900AA92E6 /* ffitarget_x86_64.h in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		FDB52FC11F6144FA00AA92E6 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 12;
+			dstPath = "include/$(PRODUCT_NAME)";
+			dstSubfolderSpec = 16;
+			files = (
+				FDB52FD51F614AE200AA92E6 /* ffi.h in CopyFiles */,
+				FDB52FD61F614AEA00AA92E6 /* ffi_arm64.h in CopyFiles */,
+				FDB52FD71F614AED00AA92E6 /* ffi_x86_64.h in CopyFiles */,
+				FDB52FDE1F6155E300AA92E6 /* ffitarget.h in CopyFiles */,
+				FDB52FDF1F6155EA00AA92E6 /* ffitarget_arm64.h in CopyFiles */,
+				FDB52FE01F6155EF00AA92E6 /* ffitarget_x86_64.h in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		FDB52FE11F6156E000AA92E6 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "include/$(PRODUCT_NAME)";
+			dstSubfolderSpec = 16;
+			files = (
+				FDB52FE21F6156FA00AA92E6 /* ffi.h in CopyFiles */,
+				FDB52FE31F61571A00AA92E6 /* ffi_x86_64.h in CopyFiles */,
+				FDB52FE41F61571D00AA92E6 /* ffitarget.h in CopyFiles */,
+				FDB52FE61F61573100AA92E6 /* ffitarget_x86_64.h in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffiw64_x86_64.c; sourceTree = "<group>"; };
+		43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = win64_x86_64.S; sourceTree = "<group>"; };
+		43E9A5C51D352C1500926A8F /* sysv_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_i386.S; sourceTree = "<group>"; };
+		43E9A5C61D352C1500926A8F /* unix64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = unix64_x86_64.S; sourceTree = "<group>"; };
+		43E9A5DA1D35373600926A8F /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
+		43E9A5DB1D35374400926A8F /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
+		43E9A5DC1D35375400926A8F /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
+		43E9A5DD1D35375400926A8F /* internal64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal64.h; sourceTree = "<group>"; };
+		DB13B1661849DF1E0010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		DB13B1911849DF510010F42D /* ffi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ffi.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+		DBFA713E187F1D8600A76262 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
+		DBFA713F187F1D8600A76262 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = "<group>"; };
+		DBFA7140187F1D8600A76262 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = "<group>"; };
+		DBFA7141187F1D8600A76262 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = "<group>"; };
+		DBFA7143187F1D8600A76262 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = closures.c; sourceTree = "<group>"; };
+		DBFA7145187F1D8600A76262 /* dlmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dlmalloc.c; sourceTree = "<group>"; };
+		DBFA7147187F1D8600A76262 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prep_cif.c; sourceTree = "<group>"; };
+		DBFA7148187F1D8600A76262 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_api.c; sourceTree = "<group>"; };
+		DBFA7149187F1D8600A76262 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = types.c; sourceTree = "<group>"; };
+		DBFA715E187F1D9B00A76262 /* ffi_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_arm64.h; sourceTree = "<group>"; };
+		DBFA715F187F1D9B00A76262 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = "<group>"; };
+		DBFA7160187F1D9B00A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
+		DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = "<group>"; };
+		DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_arm64.h; sourceTree = "<group>"; };
+		DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = "<group>"; };
+		DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
+		DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = "<group>"; };
+		DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm64.h; sourceTree = "<group>"; };
+		DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = "<group>"; };
+		DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
+		DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
+		DBFA716C187F1D9B00A76262 /* ffi_arm64.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = ffi_arm64.c; sourceTree = "<group>"; };
+		DBFA716D187F1D9B00A76262 /* sysv_arm64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_arm64.S; sourceTree = "<group>"; };
+		DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = "<group>"; };
+		DBFA7170187F1D9B00A76262 /* sysv_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_armv7.S; sourceTree = "<group>"; };
+		DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
+		DBFA7176187F1D9B00A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = "<group>"; };
+		DBFA7182187F1DA100A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
+		DBFA7183187F1DA100A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = "<group>"; };
+		DBFA7184187F1DA100A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
+		DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = "<group>"; };
+		DBFA7186187F1DA100A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
+		DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
+		DBFA718A187F1DA100A76262 /* unix64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = unix64_x86_64.S; sourceTree = "<group>"; };
+		DBFA718B187F1DA100A76262 /* sysv_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_i386.S; sourceTree = "<group>"; };
+		DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
+		DBFA718D187F1DA100A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = "<group>"; };
+		FDB52FC51F6144FA00AA92E6 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		FDDB2F3E1F5D61BC00EF414E /* asmnames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asmnames.h; sourceTree = "<group>"; };
+		FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffiw64_x86_64.c; sourceTree = "<group>"; };
+		FDDB2F421F5D68C900EF414E /* internal64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal64.h; sourceTree = "<group>"; };
+		FDDB2F431F5D68C900EF414E /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
+		FDDB2F441F5D68C900EF414E /* win64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = win64_x86_64.S; sourceTree = "<group>"; };
+		FDDB2F621F5D846400EF414E /* libffi.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXGroup section */
+		DB13B15B1849DEB70010F42D = {
+			isa = PBXGroup;
+			children = (
+				DBFA713C187F1D8600A76262 /* darwin_common */,
+				DBFA715C187F1D9B00A76262 /* darwin_ios */,
+				DBFA7180187F1DA100A76262 /* darwin_osx */,
+				DB13B1671849DF1E0010F42D /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		DB13B1671849DF1E0010F42D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				DB13B1661849DF1E0010F42D /* libffi.a */,
+				DB13B1911849DF510010F42D /* ffi.dylib */,
+				FDDB2F621F5D846400EF414E /* libffi.a */,
+				FDB52FC51F6144FA00AA92E6 /* libffi.a */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		DBFA713C187F1D8600A76262 /* darwin_common */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA713D187F1D8600A76262 /* include */,
+				DBFA7142187F1D8600A76262 /* src */,
+			);
+			path = darwin_common;
+			sourceTree = "<group>";
+		};
+		DBFA713D187F1D8600A76262 /* include */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA713E187F1D8600A76262 /* ffi.h */,
+				DBFA713F187F1D8600A76262 /* ffi_common.h */,
+				DBFA7140187F1D8600A76262 /* fficonfig.h */,
+				DBFA7141187F1D8600A76262 /* ffitarget.h */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		DBFA7142187F1D8600A76262 /* src */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA7143187F1D8600A76262 /* closures.c */,
+				DBFA7145187F1D8600A76262 /* dlmalloc.c */,
+				DBFA7147187F1D8600A76262 /* prep_cif.c */,
+				DBFA7148187F1D8600A76262 /* raw_api.c */,
+				DBFA7149187F1D8600A76262 /* types.c */,
+			);
+			path = src;
+			sourceTree = "<group>";
+		};
+		DBFA715C187F1D9B00A76262 /* darwin_ios */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA715D187F1D9B00A76262 /* include */,
+				DBFA716A187F1D9B00A76262 /* src */,
+			);
+			path = darwin_ios;
+			sourceTree = "<group>";
+		};
+		DBFA715D187F1D9B00A76262 /* include */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA715E187F1D9B00A76262 /* ffi_arm64.h */,
+				DBFA715F187F1D9B00A76262 /* ffi_armv7.h */,
+				DBFA7160187F1D9B00A76262 /* ffi_i386.h */,
+				DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */,
+				DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */,
+				DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */,
+				DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */,
+				DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */,
+				DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */,
+				DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */,
+				DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */,
+				DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		DBFA716A187F1D9B00A76262 /* src */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA716B187F1D9B00A76262 /* aarch64 */,
+				DBFA716E187F1D9B00A76262 /* arm */,
+				DBFA7172187F1D9B00A76262 /* x86 */,
+			);
+			path = src;
+			sourceTree = "<group>";
+		};
+		DBFA716B187F1D9B00A76262 /* aarch64 */ = {
+			isa = PBXGroup;
+			children = (
+				43E9A5DA1D35373600926A8F /* internal.h */,
+				DBFA716C187F1D9B00A76262 /* ffi_arm64.c */,
+				DBFA716D187F1D9B00A76262 /* sysv_arm64.S */,
+			);
+			path = aarch64;
+			sourceTree = "<group>";
+		};
+		DBFA716E187F1D9B00A76262 /* arm */ = {
+			isa = PBXGroup;
+			children = (
+				43E9A5DB1D35374400926A8F /* internal.h */,
+				DBFA716F187F1D9B00A76262 /* ffi_armv7.c */,
+				DBFA7170187F1D9B00A76262 /* sysv_armv7.S */,
+			);
+			path = arm;
+			sourceTree = "<group>";
+		};
+		DBFA7172187F1D9B00A76262 /* x86 */ = {
+			isa = PBXGroup;
+			children = (
+				43E9A5DC1D35375400926A8F /* internal.h */,
+				43E9A5DD1D35375400926A8F /* internal64.h */,
+				DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */,
+				43B5D3F71D35473200D1E1FD /* ffiw64_x86_64.c */,
+				DBFA7176187F1D9B00A76262 /* ffi_i386.c */,
+				43E9A5C51D352C1500926A8F /* sysv_i386.S */,
+				43E9A5C61D352C1500926A8F /* unix64_x86_64.S */,
+				43B5D3F91D3547CE00D1E1FD /* win64_x86_64.S */,
+			);
+			path = x86;
+			sourceTree = "<group>";
+		};
+		DBFA7180187F1DA100A76262 /* darwin_osx */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA7181187F1DA100A76262 /* include */,
+				DBFA7188187F1DA100A76262 /* src */,
+			);
+			path = darwin_osx;
+			sourceTree = "<group>";
+		};
+		DBFA7181187F1DA100A76262 /* include */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA7182187F1DA100A76262 /* ffi_i386.h */,
+				DBFA7183187F1DA100A76262 /* ffi_x86_64.h */,
+				DBFA7184187F1DA100A76262 /* fficonfig_i386.h */,
+				DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */,
+				DBFA7186187F1DA100A76262 /* ffitarget_i386.h */,
+				DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		DBFA7188187F1DA100A76262 /* src */ = {
+			isa = PBXGroup;
+			children = (
+				DBFA7189187F1DA100A76262 /* x86 */,
+			);
+			path = src;
+			sourceTree = "<group>";
+		};
+		DBFA7189187F1DA100A76262 /* x86 */ = {
+			isa = PBXGroup;
+			children = (
+				FDDB2F431F5D68C900EF414E /* internal.h */,
+				FDDB2F421F5D68C900EF414E /* internal64.h */,
+				FDDB2F3E1F5D61BC00EF414E /* asmnames.h */,
+				DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */,
+				FDDB2F3F1F5D666900EF414E /* ffiw64_x86_64.c */,
+				DBFA718D187F1DA100A76262 /* ffi_i386.c */,
+				DBFA718B187F1DA100A76262 /* sysv_i386.S */,
+				DBFA718A187F1DA100A76262 /* unix64_x86_64.S */,
+				FDDB2F441F5D68C900EF414E /* win64_x86_64.S */,
+			);
+			path = x86;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		DB13B18F1849DF510010F42D /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */,
+				DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */,
+				DBFA714A187F1D8600A76262 /* ffi.h in Headers */,
+				DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */,
+				DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */,
+				DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */,
+				DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */,
+				DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */,
+				DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */,
+				DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		DB13B1651849DF1E0010F42D /* libffi-iOS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */;
+			buildPhases = (
+				43B5D3FB1D35480D00D1E1FD /* Run Script */,
+				DB13B1621849DF1E0010F42D /* Sources */,
+				DB13B1641849DF1E0010F42D /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libffi-iOS";
+			productName = ffi;
+			productReference = DB13B1661849DF1E0010F42D /* libffi.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		DB13B1901849DF510010F42D /* libffi-Mac */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */;
+			buildPhases = (
+				DB13B3061849E0490010F42D /* ShellScript */,
+				DB13B18D1849DF510010F42D /* Sources */,
+				DB13B18F1849DF510010F42D /* Headers */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libffi-Mac";
+			productName = ffi;
+			productReference = DB13B1911849DF510010F42D /* ffi.dylib */;
+			productType = "com.apple.product-type.library.dynamic";
+		};
+		FDB52FB01F6144FA00AA92E6 /* libffi-tvOS */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = FDB52FC21F6144FA00AA92E6 /* Build configuration list for PBXNativeTarget "libffi-tvOS" */;
+			buildPhases = (
+				FDB52FB11F6144FA00AA92E6 /* Run Script */,
+				FDB52FB21F6144FA00AA92E6 /* Sources */,
+				FDB52FC11F6144FA00AA92E6 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libffi-tvOS";
+			productName = ffi;
+			productReference = FDB52FC51F6144FA00AA92E6 /* libffi.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		FDDB2F471F5D846400EF414E /* libffi-static-Mac */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = FDDB2F5F1F5D846400EF414E /* Build configuration list for PBXNativeTarget "libffi-static-Mac" */;
+			buildPhases = (
+				FDDB2F481F5D846400EF414E /* ShellScript */,
+				FDDB2F491F5D846400EF414E /* Sources */,
+				FDB52FE11F6156E000AA92E6 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "libffi-static-Mac";
+			productName = ffi;
+			productReference = FDDB2F621F5D846400EF414E /* libffi.a */;
+			productType = "com.apple.product-type.library.dynamic";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		DB13B15C1849DEB70010F42D /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0830;
+			};
+			buildConfigurationList = DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = DB13B15B1849DEB70010F42D;
+			productRefGroup = DB13B1671849DF1E0010F42D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				DB13B1651849DF1E0010F42D /* libffi-iOS */,
+				FDB52FB01F6144FA00AA92E6 /* libffi-tvOS */,
+				DB13B1901849DF510010F42D /* libffi-Mac */,
+				FDDB2F471F5D846400EF414E /* libffi-static-Mac */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		43B5D3FB1D35480D00D1E1FD /* Run Script */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Script";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-ios\nfi";
+		};
+		DB13B3061849E0490010F42D /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-osx\nfi";
+		};
+		FDB52FB11F6144FA00AA92E6 /* Run Script */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Script";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-ios\nfi";
+		};
+		FDDB2F481F5D846400EF414E /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "if [ ! -f \"./compile\" ]\nthen\nautoreconf -i -f -v\nif [ -f \"../ltmain.sh\" ]\nthen\necho \"fixing ltmain.sh for some reason\"\nmv ../ltmain.sh ./\nautoreconf -i -f -v\nfi\n/usr/bin/python generate-darwin-source-and-headers.py --only-osx\nfi";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		DB13B1621849DF1E0010F42D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				43E9A5C81D352C1500926A8F /* unix64_x86_64.S in Sources */,
+				43E9A5C71D352C1500926A8F /* sysv_i386.S in Sources */,
+				DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */,
+				DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */,
+				DBFA714E187F1D8600A76262 /* closures.c in Sources */,
+				DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */,
+				43B5D3F81D35473200D1E1FD /* ffiw64_x86_64.c in Sources */,
+				DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */,
+				DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */,
+				DBFA7158187F1D8600A76262 /* raw_api.c in Sources */,
+				DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */,
+				DBFA715A187F1D8600A76262 /* types.c in Sources */,
+				DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */,
+				43B5D3FA1D3547CE00D1E1FD /* win64_x86_64.S in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		DB13B18D1849DF510010F42D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */,
+				DBFA7195187F1DA100A76262 /* sysv_i386.S in Sources */,
+				DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */,
+				DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */,
+				FDDB2F411F5D66E200EF414E /* ffiw64_x86_64.c in Sources */,
+				DBFA715B187F1D8600A76262 /* types.c in Sources */,
+				DBFA7159187F1D8600A76262 /* raw_api.c in Sources */,
+				DBFA714F187F1D8600A76262 /* closures.c in Sources */,
+				DBFA7194187F1DA100A76262 /* unix64_x86_64.S in Sources */,
+				FDDB2F461F5D691E00EF414E /* win64_x86_64.S in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		FDB52FB21F6144FA00AA92E6 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FDB52FB31F6144FA00AA92E6 /* unix64_x86_64.S in Sources */,
+				FDB52FB41F6144FA00AA92E6 /* sysv_i386.S in Sources */,
+				FDB52FB51F6144FA00AA92E6 /* ffi64_x86_64.c in Sources */,
+				FDB52FB61F6144FA00AA92E6 /* ffi_armv7.c in Sources */,
+				FDB52FB71F6144FA00AA92E6 /* closures.c in Sources */,
+				FDB52FB81F6144FA00AA92E6 /* sysv_armv7.S in Sources */,
+				FDB52FB91F6144FA00AA92E6 /* ffiw64_x86_64.c in Sources */,
+				FDB52FBA1F6144FA00AA92E6 /* prep_cif.c in Sources */,
+				FDB52FBB1F6144FA00AA92E6 /* ffi_i386.c in Sources */,
+				FDB52FBC1F6144FA00AA92E6 /* raw_api.c in Sources */,
+				FDB52FBD1F6144FA00AA92E6 /* sysv_arm64.S in Sources */,
+				FDB52FBE1F6144FA00AA92E6 /* types.c in Sources */,
+				FDB52FBF1F6144FA00AA92E6 /* ffi_arm64.c in Sources */,
+				FDB52FC01F6144FA00AA92E6 /* win64_x86_64.S in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		FDDB2F491F5D846400EF414E /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				FDDB2F4A1F5D846400EF414E /* ffi64_x86_64.c in Sources */,
+				FDDB2F4B1F5D846400EF414E /* sysv_i386.S in Sources */,
+				FDDB2F4C1F5D846400EF414E /* prep_cif.c in Sources */,
+				FDDB2F4D1F5D846400EF414E /* ffi_i386.c in Sources */,
+				FDDB2F4E1F5D846400EF414E /* ffiw64_x86_64.c in Sources */,
+				FDDB2F4F1F5D846400EF414E /* types.c in Sources */,
+				FDDB2F501F5D846400EF414E /* raw_api.c in Sources */,
+				FDDB2F511F5D846400EF414E /* closures.c in Sources */,
+				FDDB2F521F5D846400EF414E /* unix64_x86_64.S in Sources */,
+				FDDB2F531F5D846400EF414E /* win64_x86_64.S in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		DB13B1601849DEB70010F42D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_common/include,
+				);
+				ONLY_ACTIVE_ARCH = YES;
+			};
+			name = Debug;
+		};
+		DB13B1611849DEB70010F42D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_common/include,
+				);
+			};
+			name = Release;
+		};
+		DB13B1871849DF1E0010F42D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DSTROOT = /tmp/ffi.dst;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_ios/include,
+				);
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				PRODUCT_NAME = ffi;
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64";
+			};
+			name = Debug;
+		};
+		DB13B1881849DF1E0010F42D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = YES;
+				DSTROOT = /tmp/ffi.dst;
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_ios/include,
+				);
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				PRODUCT_NAME = ffi;
+				SDKROOT = iphoneos;
+				SKIP_INSTALL = YES;
+				VALIDATE_PRODUCT = YES;
+				VALID_ARCHS = "arm64 armv7 armv7s i386 x86_64";
+			};
+			name = Release;
+		};
+		DB13B1B11849DF520010F42D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COMBINE_HIDPI_IMAGES = YES;
+				COPY_PHASE_STRIP = NO;
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_osx/include,
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
+				PRODUCT_NAME = ffi;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		DB13B1B21849DF520010F42D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COMBINE_HIDPI_IMAGES = YES;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_osx/include,
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
+				PRODUCT_NAME = ffi;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		FDB52FC31F6144FA00AA92E6 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_ios/include,
+				);
+				PRODUCT_NAME = ffi;
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+			};
+			name = Debug;
+		};
+		FDB52FC41F6144FA00AA92E6 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = YES;
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_ios/include,
+				);
+				PRODUCT_NAME = ffi;
+				SDKROOT = appletvos;
+				SKIP_INSTALL = YES;
+				TVOS_DEPLOYMENT_TARGET = 9.0;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		FDDB2F601F5D846400EF414E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COMBINE_HIDPI_IMAGES = YES;
+				COPY_PHASE_STRIP = NO;
+				EXECUTABLE_EXTENSION = a;
+				EXECUTABLE_PREFIX = lib;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_osx/include,
+				);
+				MACH_O_TYPE = staticlib;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PRODUCT_NAME = ffi;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		FDDB2F611F5D846400EF414E /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COMBINE_HIDPI_IMAGES = YES;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				EXECUTABLE_EXTENSION = a;
+				EXECUTABLE_PREFIX = lib;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"$(inherited)",
+					darwin_osx/include,
+				);
+				MACH_O_TYPE = staticlib;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				PRODUCT_NAME = ffi;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				DB13B1601849DEB70010F42D /* Debug */,
+				DB13B1611849DEB70010F42D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				DB13B1871849DF1E0010F42D /* Debug */,
+				DB13B1881849DF1E0010F42D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				DB13B1B11849DF520010F42D /* Debug */,
+				DB13B1B21849DF520010F42D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		FDB52FC21F6144FA00AA92E6 /* Build configuration list for PBXNativeTarget "libffi-tvOS" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				FDB52FC31F6144FA00AA92E6 /* Debug */,
+				FDB52FC41F6144FA00AA92E6 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		FDDB2F5F1F5D846400EF414E /* Build configuration list for PBXNativeTarget "libffi-static-Mac" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				FDDB2F601F5D846400EF414E /* Debug */,
+				FDDB2F611F5D846400EF414E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = DB13B15C1849DEB70010F42D /* Project object */;
+}

+ 29 - 0
libffi.mod/libffi/libtool-version

@@ -0,0 +1,29 @@
+# This file is used to maintain libtool version info for libffi.  See
+# the libtool manual to understand the meaning of the fields.  This is
+# a separate file so that version updates don't involve re-running
+# automake.
+#
+# Here are a set of rules to help you update your library version
+# information:
+# 
+# 1. Start with version information of `0:0:0' for each libtool library.
+#
+# 2. Update the version information only immediately before a public
+#    release of your software. More frequent updates are unnecessary,
+#    and only guarantee that the current interface number gets larger
+#    faster.
+#
+# 3. If the library source code has changed at all since the last
+#    update, then increment revision (`c:r:a' becomes `c:r+1:a').
+#
+# 4. If any interfaces have been added, removed, or changed since the
+#    last update, increment current, and set revision to 0.
+#
+# 5. If any interfaces have been added since the last public release,
+#    then increment age.
+#
+# 6. If any interfaces have been removed since the last public
+#    release, then set age to 0.
+#
+# CURRENT:REVISION:AGE
+8:0:1

+ 13 - 0
libffi.mod/libffi/m4/asmcfi.m4

@@ -0,0 +1,13 @@
+AC_DEFUN([GCC_AS_CFI_PSEUDO_OP],
+[AC_CACHE_CHECK([assembler .cfi pseudo-op support],
+    gcc_cv_as_cfi_pseudo_op, [
+    gcc_cv_as_cfi_pseudo_op=unknown
+    AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],,
+		   [gcc_cv_as_cfi_pseudo_op=yes],
+		   [gcc_cv_as_cfi_pseudo_op=no])
+ ])
+ 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
+])

+ 71 - 0
libffi.mod/libffi/m4/ax_append_flag.m4

@@ -0,0 +1,71 @@
+# ===========================================================================
+#      https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+#   FLAG is appended to 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_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <[email protected]>
+#   Copyright (c) 2011 Maarten Bosmans <[email protected]>
+#
+#   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 7
+
+AC_DEFUN([AX_APPEND_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])],
+    [
+     AS_VAR_APPEND(FLAGS,[" $1"])
+     AC_RUN_LOG([: FLAGS="$FLAGS"])
+    ])
+  ],
+  [
+  AS_VAR_SET(FLAGS,[$1])
+  AC_RUN_LOG([: FLAGS="$FLAGS"])
+  ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG

+ 194 - 0
libffi.mod/libffi/m4/ax_cc_maxopt.m4

@@ -0,0 +1,194 @@
+# ===========================================================================
+#       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 <[email protected]>
+#   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 17
+
+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 "$ac_test_CFLAGS" != "set"; then
+  CFLAGS=""
+  case $ax_cv_c_compiler_vendor in
+    dec) 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="-native -fast -xO5 -dalign"
+	 if test "x$acx_maxopt_portable" = xyes; then
+	   CFLAGS="$CFLAGS -xarch=generic"
+         fi;;
+
+    hp)  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="-O3 -qansialias -w $xlc_opt",
+               [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="-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
+	;;
+
+    gnu)
+     # default optimization flags for gcc on all systems
+     CFLAGS="-O3 -fomit-frame-pointer"
+
+     # -malign-double for x86 systems
+     # libffi local change -- don't align double, as it changes the ABI
+     # 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="-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="-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 ""
+        CFLAGS=""
+  ])
+
+fi
+])

+ 122 - 0
libffi.mod/libffi/m4/ax_cflags_warn_all.m4

@@ -0,0 +1,122 @@
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CFLAGS_WARN_ALL   [(shellvar [,default, [A/NA]])]
+#   AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
+#   AX_FCFLAGS_WARN_ALL  [(shellvar [,default, [A/NA]])]
+#
+# DESCRIPTION
+#
+#   Try to find a compiler option that enables most reasonable warnings.
+#
+#   For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
+#   is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
+#
+#   Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
+#   HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
+#   Intel compilers.  For a given compiler, the Fortran flags are much more
+#   experimental than their C equivalents.
+#
+#    - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
+#    - $2 add-value-if-not-found : nothing
+#    - $3 action-if-found : add value to shellvariable
+#    - $4 action-if-not-found : nothing
+#
+#   NOTE: These macros depend on AX_APPEND_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <[email protected]>
+#   Copyright (c) 2010 Rhys Ulerich <[email protected]>
+#
+#   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 16
+
+AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
+AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
+AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
+AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
+VAR,[VAR="no, unknown"
+ac_save_[]FLAGS="$[]FLAGS"
+for ac_arg dnl
+in "-warn all  % -warn all"   dnl Intel
+   "-pedantic  % -Wall"       dnl GCC
+   "-xstrconst % -v"          dnl Solaris C
+   "-std1      % -verbose -w0 -warnprotos" dnl Digital Unix
+   "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
+   "-ansi -ansiE % -fullwarn" dnl IRIX
+   "+ESlit     % +w1"         dnl HP-UX C
+   "-Xc        % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
+   "-h conform % -h msglevel 2" dnl Cray C (Unicos)
+   #
+do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+                     [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
+done
+FLAGS="$ac_save_[]FLAGS"
+])
+AS_VAR_POPDEF([FLAGS])dnl
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+case ".$VAR" in
+     .ok|.ok,*) m4_ifvaln($3,$3) ;;
+   .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
+   *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
+esac
+AS_VAR_POPDEF([VAR])dnl
+])dnl AX_FLAGS_WARN_ALL
+dnl  implementation tactics:
+dnl   the for-argument contains a list of options. The first part of
+dnl   these does only exist to detect the compiler - usually it is
+dnl   a global option to enable -ansi or -extrawarnings. All other
+dnl   compilers will fail about it. That was needed since a lot of
+dnl   compilers will give false positives for some option-syntax
+dnl   like -Woption or -Xoption as they think of it is a pass-through
+dnl   to later compile stages or something. The "%" is used as a
+dnl   delimiter. A non-option comment can be given after "%%" marks
+dnl   which will be shown but not added to the respective C/CXXFLAGS.
+
+AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C])
+])
+
+AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([C++])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([C++])
+])
+
+AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
+AC_LANG_PUSH([Fortran])
+AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
+AC_LANG_POP([Fortran])
+])

+ 74 - 0
libffi.mod/libffi/m4/ax_check_compile_flag.m4

@@ -0,0 +1,74 @@
+# ===========================================================================
+#  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 <[email protected]>
+#   Copyright (c) 2011 Maarten Bosmans <[email protected]>
+#
+#   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 5
+
+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 _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  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

+ 87 - 0
libffi.mod/libffi/m4/ax_compiler_vendor.m4

@@ -0,0 +1,87 @@
+# ===========================================================================
+#    https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPILER_VENDOR
+#
+# DESCRIPTION
+#
+#   Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
+#   hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
+#   watcom, etc. The vendor is returned in the cache variable
+#   $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Steven G. Johnson <[email protected]>
+#   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 16
+
+AC_DEFUN([AX_COMPILER_VENDOR],
+[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
+  dnl Please add if possible support to ax_compiler_version.m4
+  [# note: don't check for gcc first since some other compilers define __GNUC__
+  vendors="intel:     __ICC,__ECC,__INTEL_COMPILER
+           ibm:       __xlc__,__xlC__,__IBMC__,__IBMCPP__
+           pathscale: __PATHCC__,__PATHSCALE__
+           clang:     __clang__
+           cray:      _CRAYC
+           fujitsu:   __FUJITSU
+           gnu:       __GNUC__
+           sun:       __SUNPRO_C,__SUNPRO_CC
+           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__
+           portland:  __PGI
+	   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`
+ ])
+])

+ 70 - 0
libffi.mod/libffi/m4/ax_configure_args.m4

@@ -0,0 +1,70 @@
+# ===========================================================================
+#    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 <[email protected]>
+#
+#   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 13
+
+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
+])

+ 302 - 0
libffi.mod/libffi/m4/ax_enable_builddir.m4

@@ -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 <[email protected]>
+#   Copyright (c) 2009 Alan Jenkins <[email protected]>
+#
+#   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
+])

+ 263 - 0
libffi.mod/libffi/m4/ax_gcc_archflag.m4

@@ -0,0 +1,263 @@
+# ===========================================================================
+#     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 <[email protected]>
+#   Copyright (c) 2008 Matteo Frigo
+#   Copyright (c) 2014 Tsukasa Oi
+#   Copyright (c) 2017 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 20
+
+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?:*:*:*) 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";;
+       *) 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
+])

+ 89 - 0
libffi.mod/libffi/m4/ax_gcc_x86_cpuid.m4

@@ -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 <[email protected]>
+#   Copyright (c) 2008 Matteo Frigo
+#   Copyright (c) 2015 Michael Petch <[email protected]>
+#
+#   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])
+])

+ 37 - 0
libffi.mod/libffi/m4/ax_require_defined.m4

@@ -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 <[email protected]>
+#
+#   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

+ 8 - 0
libffi.mod/libffi/man/Makefile.am

@@ -0,0 +1,8 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS=foreign
+
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
+
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
+

+ 41 - 0
libffi.mod/libffi/man/ffi.3

@@ -0,0 +1,41 @@
+.Dd February 15, 2008
+.Dt FFI 3
+.Sh NAME
+.Nm FFI
+.Nd Foreign Function Interface
+.Sh LIBRARY
+libffi, -lffi
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Ft void
+.Fo ffi_prep_cif_var
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nfixedargs"
+.Fa "unsigned int ntotalargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Ft void
+.Fo ffi_call
+.Fa "ffi_cif *cif"
+.Fa "void (*fn)(void)"
+.Fa "void *rvalue"
+.Fa "void **avalue"
+.Fc
+.Sh DESCRIPTION
+The foreign function interface provides a mechanism by which a function can
+generate a call to another function at runtime without requiring knowledge of
+the called function's interface at compile time.
+.Sh SEE ALSO
+.Xr ffi_prep_cif 3 ,
+.Xr ffi_prep_cif_var 3 ,
+.Xr ffi_call 3

+ 103 - 0
libffi.mod/libffi/man/ffi_call.3

@@ -0,0 +1,103 @@
+.Dd February 15, 2008
+.Dt ffi_call 3
+.Sh NAME
+.Nm ffi_call
+.Nd Invoke a foreign function.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft void
+.Fo ffi_call
+.Fa "ffi_cif *cif"
+.Fa "void (*fn)(void)"
+.Fa "void *rvalue"
+.Fa "void **avalue"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_call
+function provides a simple mechanism for invoking a function without
+requiring knowledge of the function's interface at compile time.
+.Fa fn
+is called with the values retrieved from the pointers in the
+.Fa avalue
+array. The return value from
+.Fa fn
+is placed in storage pointed to by
+.Fa rvalue .
+.Fa cif
+contains information describing the data types, sizes and alignments of the
+arguments to and return value from
+.Fa fn ,
+and must be initialized with
+.Nm ffi_prep_cif
+before it is used with
+.Nm ffi_call .
+.Pp
+.Fa rvalue
+must point to storage that is sizeof(ffi_arg) or larger for non-floating point
+types. For smaller-sized return value types, the
+.Nm ffi_arg
+or
+.Nm ffi_sarg
+integral type must be used to hold
+the return value.
+.Sh EXAMPLES
+.Bd -literal
+#include <ffi.h>
+#include <stdio.h>
+
+unsigned char
+foo(unsigned int, float);
+
+int
+main(int argc, const char **argv)
+{
+    ffi_cif cif;
+    ffi_type *arg_types[2];
+    void *arg_values[2];
+    ffi_status status;
+
+    // Because the return value from foo() is smaller than sizeof(long), it
+    // must be passed as ffi_arg or ffi_sarg.
+    ffi_arg result;
+
+    // Specify the data type of each argument. Available types are defined
+    // in <ffi/ffi.h>.
+    arg_types[0] = &ffi_type_uint;
+    arg_types[1] = &ffi_type_float;
+
+    // Prepare the ffi_cif structure.
+    if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+        2, &ffi_type_uint8, arg_types)) != FFI_OK)
+    {
+        // Handle the ffi_status error.
+    }
+
+    // Specify the values of each argument.
+    unsigned int arg1 = 42;
+    float arg2 = 5.1;
+
+    arg_values[0] = &arg1;
+    arg_values[1] = &arg2;
+
+    // Invoke the function.
+    ffi_call(&cif, FFI_FN(foo), &result, arg_values);
+
+    // The ffi_arg 'result' now contains the unsigned char returned from foo(),
+    // which can be accessed by a typecast.
+    printf("result is %hhu", (unsigned char)result);
+
+    return 0;
+}
+
+// The target function.
+unsigned char
+foo(unsigned int x, float y)
+{
+    unsigned char result = x - y;
+    return result;
+}
+.Ed
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_prep_cif 3

+ 68 - 0
libffi.mod/libffi/man/ffi_prep_cif.3

@@ -0,0 +1,68 @@
+.Dd February 15, 2008
+.Dt ffi_prep_cif 3
+.Sh NAME
+.Nm ffi_prep_cif
+.Nd Prepare a
+.Nm ffi_cif
+structure for use with
+.Nm ffi_call 
+.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_prep_cif
+function prepares a
+.Nm ffi_cif
+structure for use with 
+.Nm ffi_call
+.
+.Fa abi
+specifies a set of calling conventions to use.
+.Fa atypes
+is an array of
+.Fa nargs
+pointers to
+.Nm ffi_type
+structs that describe the data type, size and alignment of each argument.
+.Fa rtype
+points to an
+.Nm ffi_type
+that describes the data type, size and alignment of the
+return value. Note that to call a variadic function
+.Nm ffi_prep_cif_var
+must be used instead.
+.Sh RETURN VALUES
+Upon successful completion,
+.Nm ffi_prep_cif
+returns
+.Nm FFI_OK .
+It will return
+.Nm FFI_BAD_TYPEDEF
+if
+.Fa cif
+is
+.Nm NULL
+or
+.Fa atypes
+or
+.Fa rtype
+is malformed. If
+.Fa abi
+does not refer to a valid ABI,
+.Nm FFI_BAD_ABI
+will be returned. Available ABIs are
+defined in
+.Nm <ffitarget.h> .
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_call 3 ,
+.Xr ffi_prep_cif_var 3

+ 73 - 0
libffi.mod/libffi/man/ffi_prep_cif_var.3

@@ -0,0 +1,73 @@
+.Dd January 25, 2011
+.Dt ffi_prep_cif_var 3
+.Sh NAME
+.Nm ffi_prep_cif_var
+.Nd Prepare a
+.Nm ffi_cif
+structure for use with
+.Nm ffi_call
+for variadic functions.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif_var
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nfixedargs"
+.Fa "unsigned int ntotalargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_prep_cif_var
+function prepares a
+.Nm ffi_cif
+structure for use with
+.Nm ffi_call
+for variadic functions.
+.Fa abi
+specifies a set of calling conventions to use.
+.Fa atypes
+is an array of
+.Fa ntotalargs
+pointers to
+.Nm ffi_type
+structs that describe the data type, size and alignment of each argument.
+.Fa rtype
+points to an
+.Nm ffi_type
+that describes the data type, size and alignment of the
+return value.
+.Fa nfixedargs
+must contain the number of fixed (non-variadic) arguments.
+Note that to call a non-variadic function
+.Nm ffi_prep_cif
+must be used.
+.Sh RETURN VALUES
+Upon successful completion,
+.Nm ffi_prep_cif_var
+returns
+.Nm FFI_OK .
+It will return
+.Nm FFI_BAD_TYPEDEF
+if
+.Fa cif
+is
+.Nm NULL
+or
+.Fa atypes
+or
+.Fa rtype
+is malformed. If
+.Fa abi
+does not refer to a valid ABI,
+.Nm FFI_BAD_ABI
+will be returned. Available ABIs are
+defined in
+.Nm <ffitarget.h>
+.
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_call 3 ,
+.Xr ffi_prep_cif 3

+ 328 - 0
libffi.mod/libffi/msvcc.sh

@@ -0,0 +1,328 @@
+#!/bin/sh
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the MSVC wrappificator.
+#
+# The Initial Developer of the Original Code is
+# Timothy Wall <[email protected]>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Daniel Witte <[email protected]>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# GCC-compatible wrapper for cl.exe and ml.exe. Arguments are given in GCC
+# format and translated into something sensible for cl or ml.
+#
+
+args_orig=$@
+args="-nologo -W3"
+linkargs=
+static_crt=
+debug_crt=
+cl="cl"
+ml="ml"
+safeseh="-safeseh"
+output=
+libpaths=
+libversion=7
+verbose=
+
+while [ $# -gt 0 ]
+do
+  case $1
+  in
+    --verbose)
+      $verbose=1
+      shift 1
+    ;;
+    --version)
+      args="-help"
+      shift 1
+    ;;
+    -fexceptions)
+      # Don't enable exceptions for now.
+      #args="$args -EHac"
+      shift 1
+    ;;
+    -m32)
+      shift 1
+    ;;
+    -m64)
+      ml="ml64" # "$MSVC/x86_amd64/ml64"
+      safeseh=
+      shift 1
+    ;;
+    -clang-cl)
+      cl="clang-cl"
+      shift 1
+    ;;
+    -O0)
+      args="$args -Od"
+      shift 1
+    ;;
+    -O*)
+      # Runtime error checks (enabled by setting -RTC1 in the -DFFI_DEBUG
+      # case below) are not compatible with optimization flags and will
+      # cause the build to fail. Therefore, drop the optimization flag if
+      # -DFFI_DEBUG is also set.
+      case $args_orig in
+        *-DFFI_DEBUG*)
+          args="$args"
+        ;;
+        *)
+          # The ax_cc_maxopt.m4 macro from the upstream autoconf-archive
+          # project doesn't support MSVC and therefore ends up trying to
+          # use -O3. Use the equivalent "max optimization" flag for MSVC
+          # instead of erroring out.
+          case $1 in
+            -O3)
+              args="$args -O2"
+            ;;
+            *)
+              args="$args $1"
+            ;;
+          esac
+          opt="true"
+        ;;
+      esac
+      shift 1
+    ;;
+    -g)
+      # Enable debug symbol generation.
+      args="$args -Zi"
+      shift 1
+    ;;
+    -DFFI_DEBUG)
+      # Enable runtime error checks.
+      args="$args -RTC1"
+      defines="$defines $1"
+      shift 1
+    ;;
+    -DUSE_STATIC_RTL)
+      # Link against static CRT.
+      static_crt=1
+      shift 1
+    ;;
+    -DUSE_DEBUG_RTL)
+      # Link against debug CRT.
+      debug_crt=1
+      shift 1
+    ;;
+    -c)
+      args="$args -c"
+      args="$(echo $args | sed 's%/Fe%/Fo%g')"
+      single="-c"
+      shift 1
+    ;;
+    -D*=*)
+      name="$(echo $1|sed 's/-D\([^=][^=]*\)=.*/\1/g')"
+      value="$(echo $1|sed 's/-D[^=][^=]*=//g')"
+      args="$args -D${name}='$value'"
+      defines="$defines -D${name}='$value'"
+      shift 1
+    ;;
+    -D*)
+      args="$args $1"
+      defines="$defines $1"
+      shift 1
+    ;;
+    -I)
+      p=$(cygpath -m $2)
+      args="$args -I$p"
+      includes="$includes -I$p"
+      shift 2
+    ;;
+    -I*)
+      p=$(cygpath -m ${1#-I})
+      args="$args -I$p"
+      includes="$includes -I$p"
+      shift 1
+    ;;
+    -L)
+      p=$(cygpath -m $2)
+      linkargs="$linkargs -LIBPATH:$p"
+      shift 2
+    ;;
+    -L*)
+      p=$(cygpath -m ${1#-L})
+      linkargs="$linkargs -LIBPATH:$p"
+      shift 1
+    ;;
+    -link)
+      # add next argument verbatim to linker args
+      linkargs="$linkargs $2"
+      shift 2
+      ;;
+    -l*)
+      case $1
+      in
+        -lffi)
+          linkargs="$linkargs lib${1#-l}-${libversion}.lib"
+          ;;
+        *)
+          # ignore other libraries like -lm, hope they are
+          # covered by MSVCRT
+          # linkargs="$linkargs ${1#-l}.lib"
+          ;;
+      esac
+      shift 1
+    ;;
+    -W|-Wextra)
+      # TODO map extra warnings
+      shift 1
+    ;;
+    -Wall)
+      # -Wall on MSVC is overzealous, and we already build with -W3. Nothing
+      # to do here.
+      shift 1
+    ;;
+    -pedantic)
+      # libffi tests -pedantic with -Wall, so drop it also.
+      shift 1
+    ;;
+    -warn)
+      # ignore -warn all from libtool as well.
+      if test "$2" = "all"; then
+        shift 2
+      else
+        args="$args -warn"
+        shift 1
+      fi
+    ;;
+    -Werror)
+      args="$args -WX"
+      shift 1
+    ;;
+    -W*)
+      # TODO map specific warnings
+      shift 1
+    ;;
+    -S)
+      args="$args -FAs"
+      shift 1
+    ;;
+    -o)
+      outdir="$(dirname $2)"
+      base="$(basename $2|sed 's/\.[^.]*//g')"
+      if [ -n "$single" ]; then 
+        output="-Fo$2"
+      else
+        output="-Fe$2"
+      fi
+      if [ -n "$assembly" ]; then
+        args="$args $output"
+      else
+        args="$args $output -Fd$outdir/$base -Fp$outdir/$base -Fa$outdir/$base"
+      fi
+      shift 2
+    ;;
+    *.S)
+      src=$1
+      assembly="true"
+      shift 1
+    ;;
+    *.c)
+      args="$args $1"
+      shift 1
+    ;;
+    *)
+      # Assume it's an MSVC argument, and pass it through.
+      args="$args $1"
+      shift 1
+    ;;
+  esac
+done
+
+if [ -n "$linkargs" ]; then
+
+    # If -Zi is specified, certain optimizations are implicitly disabled
+    # by MSVC. Add back those optimizations if this is an optimized build.
+    # NOTE: These arguments must come after all others.
+    if [ -n "$opt" ]; then
+	linkargs="$linkargs -OPT:REF -OPT:ICF -INCREMENTAL:NO"
+    fi
+
+    args="$args -link $linkargs"
+fi
+
+if [ -n "$static_crt" ]; then
+    md=-MT
+else
+    md=-MD
+fi
+
+if [ -n "$debug_crt" ]; then
+    md="${md}d"
+fi
+
+if [ -n "$assembly" ]; then
+    if [ -z "$outdir" ]; then
+      outdir="."
+    fi
+    ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
+
+    if test -n "$verbose"; then
+      echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
+    fi
+
+    "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
+    output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
+    args="-nologo $safeseh $single $output $ppsrc"
+
+    if test -n "$verbose"; then
+      echo "$ml $args"
+    fi
+
+    eval "\"$ml\" $args"
+    result=$?
+
+    # required to fix ml64 broken output?
+    #mv *.obj $outdir
+else
+    args="$md $args"
+
+    if test -n "$verbose"; then
+      echo "$cl $args"
+    fi
+    # Return an error code of 1 if an invalid command line parameter is passed
+    # instead of just ignoring it. Any output that is not a warning or an
+    # error is filtered so this command behaves more like gcc. cl.exe prints
+    # the name of the compiled file otherwise, which breaks the dejagnu checks
+    # for excess warnings and errors.
+    eval "(\"$cl\" $args 2>&1 1>&3 | \
+          awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1 | \
+          awk '/warning|error/'"
+    result=$?
+fi
+
+exit $result
+
+# vim: noai:ts=4:sw=4

+ 948 - 0
libffi.mod/libffi/src/aarch64/ffi.c

@@ -0,0 +1,948 @@
+/* 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__)
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <fficonfig.h>
+#include <ffi.h>
+#include <ffi_common.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_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__
+#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);
+#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. */
+
+struct arg_state
+{
+  unsigned ngrn;                /* Next general-purpose register number. */
+  unsigned nsrn;                /* Next vector register number. */
+  size_t nsaa;                  /* Next stack offset. */
+
+#if defined (__APPLE__)
+  unsigned allocating_variadic;
+#endif
+};
+
+/* Initialize a procedure call argument marshalling state.  */
+static void
+arg_init (struct arg_state *state)
+{
+  state->ngrn = 0;
+  state->nsrn = 0;
+  state->nsaa = 0;
+#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;
+}
+
+static ffi_arg
+extend_integer_type (void *source, int type)
+{
+  switch (type)
+    {
+    case FFI_TYPE_UINT8:
+      return *(UINT8 *) source;
+    case FFI_TYPE_SINT8:
+      return *(SINT8 *) source;
+    case FFI_TYPE_UINT16:
+      return *(UINT16 *) source;
+    case FFI_TYPE_SINT16:
+      return *(SINT16 *) source;
+    case FFI_TYPE_UINT32:
+      return *(UINT32 *) source;
+    case FFI_TYPE_INT:
+    case FFI_TYPE_SINT32:
+      return *(SINT32 *) source;
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+      return *(UINT64 *) source;
+      break;
+    case FFI_TYPE_POINTER:
+      return *(uintptr_t *) source;
+    default:
+      abort();
+    }
+}
+
+static void
+extend_hfa_type (void *dest, void *src, int h)
+{
+  ssize_t f = h - AARCH64_RET_S4;
+  void *x0;
+
+  asm volatile (
+	"adr	%0, 0f\n"
+"	add	%0, %0, %1\n"
+"	br	%0\n"
+"0:	ldp	s16, s17, [%3]\n"	/* S4 */
+"	ldp	s18, s19, [%3, #8]\n"
+"	b	4f\n"
+"	ldp	s16, s17, [%3]\n"	/* S3 */
+"	ldr	s18, [%3, #8]\n"
+"	b	3f\n"
+"	ldp	s16, s17, [%3]\n"	/* S2 */
+"	b	2f\n"
+"	nop\n"
+"	ldr	s16, [%3]\n"		/* S1 */
+"	b	1f\n"
+"	nop\n"
+"	ldp	d16, d17, [%3]\n"	/* D4 */
+"	ldp	d18, d19, [%3, #16]\n"
+"	b	4f\n"
+"	ldp	d16, d17, [%3]\n"	/* D3 */
+"	ldr	d18, [%3, #16]\n"
+"	b	3f\n"
+"	ldp	d16, d17, [%3]\n"	/* D2 */
+"	b	2f\n"
+"	nop\n"
+"	ldr	d16, [%3]\n"		/* D1 */
+"	b	1f\n"
+"	nop\n"
+"	ldp	q16, q17, [%3]\n"	/* Q4 */
+"	ldp	q18, q19, [%3, #32]\n"
+"	b	4f\n"
+"	ldp	q16, q17, [%3]\n"	/* Q3 */
+"	ldr	q18, [%3, #32]\n"
+"	b	3f\n"
+"	ldp	q16, q17, [%3]\n"	/* Q2 */
+"	b	2f\n"
+"	nop\n"
+"	ldr	q16, [%3]\n"		/* Q1 */
+"	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 * 12), "r"(dest), "r"(src)
+    : "memory", "v16", "v17", "v18", "v19");
+}
+
+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;
+}
+
+/* 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;
+}
+#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.  */
+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;
+  ffi_type *rtype;
+
+  flags = cif->flags;
+  rtype = cif->rtype;
+  rtype_size = rtype->size;
+  stack_bytes = cif->bytes;
+
+  /* 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 consectutive stack for everything we'll need.  */
+  context = alloca (sizeof(struct call_context) + stack_bytes + 32 + rsize);
+  stack = context + 1;
+  frame = stack + stack_bytes;
+  rvalue = (rsize ? frame + 32 : orig_rvalue);
+
+  arg_init (&state);
+  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;
+
+      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:
+	  {
+	    void *dest;
+
+	    h = is_vfp_type (ty);
+	    if (h)
+	      {
+		int elems = 4 - (h & 3);
+	        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 has been copied to memory, and
+		   the argument is replaced by a pointer to the copy.  */
+		a = &avalue[i];
+		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 += 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);
+}
+
+#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;
+
+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;
+
+  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__
+  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;
+  
+  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.  */
+  unsigned char *tramp_code = ffi_data_to_code_pointer (tramp);
+  ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE);
+#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)
+    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;
+  struct arg_state state;
+
+  arg_init (&state);
+
+  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 (state.nsrn + n <= N_V_ARG_REG)
+		{
+		  void *reg = &context->v[state.nsrn];
+		  state.nsrn += 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.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.  */
+	      avalue[i] = *(void **)
+		allocate_int_to_reg_or_stack (context, &state, stack,
+					      sizeof (void *));
+	    }
+	  else
+	    {
+	      n = (s + 7) / 8;
+	      if (state.ngrn + n <= N_X_ARG_REG)
+		{
+		  avalue[i] = &context->x[state.ngrn];
+		  state.ngrn += 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
+    }
+
+  flags = cif->flags;
+  if (flags & AARCH64_RET_IN_MEM)
+    rvalue = struct_rvalue;
+
+  fun (cif, rvalue, avalue, user_data);
+
+  return flags;
+}
+
+#endif /* __arm64__ */

+ 81 - 0
libffi.mod/libffi/src/aarch64/ffitarget.h

@@ -0,0 +1,81 @@
+/* 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;
+#else
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+#endif
+
+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
+
+#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
+
+/* ---- Internal ---- */
+
+#if defined (__APPLE__)
+#define FFI_TARGET_SPECIFIC_VARIADIC
+#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
+#else
+/* iOS reserves x18 for the system.  Disable Go closures until
+   a new static chain is chosen.  */
+#define FFI_GO_CLOSURES 1
+#endif
+
+#define FFI_TARGET_HAS_COMPLEX_TYPE
+
+#endif

+ 67 - 0
libffi.mod/libffi/src/aarch64/internal.h

@@ -0,0 +1,67 @@
+/* 
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY 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 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)

+ 440 - 0
libffi.mod/libffi/src/aarch64/sysv.S

@@ -0,0 +1,440 @@
+/* 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 __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
+
+	.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
+*/
+
+	cfi_startproc
+CNAME(ffi_call_SYSV):
+	/* Use a stack frame allocated by our caller.  */
+	cfi_def_cfa(x1, 32);
+	stp	x29, x30, [x1]
+	mov	x29, x1
+	mov	sp, x0
+	cfi_def_cfa_register(x29)
+	cfi_rel_offset (x29, 0)
+	cfi_rel_offset (x30, 8)
+
+	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
+
+	blr     x9			/* call fn */
+
+	ldp	x3, x4, [x29, #16]	/* reload rvalue and flags */
+
+	/* Partially deconstruct the stack frame.  */
+	mov     sp, x29
+	cfi_def_cfa_register (sp)
+	ldp     x29, x30, [x29]
+
+	/* Save the return value as directed.  */
+	adr	x5, 0f
+	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
+0:	ret				/* VOID */
+	nop
+1:	str	x0, [x3]		/* INT64 */
+	ret
+2:	stp	x0, x1, [x3]		/* INT128 */
+	ret
+3:	brk	#1000			/* UNUSED */
+	ret
+4:	brk	#1000			/* UNUSED */
+	ret
+5:	brk	#1000			/* UNUSED */
+	ret
+6:	brk	#1000			/* UNUSED */
+	ret
+7:	brk	#1000			/* UNUSED */
+	ret
+8:	st4	{ v0.s, v1.s, v2.s, v3.s }[0], [x3]	/* S4 */
+	ret
+9:	st3	{ v0.s, v1.s, v2.s }[0], [x3]	/* S3 */
+	ret
+10:	stp	s0, s1, [x3]		/* S2 */
+	ret
+11:	str	s0, [x3]		/* S1 */
+	ret
+12:	st4	{ v0.d, v1.d, v2.d, v3.d }[0], [x3]	/* D4 */
+	ret
+13:	st3	{ v0.d, v1.d, v2.d }[0], [x3]	/* D3 */
+	ret
+14:	stp	d0, d1, [x3]		/* D2 */
+	ret
+15:	str	d0, [x3]		/* D1 */
+	ret
+16:	str	q3, [x3, #48]		/* Q4 */
+	nop
+17:	str	q2, [x3, #32]		/* Q3 */
+	nop
+18:	stp	q0, q1, [x3]		/* Q2 */
+	ret
+19:	str	q0, [x3]		/* Q1 */
+	ret
+20:	uxtb	w0, w0			/* UINT8 */
+	str	x0, [x3]
+21:	ret				/* reserved */
+	nop
+22:	uxth	w0, w0			/* UINT16 */
+	str	x0, [x3]
+23:	ret				/* reserved */
+	nop
+24:	mov	w0, w0			/* UINT32 */
+	str	x0, [x3]
+25:	ret				/* reserved */
+	nop
+26:	sxtb	x0, w0			/* SINT8 */
+	str	x0, [x3]
+27:	ret				/* reserved */
+	nop
+28:	sxth	x0, w0			/* SINT16 */
+	str	x0, [x3]
+29:	ret				/* reserved */
+	nop
+30:	sxtw	x0, w0			/* SINT32 */
+	str	x0, [x3]
+31:	ret				/* reserved */
+	nop
+
+	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
+
+/* 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
+	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
+	cfi_startproc
+CNAME(ffi_closure_SYSV):
+	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 */
+.Ldo_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      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 #3
+	add	x3, sp, #16+CALL_CONTEXT_SIZE
+	br	x1
+
+	/* Note that each table entry is 2 insns, and thus 8 bytes.  */
+	.align	4
+0:	b	99f			/* VOID */
+	nop
+1:	ldr	x0, [x3]		/* INT64 */
+	b	99f
+2:	ldp	x0, x1, [x3]		/* INT128 */
+	b	99f
+3:	brk	#1000			/* UNUSED */
+	nop
+4:	brk	#1000			/* UNUSED */
+	nop
+5:	brk	#1000			/* UNUSED */
+	nop
+6:	brk	#1000			/* UNUSED */
+	nop
+7:	brk	#1000			/* UNUSED */
+	nop
+8:	ldr	s3, [x3, #12]		/* S4 */
+	nop
+9:	ldr	s2, [x3, #8]		/* S3 */
+	nop
+10:	ldp	s0, s1, [x3]		/* S2 */
+	b	99f
+11:	ldr	s0, [x3]		/* S1 */
+	b	99f
+12:	ldr	d3, [x3, #24]		/* D4 */
+	nop
+13:	ldr	d2, [x3, #16]		/* D3 */
+	nop
+14:	ldp	d0, d1, [x3]		/* D2 */
+	b	99f
+15:	ldr	d0, [x3]		/* D1 */
+	b	99f
+16:	ldr	q3, [x3, #48]		/* Q4 */
+	nop
+17:	ldr	q2, [x3, #32]		/* Q3 */
+	nop
+18:	ldp	q0, q1, [x3]		/* Q2 */
+	b	99f
+19:	ldr	q0, [x3]		/* Q1 */
+	b	99f
+20:	ldrb	w0, [x3, #BE(7)]	/* UINT8 */
+	b	99f
+21:	brk	#1000			/* reserved */
+	nop
+22:	ldrh	w0, [x3, #BE(6)]	/* UINT16 */
+	b	99f
+23:	brk	#1000			/* reserved */
+	nop
+24:	ldr	w0, [x3, #BE(4)]	/* UINT32 */
+	b	99f
+25:	brk	#1000			/* reserved */
+	nop
+26:	ldrsb	x0, [x3, #BE(7)]	/* SINT8 */
+	b	99f
+27:	brk	#1000			/* reserved */
+	nop
+28:	ldrsh	x0, [x3, #BE(6)]	/* SINT16 */
+	b	99f
+29:	brk	#1000			/* reserved */
+	nop
+30:	ldrsw	x0, [x3, #BE(4)]	/* SINT32 */
+	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)
+	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 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 that 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
+	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
+	cfi_startproc
+CNAME(ffi_go_closure_SYSV):
+	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	.Ldo_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 /* __arm64__ */
+
+#if defined __ELF__ && defined __linux__
+	.section .note.GNU-stack,"",%progbits
+#endif
+

+ 521 - 0
libffi.mod/libffi/src/alpha/ffi.c

@@ -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;
+}

+ 57 - 0
libffi.mod/libffi/src/alpha/ffitarget.h

@@ -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

+ 23 - 0
libffi.mod/libffi/src/alpha/internal.h

@@ -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))

+ 282 - 0
libffi.mod/libffi/src/alpha/osf.S

@@ -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

+ 135 - 0
libffi.mod/libffi/src/arc/arcompact.S

@@ -0,0 +1,135 @@
+/* -----------------------------------------------------------------------
+   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
+
+.text
+
+        /* R0:   ffi_prep_args */
+        /* R1:   &ecif */
+        /* R2:   cif->bytes */
+        /* R3:   fig->flags */
+        /* R4:   ecif.rvalue */
+        /* R5:   fn */
+ENTRY(ffi_call_ARCompact)
+        /* Save registers.  */
+        st.a       fp, [sp, -4]        /* fp + 20, fp */
+        push_s     blink               /* fp + 16, blink */
+        st.a       r4, [sp, -4]        /* fp + 12, ecif.rvalue */
+        push_s     r3                  /* fp +  8, fig->flags */
+        st.a       r5, [sp, -4]        /* fp +  4, fn */
+        push_s     r2                  /* fp +  0, cif->bytes */
+        mov        fp, sp
+
+        /* Make room for all of the new args.  */
+        sub        sp, sp, r2
+
+        /* Place all of the ffi_prep_args in position.  */
+        /* ffi_prep_args(char *stack, extended_cif *ecif) */
+        /* R1 already set.  */
+
+        /* And call.  */
+        jl_s.d     [r0]
+        mov_s      r0, sp
+
+        ld.ab      r12, [fp, 4]        /* cif->bytes */
+        ld.ab      r11, [fp, 4]        /* fn */
+
+        /* Move first 8 parameters in registers...  */
+        ld_s       r0, [sp]
+        ld_s       r1, [sp, 4]
+        ld_s       r2, [sp, 8]
+        ld_s       r3, [sp, 12]
+        ld         r4, [sp, 16]
+        ld         r5, [sp, 20]
+        ld         r6, [sp, 24]
+        ld         r7, [sp, 28]
+
+        /* ...and adjust the stack.  */
+        min        r12, r12, 32
+
+        /* Call the function.  */
+        jl.d       [r11]
+        add        sp, sp, r12 
+
+        mov        sp, fp        
+        pop_s      r3        /* fig->flags, return type */
+        pop_s      r2        /* ecif.rvalue, pointer for return value */
+
+        /* If the return value pointer is NULL, assume no return value.  */
+        breq.d     r2, 0, epilogue
+        pop_s      blink
+
+        /* Return INT.  */
+        brne       r3, FFI_TYPE_INT, return_double
+        b.d        epilogue
+        st_s       r0, [r2]        
+
+return_double:
+        brne       r3, FFI_TYPE_DOUBLE, epilogue
+        st_s       r0, [r2]        
+        st_s       r1, [r2,4]
+
+epilogue:
+        j_s.d      [blink]
+        ld.ab      fp, [sp, 4]
+
+ENTRY(ffi_closure_ARCompact)
+        st.a       r0, [sp, -32]
+        st_s       r1, [sp, 4]
+        st_s       r2, [sp, 8]
+        st_s       r3, [sp, 12]
+        st         r4, [sp, 16]
+        st         r5, [sp, 20]
+        st         r6, [sp, 24]
+        st         r7, [sp, 28]
+
+        /* pointer to arguments */
+        mov_s      r2, sp
+
+        /* return value goes here */
+        sub        sp, sp, 8
+        mov_s      r1, sp
+
+        push_s     blink
+        
+        bl.d       ffi_closure_inner_ARCompact
+        mov_s      r0, r8                /* codeloc, set by trampoline */
+
+        pop_s      blink
+
+        /* set return value to r1:r0 */
+        pop_s      r0
+        pop_s      r1
+        j_s.d      [blink]
+        add_s      sp, sp, 32

+ 266 - 0
libffi.mod/libffi/src/arc/ffi.c

@@ -0,0 +1,266 @@
+/* -----------------------------------------------------------------------
+   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>
+
+/* 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
+
+/* 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;
+  void **p_argv;
+  char *argp;
+  ffi_type **p_arg;
+
+  argp = stack;
+
+  if (ecif->cif->rtype->type == 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;
+      int alignment;
+
+      /* align alignment to 4 */
+      alignment = (((*p_arg)->alignment - 1) | 3) + 1;
+
+      /* Align if necessary.  */
+      if ((alignment - 1) & (unsigned) argp)
+	argp = (char *) FFI_ALIGN (argp, alignment);
+
+      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:
+	      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
+	{
+	  if ((*p_arg)->type == FFI_TYPE_STRUCT)
+	    {
+	      memcpy (argp, *p_argv, z);
+	    }
+	  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:
+      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_ARCompact (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_ARCOMPACT:
+      ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes,
+			  cif->flags, ecif.rvalue, fn);
+      break;
+
+    default:
+      FFI_ASSERT (0);
+      break;
+    }
+}
+
+int
+ffi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue,
+			     ffi_arg * args)
+{
+  void **arg_area, **p_argv;
+  ffi_cif *cif = closure->cif;
+  char *argp = (char *) args;
+  ffi_type **p_argt;
+  int i;
+
+  arg_area = (void **) alloca (cif->nargs * sizeof (void *));
+
+  /* handle hidden argument */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      rvalue = *(void **) argp;
+      argp += 4;
+    }
+
+  p_argv = arg_area;
+
+  for (i = 0, p_argt = cif->arg_types; i < cif->nargs;
+       i++, p_argt++, p_argv++)
+    {
+      size_t z;
+      int alignment;
+
+      /* align alignment to 4 */
+      alignment = (((*p_argt)->alignment - 1) | 3) + 1;
+
+      /* Align if necessary.  */
+      if ((alignment - 1) & (unsigned) argp)
+	argp = (char *) FFI_ALIGN (argp, alignment);
+
+      z = (*p_argt)->size;
+      *p_argv = (void *) argp;
+      argp += z;
+    }
+
+  (closure->fun) (cif, rvalue, arg_area, closure->user_data);
+
+  return cif->flags;
+}
+
+extern void ffi_closure_ARCompact (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)
+{
+  uint32_t *tramp = (uint32_t *) & (closure->tramp[0]);
+
+  switch (cif->abi)
+    {
+    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 (ffi_closure_ARCompact);
+      break;
+
+    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;
+}

+ 53 - 0
libffi.mod/libffi/src/arc/ffitarget.h

@@ -0,0 +1,53 @@
+/* -----------------------------------------------------------------------
+   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,
+  FFI_ARCOMPACT,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_ARCOMPACT
+} ffi_abi;
+#endif
+
+#define FFI_CLOSURES 		1
+#define FFI_TRAMPOLINE_SIZE	12
+#define FFI_NATIVE_RAW_API 	0
+
+#endif

+ 822 - 0
libffi.mod/libffi/src/arm/ffi.c

@@ -0,0 +1,822 @@
+/* -----------------------------------------------------------------------
+   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.
+   ----------------------------------------------------------------------- */
+
+#ifdef __arm__
+#include <fficonfig.h>
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "internal.h"
+
+#if FFI_EXEC_TRAMPOLINE_TABLE
+
+#ifdef __MACH__
+#include <mach/machine/vm_param.h>
+#endif
+
+#else
+extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
+#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:
+    case FFI_TYPE_FLOAT:
+      *(UINT32 *)dst = *(UINT32 *)src;
+      break;
+
+    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);
+}
+
+void
+ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue,
+	     void **avalue, void *closure)
+{
+  ffi_call_int (cif, fn, rvalue, avalue, closure);
+}
+
+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;
+}
+
+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;
+void ffi_go_closure_SYSV (void) FFI_HIDDEN;
+void ffi_go_closure_VFP (void) FFI_HIDDEN;
+
+/* 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) (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
+  memcpy (closure->tramp, ffi_arm_trampoline, 8);
+#if defined (__QNX__)
+  msync(closure->tramp, 8, 0x1000000);	/* clear data map */
+  msync(codeloc, 8, 0x1000000);	/* clear insn map */
+#else
+  __clear_cache(closure->tramp, closure->tramp + 8);	/* clear data map */
+  __clear_cache(codeloc, codeloc + 8);			/* clear insn map */
+#endif
+  *(void (**)(void))(closure->tramp + 8) = closure_func;
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
+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;
+}
+
+/* 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++] = 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)
+{
+  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;
+    }
+}
+
+#endif /* __arm__ */

+ 82 - 0
libffi.mod/libffi/src/arm/ffitarget.h

@@ -0,0 +1,82 @@
+/* -----------------------------------------------------------------*-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,
+#ifdef __ARM_PCS_VFP
+  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
+#define FFI_TARGET_HAS_COMPLEX_TYPE
+
+/* ---- 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
+#define FFI_TRAMPOLINE_SIZE 12
+#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
+#endif
+
+#endif

+ 7 - 0
libffi.mod/libffi/src/arm/internal.h

@@ -0,0 +1,7 @@
+#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

+ 385 - 0
libffi.mod/libffi/src/arm/sysv.S

@@ -0,0 +1,385 @@
+/* -----------------------------------------------------------------------
+   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)
+
+/* Aid in defining a jump table with 8 bytes between entries.  */
+/* ??? The clang assembler doesn't handle .if with symbolic expressions.  */
+#ifdef __clang__
+# define E(index)
+#else
+# define E(index)				\
+	.if . - 0b - 8*index;			\
+	.error "type table out of sync";	\
+	.endif
+#endif
+
+	.text
+	.syntax unified
+	.arm
+
+#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
+#ifdef __clang__
+	vldrle d0, [sp]
+	vldmgt sp, {d0-d7}
+#else
+	ldcle	p11, cr0, [r0]		@ vldrle d0, [sp]
+	ldcgt	p11, cr0, [r0], {16}	@ vldmgt sp, {d0-d7}
+#endif
+	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.
+	.align	3
+	add	pc, pc, r3, lsl #3
+	nop
+0:
+E(ARM_TYPE_VFP_S)
+#ifdef __clang__
+	vstr s0, [r2]
+#else
+	stc	p10, cr0, [r2]		@ vstr s0, [r2]
+#endif
+	pop	{fp,pc}
+E(ARM_TYPE_VFP_D)
+#ifdef __clang__
+	vstr d0, [r2]
+#else
+	stc	p11, cr0, [r2]		@ vstr d0, [r2]
+#endif
+	pop	{fp,pc}
+E(ARM_TYPE_VFP_N)
+#ifdef __clang__
+	vstm r2, {d0-d3}
+#else
+	stc	p11, cr0, [r2], {8}	@ vstm r2, {d0-d3}
+#endif
+	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)
+
+
+/*
+	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
+	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)
+	add	pc, r3, r0, lsl #3
+	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
+	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)
+#ifdef __clang__
+	vstm sp, {d0-d7}
+#else
+	stc	p11, cr0, [sp], {16}		@ vstm sp, {d0-d7}
+#endif
+	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)
+	add	pc, r3, r0, lsl #3
+	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)
+#ifdef __clang__
+	vldr s0, [r2]
+#else
+	ldc	p10, cr0, [r2]			@ vldr s0, [r2]
+#endif
+	ldm	sp, {sp,pc}
+E(ARM_TYPE_VFP_D)
+#ifdef __clang__
+	vldr d0, [r2]
+#else
+	ldc	p11, cr0, [r2]			@ vldr d0, [r2]
+#endif
+	ldm	sp, {sp,pc}
+E(ARM_TYPE_VFP_N)
+#ifdef __clang__
+	vldm r2, {d0-d3}
+#else
+	ldc	p11, cr0, [r2], {8}		@ vldm r2, {d0-d3}
+#endif
+	ldm	sp, {sp,pc}
+E(ARM_TYPE_INT64)
+	ldr	r1, [r2, #4]
+	nop
+E(ARM_TYPE_INT)
+	ldr	r0, [r2]
+	ldm	sp, {sp,pc}
+E(ARM_TYPE_VOID)
+	ldm	sp, {sp,pc}
+	nop
+E(ARM_TYPE_STRUCT)
+	ldm	sp, {sp,pc}
+	cfi_endproc
+ARM_FUNC_END(ffi_closure_ret)
+
+#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
+
+#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

+ 423 - 0
libffi.mod/libffi/src/avr32/ffi.c

@@ -0,0 +1,423 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2011  Anthony Green
+           Copyright (c) 2009  Bradley Smith <[email protected]>
+
+   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;
+}
+

+ 55 - 0
libffi.mod/libffi/src/avr32/ffitarget.h

@@ -0,0 +1,55 @@
+/* -----------------------------------------------------------------*-C-*-
+   ffitarget.h - Copyright (c) 2012  Anthony Green
+                 Copyright (c) 2009  Bradley Smith <[email protected]>
+   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

+ 208 - 0
libffi.mod/libffi/src/avr32/sysv.S

@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2009  Bradley Smith <[email protected]>
+
+   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

+ 196 - 0
libffi.mod/libffi/src/bfin/ffi.c

@@ -0,0 +1,196 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2012  Alexandre K. I. de Mendonca <[email protected]>,
+							   Paulo Pizarro <[email protected]>
+
+   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;
+   }
+}
+
+
+

+ 43 - 0
libffi.mod/libffi/src/bfin/ffitarget.h

@@ -0,0 +1,43 @@
+/* -----------------------------------------------------------------------
+   ffitarget.h - Copyright (c) 2012  Alexandre K. I. de Mendonca <[email protected]>
+
+   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
+

+ 179 - 0
libffi.mod/libffi/src/bfin/sysv.S

@@ -0,0 +1,179 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2012  Alexandre K. I. de Mendonca <[email protected]>,
+                                Paulo Pizarro <[email protected]>
+
+   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

+ 979 - 0
libffi.mod/libffi/src/closures.c

@@ -0,0 +1,979 @@
+/* -----------------------------------------------------------------------
+   closures.c - Copyright (c) 2007, 2009, 2010  Red Hat, Inc.
+                Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
+                Copyright (c) 2011 Plausible Labs Cooperative, Inc.
+
+   Code to allocate and deallocate memory for closures.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+   DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#if defined __linux__ && !defined _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include <fficonfig.h>
+#include <ffi.h>
+#include <ffi_common.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>
+
+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);
+}
+#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(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
+/* Windows systems may have Data Execution Protection (DEP) enabled, 
+   which requires the use of VirtualMalloc/VirtualFree to alloc/free
+   executable memory. */
+#  define FFI_MMAP_EXEC_WRIT 1
+# endif
+#endif
+
+#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
+# if defined(__linux__) && !defined(__ANDROID__)
+/* When defined to 1 check for SELinux and if SELinux is active,
+   don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
+   might cause audit messages.  */
+#  define FFI_MMAP_EXEC_SELINUX 1
+# endif
+#endif
+
+#if FFI_CLOSURES
+
+#if FFI_EXEC_TRAMPOLINE_TABLE
+
+#ifdef __MACH__
+
+#include <mach/mach.h>
+#include <pthread.h>
+#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;
+  vm_address_t trampoline_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;
+  trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
+#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;
+    }
+
+  /* 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;
+  table->trampoline_page = trampoline_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 *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
+
+      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(X86_WIN32) && !defined(X86_WIN64)
+#ifdef HAVE_MNTENT
+#include <mntent.h>
+#endif /* HAVE_MNTENT */
+#include <sys/param.h>
+#include <pthread.h>
+
+/* We don't want sys/mman.h to be included after we redefine mmap and
+   dlmunmap.  */
+#include <sys/mman.h>
+#define LACKS_SYS_MMAN_H 1
+
+#if FFI_MMAP_EXEC_SELINUX
+#include <sys/statfs.h>
+#include <stdlib.h>
+
+static int selinux_enabled = -1;
+
+static int
+selinux_enabled_check (void)
+{
+  struct statfs sfs;
+  FILE *f;
+  char *buf = NULL;
+  size_t len = 0;
+
+  if (statfs ("/selinux", &sfs) >= 0
+      && (unsigned int) sfs.f_type == 0xf97cff8cU)
+    return 1;
+  f = fopen ("/proc/mounts", "r");
+  if (f == NULL)
+    return 0;
+  while (getline (&buf, &len, f) >= 0)
+    {
+      char *p = strchr (buf, ' ');
+      if (p == NULL)
+        break;
+      p = strchr (p + 1, ' ');
+      if (p == NULL)
+        break;
+      if (strncmp (p + 1, "selinuxfs ", 10) == 0)
+        {
+          free (buf);
+          fclose (f);
+          return 1;
+        }
+    }
+  free (buf);
+  fclose (f);
+  return 0;
+}
+
+#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
+			      : (selinux_enabled = selinux_enabled_check ()))
+
+#else
+
+#define is_selinux_enabled() 0
+
+#endif /* !FFI_MMAP_EXEC_SELINUX */
+
+/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */
+#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
+#include <stdlib.h>
+
+static int emutramp_enabled = -1;
+
+static int
+emutramp_enabled_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))
+      {
+        char emutramp;
+        if (sscanf (buf, "%*s %*c%c", &emutramp) == 1)
+          ret = (emutramp == 'E');
+        break;
+      }
+  free (buf);
+  fclose (f);
+  return ret;
+}
+
+#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \
+                               : (emutramp_enabled = emutramp_enabled_check ()))
+#endif /* FFI_MMAP_EXEC_EMUTRAMP_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) */
+
+#ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX
+#define is_emutramp_enabled() 0
+#endif /* FFI_MMAP_EXEC_EMUTRAMP_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(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+/* Use these for mmap and munmap within dlmalloc.c.  */
+static void *dlmmap(void *, size_t, int, int, int, off_t);
+static int dlmunmap(void *, size_t);
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+
+#define mmap dlmmap
+#define munmap dlmunmap
+
+#include "dlmalloc.c"
+
+#undef mmap
+#undef munmap
+
+#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
+
+/* A mutex used to synchronize access to *exec* variables in this file.  */
+static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* A file descriptor of a temporary file from which we'll map
+   executable pages.  */
+static int execfd = -1;
+
+/* The amount of space already allocated from the temporary file.  */
+static size_t execsize = 0;
+
+/* Open a temporary file name, and immediately unlink it.  */
+static int
+open_temp_exec_file_name (char *name, int flags)
+{
+  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[] = {
+  { 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.  */
+static int
+open_temp_exec_file (void)
+{
+  int fd;
+
+  do
+    {
+      fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
+	(open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
+
+      if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
+	  || fd == -1)
+	{
+	  if (open_temp_exec_file_opts_next ())
+	    break;
+	}
+    }
+  while (fd == -1);
+
+  return fd;
+}
+
+/* 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 offset, off_t len)
+{
+  static size_t 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, offset, length))
+    return MFAIL;
+
+  flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
+  flags |= MAP_SHARED;
+
+  ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
+	      flags, execfd, offset);
+  if (ptr == MFAIL)
+    {
+      if (!offset)
+	{
+	  close (execfd);
+	  goto retry_open;
+	}
+      ftruncate (execfd, offset);
+      return MFAIL;
+    }
+  else if (!offset
+	   && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
+    open_temp_exec_file_opts_next ();
+
+  start = mmap (start, length, prot, flags, execfd, offset);
+
+  if (start == MFAIL)
+    {
+      munmap (ptr, length);
+      ftruncate (execfd, offset);
+      return start;
+    }
+
+  mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
+
+  execsize += length;
+
+  return start;
+}
+
+/* Map in a writable and executable chunk of memory if possible.
+   Failing that, fall back to dlmmap_locked.  */
+static void *
+dlmmap (void *start, size_t length, int prot,
+	int flags, int fd, off_t offset)
+{
+  void *ptr;
+
+  assert (start == NULL && length % malloc_getpagesize == 0
+	  && prot == (PROT_READ | PROT_WRITE)
+	  && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
+	  && fd == -1 && offset == 0);
+
+  if (execfd == -1 && is_emutramp_enabled ())
+    {
+      ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
+      return ptr;
+    }
+
+  if (execfd == -1 && !is_selinux_enabled ())
+    {
+      ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
+
+      if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
+	/* Cool, no need to mess with separate segments.  */
+	return ptr;
+
+      /* If MREMAP_DUP is ever introduced and implemented, try mmap
+	 with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
+	 MREMAP_DUP and prot at this point.  */
+    }
+
+  if (execsize == 0 || execfd == -1)
+    {
+      pthread_mutex_lock (&open_temp_exec_file_mutex);
+      ptr = dlmmap_locked (start, length, prot, flags, offset);
+      pthread_mutex_unlock (&open_temp_exec_file_mutex);
+
+      return ptr;
+    }
+
+  return dlmmap_locked (start, length, prot, flags, offset);
+}
+
+/* Release memory at the given address, as well as the corresponding
+   executable page if it's separate.  */
+static int
+dlmunmap (void *start, size_t length)
+{
+  /* We don't bother decreasing execsize or truncating the file, since
+     we can't quite tell whether we're unmapping the end of the file.
+     We don't expect frequent deallocation anyway.  If we did, we
+     could locate pages in the file by writing to the pages being
+     deallocated and checking that the file contents change.
+     Yuck.  */
+  msegmentptr seg = segment_holding (gm, start);
+  void *code;
+
+  if (seg && (code = add_segment_exec_offset (start, seg)) != start)
+    {
+      int ret = munmap (code, length);
+      if (ret)
+	return ret;
+    }
+
+  return munmap (start, length);
+}
+
+#if FFI_CLOSURE_FREE_CODE
+/* Return segment holding given code address.  */
+static msegmentptr
+segment_holding_code (mstate m, char* addr)
+{
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if (addr >= add_segment_exec_offset (sp->base, sp)
+	&& addr < add_segment_exec_offset (sp->base, sp) + sp->size)
+      return sp;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+#endif
+
+#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
+
+/* Allocate a chunk of memory with the given size.  Returns a pointer
+   to the writable address, and sets *CODE to the executable
+   corresponding virtual address.  */
+void *
+ffi_closure_alloc (size_t size, void **code)
+{
+  void *ptr;
+
+  if (!code)
+    return NULL;
+
+  ptr = dlmalloc (size);
+
+  if (ptr)
+    {
+      msegmentptr seg = segment_holding (gm, ptr);
+
+      *code = add_segment_exec_offset (ptr, seg);
+    }
+
+  return ptr;
+}
+
+void *
+ffi_data_to_code_pointer (void *data)
+{
+  msegmentptr seg = segment_holding (gm, data);
+  return add_segment_exec_offset (data, seg);
+}
+
+/* Release a chunk of memory allocated with ffi_closure_alloc.  If
+   FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
+   writable or the executable address given.  Otherwise, only the
+   writable address can be provided here.  */
+void
+ffi_closure_free (void *ptr)
+{
+#if FFI_CLOSURE_FREE_CODE
+  msegmentptr seg = segment_holding_code (gm, ptr);
+
+  if (seg)
+    ptr = sub_segment_exec_offset (ptr, seg);
+#endif
+
+  dlfree (ptr);
+}
+
+# else /* ! FFI_MMAP_EXEC_WRIT */
+
+/* On many systems, memory returned by malloc is writable and
+   executable, so just use it.  */
+
+#include <stdlib.h>
+
+void *
+ffi_closure_alloc (size_t size, void **code)
+{
+  if (!code)
+    return NULL;
+
+  return *code = malloc (size);
+}
+
+void
+ffi_closure_free (void *ptr)
+{
+  free (ptr);
+}
+
+void *
+ffi_data_to_code_pointer (void *data)
+{
+  return data;
+}
+
+# endif /* ! FFI_MMAP_EXEC_WRIT */
+#endif /* FFI_CLOSURES */
+
+#endif /* NetBSD with PROT_MPROTECT */

+ 386 - 0
libffi.mod/libffi/src/cris/ffi.c

@@ -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;
+}

+ 56 - 0
libffi.mod/libffi/src/cris/ffitarget.h

@@ -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

+ 215 - 0
libffi.mod/libffi/src/cris/sysv.S

@@ -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

+ 64 - 0
libffi.mod/libffi/src/debug.c

@@ -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 */
+
+void ffi_assert(char *expr, 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, 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);
+
+}

+ 5166 - 0
libffi.mod/libffi/src/dlmalloc.c

@@ -0,0 +1,5166 @@
+/*
+  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 [email protected]
+
+* 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.
+*/
+
+#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 = 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;
+
+  /* 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() {
+  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 <[email protected]>.
+        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 <[email protected]> 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 ([email protected]).
+      * Use last_remainder in more cases.
+      * Pack bins using idea from  [email protected]
+      * 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
+        ([email protected]) 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 ([email protected]).
+      * Added macros etc., allowing use in linux libc from
+        H.J. Lu ([email protected])
+      * 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 ([email protected]) 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
+        ([email protected]).
+
+    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 [email protected]
+
+    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 [email protected]
+
+    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.)
+ 
+*/

+ 128 - 0
libffi.mod/libffi/src/frv/eabi.S

@@ -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
+	

+ 292 - 0
libffi.mod/libffi/src/frv/ffi.c

@@ -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;
+}

+ 62 - 0
libffi.mod/libffi/src/frv/ffitarget.h

@@ -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

+ 604 - 0
libffi.mod/libffi/src/ia64/ffi.c

@@ -0,0 +1,604 @@
+/* -----------------------------------------------------------------------
+   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".  */
+typedef void *PTR64 __attribute__((mode(DI)));
+
+/* 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.  */
+
+#define stf_spill(addr, value)	\
+  asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
+
+/* Load a value from ADDR, which is in the current cpu implementation's
+   fp spill format.  As above, this must also be a macro.  */
+
+#define ldf_fill(result, addr)	\
+  asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr));
+
+/* 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;
+}

+ 56 - 0
libffi.mod/libffi/src/ia64/ffitarget.h

@@ -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

+ 40 - 0
libffi.mod/libffi/src/ia64/ia64_flags.h

@@ -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)

+ 567 - 0
libffi.mod/libffi/src/ia64/unix.S

@@ -0,0 +1,567 @@
+/* -----------------------------------------------------------------------
+   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
+
+/* 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
+	;;
+	ld8.mov	r18 = [r18], .Lst_table
+	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
+	;;
+	ld8.mov	r18 = [r18], .Lld_table
+	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
+
+	.section .rodata
+	.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

+ 374 - 0
libffi.mod/libffi/src/java_raw_api.c

@@ -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 <[email protected]>
+   Java_raw_api.c author: Hans-J. Boehm <[email protected]>
+
+   $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 */

+ 232 - 0
libffi.mod/libffi/src/m32r/ffi.c

@@ -0,0 +1,232 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2004  Renesas Technology
+           Copyright (c) 2008  Red Hat, Inc.
+   
+   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;
+
+  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);
+      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;
+    }
+}

+ 53 - 0
libffi.mod/libffi/src/m32r/ffitarget.h

@@ -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

+ 121 - 0
libffi.mod/libffi/src/m32r/sysv.S

@@ -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)

+ 362 - 0
libffi.mod/libffi/src/m68k/ffi.c

@@ -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;
+}

+ 54 - 0
libffi.mod/libffi/src/m68k/ffitarget.h

@@ -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
+

+ 357 - 0
libffi.mod/libffi/src/m68k/sysv.S

@@ -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

+ 400 - 0
libffi.mod/libffi/src/m88k/ffi.c

@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2013 Miodrag Vallat.  <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * ``Software''), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY 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;
+}

+ 49 - 0
libffi.mod/libffi/src/m88k/ffitarget.h

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 Miodrag Vallat.  <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * ``Software''), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY 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

+ 209 - 0
libffi.mod/libffi/src/m88k/obsd.S

@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2013 Miodrag Vallat.  <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * ``Software''), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY 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

+ 330 - 0
libffi.mod/libffi/src/metag/ffi.c

@@ -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;
+}

+ 53 - 0
libffi.mod/libffi/src/metag/ffitarget.h

@@ -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
+

+ 311 - 0
libffi.mod/libffi/src/metag/sysv.S

@@ -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]

+ 321 - 0
libffi.mod/libffi/src/microblaze/ffi.c

@@ -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;
+}

+ 53 - 0
libffi.mod/libffi/src/microblaze/ffitarget.h

@@ -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

Неке датотеке нису приказане због велике количине промена