update to libffi-3.1 (not quite the newest, but better than what we currently have)
tested with gnome3 (heavily reliant on ffi/javascript/goi) for the better part of a year
This commit is contained in:
parent
589e1a6ef1
commit
5e4b7d02f8
@ -1,11 +1,10 @@
|
||||
# $OpenBSD: Makefile,v 1.28 2015/03/16 18:07:42 naddy Exp $
|
||||
# $OpenBSD: Makefile,v 1.29 2015/04/06 12:11:39 jasper Exp $
|
||||
|
||||
COMMENT= Foreign Function Interface
|
||||
|
||||
DISTNAME= libffi-3.0.13
|
||||
SHARED_LIBS += ffi 1.0 # .6.1
|
||||
DISTNAME= libffi-3.1
|
||||
SHARED_LIBS += ffi 1.1 # .6.2
|
||||
CATEGORIES= devel
|
||||
REVISION= 0
|
||||
|
||||
MAINTAINER= Jasper Lievisse Adriaanse <jasper@openbsd.org>
|
||||
|
||||
@ -18,38 +17,9 @@ MASTER_SITES= ftp://sourceware.org/pub/libffi/
|
||||
|
||||
TEST_DEPENDS= devel/dejagnu
|
||||
|
||||
AUTOCONF_VERSION= 2.68
|
||||
AUTOMAKE_VERSION= 1.14
|
||||
|
||||
BUILD_DEPENDS= ${MODGNU_AUTOCONF_DEPENDS} \
|
||||
${MODGNU_AUTOMAKE_DEPENDS} \
|
||||
devel/libtool
|
||||
|
||||
CONFIGURE_STYLE= gnu
|
||||
CONFIGURE_ARGS+= ${CONFIGURE_SHARED}
|
||||
|
||||
FAKE_FLAGS+= includesdir="${PREFIX}/include"
|
||||
|
||||
pre-configure:
|
||||
cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \
|
||||
AUTOMAKE_VERSION=${AUTOMAKE_VERSION} aclocal
|
||||
cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \
|
||||
AUTOMAKE_VERSION=${AUTOMAKE_VERSION} autoconf
|
||||
cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \
|
||||
AUTOMAKE_VERSION=${AUTOMAKE_VERSION} automake
|
||||
# Force a regen of missing
|
||||
rm ${WRKSRC}/missing
|
||||
cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \
|
||||
AUTOMAKE_VERSION=${AUTOMAKE_VERSION} automake --add-missing
|
||||
|
||||
post-patch:
|
||||
@mkdir ${WRKSRC}/src/m88k
|
||||
@cp ${FILESDIR}/m88k_ffi.c ${WRKSRC}/src/m88k/ffi.c
|
||||
@cp ${FILESDIR}/m88k_ffitarget.h ${WRKSRC}/src/m88k/ffitarget.h
|
||||
@cp ${FILESDIR}/m88k_obsd.S ${WRKSRC}/src/m88k/obsd.S
|
||||
@mkdir ${WRKSRC}/src/vax
|
||||
@cp ${FILESDIR}/vax_ffi.c ${WRKSRC}/src/vax/ffi.c
|
||||
@cp ${FILESDIR}/vax_ffitarget.h ${WRKSRC}/src/vax/ffitarget.h
|
||||
@cp ${FILESDIR}/vax_elfbsd.S ${WRKSRC}/src/vax/elfbsd.S
|
||||
|
||||
.include <bsd.port.mk>
|
||||
|
@ -1,2 +1,2 @@
|
||||
SHA256 (libffi-3.0.13.tar.gz) = Hd3eFADDvLd0nTmAca+Iw+R1QFjS1MCzaWwvgtxc8Rw=
|
||||
SIZE (libffi-3.0.13.tar.gz) = 845747
|
||||
SHA256 (libffi-3.1.tar.gz) = l/7urcpeIYcPpEM7yVPRs68/aY1d+KQo9otzzWCu9us=
|
||||
SIZE (libffi-3.1.tar.gz) = 937214
|
||||
|
@ -1,401 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Miodrag Vallat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* ``Software''), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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;
|
||||
|
||||
if (cif->abi != FFI_ELFBSD)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
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;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Miodrag Vallat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* ``Software''), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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
|
@ -1,209 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Miodrag Vallat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* ``Software''), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Miodrag Vallat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* ``Software''), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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
|
@ -1,277 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Miodrag Vallat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* ``Software''), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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;
|
||||
|
||||
if (cif->abi != FFI_ELFBSD)
|
||||
return FFI_BAD_ABI;
|
||||
|
||||
/* 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;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Miodrag Vallat.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* ``Software''), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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
|
@ -1,20 +1,20 @@
|
||||
$OpenBSD: patch-Makefile_am,v 1.2 2014/06/04 17:40:27 jasper Exp $
|
||||
$OpenBSD: patch-Makefile_am,v 1.3 2015/04/06 12:11:40 jasper Exp $
|
||||
|
||||
Enable libffi on m88k and vax platforms.
|
||||
|
||||
--- Makefile.am.orig Sat Mar 16 12:52:11 2013
|
||||
+++ Makefile.am Sun Apr 20 18:16:13 2014
|
||||
@@ -155,6 +155,9 @@ endif
|
||||
if MICROBLAZE
|
||||
nodist_libffi_la_SOURCES += src/microblaze/ffi.c src/microblaze/sysv.S
|
||||
--- Makefile.am.orig Sun May 11 16:21:54 2014
|
||||
+++ Makefile.am Mon Sep 15 22:00:00 2014
|
||||
@@ -169,6 +169,9 @@ endif
|
||||
if NIOS2
|
||||
nodist_libffi_la_SOURCES += src/nios2/sysv.S src/nios2/ffi.c
|
||||
endif
|
||||
+if M88K
|
||||
+nodist_libffi_la_SOURCES += src/m88k/ffi.c src/m88k/obsd.S
|
||||
+endif
|
||||
if POWERPC
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
|
||||
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
|
||||
endif
|
||||
@@ -187,6 +190,9 @@ nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi
|
||||
@@ -204,6 +207,9 @@ nodist_libffi_la_SOURCES += src/frv/eabi.S src/frv/ffi
|
||||
endif
|
||||
if S390
|
||||
nodist_libffi_la_SOURCES += src/s390/sysv.S src/s390/ffi.c
|
||||
|
@ -1,44 +0,0 @@
|
||||
$OpenBSD: patch-configure_ac,v 1.2 2014/06/04 17:40:27 jasper Exp $
|
||||
|
||||
Enable libffi on hppa, m88k, mips64(el), powerpc and vax platforms.
|
||||
|
||||
--- configure.ac.orig Sun Mar 17 23:36:15 2013
|
||||
+++ configure.ac Sun Apr 20 18:16:16 2014
|
||||
@@ -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-*-openbsd*)
|
||||
+ TARGET=VAX; TARGETDIR=vax
|
||||
+ ;;
|
||||
+
|
||||
xtensa*-*)
|
||||
TARGET=XTENSA; TARGETDIR=xtensa
|
||||
;;
|
||||
@@ -281,6 +289,7 @@ AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
|
||||
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)
|
||||
@@ -302,6 +311,7 @@ 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(XTENSA, test x$TARGET = xXTENSA)
|
||||
+AM_CONDITIONAL(VAX, test x$TARGET = xVAX)
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy)
|
@ -1,13 +1,13 @@
|
||||
$OpenBSD: patch-libffi_pc_in,v 1.1.1.1 2009/09/23 20:55:46 jasper Exp $
|
||||
$OpenBSD: patch-libffi_pc_in,v 1.2 2015/04/06 12:11:40 jasper Exp $
|
||||
|
||||
Install headers into a standard directory.
|
||||
|
||||
--- libffi.pc.in.orig Sat Sep 19 15:10:14 2009
|
||||
+++ libffi.pc.in Sat Sep 19 15:10:31 2009
|
||||
@@ -1,7 +1,7 @@
|
||||
prefix=@prefix@
|
||||
--- libffi.pc.in.orig Fri Apr 25 19:45:13 2014
|
||||
+++ libffi.pc.in Mon Sep 15 22:00:14 2014
|
||||
@@ -2,7 +2,7 @@ prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
toolexeclibdir=@toolexeclibdir@
|
||||
-includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include
|
||||
+includedir=@includedir@
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
$OpenBSD: patch-src_arm_ffi_c,v 1.5 2014/06/04 17:40:27 jasper Exp $
|
||||
$OpenBSD: patch-src_arm_ffi_c,v 1.6 2015/04/06 12:11:40 jasper Exp $
|
||||
|
||||
Fix warning: implicit declaration of function '__clear_cache' and
|
||||
change the code to follow our current ABI (APCS).
|
||||
|
||||
--- src/arm/ffi.c.orig Sat Mar 16 12:19:39 2013
|
||||
+++ src/arm/ffi.c Wed Apr 16 12:04:25 2014
|
||||
--- src/arm/ffi.c.orig Fri Apr 25 19:45:13 2014
|
||||
+++ src/arm/ffi.c Mon Sep 15 22:00:37 2014
|
||||
@@ -37,6 +37,8 @@
|
||||
static int vfp_type_p (ffi_type *);
|
||||
static void layout_vfp_args (ffi_cif *);
|
||||
|
||||
+extern void __clear_cache(char *beg, char *end);
|
||||
+
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments
|
||||
int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space);
|
||||
int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space);
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
$OpenBSD: patch-src_x86_freebsd_S,v 1.1 2013/04/01 11:53:52 kettenis Exp $
|
||||
--- src/x86/freebsd.S.orig Tue Dec 29 16:22:26 2009
|
||||
+++ src/x86/freebsd.S Mon Apr 1 11:39:44 2013
|
||||
@@ -49,6 +49,9 @@ ffi_call_SYSV:
|
||||
movl 16(%ebp),%ecx
|
||||
subl %ecx,%esp
|
||||
|
||||
+ /* Align the stack pointer to 16-bytes */
|
||||
+ andl $0xfffffff0, %esp
|
||||
+
|
||||
movl %esp,%eax
|
||||
|
||||
/* Place all of the ffi_prep_args in position */
|
Loading…
x
Reference in New Issue
Block a user