diff options
author | jklos <jklos@pkgsrc.org> | 2013-11-03 23:51:51 +0000 |
---|---|---|
committer | jklos <jklos@pkgsrc.org> | 2013-11-03 23:51:51 +0000 |
commit | 475df0b058205fb57645791ea19046a1aec6a85a (patch) | |
tree | d0209c37ab2ad38eacf89e3bcd379cda0be0fff6 /devel | |
parent | 46c7f27231ff8dddae464601c1e0fe2a8e766c14 (diff) | |
download | pkgsrc-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')
-rw-r--r-- | devel/libffi/distinfo | 12 | ||||
-rw-r--r-- | devel/libffi/patches/patch-Makefile.am | 40 | ||||
-rw-r--r-- | devel/libffi/patches/patch-aa | 66 | ||||
-rw-r--r-- | devel/libffi/patches/patch-configure.ac | 42 | ||||
-rw-r--r-- | devel/libffi/patches/patch-src_m88k_elfbsd.S | 200 | ||||
-rw-r--r-- | devel/libffi/patches/patch-src_m88k_ffi.c | 405 | ||||
-rw-r--r-- | devel/libffi/patches/patch-src_m88k_ffitarget.h | 54 | ||||
-rw-r--r-- | devel/libffi/patches/patch-src_vax_elfbsd.S | 200 | ||||
-rw-r--r-- | devel/libffi/patches/patch-src_vax_ffi.c | 281 | ||||
-rw-r--r-- | devel/libffi/patches/patch-src_vax_ffitarget.h | 54 |
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 |