Add support for Windows ARM32 in libffi (#9)

This commit is contained in:
Paul Monson
2019-04-17 13:49:13 -07:00
committed by Steve Dower
parent d160812995
commit 82244f9715
14 changed files with 414 additions and 1469 deletions

View File

@@ -8,9 +8,11 @@ shallow_clone: true
# 32- and 64-bit clang/mingw # 32- and 64-bit clang/mingw
# and perhaps more. # and perhaps more.
image: Visual Studio 2013 image: Visual Studio 2017
platform: platform:
- x64 - x64
- x86
- arm
environment: environment:
global: global:
@@ -18,30 +20,42 @@ environment:
CYG_CACHE: C:/cygwin/var/cache/setup CYG_CACHE: C:/cygwin/var/cache/setup
CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/ CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
matrix: matrix:
- VSVER: 12 - VSVER: 15
install: install:
- ps: >- - ps: >-
If ($env:Platform -Match "x86") { If ($env:Platform -Match "x86") {
$env:VCVARS_PLATFORM="x86" $env:VCVARS_PLATFORM="x86"
$env:BUILD="x86-pc-cygwin" $env:BUILD="i686-pc-cygwin"
$env:HOST="x86-pc-windows" $env:HOST="i686-pc-cygwin"
$env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh"
$env:SRC_ARCHITECTURE="x86"
} ElseIf ($env:Platform -Match "arm") {
$env:VCVARS_PLATFORM="x86_arm"
$env:BUILD="i686-pc-cygwin"
$env:HOST="arm-w32-cygwin"
$env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm"
$env:SRC_ARCHITECTURE="arm"
} Else { } Else {
$env:VCVARS_PLATFORM="amd64" $env:VCVARS_PLATFORM="amd64"
$env:BUILD="x86_64-w64-cygwin" $env:BUILD="x86_64-w64-cygwin"
$env:HOST="x86_64-w64-cygwin" $env:HOST="x86_64-w64-cygwin"
$env:ASSEMBLER="/cygdrive/c/projects/libffi/msvcc.sh -m64"
$env:SRC_ARCHITECTURE="x86"
} }
- 'appveyor DownloadFile https://cygwin.com/setup-x86.exe -FileName setup.exe' - 'appveyor DownloadFile https://cygwin.com/setup-x86.exe -FileName setup.exe'
- 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu >NUL' - 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu >NUL'
- '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"' - '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"'
- echo call VsDevCmd to set VS150COMNTOOLS
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
- ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS")) - ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
- echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%" - echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%"
- call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM% - call "%VSCOMNTOOLS%..\..\vc\Auxiliary\Build\vcvarsall.bat" %VCVARS_PLATFORM%
build_script: build_script:
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./autogen.sh;)" - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./autogen.sh;)"
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='/cygdrive/c/projects/libffi/msvcc.sh -m64' CXX='/cygdrive/c/projects/libffi/msvcc.sh -m64' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)" - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='%MSVCC%' CXX='%MSVCC%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)"
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/x86/ffitarget.h include; make; find .;)" - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)"
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)" - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)"
# FIXME: "make check" currently fails. It just looks like msvcc needs # FIXME: "make check" currently fails. It just looks like msvcc needs

3
.gitignore vendored
View File

@@ -38,4 +38,5 @@ src/arm/trampoline.S
**/texinfo.tex **/texinfo.tex
x86_64-w64-cygwin x86_64-w64-cygwin
i686-pc-cygwin i686-pc-cygwin
arm-w32-cygwin

View File

@@ -82,6 +82,7 @@ EXTRA_libffi_la_SOURCES = \
src/alpha/ffi.c src/alpha/osf.S \ src/alpha/ffi.c src/alpha/osf.S \
src/arc/ffi.c src/arc/arcompact.S \ src/arc/ffi.c src/arc/arcompact.S \
src/arm/ffi.c src/arm/sysv.S \ src/arm/ffi.c src/arm/sysv.S \
src/arm/ffi.c src/arm/sysv_msvc_arm32.S \
src/avr32/ffi.c src/avr32/sysv.S \ src/avr32/ffi.c src/avr32/sysv.S \
src/bfin/ffi.c src/bfin/sysv.S \ src/bfin/ffi.c src/bfin/sysv.S \
src/cris/ffi.c src/cris/sysv.S \ src/cris/ffi.c src/cris/sysv.S \

View File

@@ -56,6 +56,7 @@ tested:
| ARC | Linux | GCC | | ARC | Linux | GCC |
| ARM | Linux | GCC | | ARM | Linux | GCC |
| ARM | iOS | GCC | | ARM | iOS | GCC |
| ARM | Windows | MSVC |
| AVR32 | Linux | GCC | | AVR32 | Linux | GCC |
| Blackfin | uClinux | GCC | | Blackfin | uClinux | GCC |
| HPPA | HPUX | GCC | | HPPA | HPUX | GCC |
@@ -190,13 +191,16 @@ History
See the git log for details at http://github.com/libffi/libffi. See the git log for details at http://github.com/libffi/libffi.
3.3 TBD 3.4 TBD
Add RISC-V support. Add RISC-V support.
New API in support of GO closures. New API in support of GO closures.
Default to Microsoft's 64 bit long double ABI with Visual C++. Default to Microsoft's 64 bit long double ABI with Visual C++.
GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI. GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
Many new tests cases and bug fixes. Many new tests cases and bug fixes.
3.3 Mar-05-19
Add Windows 32-bit arm support.
3.2.1 Nov-12-14 3.2.1 Nov-12-14
Build fix for non-iOS AArch64 targets. Build fix for non-iOS AArch64 targets.

View File

@@ -23,6 +23,11 @@ case "${host}" in
SOURCES="ffi.c arcompact.S" SOURCES="ffi.c arcompact.S"
;; ;;
arm*-*-cygwin* | arm*-*-mingw* | arm*-*-win* )
TARGET=ARM_WIN32; TARGETDIR=arm
MSVC=1
;;
arm*-*-*) arm*-*-*)
TARGET=ARM; TARGETDIR=arm TARGET=ARM; TARGETDIR=arm
SOURCES="ffi.c sysv.S" SOURCES="ffi.c sysv.S"
@@ -242,6 +247,9 @@ esac
# ... but some of the cases above share configury. # ... but some of the cases above share configury.
case "${TARGET}" in case "${TARGET}" in
ARM_WIN32)
SOURCES="ffi.c sysv_msvc_arm32.S"
;;
MIPS) MIPS)
SOURCES="ffi.c o32.S n32.S" SOURCES="ffi.c o32.S n32.S"
;; ;;

View File

@@ -1,511 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the ``Software''), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Specify which architecture libffi is configured for. */
#ifndef X86_WIN64
#define X86_WIN64
#endif
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif /* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif /* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING /* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else /* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN ffi_type ffi_type_void;
FFI_EXTERN ffi_type ffi_type_uint8;
FFI_EXTERN ffi_type ffi_type_sint8;
FFI_EXTERN ffi_type ffi_type_uint16;
FFI_EXTERN ffi_type ffi_type_sint16;
FFI_EXTERN ffi_type ffi_type_uint32;
FFI_EXTERN ffi_type ffi_type_sint32;
FFI_EXTERN ffi_type ffi_type_uint64;
FFI_EXTERN ffi_type ffi_type_sint64;
FFI_EXTERN ffi_type ffi_type_float;
FFI_EXTERN ffi_type ffi_type_double;
FFI_EXTERN ffi_type ffi_type_pointer;
#if 0
FFI_EXTERN ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN ffi_type ffi_type_complex_float;
FFI_EXTERN ffi_type ffi_type_complex_double;
#if 0
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum {
FFI_OK = 0,
FFI_BAD_TYPEDEF,
FFI_BAD_ABI
} ffi_status;
typedef struct {
ffi_abi abi;
unsigned nargs;
ffi_type **arg_types;
ffi_type *rtype;
unsigned bytes;
unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef union {
ffi_sarg sint;
ffi_arg uint;
float flt;
char data[FFI_SIZEOF_ARG];
void* ptr;
} ffi_raw;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef union {
signed int sint;
unsigned int uint;
float flt;
char data[FFI_SIZEOF_JAVA_RAW];
void* ptr;
} ffi_java_raw;
#else
typedef ffi_raw ffi_java_raw;
#endif
FFI_API
void ffi_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
FFI_API size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
FFI_API
void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue);
FFI_API
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
FFI_API
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
FFI_API
size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec(align(8))
#endif
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
} ffi_closure
#ifdef __GNUC__
__attribute__((aligned (8)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API void *ffi_closure_alloc (size_t size, void **code);
FFI_API void ffi_closure_free (void *);
FFI_API ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__((deprecated))
#endif
;
FFI_API ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void*codeloc);
#ifdef __sgi
# pragma pack 8
#endif
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
void *user_data;
} ffi_raw_closure;
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
void *user_data;
} ffi_java_raw_closure;
FFI_API ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
FFI_API ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
FFI_API ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data);
FFI_API ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc);
#endif /* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef struct {
void *tramp;
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
} ffi_go_closure;
FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*));
FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
void **avalue, void *closure);
#endif /* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
ffi_type *rtype,
ffi_type **atypes);
FFI_API
ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_abi abi,
unsigned int nfixedargs,
unsigned int ntotalargs,
ffi_type *rtype,
ffi_type **atypes);
FFI_API
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue);
FFI_API
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
size_t *offsets);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 0
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,215 +0,0 @@
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
/* #undef EH_FRAME_FLAGS */
/* Define this if you want extra debugging. */
/* #undef FFI_DEBUG */
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
/* Define this if you want to enable pax emulated trampolines */
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Cannot use malloc on this target, so, we revert to alternative means */
/* #undef FFI_MMAP_EXEC_WRIT */
/* Define this if you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this if you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
/* #undef HAVE_ALLOCA_H */
/* Define if your assembler supports .cfi_* directives. */
/* #undef HAVE_AS_CFI_PSEUDO_OP */
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if the compiler uses zarch features. */
/* #undef HAVE_AS_S390_ZARCH */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define if your assembler supports unwind section type. */
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
/* Define if your assembler supports PC relative relocs. */
#define HAVE_AS_X86_PCREL 1
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define if __attribute__((visibility("hidden"))) is supported. */
/* #undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the long double type and it is bigger than a double */
/* #undef HAVE_LONG_DOUBLE */
/* Define if you support more than one size of the long double type */
/* #undef HAVE_LONG_DOUBLE_VARIANT */
/* Define to 1 if you have the `memcpy' function. */
/* #undef HAVE_MEMCPY */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkostemp' function. */
/* #undef HAVE_MKOSTEMP */
/* Define to 1 if you have the `mmap' function. */
/* #undef HAVE_MMAP */
/* Define if mmap with MAP_ANON(YMOUS) works. */
/* #undef HAVE_MMAP_ANON */
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
/* #undef HAVE_MMAP_FILE */
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if GNU symbol versioning is used for libatomic. */
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libffi"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libffi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libffi 3.3-rc0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libffi"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.3-rc0"
/* The size of `double', as computed by sizeof. */
#define SIZEOF_DOUBLE 8
/* The size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 8
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 8
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if symbols are underscored. */
/* #undef SYMBOL_UNDERSCORE */
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
#define VERSION "3.3-rc0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#ifdef __APPLE__
#define FFI_HIDDEN(name) .private_extern name
#else
#define FFI_HIDDEN(name) .hidden name
#endif
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif

View File

@@ -1,511 +0,0 @@
/* -----------------------------------------------------------------*-C-*-
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the ``Software''), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Specify which architecture libffi is configured for. */
#ifndef X86_WIN32
#define X86_WIN32
#endif
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif /* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif /* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING /* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else /* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN ffi_type ffi_type_void;
FFI_EXTERN ffi_type ffi_type_uint8;
FFI_EXTERN ffi_type ffi_type_sint8;
FFI_EXTERN ffi_type ffi_type_uint16;
FFI_EXTERN ffi_type ffi_type_sint16;
FFI_EXTERN ffi_type ffi_type_uint32;
FFI_EXTERN ffi_type ffi_type_sint32;
FFI_EXTERN ffi_type ffi_type_uint64;
FFI_EXTERN ffi_type ffi_type_sint64;
FFI_EXTERN ffi_type ffi_type_float;
FFI_EXTERN ffi_type ffi_type_double;
FFI_EXTERN ffi_type ffi_type_pointer;
#if 0
FFI_EXTERN ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN ffi_type ffi_type_complex_float;
FFI_EXTERN ffi_type ffi_type_complex_double;
#if 0
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum {
FFI_OK = 0,
FFI_BAD_TYPEDEF,
FFI_BAD_ABI
} ffi_status;
typedef struct {
ffi_abi abi;
unsigned nargs;
ffi_type **arg_types;
ffi_type *rtype;
unsigned bytes;
unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef union {
ffi_sarg sint;
ffi_arg uint;
float flt;
char data[FFI_SIZEOF_ARG];
void* ptr;
} ffi_raw;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef union {
signed int sint;
unsigned int uint;
float flt;
char data[FFI_SIZEOF_JAVA_RAW];
void* ptr;
} ffi_java_raw;
#else
typedef ffi_raw ffi_java_raw;
#endif
FFI_API
void ffi_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
FFI_API size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
FFI_API
void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue);
FFI_API
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
FFI_API
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
FFI_API
size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec(align(8))
#endif
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
} ffi_closure
#ifdef __GNUC__
__attribute__((aligned (8)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API void *ffi_closure_alloc (size_t size, void **code);
FFI_API void ffi_closure_free (void *);
FFI_API ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__((deprecated))
#endif
;
FFI_API ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void*codeloc);
#ifdef __sgi
# pragma pack 8
#endif
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
void *user_data;
} ffi_raw_closure;
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
void *user_data;
} ffi_java_raw_closure;
FFI_API ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
FFI_API ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
FFI_API ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data);
FFI_API ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc);
#endif /* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef struct {
void *tramp;
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
} ffi_go_closure;
FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*));
FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
void **avalue, void *closure);
#endif /* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
ffi_type *rtype,
ffi_type **atypes);
FFI_API
ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_abi abi,
unsigned int nfixedargs,
unsigned int ntotalargs,
ffi_type *rtype,
ffi_type **atypes);
FFI_API
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue);
FFI_API
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
size_t *offsets);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 0
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,215 +0,0 @@
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
/* #undef EH_FRAME_FLAGS */
/* Define this if you want extra debugging. */
/* #undef FFI_DEBUG */
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
/* Define this if you want to enable pax emulated trampolines */
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Cannot use malloc on this target, so, we revert to alternative means */
/* #undef FFI_MMAP_EXEC_WRIT */
/* Define this if you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this if you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
/* #undef HAVE_ALLOCA_H */
/* Define if your assembler supports .cfi_* directives. */
/* #undef HAVE_AS_CFI_PSEUDO_OP */
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if the compiler uses zarch features. */
/* #undef HAVE_AS_S390_ZARCH */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define if your assembler supports unwind section type. */
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
/* Define if your assembler supports PC relative relocs. */
#define HAVE_AS_X86_PCREL 1
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define if __attribute__((visibility("hidden"))) is supported. */
/* #undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the long double type and it is bigger than a double */
/* #undef HAVE_LONG_DOUBLE */
/* Define if you support more than one size of the long double type */
/* #undef HAVE_LONG_DOUBLE_VARIANT */
/* Define to 1 if you have the `memcpy' function. */
/* #undef HAVE_MEMCPY */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkostemp' function. */
/* #undef HAVE_MKOSTEMP */
/* Define to 1 if you have the `mmap' function. */
/* #undef HAVE_MMAP */
/* Define if mmap with MAP_ANON(YMOUS) works. */
/* #undef HAVE_MMAP_ANON */
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
/* #undef HAVE_MMAP_FILE */
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if GNU symbol versioning is used for libatomic. */
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libffi"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libffi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libffi 3.3-rc0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libffi"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.3-rc0"
/* The size of `double', as computed by sizeof. */
#define SIZEOF_DOUBLE 8
/* The size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 8
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if symbols are underscored. */
#define SYMBOL_UNDERSCORE 1
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
#define VERSION "3.3-rc0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#ifdef __APPLE__
#define FFI_HIDDEN(name) .private_extern name
#else
#define FFI_HIDDEN(name) .hidden name
#endif
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif

View File

@@ -60,7 +60,7 @@ do
case $1 case $1
in in
--verbose) --verbose)
$verbose=1 verbose=1
shift 1 shift 1
;; ;;
--version) --version)
@@ -80,6 +80,11 @@ do
safeseh= safeseh=
shift 1 shift 1
;; ;;
-marm)
ml='armasm'
safeseh=
shift 1
;;
-clang-cl) -clang-cl)
cl="clang-cl" cl="clang-cl"
shift 1 shift 1
@@ -237,6 +242,7 @@ do
else else
output="-Fe$2" output="-Fe$2"
fi fi
armasm_output="-o $2"
if [ -n "$assembly" ]; then if [ -n "$assembly" ]; then
args="$args $output" args="$args $output"
else else
@@ -289,13 +295,21 @@ if [ -n "$assembly" ]; then
fi fi
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')" ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
if [ $ml = "armasm" ]; then
defines="$defines -D_M_ARM"
fi
if test -n "$verbose"; then if test -n "$verbose"; then
echo "$cl -nologo -EP $includes $defines $src > $ppsrc" echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
fi fi
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $? "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')" output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
args="-nologo $safeseh $single $output $ppsrc" if [ $ml = "armasm" ]; then
args="-nologo -g -oldit $armasm_output $ppsrc -errorReport:prompt"
else
args="-nologo $safeseh $single $output $ppsrc"
fi
if test -n "$verbose"; then if test -n "$verbose"; then
echo "$ml $args" echo "$ml $args"

View File

@@ -28,6 +28,7 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
#if defined(__arm__) || defined(_M_ARM)
#include <fficonfig.h> #include <fficonfig.h>
#include <ffi.h> #include <ffi.h>
#include <ffi_common.h> #include <ffi_common.h>
@@ -35,6 +36,11 @@
#include <stdlib.h> #include <stdlib.h>
#include "internal.h" #include "internal.h"
#if defined(_MSC_VER) && defined(_M_ARM)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#if FFI_EXEC_TRAMPOLINE_TABLE #if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__ #ifdef __MACH__
@@ -42,7 +48,11 @@
#endif #endif
#else #else
#ifndef _M_ARM
extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN; extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
#else
extern unsigned int ffi_arm_trampoline[3] FFI_HIDDEN;
#endif
#endif #endif
/* Forward declares. */ /* Forward declares. */
@@ -88,10 +98,20 @@ ffi_put_arg (ffi_type *ty, void *src, void *dst)
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
#ifndef _MSC_VER
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
#endif
*(UINT32 *)dst = *(UINT32 *)src; *(UINT32 *)dst = *(UINT32 *)src;
break; break;
#ifdef _MSC_VER
// casting a float* to a UINT32* doesn't work on Windows
case FFI_TYPE_FLOAT:
*(uintptr_t *)dst = 0;
*(float *)dst = *(float *)src;
break;
#endif
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
@@ -210,7 +230,7 @@ ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
} }
/* Perform machine dependent cif processing */ /* Perform machine dependent cif processing */
ffi_status ffi_status FFI_HIDDEN
ffi_prep_cif_machdep (ffi_cif *cif) ffi_prep_cif_machdep (ffi_cif *cif)
{ {
int flags = 0, cabi = cif->abi; int flags = 0, cabi = cif->abi;
@@ -301,7 +321,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
} }
/* Perform machine dependent cif processing for variadic calls */ /* Perform machine dependent cif processing for variadic calls */
ffi_status ffi_status FFI_HIDDEN
ffi_prep_cif_machdep_var (ffi_cif * cif, ffi_prep_cif_machdep_var (ffi_cif * cif,
unsigned int nfixedargs, unsigned int ntotalargs) unsigned int nfixedargs, unsigned int ntotalargs)
{ {
@@ -571,15 +591,28 @@ ffi_prep_closure_loc (ffi_closure * closure,
config[0] = closure; config[0] = closure;
config[1] = closure_func; config[1] = closure_func;
#else #else
memcpy (closure->tramp, ffi_arm_trampoline, 8);
#ifndef _M_ARM
memcpy(closure->tramp, ffi_arm_trampoline, 8);
#else
// cast away function type so MSVC doesn't set the lower bit of the function pointer
memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);
#endif
#if defined (__QNX__) #if defined (__QNX__)
msync(closure->tramp, 8, 0x1000000); /* clear data map */ msync(closure->tramp, 8, 0x1000000); /* clear data map */
msync(codeloc, 8, 0x1000000); /* clear insn map */ msync(codeloc, 8, 0x1000000); /* clear insn map */
#elif defined(_MSC_VER)
FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);
#else #else
__clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */ __clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
__clear_cache(codeloc, codeloc + 8); /* clear insn map */ __clear_cache(codeloc, codeloc + 8); /* clear insn map */
#endif #endif
#ifdef _M_ARM
*(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;
#else
*(void (**)(void))(closure->tramp + 8) = closure_func; *(void (**)(void))(closure->tramp + 8) = closure_func;
#endif
#endif #endif
closure->cif = cif; closure->cif = cif;
@@ -781,7 +814,7 @@ place_vfp_arg (ffi_cif *cif, int h)
} }
/* Found regs to allocate. */ /* Found regs to allocate. */
cif->vfp_used |= new_used; cif->vfp_used |= new_used;
cif->vfp_args[cif->vfp_nargs++] = reg; cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;
/* Update vfp_reg_free. */ /* Update vfp_reg_free. */
if (cif->vfp_used & (1 << cif->vfp_reg_free)) if (cif->vfp_used & (1 << cif->vfp_reg_free))
@@ -803,7 +836,7 @@ place_vfp_arg (ffi_cif *cif, int h)
static void static void
layout_vfp_args (ffi_cif * cif) layout_vfp_args (ffi_cif * cif)
{ {
int i; unsigned int i;
/* Init VFP fields */ /* Init VFP fields */
cif->vfp_used = 0; cif->vfp_used = 0;
cif->vfp_nargs = 0; cif->vfp_nargs = 0;
@@ -817,3 +850,5 @@ layout_vfp_args (ffi_cif * cif)
break; break;
} }
} }
#endif /* __arm__ or _M_ARM */

View File

@@ -43,7 +43,7 @@ typedef enum ffi_abi {
FFI_SYSV, FFI_SYSV,
FFI_VFP, FFI_VFP,
FFI_LAST_ABI, FFI_LAST_ABI,
#ifdef __ARM_PCS_VFP #if defined(__ARM_PCS_VFP) || defined(_M_ARM)
FFI_DEFAULT_ABI = FFI_VFP, FFI_DEFAULT_ABI = FFI_VFP,
#else #else
FFI_DEFAULT_ABI = FFI_SYSV, FFI_DEFAULT_ABI = FFI_SYSV,
@@ -57,7 +57,9 @@ typedef enum ffi_abi {
signed char vfp_args[16] \ signed char vfp_args[16] \
#define FFI_TARGET_SPECIFIC_VARIADIC #define FFI_TARGET_SPECIFIC_VARIADIC
#ifndef _M_ARM
#define FFI_TARGET_HAS_COMPLEX_TYPE #define FFI_TARGET_HAS_COMPLEX_TYPE
#endif
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
@@ -74,8 +76,13 @@ typedef enum ffi_abi {
#error "No trampoline table implementation" #error "No trampoline table implementation"
#endif #endif
#else
#ifdef _MSC_VER
#define FFI_TRAMPOLINE_SIZE 16
#define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
#else #else
#define FFI_TRAMPOLINE_SIZE 12 #define FFI_TRAMPOLINE_SIZE 12
#endif
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
#endif #endif

View File

@@ -25,6 +25,7 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
#ifdef __arm__
#define LIBFFI_ASM #define LIBFFI_ASM
#include <fficonfig.h> #include <fficonfig.h>
#include <ffi.h> #include <ffi.h>
@@ -377,6 +378,7 @@ ARM_FUNC_START(ffi_arm_trampoline)
ARM_FUNC_END(ffi_arm_trampoline) ARM_FUNC_END(ffi_arm_trampoline)
#endif /* FFI_EXEC_TRAMPOLINE_TABLE */ #endif /* FFI_EXEC_TRAMPOLINE_TABLE */
#endif /* __arm__ */
#if defined __ELF__ && defined __linux__ #if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits .section .note.GNU-stack,"",%progbits

311
src/arm/sysv_msvc_arm32.S Normal file
View File

@@ -0,0 +1,311 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
Copyright (c) 2019 Microsoft Corporation.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
#include <ffi_cfi.h>
#include "internal.h"
#include "ksarm.h"
; 8 byte aligned AREA to support 8 byte aligned jump tables
MACRO
NESTED_ENTRY_FFI $FuncName, $AreaName, $ExceptHandler
; compute the function's labels
__DeriveFunctionLabels $FuncName
; determine the area we will put the function into
__FuncArea SETS "|.text|"
IF "$AreaName" != ""
__FuncArea SETS "$AreaName"
ENDIF
; set up the exception handler itself
__FuncExceptionHandler SETS ""
IF "$ExceptHandler" != ""
__FuncExceptionHandler SETS "|$ExceptHandler|"
ENDIF
; switch to the specified area, jump tables require 8 byte alignment
AREA $__FuncArea,CODE,CODEALIGN,ALIGN=3,READONLY
; export the function name
__ExportProc $FuncName
; flush any pending literal pool stuff
ROUT
; reset the state of the unwind code tracking
__ResetUnwindState
MEND
; MACRO
; TABLE_ENTRY $Type, $Table
;$Type_$Table
; MEND
#define E(index,table) return_##index##_##table
; r0: stack
; r1: frame
; r2: fn
; r3: vfp_used
; fake entry point exists only to generate exists only to
; generate .pdata for exception unwinding
NESTED_ENTRY_FFI ffi_call_VFP_fake
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
ALTERNATE_ENTRY ffi_call_VFP
cmp r3, #3 ; load only d0 if possible
vldrle d0, [r0]
vldmgt r0, {d0-d7}
add r0, r0, #64 ; discard the vfp register args
b ffi_call_SYSV
NESTED_END ffi_call_VFP_fake
; fake entry point exists only to generate exists only to
; generate .pdata for exception unwinding
NESTED_ENTRY_FFI ffi_call_SYSV_fake
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
ALTERNATE_ENTRY ffi_call_SYSV
stm r1, {fp, lr}
mov fp, r1
mov sp, r0 ; install the stack pointer
mov lr, r2 ; move the fn pointer out of the way
ldr ip, [fp, #16] ; install the static chain
ldmia sp!, {r0-r3} ; move first 4 parameters in registers.
blx lr ; call fn
; Load r2 with the pointer to storage for the return value
; Load r3 with the return type code
ldr r2, [fp, #8]
ldr r3, [fp, #12]
; Deallocate the stack with the arguments.
mov sp, fp
; Store values stored in registers.
ALIGN 8
lsl r3, #3
add r3, r3, pc
add r3, #8
mov pc, r3
E(ARM_TYPE_VFP_S, ffi_call)
ALIGN 8
vstr s0, [r2]
pop {fp,pc}
E(ARM_TYPE_VFP_D, ffi_call)
ALIGN 8
vstr d0, [r2]
pop {fp,pc}
E(ARM_TYPE_VFP_N, ffi_call)
ALIGN 8
vstm r2, {d0-d3}
pop {fp,pc}
E(ARM_TYPE_INT64, ffi_call)
ALIGN 8
str r1, [r2, #4]
nop
E(ARM_TYPE_INT, ffi_call)
ALIGN 8
str r0, [r2]
pop {fp,pc}
E(ARM_TYPE_VOID, ffi_call)
ALIGN 8
pop {fp,pc}
nop
E(ARM_TYPE_STRUCT, ffi_call)
ALIGN 8
cmp r3, #ARM_TYPE_STRUCT
pop {fp,pc}
NESTED_END ffi_call_SYSV_fake
IMPORT |ffi_closure_inner_SYSV|
/*
int ffi_closure_inner_SYSV
(
cif, ; r0
fun, ; r1
user_data, ; r2
frame ; r3
)
*/
NESTED_ENTRY_FFI ffi_go_closure_SYSV
stmdb sp!, {r0-r3} ; save argument regs
ldr r0, [ip, #4] ; load cif
ldr r1, [ip, #8] ; load fun
mov r2, ip ; load user_data
b ffi_go_closure_SYSV_0
NESTED_END ffi_go_closure_SYSV
; r3: ffi_closure
; fake entry point exists only to generate exists only to
; generate .pdata for exception unwinding
NESTED_ENTRY_FFI ffi_closure_SYSV_fake
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
ALTERNATE_ENTRY ffi_closure_SYSV
ldmfd sp!, {ip,r0} ; restore fp (r0 is used for stack alignment)
stmdb sp!, {r0-r3} ; save argument regs
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] ; ffi_closure->cif
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] ; ffi_closure->fun
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] ; ffi_closure->user_data
ALTERNATE_ENTRY ffi_go_closure_SYSV_0
add ip, sp, #16 ; compute entry sp
sub sp, sp, #64+32 ; allocate frame parameter (sizeof(vfp_space) = 64, sizeof(result) = 32)
mov r3, sp ; set frame parameter
stmdb sp!, {ip,lr}
bl ffi_closure_inner_SYSV ; call the Python closure
; Load values returned in registers.
add r2, sp, #64+8 ; address of closure_frame->result
bl ffi_closure_ret ; move result to correct register or memory for type
ldmfd sp!, {ip,lr}
mov sp, ip ; restore stack pointer
mov pc, lr
NESTED_END ffi_closure_SYSV_fake
IMPORT |ffi_closure_inner_VFP|
/*
int ffi_closure_inner_VFP
(
cif, ; r0
fun, ; r1
user_data, ; r2
frame ; r3
)
*/
NESTED_ENTRY_FFI ffi_go_closure_VFP
stmdb sp!, {r0-r3} ; save argument regs
ldr r0, [ip, #4] ; load cif
ldr r1, [ip, #8] ; load fun
mov r2, ip ; load user_data
b ffi_go_closure_VFP_0
NESTED_END ffi_go_closure_VFP
; fake entry point exists only to generate exists only to
; generate .pdata for exception unwinding
; r3: closure
NESTED_ENTRY_FFI ffi_closure_VFP_fake
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
ALTERNATE_ENTRY ffi_closure_VFP
ldmfd sp!, {ip,r0} ; restore fp (r0 is used for stack alignment)
stmdb sp!, {r0-r3} ; save argument regs
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] ; load cif
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] ; load fun
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] ; load user_data
ALTERNATE_ENTRY ffi_go_closure_VFP_0
add ip, sp, #16 ; compute entry sp
sub sp, sp, #32 ; save space for closure_frame->result
vstmdb sp!, {d0-d7} ; push closure_frame->vfp_space
mov r3, sp ; save closure_frame
stmdb sp!, {ip,lr}
bl ffi_closure_inner_VFP
; Load values returned in registers.
add r2, sp, #64+8 ; load result
bl ffi_closure_ret
ldmfd sp!, {ip,lr}
mov sp, ip ; restore stack pointer
mov pc, lr
NESTED_END ffi_closure_VFP_fake
/* Load values returned in registers for both closure entry points.
Note that we use LDM with SP in the register set. This is deprecated
by ARM, but not yet unpredictable. */
NESTED_ENTRY_FFI ffi_closure_ret
stmdb sp!, {fp,lr}
ALIGN 8
lsl r0, #3
add r0, r0, pc
add r0, #8
mov pc, r0
E(ARM_TYPE_VFP_S, ffi_closure)
ALIGN 8
vldr s0, [r2]
b call_epilogue
E(ARM_TYPE_VFP_D, ffi_closure)
ALIGN 8
vldr d0, [r2]
b call_epilogue
E(ARM_TYPE_VFP_N, ffi_closure)
ALIGN 8
vldm r2, {d0-d3}
b call_epilogue
E(ARM_TYPE_INT64, ffi_closure)
ALIGN 8
ldr r1, [r2, #4]
nop
E(ARM_TYPE_INT, ffi_closure)
ALIGN 8
ldr r0, [r2]
b call_epilogue
E(ARM_TYPE_VOID, ffi_closure)
ALIGN 8
b call_epilogue
nop
E(ARM_TYPE_STRUCT, ffi_closure)
ALIGN 8
b call_epilogue
call_epilogue
ldmfd sp!, {fp,pc}
NESTED_END ffi_closure_ret
AREA |.trampoline|, DATA, THUMB, READONLY
EXPORT |ffi_arm_trampoline|
|ffi_arm_trampoline| DATA
thisproc adr ip, thisproc
stmdb sp!, {ip, r0}
ldr pc, [pc, #0]
DCD 0
;ENDP
END