summaryrefslogtreecommitdiff
path: root/devel/libffi
diff options
context:
space:
mode:
authorjklos <jklos@pkgsrc.org>2013-11-03 23:51:51 +0000
committerjklos <jklos@pkgsrc.org>2013-11-03 23:51:51 +0000
commit475df0b058205fb57645791ea19046a1aec6a85a (patch)
treed0209c37ab2ad38eacf89e3bcd379cda0be0fff6 /devel/libffi
parent46c7f27231ff8dddae464601c1e0fe2a8e766c14 (diff)
downloadpkgsrc-475df0b058205fb57645791ea19046a1aec6a85a.tar.gz
Add libffi support for VAX and m88k. Tested with netbsd-6 on VAX.
From Miod Vallat: https://sourceware.org/ml/libffi-discuss/2013/msg00165.html
Diffstat (limited to 'devel/libffi')
-rw-r--r--devel/libffi/distinfo12
-rw-r--r--devel/libffi/patches/patch-Makefile.am40
-rw-r--r--devel/libffi/patches/patch-aa66
-rw-r--r--devel/libffi/patches/patch-configure.ac42
-rw-r--r--devel/libffi/patches/patch-src_m88k_elfbsd.S200
-rw-r--r--devel/libffi/patches/patch-src_m88k_ffi.c405
-rw-r--r--devel/libffi/patches/patch-src_m88k_ffitarget.h54
-rw-r--r--devel/libffi/patches/patch-src_vax_elfbsd.S200
-rw-r--r--devel/libffi/patches/patch-src_vax_ffi.c281
-rw-r--r--devel/libffi/patches/patch-src_vax_ffitarget.h54
10 files changed, 1340 insertions, 14 deletions
diff --git a/devel/libffi/distinfo b/devel/libffi/distinfo
index 39718e31179..6f867de8cde 100644
--- a/devel/libffi/distinfo
+++ b/devel/libffi/distinfo
@@ -1,9 +1,10 @@
-$NetBSD: distinfo,v 1.29 2013/07/26 13:12:25 ryoon Exp $
+$NetBSD: distinfo,v 1.30 2013/11/03 23:51:51 jklos Exp $
SHA1 (libffi-3.0.13.tar.gz) = f5230890dc0be42fb5c58fbf793da253155de106
RMD160 (libffi-3.0.13.tar.gz) = 03f0627c0fcc800d38636258a2fab2d6bb8b6625
Size (libffi-3.0.13.tar.gz) = 845747 bytes
-SHA1 (patch-aa) = 2f750e47e2911711da9a06153c8c10cf143d2c58
+SHA1 (patch-Makefile.am) = 01109a0d5708835162a2d007a26decac5bb0bbac
+SHA1 (patch-aa) = 0a5f894f989c51951e3b4ea6f45631466e183181
SHA1 (patch-ac) = f3c6324f4334d23e684b4eca25173a13be5d37eb
SHA1 (patch-ad) = 8901a00abe25422e3e35f321a5fb89311185fc0b
SHA1 (patch-ae) = aa53d44c740806d54776530eeb7f7ff245d2022d
@@ -12,6 +13,13 @@ SHA1 (patch-ag) = 6333317170f6e92f89db966315276dcd8e3484f2
SHA1 (patch-ah) = e9580069ede90cd616da7bc230b28acbf5d204a6
SHA1 (patch-ai) = f85a6cb64d4a9d7c3e56b47b7092fce10a744b5b
SHA1 (patch-aj) = d130b2b20b94ca26c70dcc46614e36c6d0ac9153
+SHA1 (patch-configure.ac) = 7fc7490a5b62b00afff31824c1d86cf973d549be
SHA1 (patch-fficonfig.h.in) = fd85fa767bc057c843ff71cc61bedfcff84def43
+SHA1 (patch-src_m88k_elfbsd.S) = fae3e425dcff3e924ef195eab165f9bbc6ec4077
+SHA1 (patch-src_m88k_ffi.c) = e4b7382c3d6e253b8c1c6054150c530c21d018de
+SHA1 (patch-src_m88k_ffitarget.h) = e8479bc3aa876f5e6d52a4d578c5da88291c6646
+SHA1 (patch-src_vax_elfbsd.S) = abf284bd1db086a12608b7243344af30e4a314ca
+SHA1 (patch-src_vax_ffi.c) = f47ced03388e9744afa44d6bb5e14d5f4285cfbf
+SHA1 (patch-src_vax_ffitarget.h) = 388f3a58e37dd8af5c194b5be77a6ea6f9beef4b
SHA1 (patch-src_x86_ffi.c) = b9ac64a53a92de663a339212e22c1286fa41c1d5
SHA1 (patch-src_x86_win64.S) = 5b6836bae6c73743b925de4d11bc241c783bffd6
diff --git a/devel/libffi/patches/patch-Makefile.am b/devel/libffi/patches/patch-Makefile.am
new file mode 100644
index 00000000000..89521b781f9
--- /dev/null
+++ b/devel/libffi/patches/patch-Makefile.am
@@ -0,0 +1,40 @@
+$NetBSD: patch-Makefile.am,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- Makefile.am.orig 2013-03-16 11:52:11.000000000 +0000
++++ Makefile.am
+@@ -19,6 +19,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 Change
+ src/moxie/ffitarget.h src/moxie/eabi.S src/mips/ffitarget.h \
+ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
+ src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \
++ src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h \
+ src/microblaze/ffi.c src/microblaze/sysv.S \
+ src/microblaze/ffitarget.h src/powerpc/ffi.c \
+ src/powerpc/sysv.S src/powerpc/linux64.S \
+@@ -38,6 +39,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 Change
+ src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \
+ src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \
+ src/tile/ffitarget.h src/tile/tile.S libtool-version \
++ src/vax/ffi.c src/vax/ffitarget.h src/vax/elfbsd.S \
+ src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \
+ ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \
+ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \
+@@ -149,6 +151,9 @@ endif
+ if M68K
+ nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
+ endif
++if M88K
++nodist_libffi_la_SOURCES += src/m88k/ffi.c src/m88k/obsd.S
++endif
+ if MOXIE
+ nodist_libffi_la_SOURCES += src/moxie/ffi.c src/moxie/eabi.S
+ endif
+@@ -212,6 +217,9 @@ endif
+ if METAG
+ nodist_libffi_la_SOURCES += src/metag/sysv.S src/metag/ffi.c
+ endif
++if VAX
++nodist_libffi_la_SOURCES += src/vax/elfbsd.S src/vax/ffi.c
++endif
+
+ libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
+ nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
diff --git a/devel/libffi/patches/patch-aa b/devel/libffi/patches/patch-aa
index 709b6e24317..5c6162e5a5d 100644
--- a/devel/libffi/patches/patch-aa
+++ b/devel/libffi/patches/patch-aa
@@ -1,12 +1,17 @@
-$NetBSD: patch-aa,v 1.17 2013/04/06 12:41:23 obache Exp $
-
-Extend which ports we accept to deal with.
-
-Disable multilib directories.
+$NetBSD: patch-aa,v 1.18 2013/11/03 23:51:51 jklos Exp $
--- configure.orig 2013-03-17 22:36:19.000000000 +0000
+++ configure
-@@ -13331,7 +13331,7 @@ case "$host" in
+@@ -651,6 +651,8 @@ XTENSA_FALSE
+ XTENSA_TRUE
+ TILE_FALSE
+ TILE_TRUE
++VAX_FALSE
++VAX_TRUE
+ PA64_HPUX_FALSE
+ PA64_HPUX_TRUE
+ PA_HPUX_FALSE
+@@ -13331,7 +13333,7 @@ case "$host" in
TARGET=FRV; TARGETDIR=frv
;;
@@ -15,7 +20,7 @@ Disable multilib directories.
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
-@@ -13428,7 +13428,7 @@ case "$host" in
+@@ -13428,7 +13430,7 @@ case "$host" in
mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
TARGET=MIPS; TARGETDIR=mips
;;
@@ -24,7 +29,7 @@ Disable multilib directories.
# Support 128-bit long double for NewABI.
HAVE_LONG_DOUBLE='defined(__mips64)'
TARGET=MIPS; TARGETDIR=mips
-@@ -13449,7 +13449,7 @@ case "$host" in
+@@ -13449,7 +13451,7 @@ case "$host" in
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
@@ -33,7 +38,7 @@ Disable multilib directories.
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc64-*-freebsd*)
-@@ -13463,7 +13463,7 @@ case "$host" in
+@@ -13463,7 +13465,7 @@ case "$host" in
TARGET=S390; TARGETDIR=s390
;;
@@ -42,7 +47,33 @@ Disable multilib directories.
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
-@@ -14661,7 +14661,7 @@ case "$target" in
+@@ -13478,6 +13480,10 @@ case "$host" in
+ TARGET=TILE; TARGETDIR=tile
+ ;;
+
++ vax-*-*)
++ TARGET=VAX; TARGETDIR=vax
++ ;;
++
+ xtensa*-*)
+ TARGET=XTENSA; TARGETDIR=xtensa
+ ;;
+@@ -13747,6 +13753,14 @@ else
+ TILE_FALSE=
+ fi
+
++ if test x$TARGET = xVAX; then
++ VAX_TRUE=
++ VAX_FALSE='#'
++else
++ VAX_TRUE='#'
++ VAX_FALSE=
++fi
++
+ if test x$TARGET = xXTENSA; then
+ XTENSA_TRUE=
+ XTENSA_FALSE='#'
+@@ -14661,7 +14675,7 @@ case "$target" in
$as_echo "#define FFI_EXEC_TRAMPOLINE_TABLE 1" >>confdefs.h
;;
@@ -51,7 +82,7 @@ Disable multilib directories.
$as_echo "#define FFI_MMAP_EXEC_WRIT 1" >>confdefs.h
-@@ -14840,11 +14840,6 @@ if test "x$GCC" = "xyes"; then
+@@ -14840,11 +14854,6 @@ if test "x$GCC" = "xyes"; then
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
@@ -63,7 +94,18 @@ Disable multilib directories.
else
toolexeclibdir='$(libdir)'
-@@ -16734,13 +16729,13 @@ s/ [a-zA-Z0-9-]*-all [a-zA-Z0-9-]*-all-a
+@@ -15135,6 +15144,10 @@ if test -z "${TILE_TRUE}" && test -z "${
+ as_fn_error $? "conditional \"TILE\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+ fi
++if test -z "${VAX_TRUE}" && test -z "${VAX_FALSE}"; then
++ as_fn_error $? "conditional \"VAX\" was never defined.
++Usually this means the macro was only invoked conditionally." "$LINENO" 5
++fi
+ if test -z "${XTENSA_TRUE}" && test -z "${XTENSA_FALSE}"; then
+ as_fn_error $? "conditional \"XTENSA\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+@@ -16734,13 +16751,13 @@ s/ [a-zA-Z0-9-]*-all [a-zA-Z0-9-]*-all-a
/-all-all/d
a\\
@ HOST="\$(HOST)\" \\\\\\
diff --git a/devel/libffi/patches/patch-configure.ac b/devel/libffi/patches/patch-configure.ac
new file mode 100644
index 00000000000..1c7d0bd336f
--- /dev/null
+++ b/devel/libffi/patches/patch-configure.ac
@@ -0,0 +1,42 @@
+$NetBSD: patch-configure.ac,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- configure.ac.orig 2013-03-17 22:36:15.000000000 +0000
++++ configure.ac
+@@ -191,6 +191,10 @@ case "$host" in
+ TARGET=M68K; TARGETDIR=m68k
+ ;;
+
++ m88k-*-*)
++ TARGET=M88K; TARGETDIR=m88k
++ ;;
++
+ microblaze*-*-*)
+ TARGET=MICROBLAZE; TARGETDIR=microblaze
+ ;;
+@@ -256,6 +260,10 @@ case "$host" in
+ TARGET=TILE; TARGETDIR=tile
+ ;;
+
++ vax-*-*)
++ TARGET=VAX; TARGETDIR=vax
++ ;;
++
+ xtensa*-*)
+ TARGET=XTENSA; TARGETDIR=xtensa
+ ;;
+@@ -281,6 +289,7 @@ AM_CONDITIONAL(ALPHA, test x$TARGET = xA
+ AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
+ AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
+ AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
++AM_CONDITIONAL(M88K, test x$TARGET = xM88K)
+ AM_CONDITIONAL(MICROBLAZE, test x$TARGET = xMICROBLAZE)
+ AM_CONDITIONAL(METAG, test x$TARGET = xMETAG)
+ AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
+@@ -301,6 +310,7 @@ AM_CONDITIONAL(PA_LINUX, test x$TARGET =
+ AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
+ AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
+ AM_CONDITIONAL(TILE, test x$TARGET = xTILE)
++AM_CONDITIONAL(VAX, test x$TARGET = xVAX)
+ AM_CONDITIONAL(XTENSA, test x$TARGET = xXTENSA)
+
+ AC_HEADER_STDC
diff --git a/devel/libffi/patches/patch-src_m88k_elfbsd.S b/devel/libffi/patches/patch-src_m88k_elfbsd.S
new file mode 100644
index 00000000000..644ce2c221b
--- /dev/null
+++ b/devel/libffi/patches/patch-src_m88k_elfbsd.S
@@ -0,0 +1,200 @@
+$NetBSD: patch-src_m88k_elfbsd.S,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- src/m88k/elfbsd.S.orig 2013-11-03 22:57:57.000000000 +0000
++++ src/m88k/elfbsd.S
+@@ -0,0 +1,195 @@
++/*
++ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * ``Software''), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * vax Foreign Function Interface
++ */
++
++#define LIBFFI_ASM
++#include <fficonfig.h>
++#include <ffi.h>
++
++ .text
++
++/*
++ * void * %r0
++ * ffi_call_elfbsd(extended_cif *ecif, 4(%ap)
++ * unsigned bytes, 8(%ap)
++ * unsigned flags, 12(%ap)
++ * void *rvalue, 16(%ap)
++ * void (*fn)()); 20(%ap)
++ */
++ .globl ffi_call_elfbsd
++ .type ffi_call_elfbsd,@function
++ .align 2
++ffi_call_elfbsd:
++ .word 0x00c # save R2 and R3
++
++ # Allocate stack space for the args
++ subl2 8(%ap), %sp
++
++ # Call ffi_prep_args
++ pushl %sp
++ pushl 4(%ap)
++ calls $2, ffi_prep_args
++
++ # Get function pointer
++ movl 20(%ap), %r1
++
++ # Build a CALLS frame
++ ashl $-2, 8(%ap), %r0
++ pushl %r0 # argument stack usage
++ movl %sp, %r0 # future %ap
++ # saved registers
++ bbc $11, 0(%r1), 1f
++ pushl %r11
++1: bbc $10, 0(%r1), 1f
++ pushl %r10
++1: bbc $9, 0(%r1), 1f
++ pushl %r9
++1: bbc $8, 0(%r1), 1f
++ pushl %r8
++1: bbc $7, 0(%r1), 1f
++ pushl %r7
++1: bbc $6, 0(%r1), 1f
++ pushl %r6
++1: bbc $5, 0(%r1), 1f
++ pushl %r5
++1: bbc $4, 0(%r1), 1f
++ pushl %r4
++1: bbc $3, 0(%r1), 1f
++ pushl %r3
++1: bbc $2, 0(%r1), 1f
++ pushl %r2
++1:
++ pushal 9f
++ pushl %fp
++ pushl %ap
++ movl 16(%ap), %r3 # struct return address, if needed
++ movl %r0, %ap
++ movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask
++ bisl2 $0x20000000, %r0 # calls frame
++ movzwl 0(%r1), %r2
++ bicw2 $0xf003, %r2 # only keep R11-R2
++ ashl $16, %r2, %r2
++ bisl2 %r2, %r0 # saved register mask of the called function
++ pushl %r0
++ pushl $0
++ movl %sp, %fp
++
++ # Invoke the function
++ pushal 2(%r1) # skip procedure entry mask
++ movl %r3, %r1
++ bicpsw $0x000f
++ rsb
++
++9:
++ # Copy return value if necessary
++ tstl 16(%ap)
++ jeql 9f
++ movl 16(%ap), %r2
++
++ bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR
++ movb %r0, 0(%r2)
++ brb 9f
++1:
++ bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT
++ movw %r0, 0(%r2)
++ brb 9f
++1:
++ bbc $2, 12(%ap), 1f # CIF_FLAGS_INT
++ movl %r0, 0(%r2)
++ brb 9f
++1:
++ bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT
++ movq %r0, 0(%r2)
++ brb 9f
++1:
++ movl %r1, %r0 # might have been a struct
++ #brb 9f
++
++9:
++ ret
++
++/*
++ * ffi_closure_elfbsd(void);
++ * invoked with %r0: ffi_closure *closure
++ */
++ .globl ffi_closure_elfbsd
++ .type ffi_closure_elfbsd, @function
++ .align 2
++ffi_closure_elfbsd:
++ .word 0
++
++ # Allocate room on stack for return value
++ subl2 $8, %sp
++
++ # Invoke the closure function
++ pushal 4(%ap) # calling stack
++ pushal 4(%sp) # return value
++ pushl %r0 # closure
++ calls $3, ffi_closure_elfbsd_inner
++
++ # Copy return value if necessary
++ bitb $1, %r0 # CIF_FLAGS_CHAR
++ beql 1f
++ movb 0(%sp), %r0
++ brb 9f
++1:
++ bitb $2, %r0 # CIF_FLAGS_SHORT
++ beql 1f
++ movw 0(%sp), %r0
++ brb 9f
++1:
++ bitb $4, %r0 # CIF_FLAGS_INT
++ beql 1f
++ movl 0(%sp), %r0
++ brb 9f
++1:
++ bitb $8, %r0 # CIF_FLAGS_DINT
++ beql 1f
++ movq 0(%sp), %r0
++ #brb 9f
++1:
++
++9:
++ ret
++
++/*
++ * ffi_closure_struct_elfbsd(void);
++ * invoked with %r0: ffi_closure *closure
++ * %r1: struct return address
++ */
++ .globl ffi_closure_struct_elfbsd
++ .type ffi_closure_struct_elfbsd, @function
++ .align 2
++ffi_closure_struct_elfbsd:
++ .word 0
++
++ # Invoke the closure function
++ pushal 4(%ap) # calling stack
++ pushl %r1 # return value
++ pushl %r0 # closure
++ calls $3, ffi_closure_elfbsd_inner
++
++ ret
diff --git a/devel/libffi/patches/patch-src_m88k_ffi.c b/devel/libffi/patches/patch-src_m88k_ffi.c
new file mode 100644
index 00000000000..3eb5cdce8b7
--- /dev/null
+++ b/devel/libffi/patches/patch-src_m88k_ffi.c
@@ -0,0 +1,405 @@
+$NetBSD: patch-src_m88k_ffi.c,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- src/m88k/ffi.c.orig 2013-11-03 22:59:04.000000000 +0000
++++ src/m88k/ffi.c
+@@ -0,0 +1,400 @@
++/*
++ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * ``Software''), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * m88k Foreign Function Interface
++ *
++ * This file attempts to provide all the FFI entry points which can reliably
++ * be implemented in C.
++ *
++ * Only OpenBSD/m88k is currently supported; other platforms (such as
++ * Motorola's SysV/m88k) could be supported with the following tweaks:
++ *
++ * - non-OpenBSD systems use an `outgoing parameter area' as part of the
++ * 88BCS calling convention, which is not supported under OpenBSD from
++ * release 3.6 onwards. Supporting it should be as easy as taking it
++ * into account when adjusting the stack, in the assembly code.
++ *
++ * - the logic deciding whether a function argument gets passed through
++ * registers, or on the stack, has changed several times in OpenBSD in
++ * edge cases (especially for structs larger than 32 bytes being passed
++ * by value). The code below attemps to match the logic used by the
++ * system compiler of OpenBSD 5.3, i.e. gcc 3.3.6 with many m88k backend
++ * fixes.
++ */
++
++#include <ffi.h>
++#include <ffi_common.h>
++
++#include <stdlib.h>
++#include <unistd.h>
++
++void ffi_call_OBSD (unsigned int, extended_cif *, unsigned int, void *,
++ void (*fn) ());
++void *ffi_prep_args (void *, extended_cif *);
++void ffi_closure_OBSD (ffi_closure *);
++void ffi_closure_struct_OBSD (ffi_closure *);
++unsigned int ffi_closure_OBSD_inner (ffi_closure *, void *, unsigned int *,
++ char *);
++void ffi_cacheflush_OBSD (unsigned int, unsigned int);
++
++#define CIF_FLAGS_INT (1 << 0)
++#define CIF_FLAGS_DINT (1 << 1)
++
++/*
++ * Foreign Function Interface API
++ */
++
++/* ffi_prep_args is called by the assembly routine once stack space has
++ been allocated for the function's arguments. */
++
++void *
++ffi_prep_args (void *stack, extended_cif *ecif)
++{
++ unsigned int i;
++ void **p_argv;
++ char *argp, *stackp;
++ unsigned int *regp;
++ unsigned int regused;
++ ffi_type **p_arg;
++ void *struct_value_ptr;
++
++ regp = (unsigned int *)stack;
++ stackp = (char *)(regp + 8);
++ regused = 0;
++
++ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
++ && !ecif->cif->flags)
++ struct_value_ptr = ecif->rvalue;
++ else
++ struct_value_ptr = NULL;
++
++ p_argv = ecif->avalue;
++
++ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++)
++ {
++ size_t z;
++ unsigned short t, a;
++
++ z = (*p_arg)->size;
++ t = (*p_arg)->type;
++ a = (*p_arg)->alignment;
++
++ /*
++ * Figure out whether the argument can be passed through registers
++ * or on the stack.
++ * The rule is that registers can only receive simple types not larger
++ * than 64 bits, or structs the exact size of a register and aligned to
++ * the size of a register.
++ */
++ if (t == FFI_TYPE_STRUCT)
++ {
++ if (z == sizeof (int) && a == sizeof (int) && regused < 8)
++ argp = (char *)regp;
++ else
++ argp = stackp;
++ }
++ else
++ {
++ if (z > sizeof (int) && regused < 8 - 1)
++ {
++ /* align to an even register pair */
++ if (regused & 1)
++ {
++ regp++;
++ regused++;
++ }
++ }
++ if (regused < 8)
++ argp = (char *)regp;
++ else
++ argp = stackp;
++ }
++
++ /* Enforce proper stack alignment of 64-bit types */
++ if (argp == stackp && a > sizeof (int))
++ {
++ stackp = (char *) 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 = 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 *) 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 = 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;
++}
diff --git a/devel/libffi/patches/patch-src_m88k_ffitarget.h b/devel/libffi/patches/patch-src_m88k_ffitarget.h
new file mode 100644
index 00000000000..b9e789adb77
--- /dev/null
+++ b/devel/libffi/patches/patch-src_m88k_ffitarget.h
@@ -0,0 +1,54 @@
+$NetBSD: patch-src_m88k_ffitarget.h,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- src/m88k/ffitarget.h.orig 2013-11-03 23:00:28.000000000 +0000
++++ src/m88k/ffitarget.h
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * ``Software''), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * m88k Foreign Function Interface
++ */
++
++#ifndef LIBFFI_TARGET_H
++#define LIBFFI_TARGET_H
++
++#ifndef LIBFFI_ASM
++typedef unsigned long ffi_arg;
++typedef signed long ffi_sarg;
++
++typedef enum ffi_abi {
++ FFI_FIRST_ABI = 0,
++ FFI_OBSD,
++ FFI_DEFAULT_ABI = FFI_OBSD,
++ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
++} ffi_abi;
++#endif
++
++/* ---- Definitions for closures ----------------------------------------- */
++
++#define FFI_CLOSURES 1
++#define FFI_TRAMPOLINE_SIZE 0x14
++#define FFI_NATIVE_RAW_API 0
++
++#endif
diff --git a/devel/libffi/patches/patch-src_vax_elfbsd.S b/devel/libffi/patches/patch-src_vax_elfbsd.S
new file mode 100644
index 00000000000..de67548ae50
--- /dev/null
+++ b/devel/libffi/patches/patch-src_vax_elfbsd.S
@@ -0,0 +1,200 @@
+$NetBSD: patch-src_vax_elfbsd.S,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- src/vax/elfbsd.S.orig 2013-11-03 23:01:39.000000000 +0000
++++ src/vax/elfbsd.S
+@@ -0,0 +1,195 @@
++/*
++ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * ``Software''), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * vax Foreign Function Interface
++ */
++
++#define LIBFFI_ASM
++#include <fficonfig.h>
++#include <ffi.h>
++
++ .text
++
++/*
++ * void * %r0
++ * ffi_call_elfbsd(extended_cif *ecif, 4(%ap)
++ * unsigned bytes, 8(%ap)
++ * unsigned flags, 12(%ap)
++ * void *rvalue, 16(%ap)
++ * void (*fn)()); 20(%ap)
++ */
++ .globl ffi_call_elfbsd
++ .type ffi_call_elfbsd,@function
++ .align 2
++ffi_call_elfbsd:
++ .word 0x00c # save R2 and R3
++
++ # Allocate stack space for the args
++ subl2 8(%ap), %sp
++
++ # Call ffi_prep_args
++ pushl %sp
++ pushl 4(%ap)
++ calls $2, ffi_prep_args
++
++ # Get function pointer
++ movl 20(%ap), %r1
++
++ # Build a CALLS frame
++ ashl $-2, 8(%ap), %r0
++ pushl %r0 # argument stack usage
++ movl %sp, %r0 # future %ap
++ # saved registers
++ bbc $11, 0(%r1), 1f
++ pushl %r11
++1: bbc $10, 0(%r1), 1f
++ pushl %r10
++1: bbc $9, 0(%r1), 1f
++ pushl %r9
++1: bbc $8, 0(%r1), 1f
++ pushl %r8
++1: bbc $7, 0(%r1), 1f
++ pushl %r7
++1: bbc $6, 0(%r1), 1f
++ pushl %r6
++1: bbc $5, 0(%r1), 1f
++ pushl %r5
++1: bbc $4, 0(%r1), 1f
++ pushl %r4
++1: bbc $3, 0(%r1), 1f
++ pushl %r3
++1: bbc $2, 0(%r1), 1f
++ pushl %r2
++1:
++ pushal 9f
++ pushl %fp
++ pushl %ap
++ movl 16(%ap), %r3 # struct return address, if needed
++ movl %r0, %ap
++ movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask
++ bisl2 $0x20000000, %r0 # calls frame
++ movzwl 0(%r1), %r2
++ bicw2 $0xf003, %r2 # only keep R11-R2
++ ashl $16, %r2, %r2
++ bisl2 %r2, %r0 # saved register mask of the called function
++ pushl %r0
++ pushl $0
++ movl %sp, %fp
++
++ # Invoke the function
++ pushal 2(%r1) # skip procedure entry mask
++ movl %r3, %r1
++ bicpsw $0x000f
++ rsb
++
++9:
++ # Copy return value if necessary
++ tstl 16(%ap)
++ jeql 9f
++ movl 16(%ap), %r2
++
++ bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR
++ movb %r0, 0(%r2)
++ brb 9f
++1:
++ bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT
++ movw %r0, 0(%r2)
++ brb 9f
++1:
++ bbc $2, 12(%ap), 1f # CIF_FLAGS_INT
++ movl %r0, 0(%r2)
++ brb 9f
++1:
++ bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT
++ movq %r0, 0(%r2)
++ brb 9f
++1:
++ movl %r1, %r0 # might have been a struct
++ #brb 9f
++
++9:
++ ret
++
++/*
++ * ffi_closure_elfbsd(void);
++ * invoked with %r0: ffi_closure *closure
++ */
++ .globl ffi_closure_elfbsd
++ .type ffi_closure_elfbsd, @function
++ .align 2
++ffi_closure_elfbsd:
++ .word 0
++
++ # Allocate room on stack for return value
++ subl2 $8, %sp
++
++ # Invoke the closure function
++ pushal 4(%ap) # calling stack
++ pushal 4(%sp) # return value
++ pushl %r0 # closure
++ calls $3, ffi_closure_elfbsd_inner
++
++ # Copy return value if necessary
++ bitb $1, %r0 # CIF_FLAGS_CHAR
++ beql 1f
++ movb 0(%sp), %r0
++ brb 9f
++1:
++ bitb $2, %r0 # CIF_FLAGS_SHORT
++ beql 1f
++ movw 0(%sp), %r0
++ brb 9f
++1:
++ bitb $4, %r0 # CIF_FLAGS_INT
++ beql 1f
++ movl 0(%sp), %r0
++ brb 9f
++1:
++ bitb $8, %r0 # CIF_FLAGS_DINT
++ beql 1f
++ movq 0(%sp), %r0
++ #brb 9f
++1:
++
++9:
++ ret
++
++/*
++ * ffi_closure_struct_elfbsd(void);
++ * invoked with %r0: ffi_closure *closure
++ * %r1: struct return address
++ */
++ .globl ffi_closure_struct_elfbsd
++ .type ffi_closure_struct_elfbsd, @function
++ .align 2
++ffi_closure_struct_elfbsd:
++ .word 0
++
++ # Invoke the closure function
++ pushal 4(%ap) # calling stack
++ pushl %r1 # return value
++ pushl %r0 # closure
++ calls $3, ffi_closure_elfbsd_inner
++
++ ret
diff --git a/devel/libffi/patches/patch-src_vax_ffi.c b/devel/libffi/patches/patch-src_vax_ffi.c
new file mode 100644
index 00000000000..dedcd2bb130
--- /dev/null
+++ b/devel/libffi/patches/patch-src_vax_ffi.c
@@ -0,0 +1,281 @@
+$NetBSD: patch-src_vax_ffi.c,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- src/vax/ffi.c.orig 2013-11-03 23:02:29.000000000 +0000
++++ src/vax/ffi.c
+@@ -0,0 +1,276 @@
++/*
++ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * ``Software''), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * vax Foreign Function Interface
++ *
++ * This file attempts to provide all the FFI entry points which can reliably
++ * be implemented in C.
++ */
++
++#include <ffi.h>
++#include <ffi_common.h>
++
++#include <stdlib.h>
++#include <unistd.h>
++
++#define CIF_FLAGS_CHAR 1 /* for struct only */
++#define CIF_FLAGS_SHORT 2 /* for struct only */
++#define CIF_FLAGS_INT 4
++#define CIF_FLAGS_DINT 8
++
++/*
++ * Foreign Function Interface API
++ */
++
++void ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *,
++ void (*) ());
++void *ffi_prep_args (extended_cif *ecif, void *stack);
++
++void *
++ffi_prep_args (extended_cif *ecif, void *stack)
++{
++ unsigned int i;
++ void **p_argv;
++ char *argp;
++ ffi_type **p_arg;
++ void *struct_value_ptr;
++
++ argp = stack;
++
++ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
++ && !ecif->cif->flags)
++ struct_value_ptr = ecif->rvalue;
++ else
++ struct_value_ptr = NULL;
++
++ p_argv = ecif->avalue;
++
++ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
++ i != 0;
++ i--, p_arg++)
++ {
++ size_t z;
++
++ z = (*p_arg)->size;
++ if (z < sizeof (int))
++ {
++ switch ((*p_arg)->type)
++ {
++ case FFI_TYPE_SINT8:
++ *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
++ break;
++
++ case FFI_TYPE_UINT8:
++ *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
++ break;
++
++ case FFI_TYPE_SINT16:
++ *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
++ break;
++
++ case FFI_TYPE_UINT16:
++ *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
++ break;
++
++ case FFI_TYPE_STRUCT:
++ memcpy (argp, *p_argv, z);
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ }
++ z = sizeof (int);
++ }
++ else
++ {
++ memcpy (argp, *p_argv, z);
++
++ /* Align if necessary. */
++ if ((sizeof(int) - 1) & z)
++ z = ALIGN(z, sizeof(int));
++ }
++
++ p_argv++;
++ argp += z;
++ }
++
++ return struct_value_ptr;
++}
++
++ffi_status
++ffi_prep_cif_machdep (ffi_cif *cif)
++{
++ /* Set the return type flag */
++ switch (cif->rtype->type)
++ {
++ case FFI_TYPE_VOID:
++ cif->flags = 0;
++ break;
++
++ case FFI_TYPE_STRUCT:
++ if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT &&
++ cif->rtype->elements[1])
++ {
++ cif->flags = 0;
++ break;
++ }
++
++ if (cif->rtype->size == sizeof (char))
++ cif->flags = CIF_FLAGS_CHAR;
++ else if (cif->rtype->size == sizeof (short))
++ cif->flags = CIF_FLAGS_SHORT;
++ else if (cif->rtype->size == sizeof (int))
++ cif->flags = CIF_FLAGS_INT;
++ else if (cif->rtype->size == 2 * sizeof (int))
++ cif->flags = CIF_FLAGS_DINT;
++ else
++ cif->flags = 0;
++ break;
++
++ default:
++ if (cif->rtype->size <= sizeof (int))
++ cif->flags = CIF_FLAGS_INT;
++ else
++ cif->flags = CIF_FLAGS_DINT;
++ break;
++ }
++
++ return FFI_OK;
++}
++
++void
++ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
++{
++ extended_cif ecif;
++
++ ecif.cif = cif;
++ ecif.avalue = avalue;
++
++ /* If the return value is a struct and we don't have a return value
++ address then we need to make one. */
++
++ if (rvalue == NULL
++ && cif->rtype->type == FFI_TYPE_STRUCT
++ && cif->flags == 0)
++ ecif.rvalue = alloca (cif->rtype->size);
++ else
++ ecif.rvalue = rvalue;
++
++ switch (cif->abi)
++ {
++ case FFI_ELFBSD:
++ ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn);
++ break;
++
++ default:
++ FFI_ASSERT (0);
++ break;
++ }
++}
++
++/*
++ * Closure API
++ */
++
++void ffi_closure_elfbsd (void);
++void ffi_closure_struct_elfbsd (void);
++unsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *);
++
++static void
++ffi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp)
++{
++ unsigned int i;
++ void **p_argv;
++ ffi_type **p_arg;
++
++ p_argv = avalue;
++
++ for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)
++ {
++ size_t z;
++
++ z = (*p_arg)->size;
++ *p_argv = stackp;
++
++ /* Align if necessary */
++ if ((sizeof (int) - 1) & z)
++ z = ALIGN(z, sizeof (int));
++
++ p_argv++;
++ stackp += z;
++ }
++}
++
++unsigned int
++ffi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack)
++{
++ ffi_cif *cif;
++ void **arg_area;
++
++ cif = closure->cif;
++ arg_area = (void **) alloca (cif->nargs * sizeof (void *));
++
++ ffi_prep_closure_elfbsd (cif, arg_area, stack);
++
++ (closure->fun) (cif, resp, arg_area, closure->user_data);
++
++ return cif->flags;
++}
++
++ffi_status
++ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif,
++ void (*fun)(ffi_cif *, void *, void **, void *),
++ void *user_data, void *codeloc)
++{
++ char *tramp = (char *) codeloc;
++ void *fn;
++
++ FFI_ASSERT (cif->abi == FFI_ELFBSD);
++
++ /* entry mask */
++ *(unsigned short *)(tramp + 0) = 0x0000;
++ /* movl #closure, r0 */
++ tramp[2] = 0xd0;
++ tramp[3] = 0x8f;
++ *(unsigned int *)(tramp + 4) = (unsigned int) closure;
++ tramp[8] = 0x50;
++
++ if (cif->rtype->type == FFI_TYPE_STRUCT
++ && !cif->flags)
++ fn = &ffi_closure_struct_elfbsd;
++ else
++ fn = &ffi_closure_elfbsd;
++
++ /* jmpl #fn */
++ tramp[9] = 0x17;
++ tramp[10] = 0xef;
++ *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 -
++ (unsigned int)tramp - 9 - 6;
++
++ closure->cif = cif;
++ closure->user_data = user_data;
++ closure->fun = fun;
++
++ return FFI_OK;
++}
diff --git a/devel/libffi/patches/patch-src_vax_ffitarget.h b/devel/libffi/patches/patch-src_vax_ffitarget.h
new file mode 100644
index 00000000000..55233d268a9
--- /dev/null
+++ b/devel/libffi/patches/patch-src_vax_ffitarget.h
@@ -0,0 +1,54 @@
+$NetBSD: patch-src_vax_ffitarget.h,v 1.1 2013/11/03 23:51:51 jklos Exp $
+
+--- src/vax/ffitarget.h.orig 2013-11-03 23:03:01.000000000 +0000
++++ src/vax/ffitarget.h
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * ``Software''), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included
++ * in all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
++ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * vax Foreign Function Interface
++ */
++
++#ifndef LIBFFI_TARGET_H
++#define LIBFFI_TARGET_H
++
++#ifndef LIBFFI_ASM
++typedef unsigned long ffi_arg;
++typedef signed long ffi_sarg;
++
++typedef enum ffi_abi {
++ FFI_FIRST_ABI = 0,
++ FFI_ELFBSD,
++ FFI_DEFAULT_ABI = FFI_ELFBSD,
++ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
++} ffi_abi;
++#endif
++
++/* ---- Definitions for closures ----------------------------------------- */
++
++#define FFI_CLOSURES 1
++#define FFI_TRAMPOLINE_SIZE 15
++#define FFI_NATIVE_RAW_API 0
++
++#endif